From 93956e6e9829e8ff1d3632ae55e08711299ed13e Mon Sep 17 00:00:00 2001 From: BilalKhanWDI Date: Tue, 25 Jun 2024 11:29:00 +0530 Subject: [PATCH] - Handled the app life cycle for theme 2 - Added Teaser api with data model. - Handled the tabletitle show hide as per the media type - Updated hindi lingual file for web series - Worked on playing a item in playlist - Woka debugging for analytics --- WOKA.xcodeproj/project.pbxproj | 22 ++- .../PlayButton.imageset/PlayButton.png | Bin 1394 -> 1717 bytes .../PlayButton.imageset/PlayButton@2x.png | Bin 3091 -> 3849 bytes .../PlayButton.imageset/PlayButton@3x.png | Bin 1768 -> 2689 bytes WOKA/Home/ViewModel/MyListVM.swift | 11 +- .../hi.lproj/Localizable.strings | 3 + WOKA/Network Adapter/APIEndPoints.swift | 3 + WOKA/Theme/Controller/PlayerVC.swift | 11 +- WOKA/Theme/ViewModel/ThemeOneVM.swift | 103 ++++++++++--- WOKA/Theme/ViewModel/ThemeTwoVM.swift | 38 ++++- .../Controller/WebSeriesSeasonVC.swift | 52 ++++++- WOKA/WebSeries/Controller/WebSeriesVC.swift | 3 + WOKA/WebSeries/JWPlayerManager.swift | 141 ++++++++++++++++++ WOKA/WebSeries/Model/TeaserDM.swift | 85 +++++++++++ .../WebSeries/View/WebSeriesEpisodeCell.swift | 29 +++- WOKA/WebSeries/View/WebSeriesEpisodeCell.xib | 48 +++--- .../ViewModel/WebSeriesSeasonVM.swift | 83 +++++++++-- WOKA/WebSeries/WebSeries.storyboard | 104 +++++++++++-- 18 files changed, 630 insertions(+), 106 deletions(-) create mode 100644 WOKA/WebSeries/JWPlayerManager.swift create mode 100644 WOKA/WebSeries/Model/TeaserDM.swift diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 864ba9a..332c4bc 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -13,7 +13,6 @@ 522242662BFC74380085C632 /* MyListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242632BFC74380085C632 /* MyListVC.swift */; }; 522242682BFC74380085C632 /* TabBarVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242652BFC74380085C632 /* TabBarVC.swift */; }; 5222426A2BFC7AFC0085C632 /* SideMenuVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242692BFC7AFC0085C632 /* SideMenuVC.swift */; }; - 522A93132C0DB5D50098FE49 /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 522A93122C0DB5D50098FE49 /* JWPlayerKit */; }; 522A931A2C0DE8CC0098FE49 /* SideBarNav.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 522A93192C0DE8CC0098FE49 /* SideBarNav.storyboard */; }; 522A931C2C0DE9150098FE49 /* AboutUsVc.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522A931B2C0DE9150098FE49 /* AboutUsVc.swift */; }; 522D655E2C1ACCF40021E505 /* UserNotificationDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522D655D2C1ACCF40021E505 /* UserNotificationDM.swift */; }; @@ -89,6 +88,8 @@ 52A981D02C1AFEE8000E0BEC /* MyListVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A981CF2C1AFEE8000E0BEC /* MyListVM.swift */; }; 52A981D72C1B0E27000E0BEC /* FavouriteCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52A981D52C1B0E27000E0BEC /* FavouriteCell.swift */; }; 52A981D82C1B0E27000E0BEC /* FavouriteCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 52A981D62C1B0E27000E0BEC /* FavouriteCell.xib */; }; + 52AC2D252C295A7900337473 /* TeaserDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AC2D242C295A7900337473 /* TeaserDM.swift */; }; + 52AC2D272C29791500337473 /* JWPlayerManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AC2D262C29791500337473 /* JWPlayerManager.swift */; }; 52AECA802C08BCB6004A7579 /* PlayerVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52AECA7F2C08BCB6004A7579 /* PlayerVC.swift */; }; 52B8D4D92C04A25E00ED65F3 /* UIViewController+Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8D4CE2C04A25D00ED65F3 /* UIViewController+Container.swift */; }; 52B8D4DA2C04A25E00ED65F3 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B8D4CF2C04A25D00ED65F3 /* Preferences.swift */; }; @@ -150,6 +151,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 */; }; 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 */; }; @@ -340,6 +342,8 @@ 52A981CF2C1AFEE8000E0BEC /* MyListVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyListVM.swift; sourceTree = ""; }; 52A981D52C1B0E27000E0BEC /* FavouriteCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavouriteCell.swift; sourceTree = ""; }; 52A981D62C1B0E27000E0BEC /* FavouriteCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FavouriteCell.xib; sourceTree = ""; }; + 52AC2D242C295A7900337473 /* TeaserDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TeaserDM.swift; sourceTree = ""; }; + 52AC2D262C29791500337473 /* JWPlayerManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWPlayerManager.swift; sourceTree = ""; }; 52AECA7F2C08BCB6004A7579 /* PlayerVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerVC.swift; sourceTree = ""; }; 52B8D4CE2C04A25D00ED65F3 /* UIViewController+Container.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIViewController+Container.swift"; sourceTree = ""; }; 52B8D4CF2C04A25D00ED65F3 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = ""; }; @@ -485,7 +489,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 522A93132C0DB5D50098FE49 /* JWPlayerKit in Frameworks */, + 52E59A922C29AE3F00BB9B04 /* JWPlayerKit in Frameworks */, 9C1C69FA2C106B290035B2C7 /* RSKPlaceholderTextView in Frameworks */, 619A5A1BD8BD968ADC83C106 /* Pods_WOKA.framework in Frameworks */, ); @@ -962,6 +966,7 @@ 52DAC64A2C2176CB00E2F85B /* ViewModel */, 52DAC6492C21767900E2F85B /* Controller */, 52DAC6472C21762900E2F85B /* WebSeries.storyboard */, + 52AC2D262C29791500337473 /* JWPlayerManager.swift */, ); path = WebSeries; sourceTree = ""; @@ -1007,6 +1012,7 @@ 52D6A2532C22B93F00145908 /* CategoryListingDM.swift */, 528E5F1A2C24531200E33E4E /* SeasonListingDM.swift */, 9C007F1F2C255DF200F798C2 /* SeasonEpisodeListingDM.swift */, + 52AC2D242C295A7900337473 /* TeaserDM.swift */, ); path = Model; sourceTree = ""; @@ -1289,8 +1295,8 @@ ); name = WOKA; packageProductDependencies = ( - 522A93122C0DB5D50098FE49 /* JWPlayerKit */, 9C1C69F92C106B290035B2C7 /* RSKPlaceholderTextView */, + 52E59A912C29AE3F00BB9B04 /* JWPlayerKit */, ); productName = WOKA; productReference = 523ED25A2BDA2BC700CFED02 /* WOKA.app */; @@ -1366,8 +1372,8 @@ ); mainGroup = 523ED2512BDA2BC700CFED02; packageReferences = ( - 522A93112C0DB5D50098FE49 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */, 9C1C69F82C106B290035B2C7 /* XCRemoteSwiftPackageReference "RSKPlaceholderTextView" */, + 52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */, ); productRefGroup = 523ED25B2BDA2BC700CFED02 /* Products */; projectDirPath = ""; @@ -1577,6 +1583,7 @@ 9C56E83B2BDBC6E600E4CA14 /* SelectAgeVM.swift in Sources */, 9C535DC02C00B36000DA6DCD /* HomeVC.swift in Sources */, 52B8D4E22C04A25E00ED65F3 /* Segue.swift in Sources */, + 52AC2D272C29791500337473 /* JWPlayerManager.swift in Sources */, 5259542E2BEA393700191286 /* AlertCustomVC.swift in Sources */, 52CA28FA2BE119F500708B49 /* UserIntrestVC.swift in Sources */, 9CBE1B442C0F37B300CA6E61 /* DropDown+Appearance.swift in Sources */, @@ -1644,6 +1651,7 @@ 52C1A4E12C05B69F007BAA50 /* UIApplicationSwitchRoot.swift in Sources */, 52663FF72BDFACF60001D8CE /* ShadowView.swift in Sources */, 522D65602C1ACD8D0021E505 /* UserNotificationVC.swift in Sources */, + 52AC2D252C295A7900337473 /* TeaserDM.swift in Sources */, 9C535DC22C00B36900DA6DCD /* ThemeTwoVC.swift in Sources */, 9CA7C6C22C1095B600D73742 /* ProfileVM.swift in Sources */, 52D774F12BDFC53B001D87DE /* StringSubScript.swift in Sources */, @@ -2074,7 +2082,7 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 522A93112C0DB5D50098FE49 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = { + 52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/jwplayer/JWPlayerKit-package.git"; requirement = { @@ -2093,9 +2101,9 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 522A93122C0DB5D50098FE49 /* JWPlayerKit */ = { + 52E59A912C29AE3F00BB9B04 /* JWPlayerKit */ = { isa = XCSwiftPackageProductDependency; - package = 522A93112C0DB5D50098FE49 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */; + package = 52E59A902C29AE3F00BB9B04 /* XCRemoteSwiftPackageReference "JWPlayerKit-package" */; productName = JWPlayerKit; }; 9C1C69F92C106B290035B2C7 /* RSKPlaceholderTextView */ = { diff --git a/WOKA/Assets/Assets.xcassets/WebSeries/PlayButton.imageset/PlayButton.png b/WOKA/Assets/Assets.xcassets/WebSeries/PlayButton.imageset/PlayButton.png index effc134950463d1f3ccfa4bc56e76e608a0f2669..ef4bbd35c593dede2355d0f351f505ec24a74113 100644 GIT binary patch literal 1717 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 A_5c6? diff --git a/WOKA/Assets/Assets.xcassets/WebSeries/PlayButton.imageset/PlayButton@2x.png b/WOKA/Assets/Assets.xcassets/WebSeries/PlayButton.imageset/PlayButton@2x.png index 20b5275ef8531b7b2faf52bb5acb227acbb68def..96690c043be2d18efb56fe2bd9477dfaff1aee0e 100644 GIT binary patch literal 3849 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 LNkvXXu0mjfa8YRs literal 3091 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 diff --git a/WOKA/Assets/Assets.xcassets/WebSeries/PlayButton.imageset/PlayButton@3x.png b/WOKA/Assets/Assets.xcassets/WebSeries/PlayButton.imageset/PlayButton@3x.png index 446dd9378574c247e74c145f9d22e6585f3b13b0..58414e095ba3f1ea45e9e2e69eddf6a8518de818 100644 GIT binary patch literal 2689 zcmV-{3V!v8P)Px#*%2TFeA*YlE5LiX`fIMG z{~#cU5JMmG{RFpn^*q(wQ`iuohl3X$#IX#3uj~si+p}Wl2feh2uJ(z$Cz57cc9Y9RpmdJoeN5`tt} zcjfoMNTRb}hkj5w0e-~Mu@8B{P{_%LsoD}_32|0+%2+7@p5f@VgnUzNKefB|s$D`Q z1PG&i`A)(gv>Tp!-j346C+M7yaYdt%Mla(82*ICzcK+TdPQj?75APS#ae+|+M8eKz zm*SZPKT(_U;LsQW9Qc)ip03y^35*cHfnOW=@q>(!pfmv-__c%oNP?&6?3E1+OA){Y ze2sx0JeUH*C-C;mkf0O+p5gdcm+Cc50$hE^&53R+vo&zmup=ZTfaDg9x0z9m`T5APX62Qs5tpGm`2v??sD+#cLgD2T<#7n14=8|=# z704t27vCTIw;m4O2#8ZRKCzkzt73sn0&L;%!^37sv=xihSMsGOT?M8@1edX7qn2p} zmI%Np@6TfOj~MiQ%!t5l@o9<(Pto})J$opF0DSWPbtz61#L_l1jtCJEvedyP0&q(G z@^W0~7M6U$_#QVuCI7oX04~8_`~rCdh|7g;ZTi9ftfu;qE8S;l0IqO%(ZgO3E@X8xlgPvwaZ zX&g2=K1hBzNdmAk|78iV*=|8z-s3jds^^gaJfz>n?^wqLtg^@(rY4T=akKkK08Zjh z5xvM5X%iTgSI203rRsLU82{d8WTBs%lvapE!9j*0achzA5mi2@7 zsEHDP?Fx`Y9L`Q%c31FjJ za0F<80MYO}iEoXsS#SiXkpMqn(C=bKz*{r&>IhH+0ch;te~_we`*P_iW_xa0xMDBbsNyL$eO0k=S~&g6byiRvS%A$d zUKs*V3OK=SyfDNq4a@3G%T>HG_|u%~`O+}1+rn050eGl*Y#=TJ8Cq)t+oIy>!;gjCLN{uo$Tq2Xx&&CeQ6#se z;;Jz~3spQ_{Fkg|)@IRcb_>ZPKwDKjZS;Z1?cw4&vbKw-LlA}CsU9LGc&i;)f=m?Z(_HE-!tn^^1>#n)jR=}lOrje?qzO{j$ zauAp-=mNrOkgB5AyueS30AWDLbNYA{oos8Js-{0~e{L3#e$g!)eF0?O)(+V4b}5^F zZ30AV30+oTAJfJXoxSvEUtTi{TYxYt2)0M336<`$qzBf?z3ZB&MF5u?T7r7ijG}&D zI|xj_Hs|eS?1E6gH4^gu1h)g-8ni6{JusX-Fq=yH7w4pP;)Rp9HQ`TPXs} zNf1cIP9)MnK>wbRL}$Nf(3gH(X##}tKrmiFL&uH;`hXU>(+K$VKqCZjBq)Mi>9WSa zH%b6Ug3`dMRA3Z*;{=$K!2jR^Llr#L%a{oGvYuwl1tcqXQ?%8ARVhiSUJu=~GSU93 z=Tt&~_+f4yfeO6q%ajp$RGwZb0YaA$$i{R?f}2sKg2=qgSYmcQ!EaZ^ZYx&0ass&E zuoxg=U?zt?y1$go@l~E&3jv%yD0BYb8Kv4T1$HG?M5Kt%^|v5HBrO6~_|zh;W)#t?8U9;OTN~ z2#{>}oD6v0bi5#ek%0U}!1vG{Hj&Edf=~CcB)}pW20I?6eF;$9@LT{CKvp&GKxTa? zfUgo_*hA+dH^5tA0rD9C1OD0Xz}uGao_p|jeTbh0uq`0BCB*i_y7^2MlD_7sZu(1K v_J4eM-#YMr_c0w#@b85!*7DlH;rIUoaLkB!jGMtk00000NkvXXu0mjfRVv)t literal 1768 zcmVP)Px*qDe$SRCr$Por`hZHV{R3JFqISU4fGhq6%VHV5@>i6~wL}Rt1(SuvCGS3L;k! zxq`R@gqO2;1M!grKmx>q517$tM*N7p2iRRKK4el_j4>~W=ocb-LqxBM=p_-oA|m|V z{!0ua&P zcY;9p-!@j`p@V!wM1M1LF&ISv7-Jyzp9MspVtm(`xm#w&?@h~Q0G!%>nZdlI5)Cck zBQxKox}onrn*cDzd?2E~#CiIjNyG8YKx73VrUt?znyIk>#3eJsac3!60EoHyBF;6- zgKvCOIO|V2oON;l#u!925FfGno=O(8lnj8>dPFvGvU@I{nfWT!3nl?zj6o0eYsI!c zR!_8s^Asj&H2`A_94y2Kgi|Vj@Q#_$yIx#Y0Wij(7yEgK_C8cl)av;(EytGvkg8PLKFaTxZh6L=KIVod;+4QV84?Y)N^CT;jxK|N+K07)eyx6?|z0_dpC z4)V+bXm&qd@xc`^L9gdbkq-bmTIlVzvRr{XW_~wy`6K{IDL>DOQY&GDvF-nr9gFL|^Dbm@jx`_nTRb;w5m6x99;nKQJgEMvkAlJY36!D{X@BtW@rCR;N!3^1m15LWP`GL5h0Cr%OdNX7J!11cc`@{lp zK-3ntUNG~G1)wJDxfDQ!Ve56*0xm6pf3!?1Tmzu8u(j`$u}rG{Z-qxsdT9y(75RrV z06^q}2uMXq37~?o^&9{&*p5MW6(uzQ-vA5%NNNWCBGmrur8!|o;sTqB^iH^i zq2=~3>cdbqsc2NjEu$bYH%P^lngRZB%BcvuuSLl|P@jr8wPYNk8bmi5rndCSxKm0; zXAdhQ!=^qRz4rkbn3&DN%18kHfD9gR&qI=$_o_RygYs%Z(G*dT!fi3f8b-fr#sW~| zh}Qs65LU)mpc`hsumDud3tiI>=(4&R!pax`Z?PMr1)#OI5#7qIVP5kZmi~ ztRY^fMUkt$dr5l%h(Ay>U{gfKW&gBa2kg5v6aY*SR?^h^IVztHsgF-aJ;Q$#1VCB= z=FzmxyZxxVcHg~4FaUvo7SOh@pN5cc`})>P_E&u(>NnsBI#W)HY5@(xthCYM&-R3U z6kERNnL>-iUj;yXLTz73_0_A`gHwyk7H zE5Ij8kYHQ=DfA=&9OrxrJ?87~eeu<8@AqLsNG1i~_ysMyk%VXvdJY7KvrYQl`Q!kc zUUT+E&Y{XBI1i#j{3NwLsS}=iIoXRE6R9*T2U@}bwjNQ==+`fn+;DhJmKHGLq-)!9 zc=cCOL*Z-!V9>m)-AdtAtVQ#X8p`o-L5E$ga+T5Z$wL8xZ6Z0vjshQGf(-tt% zf56~BU}W7CV?+Rm4(GaAZCBF*CVJFx)JS)uRlLbC_yhBTIhk;*__kN_h$hw&;QXR3 zz!O1X6b?WD1E2kPDYNwe3de>s_aLbKf!IG}hTnIHu0` 1{ + 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{ - indicesToRemove.append(index) + }else{ // means single language + if bookMarkCatID.first == "18"{ + indicesToRemove.append(index) + } } } } diff --git a/WOKA/Localized Module/hi.lproj/Localizable.strings b/WOKA/Localized Module/hi.lproj/Localizable.strings index 9b81087..bfb2d32 100644 --- a/WOKA/Localized Module/hi.lproj/Localizable.strings +++ b/WOKA/Localized Module/hi.lproj/Localizable.strings @@ -222,3 +222,6 @@ "Select Video Language" = "वीडियो भाषा चुनें"; "TRAILER" = "ट्रेलर"; +"TEASERS" = "टीज़र"; +"CONTINUE WATCHING" = "देखना जारी रखें"; +"PLAY TRAILER" = "प्ले ट्रेलर"; diff --git a/WOKA/Network Adapter/APIEndPoints.swift b/WOKA/Network Adapter/APIEndPoints.swift index 093993f..16c4aed 100644 --- a/WOKA/Network Adapter/APIEndPoints.swift +++ b/WOKA/Network Adapter/APIEndPoints.swift @@ -21,6 +21,8 @@ struct APIEndPoints { struct BaseURL { static let staging = "https://wokaland.com/admin/api/" static let production = "https://simplitend.com" + + static let appUrl = "https://apps.apple.com/in/app/woka/id6465305185" } struct Auth { @@ -85,6 +87,7 @@ struct APIEndPoints { static let category_listing = makeURL(path: "category_listing") static let season_listing = makeURL(path: "season_listing") static let season_episode_listing = makeURL(path: "season_episode_listing") + static let teaser_listing = makeURL(path: "teaser_listing") } // Other endpoint categories... diff --git a/WOKA/Theme/Controller/PlayerVC.swift b/WOKA/Theme/Controller/PlayerVC.swift index d293b0e..fefe567 100644 --- a/WOKA/Theme/Controller/PlayerVC.swift +++ b/WOKA/Theme/Controller/PlayerVC.swift @@ -16,6 +16,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { let backButton = UIButton(type: .system) var config: JWPlayerConfiguration! var dismissTapped: (() -> Void)? + var videoIndex : Int? func rotateToLandsScapeDevice(){ let appDelegate = UIApplication.shared.delegate as! AppDelegate @@ -42,16 +43,14 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { // UIDevice.current.setValue(UIInterfaceOrientation.portrait.rawValue, forKey: "orientation") UIView.setAnimationsEnabled(true) } + override func viewDidLoad() { super.viewDidLoad() self.rotateToLandsScapeDevice() self.delegate = self player.configurePlayer(with: config) - -// NotificationCenter.default.addObserver(self, selector: #selector(applicationDidBecomeActive), name: UIApplication.willEnterForegroundNotification, object: nil) } - @objc func applicationDidBecomeActive() { self.setDeviceOrientation(orientation: .landscapeRight) } @@ -85,11 +84,13 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { override func jwplayer(_ player: any JWPlayer, didFinishLoadingWithTime loadTime: TimeInterval) { super.jwplayer(player, didFinishLoadingWithTime: loadTime) print("LoadTime", loadTime) - self.player.play() +// self.player.play() } override func jwplayerIsReady(_ player: JWPlayer) { super.jwplayerIsReady(player) + player.loadPlayerItemAt(index: 4) + player.seek(to: 30) print("IsReady") } @@ -121,7 +122,7 @@ class PlayerVC: JWPlayerViewController, JWPlayerViewControllerDelegate { override func jwplayer(_ player: JWPlayer, isBufferingWithReason reason: JWBufferReason) { super.jwplayer(player, isBufferingWithReason: reason) - player.play() +// player.play() print("Buffering Reason:", reason) } diff --git a/WOKA/Theme/ViewModel/ThemeOneVM.swift b/WOKA/Theme/ViewModel/ThemeOneVM.swift index 926322b..ff3616c 100644 --- a/WOKA/Theme/ViewModel/ThemeOneVM.swift +++ b/WOKA/Theme/ViewModel/ThemeOneVM.swift @@ -192,60 +192,119 @@ class ThemeOneVM{ vc.liveTVView.isUserInteractionEnabled = true } - // function which is triggered when handleTap is called + // function which is triggered when handleTap on livetv is called @objc func handleTap(_ sender: UITapGestureRecognizer) { Utilities.startProgressHUD(msg: "Loading...") print("tapped") - let vc = self.vc.storyboard?.instantiateViewController(identifier: "PlayerVC") as! PlayerVC + + guard let storyboard = self.vc.storyboard else { + print("Storyboard not found") + Utilities.dismissProgressHUD() + return + } + + guard let vc = storyboard.instantiateViewController(identifier: "PlayerVC") as? PlayerVC else { + print("PlayerVC not found") + Utilities.dismissProgressHUD() + return + } 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() + // Ensure the liveStreamURL is valid + guard let liveStreamURL = URL(string: self.liveStreamURL) else { + print("Invalid live stream URL") + Utilities.dismissProgressHUD() + return + } // Create a JWPlayerItem let item = try JWPlayerItemBuilder() - .file(URL(string: self.liveStreamURL)!) + .file(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. + // Create a JWPlayerConfiguration 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() + + // Present the PlayerVC 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 + } catch { + print("Error creating JWPlayer configuration: \(error)") + Utilities.dismissProgressHUD() } + + // Dismiss the progress HUD after the view controller presentation + 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 - self.startLiveStream() + self.avPlayer.play() + self.moveLiveTVView() self.vc.liveTvPlayer.layoutIfNeeded() } print("Sadasd") diff --git a/WOKA/Theme/ViewModel/ThemeTwoVM.swift b/WOKA/Theme/ViewModel/ThemeTwoVM.swift index af9209a..41441f3 100644 --- a/WOKA/Theme/ViewModel/ThemeTwoVM.swift +++ b/WOKA/Theme/ViewModel/ThemeTwoVM.swift @@ -21,6 +21,9 @@ class ThemeTwoVM{ var avPlayer : AVPlayer! var playerLayer: AVPlayerLayer! + /* + Static cell data + */ var cellData = [Theme2Struct(imageName: "WokaFMT2", text: "WOKA FM"), Theme2Struct(imageName: "LiveTVT2", text: "LIVE TV"), Theme2Struct(imageName: "WebSeriesT2", text: "WEB SERIES"), @@ -31,11 +34,38 @@ class ThemeTwoVM{ func initView(){ setupCell() - NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil) setupAvPlayer() setUserData() + + handleNotificationCenter() } + private func handleNotificationCenter(){ + NotificationCenter.default.addObserver(self, selector: #selector(self.reloadTheme), name: NSNotification.Name(rawValue: K.NotificationCenterReloads.reloadTheme), object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(appDidEnterBackground), name: UIApplication.didEnterBackgroundNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(appWillEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil) + } + + // MARK: - Notification Center Handlers + + @objc func reloadTheme(){ + self.vc.delegate?.didPressSwitchButton(from: self.vc) + } + + @objc func appDidEnterBackground() { + // Code to execute when the app enters the background + print("App entered background") + self.avPlayer.pause() + } + + @objc func appWillEnterForeground() { + // Code to execute when the app enters the foreground + print("App will enter foreground") + self.avPlayer.play() + } + + // MARK: - Live TV + func playLiveTV(){ Utilities.startProgressHUD(msg: "Loading...") print("tapped") @@ -177,11 +207,7 @@ class ThemeTwoVM{ } - // MARK: - Notification Center Handlers - - @objc func reloadTheme(){ - self.vc.delegate?.didPressSwitchButton(from: self.vc) - } + // MARK: - SetupCell func setupCell(){ vc.collectionView.register(UINib(nibName: K.CellIdentifier.Theme.homeExploreCell, bundle: nil), forCellWithReuseIdentifier: K.CellIdentifier.Theme.homeExploreCell) diff --git a/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift b/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift index d87546d..c689fbc 100644 --- a/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift +++ b/WOKA/WebSeries/Controller/WebSeriesSeasonVC.swift @@ -19,9 +19,16 @@ class WebSeriesSeasonVC: UIViewController { @IBOutlet weak var seasonDesc: UILabel! @IBOutlet weak var categoryCV: UICollectionView! + + //Episode Outlet + @IBOutlet weak var episodeTitle: UILabel! @IBOutlet weak var episodeTableView: UITableView! @IBOutlet weak var tableHeight: NSLayoutConstraint! + //Teaser Outlet + @IBOutlet weak var teaserTableView: UITableView! + @IBOutlet weak var teaserTableHeight: NSLayoutConstraint! + @IBOutlet weak var teaserTitle: LocalisedElementsLabel! @IBOutlet weak var addIcon: UIImageView! @IBOutlet weak var addLabel: UILabel! @@ -63,13 +70,23 @@ class WebSeriesSeasonVC: UIViewController { @IBAction func watchBtnTapped(_ sender: LocalisedElementsButton) { } + @IBAction func retryBtnTapped(_ sender: LocalisedElementsButton) { + } + } // MARK: - TableView DataSource , Delegates extension WebSeriesSeasonVC : TableViewSRC{ func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return vm.seasonEpisodeData.count + switch tableView{ + case episodeTableView: + return vm.seasonEpisodeData.first?.episodeData?.count ?? 0 + case teaserTableView: + return vm.teaserData.count + default: + return 0 + } } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { @@ -78,9 +95,34 @@ extension WebSeriesSeasonVC : TableViewSRC{ func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: K.CellIdentifier.WebSeries.webSeriesEpisodeCell) as! WebSeriesEpisodeCell + switch tableView{ + case episodeTableView: + if let data = vm.seasonEpisodeData.first?.episodeData?[indexPath.row]{ + cell.setData(data: data) + } + case teaserTableView: + let data = vm.teaserData[indexPath.row] + cell.setTeaserData(data: data) + default: + break + } + + cell.btnTapped = { [self] () -> Void in + var urls = [String]() + var title = [String]() + if let episodeData = vm.seasonEpisodeData.first?.episodeData{ + for i in episodeData{ + urls.append(i.episodeURL ?? "") + title.append(i.episodeTitle ?? "Episode") + } + } + + 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) + } + + } - let data = vm.seasonEpisodeData[indexPath.row] - cell.setData(data: data) return cell } } @@ -103,7 +145,11 @@ extension WebSeriesSeasonVC : CollectionViewSRC{ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { vm.episodeSelectedCateogory = vm.seasonListingData[indexPath.row].id + vm.setSeasonData() + episodeTitle.isHidden = false + episodeTitle.text = "" vm.getSeasonEpisode() + vm.getTeaserListing() self.categoryCV.reloadData() } } diff --git a/WOKA/WebSeries/Controller/WebSeriesVC.swift b/WOKA/WebSeries/Controller/WebSeriesVC.swift index a36e050..8c942c4 100644 --- a/WOKA/WebSeries/Controller/WebSeriesVC.swift +++ b/WOKA/WebSeries/Controller/WebSeriesVC.swift @@ -60,6 +60,9 @@ class WebSeriesVC: UIViewController { // MARK: - Tap Handler + @IBAction func playTrailer(_ sender: LocalisedElementsButton) { + } + @IBAction func expandLanguageTapped(_ sender: UIButton) { vm.dropDownModule.show() self.expandBtn.setImage(UIImage(named: "SupportUpArrow"), for: .normal) diff --git a/WOKA/WebSeries/JWPlayerManager.swift b/WOKA/WebSeries/JWPlayerManager.swift new file mode 100644 index 0000000..f352e4a --- /dev/null +++ b/WOKA/WebSeries/JWPlayerManager.swift @@ -0,0 +1,141 @@ +// +// JWPlayerManager.swift +// WOKA +// +// Created by MacBook Pro on 24/06/24. +// + +import UIKit +import JWPlayerKit + +class JWPlayerManager { + static let shared = JWPlayerManager() + + private init() {} + + func presentPlayer(from viewController: UIViewController, withURLs liveStreamURLs: [String], titles: [String]? = nil, startIndex: Int = 0, completion: (() -> Void)? = nil) { + DispatchQueue.main.async { + Utilities.startProgressHUD(msg: "Loading...") + } + + 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 + } + + DispatchQueue.main.async { + do { + // Create an array to hold the JWPlayerItems + 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 + } + + // 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 + } + + // Use the corresponding title if provided, otherwise use a default title + let itemTitle = titles?[index] ?? "Default Title \(index + 1)" + let item = try JWPlayerItemBuilder() + .file(url) + .title(itemTitle) + .build() + + items.append(item) + } + + // Ensure there is at least one valid item + guard !items.isEmpty else { + print("No valid items to play") + Utilities.dismissProgressHUD() + return + } + + // Create a JWPlayerConfiguration with the playlist + let config = try JWPlayerConfigurationBuilder() + .playlist(items: items) + .autostart(false) + .build() + + playerVC.videoIndex = startIndex + playerVC.config = config + playerVC.modalPresentationStyle = .overFullScreen + + // Present the PlayerVC + viewController.present(playerVC, animated: false) { + 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 + Utilities.dismissProgressHUD() + } + } + +// func presentPlayer(from viewController: UIViewController, withURL liveStreamURL: String, title: String = "Testing Title", completion: (() -> Void)? = nil) { +// Utilities.startProgressHUD(msg: "Loading...") +// +// 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 +// } +// +// DispatchQueue.main.async { +// do { +// // Ensure the liveStreamURL is valid +// guard let url = URL(string: liveStreamURL) else { +// print("Invalid live stream URL") +// Utilities.dismissProgressHUD() +// return +// } +// +// // Create a JWPlayerItem +// let item = try JWPlayerItemBuilder() +// .file(url) +// .title(title) +// .build() +// +// // Create a JWPlayerConfiguration +// let config = try JWPlayerConfigurationBuilder() +// .playlist(items: [item]) +// .autostart(true) +// .build() +// +// playerVC.config = config +// playerVC.modalPresentationStyle = .overFullScreen +// +// // Present the PlayerVC +// viewController.present(playerVC, animated: false) { +// 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 +// Utilities.dismissProgressHUD() +// } +// } +} diff --git a/WOKA/WebSeries/Model/TeaserDM.swift b/WOKA/WebSeries/Model/TeaserDM.swift new file mode 100644 index 0000000..9e94a72 --- /dev/null +++ b/WOKA/WebSeries/Model/TeaserDM.swift @@ -0,0 +1,85 @@ +// +// TeaserDM.swift +// WOKA +// +// Created by MacBook Pro on 24/06/24. +// + +import Foundation + +// MARK: - TeaserDM +struct TeaserDM: Codable { + let result: [ResultData]? + let totalRecords: Int? + + enum CodingKeys: String, CodingKey { + case result + case totalRecords = "total_records" + } + + // MARK: - ResultData + struct ResultData: Codable { + let id, watchShowsMasterID, seasonMasterID, teaserNumber: Int? + let serialNumber: Int? + let teaserTitle, teaserDescription: String? + let thumbnailPath: String? + let thumbnailImgURL: String? + let teaserURL: String? + let languageMasterID: Int? + let tagsKeyword, teaserDuration, releaseDate: String? + let contentMoreDetails: [ContentMoreDetail]? + let seasonData: SeasonData? +// let userVideoView: [JSONAny]? + + enum CodingKeys: String, CodingKey { + case id + case watchShowsMasterID = "watch_shows_master_id" + case seasonMasterID = "season_master_id" + case teaserNumber = "teaser_number" + case serialNumber = "serial_number" + case teaserTitle = "teaser_title" + case teaserDescription = "teaser_description" + case thumbnailPath = "thumbnail_path" + case thumbnailImgURL = "thumbnail_img_url" + case teaserURL = "teaser_url" + case languageMasterID = "language_master_id" + case tagsKeyword = "tags_keyword" + case teaserDuration = "teaser_duration" + case releaseDate = "release_date" + case contentMoreDetails = "content_more_details" + case seasonData = "season_data" +// case userVideoView = "user_video_view" + } + } + + // MARK: - ContentMoreDetail + struct ContentMoreDetail: Codable { + let id, contentID, postType, languageMasterID: Int? + let title, description, tagsKeywords: String? + let contentHDURL, contentSDURL: String? + + enum CodingKeys: String, CodingKey { + case id + case contentID = "content_id" + case postType = "post_type" + case languageMasterID = "language_master_id" + case title, description + case tagsKeywords = "tags_keywords" + case contentHDURL = "content_hd_url" + case contentSDURL = "content_sd_url" + } + } + + // MARK: - SeasonData + struct SeasonData: Codable { + let id, watchShowsMasterID: Int? + let seasonNumber: String? + + enum CodingKeys: String, CodingKey { + case id + case watchShowsMasterID = "watch_shows_master_id" + case seasonNumber = "season_number" + } + } + +} diff --git a/WOKA/WebSeries/View/WebSeriesEpisodeCell.swift b/WOKA/WebSeries/View/WebSeriesEpisodeCell.swift index a5825dd..cdb3e91 100644 --- a/WOKA/WebSeries/View/WebSeriesEpisodeCell.swift +++ b/WOKA/WebSeries/View/WebSeriesEpisodeCell.swift @@ -14,8 +14,12 @@ class WebSeriesEpisodeCell: UITableViewCell { @IBOutlet weak var seasonTime: UILabel! @IBOutlet weak var playBtn: UIButton! + typealias btnTappedBlock = () -> Void // 0 - plus 1 - minus + var btnTapped : btnTappedBlock! + override func awakeFromNib() { super.awakeFromNib() + // Initialization code } @@ -25,18 +29,37 @@ class WebSeriesEpisodeCell: UITableViewCell { // Configure the view for the selected state } - func setData(data : SeasonEpisodeListingDM.ResultData){ + func setData(data : SeasonEpisodeListingDM.EpisodeDatum){ if let url = data.thumbnailPath{ self.seasonImage.imageURL(url, color: UIColor.appColor(.TextDarkBlue)!) } + self.seasonTime.text = data.episodeDuration ?? "0:00:00" + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ - seasonTitle.text = data.seasonMoreDetails?.filter({$0.languageMasterID == 1}).first?.title + seasonTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first?.title }else{ - seasonTitle.text = data.seasonMoreDetails?.filter({$0.languageMasterID == 2}).first?.title + seasonTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first?.title + } + } + + func setTeaserData(data : TeaserDM.ResultData){ + if let url = data.thumbnailPath{ + self.seasonImage.imageURL(url, color: UIColor.appColor(.TextDarkBlue)!) + } + + self.seasonTime.text = data.teaserDuration ?? "0:00:00" + + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ + seasonTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first?.title + }else{ + seasonTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first?.title } } @IBAction func playBtnTapped(_ sender: UIButton) { + if btnTapped != nil { + btnTapped() + } } } diff --git a/WOKA/WebSeries/View/WebSeriesEpisodeCell.xib b/WOKA/WebSeries/View/WebSeriesEpisodeCell.xib index 31f9d70..8e7de22 100644 --- a/WOKA/WebSeries/View/WebSeriesEpisodeCell.xib +++ b/WOKA/WebSeries/View/WebSeriesEpisodeCell.xib @@ -6,7 +6,6 @@ - @@ -42,10 +41,10 @@ - + - - - - - - + @@ -115,12 +104,9 @@ Episodes - + - - - diff --git a/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift b/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift index 234bfa3..4e5375e 100644 --- a/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift +++ b/WOKA/WebSeries/ViewModel/WebSeriesSeasonVM.swift @@ -12,7 +12,6 @@ class WebSeriesSeasonVM{ weak var vc : WebSeriesSeasonVC! -// var watchShowID : Int? var categoryID : Int? var episodeSelectedCateogory : Int? @@ -21,6 +20,8 @@ class WebSeriesSeasonVM{ var seasonEpisodeData = [SeasonEpisodeListingDM.ResultData]() + var teaserData = [TeaserDM.ResultData]() + var showData : WebSeriesShowListDM.ShowDatum? func initView(){ @@ -67,13 +68,6 @@ class WebSeriesSeasonVM{ vc.addIcon.image = UIImage(systemName: "heart") vc.addLabel.text = "Add" } -// switch favourite{ -// case true: -// favBtn.setImage(UIImage(systemName: "heart.fill"), for: .normal) -// case false: -// favBtn.setImage(UIImage(systemName: "heart"), for: .normal) -// -// } } } @@ -85,6 +79,10 @@ class WebSeriesSeasonVM{ vc.episodeTableView.register(UINib(nibName: K.CellIdentifier.WebSeries.webSeriesEpisodeCell, bundle: nil), forCellReuseIdentifier: K.CellIdentifier.WebSeries.webSeriesEpisodeCell) vc.episodeTableView.delegate = vc.self vc.episodeTableView.dataSource = vc.self + + vc.teaserTableView.register(UINib(nibName: K.CellIdentifier.WebSeries.webSeriesEpisodeCell, bundle: nil), forCellReuseIdentifier: K.CellIdentifier.WebSeries.webSeriesEpisodeCell) + vc.teaserTableView.delegate = vc.self + vc.teaserTableView.dataSource = vc.self } // MARK: - Api Calls @@ -113,9 +111,10 @@ class WebSeriesSeasonVM{ Utilities.dismissProgressHUD() guard let data = data.data?.result else{return} self.seasonListingData = data - setSeasonData() episodeSelectedCateogory = seasonListingData.first?.id + setSeasonData() getSeasonEpisode() + getTeaserListing() self.vc.categoryCV.reloadData() default: break @@ -132,12 +131,12 @@ class WebSeriesSeasonVM{ } func setSeasonData(){ - guard let data = seasonListingData.first else{return} + guard let data = seasonListingData.filter({$0.id == episodeSelectedCateogory}).first else{return} vc.seasonImage.imageURL(data.thumbnailPath!, color: UIColor.appColor(.TextDarkBlue)!) if AuthFunc.shareInstance.getDefaultLanguage() == .english{ let englishData = data.seasonMoreDetails?.filter({$0.languageMasterID == 1}).first - vc.seasonTitle.text = englishData?.title + vc.seasonTitle.text = (englishData?.title ?? "NA") + "\n" + (data.seasonNumber ?? "NA") if let desc = englishData?.description?.replacingOccurrences(of: "
", with: "").htmlToAttributedString{ let sizeText = NSMutableAttributedString(attributedString: desc) @@ -146,7 +145,7 @@ class WebSeriesSeasonVM{ } }else{ let hindiData = data.seasonMoreDetails?.filter({$0.languageMasterID == 2}).first - vc.seasonTitle.text = hindiData?.title + vc.seasonTitle.text = (hindiData?.title ?? "NA") + "\n" + (data.seasonNumber ?? "NA") 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)!) @@ -184,6 +183,16 @@ class WebSeriesSeasonVM{ guard let data = data.data?.result else{return} self.seasonEpisodeData.removeAll() self.seasonEpisodeData = data + self.seasonEpisodeData = self.seasonEpisodeData.filter { + $0.episodeData != nil && !$0.episodeData!.isEmpty + } + if self.seasonEpisodeData.count == 0{ + self.vc.episodeTitle.isHidden = true + self.vc.episodeTitle.text = "" + }else{ + self.vc.episodeTitle.isHidden = false + self.vc.episodeTitle.text = data.first?.mediaType?.uppercased() + } self.vc.episodeTableView.reloadData() self.vc.tableHeight.constant = self.vc.episodeTableView.contentSize.height + 100 @@ -202,4 +211,54 @@ class WebSeriesSeasonVM{ } } } + + func getTeaserListing(){ + guard let watchShowID = showData?.id, let episodeSelectedCateogory else{return} + let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()] + let params : Parameters = ["watch_show_master_id" : watchShowID, + "season_master_id" : episodeSelectedCateogory] + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.WebSeries.teaser_listing, method: .post,parameters: params,headers : headers) { [weak self](result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + guard let self else{ + Utilities.dismissProgressHUD() + return + } + switch data.success{ + case 0: + /* + Error + */ + Utilities.dismissProgressHUD() + self.teaserData.removeAll() + self.reloadTeaserTable() + self.vc.teaserTitle.isHidden = true +// vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + Utilities.dismissProgressHUD() + guard let data = data.data?.result else{return} + self.teaserData.removeAll() + self.teaserData = data + self.reloadTeaserTable() + self.vc.teaserTitle.isHidden = false + default: + break + } + case .failure(let error): + guard let self else{ + Utilities.dismissProgressHUD() + return + } + Utilities.dismissProgressHUD() + vc.toast(msg: error.localizedDescription , time: 2) + } + } + } + + private func reloadTeaserTable(){ + self.vc.teaserTableView.reloadData() + self.vc.teaserTableHeight.constant = self.vc.teaserTableView.contentSize.height + 100 + self.vc.teaserTableView.layoutIfNeeded() + self.vc.teaserTableHeight.constant = self.vc.teaserTableView.contentSize.height + } } diff --git a/WOKA/WebSeries/WebSeries.storyboard b/WOKA/WebSeries/WebSeries.storyboard index b58737d..7d79d24 100644 --- a/WOKA/WebSeries/WebSeries.storyboard +++ b/WOKA/WebSeries/WebSeries.storyboard @@ -35,14 +35,42 @@ + + + @@ -103,7 +131,7 @@