competed user video view
This commit is contained in:
@@ -103,7 +103,6 @@
|
||||
527AC6FD2C173A5100434FB7 /* SongListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC6FB2C173A5100434FB7 /* SongListCell.swift */; };
|
||||
527AC6FE2C173A5100434FB7 /* SongListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 527AC6FC2C173A5100434FB7 /* SongListCell.xib */; };
|
||||
527AC7012C182DCE00434FB7 /* TimeStringToSeconds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC7002C182DCE00434FB7 /* TimeStringToSeconds.swift */; };
|
||||
527CA43A2C6C7FBF00EEDD91 /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 527CA4382C6C7FBE00EEDD91 /* WOKA.xcdatamodeld */; };
|
||||
528BEF602C2C372900FFDAB8 /* ContinueWatchingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528BEF5F2C2C372900FFDAB8 /* ContinueWatchingVC.swift */; };
|
||||
528E5F1B2C24531200E33E4E /* SeasonListingDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528E5F1A2C24531200E33E4E /* SeasonListingDM.swift */; };
|
||||
528E5F222C24660F00E33E4E /* SeasonCategoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528E5F202C24660F00E33E4E /* SeasonCategoryCell.swift */; };
|
||||
@@ -338,6 +337,9 @@
|
||||
9CBE1B432C0F37B300CA6E61 /* DropDown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBE1B382C0F37B200CA6E61 /* DropDown.swift */; };
|
||||
9CBE1B442C0F37B300CA6E61 /* DropDown+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBE1B392C0F37B200CA6E61 /* DropDown+Appearance.swift */; };
|
||||
9CBE1B452C0F37B300CA6E61 /* DropDownCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBE1B3A2C0F37B200CA6E61 /* DropDownCell.swift */; };
|
||||
9CC0D2F82C6F339D0019DF73 /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9CC0D2F62C6F339D0019DF73 /* WOKA.xcdatamodeld */; };
|
||||
9CC0D2FA2C6F33BE0019DF73 /* AuthFuncUserVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CC0D2F92C6F33BE0019DF73 /* AuthFuncUserVideoView.swift */; };
|
||||
9CC0D2FC2C6F5CAE0019DF73 /* PlayerVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CC0D2FB2C6F5CAE0019DF73 /* PlayerVM.swift */; };
|
||||
9CDAEB032C53B97B00890C47 /* VersionTexts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDAEB022C53B97B00890C47 /* VersionTexts.swift */; };
|
||||
9CDAEB052C53DB2900890C47 /* ProductDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDAEB042C53DB2900890C47 /* ProductDetailsVC.swift */; };
|
||||
9CDAEB072C53E42900890C47 /* ProductDetailsVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDAEB062C53E42900890C47 /* ProductDetailsVM.swift */; };
|
||||
@@ -494,7 +496,6 @@
|
||||
527AC6FB2C173A5100434FB7 /* SongListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SongListCell.swift; sourceTree = "<group>"; };
|
||||
527AC6FC2C173A5100434FB7 /* SongListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SongListCell.xib; sourceTree = "<group>"; };
|
||||
527AC7002C182DCE00434FB7 /* TimeStringToSeconds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeStringToSeconds.swift; sourceTree = "<group>"; };
|
||||
527CA4392C6C7FBE00EEDD91 /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = "<group>"; };
|
||||
528BEF5F2C2C372900FFDAB8 /* ContinueWatchingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContinueWatchingVC.swift; sourceTree = "<group>"; };
|
||||
528E5F1A2C24531200E33E4E /* SeasonListingDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonListingDM.swift; sourceTree = "<group>"; };
|
||||
528E5F202C24660F00E33E4E /* SeasonCategoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonCategoryCell.swift; sourceTree = "<group>"; };
|
||||
@@ -719,6 +720,9 @@
|
||||
9CBE1B392C0F37B200CA6E61 /* DropDown+Appearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DropDown+Appearance.swift"; sourceTree = "<group>"; };
|
||||
9CBE1B3A2C0F37B200CA6E61 /* DropDownCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownCell.swift; sourceTree = "<group>"; };
|
||||
9CBE1B3C2C0F37B200CA6E61 /* DropDown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DropDown.h; sourceTree = "<group>"; };
|
||||
9CC0D2F72C6F339D0019DF73 /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = "<group>"; };
|
||||
9CC0D2F92C6F33BE0019DF73 /* AuthFuncUserVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthFuncUserVideoView.swift; sourceTree = "<group>"; };
|
||||
9CC0D2FB2C6F5CAE0019DF73 /* PlayerVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerVM.swift; sourceTree = "<group>"; };
|
||||
9CDAEB022C53B97B00890C47 /* VersionTexts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionTexts.swift; sourceTree = "<group>"; };
|
||||
9CDAEB042C53DB2900890C47 /* ProductDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDetailsVC.swift; sourceTree = "<group>"; };
|
||||
9CDAEB062C53E42900890C47 /* ProductDetailsVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProductDetailsVM.swift; sourceTree = "<group>"; };
|
||||
@@ -930,7 +934,7 @@
|
||||
9C535DC82C00C34000DA6DCD /* Theme */,
|
||||
52DAC6462C21761700E2F85B /* WebSeries */,
|
||||
9C834ED92C1C20EC00B29A9C /* WOKA.entitlements */,
|
||||
527CA4382C6C7FBE00EEDD91 /* WOKA.xcdatamodeld */,
|
||||
9CC0D2F62C6F339D0019DF73 /* WOKA.xcdatamodeld */,
|
||||
52ACC1292C610EC900791528 /* PersistentStorage.swift */,
|
||||
);
|
||||
path = WOKA;
|
||||
@@ -1656,6 +1660,7 @@
|
||||
9C27E1622BDB6F1900EC1DA9 /* AuthFunc.swift */,
|
||||
525327D82BFCDDF700F64283 /* AuthFuncStartupSoundHandling.swift */,
|
||||
52FDBA7A2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift */,
|
||||
9CC0D2F92C6F33BE0019DF73 /* AuthFuncUserVideoView.swift */,
|
||||
);
|
||||
path = AuthFunc;
|
||||
sourceTree = "<group>";
|
||||
@@ -1731,6 +1736,7 @@
|
||||
524C422A2C04781B0016A11C /* ThemeTwoVM.swift */,
|
||||
52BC3BF12C170264002FACA6 /* MoreVM.swift */,
|
||||
529CFEED2C60F49000B0B380 /* UserNotificationVM.swift */,
|
||||
9CC0D2FB2C6F5CAE0019DF73 /* PlayerVM.swift */,
|
||||
);
|
||||
path = ViewModel;
|
||||
sourceTree = "<group>";
|
||||
@@ -2314,7 +2320,7 @@
|
||||
52A6DCA02C4E3AA600F63C51 /* ShopListingCell.swift in Sources */,
|
||||
525954192BE8CC3400191286 /* ConstantString.swift in Sources */,
|
||||
52D774EB2BDFC0BF001D87DE /* OTPVC.swift in Sources */,
|
||||
527CA43A2C6C7FBF00EEDD91 /* WOKA.xcdatamodeld in Sources */,
|
||||
9CC0D2F82C6F339D0019DF73 /* WOKA.xcdatamodeld in Sources */,
|
||||
9C8446872C40FC6E003E3E53 /* AVPlayerTesting.swift in Sources */,
|
||||
52AF71F42C36C40B00BC5972 /* GamesWebViewVC.swift in Sources */,
|
||||
9C007F202C255DF200F798C2 /* EpisodeListingDM.swift in Sources */,
|
||||
@@ -2327,6 +2333,7 @@
|
||||
525861DE2C4FE7A100C33C79 /* CouponCell.swift in Sources */,
|
||||
9C27E1632BDB6F1900EC1DA9 /* AuthFunc.swift in Sources */,
|
||||
9C0A85412BEE35670093783D /* ResetPassUserNameVM.swift in Sources */,
|
||||
9CC0D2FA2C6F33BE0019DF73 /* AuthFuncUserVideoView.swift in Sources */,
|
||||
52C6E0292BE3B52500E22D59 /* SelectAvatarVM.swift in Sources */,
|
||||
9CDAEB032C53B97B00890C47 /* VersionTexts.swift in Sources */,
|
||||
52C8B0592BDA57FA003B51D0 /* StaticFilesString.swift in Sources */,
|
||||
@@ -2493,6 +2500,7 @@
|
||||
5258464F2C491829004F074B /* connectedness.swift in Sources */,
|
||||
9CBE1B452C0F37B300CA6E61 /* DropDownCell.swift in Sources */,
|
||||
9C27E16D2BDB852F00EC1DA9 /* GVar.swift in Sources */,
|
||||
9CC0D2FC2C6F5CAE0019DF73 /* PlayerVM.swift in Sources */,
|
||||
52B8D4E02C04A25E00ED65F3 /* UIView+Container.swift in Sources */,
|
||||
527A2BCA2C57776A0080DF9B /* AddNewAddressVC.swift in Sources */,
|
||||
9C56E8462BDBEE6400E4CA14 /* EmailVC.swift in Sources */,
|
||||
@@ -3070,14 +3078,14 @@
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
527CA4382C6C7FBE00EEDD91 /* WOKA.xcdatamodeld */ = {
|
||||
9CC0D2F62C6F339D0019DF73 /* WOKA.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
527CA4392C6C7FBE00EEDD91 /* WOKA.xcdatamodel */,
|
||||
9CC0D2F72C6F339D0019DF73 /* WOKA.xcdatamodel */,
|
||||
);
|
||||
currentVersion = 527CA4392C6C7FBE00EEDD91 /* WOKA.xcdatamodel */;
|
||||
currentVersion = 9CC0D2F72C6F339D0019DF73 /* WOKA.xcdatamodel */;
|
||||
name = WOKA.xcdatamodeld;
|
||||
path = /Users/macbookpro/Desktop/WOKA/WOKA/WOKA.xcdatamodeld;
|
||||
path = /Users/bilal/Desktop/woka_native_ios_swift/WOKA/WOKA.xcdatamodeld;
|
||||
sourceTree = "<group>";
|
||||
versionGroupType = wrapper.xcdatamodel;
|
||||
};
|
||||
|
||||
@@ -549,19 +549,36 @@
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="n6H-pw-g1w">
|
||||
<rect key="frame" x="118.66666666666669" y="290.66666666666669" width="177" height="200"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SupportGirlImage" translatesAutoresizingMaskIntoConstraints="NO" id="Rnc-CS-DVv">
|
||||
<rect key="frame" x="0.0" y="0.0" width="177" height="166"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No Address Found!" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SR8-rF-46h" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="176" width="177" height="24"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="37x-el-mdR"/>
|
||||
<color key="backgroundColor" systemColor="systemGreenColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="n6H-pw-g1w" firstAttribute="centerY" secondItem="w05-l0-ALY" secondAttribute="centerY" id="bbS-Lc-ZsW"/>
|
||||
<constraint firstItem="37x-el-mdR" firstAttribute="bottom" secondItem="Ry1-Ll-tvj" secondAttribute="bottom" constant="5" id="g8o-D8-sxQ"/>
|
||||
<constraint firstItem="37x-el-mdR" firstAttribute="trailing" secondItem="Ry1-Ll-tvj" secondAttribute="trailing" constant="10" id="hfh-kM-3II"/>
|
||||
<constraint firstItem="Ry1-Ll-tvj" firstAttribute="top" secondItem="37x-el-mdR" secondAttribute="top" constant="5" id="nXO-UI-rOM"/>
|
||||
<constraint firstItem="n6H-pw-g1w" firstAttribute="centerX" secondItem="w05-l0-ALY" secondAttribute="centerX" id="vdb-8x-PwN"/>
|
||||
<constraint firstItem="Ry1-Ll-tvj" firstAttribute="leading" secondItem="37x-el-mdR" secondAttribute="leading" constant="10" id="zid-rU-Ovk"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="addNewAddressBtn" destination="02u-58-7FW" id="eWv-38-GfZ"/>
|
||||
<outlet property="innerView" destination="JAF-kY-lUa" id="cM7-cm-pqy"/>
|
||||
<outlet property="noDataStack" destination="n6H-pw-g1w" id="EMJ-ob-Dr1"/>
|
||||
<outlet property="tableView" destination="w05-l0-ALY" id="J15-i9-ySS"/>
|
||||
<outlet property="useSelectedAddBtn" destination="ZNs-65-Cqv" id="hYN-Nc-H8h"/>
|
||||
</connections>
|
||||
@@ -582,7 +599,7 @@
|
||||
<rect key="frame" x="0.0" y="44" width="414" height="852"/>
|
||||
<color key="backgroundColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<wkWebViewConfiguration key="configuration" allowsAirPlayForMediaPlayback="NO" allowsPictureInPictureMediaPlayback="NO">
|
||||
<dataDetectorTypes key="dataDetectorTypes"/>
|
||||
<dataDetectorTypes key="dataDetectorTypes" none="YES"/>
|
||||
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
|
||||
<wkPreferences key="preferences"/>
|
||||
</wkWebViewConfiguration>
|
||||
@@ -636,6 +653,7 @@
|
||||
</designable>
|
||||
</designables>
|
||||
<resources>
|
||||
<image name="SupportGirlImage" width="166" height="166"/>
|
||||
<namedColor name="TextDarkBlue">
|
||||
<color red="0.10599999874830246" green="0.050999999046325684" blue="0.60399997234344482" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
@@ -643,7 +661,7 @@
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemGreenColor">
|
||||
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.20392156859999999" green="0.78039215689999997" blue="0.34901960780000002" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -13,6 +13,7 @@ class AddressListVC: UIViewController {
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
@IBOutlet weak var useSelectedAddBtn : LocalisedElementsButton!
|
||||
@IBOutlet weak var addNewAddressBtn : LocalisedElementsButton!
|
||||
@IBOutlet weak var noDataStack: UIStackView!
|
||||
|
||||
var vm = AddressListVM()
|
||||
|
||||
@@ -61,6 +62,10 @@ class AddressListVC: UIViewController {
|
||||
|
||||
switch sender{
|
||||
case useSelectedAddBtn:
|
||||
if CartDataCache.addressData.count == 0{
|
||||
self.toast(msg: "Please add address", time: 1.5)
|
||||
return
|
||||
}
|
||||
if let addressID = CartDataCache.addressData.filter({$0.isDefault == true}).first?.id{
|
||||
vm.createOrder(addressID: addressID, couponCode: vm.couponCodeApplied)
|
||||
}
|
||||
|
||||
@@ -64,6 +64,7 @@ class AddressListVM{
|
||||
Error
|
||||
*/
|
||||
Utilities.dismissProgressHUD()
|
||||
self.checkForNoData()
|
||||
case 1:
|
||||
Utilities.dismissProgressHUD()
|
||||
guard let data = data.data else{return}
|
||||
@@ -73,6 +74,7 @@ class AddressListVM{
|
||||
CartDataCache.addressData[0].isAnimating = true
|
||||
}
|
||||
self.vc.tableView.reloadData()
|
||||
self.checkForNoData()
|
||||
if let pincode = CartDataCache.addressData.first?.pincode , let id = CartDataCache.addressData.first?.id{
|
||||
checkEstimatedDeliveryData(pinCode: pincode, id: id)
|
||||
}
|
||||
@@ -83,9 +85,11 @@ class AddressListVM{
|
||||
case .failure(let error):
|
||||
guard let self else{
|
||||
Utilities.dismissProgressHUD()
|
||||
self?.checkForNoData()
|
||||
return
|
||||
}
|
||||
Utilities.dismissProgressHUD()
|
||||
checkForNoData()
|
||||
Utilities.alertWithBtnCompletion(title: "Error", msgBody: error.localizedDescription, okBtnStr: "Retry?", vc: self.vc) { isDone in
|
||||
if isDone{
|
||||
self.getAddressListing()
|
||||
@@ -95,6 +99,14 @@ class AddressListVM{
|
||||
}
|
||||
}
|
||||
|
||||
func checkForNoData(){
|
||||
if CartDataCache.addressData.count == 0{
|
||||
vc.noDataStack.isHidden = false
|
||||
}else{
|
||||
vc.noDataStack.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
func checkEstimatedDeliveryData(pinCode : String, id : Int){
|
||||
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()]
|
||||
let params : Parameters = ["pincode" : pinCode]
|
||||
|
||||
@@ -361,7 +361,9 @@ class AudioBookDetailsVC : UIViewController{
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: 0, contentType: .audioBooks)
|
||||
if let audioID = audioData?.id{
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: 0, contentType: .audioBooks,videoIDs: [audioID])
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func closeBtnTapped(_ sender: UIButton) {
|
||||
|
||||
@@ -66,6 +66,13 @@ class AudioBookHomeVC: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
if K.GVar.reloadContinueAudioBooks{
|
||||
K.GVar.reloadContinueAudioBooks = false
|
||||
vm.getContinueWatching()
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
vm.updateTableHeight()
|
||||
}
|
||||
@@ -78,10 +85,8 @@ class AudioBookHomeVC: UIViewController {
|
||||
}
|
||||
|
||||
@IBAction func listenAudioBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
guard let data = vm.headerData else{return}
|
||||
if let postID = data.id{
|
||||
PersistentStorage.shared.addAudioCount(postID: postID)
|
||||
}
|
||||
guard let data = vm.headerData, let postID = data.id else{return}
|
||||
PersistentStorage.shared.addAudioCount(postID: postID)
|
||||
var playerItems = [JwPlayerItemCreate]()
|
||||
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
|
||||
if let englishData = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first, let url = englishData.url{
|
||||
@@ -92,7 +97,7 @@ class AudioBookHomeVC: UIViewController {
|
||||
playerItems.append(JwPlayerItemCreate(url: url, poster: data.thumbnailPath, titles: hindiData.title))
|
||||
}
|
||||
}
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: 0, contentType: .audioBooks)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: 0, contentType: .audioBooks, videoIDs: [postID])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,5 +33,7 @@ extension K{
|
||||
static let error = "Error"
|
||||
|
||||
static let rupeeSign = "₹"
|
||||
|
||||
static let sync = "Syncing..."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,5 +24,9 @@ extension K{
|
||||
|
||||
static var reloadMyListAll = 0 // 0 - null, 1 - add , 2- remove
|
||||
static var reloadMyListAllID = 0
|
||||
|
||||
static var reloadContinueKaraoke = false
|
||||
static var reloadContinueAudioBooks = false
|
||||
static var reloadContinueWebSeries = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -205,7 +205,11 @@ class GamesDetailVC: UIViewController {
|
||||
}
|
||||
}
|
||||
|
||||
shareView.addTapGesture {
|
||||
shareView.addTapGesture { [weak self] in
|
||||
guard let self else{return}
|
||||
if let postID = gameData?.id{
|
||||
PersistentStorage.shared.addGamesCount(postID: postID)
|
||||
}
|
||||
if let name = URL(string: "https://apps.apple.com/in/app/woka/id6465305185"), !name.absoluteString.isEmpty {
|
||||
let objectsToShare = [name]
|
||||
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
|
||||
|
||||
@@ -14,12 +14,20 @@ class GamesWebViewVC: UIViewController, WKNavigationDelegate,UIGestureRecognizer
|
||||
var orientation : ScreenOrientation?
|
||||
var count = 0
|
||||
var postID : Int?
|
||||
|
||||
@IBOutlet weak var clickView: UIView!
|
||||
|
||||
@IBOutlet weak var webView: WKWebView!
|
||||
|
||||
var startTimeStamp = Date()
|
||||
|
||||
typealias btnTappedBlock = () -> Void
|
||||
var btnTapped : btnTappedBlock?
|
||||
|
||||
deinit{
|
||||
// print("Deinit Game")
|
||||
NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self,name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
|
||||
if let postID = self.postID{
|
||||
PersistentStorage.shared.addGamesCount(postID: postID,count: count)
|
||||
}
|
||||
@@ -49,6 +57,10 @@ class GamesWebViewVC: UIViewController, WKNavigationDelegate,UIGestureRecognizer
|
||||
|
||||
// Add the gesture recognizer to the web view
|
||||
clickView.addGestureRecognizer(tap)
|
||||
|
||||
// Add observers
|
||||
NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil)
|
||||
NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.willEnterForegroundNotification,object: nil)
|
||||
}
|
||||
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
|
||||
@@ -61,9 +73,7 @@ class GamesWebViewVC: UIViewController, WKNavigationDelegate,UIGestureRecognizer
|
||||
}
|
||||
|
||||
@IBAction func backBtnTapped(_ sender: UIButton) {
|
||||
if let postID = self.postID{
|
||||
PersistentStorage.shared.addOthersCount()
|
||||
}
|
||||
PersistentStorage.shared.addOthersCount()
|
||||
|
||||
let sb = UIStoryboard(name: K.StoryBoard.customAlerts, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.CustomAlerts.yesNoAlertVC) as! YesNoAlertVC
|
||||
@@ -75,7 +85,8 @@ class GamesWebViewVC: UIViewController, WKNavigationDelegate,UIGestureRecognizer
|
||||
guard let self else{return}
|
||||
switch mode{
|
||||
case .yes:
|
||||
|
||||
// update continue watching
|
||||
self.updateGamesView()
|
||||
if orientation == .landscape{
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
@@ -85,7 +96,6 @@ class GamesWebViewVC: UIViewController, WKNavigationDelegate,UIGestureRecognizer
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
case .no:
|
||||
if let postID = self.postID{
|
||||
PersistentStorage.shared.addGamesCount(postID: postID)
|
||||
@@ -98,6 +108,26 @@ class GamesWebViewVC: UIViewController, WKNavigationDelegate,UIGestureRecognizer
|
||||
self.present(vcPush, animated: true)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - App LifeCycle HAndler
|
||||
|
||||
@objc func appDidEnterBackground() {
|
||||
//when app goes in background make a count
|
||||
updateGamesView()
|
||||
}
|
||||
|
||||
@objc func appWillEnterForeground() {
|
||||
//reset the start time
|
||||
startTimeStamp = Date()
|
||||
}
|
||||
|
||||
func updateGamesView(){
|
||||
if let postID {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: startTimeStamp, date2: Date())
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.game.rawValue, duration: duration, catID: 0) { _ in}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Handle Screen Transition
|
||||
|
||||
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
|
||||
@@ -191,6 +191,22 @@ class DateFormatterLib{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static func dateDifferenceINT(date1 : Date, date2 : Date) -> Int{
|
||||
// Calculate the difference in seconds
|
||||
let timeInterval = date2.timeIntervalSince(date1)
|
||||
|
||||
// Convert the time interval to an integer representing the difference in seconds
|
||||
let differenceInSeconds = Int(timeInterval)
|
||||
|
||||
// If you want the difference in minutes, divide by 60
|
||||
// let differenceInMinutes = Int(timeInterval / 60)
|
||||
|
||||
// If you want the difference in hours, divide by 3600
|
||||
// let differenceInHours = Int(timeInterval / 3600)
|
||||
|
||||
return differenceInSeconds
|
||||
}
|
||||
}
|
||||
|
||||
extension Date {
|
||||
|
||||
@@ -37,6 +37,10 @@ class MyListVC: UIViewController{
|
||||
@IBOutlet weak var gamesBtn: LocalisedElementsButton!
|
||||
@IBOutlet weak var karaokeViewBtn: LocalisedElementsButton!
|
||||
|
||||
@IBOutlet weak var shimmerStack: UIStackView!
|
||||
@IBOutlet var shimmerView: [ShimmerEffectView]!
|
||||
|
||||
|
||||
var vm = MyListVM()
|
||||
|
||||
deinit{
|
||||
|
||||
@@ -1461,6 +1461,49 @@
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="n3b-MP-wOW">
|
||||
<rect key="frame" x="0.0" y="126" width="430" height="660"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zVG-vD-Pa9" customClass="ShimmerEffectView" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="15" y="10" width="400" height="200"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="200" id="BOv-Or-mtr"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
||||
<integer key="value" value="10"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5PD-9x-fXz" customClass="ShimmerEffectView" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="15" y="230" width="400" height="200"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="200" id="1Hd-rU-zAi"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
||||
<integer key="value" value="10"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LMU-lo-nNz" customClass="ShimmerEffectView" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="15" y="450" width="400" height="200"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="200" id="xlu-qi-KIb"/>
|
||||
</constraints>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
||||
<integer key="value" value="10"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<edgeInsets key="layoutMargins" top="10" left="15" bottom="10" right="15"/>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="fPD-rO-ZgU"/>
|
||||
<color key="backgroundColor" red="0.82745098039215681" green="0.93725490196078431" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
@@ -1469,6 +1512,8 @@
|
||||
<constraint firstItem="fPD-rO-ZgU" firstAttribute="trailing" secondItem="a7Y-B6-f0Q" secondAttribute="trailing" constant="15" id="1TC-Nf-fdz"/>
|
||||
<constraint firstItem="jbL-QO-JJl" firstAttribute="leading" secondItem="5ML-g4-686" secondAttribute="trailing" constant="15" id="5bI-AA-E64"/>
|
||||
<constraint firstItem="SyC-Qw-kzE" firstAttribute="bottom" secondItem="fPD-rO-ZgU" secondAttribute="bottom" id="7R3-kt-ANX"/>
|
||||
<constraint firstItem="n3b-MP-wOW" firstAttribute="leading" secondItem="fPD-rO-ZgU" secondAttribute="leading" id="E1C-E8-97R"/>
|
||||
<constraint firstItem="n3b-MP-wOW" firstAttribute="trailing" secondItem="fPD-rO-ZgU" secondAttribute="trailing" id="I4g-uI-OU6"/>
|
||||
<constraint firstItem="fTK-nk-bN9" firstAttribute="leading" secondItem="fPD-rO-ZgU" secondAttribute="leading" id="KDZ-vt-s13"/>
|
||||
<constraint firstItem="a7Y-B6-f0Q" firstAttribute="top" secondItem="fPD-rO-ZgU" secondAttribute="top" constant="10" id="L4o-KM-D1O"/>
|
||||
<constraint firstItem="cxl-Av-gEU" firstAttribute="bottom" secondItem="a7Y-B6-f0Q" secondAttribute="bottom" constant="7" id="Lur-Ax-w8w"/>
|
||||
@@ -1477,6 +1522,7 @@
|
||||
<constraint firstItem="5ML-g4-686" firstAttribute="leading" secondItem="23B-pX-ODs" secondAttribute="leading" constant="5" id="Na5-Wr-DSa"/>
|
||||
<constraint firstItem="SyC-Qw-kzE" firstAttribute="top" secondItem="a7Y-B6-f0Q" secondAttribute="bottom" constant="10" id="Nyh-j8-zuL"/>
|
||||
<constraint firstItem="fPD-rO-ZgU" firstAttribute="trailing" secondItem="ygH-wj-cLk" secondAttribute="trailing" id="Pyd-Eq-Pwe"/>
|
||||
<constraint firstItem="n3b-MP-wOW" firstAttribute="bottom" relation="lessThanOrEqual" secondItem="fPD-rO-ZgU" secondAttribute="bottom" id="UgR-R8-f7G"/>
|
||||
<constraint firstItem="fPD-rO-ZgU" firstAttribute="trailing" secondItem="fTK-nk-bN9" secondAttribute="trailing" id="XRW-xO-sGx"/>
|
||||
<constraint firstItem="cxl-Av-gEU" firstAttribute="top" secondItem="23B-pX-ODs" secondAttribute="top" id="Y0G-Ua-UcP"/>
|
||||
<constraint firstItem="QHo-nZ-miK" firstAttribute="centerX" secondItem="fPD-rO-ZgU" secondAttribute="centerX" id="ZkK-bD-6Ys"/>
|
||||
@@ -1491,6 +1537,7 @@
|
||||
<constraint firstItem="ygH-wj-cLk" firstAttribute="top" secondItem="cxl-Av-gEU" secondAttribute="bottom" id="rb7-EW-WCc"/>
|
||||
<constraint firstItem="fPD-rO-ZgU" firstAttribute="trailing" secondItem="cxl-Av-gEU" secondAttribute="trailing" id="usz-Hi-BR2"/>
|
||||
<constraint firstItem="fPD-rO-ZgU" firstAttribute="bottom" secondItem="fTK-nk-bN9" secondAttribute="bottom" constant="-20" id="vmC-a4-Yy3"/>
|
||||
<constraint firstItem="n3b-MP-wOW" firstAttribute="top" secondItem="cxl-Av-gEU" secondAttribute="bottom" constant="10" id="xGm-9v-fwc"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="MY LIST" image="HeartIcon" id="dhn-IV-GcD"/>
|
||||
@@ -1510,17 +1557,21 @@
|
||||
<outlet property="karaokeViewBtn" destination="MNq-YB-EUG" id="nhX-tu-YWQ"/>
|
||||
<outlet property="noDataStack" destination="QHo-nZ-miK" id="mA1-FT-iQl"/>
|
||||
<outlet property="scrollView" destination="SyC-Qw-kzE" id="0xd-Wb-TU1"/>
|
||||
<outlet property="shimmerStack" destination="n3b-MP-wOW" id="taO-4R-ZPG"/>
|
||||
<outlet property="webSeriesBtn" destination="zNj-21-nce" id="Tkc-4Z-odt"/>
|
||||
<outlet property="webSeriesCV" destination="6Y6-vJ-OYT" id="FRf-D2-kxM"/>
|
||||
<outlet property="webSeriesEnglishStack" destination="vZT-j7-NyY" id="HG5-LW-alT"/>
|
||||
<outlet property="webSeriesHindiBtn" destination="PHL-y5-hHs" id="5Ez-Te-6El"/>
|
||||
<outlet property="webSeriesHindiCV" destination="aW7-x8-HRh" id="eJM-QC-gIw"/>
|
||||
<outlet property="webSeriesHindiStack" destination="h1g-o9-Qbb" id="cbP-E3-4Bc"/>
|
||||
<outletCollection property="shimmerView" destination="zVG-vD-Pa9" collectionClass="NSMutableArray" id="zku-q7-DXa"/>
|
||||
<outletCollection property="shimmerView" destination="5PD-9x-fXz" collectionClass="NSMutableArray" id="JrO-dN-fRP"/>
|
||||
<outletCollection property="shimmerView" destination="LMU-lo-nNz" collectionClass="NSMutableArray" id="Va8-vH-tav"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="lPK-ME-Nlb" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2198.5507246376815" y="977.67857142857133"/>
|
||||
<point key="canvasLocation" x="2197.6744186046512" y="977.2532188841202"/>
|
||||
</scene>
|
||||
<!--EXPLORE WOKA-->
|
||||
<scene sceneID="taU-OT-R2P">
|
||||
|
||||
@@ -36,7 +36,7 @@ class MyListVM{
|
||||
}
|
||||
|
||||
setupCell()
|
||||
Utilities.startProgressHUD()
|
||||
startShimmer(load: true)
|
||||
getFavouriteListing()
|
||||
|
||||
vc.karaokeViewBtn.roundCorner()
|
||||
@@ -46,6 +46,18 @@ class MyListVM{
|
||||
vc.webSeriesHindiBtn.roundCorner()
|
||||
}
|
||||
|
||||
func startShimmer(load : Bool){
|
||||
vc.shimmerView.forEach { shimmer in
|
||||
if load{
|
||||
shimmer.gradientColorOne = UIColor.lightGray.cgColor
|
||||
shimmer.startShimmer()
|
||||
}else{
|
||||
shimmer.stopShimmer()
|
||||
}
|
||||
}
|
||||
vc.shimmerStack.isHidden = !load
|
||||
}
|
||||
|
||||
@objc func viewPush(notification: Notification){
|
||||
if let userInfo = notification.userInfo, let action = userInfo["action"] as? TopViewPush {
|
||||
switch action {
|
||||
@@ -134,6 +146,7 @@ class MyListVM{
|
||||
case 0:
|
||||
self.refreshControl.endRefreshing()
|
||||
Utilities.dismissProgressHUD()
|
||||
self.startShimmer(load: false)
|
||||
self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2)
|
||||
// MyListDataTemp.shareInstance.webSeriesHindi.removeAll()
|
||||
MyListDataTemp.shareInstance.favListingData = nil
|
||||
@@ -148,6 +161,7 @@ class MyListVM{
|
||||
case 1:
|
||||
self.refreshControl.endRefreshing()
|
||||
Utilities.dismissProgressHUD()
|
||||
self.startShimmer(load: false)
|
||||
guard let data = data.data?.result else{return}
|
||||
MyListDataTemp.shareInstance.favListingData = nil
|
||||
// MyListDataTemp.shareInstance.webSeriesHindi.removeAll()
|
||||
@@ -218,6 +232,7 @@ class MyListVM{
|
||||
guard let self else{return}
|
||||
self.refreshControl.endRefreshing()
|
||||
Utilities.dismissProgressHUD()
|
||||
self.startShimmer(load: false)
|
||||
checkNil()
|
||||
if MyListDataTemp.shareInstance.favListingData?.showData == nil {
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: FavouriteListingDM.ResultData.ShowData(hindi: [],english: []),videoData: [],gameData: [],singKaraokeData: [],audioData: [])
|
||||
|
||||
@@ -30,8 +30,15 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
|
||||
var audioPlayer = AVPlayer()
|
||||
|
||||
var videoID = Int()
|
||||
|
||||
var vm = JWKaraokePlayerVM()
|
||||
|
||||
deinit{
|
||||
NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self,name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
vm.vc = self
|
||||
@@ -43,7 +50,11 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
playerView.allowsPictureInPicturePlayback = false
|
||||
playerView.captionStyle = .none
|
||||
self.view.bringSubviewToFront(outerStack)
|
||||
self.view.bringSubviewToFront(backButton)
|
||||
self.view.bringSubviewToFront(backButton)
|
||||
|
||||
// Add observers
|
||||
NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil)
|
||||
NotificationCenter.default.addObserver(self,selector: #selector(appWillEnterForeground),name: UIApplication.willEnterForegroundNotification,object: nil)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@@ -129,7 +140,20 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
PersistentStorage.shared.addKaraokeCount(postID: postID)
|
||||
}
|
||||
self.player.stop()
|
||||
self.dismiss(animated: true)
|
||||
if let postID = vm.postID{
|
||||
Utilities.startProgressHUD(msg: "Syncing...")
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.karaokeVideo.rawValue, duration: duration, catID: 0) { isDone in
|
||||
if isDone{
|
||||
K.GVar.reloadContinueKaraoke = true
|
||||
Utilities.dismissProgressHUD()
|
||||
self.dismiss(animated: true)
|
||||
}else{
|
||||
Utilities.dismissProgressHUD()
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func retryBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
@@ -140,12 +164,35 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
vm.setupKaraoke()
|
||||
}
|
||||
|
||||
// MARK: - App LifeCycle HAndler
|
||||
|
||||
@objc func appDidEnterBackground() {
|
||||
//when app goes in background make a count
|
||||
vm.updateKaraokeVideoView()
|
||||
self.player.pause()
|
||||
|
||||
self.playBtn.isEnabled = false
|
||||
|
||||
if isRecording {
|
||||
vm.stopRecording()
|
||||
//make sure the interfacebehaviour is enabbled && updated the record btn title and image
|
||||
self.interfaceBehavior = .normal
|
||||
startRecordBtn.setTitle("Start Recording", for: .normal)
|
||||
isRecording = false
|
||||
}
|
||||
}
|
||||
|
||||
@objc func appWillEnterForeground() {
|
||||
//reset the start time
|
||||
vm.startTimeStamp = Date()
|
||||
self.player.play()
|
||||
}
|
||||
|
||||
// MARK: - JWPlayerViewControllerDelegate
|
||||
|
||||
override func jwplayer(_ player: any JWPlayer, didFinishLoadingWithTime loadTime: TimeInterval) {
|
||||
super.jwplayer(player, didFinishLoadingWithTime: loadTime)
|
||||
print("LoadTime", loadTime)
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
vm.setupKaraoke()
|
||||
@@ -241,6 +288,9 @@ extension JWKaraokePlayerVC {
|
||||
// self.setDeviceOrientation(orientation: .portrait)
|
||||
self.player.stop()
|
||||
self.dismiss(animated: true)
|
||||
|
||||
vm.updateKaraokeVideoView()
|
||||
|
||||
print("playerViewControllerWillGoFullScreen")
|
||||
return nil
|
||||
}
|
||||
@@ -257,13 +307,13 @@ extension JWKaraokePlayerVC {
|
||||
}
|
||||
|
||||
func playerViewControllerDidDismissFullScreen(_ controller: JWPlayerViewController) {
|
||||
print("playerViewControllerDidDismissFullScreen")
|
||||
|
||||
self.dismissTapped?()
|
||||
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
|
||||
self.player.stop()
|
||||
controller.dismiss(animated: true)
|
||||
}
|
||||
// print("playerViewControllerDidDismissFullScreen")
|
||||
//
|
||||
// self.dismissTapped?()
|
||||
// Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
|
||||
// self.player.stop()
|
||||
// controller.dismiss(animated: true)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,13 @@ class KaraokeListingVC: UIViewController {
|
||||
vm.updateTableHeight()
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
if K.GVar.reloadContinueKaraoke{
|
||||
K.GVar.reloadContinueKaraoke = false
|
||||
self.vm.getContinueWatching()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func loadMoreBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
PersistentStorage.shared.addOthersCount()
|
||||
loadMoreBtn.isHidden = true
|
||||
|
||||
@@ -26,7 +26,10 @@ class JWKaraokePlayerVM{
|
||||
var startTime : TimeInterval?
|
||||
var endTime : TimeInterval?
|
||||
|
||||
var startTimeStamp = Date()
|
||||
|
||||
func initView(){
|
||||
startTimeStamp = Date()
|
||||
vc.downloadRecordingBtn.isEnabled = false
|
||||
hideShowKaraoke(isLoading: true)
|
||||
}
|
||||
@@ -85,6 +88,19 @@ class JWKaraokePlayerVM{
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - App LifeCycle HAndler
|
||||
|
||||
func updateKaraokeVideoView(){
|
||||
if let postID {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: startTimeStamp, date2: Date())
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.karaokeVideo.rawValue, duration: duration, catID: 0) { isDone in
|
||||
if isDone{
|
||||
K.GVar.reloadContinueKaraoke = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - AudioRecording
|
||||
|
||||
func setupAudio() {
|
||||
|
||||
45
WOKA/Main/AuthFunc/AuthFuncUserVideoView.swift
Normal file
45
WOKA/Main/AuthFunc/AuthFuncUserVideoView.swift
Normal file
@@ -0,0 +1,45 @@
|
||||
//
|
||||
// AuthFuncUserVideoView.swift
|
||||
// WOKA
|
||||
//
|
||||
// Created by Bilal on 16/08/2024.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Alamofire
|
||||
|
||||
extension AuthFunc{
|
||||
|
||||
func userVideoView(postID : Int, postType : Int, duration : Int, catID : Int, onCompletion : @escaping (Bool) -> Void){
|
||||
let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken(),
|
||||
"device-id": AuthFunc.shareInstance.getDeviceUUID()]
|
||||
let params : Parameters = ["post_id" : postID,
|
||||
"post_type" : postType,
|
||||
"total_watched_duration" : duration,
|
||||
"device_type" : "2", //1- android, 2 - iOS
|
||||
"category_id": catID]
|
||||
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Analytics.user_video_view, method: .post,parameters: params,headers: headers) { (result : Result<CommonResponseModel, NetworkManager.APIError>) in
|
||||
switch result{
|
||||
case .success(let data):
|
||||
switch data.success{
|
||||
case 0:
|
||||
/*
|
||||
Error
|
||||
*/
|
||||
Utilities.dismissProgressHUD()
|
||||
onCompletion(false)
|
||||
case 1:
|
||||
Utilities.dismissProgressHUD()
|
||||
print("Updated PostType:- \(postType)")
|
||||
onCompletion(true)
|
||||
default:
|
||||
onCompletion(false)
|
||||
}
|
||||
case .failure(let error):
|
||||
Utilities.dismissProgressHUD()
|
||||
print(error)
|
||||
onCompletion(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,6 +144,7 @@ struct APIEndPoints {
|
||||
|
||||
struct Analytics{
|
||||
static let user_clicks = makeURL(path: "v2/user_clicks")
|
||||
static let user_video_view = makeURL(path: "user_video_view")
|
||||
}
|
||||
|
||||
// Helper method to construct full URL from base URL and path
|
||||
|
||||
@@ -15,7 +15,6 @@ import CoreData
|
||||
|
||||
enum PersistentStorageEnum : String{
|
||||
case UserClicks
|
||||
|
||||
case click_counts
|
||||
case category_id
|
||||
case post_id
|
||||
@@ -41,25 +40,6 @@ enum PostType: Int {
|
||||
case home = 16
|
||||
}
|
||||
|
||||
//enum PostType: String {
|
||||
// case series = "1"
|
||||
// case season = "2"
|
||||
// case episode = "3"
|
||||
// case video = "4"
|
||||
//// case paint = "5"
|
||||
// case game = "6"
|
||||
// case audio = "7"
|
||||
// case karaokeVideo = "8"
|
||||
// case shopProduct = "9"
|
||||
//// case parentalVideo = "10"
|
||||
//// case article = "11"
|
||||
// case liveTV = "12"
|
||||
// case FM = "13"
|
||||
// case teaser = "14"
|
||||
// case others = "15"
|
||||
// case home = "16"
|
||||
//}
|
||||
|
||||
struct UserClickData {
|
||||
let clickCounts: Int
|
||||
let categoryId: Int
|
||||
@@ -67,6 +47,13 @@ struct UserClickData {
|
||||
let postType: Int
|
||||
}
|
||||
|
||||
//struct UserVideoViewData {
|
||||
// let postId: Int
|
||||
// let postType: Int
|
||||
// let watchedDuration: Double
|
||||
// let categoryId: Int
|
||||
//}
|
||||
|
||||
final class PersistentStorage
|
||||
{
|
||||
|
||||
@@ -126,18 +113,18 @@ final class PersistentStorage
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: PersistentStorageEnum.UserClicks.rawValue)
|
||||
// fetchRequest.fetchLimit = 1
|
||||
// fetchRequest.predicate = NSPredicate(format: "id == %d" ,id)
|
||||
fetchRequest.predicate = NSPredicate(format: "\(key.rawValue) == %@" ,clicksData.postType.toString())
|
||||
fetchRequest.predicate = NSPredicate(format: "\(key.rawValue) == %@ AND post_id == %@" ,clicksData.postType.toString(),clicksData.postId.toString())
|
||||
|
||||
do {
|
||||
guard let result = try managedContext.fetch(fetchRequest) as? [UserClicks] else {return}
|
||||
if result.isEmpty{
|
||||
//create
|
||||
PersistentStorage.shared.createData(data: clicksData)
|
||||
print("create")
|
||||
print("create, In Exist")
|
||||
}else{
|
||||
//update
|
||||
let objectUpdate = result[0] as NSManagedObject
|
||||
print("Update")
|
||||
print("Update, In Exist")
|
||||
objectUpdate.setValue(result.first!.click_counts + Int64(clicksData.clickCounts), forKey: "click_counts")
|
||||
do{
|
||||
try managedContext.save()
|
||||
@@ -216,7 +203,7 @@ final class PersistentStorage
|
||||
//We need to create a context from this container
|
||||
let managedContext = PersistentStorage.shared.context
|
||||
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserClicks")
|
||||
fetchRequest.fetchLimit = 4
|
||||
fetchRequest.fetchLimit = 10
|
||||
do {
|
||||
guard let result = try managedContext.fetch(fetchRequest) as? [UserClicks] else {return}
|
||||
result.forEach { clicks in
|
||||
@@ -238,7 +225,7 @@ final class PersistentStorage
|
||||
// let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
|
||||
// debugPrint(path[0])
|
||||
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserClicks")
|
||||
fetchRequest.fetchLimit = 4
|
||||
fetchRequest.fetchLimit = 15
|
||||
do {
|
||||
guard let result = try managedContext.fetch(fetchRequest) as? [UserClicks] else {return}
|
||||
var userClicks = [ClicksAnalytics]()
|
||||
@@ -275,73 +262,8 @@ final class PersistentStorage
|
||||
debugPrint("Failed to delete data:", error)
|
||||
}
|
||||
}
|
||||
// func updateData(){
|
||||
// //We need to create a context from this container
|
||||
// let managedContext = PersistentStorage.shared.context
|
||||
//
|
||||
//
|
||||
// let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserClicks")
|
||||
// fetchRequest.predicate = NSPredicate(format: "uuid = %@", "2")
|
||||
// do
|
||||
// {
|
||||
// let test = try managedContext.fetch(fetchRequest)
|
||||
//
|
||||
// let objectUpdate = test[0] as! NSManagedObject
|
||||
// objectUpdate.setValue("Bilal Ahmed Khan New Name", forKey: "name")
|
||||
// do{
|
||||
// try managedContext.save()
|
||||
// self.retrieveData()
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// print(error)
|
||||
// }
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// print(error)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
// func deleteData(){
|
||||
// //We need to create a context from this container
|
||||
// let managedContext = PersistentStorage.shared.context
|
||||
//
|
||||
// let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "UserClicks")
|
||||
//// fetchRequest.fetchLimit = 1
|
||||
//// fetchRequest.predicate = NSPredicate(format: "uuid = %@ AND uuid = %@", "1", "1")
|
||||
// fetchRequest.predicate = NSPredicate(format: "post_id = %@", "11")
|
||||
//
|
||||
// do
|
||||
// {
|
||||
// let test = try managedContext.fetch(fetchRequest)
|
||||
//
|
||||
// let objectToDelete = test[0] as! NSManagedObject
|
||||
//// test.forEach { obbject in
|
||||
//// managedContext.delete(obbject as! NSManagedObject)
|
||||
//// }
|
||||
// managedContext.delete(test.first as! NSManagedObject)
|
||||
//// managedContext.delete(objectToDelete)
|
||||
//
|
||||
// do{
|
||||
// try managedContext.save()
|
||||
//// self.createData()
|
||||
// self.retrieveData()
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// print(error)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// print(error)
|
||||
// }
|
||||
// }
|
||||
|
||||
// MARK: - Handle Clicks
|
||||
// MARK: - Handle Clicks For UserClicks
|
||||
|
||||
func addOthersCount(){
|
||||
let userClicks = UserClickData(clickCounts: 1, categoryId: 0, postId: 0, postType: PostType.others.rawValue)
|
||||
@@ -389,4 +311,51 @@ final class PersistentStorage
|
||||
let userClicks = UserClickData(clickCounts: 1, categoryId: catID, postId: postID, postType: postType.rawValue)
|
||||
PersistentStorage.shared.checkWebSeries(clicksData: userClicks)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Handling UserViewView CRUD
|
||||
|
||||
// func createVideoViewData(data : UserVideoViewData){
|
||||
//
|
||||
// //We need to create a context from this container
|
||||
// let managedContext = PersistentStorage.shared.context
|
||||
//
|
||||
// let videoData = UserVideoView(context: managedContext)
|
||||
// videoData.post_id = Int64(data.postId)
|
||||
// videoData.post_type = Int64(data.postType)
|
||||
// videoData.total_watched_duration = data.watchedDuration
|
||||
// videoData.category_id = Int64(data.categoryId)
|
||||
//
|
||||
// do {
|
||||
// try managedContext.save()
|
||||
// retrieveData(postID: data.postId, catID: data.categoryId, postType: data.postType)
|
||||
// } catch let error as NSError {
|
||||
// print("Could not save. \(error), \(error.userInfo)")
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func retrieveVideoViewData(postID : Int?, catID : Int?, postType : Int) {
|
||||
//
|
||||
// //We need to create a context from this container
|
||||
// let managedContext = PersistentStorage.shared.context
|
||||
//
|
||||
// let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
|
||||
// // debugPrint(path[0])
|
||||
// let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "UserVideoView")
|
||||
//
|
||||
// fetchRequest.predicate = NSPredicate(format: "post_id == %@ AND category_id == %@ AND post_type == %@" ,postID?.toString() ?? "0", catID?.toString() ?? "0" ,postType.toString())
|
||||
//
|
||||
// do {
|
||||
// guard let result = try managedContext.fetch(fetchRequest) as? [UserClicks] else {return}
|
||||
// result.forEach { clicks in
|
||||
// print("VideoView:- ","ID:-" , PostType(rawValue: Int(clicks.post_type))!, "CatID:- ", clicks.category_id, "PostID:- ", clicks.post_id , "Count:-", clicks.click_counts)
|
||||
// }
|
||||
// }
|
||||
// catch let error
|
||||
// {
|
||||
// debugPrint(error)
|
||||
// }
|
||||
// }
|
||||
// MARK: - Handle Clicks For UserVideoView
|
||||
|
||||
}
|
||||
|
||||
@@ -1098,19 +1098,19 @@
|
||||
<cells/>
|
||||
</collectionView>
|
||||
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="Nqj-wh-mOZ">
|
||||
<rect key="frame" x="113.66666666666669" y="295.66666666666669" width="166" height="245.66666666666669"/>
|
||||
<rect key="frame" x="93.666666666666686" y="295.66666666666669" width="206" height="245.66666666666669"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SupportGirlImage" translatesAutoresizingMaskIntoConstraints="NO" id="aKI-uI-tys">
|
||||
<rect key="frame" x="0.0" y="0.0" width="166" height="166"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="206" height="166"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No Blogs Found" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="h4b-OB-vin" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="176" width="166" height="24"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="No Notification Found" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="h4b-OB-vin" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="176" width="206" height="24"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="JCl-tp-aCA">
|
||||
<rect key="frame" x="0.0" y="210" width="166" height="35.666666666666657"/>
|
||||
<rect key="frame" x="0.0" y="210" width="206" height="35.666666666666657"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<state key="normal" title="Button"/>
|
||||
<buttonConfiguration key="configuration" style="plain">
|
||||
@@ -1319,7 +1319,7 @@
|
||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</systemColor>
|
||||
<systemColor name="systemBrownColor">
|
||||
<color red="0.63529411759999999" green="0.51764705879999995" blue="0.36862745099999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.63529411764705879" green="0.51764705882352946" blue="0.36862745098039218" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</systemColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -41,7 +41,7 @@ class MoreVC: UIViewController {
|
||||
@IBAction func playTrailerBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
PersistentStorage.shared.addTrailerCount()
|
||||
let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila")
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer, videoIDs: [0])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,45 +256,45 @@ extension MoreVC : UICollectionViewDelegateFlowLayout{
|
||||
}
|
||||
|
||||
|
||||
class VideoAVPlayer {
|
||||
|
||||
var player: AVPlayer?
|
||||
var playerObserver: NSKeyValueObservation?
|
||||
var status = PlayerStatus.loading
|
||||
|
||||
init(url: URL) {
|
||||
self.player = AVPlayer(url: url)
|
||||
observePlayer()
|
||||
}
|
||||
|
||||
private func observePlayer() {
|
||||
playerObserver = player?.observe(\.timeControlStatus, options: [.new, .old], changeHandler: { [weak self] player, change in
|
||||
guard let self = self else { return }
|
||||
switch player.timeControlStatus {
|
||||
case .playing:
|
||||
print("Player is playing")
|
||||
self.status = .play
|
||||
case .paused:
|
||||
print("Player is paused")
|
||||
self.status = .pause
|
||||
case .waitingToPlayAtSpecifiedRate:
|
||||
print("Player is waiting to play at specified rate")
|
||||
self.status = .loading
|
||||
@unknown default:
|
||||
print("Unknown player status")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deinit {
|
||||
playerObserver?.invalidate()
|
||||
}
|
||||
|
||||
func play() {
|
||||
player?.play()
|
||||
}
|
||||
|
||||
func pause() {
|
||||
player?.pause()
|
||||
}
|
||||
}
|
||||
//class VideoAVPlayer {
|
||||
//
|
||||
// var player: AVPlayer?
|
||||
// var playerObserver: NSKeyValueObservation?
|
||||
// var status = PlayerStatus.loading
|
||||
//
|
||||
// init(url: URL) {
|
||||
// self.player = AVPlayer(url: url)
|
||||
// observePlayer()
|
||||
// }
|
||||
//
|
||||
// private func observePlayer() {
|
||||
// playerObserver = player?.observe(\.timeControlStatus, options: [.new, .old], changeHandler: { [weak self] player, change in
|
||||
// guard let self = self else { return }
|
||||
// switch player.timeControlStatus {
|
||||
// case .playing:
|
||||
// print("Player is playing")
|
||||
// self.status = .play
|
||||
// case .paused:
|
||||
// print("Player is paused")
|
||||
// self.status = .pause
|
||||
// case .waitingToPlayAtSpecifiedRate:
|
||||
// print("Player is waiting to play at specified rate")
|
||||
// self.status = .loading
|
||||
// @unknown default:
|
||||
// print("Unknown player status")
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
//
|
||||
// deinit {
|
||||
// playerObserver?.invalidate()
|
||||
// }
|
||||
//
|
||||
// func play() {
|
||||
// player?.play()
|
||||
// }
|
||||
//
|
||||
// func pause() {
|
||||
// player?.pause()
|
||||
// }
|
||||
//}
|
||||
|
||||
@@ -9,7 +9,7 @@ import UIKit
|
||||
import JWPlayerKit
|
||||
import AVKit
|
||||
|
||||
class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate{
|
||||
|
||||
@IBOutlet weak var backButton: UIButton!
|
||||
var previousScale: CGFloat = 1.0
|
||||
@@ -19,8 +19,17 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
var config: JWPlayerConfiguration!
|
||||
var dismissTapped: (() -> Void)?
|
||||
var videoIndex : Int?
|
||||
|
||||
|
||||
var isFullScreenBtn = false
|
||||
|
||||
var vm = PlayerVM()
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self,name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
}
|
||||
|
||||
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
|
||||
return .allButUpsideDown
|
||||
}
|
||||
@@ -31,40 +40,20 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
vm.vc = self
|
||||
vm.initView()
|
||||
// rotateView(to: .pi / 2) // Example: 90 degrees rotation
|
||||
//bring back button to the front
|
||||
self.view.bringSubviewToFront(backButton)
|
||||
// NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
// NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
}
|
||||
|
||||
// MARK: - Notification Center Handlers
|
||||
|
||||
@objc func appDidEnterBackground() {
|
||||
// Code to execute when the app enters the background
|
||||
print("App entered background PlayerVC")
|
||||
if UIApplication.topViewController() == self{
|
||||
player.stop()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func appWillEnterForeground() {
|
||||
// Code to execute when the app enters the foreground
|
||||
print("App will enter foreground PlayerVC")
|
||||
if UIApplication.topViewController() == self{
|
||||
player.play()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// func rotateView(to angle: CGFloat) {
|
||||
// // Apply rotation to the view's transform
|
||||
// view.transform = CGAffineTransform(rotationAngle: angle)
|
||||
// }
|
||||
|
||||
@objc func applicationDidBecomeActive() {
|
||||
// self.setDeviceOrientation(orientation: .landscapeRight)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
@@ -88,77 +77,147 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
}
|
||||
|
||||
@IBAction func backBtnTapped(_ sender: UIButton) {
|
||||
handleBackAction()
|
||||
}
|
||||
|
||||
func handleBackAction(){
|
||||
self.interfaceBehavior = .hidden
|
||||
self.player.stop()
|
||||
if contentType == .liveStream{
|
||||
self.dismissTapped?()
|
||||
}
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
updateClicks()
|
||||
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
}
|
||||
|
||||
func updateClicks(){
|
||||
switch contentType {
|
||||
case .liveStream:
|
||||
PersistentStorage.shared.addLiveTVCount()
|
||||
// case .webSeries:
|
||||
//// PersistentStorage.shared.addOthersCount()
|
||||
if let postID = vm.videoIDs.first {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + vm.totalVideoViewTime
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.liveTV.rawValue, duration: totalDuration, catID: 0) { _ in}
|
||||
vm.handleBackAction()
|
||||
}
|
||||
case .webSeries:
|
||||
if let catID = vm.catID, vm.currentPlayingIndex >= 0 && vm.currentPlayingIndex < (vm.videoIDs.count - 1) {
|
||||
let postID = vm.videoIDs[vm.currentPlayingIndex]
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + vm.totalVideoViewTime
|
||||
Utilities.startProgressHUD(msg: K.ConstantString.sync)
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.episode.rawValue, duration: totalDuration, catID: catID) { [weak self] isDone in
|
||||
guard let self else{return}
|
||||
if isDone{
|
||||
Utilities.dismissProgressHUD()
|
||||
vm.handleBackAction()
|
||||
K.GVar.reloadContinueWebSeries = true
|
||||
}else{
|
||||
Utilities.dismissProgressHUD()
|
||||
vm.handleBackAction()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vm.handleBackAction()
|
||||
}
|
||||
case .trailer:
|
||||
PersistentStorage.shared.addTrailerCount()
|
||||
// case .continueWatching:
|
||||
// <#code#>
|
||||
// case .audioBooks:
|
||||
// <#code#>
|
||||
// case .games:
|
||||
// <#code#>
|
||||
// case .songs:
|
||||
// <#code#>
|
||||
case nil:
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + vm.totalVideoViewTime
|
||||
AuthFunc.shareInstance.userVideoView(postID: 0, postType: PostType.episode.rawValue, duration: totalDuration, catID: 0) { _ in}
|
||||
vm.handleBackAction()
|
||||
case .continueWatching:
|
||||
if let catID = vm.catID,let postID = vm.videoIDs.first{
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + vm.totalVideoViewTime
|
||||
Utilities.startProgressHUD(msg: K.ConstantString.sync)
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.episode.rawValue, duration: totalDuration, catID: catID) { [weak self] isDone in
|
||||
guard let self else{return}
|
||||
if isDone{
|
||||
Utilities.dismissProgressHUD()
|
||||
vm.handleBackAction()
|
||||
K.GVar.reloadContinueWebSeries = true
|
||||
}else{
|
||||
Utilities.dismissProgressHUD()
|
||||
vm.handleBackAction()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vm.handleBackAction()
|
||||
}
|
||||
case .audioBooks:
|
||||
if let postID = vm.videoIDs.first {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + vm.totalVideoViewTime
|
||||
Utilities.startProgressHUD(msg: K.ConstantString.sync)
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.audio.rawValue, duration: totalDuration, catID: 0) { [weak self] isDone in
|
||||
guard let self else{
|
||||
Utilities.dismissProgressHUD()
|
||||
return
|
||||
}
|
||||
if isDone{
|
||||
Utilities.dismissProgressHUD()
|
||||
vm.handleBackAction()
|
||||
}else{
|
||||
Utilities.dismissProgressHUD()
|
||||
vm.handleBackAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
case .games:
|
||||
break
|
||||
case .songs:
|
||||
break
|
||||
default:
|
||||
vm.handleBackAction()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - App LifeCycle Handling
|
||||
|
||||
@objc func appDidEnterBackground() {
|
||||
print("App entered background PlayerVC")
|
||||
player.pause()
|
||||
|
||||
//Update uservideo view
|
||||
switch contentType {
|
||||
case .liveStream:
|
||||
vm.updateUserView()
|
||||
case .webSeries:
|
||||
vm.updateUserView()
|
||||
case .trailer:
|
||||
vm.updateUserView()
|
||||
case .continueWatching:
|
||||
vm.updateUserView()
|
||||
case .audioBooks:
|
||||
vm.updateUserView()
|
||||
case .games:
|
||||
break
|
||||
case .songs:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@objc func appWillEnterForeground() {
|
||||
print("App will enter foreground PlayerVC")
|
||||
|
||||
//Reset StartTimestamp
|
||||
vm.startTimeStamp = Date()
|
||||
|
||||
player.play()
|
||||
}
|
||||
|
||||
// MARK: - Handle Screen Transition
|
||||
|
||||
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
super.viewWillTransition(to: size, with: coordinator)
|
||||
|
||||
coordinator.animate(alongsideTransition: nil) { _ in
|
||||
self.checkOrientation()
|
||||
}
|
||||
}
|
||||
|
||||
private func checkOrientation() {
|
||||
let isPortrait = UIScreen.main.bounds.size.width < UIScreen.main.bounds.size.height
|
||||
if isPortrait {
|
||||
print("Device is in portrait mode")
|
||||
Timer.scheduledTimer(withTimeInterval: 0.4, repeats: false) { _ in
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
} else {
|
||||
print("Device is in landscape mode")
|
||||
if isFullScreenBtn{
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
}
|
||||
coordinator.animate(alongsideTransition: nil) { [weak self] _ in
|
||||
guard let self else{return}
|
||||
vm.checkOrientation()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - JWPlayerViewControllerDelegate
|
||||
|
||||
// override func jwplayerPlaylistHasCompleted(_ player: any JWPlayer) {
|
||||
// print("PlayList Over")
|
||||
// }
|
||||
|
||||
// this will give index
|
||||
override func jwplayer(_ player: any JWPlayer, didLoadPlaylistItem item: JWPlayerItem, at index: UInt) {
|
||||
super.jwplayer(player, didLoadPlaylistItem: item, at: index)
|
||||
print("didLoadPlaylistItem ", index)
|
||||
vm.currentPlayingIndex = Int(index)
|
||||
}
|
||||
|
||||
override func jwplayer(_ player: any JWPlayer, didFinishLoadingWithTime loadTime: TimeInterval) {
|
||||
super.jwplayer(player, didFinishLoadingWithTime: loadTime)
|
||||
print("LoadTime", loadTime)
|
||||
@@ -194,8 +253,6 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
case nil:
|
||||
break
|
||||
}
|
||||
|
||||
|
||||
print("IsReady")
|
||||
}
|
||||
|
||||
@@ -211,19 +268,19 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
DispatchQueue.main.async {
|
||||
Utilities.alertWithBtnCancelCompletion(title: "Error", msgBody: message, okBtnStr: "Connect", vc: self) { [weak self] isDone in
|
||||
guard let self else{
|
||||
self?.handleBackAction()
|
||||
self?.vm.handleBackAction()
|
||||
return
|
||||
}
|
||||
if isDone{
|
||||
self.player.configurePlayer(with: config)
|
||||
self.player.play()
|
||||
}else{
|
||||
self.handleBackAction()
|
||||
self.vm.handleBackAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override func jwplayer(_ player: JWPlayer, encounteredWarning code: UInt, message: String) {
|
||||
super.jwplayer(player, encounteredWarning: code, message: message)
|
||||
//Handle the reconnecting of video here
|
||||
@@ -250,7 +307,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
override func jwplayer(_ player: JWPlayer, didPauseWithReason reason: JWPauseReason) {
|
||||
super.jwplayer(player, didPauseWithReason: reason)
|
||||
if reason == .interaction{
|
||||
updateClicks()
|
||||
vm.updateClicks()
|
||||
}
|
||||
// Implement custom behavior
|
||||
}
|
||||
@@ -259,10 +316,10 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
override func jwplayer(_ player: JWPlayer, isPlayingWithReason reason: JWPlayReason) {
|
||||
super.jwplayer(player, isPlayingWithReason: reason)
|
||||
if reason == .interaction{
|
||||
updateClicks()
|
||||
vm.updateClicks()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Full Screen Handling
|
||||
@@ -289,13 +346,19 @@ extension PlayerVC {
|
||||
}
|
||||
|
||||
func playerViewControllerWillDismissFullScreen(_ controller: JWPlayerViewController) {
|
||||
switch contentType {
|
||||
case .audioBooks,.liveStream,.webSeries, .continueWatching, .trailer:
|
||||
vm.updateUserView()
|
||||
default:
|
||||
break
|
||||
}
|
||||
print("playerViewControllerWillDismissFullScreen")
|
||||
}
|
||||
|
||||
|
||||
func playerViewControllerDidDismissFullScreen(_ controller: JWPlayerViewController) {
|
||||
print("playerViewControllerDidDismissFullScreen")
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
updateClicks()
|
||||
vm.updateClicks()
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
@@ -327,7 +390,7 @@ extension PlayerVC {
|
||||
}
|
||||
|
||||
func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, relatedItemBeganPlaying item: JWPlayerKit.JWPlayerItem, atIndex index: Int, withMethod method: JWPlayerKit.JWRelatedMethod) {
|
||||
print("Item ", item)
|
||||
print("Item ", item, index)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -128,6 +128,8 @@ class ThemeOneVC: UIViewController {
|
||||
let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Home.userNotificationVC) as! UserNotificationVC
|
||||
self.navigationController?.pushViewController(vcPush, animated: true)
|
||||
|
||||
PersistentStorage.shared.sendDataToServer()
|
||||
}
|
||||
|
||||
@IBAction func radioBtnTapped(_ sender: UIButton) {
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFAudio
|
||||
|
||||
class ThemeTwoVC: UIViewController {
|
||||
|
||||
@@ -44,6 +45,9 @@ class ThemeTwoVC: UIViewController {
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
K.GVar.topView = .theme2
|
||||
if let player = vm.avPlayer{
|
||||
player.play()
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
@@ -72,7 +76,7 @@ class ThemeTwoVC: UIViewController {
|
||||
@IBAction func playTrailer(_ sender: LocalisedElementsButton) {
|
||||
PersistentStorage.shared.addOthersCount()
|
||||
let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila")
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer, videoIDs: [0])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +41,12 @@ class MoreVM{
|
||||
vc.songTableView.showsVerticalScrollIndicator = false
|
||||
vc.songTableView.showsHorizontalScrollIndicator = false
|
||||
|
||||
vc.homeBtn.addTapGesture {
|
||||
self.vc.dismiss(animated: true) {
|
||||
PersistentStorage.shared.addOthersCount()
|
||||
vc.homeBtn.addTapGesture { [weak self] in
|
||||
guard let self else{return}
|
||||
DispatchQueue.main.async{
|
||||
self.vc.dismiss(animated: true) {
|
||||
PersistentStorage.shared.addOthersCount()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
172
WOKA/Theme/ViewModel/PlayerVM.swift
Normal file
172
WOKA/Theme/ViewModel/PlayerVM.swift
Normal file
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// PlayerVM.swift
|
||||
// WOKA
|
||||
//
|
||||
// Created by Bilal on 16/08/2024.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PlayerVM{
|
||||
|
||||
weak var vc : PlayerVC!
|
||||
|
||||
// this will map the start time
|
||||
var startTimeStamp = Date()
|
||||
var totalVideoViewTime = 0
|
||||
|
||||
// this will come from webseries, audiobooks, live tv
|
||||
var videoIDs = [Int]()
|
||||
|
||||
// this will come only for webseries
|
||||
var catID : Int?
|
||||
|
||||
// this will store the index of the item playing
|
||||
var currentPlayingIndex = 0
|
||||
|
||||
func initView(){
|
||||
switch vc.contentType {
|
||||
case .liveStream, .trailer, .continueWatching, .audioBooks:
|
||||
startTimeStamp = Date()
|
||||
// case .games:
|
||||
// <#code#>
|
||||
// case .songs:
|
||||
// <#code#>
|
||||
case nil:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Update UserVideo View
|
||||
|
||||
func updateUserView(){
|
||||
switch vc.contentType {
|
||||
case .liveStream:
|
||||
if let postID = videoIDs.first {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + totalVideoViewTime
|
||||
startTimeStamp = Date()
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.liveTV.rawValue, duration: totalDuration, catID: 0) { isDone in
|
||||
if isDone{
|
||||
K.GVar.reloadContinueAudioBooks = true
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
case .webSeries:
|
||||
if let catID = catID, currentPlayingIndex >= 0 && currentPlayingIndex < (videoIDs.count - 1) {
|
||||
let postID = videoIDs[currentPlayingIndex]
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + totalVideoViewTime
|
||||
startTimeStamp = Date()
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.episode.rawValue, duration: totalDuration, catID: catID) { isDone in
|
||||
if isDone{
|
||||
K.GVar.reloadContinueWebSeries = true
|
||||
}
|
||||
}
|
||||
}
|
||||
case .trailer:
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + totalVideoViewTime
|
||||
AuthFunc.shareInstance.userVideoView(postID: 0, postType: PostType.episode.rawValue, duration: totalDuration, catID: 0) { _ in}
|
||||
case .continueWatching:
|
||||
if let catID = catID , let postID = videoIDs.first{
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + totalVideoViewTime
|
||||
startTimeStamp = Date()
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.episode.rawValue, duration: totalDuration, catID: catID) { isDone in
|
||||
if isDone{
|
||||
K.GVar.reloadContinueWebSeries = true
|
||||
}
|
||||
}
|
||||
}
|
||||
case .audioBooks:
|
||||
if let postID = videoIDs.first {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: startTimeStamp, date2: Date())
|
||||
let totalDuration = duration + totalVideoViewTime
|
||||
startTimeStamp = Date()
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.audio.rawValue, duration: totalDuration, catID: 0) { isDone in
|
||||
if isDone{
|
||||
K.GVar.reloadContinueAudioBooks = true
|
||||
}else{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
// case .games:
|
||||
// <#code#>
|
||||
// case .songs:
|
||||
// <#code#>
|
||||
case nil:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Handle Back btn tap, and update clicks
|
||||
|
||||
func handleBackAction(){
|
||||
self.vc.interfaceBehavior = .hidden
|
||||
self.vc.player.stop()
|
||||
if vc.contentType == .liveStream{
|
||||
self.vc.dismissTapped?()
|
||||
}
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
updateClicks()
|
||||
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
}
|
||||
|
||||
func updateClicks(){
|
||||
switch vc.contentType {
|
||||
case .liveStream:
|
||||
PersistentStorage.shared.addLiveTVCount()
|
||||
// case .webSeries:
|
||||
//// PersistentStorage.shared.addOthersCount()
|
||||
case .trailer:
|
||||
PersistentStorage.shared.addTrailerCount()
|
||||
// case .continueWatching:
|
||||
// <#code#>
|
||||
// case .audioBooks:
|
||||
// <#code#>
|
||||
// case .games:
|
||||
// <#code#>
|
||||
// case .songs:
|
||||
// <#code#>
|
||||
case nil:
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Orientation check
|
||||
|
||||
func checkOrientation() {
|
||||
let isPortrait = UIScreen.main.bounds.size.width < UIScreen.main.bounds.size.height
|
||||
if isPortrait {
|
||||
print("Device is in portrait mode")
|
||||
Timer.scheduledTimer(withTimeInterval: 0.4, repeats: false) { _ in
|
||||
self.vc.dismiss(animated: true)
|
||||
}
|
||||
} else {
|
||||
print("Device is in landscape mode")
|
||||
if vc.isFullScreenBtn{
|
||||
appDelegate.deviceOrientation = .portrait
|
||||
|
||||
let value = UIInterfaceOrientation.portrait.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
UIViewController.attemptRotationToDeviceOrientation()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -205,8 +205,6 @@ class ThemeOneVM{
|
||||
vcPush.modalPresentationStyle = .fullScreen
|
||||
vcPush.modalTransitionStyle = .crossDissolve
|
||||
self.vc.present(vcPush, animated: true)
|
||||
|
||||
// PersistentStorage.shared.sendDataToServer()
|
||||
}
|
||||
/*
|
||||
1 = series, 2 = season, 3= episode, 4 = video, 5 = paint, 6 = game, 7 = audio, 8 = kareoke video, 9 = shop product, 10 = parental video, 11 = article, 12 = live TV, 13 = FM, 14 = teaser, 15 others, 16 = Home
|
||||
@@ -441,6 +439,9 @@ class ThemeOneVM{
|
||||
vc.config = config
|
||||
vc.dismissTapped = self.tapped
|
||||
vc.contentType = .liveStream
|
||||
if let streamID = AuthFunc.shareInstance.staticURLs?.liveData?.first?.id{
|
||||
vc.vm.videoIDs = [streamID]
|
||||
}
|
||||
vc.modalPresentationStyle = .fullScreen
|
||||
vc.modalTransitionStyle = .crossDissolve
|
||||
|
||||
|
||||
@@ -19,13 +19,45 @@ class WokaFMVC: UIViewController {
|
||||
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
|
||||
|
||||
var vm = WokaFMVM()
|
||||
|
||||
deinit {
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "status")
|
||||
vm.player.removeObserver(self, forKeyPath: "timeControlStatus")
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty")
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp")
|
||||
|
||||
vm.player?.pause()
|
||||
NotificationCenter.default.removeObserver(self,name: UIApplication.didEnterBackgroundNotification, object: nil)
|
||||
|
||||
// Deactivate the audio session if needed
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
|
||||
} catch {
|
||||
print("Failed to deactivate audio session: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
vm.vc = self
|
||||
vm.initView()
|
||||
NotificationCenter.default.addObserver(self,selector: #selector(appDidEnterBackground),name: UIApplication.didEnterBackgroundNotification,object: nil)
|
||||
}
|
||||
|
||||
// MARK: - App LifeCycle HAndler
|
||||
|
||||
@objc func appDidEnterBackground() {
|
||||
if let postID = AuthFunc.shareInstance.staticURLs?.liveFmData?.id {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.FM.rawValue, duration: duration, catID: 0) { [weak self] isDone in
|
||||
guard let self else{return}
|
||||
if isDone{
|
||||
vm.startTimeStamp = Date()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func playBtnTapped(_ sender: UIButton) {
|
||||
PersistentStorage.shared.addRadioCount()
|
||||
if sender == playBtn{
|
||||
@@ -71,6 +103,10 @@ class WokaFMVC: UIViewController {
|
||||
|
||||
@IBAction func closeBtnTapped(_ sender: UIButton) {
|
||||
PersistentStorage.shared.addRadioCount()
|
||||
if let postID = AuthFunc.shareInstance.staticURLs?.liveFmData?.id {
|
||||
let duration = DateFormatterLib.dateDifferenceINT(date1: vm.startTimeStamp, date2: Date())
|
||||
AuthFunc.shareInstance.userVideoView(postID: postID, postType: PostType.FM.rawValue, duration: duration, catID: 0) { _ in}
|
||||
}
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
|
||||
@@ -151,22 +187,6 @@ class WokaFMVC: UIViewController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deinit {
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "status")
|
||||
vm.player.removeObserver(self, forKeyPath: "timeControlStatus")
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty")
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp")
|
||||
|
||||
vm.player?.pause()
|
||||
|
||||
// Deactivate the audio session if needed
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
|
||||
} catch {
|
||||
print("Failed to deactivate audio session: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@ class WokaFMVM{
|
||||
var player: AVPlayer!
|
||||
var playerItem: AVPlayerItem!
|
||||
|
||||
var startTimeStamp = Date()
|
||||
|
||||
func initView(){
|
||||
startTimeStamp = Date()
|
||||
vc.mainView.roundCorners(radius: 10, corners: [.topLeft, .topRight])
|
||||
let color1 = #colorLiteral(red: 0.5921568627, green: 0.2588235294, blue: 0.8941176471, alpha: 1)
|
||||
let color2 = #colorLiteral(red: 0.368627451, green: 0.1215686275, blue: 0.768627451, alpha: 1)
|
||||
|
||||
@@ -81,7 +81,6 @@
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" image="speaker.wave.1.fill" catalog="system"/>
|
||||
<connections>
|
||||
<action selector="playBtnTapped:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="YJE-XF-HOm"/>
|
||||
<action selector="volumeBtnTapped:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="bZA-9P-p0X"/>
|
||||
</connections>
|
||||
</button>
|
||||
|
||||
@@ -64,8 +64,8 @@ class ContinueWatchingVC: UIViewController {
|
||||
}
|
||||
|
||||
@IBAction func watchBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
guard let watchData else{return}
|
||||
if let showID = watchData.id, let catID = self.categoryID{
|
||||
guard let watchData ,let showID = watchData.id else{return}
|
||||
if let catID = self.categoryID{
|
||||
PersistentStorage.shared.addWebSeries(catID: catID, postID: showID, postType: .episode)
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class ContinueWatchingVC: UIViewController {
|
||||
playerItem.url = url
|
||||
}
|
||||
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [playerItem], startIndex: 0, contentType: .continueWatching)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [playerItem], startIndex: 0, contentType: .continueWatching,videoIDs: [showID], catID: categoryID)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ class WebSeriesSeasonVC: UIViewController {
|
||||
playerItems.append(JwPlayerItemCreate(url: url, poster: seasonData.thumbnailPath, titles: hindiData.title))
|
||||
}
|
||||
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: 0, contentType: .trailer)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: 0, contentType: .trailer, videoIDs: [0])
|
||||
}
|
||||
|
||||
@IBAction func loadMoreBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
@@ -186,53 +186,7 @@ extension WebSeriesSeasonVC : TableViewSRC{
|
||||
playerItems.append(JwPlayerItemCreate(url: url, poster: teaserData.thumbnailPath, titles: hindiData.title))
|
||||
}
|
||||
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: indexPath.row, contentType: .trailer)
|
||||
|
||||
// let builder = JWPlayerConfigurationBuilder()
|
||||
//
|
||||
// do {
|
||||
// let playlist: [JSONObject] = [
|
||||
// [
|
||||
// "file": "https://cdn.jwplayer.com/manifests/gzIo9zlJ.m3u8",
|
||||
// "title": "First Video Title"
|
||||
// ],
|
||||
// [
|
||||
// "file": "https://cdn.jwplayer.com/manifests/pDu0xxUh.m3u8", // replace with the second video URL
|
||||
// "title": "Second Video Title",
|
||||
//
|
||||
// ]
|
||||
// ]
|
||||
//
|
||||
// let json: JSONObject = [
|
||||
// "playlist": playlist,
|
||||
// "playlistIndex": 1,
|
||||
// "videoGravity" : "resize"
|
||||
// ]
|
||||
//
|
||||
// try builder.configuration(json: json).build()
|
||||
//
|
||||
// let config = try builder.configuration(json: json).build()
|
||||
// let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
|
||||
// let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC
|
||||
//
|
||||
// vc.config = config
|
||||
// vc.contentType = .liveStream
|
||||
// vc.modalPresentationStyle = .fullScreen
|
||||
// vc.modalTransitionStyle = .crossDissolve
|
||||
//
|
||||
// DispatchQueue.main.async { [weak self] in
|
||||
// guard let self else{return}
|
||||
// // Present the PlayerVC
|
||||
// self.present(vc, animated: false) { [weak self] in
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//// player.configurePlayer(with: config)
|
||||
// } catch {
|
||||
// // Handle build errors
|
||||
// print("Failed to build JWPlayer configuration: \(error.localizedDescription)")
|
||||
// }
|
||||
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: indexPath.row, contentType: .trailer, videoIDs: [0])
|
||||
case self.episodeTableView:
|
||||
|
||||
let episodeData = vm.seasonEpisodeData
|
||||
@@ -240,10 +194,15 @@ extension WebSeriesSeasonVC : TableViewSRC{
|
||||
if let showID = episodeData[indexPath.row].id, let catID = self.vm.categoryID{
|
||||
PersistentStorage.shared.addWebSeries(catID: catID, postID: showID, postType: .episode)
|
||||
}
|
||||
var videoIDs = [Int]()
|
||||
|
||||
for i in episodeData{
|
||||
var url = String()
|
||||
guard let englishData = i.contentMoreDetails?.filter({$0.languageMasterID == 1}).first, let hindiData = i.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return}
|
||||
|
||||
if let id = i.id{
|
||||
videoIDs.append(id)
|
||||
}
|
||||
/*
|
||||
Based on selected Category language update the url
|
||||
*/
|
||||
@@ -263,7 +222,7 @@ extension WebSeriesSeasonVC : TableViewSRC{
|
||||
}
|
||||
}
|
||||
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: indexPath.row, contentType: .webSeries)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: indexPath.row, contentType: .webSeries, videoIDs: videoIDs, catID: vm.categoryID)
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -317,11 +276,16 @@ extension WebSeriesSeasonVC : TableViewSRC{
|
||||
}else{
|
||||
playerItems.append(JwPlayerItemCreate(url: url, poster: teaserData.thumbnailPath, titles: hindiData.title))
|
||||
}
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems,startIndex: indexPath.row, contentType: .trailer)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems,startIndex: indexPath.row, contentType: .trailer, videoIDs: [0])
|
||||
case self.episodeTableView:
|
||||
let episodeData = vm.seasonEpisodeData
|
||||
var videoIDs = [Int]()
|
||||
for i in episodeData{
|
||||
var url = String()
|
||||
if let id = i.id{
|
||||
videoIDs.append(id)
|
||||
}
|
||||
|
||||
guard let englishData = i.contentMoreDetails?.filter({$0.languageMasterID == 1}).first, let hindiData = i.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return}
|
||||
/*
|
||||
Based on selected Category language update the url
|
||||
@@ -342,7 +306,7 @@ extension WebSeriesSeasonVC : TableViewSRC{
|
||||
}
|
||||
}
|
||||
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: indexPath.row, contentType: .webSeries)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: indexPath.row, contentType: .webSeries, videoIDs: videoIDs,catID: vm.categoryID)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -38,6 +38,8 @@ class WebSeriesVC: UIViewController {
|
||||
|
||||
var vm = WebSeriesVM()
|
||||
|
||||
private var isFirstLoad = true
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
vm.vc = self
|
||||
@@ -45,6 +47,8 @@ class WebSeriesVC: UIViewController {
|
||||
vm.initView()
|
||||
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
|
||||
navigationController?.navigationBar.shadowImage = UIImage()
|
||||
|
||||
isFirstLoad = false
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@@ -70,6 +74,19 @@ class WebSeriesVC: UIViewController {
|
||||
self.navigationController?.setColor(color: .black)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
if !isFirstLoad{
|
||||
if K.GVar.reloadContinueWebSeries{
|
||||
K.GVar.reloadContinueWebSeries = false
|
||||
vm.getContinueWatching()
|
||||
}
|
||||
}else{
|
||||
K.GVar.reloadContinueWebSeries = false
|
||||
}
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
vm.updateTableHeight()
|
||||
@@ -78,7 +95,7 @@ class WebSeriesVC: UIViewController {
|
||||
// MARK: - Tap Handler
|
||||
@IBAction func playTrailer(_ sender: LocalisedElementsButton) {
|
||||
let item = JwPlayerItemCreate(url: APIEndPoints.StaticURLs.masilaUrl, poster: nil, titles: "Masila")
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer)
|
||||
JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer, videoIDs: [0])
|
||||
PersistentStorage.shared.addTrailerCount()
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class JWPlayerManager {
|
||||
|
||||
private init() {}
|
||||
|
||||
func presentPlayer(from viewController: UIViewController,playerItems : [JwPlayerItemCreate], startIndex: Int = 0, contentType : VideoContentType , completion: (() -> Void)? = nil) {
|
||||
func presentPlayer(from viewController: UIViewController,playerItems : [JwPlayerItemCreate], startIndex: Int = 0, contentType : VideoContentType , videoIDs : [Int],catID : Int? = nil, completion: (() -> Void)? = nil) {
|
||||
|
||||
let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
|
||||
let playerVC = sb.instantiateViewController(identifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC
|
||||
@@ -133,7 +133,8 @@ class JWPlayerManager {
|
||||
playerVC.videoIndex = startIndex
|
||||
playerVC.contentType = contentType
|
||||
playerVC.config = finalConfig
|
||||
|
||||
playerVC.vm.videoIDs = videoIDs
|
||||
playerVC.vm.catID = catID
|
||||
playerVC.modalPresentationStyle = .fullScreen
|
||||
playerVC.modalTransitionStyle = .crossDissolve
|
||||
// Present the PlayerVC
|
||||
|
||||
Reference in New Issue
Block a user