diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 332c4bc..7ca1b24 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ 5259545A2BEB67D200191286 /* DateFormatterLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954592BEB67D200191286 /* DateFormatterLib.swift */; }; 5259545C2BEBB80400191286 /* AvatarDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259545B2BEBB80400191286 /* AvatarDM.swift */; }; 5259545E2BEBBA1A00191286 /* LoadingIndicatorImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259545D2BEBBA1A00191286 /* LoadingIndicatorImageView.swift */; }; + 525FD79B2C2AFB990062C80F /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 525FD79A2C2AFB990062C80F /* JWPlayerKit */; }; 52663FF52BDFAB830001D8CE /* TextFieldErrorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF42BDFAB830001D8CE /* TextFieldErrorView.swift */; }; 52663FF72BDFACF60001D8CE /* ShadowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF62BDFACF60001D8CE /* ShadowView.swift */; }; 52663FF92BDFAF110001D8CE /* EmailVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52663FF82BDFAF110001D8CE /* EmailVM.swift */; }; @@ -151,7 +152,7 @@ 52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52D774F02BDFC53B001D87DE /* StringSubScript.swift */; }; 52DAC6482C21762900E2F85B /* WebSeries.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 52DAC6472C21762900E2F85B /* WebSeries.storyboard */; }; 52DAC64E2C21775300E2F85B /* WebSeriesVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52DAC64D2C21775300E2F85B /* WebSeriesVC.swift */; }; - 52E59A922C29AE3F00BB9B04 /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 52E59A912C29AE3F00BB9B04 /* JWPlayerKit */; }; + 52E214C72C2AD47F00BC2D29 /* EpisodeDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52E214C62C2AD47F00BC2D29 /* EpisodeDetailsVC.swift */; }; 52FB2D8F2BDF898F0009B0C7 /* TextFieldPadding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FB2D8E2BDF898F0009B0C7 /* TextFieldPadding.swift */; }; 52FDBA782BFF23F4009D7AC7 /* TimePeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FDBA772BFF23F4009D7AC7 /* TimePeriod.swift */; }; 52FDBA7B2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52FDBA7A2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift */; }; @@ -407,6 +408,7 @@ 52D774F02BDFC53B001D87DE /* StringSubScript.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringSubScript.swift; sourceTree = ""; }; 52DAC6472C21762900E2F85B /* WebSeries.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = WebSeries.storyboard; sourceTree = ""; }; 52DAC64D2C21775300E2F85B /* WebSeriesVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebSeriesVC.swift; sourceTree = ""; }; + 52E214C62C2AD47F00BC2D29 /* EpisodeDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EpisodeDetailsVC.swift; sourceTree = ""; }; 52E7E0F62BDF7DD500C86E10 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/AuthenticationSB.strings; sourceTree = ""; }; 52E7E0F82BDF7DD900C86E10 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/AuthenticationSB.strings; sourceTree = ""; }; 52FB2D8E2BDF898F0009B0C7 /* TextFieldPadding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldPadding.swift; sourceTree = ""; }; @@ -489,7 +491,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 52E59A922C29AE3F00BB9B04 /* JWPlayerKit in Frameworks */, + 525FD79B2C2AFB990062C80F /* JWPlayerKit in Frameworks */, 9C1C69FA2C106B290035B2C7 /* RSKPlaceholderTextView in Frameworks */, 619A5A1BD8BD968ADC83C106 /* Pods_WOKA.framework in Frameworks */, ); @@ -976,6 +978,7 @@ children = ( 52DAC64D2C21775300E2F85B /* WebSeriesVC.swift */, 5242FE582C24203E0086A86D /* WebSeriesSeasonVC.swift */, + 52E214C62C2AD47F00BC2D29 /* EpisodeDetailsVC.swift */, ); path = Controller; sourceTree = ""; @@ -1296,7 +1299,7 @@ name = WOKA; packageProductDependencies = ( 9C1C69F92C106B290035B2C7 /* RSKPlaceholderTextView */, - 52E59A912C29AE3F00BB9B04 /* JWPlayerKit */, + 525FD79A2C2AFB990062C80F /* JWPlayerKit */, ); productName = WOKA; productReference = 523ED25A2BDA2BC700CFED02 /* WOKA.app */; @@ -1373,7 +1376,7 @@ mainGroup = 523ED2512BDA2BC700CFED02; packageReferences = ( 9C1C69F82C106B290035B2C7 /* XCRemoteSwiftPackageReference "RSKPlaceholderTextView" */, - 52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */, + 525FD7992C2AFB990062C80F /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */, ); productRefGroup = 523ED25B2BDA2BC700CFED02 /* Products */; projectDirPath = ""; @@ -1654,6 +1657,7 @@ 52AC2D252C295A7900337473 /* TeaserDM.swift in Sources */, 9C535DC22C00B36900DA6DCD /* ThemeTwoVC.swift in Sources */, 9CA7C6C22C1095B600D73742 /* ProfileVM.swift in Sources */, + 52E214C72C2AD47F00BC2D29 /* EpisodeDetailsVC.swift in Sources */, 52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */, 9CBE1B3F2C0F37B300CA6E61 /* DPDConstants.swift in Sources */, 52B8D4DA2C04A25E00ED65F3 /* Preferences.swift in Sources */, @@ -2082,7 +2086,7 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = { + 525FD7992C2AFB990062C80F /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/jwplayer/JWPlayerKit-package.git"; requirement = { @@ -2101,9 +2105,9 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 52E59A912C29AE3F00BB9B04 /* JWPlayerKit */ = { + 525FD79A2C2AFB990062C80F /* JWPlayerKit */ = { isa = XCSwiftPackageProductDependency; - package = 52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */; + package = 525FD7992C2AFB990062C80F /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */; productName = JWPlayerKit; }; 9C1C69F92C106B290035B2C7 /* RSKPlaceholderTextView */ = { diff --git a/WOKA/Assets/Assets.xcassets/WebSeries/PlayButtonSmall.imageset/Contents.json b/WOKA/Assets/Assets.xcassets/WebSeries/PlayButtonSmall.imageset/Contents.json new file mode 100644 index 0000000..7e736e2 --- /dev/null +++ b/WOKA/Assets/Assets.xcassets/WebSeries/PlayButtonSmall.imageset/Contents.json @@ -0,0 +1,24 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "PlayButton@2x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/WOKA/Assets/Assets.xcassets/WebSeries/PlayButtonSmall.imageset/PlayButton@2x.png b/WOKA/Assets/Assets.xcassets/WebSeries/PlayButtonSmall.imageset/PlayButton@2x.png new file mode 100644 index 0000000..96690c0 Binary files /dev/null and b/WOKA/Assets/Assets.xcassets/WebSeries/PlayButtonSmall.imageset/PlayButton@2x.png differ diff --git a/WOKA/Constants K/StoryBoardID.swift b/WOKA/Constants K/StoryBoardID.swift index bac3f99..2f6e800 100644 --- a/WOKA/Constants K/StoryBoardID.swift +++ b/WOKA/Constants K/StoryBoardID.swift @@ -56,13 +56,12 @@ extension K{ static let myOrdersVC = "MyOrdersVC" } - /* - Web Series - */ - + // MARK: - Web Series + struct WebSeries{ static let webSeriesVC = "WebSeriesVC" static let webSeriesSeasonVC = "WebSeriesSeasonVC" + static let episodeDetailsVC = "EpisodeDetailsVC" } } } diff --git a/WOKA/Localized Module/hi.lproj/Localizable.strings b/WOKA/Localized Module/hi.lproj/Localizable.strings index bfb2d32..32a85a7 100644 --- a/WOKA/Localized Module/hi.lproj/Localizable.strings +++ b/WOKA/Localized Module/hi.lproj/Localizable.strings @@ -225,3 +225,4 @@ "TEASERS" = "टीज़र"; "CONTINUE WATCHING" = "देखना जारी रखें"; "PLAY TRAILER" = "प्ले ट्रेलर"; +"Teaser" = "टीज़र"; diff --git a/WOKA/Theme/Base.lproj/Theme.storyboard b/WOKA/Theme/Base.lproj/Theme.storyboard index 897d9eb..a189bee 100644 --- a/WOKA/Theme/Base.lproj/Theme.storyboard +++ b/WOKA/Theme/Base.lproj/Theme.storyboard @@ -1031,10 +1031,10 @@ - + - + diff --git a/WOKA/Theme/Controller/PlayerVC.swift b/WOKA/Theme/Controller/PlayerVC.swift index fefe567..85e075c 100644 --- a/WOKA/Theme/Controller/PlayerVC.swift +++ b/WOKA/Theme/Controller/PlayerVC.swift @@ -13,7 +13,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { @IBOutlet weak var innerPlayerView: UIView! var previousScale: CGFloat = 1.0 - let backButton = UIButton(type: .system) +// let backButton = UIButton(type: .system) var config: JWPlayerConfiguration! var dismissTapped: (() -> Void)? var videoIndex : Int? @@ -30,6 +30,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { UIView.setAnimationsEnabled(true) } + func rotateToPotraitScapeDevice(){ let appDelegate = UIApplication.shared.delegate as! AppDelegate @@ -46,11 +47,16 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { override func viewDidLoad() { super.viewDidLoad() + player.configurePlayer(with: config) + self.rotateToLandsScapeDevice() self.delegate = self - player.configurePlayer(with: config) + + //Disable Picture in Picture + playerView.allowsPictureInPicturePlayback = false +// playerView.captionStyle = .none } - + @objc func applicationDidBecomeActive() { self.setDeviceOrientation(orientation: .landscapeRight) } @@ -65,13 +71,9 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { } } -// @objc func backButtonTapped() { -// setDeviceOrientation(orientation: .portrait) -// } - override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) - self.navigationController?.isNavigationBarHidden = true +// self.navigationController?.isNavigationBarHidden = true } override func viewWillDisappear(_ animated: Bool) { @@ -86,11 +88,35 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { 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) { +// 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.loadPlayerItemAt(index: 4) - player.seek(to: 30) +// player.seek(to: 30) +// player.play() print("IsReady") } @@ -207,7 +233,7 @@ extension PlayerVC { extension PlayerVC { func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, controlBarVisibilityChanged isVisible: Bool, frame: CGRect) { - backButton.isHidden = !isVisible +// backButton.isHidden = !isVisible } func playerViewController(_ controller: JWPlayerKit.JWPlayerViewController, sizeChangedFrom oldSize: CGSize, to newSize: CGSize) { diff --git a/WOKA/WebSeries/Controller/EpisodeDetailsVC.swift b/WOKA/WebSeries/Controller/EpisodeDetailsVC.swift new file mode 100644 index 0000000..2b8421a --- /dev/null +++ b/WOKA/WebSeries/Controller/EpisodeDetailsVC.swift @@ -0,0 +1,92 @@ +// +// EpisodeDetailsVC.swift +// WOKA +// +// Created by MacBook Pro on 25/06/24. +// + +import UIKit + +class EpisodeDetailsVC: UIViewController { + + @IBOutlet weak var episodeImage: UIImageView! + @IBOutlet weak var episodeTitle: UILabel! + @IBOutlet weak var mediaType: UILabel! + @IBOutlet weak var episodeTimeLine: UILabel! + @IBOutlet weak var episodeDesc: UITextView! + @IBOutlet weak var watchBtn: LocalisedElementsButton! + + // Completion block to be executed when the alert is dismissed + var onDoneBlock: (() -> Void)? + + var teaserData : TeaserDM.ResultData? + + var episodeData : SeasonEpisodeListingDM.EpisodeDatum? + + override func viewDidLoad() { + super.viewDidLoad() + episodeDesc.font = FontCustom.shareInstance.customFont(fontName: .Exo2_Medium, size: 16) + watchBtn.addShadowAndCorner(radius: 25, shadowColor: .black, shadowOpacity: 0.6, shadowOffset: CGSize(width: 0, height: 0.5), shadowRadius: 5) + if teaserData != nil{ + initTeaser() + } + + if episodeData != nil{ + initEpisode() + } + } + + func initEpisode(){ + guard let episodeData else{return} + episodeImage.imageURL(episodeData.thumbnailPath ?? "", color: .black) + + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ + guard let englishData = episodeData.contentMoreDetails?.filter({$0.languageMasterID == 1}).first else{return} + episodeTitle.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.episodeDesc.attributedText = sizeText + } + }else{ + guard let hindiData = episodeData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return} + episodeTitle.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.episodeDesc.attributedText = sizeText + } + } + + mediaType.text = "Episode".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) + " " + (episodeData.episodeNumber?.toString() ?? "0") + episodeTimeLine.text = episodeData.episodeDuration + } + + func initTeaser(){ + guard let teaserData else{return} + episodeImage.imageURL(teaserData.thumbnailPath ?? "", color: .black) + + 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 + }else{ + guard let hindiData = teaserData.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return} + episodeTitle.text = hindiData.title + episodeDesc.text = hindiData.description + } + + mediaType.text = "Teaser".localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) + " " + (teaserData.serialNumber?.toString() ?? "0") + episodeTimeLine.text = teaserData.teaserDuration + } + + @IBAction func closeBtnTapped(_ sender: UIButton) { + self.dismiss(animated: true) + } + + @IBAction func watchBtnTapped(_ sender: LocalisedElementsButton) { + self.dismiss(animated: true) { + self.onDoneBlock?() + } + } +} diff --git a/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift b/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift index c689fbc..b4eaec3 100644 --- a/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift +++ b/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift @@ -110,21 +110,62 @@ 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 ?? "") } } - if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] , let url = data.episodeURL{ - JWPlayerManager.shared.presentPlayer(from: self, withURLs: urls, titles: title,startIndex: indexPath.row) - } +// if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] , let url = data.episodeURL{ + // 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") + }// } } return cell } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let sb = UIStoryboard(name: K.StoryBoard.webSeries, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.WebSeries.episodeDetailsVC) as! EpisodeDetailsVC + + switch tableView{ + case teaserTableView: + let data = vm.teaserData[indexPath.row] + vcPush.teaserData = data + default: + let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row] + vcPush.episodeData = data + } + 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 ?? "") + } + } + +// 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) +// } + } + + vcPush.modalPresentationStyle = .overCurrentContext + vcPush.modalTransitionStyle = .crossDissolve + self.present(vcPush, animated: true) + } } // MARK: - CollectionView Delegate diff --git a/WOKA/WebSeries/JWPlayerManager.swift b/WOKA/WebSeries/JWPlayerManager.swift index f352e4a..f16a762 100644 --- a/WOKA/WebSeries/JWPlayerManager.swift +++ b/WOKA/WebSeries/JWPlayerManager.swift @@ -13,7 +13,7 @@ class JWPlayerManager { private init() {} - func presentPlayer(from viewController: UIViewController, withURLs liveStreamURLs: [String], titles: [String]? = nil, startIndex: Int = 0, completion: (() -> Void)? = nil) { + 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...") } @@ -46,9 +46,13 @@ class JWPlayerManager { // 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)!) .build() items.append(item) diff --git a/WOKA/WebSeries/WebSeries.storyboard b/WOKA/WebSeries/WebSeries.storyboard index 7d79d24..1740593 100644 --- a/WOKA/WebSeries/WebSeries.storyboard +++ b/WOKA/WebSeries/WebSeries.storyboard @@ -404,17 +404,16 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -660,6 +848,9 @@ + + +