- Added no data and error handling in my orderdetails
- added lazy loading in myorders - finalised karaoke with new key - handled failure to show retry btn in karaoke - made mylist view all, with api call, modified the api which will display all kind of data. - made a common module for above
This commit is contained in:
@@ -147,7 +147,6 @@
|
||||
52ACC1252C610CBC00791528 /* UserClicks+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1232C610CBC00791528 /* UserClicks+CoreDataClass.swift */; };
|
||||
52ACC1262C610CBC00791528 /* UserClicks+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1242C610CBC00791528 /* UserClicks+CoreDataProperties.swift */; };
|
||||
52ACC12A2C610EC900791528 /* PersistentStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1292C610EC900791528 /* PersistentStorage.swift */; };
|
||||
52ACC12D2C63479300791528 /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC12B2C63479300791528 /* WOKA.xcdatamodeld */; };
|
||||
52ACC1302C639DBA00791528 /* MyOrderCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC12E2C639DBA00791528 /* MyOrderCell.swift */; };
|
||||
52ACC1312C639DBA00791528 /* MyOrderCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 52ACC12F2C639DBA00791528 /* MyOrderCell.xib */; };
|
||||
52ACC1332C639F3800791528 /* OrderListingDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52ACC1322C639F3800791528 /* OrderListingDM.swift */; };
|
||||
@@ -308,6 +307,8 @@
|
||||
9C85A9F32C5CE1060031C365 /* FirebasePerformance in Frameworks */ = {isa = PBXBuildFile; productRef = 9C85A9F22C5CE1060031C365 /* FirebasePerformance */; };
|
||||
9C8C4FAE2C1315410017DD3B /* WebViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8C4FAD2C1315410017DD3B /* WebViewVC.swift */; };
|
||||
9C8C4FB02C1328060017DD3B /* Disclaimer.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9C8C4FAF2C1328060017DD3B /* Disclaimer.rtf */; };
|
||||
9C9BE46C2C65DF2A00C48D6A /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9C9BE46A2C65DF2A00C48D6A /* WOKA.xcdatamodeld */; };
|
||||
9C9BE46E2C663B1600C48D6A /* JWKaraokePlayerVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C9BE46D2C663B1600C48D6A /* JWKaraokePlayerVM.swift */; };
|
||||
9C9BEEC72BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C9BEEC62BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift */; };
|
||||
9CA7C6C02C1093E500D73742 /* ProfileVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CA7C6BF2C1093E500D73742 /* ProfileVC.swift */; };
|
||||
9CA7C6C22C1095B600D73742 /* ProfileVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CA7C6C12C1095B600D73742 /* ProfileVM.swift */; };
|
||||
@@ -511,7 +512,6 @@
|
||||
52ACC1232C610CBC00791528 /* UserClicks+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserClicks+CoreDataClass.swift"; sourceTree = SOURCE_ROOT; };
|
||||
52ACC1242C610CBC00791528 /* UserClicks+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserClicks+CoreDataProperties.swift"; sourceTree = SOURCE_ROOT; };
|
||||
52ACC1292C610EC900791528 /* PersistentStorage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistentStorage.swift; sourceTree = "<group>"; };
|
||||
52ACC12C2C63479300791528 /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = "<group>"; };
|
||||
52ACC12E2C639DBA00791528 /* MyOrderCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyOrderCell.swift; sourceTree = "<group>"; };
|
||||
52ACC12F2C639DBA00791528 /* MyOrderCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyOrderCell.xib; sourceTree = "<group>"; };
|
||||
52ACC1322C639F3800791528 /* OrderListingDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderListingDM.swift; sourceTree = "<group>"; };
|
||||
@@ -662,6 +662,8 @@
|
||||
9C85A9EB2C5CD5CD0031C365 /* MyListDataTemp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyListDataTemp.swift; sourceTree = "<group>"; };
|
||||
9C8C4FAD2C1315410017DD3B /* WebViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewVC.swift; sourceTree = "<group>"; };
|
||||
9C8C4FAF2C1328060017DD3B /* Disclaimer.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Disclaimer.rtf; sourceTree = "<group>"; };
|
||||
9C9BE46B2C65DF2A00C48D6A /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = "<group>"; };
|
||||
9C9BE46D2C663B1600C48D6A /* JWKaraokePlayerVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWKaraokePlayerVM.swift; sourceTree = "<group>"; };
|
||||
9C9BEEC62BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCenteredFlowLayout.swift; sourceTree = "<group>"; };
|
||||
9CA7C6BF2C1093E500D73742 /* ProfileVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileVC.swift; sourceTree = "<group>"; };
|
||||
9CA7C6C12C1095B600D73742 /* ProfileVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileVM.swift; sourceTree = "<group>"; };
|
||||
@@ -886,7 +888,7 @@
|
||||
9C535DC82C00C34000DA6DCD /* Theme */,
|
||||
52DAC6462C21761700E2F85B /* WebSeries */,
|
||||
9C834ED92C1C20EC00B29A9C /* WOKA.entitlements */,
|
||||
52ACC12B2C63479300791528 /* WOKA.xcdatamodeld */,
|
||||
9C9BE46A2C65DF2A00C48D6A /* WOKA.xcdatamodeld */,
|
||||
52ACC1292C610EC900791528 /* PersistentStorage.swift */,
|
||||
);
|
||||
path = WOKA;
|
||||
@@ -1801,6 +1803,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
9CB3D08C2C37CDD50062869D /* KaraokeListingVM.swift */,
|
||||
9C9BE46D2C663B1600C48D6A /* JWKaraokePlayerVM.swift */,
|
||||
);
|
||||
path = ViewModel;
|
||||
sourceTree = "<group>";
|
||||
@@ -2270,7 +2273,6 @@
|
||||
52A6DCBC2C4EA46400F63C51 /* ShopProductsCell.swift in Sources */,
|
||||
528BEF602C2C372900FFDAB8 /* ContinueWatchingVC.swift in Sources */,
|
||||
9CBCB29B2BE4D614007D7934 /* LoginVC.swift in Sources */,
|
||||
52ACC12D2C63479300791528 /* WOKA.xcdatamodeld in Sources */,
|
||||
52BC3BE82C0E04A9002FACA6 /* FaqListDM.swift in Sources */,
|
||||
9C56E83B2BDBC6E600E4CA14 /* SelectAgeVM.swift in Sources */,
|
||||
9C535DC02C00B36000DA6DCD /* HomeVC.swift in Sources */,
|
||||
@@ -2377,6 +2379,7 @@
|
||||
52C8B05F2BDA5AFA003B51D0 /* SplashVM.swift in Sources */,
|
||||
52C1A4E12C05B69F007BAA50 /* UIApplicationSwitchRoot.swift in Sources */,
|
||||
527A2BCC2C577F8A0080DF9B /* AnalyticsEventKeys.swift in Sources */,
|
||||
9C9BE46C2C65DF2A00C48D6A /* WOKA.xcdatamodeld in Sources */,
|
||||
52663FF72BDFACF60001D8CE /* ShadowView.swift in Sources */,
|
||||
522D65602C1ACD8D0021E505 /* UserNotificationVC.swift in Sources */,
|
||||
52AC2D252C295A7900337473 /* TeaserDM.swift in Sources */,
|
||||
@@ -2385,6 +2388,7 @@
|
||||
9CB3D0912C37D6930062869D /* KaraokeDetailsVC.swift in Sources */,
|
||||
52E214C72C2AD47F00BC2D29 /* EpisodeDetailsVC.swift in Sources */,
|
||||
52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */,
|
||||
9C9BE46E2C663B1600C48D6A /* JWKaraokePlayerVM.swift in Sources */,
|
||||
9CBE1B3F2C0F37B300CA6E61 /* DPDConstants.swift in Sources */,
|
||||
9CDAEB102C53F12800890C47 /* SwiftyInnerShadowLayer.swift in Sources */,
|
||||
52A6DCA42C4E48AF00F63C51 /* ShopSuperCategoryDM.swift in Sources */,
|
||||
@@ -2875,14 +2879,14 @@
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
||||
/* Begin XCVersionGroup section */
|
||||
52ACC12B2C63479300791528 /* WOKA.xcdatamodeld */ = {
|
||||
9C9BE46A2C65DF2A00C48D6A /* WOKA.xcdatamodeld */ = {
|
||||
isa = XCVersionGroup;
|
||||
children = (
|
||||
52ACC12C2C63479300791528 /* WOKA.xcdatamodel */,
|
||||
9C9BE46B2C65DF2A00C48D6A /* WOKA.xcdatamodel */,
|
||||
);
|
||||
currentVersion = 52ACC12C2C63479300791528 /* WOKA.xcdatamodel */;
|
||||
currentVersion = 9C9BE46B2C65DF2A00C48D6A /* 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;
|
||||
};
|
||||
|
||||
@@ -151,7 +151,8 @@ extension AudioBookHomeVC : TableViewSRC{
|
||||
cell.stopShimmer()
|
||||
}
|
||||
|
||||
cell.btnTapped = { [self] (type) -> Void in
|
||||
cell.btnTapped = { [weak self] (type) -> Void in
|
||||
guard let self else{return}
|
||||
let data = vm.audioListData[indexPath.row]
|
||||
guard let postID = data.id ,let postType = data.contentMoreDetails?.first?.postType else{return}
|
||||
let isFav = data.markAsFavourite
|
||||
|
||||
@@ -195,13 +195,14 @@ class AudioBookHomeVM{
|
||||
audioListData[showListIndex].markAsFavourite = false
|
||||
vc.audioListingTableView.reloadRows(at: [IndexPath(row: showListIndex, section: 0)],with: .none)
|
||||
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
if let indexRemove = MyListDataTemp.shareInstance.favListingData?.audioData?.firstIndex(where: {$0.id == postID}){
|
||||
MyListDataTemp.shareInstance.favListingData?.audioData?.remove(at: indexRemove)
|
||||
K.GVar.myListSoftReload = true
|
||||
}
|
||||
}
|
||||
K.GVar.reloadMyList = true
|
||||
// // MyList Update
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// if let indexRemove = MyListDataTemp.shareInstance.favListingData?.audioData?.firstIndex(where: {$0.id == postID}){
|
||||
// MyListDataTemp.shareInstance.favListingData?.audioData?.remove(at: indexRemove)
|
||||
// K.GVar.myListSoftReload = true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -210,14 +211,14 @@ class AudioBookHomeVM{
|
||||
if let continueWatchingIndex = continueWatchingData.firstIndex(where: { $0.id == postID }){
|
||||
continueWatchingData[continueWatchingIndex].markAsFavourite = false
|
||||
vc.continueWatchingCV.reloadItems(at: [IndexPath(row: continueWatchingIndex, section: 0)])
|
||||
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
if let indexRemove = MyListDataTemp.shareInstance.favListingData?.audioData?.firstIndex(where: {$0.id == postID}){
|
||||
MyListDataTemp.shareInstance.favListingData?.audioData?.remove(at: indexRemove)
|
||||
K.GVar.myListSoftReload = true
|
||||
}
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// if let indexRemove = MyListDataTemp.shareInstance.favListingData?.audioData?.firstIndex(where: {$0.id == postID}){
|
||||
// MyListDataTemp.shareInstance.favListingData?.audioData?.remove(at: indexRemove)
|
||||
// K.GVar.myListSoftReload = true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,13 +228,13 @@ class AudioBookHomeVM{
|
||||
if let showListIndex = audioListData.firstIndex(where: { $0.id == postID }){
|
||||
audioListData[showListIndex].markAsFavourite = true
|
||||
vc.audioListingTableView.reloadRows(at: [IndexPath(row: showListIndex, section: 0)],with: .none)
|
||||
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
let audioData = audioListData[showListIndex]
|
||||
MyListDataTemp.shareInstance.favListingData?.audioData?.append(audioData)
|
||||
K.GVar.myListSoftReload = true
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// let audioData = audioListData[showListIndex]
|
||||
// MyListDataTemp.shareInstance.favListingData?.audioData?.append(audioData)
|
||||
// K.GVar.myListSoftReload = true
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -242,15 +243,15 @@ class AudioBookHomeVM{
|
||||
if let continueWatchingIndex = continueWatchingData.firstIndex(where: { $0.id == postID }){
|
||||
continueWatchingData[continueWatchingIndex].markAsFavourite = true
|
||||
vc.continueWatchingCV.reloadItems(at: [IndexPath(row: continueWatchingIndex, section: 0)])
|
||||
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
if MyListDataTemp.shareInstance.favListingData?.audioData?.firstIndex(where: {$0.id == postID}) == nil{
|
||||
let audioData = continueWatchingData[continueWatchingIndex]
|
||||
MyListDataTemp.shareInstance.favListingData?.audioData?.append(audioData)
|
||||
K.GVar.myListSoftReload = true
|
||||
}
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// if MyListDataTemp.shareInstance.favListingData?.audioData?.firstIndex(where: {$0.id == postID}) == nil{
|
||||
// let audioData = continueWatchingData[continueWatchingIndex]
|
||||
// MyListDataTemp.shareInstance.favListingData?.audioData?.append(audioData)
|
||||
// K.GVar.myListSoftReload = true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,9 +13,7 @@ class GamesListVM{
|
||||
weak var vc : GamesListVC!
|
||||
var gameData = [GamesListDM.GameDatum]()
|
||||
var indexToLoad = 0
|
||||
|
||||
var pageNo = 0
|
||||
var stopFetch = false
|
||||
|
||||
func initView(){
|
||||
setupCell()
|
||||
@@ -91,7 +89,7 @@ class GamesListVM{
|
||||
// vc.toast(msg: data.message ?? "Unrecognised error" , time: 2)
|
||||
case 1:
|
||||
Utilities.dismissProgressHUD()
|
||||
guard let data = data.data?.gameData else{return}
|
||||
guard let dataCount = data.data?.totalRecords, let data = data.data?.gameData else{return}
|
||||
self.gameData.append(contentsOf: data)
|
||||
self.vc.gamesListingTableView.reloadData()
|
||||
self.vc.tableHeight.constant = self.vc.gamesListingTableView.contentSize.height + 100
|
||||
@@ -107,13 +105,19 @@ class GamesListVM{
|
||||
self.vc.loadMoreActivityIndicator.stopAnimating()
|
||||
self.vc.loadMoreActivityIndicator.hidesWhenStopped = true
|
||||
|
||||
if self.gameData.count.isMultiple(of: 5) && !self.stopFetch{
|
||||
// if not multiple of 10, means more data can be there, show more btn
|
||||
self.vc.loadMoreBtn.isHidden = false
|
||||
}else{
|
||||
self.stopFetch = true
|
||||
if self.gameData.count == dataCount{
|
||||
self.vc.loadMoreBtn.isHidden = true
|
||||
}else{
|
||||
self.vc.loadMoreBtn.isHidden = false
|
||||
}
|
||||
|
||||
// if self.gameData.count.isMultiple(of: 5) && !self.stopFetch{
|
||||
// // if not multiple of 10, means more data can be there, show more btn
|
||||
// self.vc.loadMoreBtn.isHidden = false
|
||||
// }else{
|
||||
// self.stopFetch = true
|
||||
// self.vc.loadMoreBtn.isHidden = true
|
||||
// }
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -144,14 +148,14 @@ class GamesListVM{
|
||||
if isDone{
|
||||
gameData[index].markAsFavourite = false
|
||||
vc.gamesListingTableView.reloadRows(at: [IndexPath(row: index, section: 0)],with: .none)
|
||||
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
if let indexRemove = MyListDataTemp.shareInstance.favListingData?.gameData?.firstIndex(where: {$0.id == postID}){
|
||||
MyListDataTemp.shareInstance.favListingData?.gameData?.remove(at: indexRemove)
|
||||
K.GVar.myListSoftReload = true
|
||||
}
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// if let indexRemove = MyListDataTemp.shareInstance.favListingData?.gameData?.firstIndex(where: {$0.id == postID}){
|
||||
// MyListDataTemp.shareInstance.favListingData?.gameData?.remove(at: indexRemove)
|
||||
// K.GVar.myListSoftReload = true
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -159,13 +163,13 @@ class GamesListVM{
|
||||
if isDone{
|
||||
gameData[index].markAsFavourite = true
|
||||
vc.gamesListingTableView.reloadRows(at: [IndexPath(row: index, section: 0)],with: .none)
|
||||
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
let gameData = gameData[index]
|
||||
MyListDataTemp.shareInstance.favListingData?.gameData?.append(gameData)
|
||||
K.GVar.myListSoftReload = true
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// let gameData = gameData[index]
|
||||
// MyListDataTemp.shareInstance.favListingData?.gameData?.append(gameData)
|
||||
// K.GVar.myListSoftReload = true
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,10 @@ class MyListVC: UIViewController{
|
||||
@IBOutlet weak var guestLoginView: UIView!
|
||||
@IBOutlet weak var guestLoginStack: UIStackView!
|
||||
|
||||
@IBOutlet weak var WebSeriesBtn: LocalisedElementsButton!
|
||||
@IBOutlet weak var webSeriesBtn: LocalisedElementsButton!
|
||||
@IBOutlet weak var webSeriesHindiBtn: LocalisedElementsButton!
|
||||
@IBOutlet weak var audioBooksBtn: LocalisedElementsButton!
|
||||
@IBOutlet weak var gamesBtn: LocalisedElementsButton!
|
||||
@IBOutlet weak var karaokeViewBtn: LocalisedElementsButton!
|
||||
|
||||
var vm = MyListVM()
|
||||
@@ -72,17 +75,18 @@ class MyListVC: UIViewController{
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
K.GVar.topView = .myList
|
||||
|
||||
if K.GVar.reloadMyList{
|
||||
K.GVar.reloadMyList = false
|
||||
K.GVar.myListSoftReload = false
|
||||
Utilities.startProgressHUD()
|
||||
vm.getFavouriteListing()
|
||||
}
|
||||
|
||||
if K.GVar.myListSoftReload{
|
||||
vm.reloadCollections()
|
||||
vm.checkNil()
|
||||
K.GVar.myListSoftReload = false
|
||||
}
|
||||
|
||||
if K.GVar.reloadMyList{
|
||||
K.GVar.reloadMyList = false
|
||||
Utilities.startProgressHUD()
|
||||
vm.getFavouriteListing()
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func sideBarBtnTapped(_ sender: UIButton) {
|
||||
@@ -99,11 +103,33 @@ class MyListVC: UIViewController{
|
||||
|
||||
@IBAction func viewAllBtnTapped(_ sender: UIButton) {
|
||||
switch sender{
|
||||
case webSeriesHindiBtn:
|
||||
let sb = UIStoryboard(name: K.StoryBoard.home, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Home.MyListViewAllVC) as! MyListViewAllVC
|
||||
vcPush.vm.postType = 1
|
||||
vcPush.vm.catID = "18"
|
||||
self.navigationController?.pushViewController(vcPush, animated: true)
|
||||
case webSeriesBtn:
|
||||
let sb = UIStoryboard(name: K.StoryBoard.home, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Home.MyListViewAllVC) as! MyListViewAllVC
|
||||
vcPush.vm.postType = 1
|
||||
vcPush.vm.catID = "1"
|
||||
self.navigationController?.pushViewController(vcPush, animated: true)
|
||||
case karaokeViewBtn:
|
||||
let sb = UIStoryboard(name: K.StoryBoard.home, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Home.MyListViewAllVC) as! MyListViewAllVC
|
||||
vcPush.vm.postType = 8
|
||||
self.navigationController?.pushViewController(vcPush, animated: true)
|
||||
case audioBooksBtn:
|
||||
let sb = UIStoryboard(name: K.StoryBoard.home, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Home.MyListViewAllVC) as! MyListViewAllVC
|
||||
vcPush.vm.postType = 7
|
||||
self.navigationController?.pushViewController(vcPush, animated: true)
|
||||
case gamesBtn:
|
||||
let sb = UIStoryboard(name: K.StoryBoard.home, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Home.MyListViewAllVC) as! MyListViewAllVC
|
||||
vcPush.vm.postType = 6
|
||||
self.navigationController?.pushViewController(vcPush, animated: true)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -10,6 +10,11 @@ import UIKit
|
||||
class MyListViewAllVC: UIViewController {
|
||||
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
@IBOutlet weak var tableHeight: NSLayoutConstraint!
|
||||
|
||||
@IBOutlet weak var scrollView: UIScrollView!
|
||||
@IBOutlet weak var loadMoreBtn: LocalisedElementsButton!
|
||||
@IBOutlet weak var loadMoreActivityIndicator: UIActivityIndicatorView!
|
||||
|
||||
var vm = MyListViewAllVM()
|
||||
|
||||
@@ -44,6 +49,12 @@ class MyListViewAllVC: UIViewController {
|
||||
self.navigationController?.setColor(color: .black)
|
||||
}
|
||||
|
||||
@IBAction func loadMoreBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
loadMoreBtn.isHidden = true
|
||||
vm.pageNo += 1
|
||||
loadMoreActivityIndicator.startAnimating()
|
||||
vm.getFavouriteListing()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - TableView DataSource , Delegates
|
||||
@@ -52,7 +63,11 @@ extension MyListViewAllVC : TableViewSRC{
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
switch vm.postType{
|
||||
case 1: // webSeries
|
||||
return 0
|
||||
return vm.favListingData?.showData?.count ?? 0
|
||||
case 6: // Games
|
||||
return vm.favListingData?.gameData?.count ?? 0
|
||||
case 7: // Audio
|
||||
return vm.favListingData?.audioData?.count ?? 0
|
||||
case 8: //KAraoke
|
||||
return vm.favListingData?.singKaraokeData?.count ?? 0
|
||||
default:
|
||||
@@ -60,15 +75,60 @@ extension MyListViewAllVC : TableViewSRC{
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
switch vm.postType{
|
||||
case 1: // webSeries
|
||||
break
|
||||
case 6://Games
|
||||
guard let gameData = vm.favListingData?.gameData?[indexPath.row] else{return}
|
||||
|
||||
let sb = UIStoryboard(name: K.StoryBoard.Games, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Games.gamesDetailVC) as! GamesDetailVC
|
||||
vcPush.modalPresentationStyle = .overCurrentContext
|
||||
vcPush.modalTransitionStyle = .crossDissolve
|
||||
vcPush.gameData = gameData
|
||||
self.present(vcPush, animated: true)
|
||||
case 7: // audio books
|
||||
guard let audioData = vm.favListingData?.audioData?[indexPath.row] else{return}
|
||||
let sb = UIStoryboard(name: K.StoryBoard.audioBooks, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.AudioBooks.audioBookDetailsVC) as! AudioBookDetailsVC
|
||||
vcPush.modalPresentationStyle = .overCurrentContext
|
||||
vcPush.modalTransitionStyle = .crossDissolve
|
||||
vcPush.audioData = audioData
|
||||
// vcPush.delegate = self
|
||||
self.present(vcPush, animated: true)
|
||||
case 8: //KAraoke
|
||||
guard let karaokeData = vm.favListingData?.singKaraokeData?[indexPath.row] else{return}
|
||||
let sb = UIStoryboard(name: K.StoryBoard.Karaoke, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Karaoke.karaokeDetailsVC) as! KaraokeDetailsVC
|
||||
vcPush.modalPresentationStyle = .overCurrentContext
|
||||
vcPush.modalTransitionStyle = .crossDissolve
|
||||
vcPush.karaokeData = karaokeData
|
||||
self.present(vcPush, animated: true)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
return 220
|
||||
return 230
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: K.CellIdentifier.Home.myListViewAllCell) as! MyListViewAllCell
|
||||
switch vm.postType{
|
||||
case 1: // Webseries
|
||||
break
|
||||
if let webSeriesData = vm.favListingData?.showData?[indexPath.row] {
|
||||
cell.webSeriesData(data: webSeriesData)
|
||||
}
|
||||
case 6: // Games
|
||||
if let gameData = vm.favListingData?.gameData?[indexPath.row] {
|
||||
cell.gameData(data: gameData)
|
||||
}
|
||||
case 7:
|
||||
if let karaokeData = vm.favListingData?.audioData?[indexPath.row] {
|
||||
cell.audioData(data: karaokeData)
|
||||
}
|
||||
case 8: // Karaoke
|
||||
if let karaokeData = vm.favListingData?.singKaraokeData?[indexPath.row] {
|
||||
cell.setKaraokeData(data: karaokeData)
|
||||
|
||||
@@ -892,24 +892,93 @@
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="OrderBottom" translatesAutoresizingMaskIntoConstraints="NO" id="lws-zb-kGG">
|
||||
<rect key="frame" x="0.0" y="637.33333333333337" width="430" height="294.66666666666663"/>
|
||||
</imageView>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="19V-eU-c5X">
|
||||
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qPJ-td-erW">
|
||||
<rect key="frame" x="0.0" y="59" width="430" height="839"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</tableView>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="3Uf-oo-lnR">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="60"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" bounces="NO" alwaysBounceVertical="YES" scrollEnabled="NO" bouncesZoom="NO" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="19V-eU-c5X">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="0.0"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" id="Xh9-cs-jR1"/>
|
||||
</constraints>
|
||||
</tableView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rLI-Mx-4Bx">
|
||||
<rect key="frame" x="0.0" y="10" width="430" height="50"/>
|
||||
<subviews>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="GLK-nm-CdV" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="137.66666666666666" y="0.0" width="154.99999999999997" height="50"/>
|
||||
<color key="backgroundColor" red="0.36862745099999999" green="0.1215686275" blue="0.76862745099999996" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="BUE-lV-Q3o"/>
|
||||
<constraint firstAttribute="width" constant="155" id="HH0-3I-ts7"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<inset key="imageEdgeInsets" minX="-10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="LOAD MORE"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
||||
<integer key="value" value="25"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="loadMoreBtnTapped:" destination="4Hd-On-nDp" eventType="touchUpInside" id="wnd-wT-iDm"/>
|
||||
</connections>
|
||||
</button>
|
||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="medium" translatesAutoresizingMaskIntoConstraints="NO" id="FDe-HE-4tE">
|
||||
<rect key="frame" x="190" y="0.0" width="50" height="50"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="FDe-HE-4tE" secondAttribute="height" multiplier="1:1" id="KKK-SY-YrN"/>
|
||||
</constraints>
|
||||
<color key="color" name="ImageDarkBlue"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="GLK-nm-CdV" firstAttribute="top" secondItem="rLI-Mx-4Bx" secondAttribute="top" id="5eh-hN-zWJ"/>
|
||||
<constraint firstItem="FDe-HE-4tE" firstAttribute="centerX" secondItem="rLI-Mx-4Bx" secondAttribute="centerX" id="JcB-un-Laz"/>
|
||||
<constraint firstItem="FDe-HE-4tE" firstAttribute="top" secondItem="rLI-Mx-4Bx" secondAttribute="top" id="NI8-uA-plc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="FDe-HE-4tE" secondAttribute="bottom" id="YiF-0w-dBA"/>
|
||||
<constraint firstAttribute="height" constant="50" id="dBx-uA-16F"/>
|
||||
<constraint firstAttribute="bottom" secondItem="GLK-nm-CdV" secondAttribute="bottom" id="l0k-WQ-81u"/>
|
||||
<constraint firstItem="GLK-nm-CdV" firstAttribute="centerX" secondItem="rLI-Mx-4Bx" secondAttribute="centerX" id="zeF-ra-bpO"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="3Uf-oo-lnR" firstAttribute="width" secondItem="q3R-0H-Dwp" secondAttribute="width" id="eEq-0a-NhO"/>
|
||||
<constraint firstItem="3Uf-oo-lnR" firstAttribute="top" secondItem="qPJ-td-erW" secondAttribute="top" id="fP6-pj-gTy"/>
|
||||
<constraint firstItem="3Uf-oo-lnR" firstAttribute="leading" secondItem="PYa-pY-Uke" secondAttribute="leading" id="jMV-1Y-Q9Z"/>
|
||||
<constraint firstAttribute="bottom" secondItem="3Uf-oo-lnR" secondAttribute="bottom" id="xBp-j5-M0l"/>
|
||||
<constraint firstItem="3Uf-oo-lnR" firstAttribute="trailing" secondItem="PYa-pY-Uke" secondAttribute="trailing" id="zex-so-Xdr"/>
|
||||
</constraints>
|
||||
<viewLayoutGuide key="contentLayoutGuide" id="q3R-0H-Dwp"/>
|
||||
<viewLayoutGuide key="frameLayoutGuide" id="PYa-pY-Uke"/>
|
||||
</scrollView>
|
||||
</subviews>
|
||||
<viewLayoutGuide key="safeArea" id="RUi-Wa-LCY"/>
|
||||
<color key="backgroundColor" red="0.82745098039215681" green="0.93725490196078431" blue="0.97254901960784312" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="qPJ-td-erW" firstAttribute="top" secondItem="RUi-Wa-LCY" secondAttribute="top" id="9Ig-wg-qgc"/>
|
||||
<constraint firstAttribute="bottom" secondItem="lws-zb-kGG" secondAttribute="bottom" id="GEe-p1-saO"/>
|
||||
<constraint firstItem="19V-eU-c5X" firstAttribute="bottom" secondItem="RUi-Wa-LCY" secondAttribute="bottom" id="Yig-Wg-yNm"/>
|
||||
<constraint firstItem="19V-eU-c5X" firstAttribute="leading" secondItem="RUi-Wa-LCY" secondAttribute="leading" id="aZO-vF-FAH"/>
|
||||
<constraint firstItem="qPJ-td-erW" firstAttribute="bottom" secondItem="RUi-Wa-LCY" secondAttribute="bottom" id="Lpy-FM-TbU"/>
|
||||
<constraint firstItem="qPJ-td-erW" firstAttribute="trailing" secondItem="RUi-Wa-LCY" secondAttribute="trailing" id="M92-c1-SgU"/>
|
||||
<constraint firstItem="lws-zb-kGG" firstAttribute="leading" secondItem="of6-Su-bMU" secondAttribute="leading" id="hii-NV-BJu"/>
|
||||
<constraint firstItem="19V-eU-c5X" firstAttribute="top" secondItem="RUi-Wa-LCY" secondAttribute="top" id="tuE-vT-SkZ"/>
|
||||
<constraint firstItem="RUi-Wa-LCY" firstAttribute="trailing" secondItem="19V-eU-c5X" secondAttribute="trailing" id="uAZ-dh-098"/>
|
||||
<constraint firstItem="qPJ-td-erW" firstAttribute="leading" secondItem="RUi-Wa-LCY" secondAttribute="leading" id="uIr-07-yps"/>
|
||||
<constraint firstItem="RUi-Wa-LCY" firstAttribute="trailing" secondItem="lws-zb-kGG" secondAttribute="trailing" id="uOv-Wm-a4n"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="loadMoreActivityIndicator" destination="FDe-HE-4tE" id="b5b-DH-XFb"/>
|
||||
<outlet property="loadMoreBtn" destination="GLK-nm-CdV" id="Z6k-fY-U7o"/>
|
||||
<outlet property="scrollView" destination="qPJ-td-erW" id="24C-Yl-yMU"/>
|
||||
<outlet property="tableHeight" destination="Xh9-cs-jR1" id="wgb-1d-u8a"/>
|
||||
<outlet property="tableView" destination="19V-eU-c5X" id="1dg-6e-wcU"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
@@ -1006,7 +1075,7 @@
|
||||
<rect key="frame" x="0.0" y="119" width="430" height="730"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="45l-57-MA3">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="1357"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="1385"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="vZT-j7-NyY">
|
||||
<rect key="frame" x="0.0" y="10" width="430" height="261"/>
|
||||
@@ -1015,7 +1084,7 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="31"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="WebSeries (English)" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xht-7u-pAV" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="31"/>
|
||||
<rect key="frame" x="10" y="0.0" width="410" height="31"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -1037,8 +1106,12 @@
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</buttonConfiguration>
|
||||
<connections>
|
||||
<action selector="viewAllBtnTapped:" destination="55l-Gk-Npk" eventType="touchUpInside" id="kfL-Hw-odi"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="6Y6-vJ-OYT">
|
||||
<rect key="frame" x="0.0" y="31" width="430" height="230"/>
|
||||
@@ -1057,22 +1130,43 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="h1g-o9-Qbb">
|
||||
<rect key="frame" x="0.0" y="281" width="430" height="251.66666666666663"/>
|
||||
<rect key="frame" x="0.0" y="281" width="430" height="261"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="5FA-pO-H2O">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="21.666666666666668"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="5FA-pO-H2O">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="31"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="WebSeries (Hindi)" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UTS-hr-ix6" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="15" y="0.0" width="415" height="21.666666666666668"/>
|
||||
<rect key="frame" x="10" y="0.0" width="410" height="31"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PHL-y5-hHs" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="31"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="kCo-dL-89G"/>
|
||||
</constraints>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<state key="normal" title="Button"/>
|
||||
<buttonConfiguration key="configuration" style="plain">
|
||||
<attributedString key="attributedTitle">
|
||||
<fragment content="VIEW ALL">
|
||||
<attributes>
|
||||
<font key="NSFont" size="14" name="Exo2-Bold"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</buttonConfiguration>
|
||||
<connections>
|
||||
<action selector="viewAllBtnTapped:" destination="55l-Gk-Npk" eventType="touchUpInside" id="M41-T6-ZPA"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="15" bottom="0.0" right="0.0"/>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="aW7-x8-HRh">
|
||||
<rect key="frame" x="0.0" y="21.666666666666686" width="430" height="230"/>
|
||||
<rect key="frame" x="0.0" y="31" width="430" height="230"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="230" id="rMj-vz-b8j"/>
|
||||
@@ -1088,22 +1182,43 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="G4a-BA-Nw8">
|
||||
<rect key="frame" x="0.0" y="542.66666666666663" width="430" height="251.66666666666663"/>
|
||||
<rect key="frame" x="0.0" y="552" width="430" height="261"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="xQU-Hb-duc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="21.666666666666668"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xQU-Hb-duc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="31"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Audio Books" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uOV-bc-Z6x" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="15" y="0.0" width="415" height="21.666666666666668"/>
|
||||
<rect key="frame" x="10" y="0.0" width="410" height="31"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="f9x-Vl-IXu" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="31"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="U3P-PG-Fle"/>
|
||||
</constraints>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<state key="normal" title="Button"/>
|
||||
<buttonConfiguration key="configuration" style="plain">
|
||||
<attributedString key="attributedTitle">
|
||||
<fragment content="VIEW ALL">
|
||||
<attributes>
|
||||
<font key="NSFont" size="14" name="Exo2-Bold"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</buttonConfiguration>
|
||||
<connections>
|
||||
<action selector="viewAllBtnTapped:" destination="55l-Gk-Npk" eventType="touchUpInside" id="dK1-eI-Lq5"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="15" bottom="0.0" right="0.0"/>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="ABR-no-OBf">
|
||||
<rect key="frame" x="0.0" y="21.666666666666742" width="430" height="230"/>
|
||||
<rect key="frame" x="0.0" y="31" width="430" height="230"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="230" id="hbc-ha-qTS"/>
|
||||
@@ -1119,45 +1234,40 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="jE2-WP-tD4">
|
||||
<rect key="frame" x="0.0" y="804.33333333333337" width="430" height="261.00000000000011"/>
|
||||
<rect key="frame" x="0.0" y="823" width="430" height="261"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="YGM-QR-sbm">
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="YGM-QR-sbm">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="31"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="geP-gI-gZd">
|
||||
<rect key="frame" x="15" y="0.0" width="395" height="31"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Karaoke" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JBX-qP-uJM" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="395" height="31"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MNq-YB-EUG" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="31"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="bma-Om-NPP"/>
|
||||
</constraints>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<state key="normal" title="Button"/>
|
||||
<buttonConfiguration key="configuration" style="plain">
|
||||
<attributedString key="attributedTitle">
|
||||
<fragment content="VIEW ALL">
|
||||
<attributes>
|
||||
<font key="NSFont" size="14" name="Exo2-Bold"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</buttonConfiguration>
|
||||
<connections>
|
||||
<action selector="viewAllBtnTapped:" destination="55l-Gk-Npk" eventType="touchUpInside" id="pAS-gT-xTU"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Karaoke" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JBX-qP-uJM" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="10" y="0.0" width="410" height="31"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="MNq-YB-EUG" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="31"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="bma-Om-NPP"/>
|
||||
</constraints>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<state key="normal" title="Button"/>
|
||||
<buttonConfiguration key="configuration" style="plain">
|
||||
<attributedString key="attributedTitle">
|
||||
<fragment content="VIEW ALL">
|
||||
<attributes>
|
||||
<font key="NSFont" size="14" name="Exo2-Bold"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</buttonConfiguration>
|
||||
<connections>
|
||||
<action selector="viewAllBtnTapped:" destination="55l-Gk-Npk" eventType="touchUpInside" id="pAS-gT-xTU"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="15" bottom="0.0" right="20"/>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="Grz-ok-w2U">
|
||||
<rect key="frame" x="0.0" y="31" width="430" height="230"/>
|
||||
@@ -1176,22 +1286,43 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="Cgp-Ok-Imj">
|
||||
<rect key="frame" x="0.0" y="1075.3333333333333" width="430" height="251.66666666666674"/>
|
||||
<rect key="frame" x="0.0" y="1094" width="430" height="261"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="V6u-Uf-Yc7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="21.666666666666668"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="V6u-Uf-Yc7">
|
||||
<rect key="frame" x="0.0" y="0.0" width="430" height="31"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Games" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qph-Fh-w3E" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="15" y="0.0" width="415" height="21.666666666666668"/>
|
||||
<rect key="frame" x="10" y="0.0" width="410" height="31"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="18"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button hidden="YES" opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="KaX-7S-wh3" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="100" height="31"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="mzh-ro-W0m"/>
|
||||
</constraints>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<state key="normal" title="Button"/>
|
||||
<buttonConfiguration key="configuration" style="plain">
|
||||
<attributedString key="attributedTitle">
|
||||
<fragment content="VIEW ALL">
|
||||
<attributes>
|
||||
<font key="NSFont" size="14" name="Exo2-Bold"/>
|
||||
</attributes>
|
||||
</fragment>
|
||||
</attributedString>
|
||||
</buttonConfiguration>
|
||||
<connections>
|
||||
<action selector="viewAllBtnTapped:" destination="55l-Gk-Npk" eventType="touchUpInside" id="ley-C1-dsk"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="15" bottom="0.0" right="0.0"/>
|
||||
<edgeInsets key="layoutMargins" top="0.0" left="10" bottom="0.0" right="10"/>
|
||||
</stackView>
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="5ff-Y7-nit">
|
||||
<rect key="frame" x="0.0" y="21.666666666666742" width="430" height="230"/>
|
||||
<rect key="frame" x="0.0" y="31" width="430" height="230"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="230" id="vnV-51-p2Q"/>
|
||||
@@ -1207,7 +1338,7 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="F2F-sK-9oY">
|
||||
<rect key="frame" x="0.0" y="1337" width="430" height="20"/>
|
||||
<rect key="frame" x="0.0" y="1365" width="430" height="20"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="Jsj-FP-k6f"/>
|
||||
@@ -1365,9 +1496,10 @@
|
||||
<tabBarItem key="tabBarItem" title="MY LIST" image="HeartIcon" id="dhn-IV-GcD"/>
|
||||
<navigationItem key="navigationItem" id="dCO-Wi-XFC"/>
|
||||
<connections>
|
||||
<outlet property="WebSeriesBtn" destination="zNj-21-nce" id="Tkc-4Z-odt"/>
|
||||
<outlet property="audioBooksBtn" destination="f9x-Vl-IXu" id="POf-cl-Ccb"/>
|
||||
<outlet property="audioBooksCV" destination="ABR-no-OBf" id="axa-Ry-rEx"/>
|
||||
<outlet property="audioBooksStack" destination="G4a-BA-Nw8" id="kNl-ev-XoJ"/>
|
||||
<outlet property="gamesBtn" destination="KaX-7S-wh3" id="TuJ-QI-lx2"/>
|
||||
<outlet property="gamesCV" destination="5ff-Y7-nit" id="vM3-Z9-paV"/>
|
||||
<outlet property="gamesStack" destination="Cgp-Ok-Imj" id="63D-lB-0lW"/>
|
||||
<outlet property="gradientView" destination="cxl-Av-gEU" id="Sag-vq-nKu"/>
|
||||
@@ -1378,8 +1510,10 @@
|
||||
<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="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"/>
|
||||
</connections>
|
||||
|
||||
@@ -13,17 +13,20 @@ struct FavouriteListingDM: Codable {
|
||||
|
||||
// MARK: - Result
|
||||
struct ResultData: Codable {
|
||||
let totalRecords: Int?
|
||||
var showData: [ShowDatum]?
|
||||
var videoData: [Datum]?
|
||||
var gameData: [GamesListDM.GameDatum]?
|
||||
var singKaraokeData : [KaraokeListingDM.KaraokeDatum]?
|
||||
var audioData : [ListenAudioListingDM.AudioDatum]?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case showData = "show_data"
|
||||
case videoData = "video_data"
|
||||
case gameData = "game_data"
|
||||
case audioData = "audio_data"
|
||||
case singKaraokeData = "sing_karaoke_data"
|
||||
case totalRecords = "total_records"
|
||||
}
|
||||
|
||||
// MARK: - Datum
|
||||
|
||||
@@ -42,19 +42,17 @@
|
||||
<rect key="frame" x="10" y="215" width="444" height="35"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oRP-Fz-UDh">
|
||||
<rect key="frame" x="0.0" y="7.9999999999999982" width="41.666666666666664" height="19.333333333333329"/>
|
||||
<rect key="frame" x="0.0" y="7.9999999999999982" width="444" height="19.333333333333329"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="3Ie-X7-GNB">
|
||||
<rect key="frame" x="363" y="0.0" width="81" height="35"/>
|
||||
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="3Ie-X7-GNB">
|
||||
<rect key="frame" x="0.0" y="17.666666666666657" width="4" height="0.0"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dqQ-h9-X5j">
|
||||
<rect key="frame" x="0.0" y="0.0" width="42" height="35"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0wl-al-Mem">
|
||||
<rect key="frame" x="0.0" y="0.0" width="35" height="35"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="0wl-al-Mem" secondAttribute="height" multiplier="1:1" id="f5X-yy-AaB"/>
|
||||
</constraints>
|
||||
@@ -66,7 +64,6 @@
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="UPC-ka-rtd">
|
||||
<rect key="frame" x="35" y="0.0" width="7" height="35"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -74,7 +71,7 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DBE-WR-Rqm">
|
||||
<rect key="frame" x="46" y="0.0" width="35" height="35"/>
|
||||
<rect key="frame" x="4" y="0.0" width="0.0" height="0.0"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="DBE-WR-Rqm" secondAttribute="height" multiplier="1:1" id="2V7-gp-vng"/>
|
||||
</constraints>
|
||||
@@ -136,7 +133,7 @@
|
||||
<image name="FavouriteRemove" width="42.666667938232422" height="42.666667938232422"/>
|
||||
<image name="LikeRemove" width="42.666667938232422" height="42.666667938232422"/>
|
||||
<namedColor name="ImageDarkBlue">
|
||||
<color red="0.035294117647058823" green="0.0" blue="0.36470588235294116" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color red="0.035000000149011612" green="0.0" blue="0.36500000953674316" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</namedColor>
|
||||
</resources>
|
||||
</document>
|
||||
|
||||
@@ -73,4 +73,96 @@ class MyListViewAllCell: UITableViewCell {
|
||||
}
|
||||
}
|
||||
|
||||
func audioData(data : ListenAudioListingDM.AudioDatum){
|
||||
//heart.fill , heart , hand.thumbsup.fill , hand.thumbsup
|
||||
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
|
||||
cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first?.title
|
||||
}else{
|
||||
cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first?.title
|
||||
}
|
||||
totalLikes.text = data.likesCount?.toString() ?? "0"
|
||||
if let url = data.thumbnailPath{
|
||||
cellImage.imageURL(url)
|
||||
}
|
||||
|
||||
if let favourite = data.markAsFavourite{
|
||||
switch favourite{
|
||||
case true:
|
||||
favBtnn.setImage(UIImage(named: "FavouriteAdd"), for: .normal)
|
||||
case false:
|
||||
favBtnn.setImage(UIImage(named: "FavouriteRemove"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
if let like = data.isLiked{
|
||||
switch like{
|
||||
case true:
|
||||
likeBtn.setImage(UIImage(named: "LikeAdd"), for: .normal)
|
||||
case false:
|
||||
likeBtn.setImage(UIImage(named: "LikeRemove"), for: .normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
func gameData(data : GamesListDM.GameDatum){
|
||||
//heart.fill , heart , hand.thumbsup.fill , hand.thumbsup
|
||||
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
|
||||
cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first?.title
|
||||
}else{
|
||||
cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first?.title
|
||||
}
|
||||
totalLikes.text = data.likesCount?.toString() ?? "0"
|
||||
if let url = data.thumbnailPath{
|
||||
cellImage.imageURL(url)
|
||||
}
|
||||
|
||||
if let favourite = data.markAsFavourite{
|
||||
switch favourite{
|
||||
case true:
|
||||
favBtnn.setImage(UIImage(named: "FavouriteAdd"), for: .normal)
|
||||
case false:
|
||||
favBtnn.setImage(UIImage(named: "FavouriteRemove"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
if let like = data.isLiked{
|
||||
switch like{
|
||||
case true:
|
||||
likeBtn.setImage(UIImage(named: "LikeAdd"), for: .normal)
|
||||
case false:
|
||||
likeBtn.setImage(UIImage(named: "LikeRemove"), for: .normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func webSeriesData(data : FavouriteListingDM.ResultData.ShowDatum){
|
||||
//heart.fill , heart , hand.thumbsup.fill , hand.thumbsup
|
||||
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
|
||||
cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first?.title
|
||||
}else{
|
||||
cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first?.title
|
||||
}
|
||||
totalLikes.text = data.likesCount?.toString() ?? "0"
|
||||
if let url = data.thumbnailPath{
|
||||
cellImage.imageURL(url)
|
||||
}
|
||||
|
||||
if let favourite = data.markAsFavourite{
|
||||
switch favourite{
|
||||
case true:
|
||||
favBtnn.setImage(UIImage(named: "FavouriteAdd"), for: .normal)
|
||||
case false:
|
||||
favBtnn.setImage(UIImage(named: "FavouriteRemove"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
if let like = data.isLiked{
|
||||
switch like{
|
||||
case true:
|
||||
likeBtn.setImage(UIImage(named: "LikeAdd"), for: .normal)
|
||||
case false:
|
||||
likeBtn.setImage(UIImage(named: "LikeRemove"), for: .normal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,19 +39,17 @@
|
||||
<rect key="frame" x="10" y="176" width="432" height="35"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cU1-N6-K7n">
|
||||
<rect key="frame" x="0.0" y="7.9999999999999982" width="41.666666666666664" height="19.333333333333329"/>
|
||||
<rect key="frame" x="0.0" y="7.9999999999999982" width="432" height="19.333333333333329"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="A0I-5C-IVv">
|
||||
<rect key="frame" x="351" y="0.0" width="81" height="35"/>
|
||||
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="A0I-5C-IVv">
|
||||
<rect key="frame" x="432" y="17.666666666666657" width="4" height="0.0"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ghl-pn-MhV">
|
||||
<rect key="frame" x="0.0" y="0.0" width="42" height="35"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Q69-kf-j62">
|
||||
<rect key="frame" x="0.0" y="0.0" width="35" height="35"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="Q69-kf-j62" secondAttribute="height" multiplier="1:1" id="Ns6-yn-HOa"/>
|
||||
</constraints>
|
||||
@@ -60,7 +58,6 @@
|
||||
<state key="normal" image="LikeRemove"/>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="GgZ-Se-yNw">
|
||||
<rect key="frame" x="35" y="0.0" width="7" height="35"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -68,7 +65,7 @@
|
||||
</subviews>
|
||||
</stackView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QM5-Ju-7Lu">
|
||||
<rect key="frame" x="46" y="0.0" width="35" height="35"/>
|
||||
<rect key="frame" x="4" y="0.0" width="0.0" height="0.0"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="QM5-Ju-7Lu" secondAttribute="height" multiplier="1:1" id="W0Z-YP-aEV"/>
|
||||
</constraints>
|
||||
|
||||
@@ -40,6 +40,10 @@ class MyListVM{
|
||||
getFavouriteListing()
|
||||
|
||||
vc.karaokeViewBtn.roundCorner()
|
||||
vc.audioBooksBtn.roundCorner()
|
||||
vc.gamesBtn.roundCorner()
|
||||
vc.webSeriesBtn.roundCorner()
|
||||
vc.webSeriesHindiBtn.roundCorner()
|
||||
}
|
||||
|
||||
@objc func viewPush(notification: Notification){
|
||||
@@ -137,7 +141,7 @@ class MyListVM{
|
||||
MyListDataTemp.shareInstance.isDatafetched = true
|
||||
|
||||
if MyListDataTemp.shareInstance.favListingData?.showData == nil {
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
reloadCollections()
|
||||
checkNil()
|
||||
@@ -215,7 +219,7 @@ class MyListVM{
|
||||
Utilities.dismissProgressHUD()
|
||||
checkNil()
|
||||
if MyListDataTemp.shareInstance.favListingData?.showData == nil {
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
self.vc.toast(msg: error.localizedDescription , time: 2)
|
||||
}
|
||||
@@ -231,8 +235,31 @@ class MyListVM{
|
||||
vc.karaokeViewBtn.isHidden = true
|
||||
}
|
||||
|
||||
}
|
||||
if let audioBooksCount = favListing.audioData?.count , audioBooksCount >= 3{
|
||||
vc.audioBooksBtn.isHidden = false
|
||||
}else{
|
||||
vc.audioBooksBtn.isHidden = true
|
||||
}
|
||||
|
||||
if let gamesCount = favListing.gameData?.count , gamesCount >= 3{
|
||||
vc.gamesBtn.isHidden = false
|
||||
}else{
|
||||
vc.gamesBtn.isHidden = true
|
||||
}
|
||||
|
||||
if let webbSeriesEnglishCount = favListing.showData?.count , webbSeriesEnglishCount >= 3{
|
||||
vc.webSeriesBtn.isHidden = false
|
||||
}else{
|
||||
vc.webSeriesBtn.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
let hindiListing = MyListDataTemp.shareInstance.webSeriesHindi
|
||||
if hindiListing.count >= 3{
|
||||
vc.webSeriesHindiBtn.isHidden = false
|
||||
}else{
|
||||
vc.webSeriesHindiBtn.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Like , unlike
|
||||
|
||||
@@ -14,13 +14,17 @@ class MyListViewAllVM{
|
||||
// var moduleType = Int()
|
||||
var postType = Int()
|
||||
var pageNo = 0
|
||||
var catID = String()
|
||||
|
||||
var favListingData : FavouriteListingDM.ResultData?
|
||||
var webSeriesHindi = [FavouriteListingDM.ResultData.ShowDatum]()
|
||||
|
||||
let refreshControl = UIRefreshControl()
|
||||
|
||||
func initView(){
|
||||
setupCell()
|
||||
Utilities.startProgressHUD()
|
||||
getFavouriteListing()
|
||||
updateData()
|
||||
}
|
||||
|
||||
func setupCell(){
|
||||
@@ -28,18 +32,17 @@ class MyListViewAllVM{
|
||||
vc.tableView.delegate = vc.self
|
||||
vc.tableView.dataSource = vc.self
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Get Favourite Listing
|
||||
|
||||
func getFavouriteListing(){
|
||||
Utilities.startProgressHUD()
|
||||
let headers : HTTPHeaders = ["Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi",
|
||||
"access-token": AuthFunc.shareInstance.getAccessToken()]
|
||||
|
||||
let params : Parameters = ["post_type" : postType,
|
||||
"api_version" : "v2",
|
||||
"start" : pageNo,
|
||||
"limit" : "10"]
|
||||
"limit" : "6",
|
||||
"category_id" : catID]
|
||||
|
||||
NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.favourite_listing, method: .post,parameters : params, headers: headers) { [weak self](result : Result<BaseResponseModel<FavouriteListingDM>, NetworkManager.APIError>) in
|
||||
switch result{
|
||||
@@ -48,61 +51,129 @@ class MyListViewAllVM{
|
||||
switch data.success{
|
||||
case 0:
|
||||
Utilities.dismissProgressHUD()
|
||||
self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2)
|
||||
refreshControl.endRefreshing()
|
||||
// self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2)
|
||||
self.vc.loadMoreActivityIndicator.stopAnimating()
|
||||
self.vc.loadMoreActivityIndicator.hidesWhenStopped = true
|
||||
case 1:
|
||||
Utilities.dismissProgressHUD()
|
||||
guard let data = data.data?.result else{return}
|
||||
self.favListingData = data
|
||||
if var hindiData = favListingData?.showData{
|
||||
|
||||
/*
|
||||
Taking out the hindi series , 1-> English , 18-> Hindi
|
||||
And the saving it to hindi series, also modify the bookmark category ids
|
||||
*/
|
||||
webSeriesHindi = hindiData.compactMap { $0 }.filter {
|
||||
($0.bookmarkCategoryIDS?.components(separatedBy: ",").first == "18" || $0.bookmarkCategoryIDS?.components(separatedBy: ",").last == "18")
|
||||
}.map { element -> FavouriteListingDM.ResultData.ShowDatum in
|
||||
var modifiedElement = element
|
||||
modifiedElement.bookmarkCategoryIDS = "18"
|
||||
modifiedElement.categoryMasterID = "18"
|
||||
return modifiedElement
|
||||
refreshControl.endRefreshing()
|
||||
guard let totalCount = data.data?.result?.totalRecords ,let data = data.data?.result else{return}
|
||||
|
||||
switch postType{
|
||||
case 0: // webSeriesHindi
|
||||
if favListingData?.gameData == nil {
|
||||
favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
if let webSeriesData = data.showData {
|
||||
favListingData?.showData?.append(contentsOf: webSeriesData)
|
||||
}
|
||||
|
||||
if let data = favListingData?.showData{
|
||||
var indicesToRemove = [Int]()
|
||||
|
||||
// Deleting the hindi series from main (those with category ID "18")
|
||||
for (index, element) in data.enumerated() {
|
||||
if let bookMarkCatID = element.bookmarkCategoryIDS?.components(separatedBy: ","){
|
||||
if bookMarkCatID.count > 1{ // means multiple language
|
||||
/*
|
||||
if its greater than one , its for sure we have extracted the hindi episode
|
||||
*/
|
||||
hindiData[index].bookmarkCategoryIDS = "1"
|
||||
}else{ // means single language
|
||||
if bookMarkCatID.first == "18"{
|
||||
indicesToRemove.append(index)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.vc.tableView.reloadData()
|
||||
self.vc.tableHeight.constant = self.vc.tableView.contentSize.height + 100
|
||||
self.vc.tableView.layoutIfNeeded()
|
||||
let webSeriesCount = self.favListingData?.showData?.count ?? 0
|
||||
self.vc.tableHeight.constant = CGFloat(webSeriesCount * 230)
|
||||
self.vc.loadMoreActivityIndicator.stopAnimating()
|
||||
self.vc.loadMoreActivityIndicator.hidesWhenStopped = true
|
||||
|
||||
if webSeriesCount == totalCount{
|
||||
self.vc.loadMoreBtn.isHidden = true
|
||||
}else{
|
||||
self.vc.loadMoreBtn.isHidden = false
|
||||
}
|
||||
case 1: // webSeriesEnglish
|
||||
if favListingData?.gameData == nil {
|
||||
favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
if let webSeriesData = data.showData {
|
||||
favListingData?.showData?.append(contentsOf: webSeriesData)
|
||||
}
|
||||
|
||||
|
||||
self.vc.tableView.reloadData()
|
||||
self.vc.tableHeight.constant = self.vc.tableView.contentSize.height + 100
|
||||
self.vc.tableView.layoutIfNeeded()
|
||||
let webSeriesCount = self.favListingData?.showData?.count ?? 0
|
||||
self.vc.tableHeight.constant = CGFloat(webSeriesCount * 230)
|
||||
self.vc.loadMoreActivityIndicator.stopAnimating()
|
||||
self.vc.loadMoreActivityIndicator.hidesWhenStopped = true
|
||||
|
||||
if webSeriesCount == totalCount{
|
||||
self.vc.loadMoreBtn.isHidden = true
|
||||
}else{
|
||||
self.vc.loadMoreBtn.isHidden = false
|
||||
}
|
||||
case 6: // Games
|
||||
if let gameData = data.gameData{
|
||||
if favListingData?.gameData == nil {
|
||||
favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
|
||||
// Remove items in reverse order to avoid index shifting issues
|
||||
for index in indicesToRemove.reversed() {
|
||||
hindiData.remove(at: index)
|
||||
self.favListingData?.gameData?.append(contentsOf: gameData)
|
||||
|
||||
self.vc.tableView.reloadData()
|
||||
self.vc.tableHeight.constant = self.vc.tableView.contentSize.height + 100
|
||||
self.vc.tableView.layoutIfNeeded()
|
||||
let gameCount = self.favListingData?.gameData?.count ?? 0
|
||||
self.vc.tableHeight.constant = CGFloat(gameCount * 230)
|
||||
self.vc.loadMoreActivityIndicator.stopAnimating()
|
||||
self.vc.loadMoreActivityIndicator.hidesWhenStopped = true
|
||||
|
||||
if gameCount == totalCount{
|
||||
self.vc.loadMoreBtn.isHidden = true
|
||||
}else{
|
||||
self.vc.loadMoreBtn.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Updating the showData with the filtered list
|
||||
// MyListDataTemp.shareInstance.favListingData?.showData = hindiData.map({$0.categoryMasterID = 1})
|
||||
favListingData?.showData = hindiData.map { item in
|
||||
var modifiedItem = item
|
||||
modifiedItem.categoryMasterID = "1"
|
||||
return modifiedItem
|
||||
case 7:
|
||||
if let audioData = data.audioData{
|
||||
if favListingData?.audioData == nil {
|
||||
favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
|
||||
self.favListingData?.audioData?.append(contentsOf: audioData)
|
||||
|
||||
self.vc.tableView.reloadData()
|
||||
self.vc.tableHeight.constant = self.vc.tableView.contentSize.height + 100
|
||||
self.vc.tableView.layoutIfNeeded()
|
||||
let audioCount = self.favListingData?.audioData?.count ?? 0
|
||||
self.vc.tableHeight.constant = CGFloat(audioCount * 230)
|
||||
self.vc.loadMoreActivityIndicator.stopAnimating()
|
||||
self.vc.loadMoreActivityIndicator.hidesWhenStopped = true
|
||||
|
||||
if audioCount == totalCount{
|
||||
self.vc.loadMoreBtn.isHidden = true
|
||||
}else{
|
||||
self.vc.loadMoreBtn.isHidden = false
|
||||
}
|
||||
}
|
||||
case 8: //KAraoke
|
||||
if let karaokeData = data.singKaraokeData{
|
||||
if favListingData?.showData == nil {
|
||||
favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
|
||||
self.favListingData?.singKaraokeData?.append(contentsOf: karaokeData)
|
||||
|
||||
self.vc.tableView.reloadData()
|
||||
self.vc.tableHeight.constant = self.vc.tableView.contentSize.height + 100
|
||||
self.vc.tableView.layoutIfNeeded()
|
||||
let karaokeCount = self.favListingData?.singKaraokeData?.count ?? 0
|
||||
self.vc.tableHeight.constant = CGFloat(karaokeCount * 230)
|
||||
self.vc.loadMoreActivityIndicator.stopAnimating()
|
||||
self.vc.loadMoreActivityIndicator.hidesWhenStopped = true
|
||||
|
||||
if karaokeCount == totalCount{
|
||||
self.vc.loadMoreBtn.isHidden = true
|
||||
}else{
|
||||
self.vc.loadMoreBtn.isHidden = false
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
self.vc.tableView.reloadData()
|
||||
|
||||
default:
|
||||
break
|
||||
@@ -110,6 +181,7 @@ class MyListViewAllVM{
|
||||
case .failure(let error):
|
||||
guard let self else{return}
|
||||
Utilities.dismissProgressHUD()
|
||||
refreshControl.endRefreshing()
|
||||
self.vc.toast(msg: error.localizedDescription , time: 2)
|
||||
}
|
||||
}
|
||||
@@ -121,6 +193,10 @@ class MyListViewAllVM{
|
||||
switch postType{
|
||||
case 1: // webSeries
|
||||
self.vc.title = "WEB SERIES"
|
||||
case 6: // Games
|
||||
self.vc.title = "GAMES"
|
||||
case 7: // AUDIOBOOKS
|
||||
self.vc.title = "AUDIO BOOKS"
|
||||
case 8: //KAraoke
|
||||
self.vc.title = "KARAOKE"
|
||||
default:
|
||||
|
||||
@@ -25,7 +25,7 @@ extension AVAsset {
|
||||
return
|
||||
}
|
||||
|
||||
Utilities.startProgressHUD(msg: "Preparing")
|
||||
// Utilities.startProgressHUD(msg: "Preparing")
|
||||
// Create an AVMutableAudioMix to adjust the volume
|
||||
let audioMix = AVMutableAudioMix()
|
||||
var inputParameters = [AVMutableAudioMixInputParameters]()
|
||||
@@ -58,24 +58,11 @@ extension AVAsset {
|
||||
case .unknown, .waiting, .exporting, .failed, .cancelled:
|
||||
Utilities.dismissProgressHUD()
|
||||
completion(false, nil, nil)
|
||||
@unknown default:
|
||||
Utilities.dismissProgressHUD()
|
||||
completion(false, nil, nil)
|
||||
}
|
||||
}
|
||||
// guard let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetAppleM4A) else {
|
||||
// completion(false, nil , nil)
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// exportSession.outputFileType = .m4a
|
||||
// exportSession.outputURL = url
|
||||
//
|
||||
// exportSession.exportAsynchronously {
|
||||
// switch exportSession.status {
|
||||
// case .completed:
|
||||
// completion(true, nil, url)
|
||||
// case .unknown, .waiting, .exporting, .failed, .cancelled:
|
||||
// completion(false, nil, nil)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
func audioAsset() throws -> AVAsset {
|
||||
|
||||
@@ -20,261 +20,30 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
@IBOutlet weak var karaokeLoading: UIActivityIndicatorView!
|
||||
@IBOutlet weak var startStopRecordingStack: UIStackView!
|
||||
@IBOutlet weak var outerStack : UIStackView!
|
||||
@IBOutlet weak var retryKaraokeBtn: LocalisedElementsButton!
|
||||
|
||||
var config: JWPlayerConfiguration!
|
||||
var dismissTapped: (() -> Void)?
|
||||
|
||||
var audioURLFromMP4 : URL?
|
||||
var recordedAudioURL: URL?
|
||||
var audioRecorder: AVAudioRecorder?
|
||||
var videoTitle : String?
|
||||
var videoUrl : String?
|
||||
|
||||
var mixedAudioURL: URL?
|
||||
var isRecording = false
|
||||
var isPlaying = false
|
||||
|
||||
var startTime : TimeInterval?
|
||||
var endTime : TimeInterval?
|
||||
|
||||
var audioPlayer = AVPlayer()
|
||||
|
||||
var vm = JWKaraokePlayerVM()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
vm.vc = self
|
||||
vm.initView()
|
||||
|
||||
player.configurePlayer(with: config)
|
||||
self.delegate = self
|
||||
//Disable Picture in Picture
|
||||
playerView.allowsPictureInPicturePlayback = false
|
||||
playerView.captionStyle = .none
|
||||
self.view.bringSubviewToFront(outerStack)
|
||||
self.view.bringSubviewToFront(backButton)
|
||||
setupKaraoke()
|
||||
self.downloadRecordingBtn.isEnabled = false
|
||||
}
|
||||
|
||||
// MARK: - AudioRecording
|
||||
|
||||
func setupAudio() {
|
||||
// FileManager.default.clearTmpDirectory()
|
||||
|
||||
let audioSession = AVAudioSession.sharedInstance()
|
||||
do {
|
||||
try audioSession.setCategory(.playAndRecord, mode: .default,options: .defaultToSpeaker)
|
||||
try audioSession.setActive(true)
|
||||
|
||||
// // URL of the downloaded M4A file
|
||||
// guard let audioURL = Bundle.main.url(forResource: "Sample_audio", withExtension: "m4a") else {
|
||||
// print("Audio file not found.")
|
||||
// return
|
||||
// }
|
||||
|
||||
// Initialize AVAudioPlayer with the downloaded M4A file
|
||||
// player = try AVAudioPlayer(contentsOf: audioURLFromMP4!)
|
||||
// player?.prepareToPlay()
|
||||
|
||||
// Define settings for the audio recorder
|
||||
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
||||
let outputURL = documentsDirectory.appendingPathComponent("recordedAudio.m4a")
|
||||
let settings: [String: Any] = [
|
||||
AVFormatIDKey: kAudioFormatMPEG4AAC,
|
||||
AVSampleRateKey: 44100,
|
||||
AVNumberOfChannelsKey: 2,
|
||||
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
|
||||
]
|
||||
|
||||
// Initialize AVAudioRecorder with the output URL and settings
|
||||
audioRecorder = try AVAudioRecorder(url: outputURL, settings: settings)
|
||||
audioRecorder?.prepareToRecord()
|
||||
recordedAudioURL = outputURL // Store the recorded audio URL
|
||||
} catch {
|
||||
print("Error setting up audio: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
func startRecording() {
|
||||
startTime = self.player.time.position.round(to: 1)
|
||||
self.interfaceBehavior = .hidden
|
||||
guard let audioRecorder = audioRecorder else { return }
|
||||
audioRecorder.record()
|
||||
}
|
||||
|
||||
func stopRecording() {
|
||||
endTime = self.player.time.position.round(to: 1)
|
||||
self.interfaceBehavior = .normal
|
||||
guard let audioRecorder = audioRecorder else { return }
|
||||
audioRecorder.stop()
|
||||
self.player.pause()
|
||||
// Mix the recorded audio with the downloaded M4A file
|
||||
guard let startTime , let endTime else{return}
|
||||
mixAudio(start: startTime, stop: endTime)
|
||||
}
|
||||
|
||||
|
||||
func mixAudio(start : TimeInterval, stop : TimeInterval) {
|
||||
let totalTime = stop - start
|
||||
guard let recordedAudioURL = recordedAudioURL else { return }
|
||||
guard let playerURL = audioURLFromMP4 else { return }
|
||||
Utilities.startProgressHUD(msg: "Mixing Audio")
|
||||
let composition = AVMutableComposition()
|
||||
let compositionDuration = CMTime(seconds: totalTime, preferredTimescale: 1)
|
||||
|
||||
// Add the recorded audio from 0 to 10 seconds
|
||||
let recordedAudioAsset = AVURLAsset(url: recordedAudioURL)
|
||||
let recordedAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
|
||||
|
||||
do {
|
||||
try recordedAudioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: compositionDuration), of: recordedAudioAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
|
||||
} catch {
|
||||
Utilities.dismissProgressHUD()
|
||||
print("Error adding recorded audio track: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
// Add the downloaded M4A file from 10 to 20 seconds
|
||||
let playerAsset = AVURLAsset(url: playerURL)
|
||||
let playerTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
|
||||
|
||||
do {
|
||||
try playerTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime(seconds: start, preferredTimescale: 1), duration: compositionDuration), of: playerAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
|
||||
} catch {
|
||||
Utilities.dismissProgressHUD()
|
||||
print("Error adding player audio track: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
// Example usage:
|
||||
|
||||
|
||||
// Export the mixed audio
|
||||
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
||||
let fileName = "\((self.videoTitle?.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: ".", with: "") ?? "Audio") + Date().timeIntervalSince1970.toString()).m4a"
|
||||
let filePath = documentsDirectory.appendingPathComponent(fileName)
|
||||
deleteFileIfExist(at: filePath)
|
||||
|
||||
mixedAudioURL = filePath
|
||||
|
||||
guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) else { return }
|
||||
exportSession.outputURL = mixedAudioURL
|
||||
exportSession.outputFileType = .m4a
|
||||
|
||||
exportSession.exportAsynchronously {
|
||||
if exportSession.status == .completed {
|
||||
print("Mixing audio completed.")
|
||||
Utilities.dismissProgressHUD()
|
||||
DispatchQueue.main.async {
|
||||
self.playBtn.isEnabled = true
|
||||
self.downloadRecordingBtn.isEnabled = true
|
||||
}
|
||||
|
||||
|
||||
} else if exportSession.status == .failed {
|
||||
print("Mixing audio failed.", exportSession.error?.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func deleteFileIfExist(at url: URL) {
|
||||
let fileManager = FileManager.default
|
||||
|
||||
do {
|
||||
// Check if the file exists
|
||||
if fileManager.fileExists(atPath: url.path) {
|
||||
// Attempt to delete the file
|
||||
try fileManager.removeItem(at: url)
|
||||
print("File deleted successfully.")
|
||||
} else {
|
||||
print("File does not exist at path: \(url.path)")
|
||||
}
|
||||
} catch {
|
||||
print("Error deleting file: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// func mixAudio() {
|
||||
// guard let recordedAudioURL = recordedAudioURL else { return }
|
||||
// guard let playerURL = audioURLFromMP4 else{return}
|
||||
// let composition = AVMutableComposition()
|
||||
//
|
||||
// // Add the recorded audio
|
||||
// let recordedAudioAsset = AVURLAsset(url: recordedAudioURL)
|
||||
// let recordedAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
|
||||
// do {
|
||||
// try recordedAudioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: recordedAudioAsset.duration), of: recordedAudioAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
|
||||
// } catch {
|
||||
// print("Error adding recorded audio track: \(error.localizedDescription)")
|
||||
// }
|
||||
//
|
||||
// // Add the downloaded M4A file
|
||||
// let playerAsset = AVURLAsset(url: playerURL)
|
||||
// let playerTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
|
||||
//
|
||||
// do {
|
||||
// try playerTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: playerAsset.duration), of: playerAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
|
||||
// } catch {
|
||||
// print("Error adding player audio track: \(error.localizedDescription)")
|
||||
// }
|
||||
//
|
||||
// // Export the mixed audio
|
||||
// let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
||||
// mixedAudioURL = documentsDirectory.appendingPathComponent("mixedAudio.m4a")
|
||||
// guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) else { return }
|
||||
// exportSession.outputURL = mixedAudioURL
|
||||
// exportSession.outputFileType = .m4a
|
||||
// exportSession.exportAsynchronously {
|
||||
// if exportSession.status == .completed {
|
||||
// print("Mixing audio completed.")
|
||||
//
|
||||
// self.saveToFilesApp()
|
||||
// // Play the mixed audio if needed
|
||||
//
|
||||
//
|
||||
// } else if exportSession.status == .failed {
|
||||
// print("Mixing audio failed.")
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
func saveToFilesApp() {
|
||||
guard let mixedAudioURL = mixedAudioURL else { return }
|
||||
DispatchQueue.main.async {
|
||||
let documentPicker = UIDocumentPickerViewController(url: mixedAudioURL, in: .exportToService)
|
||||
documentPicker.delegate = self
|
||||
self.present(documentPicker, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func setupKaraoke(){
|
||||
guard let videoUrl else{return}
|
||||
let avURL = URL(string: videoUrl)!
|
||||
let asset = AVAsset(url: avURL)
|
||||
hideShowKaraoke(isLoading: true)
|
||||
let outputURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(videoTitle?.trimmingCharacters(in: .whitespaces) ?? "extractedAudio").m4a")
|
||||
FileManager.default.clearTmpDirectory()
|
||||
asset.writeAudioTrackToURL(outputURL) { [weak self] isDone, error,url in
|
||||
guard let self else{return}
|
||||
print(isDone, error , url)
|
||||
if error == nil && isDone{
|
||||
hideShowKaraoke(isLoading: false)
|
||||
self.audioURLFromMP4 = url
|
||||
self.setupAudio()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func hideShowKaraoke(isLoading : Bool){
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
if isLoading{
|
||||
karaokeLoading.startAnimating()
|
||||
karaokeStack.isHidden = false
|
||||
startStopRecordingStack.isHidden = true
|
||||
}else{
|
||||
karaokeLoading.stopAnimating()
|
||||
karaokeLoading.hidesWhenStopped = true
|
||||
karaokeStack.isHidden = true
|
||||
startStopRecordingStack.isHidden = false
|
||||
}
|
||||
}
|
||||
self.view.bringSubviewToFront(backButton)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@@ -292,12 +61,22 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
|
||||
self.playBtn.isEnabled = false
|
||||
if isRecording {
|
||||
stopRecording()
|
||||
vm.stopRecording()
|
||||
|
||||
//make sure the interfacebehaviour is enabbled && updated the record btn title and image
|
||||
self.interfaceBehavior = .normal
|
||||
sender.setTitle("Start Recording", for: .normal)
|
||||
} else {
|
||||
//when recording is started change btn name to play and disable it
|
||||
playBtn.setTitle("Play", for: .normal)
|
||||
playBtn.setImage(UIImage(named: "PlayButtonSmall"), for: .normal)
|
||||
playBtn.isEnabled = false
|
||||
downloadRecordingBtn.isEnabled = false
|
||||
self.player.play()
|
||||
|
||||
//make sure the interfacebehaviour is disabled && updated the record btn title and image
|
||||
self.interfaceBehavior = .hidden
|
||||
startRecording()
|
||||
vm.startRecording()
|
||||
sender.setTitle("Stop Recording", for: .normal)
|
||||
}
|
||||
isRecording.toggle()
|
||||
@@ -305,12 +84,13 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
|
||||
@IBAction func playBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
if !isPlaying {
|
||||
playMixedAudio()
|
||||
vm.playMixedAudio()
|
||||
sender.setTitle("Pause", for: .normal)
|
||||
sender.setImage(UIImage(named: "KaraokePause"), for: .normal)
|
||||
|
||||
// Disable Recording while playing, hide controls for jwplayer
|
||||
self.interfaceBehavior = .hidden
|
||||
|
||||
self.startRecordBtn.isEnabled = false
|
||||
self.downloadRecordingBtn.isEnabled = false
|
||||
} else {
|
||||
@@ -329,90 +109,36 @@ class JWKaraokePlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate
|
||||
print("Play")
|
||||
}
|
||||
|
||||
func playMixedAudio() {
|
||||
guard let mixedAudioURL = mixedAudioURL else { return }
|
||||
|
||||
do {
|
||||
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
||||
let destinationURL = documentsDirectoryURL.appendingPathComponent("xyze.m4a")
|
||||
|
||||
// Check if file already exists
|
||||
if FileManager.default.fileExists(atPath: destinationURL.path) {
|
||||
// Delete the existing file
|
||||
try FileManager.default.removeItem(at: destinationURL)
|
||||
}
|
||||
|
||||
// Copy the new file
|
||||
try FileManager.default.copyItem(at: mixedAudioURL, to: destinationURL)
|
||||
|
||||
// Play the audio
|
||||
let playerKAraoke = AVPlayer(url: destinationURL)
|
||||
|
||||
// Adding a completion handler to check if the player starts playing
|
||||
let playerObserver = playerKAraoke.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 1), queue: .main) { time in
|
||||
print("Playing audio at time: \(time.seconds)")
|
||||
}
|
||||
|
||||
// Observing when playback finishes
|
||||
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: playerKAraoke.currentItem, queue: .main) { _ in
|
||||
print("Audio finished playing")
|
||||
// Remove observer
|
||||
playerKAraoke.removeTimeObserver(playerObserver)
|
||||
}
|
||||
|
||||
playerKAraoke.volume = 1.0
|
||||
playerKAraoke.play()
|
||||
print("Audio is playing...")
|
||||
// Uncomment this block if you need to configure the audio session and play using AVAudioPlayer
|
||||
/*
|
||||
// Configure the audio session
|
||||
let audioSession = AVAudioSession.sharedInstance()
|
||||
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker])
|
||||
try audioSession.setActive(true)
|
||||
|
||||
let audioPlayer = try AVAudioPlayer(contentsOf: mixedAudioURL)
|
||||
audioPlayer.volume = 1.0
|
||||
audioPlayer.play()
|
||||
*/
|
||||
|
||||
} catch {
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
@IBAction func downloadRecording(_ sender: LocalisedElementsButton) {
|
||||
print("DownloadRecording")
|
||||
self.saveToFilesApp()
|
||||
vm.saveToFilesApp()
|
||||
}
|
||||
|
||||
@IBAction func backBtnTapped(_ sender: UIButton) {
|
||||
self.player.stop()
|
||||
self.dismiss(animated: true)
|
||||
}
|
||||
|
||||
@IBAction func retryBtnTapped(_ sender: LocalisedElementsButton) {
|
||||
retryKaraokeBtn.isHidden = true
|
||||
vm.setupKaraoke()
|
||||
}
|
||||
// MARK: - JWPlayerViewControllerDelegate
|
||||
|
||||
override func jwplayer(_ player: any JWPlayer, didFinishLoadingWithTime loadTime: TimeInterval) {
|
||||
super.jwplayer(player, didFinishLoadingWithTime: loadTime)
|
||||
print("LoadTime", loadTime)
|
||||
DispatchQueue.main.async {
|
||||
self.startRecordBtn.isEnabled = true
|
||||
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
vm.setupKaraoke()
|
||||
// self.startRecordBtn.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
//Playlist Functions
|
||||
|
||||
// override func jwplayerHasSeeked(_ player: any JWPlayer) {
|
||||
//// if player.getState() != .playing{
|
||||
//// print("Again Play")
|
||||
//// player.play()
|
||||
//// }
|
||||
// print("Seeked " , player.getState())
|
||||
// }
|
||||
|
||||
override func jwplayerIsReady(_ player: JWPlayer) {
|
||||
super.jwplayerIsReady(player)
|
||||
player.seek(to: 0)
|
||||
|
||||
print("IsReady")
|
||||
}
|
||||
|
||||
@@ -458,17 +184,11 @@ extension JWKaraokePlayerVC: UIDocumentPickerDelegate {
|
||||
|
||||
func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
|
||||
deleteTemporaryFile()
|
||||
|
||||
// guard let selectedURL = urls.first else { return }
|
||||
// do {
|
||||
// try FileManager.default.moveItem(at: fileURL, to: selectedURL)
|
||||
// } catch {
|
||||
// print("Error saving file to Files app: \(error)")
|
||||
// }
|
||||
}
|
||||
|
||||
// Method to delete the temporary file
|
||||
func deleteTemporaryFile() {
|
||||
let tempFileURL = audioURLFromMP4!
|
||||
let tempFileURL = vm.audioURLFromMP4!
|
||||
do {
|
||||
try FileManager.default.removeItem(at: tempFileURL)
|
||||
print("Temporary file deleted successfully.")
|
||||
@@ -512,30 +232,7 @@ extension JWKaraokePlayerVC {
|
||||
self.player.stop()
|
||||
controller.dismiss(animated: true)
|
||||
}
|
||||
// self.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
// func playerViewControllerWillGoFullScreen(_ controller: JWPlayerViewController) -> JWFullScreenViewController? {
|
||||
// print("playerViewControllerWillGoFullScreen")
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// func playerViewControllerDidGoFullScreen(_ controller: JWPlayerViewController) {
|
||||
// print("playerViewControllerDidGoFullScreen")
|
||||
// }
|
||||
//
|
||||
// func playerViewControllerWillDismissFullScreen(_ controller: JWPlayerViewController) {
|
||||
// print("playerViewControllerWillDismissFullScreen")
|
||||
// self.player.stop()
|
||||
// self.dismissTapped?()
|
||||
// self.setDeviceOrientation(orientation: .portrait)
|
||||
// }
|
||||
//
|
||||
// func playerViewControllerDidDismissFullScreen(_ controller: JWPlayerViewController) {
|
||||
// print("playerViewControllerDidDismissFullScreen")
|
||||
// Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false) { _ in
|
||||
// self.navigationController?.popViewController(animated: true)
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// MARK: - JWPlayerViewController Delegate Functions
|
||||
|
||||
@@ -215,15 +215,18 @@ class KaraokeDetailsVC: UIViewController {
|
||||
// return
|
||||
|
||||
var itemBuild = JwPlayerItemCreate(url: "")
|
||||
var mp4URL = String()
|
||||
|
||||
if AuthFunc.shareInstance.getDefaultLanguage() == .english{
|
||||
if let englishData = karaokeData?.contentMoreDetails?.filter({$0.languageMasterID == 1}).first{
|
||||
guard let url = englishData.url , let title = englishData.title else{return}
|
||||
guard let url = englishData.url , let title = englishData.title, let englishMp4URL = englishData.videoUrlHd else{return}
|
||||
mp4URL = englishMp4URL
|
||||
itemBuild = JwPlayerItemCreate(url: url, poster: karaokeData?.thumbnailPath, titles: title)
|
||||
}
|
||||
}else{
|
||||
if let hindiData = karaokeData?.contentMoreDetails?.filter({$0.languageMasterID == 2}).first{
|
||||
guard let url = hindiData.url , let title = hindiData.title else{return}
|
||||
guard let url = hindiData.url , let title = hindiData.title , let hindiMp4URL = hindiData.videoUrlHd else{return}
|
||||
mp4URL = hindiMp4URL
|
||||
itemBuild = JwPlayerItemCreate(url: url, poster: karaokeData?.thumbnailPath, titles: title)
|
||||
}
|
||||
}
|
||||
@@ -250,8 +253,8 @@ class KaraokeDetailsVC: UIViewController {
|
||||
.build()
|
||||
|
||||
vc.config = config
|
||||
vc.videoTitle = itemBuild.titles
|
||||
vc.videoUrl = itemBuild.url
|
||||
vc.vm.videoTitle = itemBuild.titles
|
||||
vc.vm.videoUrl = mp4URL
|
||||
|
||||
vc.modalPresentationStyle = .overFullScreen
|
||||
vc.modalTransitionStyle = .crossDissolve
|
||||
@@ -267,21 +270,7 @@ class KaraokeDetailsVC: UIViewController {
|
||||
// Dismiss the progress HUD after the view controller presentation
|
||||
Utilities.dismissProgressHUD()
|
||||
|
||||
}
|
||||
// DispatchQueue.main.async { [weak self] in
|
||||
// guard let self else{return}
|
||||
// Utilities.startProgressHUD()
|
||||
// let sb = UIStoryboard(name: K.StoryBoard.Karaoke, bundle: nil)
|
||||
// let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Karaoke.aVPlayerVC) as! AVPlayerVC
|
||||
// vc.videoURL = itemBuild.url
|
||||
// vc.titleVideo = itemBuild.titles
|
||||
// vc.modalPresentationStyle = .fullScreen
|
||||
// self.present(vc, animated: true)
|
||||
// // Dismiss the progress HUD after the view controller presentation
|
||||
// Utilities.dismissProgressHUD()
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -619,6 +619,28 @@
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<button hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="tailTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="L00-cA-hv1" customClass="LocalisedElementsButton" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="50"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="50" id="mBJ-xn-J0m"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<inset key="titleEdgeInsets" minX="5" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
<inset key="imageEdgeInsets" minX="-10" minY="0.0" maxX="10" maxY="0.0"/>
|
||||
<state key="normal" title="Retry" image="Reload">
|
||||
<color key="titleColor" name="ImageDarkBlue"/>
|
||||
</state>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
|
||||
<integer key="value" value="25"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="retryBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="XII-fx-hrA"/>
|
||||
</connections>
|
||||
</button>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="7RJ-zB-bI1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="374" height="86"/>
|
||||
<subviews>
|
||||
@@ -642,7 +664,6 @@
|
||||
</userDefinedRuntimeAttribute>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="ru7-Wv-EJr"/>
|
||||
<action selector="startRecordingBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="2bh-Cr-Joy"/>
|
||||
</connections>
|
||||
</button>
|
||||
@@ -664,7 +685,6 @@
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="playBtnTapped:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="WZm-M9-WLE"/>
|
||||
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="NX9-0v-D3v"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
@@ -684,7 +704,6 @@
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="downloadRecording:" destination="9gy-Qq-XHU" eventType="touchUpInside" id="kED-rq-2EY"/>
|
||||
<action selector="playNowBtnTapped:" destination="fax-bi-Mb9" eventType="touchUpInside" id="Smw-Oi-Xnt"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
@@ -709,8 +728,9 @@
|
||||
<outlet property="karaokeStack" destination="Oj2-hr-beY" id="apD-yP-Yfh"/>
|
||||
<outlet property="outerStack" destination="yek-VM-Cus" id="nRc-sO-HjJ"/>
|
||||
<outlet property="playBtn" destination="4rT-nK-Wb6" id="XLE-Da-4YA"/>
|
||||
<outlet property="retryKaraokeBtn" destination="L00-cA-hv1" id="sNS-JU-CLM"/>
|
||||
<outlet property="startRecordBtn" destination="vbj-gW-VZl" id="QV4-c3-Fub"/>
|
||||
<outlet property="startStopRecordingStack" destination="7RJ-zB-bI1" id="LeT-d7-eoh"/>
|
||||
<outlet property="startStopRecordingStack" destination="7RJ-zB-bI1" id="2vl-wr-cYu"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="s0j-fC-RFe" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
@@ -725,6 +745,7 @@
|
||||
<image name="LikeRemove" width="42.5" height="42.5"/>
|
||||
<image name="Microphone" width="31" height="31"/>
|
||||
<image name="PlayButtonSmall" width="28.333333969116211" height="28.333333969116211"/>
|
||||
<image name="Reload" width="42.5" height="42.5"/>
|
||||
<image name="ShareImage" width="18" height="18"/>
|
||||
<image name="WebSeriesSeasonsBackground" width="142.66667175292969" height="187.33332824707031"/>
|
||||
<image name="hand.thumbsup.fill" catalog="system" width="128" height="121"/>
|
||||
|
||||
@@ -59,7 +59,8 @@ struct KaraokeListingDM: Codable {
|
||||
let title, description: String?
|
||||
let url: String?
|
||||
let tagsKeywords: String?
|
||||
|
||||
let videoUrlHd : String?
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case id
|
||||
case contentID = "content_id"
|
||||
@@ -67,6 +68,7 @@ struct KaraokeListingDM: Codable {
|
||||
case languageMasterID = "language_master_id"
|
||||
case title, description, url
|
||||
case tagsKeywords = "tags_keywords"
|
||||
case videoUrlHd = "video_url_hd"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
279
WOKA/Karaoke/ViewModel/JWKaraokePlayerVM.swift
Normal file
279
WOKA/Karaoke/ViewModel/JWKaraokePlayerVM.swift
Normal file
@@ -0,0 +1,279 @@
|
||||
//
|
||||
// JWKaraokePlayerVM.swift
|
||||
// WOKA
|
||||
//
|
||||
// Created by Bilal on 09/08/2024.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AVFAudio
|
||||
import AVFoundation
|
||||
|
||||
class JWKaraokePlayerVM{
|
||||
|
||||
weak var vc : JWKaraokePlayerVC!
|
||||
var mixedAudioURL: URL?
|
||||
var audioURLFromMP4 : URL?
|
||||
var recordedAudioURL: URL?
|
||||
var audioRecorder: AVAudioRecorder?
|
||||
var videoTitle : String?
|
||||
var videoUrl : String?
|
||||
|
||||
//Start and end time for trimming the audio
|
||||
var startTime : TimeInterval?
|
||||
var endTime : TimeInterval?
|
||||
|
||||
func initView(){
|
||||
vc.downloadRecordingBtn.isEnabled = false
|
||||
hideShowKaraoke(isLoading: true)
|
||||
}
|
||||
|
||||
// MARK: - Document Directory Save & Fetch audio for recording
|
||||
|
||||
func saveToFilesApp() {
|
||||
guard let mixedAudioURL = mixedAudioURL else { return }
|
||||
DispatchQueue.main.async {
|
||||
let documentPicker = UIDocumentPickerViewController(url: mixedAudioURL, in: .exportToService)
|
||||
documentPicker.delegate = self.vc
|
||||
self.vc.present(documentPicker, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func setupKaraoke(){
|
||||
guard let videoUrl else{return}
|
||||
let avURL = URL(string: videoUrl)!
|
||||
let asset = AVAsset(url: avURL)
|
||||
hideShowKaraoke(isLoading: true)
|
||||
let outputURL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("\(videoTitle?.trimmingCharacters(in: .whitespaces) ?? "extractedAudio").m4a")
|
||||
FileManager.default.clearTmpDirectory()
|
||||
asset.writeAudioTrackToURL(outputURL) { [weak self] isDone, error,url in
|
||||
guard let self else{return}
|
||||
print(isDone, error , url)
|
||||
DispatchQueue.main.async {
|
||||
if error == nil && isDone{
|
||||
self.hideShowKaraoke(isLoading: false)
|
||||
self.audioURLFromMP4 = url
|
||||
self.setupAudio()
|
||||
}else{
|
||||
print("errrrrr", error)
|
||||
self.vc.karaokeLoading.stopAnimating()
|
||||
self.vc.karaokeStack.isHidden = true
|
||||
self.vc.startStopRecordingStack.isHidden = true
|
||||
|
||||
self.vc.retryKaraokeBtn.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func hideShowKaraoke(isLoading : Bool){
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
if isLoading{
|
||||
vc.karaokeLoading.startAnimating()
|
||||
vc.karaokeStack.isHidden = false
|
||||
vc.startStopRecordingStack.isHidden = true
|
||||
}else{
|
||||
vc.karaokeLoading.stopAnimating()
|
||||
vc.karaokeLoading.hidesWhenStopped = true
|
||||
vc.karaokeStack.isHidden = true
|
||||
vc.startStopRecordingStack.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - AudioRecording
|
||||
|
||||
func setupAudio() {
|
||||
// FileManager.default.clearTmpDirectory()
|
||||
|
||||
let audioSession = AVAudioSession.sharedInstance()
|
||||
do {
|
||||
try audioSession.setCategory(.playAndRecord, mode: .default,options: .defaultToSpeaker)
|
||||
try audioSession.setActive(true)
|
||||
|
||||
// // URL of the downloaded M4A file
|
||||
// guard let audioURL = Bundle.main.url(forResource: "Sample_audio", withExtension: "m4a") else {
|
||||
// print("Audio file not found.")
|
||||
// return
|
||||
// }
|
||||
|
||||
// Initialize AVAudioPlayer with the downloaded M4A file
|
||||
// player = try AVAudioPlayer(contentsOf: audioURLFromMP4!)
|
||||
// player?.prepareToPlay()
|
||||
|
||||
// Define settings for the audio recorder
|
||||
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
||||
let outputURL = documentsDirectory.appendingPathComponent("recordedAudio.m4a")
|
||||
let settings: [String: Any] = [
|
||||
AVFormatIDKey: kAudioFormatMPEG4AAC,
|
||||
AVSampleRateKey: 44100,
|
||||
AVNumberOfChannelsKey: 2,
|
||||
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
|
||||
]
|
||||
|
||||
// Initialize AVAudioRecorder with the output URL and settings
|
||||
audioRecorder = try AVAudioRecorder(url: outputURL, settings: settings)
|
||||
audioRecorder?.prepareToRecord()
|
||||
recordedAudioURL = outputURL // Store the recorded audio URL
|
||||
} catch {
|
||||
print("Error setting up audio: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
func startRecording() {
|
||||
startTime = vc.player.time.position.round(to: 1)
|
||||
vc.interfaceBehavior = .hidden
|
||||
guard let audioRecorder = audioRecorder else { return }
|
||||
audioRecorder.record()
|
||||
}
|
||||
|
||||
func stopRecording() {
|
||||
endTime = vc.player.time.position.round(to: 1)
|
||||
vc.interfaceBehavior = .normal
|
||||
guard let audioRecorder = audioRecorder else { return }
|
||||
audioRecorder.stop()
|
||||
vc.player.pause()
|
||||
// Mix the recorded audio with the downloaded M4A file
|
||||
guard let startTime , let endTime else{return}
|
||||
mixAudio(start: startTime, stop: endTime)
|
||||
}
|
||||
|
||||
func playMixedAudio() {
|
||||
guard let mixedAudioURL = mixedAudioURL else { return }
|
||||
|
||||
do {
|
||||
let documentsDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
||||
let destinationURL = documentsDirectoryURL.appendingPathComponent("xyze.m4a")
|
||||
|
||||
// Check if file already exists
|
||||
if FileManager.default.fileExists(atPath: destinationURL.path) {
|
||||
// Delete the existing file
|
||||
try FileManager.default.removeItem(at: destinationURL)
|
||||
}
|
||||
|
||||
// Copy the new file
|
||||
try FileManager.default.copyItem(at: mixedAudioURL, to: destinationURL)
|
||||
|
||||
// Play the audio
|
||||
let playerKAraoke = AVPlayer(url: destinationURL)
|
||||
|
||||
// Adding a completion handler to check if the player starts playing
|
||||
let playerObserver = playerKAraoke.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 1), queue: .main) { time in
|
||||
print("Playing audio at time: \(time.seconds)")
|
||||
}
|
||||
|
||||
// Observing when playback finishes
|
||||
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: playerKAraoke.currentItem, queue: .main) { [weak self] _ in
|
||||
print("Audio finished playing")
|
||||
guard let self else{return}
|
||||
self.vc.playBtn.setTitle("Play", for: .normal)
|
||||
self.vc.playBtn.setImage(UIImage(named: "PlayButtonSmall"), for: .normal)
|
||||
|
||||
// Disable Recording while playing, hide controls for jwplayer
|
||||
self.vc.interfaceBehavior = .normal
|
||||
self.vc.startRecordBtn.isEnabled = true
|
||||
self.vc.downloadRecordingBtn.isEnabled = true
|
||||
// Remove observer
|
||||
playerKAraoke.removeTimeObserver(playerObserver)
|
||||
}
|
||||
|
||||
playerKAraoke.volume = 1.0
|
||||
playerKAraoke.play()
|
||||
print("Audio is playing...")
|
||||
// Uncomment this block if you need to configure the audio session and play using AVAudioPlayer
|
||||
/*
|
||||
// Configure the audio session
|
||||
let audioSession = AVAudioSession.sharedInstance()
|
||||
try audioSession.setCategory(.playAndRecord, mode: .default, options: [.defaultToSpeaker])
|
||||
try audioSession.setActive(true)
|
||||
|
||||
let audioPlayer = try AVAudioPlayer(contentsOf: mixedAudioURL)
|
||||
audioPlayer.volume = 1.0
|
||||
audioPlayer.play()
|
||||
*/
|
||||
|
||||
} catch {
|
||||
print("Error: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
|
||||
func mixAudio(start : TimeInterval, stop : TimeInterval) {
|
||||
let totalTime = stop - start
|
||||
guard let recordedAudioURL = recordedAudioURL else { return }
|
||||
guard let playerURL = audioURLFromMP4 else { return }
|
||||
Utilities.startProgressHUD(msg: "Mixing Audio")
|
||||
let composition = AVMutableComposition()
|
||||
let compositionDuration = CMTime(seconds: totalTime, preferredTimescale: 1)
|
||||
|
||||
// Add the recorded audio from 0 to 10 seconds
|
||||
let recordedAudioAsset = AVURLAsset(url: recordedAudioURL)
|
||||
let recordedAudioTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
|
||||
|
||||
do {
|
||||
try recordedAudioTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: compositionDuration), of: recordedAudioAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
|
||||
} catch {
|
||||
Utilities.dismissProgressHUD()
|
||||
print("Error adding recorded audio track: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
// Add the downloaded M4A file from 10 to 20 seconds
|
||||
let playerAsset = AVURLAsset(url: playerURL)
|
||||
let playerTrack = composition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
|
||||
|
||||
do {
|
||||
try playerTrack?.insertTimeRange(CMTimeRangeMake(start: CMTime(seconds: start, preferredTimescale: 1), duration: compositionDuration), of: playerAsset.tracks(withMediaType: .audio)[0], at: CMTime.zero)
|
||||
} catch {
|
||||
Utilities.dismissProgressHUD()
|
||||
print("Error adding player audio track: \(error.localizedDescription)")
|
||||
}
|
||||
|
||||
// Example usage:
|
||||
|
||||
|
||||
// Export the mixed audio
|
||||
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
|
||||
let fileName = "\((self.videoTitle?.replacingOccurrences(of: " ", with: "").replacingOccurrences(of: ".", with: "") ?? "Audio") + Date().timeIntervalSince1970.toString()).m4a"
|
||||
let filePath = documentsDirectory.appendingPathComponent(fileName)
|
||||
deleteFileIfExist(at: filePath)
|
||||
|
||||
mixedAudioURL = filePath
|
||||
|
||||
guard let exportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A) else { return }
|
||||
exportSession.outputURL = mixedAudioURL
|
||||
exportSession.outputFileType = .m4a
|
||||
|
||||
exportSession.exportAsynchronously {
|
||||
if exportSession.status == .completed {
|
||||
print("Mixing audio completed.")
|
||||
Utilities.dismissProgressHUD()
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
vc.playBtn.isEnabled = true
|
||||
vc.downloadRecordingBtn.isEnabled = true
|
||||
}
|
||||
|
||||
|
||||
} else if exportSession.status == .failed {
|
||||
print("Mixing audio failed.", exportSession.error?.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func deleteFileIfExist(at url: URL) {
|
||||
let fileManager = FileManager.default
|
||||
|
||||
do {
|
||||
// Check if the file exists
|
||||
if fileManager.fileExists(atPath: url.path) {
|
||||
// Attempt to delete the file
|
||||
try fileManager.removeItem(at: url)
|
||||
print("File deleted successfully.")
|
||||
} else {
|
||||
print("File does not exist at path: \(url.path)")
|
||||
}
|
||||
} catch {
|
||||
print("Error deleting file: \(error.localizedDescription)")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -190,15 +190,15 @@ class KaraokeListingVM{
|
||||
if let showListIndex = karaokeListData.firstIndex(where: { $0.id == postID }){
|
||||
karaokeListData[showListIndex].markAsFavourite = false
|
||||
vc.karaokeListingTableView.reloadRows(at: [IndexPath(row: showListIndex, section: 0)],with: .none)
|
||||
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
if let indexRemove = MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.firstIndex(where: {$0.id == postID}){
|
||||
MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.remove(at: indexRemove)
|
||||
K.GVar.myListSoftReload = true
|
||||
|
||||
}
|
||||
}
|
||||
K.GVar.reloadMyList = true
|
||||
// // MyList Update
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// if let indexRemove = MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.firstIndex(where: {$0.id == postID}){
|
||||
// MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.remove(at: indexRemove)
|
||||
// K.GVar.myListSoftReload = true
|
||||
//
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -207,15 +207,15 @@ class KaraokeListingVM{
|
||||
if let continueWatchingIndex = continueWatchingData.firstIndex(where: { $0.id == postID }){
|
||||
continueWatchingData[continueWatchingIndex].markAsFavourite = false
|
||||
vc.continueWatchingCV.reloadItems(at: [IndexPath(row: continueWatchingIndex, section: 0)])
|
||||
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
if let indexRemove = MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.firstIndex(where: {$0.id == postID}){
|
||||
MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.remove(at: indexRemove)
|
||||
K.GVar.myListSoftReload = true
|
||||
|
||||
}
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// if let indexRemove = MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.firstIndex(where: {$0.id == postID}){
|
||||
// MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.remove(at: indexRemove)
|
||||
// K.GVar.myListSoftReload = true
|
||||
//
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,13 +225,14 @@ class KaraokeListingVM{
|
||||
if let showListIndex = karaokeListData.firstIndex(where: { $0.id == postID }){
|
||||
karaokeListData[showListIndex].markAsFavourite = true
|
||||
vc.karaokeListingTableView.reloadRows(at: [IndexPath(row: showListIndex, section: 0)],with: .none)
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
let karaokeData = karaokeListData[showListIndex]
|
||||
MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.append(karaokeData)
|
||||
K.GVar.myListSoftReload = true
|
||||
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// let karaokeData = karaokeListData[showListIndex]
|
||||
// MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.append(karaokeData)
|
||||
// K.GVar.myListSoftReload = true
|
||||
//
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -240,17 +241,17 @@ class KaraokeListingVM{
|
||||
if let continueWatchingIndex = continueWatchingData.firstIndex(where: { $0.id == postID }){
|
||||
continueWatchingData[continueWatchingIndex].markAsFavourite = true
|
||||
vc.continueWatchingCV.reloadItems(at: [IndexPath(row: continueWatchingIndex, section: 0)])
|
||||
|
||||
K.GVar.reloadMyList = true
|
||||
// MyList Update
|
||||
if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// if data is updated for main list this ill not work
|
||||
if MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.firstIndex(where: {$0.id == postID}) == nil{
|
||||
let audioData = continueWatchingData[continueWatchingIndex]
|
||||
MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.append(audioData)
|
||||
K.GVar.myListSoftReload = true
|
||||
|
||||
}
|
||||
}
|
||||
// if MyListDataTemp.shareInstance.isDatafetched{
|
||||
// // if data is updated for main list this ill not work
|
||||
// if MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.firstIndex(where: {$0.id == postID}) == nil{
|
||||
// let audioData = continueWatchingData[continueWatchingIndex]
|
||||
// MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.append(audioData)
|
||||
// K.GVar.myListSoftReload = true
|
||||
//
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,7 +308,7 @@ class KaraokeListingVM{
|
||||
}
|
||||
|
||||
/*
|
||||
Check if the data is in karaoke
|
||||
Check if the data is in karaoke mylist
|
||||
*/
|
||||
if let index = MyListDataTemp.shareInstance.favListingData?.singKaraokeData?.firstIndex(where: {$0.id == postID}){
|
||||
MyListDataTemp.shareInstance.favListingData?.singKaraokeData?[index].isLiked = true
|
||||
|
||||
@@ -16,6 +16,9 @@ class MyOrderDetailsVC: UIViewController {
|
||||
@IBOutlet weak var expectedDate: UILabel!
|
||||
@IBOutlet weak var tableView: UITableView!
|
||||
|
||||
@IBOutlet weak var noDataStack: UIStackView!
|
||||
@IBOutlet weak var mainStack: UIStackView!
|
||||
|
||||
var orderID : String?
|
||||
var data : OrderDetailsDM.ResultData?
|
||||
|
||||
@@ -34,6 +37,12 @@ class MyOrderDetailsVC: UIViewController {
|
||||
tableView.dataSource = self
|
||||
}
|
||||
|
||||
@IBAction func retryBtnTapped(_ sender: UIButton) {
|
||||
if let orderID{
|
||||
getOrdersDetails(orderID: orderID)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Get MyORders
|
||||
|
||||
func getOrdersDetails(orderID : String){
|
||||
@@ -47,6 +56,8 @@ class MyOrderDetailsVC: UIViewController {
|
||||
switch data.success{
|
||||
case 0:
|
||||
Utilities.dismissProgressHUD()
|
||||
self?.toast(msg: K.ConstantString.unRecognised, time: 1.5)
|
||||
self?.noDataStack.isHidden = false
|
||||
return
|
||||
case 1:
|
||||
Utilities.dismissProgressHUD()
|
||||
@@ -54,12 +65,16 @@ class MyOrderDetailsVC: UIViewController {
|
||||
self.data = data
|
||||
self.tableView.reloadData()
|
||||
setData()
|
||||
self.mainStack.isHidden = false
|
||||
self.tableView.isHidden = false
|
||||
self.noDataStack.isHidden = true
|
||||
default:
|
||||
break
|
||||
}
|
||||
case .failure(let error):
|
||||
Utilities.dismissProgressHUD()
|
||||
print(error)
|
||||
self?.noDataStack.isHidden = false
|
||||
self?.toast(msg: error.localizedDescription, time: 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,14 +52,24 @@ extension MyOrdersVC : TableViewSRC{
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: K.CellIdentifier.SideBarNav.myOrderCell) as! MyOrderCell
|
||||
let data = vm.orderData[indexPath.row]
|
||||
cell.setData(data: data)
|
||||
|
||||
cell.btnTapped = { [weak self] in
|
||||
guard let self else{return}
|
||||
|
||||
let sb = UIStoryboard(name: K.StoryBoard.sideBarNav, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.SideBarNav.myOrderDetailsVC) as! MyOrderDetailsVC
|
||||
let orderID = vm.orderData[indexPath.row].orderID
|
||||
vcPush.orderID = orderID
|
||||
self.navigationController?.present(vcPush, animated: true)
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let sb = UIStoryboard(name: K.StoryBoard.sideBarNav, bundle: nil)
|
||||
let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.SideBarNav.myOrderDetailsVC) as! MyOrderDetailsVC
|
||||
let orderID = vm.orderData[indexPath.row].orderID
|
||||
vcPush.orderID = orderID
|
||||
self.navigationController?.present(vcPush, animated: true)
|
||||
// let sb = UIStoryboard(name: K.StoryBoard.sideBarNav, bundle: nil)
|
||||
// let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.SideBarNav.myOrderDetailsVC) as! MyOrderDetailsVC
|
||||
// let orderID = vm.orderData[indexPath.row].orderID
|
||||
// vcPush.orderID = orderID
|
||||
// self.navigationController?.present(vcPush, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,14 +710,43 @@
|
||||
<constraint firstAttribute="height" constant="15" id="CtV-ZL-cNd"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="yKd-Wm-7Eb">
|
||||
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="uYU-Td-S3P">
|
||||
<rect key="frame" x="95" y="321.5" width="224" height="267.5"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SupportGirlImage" translatesAutoresizingMaskIntoConstraints="NO" id="0Q1-k8-Stp">
|
||||
<rect key="frame" x="0.0" y="0.0" width="224" height="166"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mKx-5X-KDL" customClass="LocalisedElementsLabel" customModule="WOKA" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="176" width="224" height="48"/>
|
||||
<string key="text">Something went wrong.
|
||||
Retry after some time</string>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" name="TextDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="QJt-Pf-YLm">
|
||||
<rect key="frame" x="0.0" y="234" width="224" height="33.5"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Medium" family="Exo 2" pointSize="16"/>
|
||||
<color key="tintColor" name="ImageDarkBlue"/>
|
||||
<inset key="imageEdgeInsets" minX="0.0" minY="0.0" maxX="2.2250738585072014e-308" maxY="0.0"/>
|
||||
<state key="normal" title="Retry?"/>
|
||||
<buttonConfiguration key="configuration" style="plain" title="Retry?">
|
||||
<fontDescription key="titleFontDescription" name="Exo2-Medium" family="Exo 2" pointSize="16"/>
|
||||
</buttonConfiguration>
|
||||
<connections>
|
||||
<action selector="retryBtnTapped:" destination="iq2-ef-Mlf" eventType="touchUpInside" id="0FJ-yX-D4v"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView hidden="YES" opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="7" translatesAutoresizingMaskIntoConstraints="NO" id="yKd-Wm-7Eb">
|
||||
<rect key="frame" x="10" y="58" width="394" height="150.5"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="gHG-Sq-26N">
|
||||
<rect key="frame" x="10" y="15" width="374" height="24"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="3" translatesAutoresizingMaskIntoConstraints="NO" id="qa1-U8-wO9">
|
||||
<rect key="frame" x="91.5" y="0.0" width="191" height="24"/>
|
||||
<rect key="frame" x="128.5" y="0.0" width="117.5" height="24"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" text="Order ID :" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0pK-Sr-Zu5">
|
||||
<rect key="frame" x="0.0" y="0.0" width="87" height="24"/>
|
||||
@@ -725,8 +754,8 @@
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" text="W12121212" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XOs-lG-BTm">
|
||||
<rect key="frame" x="90" y="0.0" width="101" height="24"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" text="NA" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="XOs-lG-BTm">
|
||||
<rect key="frame" x="90" y="0.0" width="27.5" height="24"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="20"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -751,7 +780,7 @@
|
||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" text="W12121212" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hBF-FJ-TnF">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" text="NA" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hBF-FJ-TnF">
|
||||
<rect key="frame" x="138" y="0.0" width="236" height="19.5"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
@@ -768,7 +797,7 @@
|
||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" text="W12121212" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="75q-hi-LB9">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" text="NA" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="75q-hi-LB9">
|
||||
<rect key="frame" x="54" y="0.0" width="320" height="19.5"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
@@ -785,7 +814,7 @@
|
||||
<color key="textColor" white="0.66666666669999997" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" text="W12121212" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2nO-72-dWp">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="252" text="NA" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="2nO-72-dWp">
|
||||
<rect key="frame" x="104" y="0.0" width="270" height="19.5"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<color key="textColor" name="ImageDarkBlue"/>
|
||||
@@ -796,7 +825,7 @@
|
||||
</subviews>
|
||||
<edgeInsets key="layoutMargins" top="15" left="10" bottom="15" right="10"/>
|
||||
</stackView>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="MeS-Fv-FWi">
|
||||
<tableView hidden="YES" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="none" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="-1" estimatedSectionHeaderHeight="-1" sectionFooterHeight="-1" estimatedSectionFooterHeight="-1" translatesAutoresizingMaskIntoConstraints="NO" id="MeS-Fv-FWi">
|
||||
<rect key="frame" x="0.0" y="213.5" width="414" height="643.5"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
</tableView>
|
||||
@@ -804,8 +833,10 @@
|
||||
<viewLayoutGuide key="safeArea" id="EUh-wH-T1u"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstItem="uYU-Td-S3P" firstAttribute="centerY" secondItem="EUh-wH-T1u" secondAttribute="centerY" id="5TQ-XJ-NvN"/>
|
||||
<constraint firstItem="yKd-Wm-7Eb" firstAttribute="top" secondItem="EUh-wH-T1u" secondAttribute="top" constant="10" id="Eze-3L-ONQ"/>
|
||||
<constraint firstItem="EUh-wH-T1u" firstAttribute="bottom" secondItem="MeS-Fv-FWi" secondAttribute="bottom" constant="5" id="I1j-1P-h2P"/>
|
||||
<constraint firstItem="uYU-Td-S3P" firstAttribute="centerX" secondItem="EUh-wH-T1u" secondAttribute="centerX" id="Kxg-cC-WoH"/>
|
||||
<constraint firstItem="MeS-Fv-FWi" firstAttribute="top" secondItem="yKd-Wm-7Eb" secondAttribute="bottom" constant="5" id="Ws2-Im-96q"/>
|
||||
<constraint firstItem="EUh-wH-T1u" firstAttribute="trailing" secondItem="MeS-Fv-FWi" secondAttribute="trailing" id="YgT-Bw-if4"/>
|
||||
<constraint firstItem="MeS-Fv-FWi" firstAttribute="leading" secondItem="EUh-wH-T1u" secondAttribute="leading" id="dkd-J0-hhe"/>
|
||||
@@ -819,6 +850,8 @@
|
||||
<connections>
|
||||
<outlet property="airWayBillNo" destination="hBF-FJ-TnF" id="7CS-13-G5N"/>
|
||||
<outlet property="expectedDate" destination="2nO-72-dWp" id="tlh-7p-D8l"/>
|
||||
<outlet property="mainStack" destination="yKd-Wm-7Eb" id="xc6-gR-Wvf"/>
|
||||
<outlet property="noDataStack" destination="uYU-Td-S3P" id="rE3-W9-ciA"/>
|
||||
<outlet property="orderIDNumber" destination="XOs-lG-BTm" id="SgR-et-rLR"/>
|
||||
<outlet property="status" destination="75q-hi-LB9" id="Y5O-w2-id5"/>
|
||||
<outlet property="tableView" destination="MeS-Fv-FWi" id="v5B-8C-dLj"/>
|
||||
|
||||
@@ -15,6 +15,9 @@ class MyOrderCell: UITableViewCell {
|
||||
@IBOutlet weak var courierNumber: UILabel!
|
||||
@IBOutlet weak var price: UILabel!
|
||||
|
||||
typealias btnTappedBlock = () -> Void
|
||||
var btnTapped : btnTappedBlock!
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
// Initialization code
|
||||
@@ -34,5 +37,8 @@ class MyOrderCell: UITableViewCell {
|
||||
}
|
||||
|
||||
@IBAction func trackBtnTapped(_ sender: UIButton) {
|
||||
if btnTapped != nil {
|
||||
btnTapped()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,11 +13,20 @@ class MyOrdersVM{
|
||||
weak var vc : MyOrdersVC!
|
||||
var cartButton: UIBarButtonItem!
|
||||
var pageNo = 1
|
||||
var stopFetch = false
|
||||
var orderData = [OrderListingDM.Datum]()
|
||||
|
||||
var footerView = UIView()
|
||||
|
||||
let refreshControl = UIRefreshControl()
|
||||
let feedbackGenerator = UIImpactFeedbackGenerator(style: .light)
|
||||
func initView(){
|
||||
|
||||
vc.title = "MY ORDERS".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue)
|
||||
vc.tableView.indicatorStyle = .black
|
||||
refreshControl.attributedTitle = NSAttributedString(string: "Refreshing...",attributes: [.foregroundColor: UIColor.appColor(.TextDarkBlue)!])
|
||||
refreshControl.tintColor = UIColor.appColor(.TextDarkBlue)!
|
||||
refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
|
||||
vc.tableView.addSubview(refreshControl)
|
||||
|
||||
cartButton = BadgeBarBtn.shared.setupCartButton(target: self, action: #selector(self.cartButtonTapped))
|
||||
self.vc.navigationItem.rightBarButtonItem = cartButton
|
||||
@@ -34,7 +43,12 @@ class MyOrdersVM{
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the footer view with a button
|
||||
let footerView = createFooterView()
|
||||
vc.tableView.tableFooterView = footerView
|
||||
self.toggleFooterView(show: false)
|
||||
setupCell()
|
||||
Utilities.startProgressHUD()
|
||||
getOrders()
|
||||
}
|
||||
|
||||
@@ -52,34 +66,109 @@ class MyOrdersVM{
|
||||
self.vc.navigationController?.pushViewController(vcPush, animated: true)
|
||||
}
|
||||
|
||||
@objc func refresh(_ sender: AnyObject) {
|
||||
pageNo = 1
|
||||
self.getOrders()
|
||||
}
|
||||
|
||||
// MARK: - Get MyORders
|
||||
|
||||
func getOrders(){
|
||||
Utilities.startProgressHUD()
|
||||
let headers : HTTPHeaders = ["Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi",
|
||||
"access-token": AuthFunc.shareInstance.getAccessToken()]
|
||||
let params : Parameters = ["limit" : "10"]
|
||||
let url = "\(APIEndPoints.SideBarNav.order_listing )?page=\(pageNo)"
|
||||
NetworkManager.shareInstance.apiRequest(url: url, method: .post, parameters: params,headers : headers) {(result : Result<BaseResponseModel<OrderListingDM>, NetworkManager.APIError>) in
|
||||
NetworkManager.shareInstance.apiRequest(url: url, method: .post, parameters: params,headers : headers) { [weak self](result : Result<BaseResponseModel<OrderListingDM>, NetworkManager.APIError>) in
|
||||
switch result{
|
||||
case .success(let data):
|
||||
switch data.success{
|
||||
case 0:
|
||||
guard let self else{return}
|
||||
Utilities.dismissProgressHUD()
|
||||
refreshControl.endRefreshing()
|
||||
return
|
||||
case 1:
|
||||
Utilities.dismissProgressHUD()
|
||||
guard let data = data.data?.result?.data else{return}
|
||||
self.orderData = data
|
||||
guard let self, let totalCount = data.data?.result?.total , let data = data.data?.result?.data else{
|
||||
Utilities.dismissProgressHUD()
|
||||
self?.refreshControl.endRefreshing()
|
||||
return
|
||||
}
|
||||
if refreshControl.isRefreshing{
|
||||
self.orderData.removeAll()
|
||||
}
|
||||
self.orderData.append(contentsOf: data)
|
||||
if self.orderData.count == totalCount{
|
||||
self.toggleFooterView(show: false)
|
||||
}else{
|
||||
self.toggleFooterView(show: true)
|
||||
}
|
||||
self.vc.tableView.reloadData()
|
||||
Utilities.dismissProgressHUD()
|
||||
refreshControl.endRefreshing()
|
||||
feedbackGenerator.impactOccurred()
|
||||
default:
|
||||
break
|
||||
}
|
||||
case .failure(let error):
|
||||
guard let self else{return}
|
||||
Utilities.dismissProgressHUD()
|
||||
refreshControl.endRefreshing()
|
||||
print(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle footer view visibility
|
||||
func toggleFooterView(show: Bool) {
|
||||
if show {
|
||||
vc.tableView.tableFooterView = footerView
|
||||
} else {
|
||||
vc.tableView.tableFooterView = nil
|
||||
}
|
||||
}
|
||||
|
||||
func createFooterView() -> UIView {
|
||||
// Create a UIView for the footer
|
||||
footerView = UIView(frame: CGRect(x: 0, y: 0, width: vc.view.frame.width, height: 60))
|
||||
footerView.backgroundColor = .clear // You can set a background color if you want
|
||||
|
||||
// Create a UIButton
|
||||
let button = UIButton(type: .system)
|
||||
button.setTitle("Load More", for: .normal)
|
||||
button.titleLabel?.font = FontCustom.shareInstance.customFont(fontName: .Exo2_Bold, size: 16)
|
||||
button.backgroundColor = UIColor.appColor(.TextDarkBlue)
|
||||
button.setTitleColor(.white, for: .normal)
|
||||
button.layer.cornerRadius = 25
|
||||
button.frame = CGRect(x: 0, y: 0, width: vc.view.frame.width, height: 50)
|
||||
|
||||
// Add action to the button
|
||||
button.addTarget(self, action: #selector(footerButtonTapped), for: .touchUpInside)
|
||||
|
||||
button.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
// Add the button to the footer view
|
||||
footerView.addSubview(button)
|
||||
|
||||
// Set up Auto Layout constraints
|
||||
NSLayoutConstraint.activate([
|
||||
// Center the button horizontally in the footer view
|
||||
button.centerXAnchor.constraint(equalTo: footerView.centerXAnchor),
|
||||
// Center the button vertically in the footer view
|
||||
button.centerYAnchor.constraint(equalTo: footerView.centerYAnchor),
|
||||
// Set the button's width with 50 points padding from each side
|
||||
// button.leadingAnchor.constraint(equalTo: footerView.leadingAnchor, constant: 50),
|
||||
// button.trailingAnchor.constraint(equalTo: footerView.trailingAnchor, constant: -50),
|
||||
// Set the button's height
|
||||
button.heightAnchor.constraint(equalToConstant: 50),
|
||||
button.widthAnchor.constraint(equalToConstant: 160)
|
||||
])
|
||||
|
||||
return footerView
|
||||
}
|
||||
|
||||
@objc func footerButtonTapped() {
|
||||
Utilities.startProgressHUD()
|
||||
pageNo += 1
|
||||
getOrders()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,11 @@ class MoreVC: UIViewController {
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": true])
|
||||
|
||||
do {
|
||||
try AVAudioSession.sharedInstance().setActive(false)
|
||||
} catch {
|
||||
print("Failed to deactivate audio session: \(error.localizedDescription)")
|
||||
}
|
||||
vm.player?.pause()
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,30 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
// self.rotateToLandsScapeDevice()
|
||||
// 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)
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@@ -48,21 +68,24 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
|
||||
appDelegate.deviceOrientation = .landscapeRight
|
||||
let value = UIInterfaceOrientation.landscapeRight.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
player.configurePlayer(with: config)
|
||||
|
||||
self.delegate = self
|
||||
//Disable Picture in Picture
|
||||
playerView.allowsPictureInPicturePlayback = false
|
||||
playerView.captionStyle = .none
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self else{return}
|
||||
appDelegate.deviceOrientation = .landscapeRight
|
||||
let value = UIInterfaceOrientation.landscapeRight.rawValue
|
||||
UIDevice.current.setValue(value, forKey: "orientation")
|
||||
player.configurePlayer(with: config)
|
||||
|
||||
self.delegate = self
|
||||
//Disable Picture in Picture
|
||||
playerView.allowsPictureInPicturePlayback = false
|
||||
playerView.captionStyle = .none
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
player.stop()
|
||||
|
||||
}
|
||||
|
||||
@IBAction func backBtnTapped(_ sender: UIButton) {
|
||||
@@ -178,16 +201,18 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate {
|
||||
super.jwplayer(player, failedWithError: code, message: message)
|
||||
|
||||
print("Error: \(code) - \(message)")
|
||||
Utilities.alertWithBtnCancelCompletion(title: "Error", msgBody: message, okBtnStr: "Connect", vc: self) { [weak self] isDone in
|
||||
guard let self else{
|
||||
self?.handleBackAction()
|
||||
return
|
||||
}
|
||||
if isDone{
|
||||
self.player.configurePlayer(with: config)
|
||||
self.player.play()
|
||||
}else{
|
||||
self.handleBackAction()
|
||||
DispatchQueue.main.async {
|
||||
Utilities.alertWithBtnCancelCompletion(title: "Error", msgBody: message, okBtnStr: "Connect", vc: self) { [weak self] isDone in
|
||||
guard let self else{
|
||||
self?.handleBackAction()
|
||||
return
|
||||
}
|
||||
if isDone{
|
||||
self.player.configurePlayer(with: config)
|
||||
self.player.play()
|
||||
}else{
|
||||
self.handleBackAction()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,12 +49,16 @@ class ThemeOneVC: UIViewController {
|
||||
NotificationCenter.default.removeObserver(self, name: UIApplication.willEnterForegroundNotification, object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil)
|
||||
NotificationCenter.default.removeObserver(self, name: NSNotification.Name(rawValue: K.NotificationCenterReloads.themeOnePush), object: nil)
|
||||
if let playerItem = vm.playerItem{
|
||||
playerItem.removeObserver(self, forKeyPath: "status")
|
||||
playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty")
|
||||
playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp")
|
||||
}
|
||||
if let playerLayer = vm.playerLayer, let avPlayer = vm.avPlayer {
|
||||
playerLayer.removeObserver(self, forKeyPath: "timeControlStatus")
|
||||
avPlayer.pause()
|
||||
}
|
||||
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "status")
|
||||
vm.avPlayer.removeObserver(self, forKeyPath: "timeControlStatus")
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackBufferEmpty")
|
||||
vm.playerItem.removeObserver(self, forKeyPath: "isPlaybackLikelyToKeepUp")
|
||||
vm.avPlayer.pause()
|
||||
}
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
@@ -67,7 +71,7 @@ class ThemeOneVC: UIViewController {
|
||||
vm.initView()
|
||||
|
||||
if MyListDataTemp.shareInstance.favListingData?.showData == nil {
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
// connectedToNetwork()
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ class ThemeTwoVC: UIViewController {
|
||||
vm.initView()
|
||||
|
||||
if MyListDataTemp.shareInstance.favListingData?.showData == nil {
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
MyListDataTemp.shareInstance.favListingData = FavouriteListingDM.ResultData(totalRecords: nil, showData: [], videoData: [], gameData: [], singKaraokeData: [], audioData: [])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
<stackView opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" distribution="equalSpacing" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="era-Az-5kr">
|
||||
<rect key="frame" x="5" y="5" width="341" height="59"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="ngc-D8-N88">
|
||||
<rect key="frame" x="0.0" y="0.0" width="96.666666666666671" height="59"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="ngc-D8-N88">
|
||||
<rect key="frame" x="0.0" y="0.0" width="147.33333333333334" height="59"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rtY-dp-opx">
|
||||
<rect key="frame" x="0.0" y="0.0" width="59" height="59"/>
|
||||
@@ -47,30 +47,33 @@
|
||||
</imageView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Text" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QJ2-HR-46k">
|
||||
<rect key="frame" x="64" y="0.0" width="32.666666666666657" height="59"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Text Text Te" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QJ2-HR-46k">
|
||||
<rect key="frame" x="63.999999999999993" y="0.0" width="83.333333333333314" height="59"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="15"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eI6-es-65E">
|
||||
<rect key="frame" x="258" y="0.0" width="78" height="59"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="249" translatesAutoresizingMaskIntoConstraints="NO" id="eI6-es-65E">
|
||||
<rect key="frame" x="243.66666666666666" y="0.0" width="92.333333333333343" height="59"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="0:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mcL-xd-aWa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="34.666666666666664" height="59"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="00:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mcL-xd-aWa">
|
||||
<rect key="frame" x="0.0" y="0.0" width="42" height="59"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="15"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="/0:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5XU-52-i0j">
|
||||
<rect key="frame" x="34.666666666666686" y="0.0" width="43.333333333333343" height="59"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="16"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="/00:00" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5XU-52-i0j">
|
||||
<rect key="frame" x="42.000000000000028" y="0.0" width="50.333333333333343" height="59"/>
|
||||
<fontDescription key="fontDescription" name="Exo2-Bold" family="Exo 2" pointSize="15"/>
|
||||
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" relation="greaterThanOrEqual" constant="92.329999999999998" id="CNo-m6-6IU"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.035294117647058823" green="0.0" blue="0.36470588235294116" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
||||
@@ -50,7 +50,7 @@ class MoreVM{
|
||||
func setupAudioSession() {
|
||||
let session = AVAudioSession.sharedInstance()
|
||||
do {
|
||||
try session.setCategory(.playback, mode: .default)
|
||||
try session.setCategory(.playback, mode: .spokenAudio)
|
||||
try session.setActive(true)
|
||||
} catch {
|
||||
print("Failed to set up audio session")
|
||||
|
||||
@@ -180,15 +180,19 @@ class ThemeOneVM{
|
||||
@objc func appDidEnterBackground() {
|
||||
// Code to execute when the app enters the background
|
||||
print("App entered background")
|
||||
self.avPlayer.pause()
|
||||
self.handleBackground()
|
||||
if UIApplication.topViewController() == ThemeOneVC(){
|
||||
avPlayer.pause()
|
||||
handleBackground()
|
||||
}
|
||||
}
|
||||
|
||||
@objc func appWillEnterForeground() {
|
||||
// Code to execute when the app enters the foreground
|
||||
print("App will enter foreground")
|
||||
self.avPlayer.play()
|
||||
self.handleBackground()
|
||||
if UIApplication.topViewController() == ThemeOneVC(){
|
||||
avPlayer.play()
|
||||
handleBackground()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Handle Tap Gesture
|
||||
|
||||
@@ -34,7 +34,6 @@ class JWPlayerManager {
|
||||
let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil)
|
||||
let playerVC = sb.instantiateViewController(identifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC
|
||||
|
||||
DispatchQueue.main.async {
|
||||
do {
|
||||
// Create an array to hold the JWPlayerItems
|
||||
var items: [JWPlayerItem] = []
|
||||
@@ -129,25 +128,24 @@ class JWPlayerManager {
|
||||
.build()
|
||||
}
|
||||
|
||||
playerVC.videoIndex = startIndex
|
||||
playerVC.contentType = contentType
|
||||
playerVC.config = finalConfig
|
||||
playerVC.modalPresentationStyle = .fullScreen
|
||||
playerVC.modalTransitionStyle = .crossDissolve
|
||||
// Present the PlayerVC
|
||||
Utilities.dismissProgressHUD()
|
||||
viewController.present(playerVC, animated: true) {
|
||||
completion?()
|
||||
// playerVC.transitionToFullScreen(animated: true) {
|
||||
// print("FullScreen")
|
||||
// }
|
||||
DispatchQueue.main.async {
|
||||
playerVC.videoIndex = startIndex
|
||||
playerVC.contentType = contentType
|
||||
playerVC.config = finalConfig
|
||||
playerVC.modalPresentationStyle = .fullScreen
|
||||
playerVC.modalTransitionStyle = .crossDissolve
|
||||
// Present the PlayerVC
|
||||
Utilities.dismissProgressHUD()
|
||||
viewController.present(playerVC, animated: true) {
|
||||
completion?()
|
||||
// playerVC.transitionToFullScreen(animated: true) {
|
||||
// print("FullScreen")
|
||||
// }
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
print("Error creating JWPlayer configuration: \(error)")
|
||||
Utilities.dismissProgressHUD()
|
||||
}
|
||||
|
||||
// Dismiss the progress HUD after the view controller presentation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user