diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 7ca1b24..b36f901 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -74,6 +74,7 @@ 527AC6FD2C173A5100434FB7 /* SongListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC6FB2C173A5100434FB7 /* SongListCell.swift */; }; 527AC6FE2C173A5100434FB7 /* SongListCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 527AC6FC2C173A5100434FB7 /* SongListCell.xib */; }; 527AC7012C182DCE00434FB7 /* TimeStringToSeconds.swift in Sources */ = {isa = PBXBuildFile; fileRef = 527AC7002C182DCE00434FB7 /* TimeStringToSeconds.swift */; }; + 528BEF602C2C372900FFDAB8 /* ContinueWatchingVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528BEF5F2C2C372900FFDAB8 /* ContinueWatchingVC.swift */; }; 528E5F1B2C24531200E33E4E /* SeasonListingDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528E5F1A2C24531200E33E4E /* SeasonListingDM.swift */; }; 528E5F222C24660F00E33E4E /* SeasonCategoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 528E5F202C24660F00E33E4E /* SeasonCategoryCell.swift */; }; 528E5F232C24660F00E33E4E /* SeasonCategoryCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 528E5F212C24660F00E33E4E /* SeasonCategoryCell.xib */; }; @@ -328,6 +329,7 @@ 527AC6FB2C173A5100434FB7 /* SongListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SongListCell.swift; sourceTree = ""; }; 527AC6FC2C173A5100434FB7 /* SongListCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SongListCell.xib; sourceTree = ""; }; 527AC7002C182DCE00434FB7 /* TimeStringToSeconds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeStringToSeconds.swift; sourceTree = ""; }; + 528BEF5F2C2C372900FFDAB8 /* ContinueWatchingVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContinueWatchingVC.swift; sourceTree = ""; }; 528E5F1A2C24531200E33E4E /* SeasonListingDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonListingDM.swift; sourceTree = ""; }; 528E5F202C24660F00E33E4E /* SeasonCategoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeasonCategoryCell.swift; sourceTree = ""; }; 528E5F212C24660F00E33E4E /* SeasonCategoryCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SeasonCategoryCell.xib; sourceTree = ""; }; @@ -979,6 +981,7 @@ 52DAC64D2C21775300E2F85B /* WebSeriesVC.swift */, 5242FE582C24203E0086A86D /* WebSeriesSeasonVC.swift */, 52E214C62C2AD47F00BC2D29 /* EpisodeDetailsVC.swift */, + 528BEF5F2C2C372900FFDAB8 /* ContinueWatchingVC.swift */, ); path = Controller; sourceTree = ""; @@ -1581,6 +1584,7 @@ 9C834EC62C1C1D9500B29A9C /* BlogDetailsVC.swift in Sources */, 9CBCB2A52BE50D49007D7934 /* NewPasswordVC.swift in Sources */, 9CBCB29F2BE4E13A007D7934 /* ValidatorClass.swift in Sources */, + 528BEF602C2C372900FFDAB8 /* ContinueWatchingVC.swift in Sources */, 9CBCB29B2BE4D614007D7934 /* LoginVC.swift in Sources */, 52BC3BE82C0E04A9002FACA6 /* FaqListDM.swift in Sources */, 9C56E83B2BDBC6E600E4CA14 /* SelectAgeVM.swift in Sources */, diff --git a/WOKA/Assets/Assets.xcassets/WebSeries/ShareImage.imageset/Contents.json b/WOKA/Assets/Assets.xcassets/WebSeries/ShareImage.imageset/Contents.json index d06dc5b..685d429 100644 --- a/WOKA/Assets/Assets.xcassets/WebSeries/ShareImage.imageset/Contents.json +++ b/WOKA/Assets/Assets.xcassets/WebSeries/ShareImage.imageset/Contents.json @@ -19,5 +19,8 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" } } diff --git a/WOKA/Constants K/StoryBoardID.swift b/WOKA/Constants K/StoryBoardID.swift index 2f6e800..132fc17 100644 --- a/WOKA/Constants K/StoryBoardID.swift +++ b/WOKA/Constants K/StoryBoardID.swift @@ -45,6 +45,7 @@ extension K{ static let moreVC = "MoreVC" static let radioVC = "RadioVC" static let blogDetailsVC = "BlogDetailsVC" + static let playerVC = "PlayerVC" } struct SideBarNav{ @@ -62,6 +63,7 @@ extension K{ static let webSeriesVC = "WebSeriesVC" static let webSeriesSeasonVC = "WebSeriesSeasonVC" static let episodeDetailsVC = "EpisodeDetailsVC" + static let continueWatchingVC = "ContinueWatchingVC" } } } diff --git a/WOKA/Localized Module/hi.lproj/Localizable.strings b/WOKA/Localized Module/hi.lproj/Localizable.strings index 32a85a7..0f64712 100644 --- a/WOKA/Localized Module/hi.lproj/Localizable.strings +++ b/WOKA/Localized Module/hi.lproj/Localizable.strings @@ -226,3 +226,9 @@ "CONTINUE WATCHING" = "देखना जारी रखें"; "PLAY TRAILER" = "प्ले ट्रेलर"; "Teaser" = "टीज़र"; +"WATCH" = "देखें"; +"ADD" = "अप्रिय"; +"ADDED" = "प्रिय"; +"SHARE" = "शेयर"; +"LIKE" = "पसंद"; +"LIKED" = "पसंदिता"; diff --git a/WOKA/Theme/Controller/PlayerVC.swift b/WOKA/Theme/Controller/PlayerVC.swift index 85e075c..5d32dbe 100644 --- a/WOKA/Theme/Controller/PlayerVC.swift +++ b/WOKA/Theme/Controller/PlayerVC.swift @@ -13,7 +13,9 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { @IBOutlet weak var innerPlayerView: UIView! var previousScale: CGFloat = 1.0 -// let backButton = UIButton(type: .system) + + var contentType : VideoContentType? + var config: JWPlayerConfiguration! var dismissTapped: (() -> Void)? var videoIndex : Int? @@ -54,7 +56,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { //Disable Picture in Picture playerView.allowsPictureInPicturePlayback = false -// playerView.captionStyle = .none + playerView.captionStyle = .none } @objc func applicationDidBecomeActive() { @@ -86,37 +88,38 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { override func jwplayer(_ player: any JWPlayer, didFinishLoadingWithTime loadTime: TimeInterval) { super.jwplayer(player, didFinishLoadingWithTime: loadTime) print("LoadTime", loadTime) -// self.player.play() } //Playlist Functions -// -// override func jwplayer(_ player: any JWPlayer, didLoadPlaylist playlist: [JWPlayerItem]) { -// print("DidLoad", playlist.count , playlist) -//// player.loadPlayerItemAt(index: videoIndex ?? 0) -//// player.play(relatedContent: videoIndex ?? 0) -// + +// override func jwplayerHasSeeked(_ player: any JWPlayer) { +//// if player.getState() != .playing{ +//// print("Again Play") +//// player.play() +//// } +// print("Seeked " , player.getState()) // } -// - override func jwplayerHasSeeked(_ player: any JWPlayer) { -// player.play() - if player.getState() != .playing{ - print("Again Play") - player.play() - } - print("Seeked") - } - - override func jwplayer(_ player: any JWPlayer, didLoadPlaylistItem item: JWPlayerItem, at index: UInt) { -// player.loadPlayerItemAt(index: 4) -// player.play(relatedContent: 4) - print("Item" , item) - } override func jwplayerIsReady(_ player: JWPlayer) { super.jwplayerIsReady(player) -// player.seek(to: 30) -// player.play() + switch contentType { + case .liveStream: + player.play() + case .webSeries: + if videoIndex == 0{ + player.play() + }else{ + player.nextUpPlaylistIndex = videoIndex ?? 0 + player.next() + } + case .trailer: + player.play() + case .continueWatching: + player.play() + case nil: + break + } + print("IsReady") } diff --git a/WOKA/Theme/ViewModel/ThemeOneVM.swift b/WOKA/Theme/ViewModel/ThemeOneVM.swift index ff3616c..a82c67c 100644 --- a/WOKA/Theme/ViewModel/ThemeOneVM.swift +++ b/WOKA/Theme/ViewModel/ThemeOneVM.swift @@ -221,7 +221,6 @@ class ThemeOneVM{ // Create a JWPlayerItem let item = try JWPlayerItemBuilder() .file(liveStreamURL) - .title("Testing Title") .build() // Create a JWPlayerConfiguration @@ -232,6 +231,7 @@ class ThemeOneVM{ vc.config = config vc.dismissTapped = self.tapped + vc.contentType = .liveStream vc.modalPresentationStyle = .overFullScreen // Present the PlayerVC @@ -250,56 +250,6 @@ class ThemeOneVM{ Utilities.dismissProgressHUD() } } - -// @objc func handleTap(_ sender: UITapGestureRecognizer) { -// Utilities.startProgressHUD(msg: "Loading...") -// print("tapped") -// let vc = self.vc.storyboard?.instantiateViewController(identifier: "PlayerVC") as! PlayerVC -// -// DispatchQueue.main.async { -// do { -// // Create a JWMediaTrack with the thumbnails .vtt file -// // let thumbnailTrack = try JWThumbnailTrackBuilder() -// // .file(URL(string:"https://content.jwplatform.com/videos/Agy4RIje-Ysj2G4DQ.mp4")!) -// // .build() -// -// // Create a JWPlayerItem -// let item = try JWPlayerItemBuilder() -// .file(URL(string: self.liveStreamURL)!) -// .title("Testing Title") -//// .posterImage(URL(string: "https://img.freepik.com/free-photo/painting-mountain-lake-with-mountain-background_188544-9126.jpg")!) -// // .mediaTracks([thumbnailTrack]) -// .build() -// -// // Create a config, and give it the item as a playlist. -// let config = try JWPlayerConfigurationBuilder() -// .playlist(items: [item]) -// .autostart(true) -//// .preload(.auto) -//// .repeatContent(true) -// .build() -// -// vc.config = config -// vc.dismissTapped = self.tapped -// -// vc.modalPresentationStyle = .overFullScreen -// Utilities.dismissProgressHUD() -// self.vc.present(vc, animated: false) { -// self.stopLiveStream() -// vc.transitionToFullScreen(animated: true) { -// print("FullScreen") -// } -// // vc.setDeviceOrientation(orientation: .landscapeRight) -// } -//// Utilities.dismissProgressHUD() -//// self.vc.navigationController?.pushViewController(vc, animated: true) -//// self.stopLiveStream() -// } -// catch { -// // Handle Error -// } -// } -// } func tapped(){ Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in diff --git a/WOKA/Theme/ViewModel/ThemeTwoVM.swift b/WOKA/Theme/ViewModel/ThemeTwoVM.swift index 41441f3..d86c21a 100644 --- a/WOKA/Theme/ViewModel/ThemeTwoVM.swift +++ b/WOKA/Theme/ViewModel/ThemeTwoVM.swift @@ -81,7 +81,6 @@ class ThemeTwoVM{ // Create a JWPlayerItem let item = try JWPlayerItemBuilder() .file(URL(string: self.liveStreamURL)!) - .title("Testing Title") // .posterImage(URL(string: "https://img.freepik.com/free-photo/painting-mountain-lake-with-mountain-background_188544-9126.jpg")!) // .mediaTracks([thumbnailTrack]) .build() @@ -96,7 +95,7 @@ class ThemeTwoVM{ vc.config = config vc.dismissTapped = self.tapped - + vc.contentType = .liveStream vc.modalPresentationStyle = .overFullScreen Utilities.dismissProgressHUD() self.vc.present(vc, animated: false) { diff --git a/WOKA/WebSeries/Controller/ContinueWatchingVC.swift b/WOKA/WebSeries/Controller/ContinueWatchingVC.swift new file mode 100644 index 0000000..7371c1e --- /dev/null +++ b/WOKA/WebSeries/Controller/ContinueWatchingVC.swift @@ -0,0 +1,84 @@ +// +// ContinueWatchingVC.swift +// WOKA +// +// Created by MacBook Pro on 26/06/24. +// + +import UIKit + +class ContinueWatchingVC: UIViewController { + + @IBOutlet weak var watchingImage: UIImageView! + @IBOutlet weak var watchingTitle: UILabel! + @IBOutlet weak var watchingDesc: UITextView! + + var watchData : ContinueWatchingDM.ResultData? + + // This ID is from webseries main screen, where user selectes + var categoryID : Int? + + override func viewDidLoad() { + super.viewDidLoad() + if watchData != nil{ + setData() + } + } + + func setData(){ + guard let watchData else{return} + + if let url = watchData.thumbnailPath{ + self.watchingImage.imageURL(url, color: .black) + } + + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ + guard let englishData = watchData.contentMoreDetails?.filter({$0.languageMasterID == 1}).first else{return} + watchingTitle.text = englishData.title + if let desc = englishData.description?.replacingOccurrences(of: "
", with: "").htmlToAttributedString{ + let sizeText = NSMutableAttributedString(attributedString: desc) + sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 15),color: UIColor.appColor(.TextDarkBlue)!) + self.watchingDesc.attributedText = sizeText + } + }else{ + guard let hindiData = watchData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return} + watchingTitle.text = hindiData.title + if let desc = hindiData.description?.replacingOccurrences(of: "
", with: "").htmlToAttributedString{ + let sizeText = NSMutableAttributedString(attributedString: desc) + sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 15),color: UIColor.appColor(.TextDarkBlue)!) + self.watchingDesc.attributedText = sizeText + } + } + } + + @IBAction func watchBtnTapped(_ sender: LocalisedElementsButton) { + guard let watchData else{return} + var playerItem = JwPlayerItemCreate(url: "", poster: "", titles: "") + playerItem.poster = watchData.thumbnailPath + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ + guard let englishData = watchData.contentMoreDetails?.filter({$0.languageMasterID == 1}).first else{return} + playerItem.titles = englishData.title + }else{ + guard let hindiData = watchData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return} + playerItem.titles = hindiData.title + } + + if categoryID == 1{ + guard let englishData = watchData.contentMoreDetails?.filter({$0.languageMasterID == 1}).first, let url = englishData.contentHDURL else{return} + playerItem.url = url + + }else if categoryID == 18{ + guard let hindiData = watchData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first, let url = hindiData.contentHDURL else{return} + playerItem.url = url + } + + JWPlayerManager.shared.presentPlayer(from: self, playerItems: [playerItem], startIndex: 0, contentType: .continueWatching) + + } + + @IBAction func closeBtnTapped(_ sender: LocalisedElementsButton) { + self.dismiss(animated: true) { + + } + } +} diff --git a/WOKA/WebSeries/Controller/EpisodeDetailsVC.swift b/WOKA/WebSeries/Controller/EpisodeDetailsVC.swift index 2b8421a..aa22c47 100644 --- a/WOKA/WebSeries/Controller/EpisodeDetailsVC.swift +++ b/WOKA/WebSeries/Controller/EpisodeDetailsVC.swift @@ -69,11 +69,19 @@ class EpisodeDetailsVC: UIViewController { if AuthFunc.shareInstance.getDefaultLanguage() == .english{ guard let englishData = teaserData.contentMoreDetails?.filter({$0.languageMasterID == 1}).first else{return} episodeTitle.text = englishData.title - episodeDesc.text = englishData.description + if let desc = englishData.description?.replacingOccurrences(of: "
", with: "").htmlToAttributedString{ + let sizeText = NSMutableAttributedString(attributedString: desc) + sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 15),color: UIColor.appColor(.TextDarkBlue)!) + self.episodeDesc.attributedText = sizeText + } }else{ guard let hindiData = teaserData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return} episodeTitle.text = hindiData.title - episodeDesc.text = hindiData.description + if let desc = hindiData.description?.replacingOccurrences(of: "
", with: "").htmlToAttributedString{ + let sizeText = NSMutableAttributedString(attributedString: desc) + sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Regular, size: 15),color: UIColor.appColor(.TextDarkBlue)!) + self.episodeDesc.attributedText = sizeText + } } mediaType.text = "Teaser".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) + " " + (teaserData.serialNumber?.toString() ?? "0") diff --git a/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift b/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift index b4eaec3..6009d0c 100644 --- a/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift +++ b/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift @@ -36,9 +36,11 @@ class WebSeriesSeasonVC: UIViewController { @IBOutlet weak var likeLabel: UILabel! @IBOutlet weak var totalLikes: UILabel! - @IBOutlet weak var addStack: UIStackView! - @IBOutlet weak var shareStack: UIStackView! - @IBOutlet weak var likeStack: UIStackView! + @IBOutlet weak var addView: UIView! + @IBOutlet weak var shareView: UIView! + @IBOutlet weak var likeView: UIView! + + var likeFavDelegate : ReloadSeriesFavLike? override func viewDidLoad() { super.viewDidLoad() @@ -70,6 +72,20 @@ class WebSeriesSeasonVC: UIViewController { @IBAction func watchBtnTapped(_ sender: LocalisedElementsButton) { } + @IBAction func playTrailerBtnTapped(_ sender: LocalisedElementsButton) { + // 1-> english , 18- hindi + let seasonData = vm.seasonListingData.filter({$0.id == vm.episodeSelectedCateogory}).first + if vm.categoryID == 1{ + guard let englishData = seasonData?.seasonMoreDetails?.filter({$0.languageMasterID == 1}).first , let url = englishData.trailerHDURL , let title = englishData.title else{return} + let playerItem = JwPlayerItemCreate(url: url, poster: seasonData?.thumbnailPath, titles: title) + JWPlayerManager.shared.presentPlayer(from: self, playerItems: [playerItem], startIndex: 0, contentType: .trailer) + }else if vm.categoryID == 18{ + guard let hindiData = seasonData?.seasonMoreDetails?.filter({$0.languageMasterID == 2}).first , let url = hindiData.trailerHDURL , let title = hindiData.title else{return} + let playerItem = JwPlayerItemCreate(url: url, poster: seasonData?.thumbnailPath, titles: title) + JWPlayerManager.shared.presentPlayer(from: self, playerItems: [playerItem], startIndex: 0, contentType: .trailer) + } + } + @IBAction func retryBtnTapped(_ sender: LocalisedElementsButton) { } @@ -108,25 +124,44 @@ extension WebSeriesSeasonVC : TableViewSRC{ } cell.btnTapped = { [self] () -> Void in - var urls = [String]() - var title = [String]() - var poster = [String]() - if let episodeData = vm.seasonEpisodeData.first?.episodeData{ - for i in episodeData{ - urls.append(i.episodeURL ?? "") - title.append(i.episodeTitle ?? "Episode") - poster.append(i.thumbnailPath ?? "") + + var playerItems = [JwPlayerItemCreate]() + + if let episodeData = vm.seasonEpisodeData.first?.episodeData { + if vm.categoryID == 1{ + playerItems = episodeData.flatMap { episode in + episode.contentMoreDetails? + .filter { $0.languageMasterID == 1 } + .prefix(1) + .compactMap { data in + if let url = data.contentHDURL, let title = data.title { + return JwPlayerItemCreate(url: url, poster: episode.thumbnailPath, titles: title) + } + return nil + } ?? [] + } + }else if vm.categoryID == 18{ + playerItems = episodeData.flatMap { episode in + episode.contentMoreDetails? + .filter { $0.languageMasterID == 2 } + .prefix(1) + .compactMap { data in + if let url = data.contentHDURL, let title = data.title { + return JwPlayerItemCreate(url: url, poster: episode.thumbnailPath, titles: title) + } + return nil + } ?? [] + } } } - -// if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] , let url = data.episodeURL{ + + JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems, startIndex: indexPath.row, contentType: .webSeries) + // Ensure indexPath.row is valid before proceeding - if indexPath.row < urls.count { - JWPlayerManager.shared.presentPlayer(from: self, withURLs: urls, poster: poster, titles: title, startIndex: indexPath.row) - } else { - print("Index out of bounds for episode data") - }// } - +// if indexPath.row < playerItems.count { +// } else { +// print("Index out of bounds for episode data") +// } } return cell @@ -146,20 +181,14 @@ extension WebSeriesSeasonVC : TableViewSRC{ } vcPush.onDoneBlock = { [weak self] in guard let self else{return} - var urls = [String]() - var title = [String]() - var poster = [String]() - if let episodeData = vm.seasonEpisodeData.first?.episodeData{ - for i in episodeData{ - urls.append(i.episodeURL ?? "") - title.append(i.episodeTitle ?? "Episode") - poster.append(i.thumbnailPath ?? "") + var playerItems = [JwPlayerItemCreate]() + if let episodeData = vm.seasonEpisodeData.first?.episodeData { + // Use compactMap to create an array of JwPlayerItemCreate instances + playerItems = episodeData.compactMap { episode in + JwPlayerItemCreate(url: episode.episodeURL ?? "", poster: episode.thumbnailPath, titles: episode.episodeTitle) } } - -// if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] , let url = data.episodeURL{ - JWPlayerManager.shared.presentPlayer(from: self, withURLs: urls, poster: poster, titles: title,startIndex: indexPath.row) -// } + JWPlayerManager.shared.presentPlayer(from: self, playerItems: playerItems,startIndex: indexPath.row, contentType: .webSeries) } vcPush.modalPresentationStyle = .overCurrentContext diff --git a/WOKA/WebSeries/Controller/WebSeriesVC.swift b/WOKA/WebSeries/Controller/WebSeriesVC.swift index 8c942c4..3eb25fb 100644 --- a/WOKA/WebSeries/Controller/WebSeriesVC.swift +++ b/WOKA/WebSeries/Controller/WebSeriesVC.swift @@ -7,6 +7,10 @@ import UIKit +protocol ReloadSeriesFavLike{ + func updateRows(index : Int, type : FavCellCLick) +} + class WebSeriesVC: UIViewController { @IBOutlet weak var headerView: ShimmerEffectView! @@ -59,8 +63,9 @@ class WebSeriesVC: UIViewController { } // MARK: - Tap Handler - @IBAction func playTrailer(_ sender: LocalisedElementsButton) { + let item = JwPlayerItemCreate(url: vm.masilaUrl, poster: nil, titles: "Masila") + JWPlayerManager.shared.presentPlayer(from: self, playerItems: [item], contentType: .trailer) } @IBAction func expandLanguageTapped(_ sender: UIButton) { @@ -199,6 +204,8 @@ extension WebSeriesVC : TableViewSRC{ let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil) let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.webSeriesSeasonVC) as! WebSeriesSeasonVC vcPush.vm.showData = showData + vcPush.vm.indexSelected = indexPath.row + vcPush.likeFavDelegate = self if let selectedIndex = vm.dropDownModule.indexForSelectedRow{ let categoryID = vm.categoryListingData[selectedIndex] vcPush.vm.categoryID = categoryID.id @@ -207,6 +214,14 @@ extension WebSeriesVC : TableViewSRC{ } } +extension WebSeriesVC : ReloadSeriesFavLike{ + func updateRows(index: Int, type: FavCellCLick) { + print(index , type) + updateFavLikes(type: type, index: index) + } + +} + // MARK: - CollectionView Delegate and Data Source extension WebSeriesVC : CollectionViewSRC{ @@ -223,7 +238,19 @@ extension WebSeriesVC : CollectionViewSRC{ } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - print(indexPath.row) + let data = vm.continueWatchingData[indexPath.row] + + let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.continueWatchingVC) as! ContinueWatchingVC + vcPush.modalPresentationStyle = .overCurrentContext + vcPush.modalTransitionStyle = .crossDissolve + vcPush.watchData = data + if let selectedIndex = vm.dropDownModule.indexForSelectedRow{ + let categoryID = vm.categoryListingData[selectedIndex] + vcPush.categoryID = categoryID.id + } + self.present(vcPush, animated: true) + } } diff --git a/WOKA/WebSeries/JWPlayerManager.swift b/WOKA/WebSeries/JWPlayerManager.swift index f16a762..bafdddc 100644 --- a/WOKA/WebSeries/JWPlayerManager.swift +++ b/WOKA/WebSeries/JWPlayerManager.swift @@ -8,22 +8,28 @@ import UIKit import JWPlayerKit +enum VideoContentType{ + case liveStream + case webSeries + case trailer + case continueWatching +} + +struct JwPlayerItemCreate{ + var url : String + var poster : String? + var titles : String? +} + class JWPlayerManager { static let shared = JWPlayerManager() private init() {} - func presentPlayer(from viewController: UIViewController, withURLs liveStreamURLs: [String], poster : [String], titles: [String]? = nil, startIndex: Int = 0, completion: (() -> Void)? = nil) { - DispatchQueue.main.async { - Utilities.startProgressHUD(msg: "Loading...") - } + func presentPlayer(from viewController: UIViewController,playerItems : [JwPlayerItemCreate], startIndex: Int = 0, contentType : VideoContentType , completion: (() -> Void)? = nil) { let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil) - guard let playerVC = sb.instantiateViewController(identifier: "PlayerVC") as? PlayerVC else { - print("PlayerVC not found") - Utilities.dismissProgressHUD() - return - } + let playerVC = sb.instantiateViewController(identifier: K.StoryBoardID.Theme.playerVC) as! PlayerVC DispatchQueue.main.async { do { @@ -31,32 +37,62 @@ class JWPlayerManager { var items: [JWPlayerItem] = [] // Ensure the liveStreamURLs and titles arrays have the same count, if titles are provided - if let titles = titles, titles.count != liveStreamURLs.count { - print("Titles count does not match URLs count") - Utilities.dismissProgressHUD() - return - } +// if let titles = titles, titles.count != liveStreamURLs.count { +// print("Titles count does not match URLs count") +// Utilities.dismissProgressHUD() +// return +// } - // Iterate over the liveStreamURLs to create JWPlayerItems - for (index, urlString) in liveStreamURLs.enumerated() { - guard let url = URL(string: urlString) else { - print("Invalid live stream URL at index \(index)") - continue + switch contentType{ + case .webSeries: + // Iterate over the liveStreamURLs to create JWPlayerItems + for (index, singleItem) in playerItems.enumerated() { + guard let url = URL(string: singleItem.url) else { + print("Invalid live stream URL at index \(index)") + continue + } + + + let item = try JWPlayerItemBuilder() + .file(url) + .title(singleItem.titles ?? "") + .posterImage(URL(string: singleItem.poster ?? "")!) + .build() + + items.append(item) + } + case .liveStream: + guard let liveStreamItem = playerItems.first else { + print("Invalid live stream URL") + return } - - // Use the corresponding title if provided, otherwise use a default title - let itemTitle = titles?[index] ?? "Default Title \(index + 1)" - let itemPoster = poster[index] - - let item = try JWPlayerItemBuilder() - .file(url) - .title(itemTitle) - .posterImage(URL(string: itemPoster)!) + .file(URL(string: liveStreamItem.url)!) + .title(liveStreamItem.titles ?? "Trailer") + .build() + items.append(item) + case .trailer: + guard let liveStreamItem = playerItems.first else { + print("Invalid live stream URL") + return + } + let item = try JWPlayerItemBuilder() + .file(URL(string: liveStreamItem.url)!) + .title(liveStreamItem.titles ?? "Trailer") + .build() + items.append(item) + case .continueWatching: + guard let liveStreamItem = playerItems.first else { + print("Invalid live stream URL") + return + } + let item = try JWPlayerItemBuilder() + .file(URL(string: liveStreamItem.url)!) + .title(liveStreamItem.titles ?? "Trailer") .build() - items.append(item) } + // Ensure there is at least one valid item guard !items.isEmpty else { @@ -72,10 +108,12 @@ class JWPlayerManager { .build() playerVC.videoIndex = startIndex + playerVC.contentType = contentType playerVC.config = config playerVC.modalPresentationStyle = .overFullScreen // Present the PlayerVC + Utilities.dismissProgressHUD() viewController.present(playerVC, animated: false) { completion?() playerVC.transitionToFullScreen(animated: true) { @@ -88,7 +126,6 @@ class JWPlayerManager { } // Dismiss the progress HUD after the view controller presentation - Utilities.dismissProgressHUD() } } diff --git a/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift b/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift index 4e5375e..f4783b0 100644 --- a/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift +++ b/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift @@ -24,12 +24,32 @@ class WebSeriesSeasonVM{ var showData : WebSeriesShowListDM.ShowDatum? + var indexSelected : Int? + func initView(){ getSeasonListing() setupCell() setShowData() - vc.shareStack.addTapGesture { + vc.addView.addTapGesture { [weak self] in + guard let self else{return} +// if let showData, let fav = showData.markAsFavourite{ +// if fav{ +// self.showData?.markAsFavourite = false +//// self.showData?.likesCount! -= 1 +// }else{ +// self.showData?.markAsFavourite = true +//// self.showData?.likesCount! += 1 +// } +// } +// setShowData() + vc.likeFavDelegate?.updateRows(index: indexSelected!, type: .favourite) + } + vc.likeView.addTapGesture { [weak self] in + guard let self else{return} + vc.likeFavDelegate?.updateRows(index: indexSelected!, type: .liked) + } + vc.shareView.addTapGesture { print("share") } } @@ -41,10 +61,10 @@ class WebSeriesSeasonVM{ switch like{ case true: vc.likeIcon.image = UIImage(systemName: "hand.thumbsup.fill") - vc.likeLabel.text = "Liked" + vc.likeLabel.text = "LIKED".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) case false: vc.likeIcon.image = UIImage(systemName: "hand.thumbsup") - vc.likeLabel.text = "Like" + vc.likeLabel.text = "LIKE".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) } } @@ -53,20 +73,20 @@ class WebSeriesSeasonVM{ let components = categoryIds.components(separatedBy: ",") if favourite == true && (components.first == categoryID?.toString() || components.last == categoryID?.toString()){ vc.addIcon.image = UIImage(systemName: "heart.fill") - vc.addLabel.text = "Added" + vc.addLabel.text = "ADDED".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) }else{ vc.addIcon.image = UIImage(systemName: "heart") - vc.addLabel.text = "Add" + vc.addLabel.text = "ADD".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) } return } if favourite == true && showData.favouriteCategoryIDS?.intValue == categoryID{ vc.addIcon.image = UIImage(systemName: "heart.fill") - vc.addLabel.text = "Added" + vc.addLabel.text = "ADDED".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) }else{ vc.addIcon.image = UIImage(systemName: "heart") - vc.addLabel.text = "Add" + vc.addLabel.text = "ADD".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) } } } diff --git a/WOKA/WebSeries/ViewModel/WebSeriesVM.swift b/WOKA/WebSeries/ViewModel/WebSeriesVM.swift index c93dd0f..0fa90c7 100644 --- a/WOKA/WebSeries/ViewModel/WebSeriesVM.swift +++ b/WOKA/WebSeries/ViewModel/WebSeriesVM.swift @@ -19,6 +19,9 @@ class WebSeriesVM{ let dropDownModule = DropDown() var dataSource = [String]() + //Static url for masila + var masilaUrl = "https://content.jwplatform.com/videos/Iygt11AD-Ysj2G4DQ.mp4" + func initView(){ setupCell() self.vc.tableHeight.constant = self.vc.showListingTableView.contentSize.height + 100 @@ -136,7 +139,7 @@ class WebSeriesVM{ }else{ self.vc.continueWatchingStack.isHidden = false } - self.continueWatchingData = data + self.continueWatchingData = data.reversed() self.vc.continueWatchingCV.reloadData() default: break diff --git a/WOKA/WebSeries/WebSeries.storyboard b/WOKA/WebSeries/WebSeries.storyboard index 1740593..0c1b7d3 100644 --- a/WOKA/WebSeries/WebSeries.storyboard +++ b/WOKA/WebSeries/WebSeries.storyboard @@ -35,42 +35,14 @@ - - - @@ -80,10 +52,10 @@ - + - + @@ -123,7 +98,7 @@ - + @@ -293,7 +268,7 @@ - + @@ -301,11 +276,6 @@ - - - - - @@ -321,12 +291,40 @@ + + + @@ -404,15 +402,15 @@ - + - - + + - - - - - - - - + + + + + + + + + + + + + - - - + + + + + + + + + + + - - + + - - - + + + + + + + + + + + + - + - - + - + + + + + + + + - + - - + + - - - - - - - - + + + + + + + + + + + + + - + + + + + + + + + @@ -546,13 +595,13 @@ - + - + - - + @@ -570,13 +619,13 @@ - + - + - - + @@ -621,20 +670,20 @@ - + - + - + @@ -834,6 +883,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +