From a8f0b7b662a5cd72a8940b60f00397ec1c2a4ac5 Mon Sep 17 00:00:00 2001 From: Bilal Date: Fri, 14 Jun 2024 21:27:18 +0530 Subject: [PATCH] - contact apple developer, now if enrolling for a organisation account, same domain website is compulsary - Completed the blogs detail screen, also handled the language change. - added a nsnotification to handle the sidebar only on home an my list - Added api for like , unlike , fav remove, with data models. - handled the like unlike realtime, without the extra network call. - added realtime language change will update the fav cells. --- WOKA.xcodeproj/project.pbxproj | 68 ++++- .../CloseIconEmpty.png | Bin 0 -> 1456 bytes .../CloseIconEmpty@2x.png | Bin 0 -> 3724 bytes .../CloseIconEmpty@3x.png | Bin 0 -> 2533 bytes .../CloseIconEmpty.imageset/Contents.json | 26 ++ WOKA/Authentication/Controller/LoginVC.swift | 4 +- WOKA/Constants K/GVar.swift | 1 + WOKA/Constants K/StoryBoardID.swift | 1 + WOKA/Helpers/HTML/HtmlText.swift | 218 ++++++++++++++++ WOKA/Helpers/NsNotificationExtension.swift | 1 + WOKA/Home/Controller/MyListVC.swift | 235 +++++++++++++++++- WOKA/Home/Home.storyboard | 99 ++++++-- WOKA/Home/Model/FavouriteListingDM.swift | 13 +- WOKA/Home/View/FavouriteCell.swift | 33 ++- WOKA/Home/View/FavouriteCell.xib | 53 ++-- WOKA/Home/ViewModel/MyListVM.swift | 152 ++++++++++- .../en.lproj/Localizable.strings | 11 + .../hi.lproj/Localizable.strings | 11 + WOKA/Network Adapter/APIEndPoints.swift | 8 + WOKA/Network Adapter/BaseResponseModel.swift | 2 +- .../SideMenu/SideMenuController.swift | 11 + WOKA/Theme/Base.lproj/Theme.storyboard | 133 ++++++++++ WOKA/Theme/CommonNwCall.swift | 2 +- WOKA/Theme/Controller/BlogDetailsVC.swift | 55 ++++ WOKA/Theme/Controller/MoreVC.swift | 14 +- WOKA/Theme/Controller/ThemeOneVC.swift | 16 ++ WOKA/WOKA.entitlements | 11 + 27 files changed, 1098 insertions(+), 80 deletions(-) create mode 100644 WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/CloseIconEmpty.png create mode 100644 WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/CloseIconEmpty@2x.png create mode 100644 WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/CloseIconEmpty@3x.png create mode 100644 WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/Contents.json create mode 100644 WOKA/Helpers/HTML/HtmlText.swift create mode 100644 WOKA/Theme/Controller/BlogDetailsVC.swift create mode 100644 WOKA/WOKA.entitlements diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 47bd7ca..d0a1d24 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -57,12 +57,6 @@ 525954302BEA394400191286 /* CustomAlerts.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5259542F2BEA394300191286 /* CustomAlerts.storyboard */; }; 525954322BEA39D200191286 /* AddTapGesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954312BEA39D200191286 /* AddTapGesture.swift */; }; 525954342BEA620800191286 /* IntrestTopicDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954332BEA620800191286 /* IntrestTopicDM.swift */; }; - 525954352BEB4B3B00191286 /* Exo2-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8312BDBC3EF00E4CA14 /* Exo2-Thin.ttf */; }; - 525954362BEB4B3B00191286 /* Exo2-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82F2BDBC3EF00E4CA14 /* Exo2-Medium.ttf */; }; - 525954372BEB4B3B00191286 /* Exo2-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82E2BDBC3EF00E4CA14 /* Exo2-Bold.ttf */; }; - 525954382BEB4B3B00191286 /* Exo2-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8332BDBC3EF00E4CA14 /* Exo2-Regular.ttf */; }; - 525954392BEB4B3B00191286 /* Exo2-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8322BDBC3EF00E4CA14 /* Exo2-ExtraBold.ttf */; }; - 5259543A2BEB4B3B00191286 /* Exo2-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8302BDBC3EF00E4CA14 /* Exo2-SemiBold.ttf */; }; 525954512BEB5EB700191286 /* SkeletonView in Frameworks */ = {isa = PBXBuildFile; productRef = 525954502BEB5EB700191286 /* SkeletonView */; }; 5259545A2BEB67D200191286 /* DateFormatterLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525954592BEB67D200191286 /* DateFormatterLib.swift */; }; 5259545C2BEBB80400191286 /* AvatarDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5259545B2BEBB80400191286 /* AvatarDM.swift */; }; @@ -176,6 +170,26 @@ 9C7939152C0F23AA00F5D6E6 /* NsNotificationExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C7939142C0F23AA00F5D6E6 /* NsNotificationExtension.swift */; }; 9C7939172C0F23E900F5D6E6 /* LinkTypeEnum.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C7939162C0F23E900F5D6E6 /* LinkTypeEnum.swift */; }; 9C7939192C0F345000F5D6E6 /* ContactSupportVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C7939182C0F345000F5D6E6 /* ContactSupportVC.swift */; }; + 9C834EC62C1C1D9500B29A9C /* BlogDetailsVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C834EC52C1C1D9500B29A9C /* BlogDetailsVC.swift */; }; + 9C834EC72C1C1F9000B29A9C /* Exo2-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8302BDBC3EF00E4CA14 /* Exo2-SemiBold.ttf */; }; + 9C834EC82C1C1F9000B29A9C /* Exo2-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82F2BDBC3EF00E4CA14 /* Exo2-Medium.ttf */; }; + 9C834EC92C1C1F9000B29A9C /* Exo2-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82E2BDBC3EF00E4CA14 /* Exo2-Bold.ttf */; }; + 9C834ECA2C1C1F9000B29A9C /* Exo2-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8322BDBC3EF00E4CA14 /* Exo2-ExtraBold.ttf */; }; + 9C834ECB2C1C1F9000B29A9C /* Exo2-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8332BDBC3EF00E4CA14 /* Exo2-Regular.ttf */; }; + 9C834ECC2C1C1F9000B29A9C /* Exo2-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8312BDBC3EF00E4CA14 /* Exo2-Thin.ttf */; }; + 9C834ECD2C1C1F9000B29A9C /* Exo2-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8302BDBC3EF00E4CA14 /* Exo2-SemiBold.ttf */; }; + 9C834ECE2C1C1F9000B29A9C /* Exo2-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82F2BDBC3EF00E4CA14 /* Exo2-Medium.ttf */; }; + 9C834ECF2C1C1F9000B29A9C /* Exo2-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82E2BDBC3EF00E4CA14 /* Exo2-Bold.ttf */; }; + 9C834ED02C1C1F9000B29A9C /* Exo2-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8322BDBC3EF00E4CA14 /* Exo2-ExtraBold.ttf */; }; + 9C834ED12C1C1F9000B29A9C /* Exo2-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8332BDBC3EF00E4CA14 /* Exo2-Regular.ttf */; }; + 9C834ED22C1C1F9000B29A9C /* Exo2-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8312BDBC3EF00E4CA14 /* Exo2-Thin.ttf */; }; + 9C834ED32C1C1F9200B29A9C /* Exo2-SemiBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8302BDBC3EF00E4CA14 /* Exo2-SemiBold.ttf */; }; + 9C834ED42C1C1F9200B29A9C /* Exo2-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82F2BDBC3EF00E4CA14 /* Exo2-Medium.ttf */; }; + 9C834ED52C1C1F9200B29A9C /* Exo2-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E82E2BDBC3EF00E4CA14 /* Exo2-Bold.ttf */; }; + 9C834ED62C1C1F9200B29A9C /* Exo2-ExtraBold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8322BDBC3EF00E4CA14 /* Exo2-ExtraBold.ttf */; }; + 9C834ED72C1C1F9200B29A9C /* Exo2-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8332BDBC3EF00E4CA14 /* Exo2-Regular.ttf */; }; + 9C834ED82C1C1F9200B29A9C /* Exo2-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9C56E8312BDBC3EF00E4CA14 /* Exo2-Thin.ttf */; }; + 9C834EDC2C1C26CD00B29A9C /* HtmlText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C834EDB2C1C26CD00B29A9C /* HtmlText.swift */; }; 9C8C4FAE2C1315410017DD3B /* WebViewVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C8C4FAD2C1315410017DD3B /* WebViewVC.swift */; }; 9C8C4FB02C1328060017DD3B /* Disclaimer.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 9C8C4FAF2C1328060017DD3B /* Disclaimer.rtf */; }; 9C9BEEC72BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C9BEEC62BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift */; }; @@ -396,6 +410,9 @@ 9C7939142C0F23AA00F5D6E6 /* NsNotificationExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NsNotificationExtension.swift; sourceTree = ""; }; 9C7939162C0F23E900F5D6E6 /* LinkTypeEnum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkTypeEnum.swift; sourceTree = ""; }; 9C7939182C0F345000F5D6E6 /* ContactSupportVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactSupportVC.swift; sourceTree = ""; }; + 9C834EC52C1C1D9500B29A9C /* BlogDetailsVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlogDetailsVC.swift; sourceTree = ""; }; + 9C834ED92C1C20EC00B29A9C /* WOKA.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WOKA.entitlements; sourceTree = ""; }; + 9C834EDB2C1C26CD00B29A9C /* HtmlText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HtmlText.swift; sourceTree = ""; }; 9C8C4FAD2C1315410017DD3B /* WebViewVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewVC.swift; sourceTree = ""; }; 9C8C4FAF2C1328060017DD3B /* Disclaimer.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = Disclaimer.rtf; sourceTree = ""; }; 9C9BEEC62BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CollectionViewCenteredFlowLayout.swift; sourceTree = ""; }; @@ -567,6 +584,7 @@ 523ED25C2BDA2BC700CFED02 /* WOKA */ = { isa = PBXGroup; children = ( + 9C834ED92C1C20EC00B29A9C /* WOKA.entitlements */, 523ED26B2BDA2BC900CFED02 /* Info.plist */, 9C9BEEC62BEE1BBF004ECC2F /* CollectionViewCenteredFlowLayout.swift */, 5259541E2BE8E93500191286 /* Config.xcconfig */, @@ -824,6 +842,7 @@ 52C8B0512BDA4B51003B51D0 /* Helpers */ = { isa = PBXGroup; children = ( + 9C834EDA2C1C26C000B29A9C /* HTML */, 527AC6FF2C182D1700434FB7 /* Timer */, 9CBE1B3E2C0F37B200CA6E61 /* DropDown */, 9C535DB62C0089A700DA6DCD /* Animation */, @@ -990,6 +1009,7 @@ 52BC3BED2C16FBDB002FACA6 /* MoreVC.swift */, 522D655F2C1ACD8C0021E505 /* UserNotificationVC.swift */, 52CCD7AF2C1AF0F80078BD65 /* RadioVC.swift */, + 9C834EC52C1C1D9500B29A9C /* BlogDetailsVC.swift */, ); path = Controller; sourceTree = ""; @@ -1087,6 +1107,14 @@ path = ViewModel; sourceTree = ""; }; + 9C834EDA2C1C26C000B29A9C /* HTML */ = { + isa = PBXGroup; + children = ( + 9C834EDB2C1C26CD00B29A9C /* HtmlText.swift */, + ); + path = HTML; + sourceTree = ""; + }; 9CBCB2A62BE5104F007D7934 /* Home */ = { isa = PBXGroup; children = ( @@ -1275,22 +1303,22 @@ 527AC6FE2C173A5100434FB7 /* SongListCell.xib in Resources */, 523ED26A2BDA2BC900CFED02 /* Base in Resources */, 52C8B05B2BDA5924003B51D0 /* WokaSplashSound.m4a in Resources */, - 525954352BEB4B3B00191286 /* Exo2-Thin.ttf in Resources */, 527AC6F82C171C8F00434FB7 /* BlogsCell.xib in Resources */, 52A981D82C1B0E27000E0BEC /* FavouriteCell.xib in Resources */, 52C1A4E82C05C95D007BAA50 /* Theme.storyboard in Resources */, - 525954362BEB4B3B00191286 /* Exo2-Medium.ttf in Resources */, 522D65652C1ACE9C0021E505 /* UserNotificationCell.xib in Resources */, - 525954372BEB4B3B00191286 /* Exo2-Bold.ttf in Resources */, - 525954382BEB4B3B00191286 /* Exo2-Regular.ttf in Resources */, - 525954392BEB4B3B00191286 /* Exo2-ExtraBold.ttf in Resources */, - 5259543A2BEB4B3B00191286 /* Exo2-SemiBold.ttf in Resources */, 9C535DC52C00BF2400DA6DCD /* HomeExploreCell.xib in Resources */, 9CBE1B422C0F37B300CA6E61 /* DropDownCell.xib in Resources */, 52A3F6A92BECBF2A0000BB0B /* LinkedChildCell.xib in Resources */, 523ED2652BDA2BC700CFED02 /* Base in Resources */, 52BC3BE62C0E0326002FACA6 /* FaqCell.xib in Resources */, 52C6E01C2BE383C000E22D59 /* YourIntrestCell.xib in Resources */, + 9C834ED32C1C1F9200B29A9C /* Exo2-SemiBold.ttf in Resources */, + 9C834ED42C1C1F9200B29A9C /* Exo2-Medium.ttf in Resources */, + 9C834ED52C1C1F9200B29A9C /* Exo2-Bold.ttf in Resources */, + 9C834ED62C1C1F9200B29A9C /* Exo2-ExtraBold.ttf in Resources */, + 9C834ED72C1C1F9200B29A9C /* Exo2-Regular.ttf in Resources */, + 9C834ED82C1C1F9200B29A9C /* Exo2-Thin.ttf in Resources */, 52C6E0262BE3B46A00E22D59 /* SelectAvatarCell.xib in Resources */, 52C8B0712BDA7512003B51D0 /* PassingCloud.json in Resources */, 9C8C4FB02C1328060017DD3B /* Disclaimer.rtf in Resources */, @@ -1301,6 +1329,12 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9C834EC72C1C1F9000B29A9C /* Exo2-SemiBold.ttf in Resources */, + 9C834EC82C1C1F9000B29A9C /* Exo2-Medium.ttf in Resources */, + 9C834EC92C1C1F9000B29A9C /* Exo2-Bold.ttf in Resources */, + 9C834ECA2C1C1F9000B29A9C /* Exo2-ExtraBold.ttf in Resources */, + 9C834ECB2C1C1F9000B29A9C /* Exo2-Regular.ttf in Resources */, + 9C834ECC2C1C1F9000B29A9C /* Exo2-Thin.ttf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1308,6 +1342,12 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9C834ECD2C1C1F9000B29A9C /* Exo2-SemiBold.ttf in Resources */, + 9C834ECE2C1C1F9000B29A9C /* Exo2-Medium.ttf in Resources */, + 9C834ECF2C1C1F9000B29A9C /* Exo2-Bold.ttf in Resources */, + 9C834ED02C1C1F9000B29A9C /* Exo2-ExtraBold.ttf in Resources */, + 9C834ED12C1C1F9000B29A9C /* Exo2-Regular.ttf in Resources */, + 9C834ED22C1C1F9000B29A9C /* Exo2-Thin.ttf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1410,6 +1450,7 @@ 52C6E01B2BE383C000E22D59 /* YourIntrestCell.swift in Sources */, 525954142BE8C87300191286 /* ExtensionVCToastAlert.swift in Sources */, 52B8D4D92C04A25E00ED65F3 /* UIViewController+Container.swift in Sources */, + 9C834EDC2C1C26CD00B29A9C /* HtmlText.swift in Sources */, 527AC6F72C171C8F00434FB7 /* BlogsCell.swift in Sources */, 523ED25E2BDA2BC700CFED02 /* AppDelegate.swift in Sources */, 9C7939132C0EFCAE00F5D6E6 /* FaqVM.swift in Sources */, @@ -1421,6 +1462,7 @@ 9CBE1B402C0F37B300CA6E61 /* DPDKeyboardListener.swift in Sources */, 52A3F6AB2BECBF550000BB0B /* LinkedChildVC.swift in Sources */, 52FDBA7B2BFF2712009D7AC7 /* AuthFuncTimeHandling.swift in Sources */, + 9C834EC62C1C1D9500B29A9C /* BlogDetailsVC.swift in Sources */, 9CBCB2A52BE50D49007D7934 /* NewPasswordVC.swift in Sources */, 9CBCB29F2BE4E13A007D7934 /* ValidatorClass.swift in Sources */, 9CBCB29B2BE4D614007D7934 /* LoginVC.swift in Sources */, @@ -1730,6 +1772,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = WOKA/WOKA.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 4S9A74ZB6H; @@ -1768,6 +1811,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = WOKA/WOKA.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_TEAM = 4S9A74ZB6H; diff --git a/WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/CloseIconEmpty.png b/WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/CloseIconEmpty.png new file mode 100644 index 0000000000000000000000000000000000000000..d1506ecc1cec741346dd6552c82d5c78e685a517 GIT binary patch literal 1456 zcmV;h1yA~kP)Px)YDq*vR7gvumw9XyRUF4Zvoo{XE~o_yy(y@u0SvHKY`F{}KsBORP&tGIF>*Am zAwWpvh!HR`1&kn2{!kMX@PLBB#1=zHgmN^sU~CbC2c@MHtbhmG?i{=3&CWF2WqPE( zWYgxodB5-beSgRMK8enU44Bd7ls+;8o>j=4S z&=j;6V{CK;l3Z}bocM(y=~ zAcA>2OykEPYTtz>@r@^Ht7~BAAQ6?E1uB7E5%gA_3tJ58_e1mLE*Jt*2P(p(e7yiFO+&nTWs>{))42{!}UAuyn>+5ZHTbghLi7632amu zT5R&mt`HT=Y|q8I^^F58{t8OW1ZM5?kTgf*WWK@03L8PO>AH)uxDyB);%A6?g-7ze zJoQbOTl?Dhavsq`3mXv!*h&H)({{>aFVUzNXHb6{!B^BsJ4Ibn-GMz}(@@CHQ<-`y zLd)(p4lS|4O#y6ydI`)^$oo{|nB%Dc)q4ok*=Lpwg-54)nOvcBYJtu<5p&s&>%IN_ z%x*Bb@?nVbV%yVL(3ni`@+gAl_Bh&KTHrqNx5^AE4Dv+^-2Tg=T4l;+g{&p5ln;ca zHkZu~nrms;i=C}G`QuIG)y4=7rEPq>MuGu-{Y<~AQMbk5?AumO*vVlhUnG&4hfQu& zX`FZ`ZrwSMwa3f&H8QDVS~>8%vo|I=4KHI>D~wndvHOA?%7B(@aRqOA z;br1lm600^s#k?Ly*Uot0`-x%QsMCuo%3roPHu9s6M^J3KQkIaoSrB7$UiLMPj91a zOebB&0(T4>d>;!g95Q^2Td6R*BxcQxc55z?In^e&FH3$FUeUQ!rgL(+o#9pu#*GeM z8Jt@cqEdK{3utVpV$FzoQ)SZo3WEzIKd+fOKNsqpDD5PE9pWf}WCA57)kR`KCTF|p z9s<|Ht4v(1GIXcpXHg`?@tG#Sm30FgZAM_I~_fvJGrfTO8^gu%P;N0iXcZatV<$+DVrqglK3bS z(45QKrIGaZl8_)hA(8wWCXKr^j;^w=yQKU4ymZ~9{(}$|EB@!T7_U;CYjK;*phZDG z%YwgewF?22(eqWt?$J0l&EVou7x3O_0!Ii;^D?>I;PfjRHG3T)5bb=H-kP!7!+_T{ zj*hjZkJVp$DSgCVT}U4<`IRP@OKs6-VY!IC7x#MTH%FuL8H2j=nEO;v*bA{YQHZ_$ zZ5){ECiaB=c6k#OeGe@)xwI`r&01*r$3B1)8aLWwm>JO5N8l})2Umo-=7_uwvMBx~ z5i98DD+G3kYe471W`p`Y-3$7ZAqs$Um- literal 0 HcmV?d00001 diff --git a/WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/CloseIconEmpty@2x.png b/WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/CloseIconEmpty@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..91411176371ab1f16cfcaff309226ae16364bd11 GIT binary patch literal 3724 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 literal 0 HcmV?d00001 diff --git a/WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/Contents.json b/WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/Contents.json new file mode 100644 index 0000000..81787a4 --- /dev/null +++ b/WOKA/Assets/Assets.xcassets/Menu/CloseIconEmpty.imageset/Contents.json @@ -0,0 +1,26 @@ +{ + "images" : [ + { + "filename" : "CloseIconEmpty.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "CloseIconEmpty@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "CloseIconEmpty@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/WOKA/Authentication/Controller/LoginVC.swift b/WOKA/Authentication/Controller/LoginVC.swift index 19c3ea3..99e04d2 100644 --- a/WOKA/Authentication/Controller/LoginVC.swift +++ b/WOKA/Authentication/Controller/LoginVC.swift @@ -25,8 +25,8 @@ class LoginVC: UIViewController { vm.vc = self vm.initView() - self.userNameTF.text = "rizwan" - self.passwordTF.text = "Rizwan@123" + self.userNameTF.text = "child1" + self.passwordTF.text = "Admin@123" } @IBAction func loginBtnTapped(_ sender: LocalisedElementsButton) { diff --git a/WOKA/Constants K/GVar.swift b/WOKA/Constants K/GVar.swift index 4885e88..52dbf76 100644 --- a/WOKA/Constants K/GVar.swift +++ b/WOKA/Constants K/GVar.swift @@ -11,6 +11,7 @@ extension K{ struct GVar{ // static var localized = K.LocalizedEnum.english + static var reloadMyList = false } } diff --git a/WOKA/Constants K/StoryBoardID.swift b/WOKA/Constants K/StoryBoardID.swift index c0f8139..e3409a4 100644 --- a/WOKA/Constants K/StoryBoardID.swift +++ b/WOKA/Constants K/StoryBoardID.swift @@ -44,6 +44,7 @@ extension K{ static let themeTwoVC = "ThemeTwoVC" static let moreVC = "MoreVC" static let radioVC = "RadioVC" + static let blogDetailsVC = "BlogDetailsVC" } struct SideBarNav{ diff --git a/WOKA/Helpers/HTML/HtmlText.swift b/WOKA/Helpers/HTML/HtmlText.swift new file mode 100644 index 0000000..4802e60 --- /dev/null +++ b/WOKA/Helpers/HTML/HtmlText.swift @@ -0,0 +1,218 @@ +// +// HtmlText.swift +// WOKA +// +// Created by Bilal on 14/06/2024. +// + +import Foundation + +import UIKit + +//MARK : - html Data to Swift Readable +extension String { + var htmlToAttributedString: NSAttributedString? { + guard let data = data(using: .utf8) else { return nil } + do { + return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil) + } catch { + return nil + } + } + var htmlToString: String { + return htmlToAttributedString?.string ?? "" + } +} +//MARK : - changing attributed text size without losing html attributes +extension NSMutableAttributedString { + func setFontFace(font: UIFont, color: UIColor? = nil) { + beginEditing() + self.enumerateAttribute(.font,in: NSRange(location: 0, length: self.length)) { (value, range, stop) in + if let f = value as? UIFont, + let newFontDescriptor = f.fontDescriptor.withFamily(font.familyName).withSymbolicTraits(f.fontDescriptor.symbolicTraits) { + let newFont = UIFont(descriptor: newFontDescriptor,size: font.pointSize) + removeAttribute(.font, range: range) + addAttribute(.font, value: newFont, range: range) + if let color = color { + removeAttribute(.foregroundColor,range: range) + addAttribute(.foregroundColor,value: color, range: range) + } + } + } + endEditing() + } +} + +class AttibutedStringSize { + static let shareInstance = AttibutedStringSize() +// func generateAttributedString(targetString: NSAttributedString, selectedNsRange : [NSRange]) -> NSAttributedString? { +// let attributedString = NSMutableAttributedString(attributedString: targetString) +// for range in selectedNsRange{ +// attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: range) +// } +// return attributedString +// } +// +// func changeFontSize(targetString: NSAttributedString,fontSize : CGFloat) -> NSAttributedString? { +// let attributedString = NSMutableAttributedString(attributedString: targetString) +// attributedString.addAttribute(NSAttributedString.Key.font, value: UIFont.boldSystemFont(ofSize: fontSize), range: NSRange(location: 0, length: targetString.string.utf16.count)) +// return attributedString +// } + + func changeDarkOrLightMode(targetString: NSAttributedString,color : UIColor ,selectedNsRange : [NSRange]) -> NSAttributedString? { + let attributedString = NSMutableAttributedString(attributedString: targetString) + attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: NSRange(location: 0, length: targetString.string.utf16.count)) + for range in selectedNsRange{ + attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: range) + } + return attributedString + } + + func generateFullyAttributedString(targetString: NSAttributedString, selectedNsRange : [NSRange],selectedLinkNsRange : [NSRange],linkURL:String ,textColor : UIColor , fontSize : CGFloat) -> NSAttributedString?{ + let attributedString = NSMutableAttributedString(attributedString: targetString) + let range = NSRange(location: 0, length: targetString.string.utf16.count) + //MARK : - color + attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: textColor, range: range) + + //MARK : - for selected range with link and underline + for range1 in selectedLinkNsRange{ + attributedString.addAttribute(.link, value: linkURL, range:range1) + attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range1) + attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.blue, range: range1) + } + //MARK : - for highlight the text saved RED Color + for range2 in selectedNsRange{ + attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: range2) + } + //MARK : - for font family and size + attributedString.setFontFace(font: UIFont.systemFont(ofSize: fontSize)) + return attributedString + } + + func attributedStringSearch(with searchTerm: String, targetString: NSAttributedString) -> NSAttributedString? { + let attributedString = NSMutableAttributedString(attributedString: targetString) + do { + let regex = try NSRegularExpression(pattern: NSRegularExpression.escapedPattern(for: searchTerm).trimmingCharacters(in: .whitespacesAndNewlines).folding(options: .regularExpression, locale: .current), options: .caseInsensitive) + let range = NSRange(location: 0, length: targetString.string.utf16.count) + attributedString.addAttribute(NSAttributedString.Key.backgroundColor, value: UIColor.clear, range: range) + for match in regex.matches(in: targetString.string.folding(options: .regularExpression, locale: .current), options: .withTransparentBounds, range: range) { + attributedString.addAttribute(NSAttributedString.Key.backgroundColor, value: UIColor.green, range: match.range) + } + return attributedString + } catch { + NSLog("Error creating regular expresion: \(error)") + return nil + } + } + +// func generateAttributedStringSearch(with searchTerm: String, targetString: NSAttributedString) -> NSAttributedString? { +// let attributedString = NSMutableAttributedString(attributedString: targetString) +// do { +// let regex = try NSRegularExpression(pattern: NSRegularExpression.escapedPattern(for: searchTerm).trimmingCharacters(in: .whitespacesAndNewlines).folding(options: .regularExpression, locale: .current), options: .caseInsensitive) +// let range = NSRange(location: 0, length: targetString.string.utf16.count) +// attributedString.addAttribute(NSAttributedString.Key.backgroundColor, value: UIColor.clear, range: range) +// for match in regex.matches(in: targetString.string.folding(options: .regularExpression, locale: .current), options: .withTransparentBounds, range: range) { +// attributedString.addAttribute(NSAttributedString.Key.backgroundColor, value: UIColor.green, range: match.range) +// } +// return attributedString +// } catch { +// NSLog("Error creating regular expresion: \(error)") +// return nil +// } +// } + +// func generateAttributedStringColor(targetString: NSAttributedString, color : UIColor) -> NSAttributedString? { +// let attributedString = NSMutableAttributedString(attributedString: targetString) +// let range = NSRange(location: 0, length: targetString.string.utf16.count) +// attributedString.addAttribute(NSAttributedString.Key.backgroundColor, value: color, range: range) +// return attributedString +// } + +// func generateAttributedStringDarkLight(targetString: NSAttributedString, selectedNsRange : [NSRange], color : UIColor,fontSize : CGFloat) -> NSAttributedString? { +// let attributedString = NSMutableAttributedString(attributedString: targetString) +// let fullRange = NSRange(location: 0, length: targetString.string.utf16.count) +// attributedString.addAttribute(NSAttributedString.Key.font, value: UIFont(name: "Arial", size: fontSize)!, range: fullRange) +// attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: fullRange) +// for range in selectedNsRange{ +// attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: range) +// } +// return attributedString +// } + +// func generateLink(targetString: NSAttributedString ,selectedNsRange : [NSRange], linkURL:String) -> NSAttributedString? { +// let attributedString = NSMutableAttributedString(attributedString: targetString) +// for range in selectedNsRange{ +// attributedString.addAttribute(.link, value: linkURL, range:range) +// attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range) +// attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.blue, range: range) +// } +// return attributedString +// } + + //MARK : - for highlight and hyperlink +// func fullyAttributed(targetString: NSAttributedString ,selectedHighlightRange : [NSRange],selectedLinkRange : [NSRange] ,linkURL:String) -> NSAttributedString? { +// let attributedString = NSMutableAttributedString(attributedString: targetString) +// for range in selectedHighlightRange{ +// attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.red, range: range) +// } +// for range in selectedLinkRange{ +// attributedString.addAttribute(.link, value: linkURL, range:range) +// attributedString.addAttribute(NSAttributedString.Key.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range) +// attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.blue, range: range) +// } +// +// return attributedString +// } + //MARK : - searchControl + +} +//MARK : - attStr To Html + + +//extension String { +// func attributedStringWithColor(_ strings: [String], color: UIColor, characterSpacing: UInt? = nil) -> NSAttributedString { +// let attributedString = NSMutableAttributedString(string: self) +// for string in strings { +// let range = (self as NSString).range(of: string) +// attributedString.addAttribute(NSAttributedString.Key.foregroundColor, value: color, range: range) +// } +// +// guard let characterSpacing = characterSpacing else {return attributedString} +// +// attributedString.addAttribute(NSAttributedString.Key.kern, value: characterSpacing, range: NSRange(location: 0, length: attributedString.length)) +// +// return attributedString +// } +//} +// +//extension String { +// public var convertHtmlToNSAttributedString: NSAttributedString? { +// guard let data = data(using: .utf8) else { +// return nil +// } +// do { +// return try NSAttributedString(data: data,options: [.documentType: NSAttributedString.DocumentType.html,.characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) +// } +// catch { +// print(error.localizedDescription) +// return nil +// } +// } +// +// public func convertHtmlToAttributedStringWithCSS(font: UIFont? , csscolor: String , lineheight: Int, csstextalign: String) -> NSAttributedString? { +// guard let font = font else { +// return convertHtmlToNSAttributedString +// } +// let modifiedString = "\(self)"; +// guard let data = modifiedString.data(using: .utf8) else { +// return nil +// } +// do { +// return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil) +// } +// catch { +// print(error) +// return nil +// } +// } +//} diff --git a/WOKA/Helpers/NsNotificationExtension.swift b/WOKA/Helpers/NsNotificationExtension.swift index cf1173e..1ad9d4c 100644 --- a/WOKA/Helpers/NsNotificationExtension.swift +++ b/WOKA/Helpers/NsNotificationExtension.swift @@ -10,4 +10,5 @@ import Foundation extension Notification.Name { static let languageDidChange = Notification.Name("languageDidChange") static let linkPush = Notification.Name("linkPush") + static let enableDisableSideBar = Notification.Name("enableDisableSideBar") } diff --git a/WOKA/Home/Controller/MyListVC.swift b/WOKA/Home/Controller/MyListVC.swift index 7eee5fb..b2bf10d 100644 --- a/WOKA/Home/Controller/MyListVC.swift +++ b/WOKA/Home/Controller/MyListVC.swift @@ -24,17 +24,48 @@ class MyListVC: UIViewController { @IBOutlet weak var gamesCV: UICollectionView! @IBOutlet weak var gamesStack: UIStackView! + @IBOutlet weak var noDataStack: UIStackView! + + @IBOutlet weak var scrollView: UIScrollView! + var vm = MyListVM() override func viewDidLoad() { super.viewDidLoad() vm.vc = self vm.initView() + + vm.refreshControl.attributedTitle = NSAttributedString(string: "Refreshing...",attributes: [.foregroundColor: UIColor.appColor(.TextDarkBlue)!]) + vm.refreshControl.tintColor = UIColor.appColor(.TextDarkBlue)! + vm.refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged) + scrollView.addSubview(vm.refreshControl) + } + + @objc func refresh(_ sender: AnyObject) { + Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { [unowned self] _ in + vm.getFavouriteListing() + } + } + + override func viewWillAppear(_ animated: Bool) { + + } + + override func viewWillDisappear(_ animated: Bool) { + + } + + override func viewDidAppear(_ animated: Bool) { + if K.GVar.reloadMyList{ + K.GVar.reloadMyList = false + vm.getFavouriteListing() + } } @IBAction func sideBarBtnTapped(_ sender: UIButton) { self.sideMenuController?.revealMenu() } + @IBAction func backBtntapped(_ sender: UIButton) { self.tabBarController?.selectedIndex = 0 } @@ -48,35 +79,35 @@ extension MyListVC : CollectionViewSRC{ func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { switch collectionView{ case webSeriesCV: - if vm.favListingData?.showData?.count == 0{ + if vm.favListingData?.showData?.count == 0 || vm.favListingData == nil{ webSeriesEnglishStack.isHidden = true }else{ webSeriesEnglishStack.isHidden = false } return vm.favListingData?.showData?.count ?? 0 case audioBooksCV: - if vm.favListingData?.audioData?.count == 0{ + if vm.favListingData?.audioData?.count == 0 || vm.favListingData == nil{ audioBooksStack.isHidden = true }else{ audioBooksStack.isHidden = false } return vm.favListingData?.audioData?.count ?? 0 case karaokeCV: - if vm.favListingData?.singKaraokeData?.count == 0{ + if vm.favListingData?.singKaraokeData?.count == 0 || vm.favListingData == nil{ karaokeStack.isHidden = true }else{ karaokeStack.isHidden = false } return vm.favListingData?.singKaraokeData?.count ?? 0 case gamesCV: - if vm.favListingData?.gameData?.count == 0{ + if vm.favListingData?.gameData?.count == 0 || vm.favListingData == nil{ gamesStack.isHidden = true }else{ gamesStack.isHidden = false } return vm.favListingData?.gameData?.count ?? 0 case webSeriesHindiCV: - if vm.webSeriesHindi.count == 0{ + if vm.webSeriesHindi.count == 0 || vm.favListingData == nil{ webSeriesHindiStack.isHidden = true }else{ webSeriesHindiStack.isHidden = false @@ -115,8 +146,202 @@ extension MyListVC : CollectionViewSRC{ cell.setData(data: data) } } + + cell.btnTapped = { [self] (type) -> Void in + updateFavLikes(cv: collectionView, type: type, index: indexPath.row) + } + return cell } + + func updateFavLikes(cv : UICollectionView , type : FavCellCLick, index : Int){ + switch cv{ + case webSeriesCV: + guard let data = vm.favListingData?.showData?[index] else{return} + switch type { + case .favourite: + guard let isFav = data.markAsFavourite ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType,let categoryID = data.bookmarkCategoryIDS else{return} + if isFav{ + vm.removeFavourite(postID: postID, postType: postType, categoryID: categoryID, index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.showData?.remove(at: index) + webSeriesCV.reloadData() + } + } + } + case .liked: + guard let isLiked = data.isLiked ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType else{return} + if isLiked{ + vm.unlikePost(postID: postID, postType: postType, index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.showData?[index].isLiked = false + vm.favListingData?.showData?[index].likesCount! -= 1 + webSeriesCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + } + } + }else{ + vm.likePost(postID: postID, postType: postType, index: index){ [unowned self] isDone in + if isDone{ + vm.favListingData?.showData?[index].isLiked = true + vm.favListingData?.showData?[index].likesCount! += 1 + webSeriesCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + } + } + } + } + case webSeriesHindiCV: + let data = vm.webSeriesHindi[index] + switch type { + case .favourite: + guard let isFav = data.markAsFavourite ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType,let categoryID = data.bookmarkCategoryIDS else{return} + if isFav{ + vm.removeFavourite(postID: postID, postType: postType, categoryID: categoryID, index: index) { [unowned self] isDone in + if isDone{ + vm.webSeriesHindi.remove(at: index) + webSeriesHindiCV.reloadData() + vm.checkNil() + } + } + } + case .liked: + guard let isLiked = data.isLiked ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType,let categoryID = data.bookmarkCategoryIDS else{return} + if isLiked{ + vm.unlikePost(postID: postID, postType: postType, index: index) { [unowned self] isDone in + if isDone{ + vm.webSeriesHindi[index].isLiked = false + vm.webSeriesHindi[index].likesCount! -= 1 + webSeriesHindiCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + }else{ + vm.likePost(postID: postID, postType: postType, index: index){ [unowned self] isDone in + if isDone{ + vm.webSeriesHindi[index].isLiked = true + vm.webSeriesHindi[index].likesCount! += 1 + webSeriesHindiCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + } + } + case audioBooksCV: + guard let data = vm.favListingData?.audioData?[index] else{return} + switch type { + case .favourite: + guard let isFav = data.markAsFavourite ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType else{return} + if isFav{ + vm.removeFavourite(postID: postID, postType: postType, categoryID: "", index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.audioData?.remove(at: index) + audioBooksCV.reloadData() + vm.checkNil() + } + } + } + case .liked: + guard let isLiked = data.isLiked ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType else{return} + if isLiked{ + vm.unlikePost(postID: postID, postType: postType, index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.audioData?[index].isLiked = false + vm.favListingData?.audioData?[index].likesCount! -= 1 + audioBooksCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + }else{ + vm.likePost(postID: postID, postType: postType, index: index){ [unowned self] isDone in + if isDone{ + vm.favListingData?.audioData?[index].isLiked = true + vm.favListingData?.audioData?[index].likesCount! += 1 + audioBooksCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + } + } + case karaokeCV: + guard let data = vm.favListingData?.singKaraokeData?[index] else{return} + + switch type { + case .favourite: + guard let isFav = data.markAsFavourite ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType else{return} + if isFav{ + vm.removeFavourite(postID: postID, postType: postType, categoryID: "", index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.singKaraokeData?.remove(at: index) + karaokeCV.reloadData() + vm.checkNil() + } + } + } + case .liked: + guard let isLiked = data.isLiked ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType else{return} + if isLiked{ + vm.unlikePost(postID: postID, postType: postType, index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.singKaraokeData?[index].isLiked = false + vm.favListingData?.singKaraokeData?[index].likesCount! -= 1 + karaokeCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + }else{ + vm.likePost(postID: postID, postType: postType, index: index){ [unowned self] isDone in + if isDone{ + vm.favListingData?.singKaraokeData?[index].isLiked = true + vm.favListingData?.singKaraokeData?[index].likesCount! += 1 + karaokeCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + } + } + case gamesCV: + guard let data = vm.favListingData?.gameData?[index] else{return} + + switch type { + case .favourite: + guard let isFav = data.markAsFavourite ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType else{return} + if isFav{ + vm.removeFavourite(postID: postID, postType: postType, categoryID: "", index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.gameData?.remove(at: index) + gamesCV.reloadData() + vm.checkNil() + } + } + } + case .liked: + guard let isLiked = data.isLiked ,let postID = data.id,let postType = data.contentMoreDetails?.first?.postType else{return} + if isLiked{ + vm.unlikePost(postID: postID, postType: postType, index: index) { [unowned self] isDone in + if isDone{ + vm.favListingData?.gameData?[index].isLiked = false + vm.favListingData?.gameData?[index].likesCount! -= 1 + gamesCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + }else{ + vm.likePost(postID: postID, postType: postType, index: index){ [unowned self] isDone in + if isDone{ + vm.favListingData?.gameData?[index].isLiked = true + vm.favListingData?.gameData?[index].likesCount! += 1 + gamesCV.reloadItems(at: [IndexPath(row: index, section: 0)]) + vm.checkNil() + } + } + } + } + default: + break + } + + } + + } diff --git a/WOKA/Home/Home.storyboard b/WOKA/Home/Home.storyboard index 58ba88a..af7cdaa 100644 --- a/WOKA/Home/Home.storyboard +++ b/WOKA/Home/Home.storyboard @@ -899,6 +899,20 @@ + @@ -908,12 +922,18 @@ - + + + + + @@ -933,12 +953,18 @@ - + + + + + @@ -958,12 +984,18 @@ - + + + + + @@ -983,12 +1015,18 @@ - + + + + + @@ -1008,12 +1046,18 @@ - + + + + + @@ -1065,9 +1109,11 @@ + + @@ -1080,6 +1126,8 @@ + + @@ -1153,6 +1201,7 @@ + diff --git a/WOKA/Home/Model/FavouriteListingDM.swift b/WOKA/Home/Model/FavouriteListingDM.swift index 3f21922..d1f03f8 100644 --- a/WOKA/Home/Model/FavouriteListingDM.swift +++ b/WOKA/Home/Model/FavouriteListingDM.swift @@ -14,8 +14,8 @@ struct FavouriteListingDM: Codable { // MARK: - Result struct ResultData: Codable { var showData: [ShowDatum]? - let videoData: [Datum]? - let gameData, audioData, singKaraokeData: [Datum]? + var videoData: [Datum]? + var gameData, audioData, singKaraokeData: [Datum]? enum CodingKeys: String, CodingKey { case showData = "show_data" @@ -35,8 +35,8 @@ struct FavouriteListingDM: Codable { let languageMasterID: Int? let genderMasterID, audioDuration, mediaID: String? let contentMoreDetails: [ContentMoreDetail]? - let markAsFavourite, isLiked: Bool? - let viewsCount, likesCount, bookmarkCount: Int? + var markAsFavourite, isLiked: Bool? + var viewsCount, likesCount, bookmarkCount: Int? let bookmarkCategoryIDS: String? let gameURL: String? let screenOrientation: String? @@ -95,8 +95,9 @@ struct FavouriteListingDM: Codable { let totalSeasons, totalEpisodes: Int? let categoryMasterID, ageRangeMasterID, genderMasterID: String? let contentMoreDetails: [ContentMoreDetail]? - let markAsFavourite, isLiked: Bool? - let viewsCount, likesCount, bookmarkCount: Int? + var markAsFavourite, isLiked: Bool? + var likesCount : Int? + let viewsCount, bookmarkCount: Int? let bookmarkCategoryIDS: String? enum CodingKeys: String, CodingKey { diff --git a/WOKA/Home/View/FavouriteCell.swift b/WOKA/Home/View/FavouriteCell.swift index fea4489..f5fb803 100644 --- a/WOKA/Home/View/FavouriteCell.swift +++ b/WOKA/Home/View/FavouriteCell.swift @@ -7,6 +7,11 @@ import UIKit +enum FavCellCLick{ + case favourite + case liked +} + class FavouriteCell: UICollectionViewCell { @IBOutlet weak var cellImage: UIImageView! @@ -15,15 +20,35 @@ class FavouriteCell: UICollectionViewCell { @IBOutlet weak var favBtnn: UIButton! @IBOutlet weak var totalLikes: UILabel! + typealias btnTappedBlock = ( _ from : FavCellCLick) -> Void // 0 - plus 1 - minus + var btnTapped : btnTappedBlock! + override func awakeFromNib() { super.awakeFromNib() // Initialization code } + @IBAction func favouriteBtnTapped(_ sender: UIButton) { + if btnTapped != nil { + btnTapped( .favourite) + } + } + + @IBAction func likeBtnTapped(_ sender: UIButton) { + if btnTapped != nil { + btnTapped( .liked) + } + } + func setData(data : FavouriteListingDM.ResultData.ShowDatum){ //heart.fill , heart , hand.thumbsup.fill , hand.thumbsup - cellTitle.text = data.title + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ + cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first?.title + }else{ + cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first?.title + } totalLikes.text = data.likesCount?.toString() ?? "0" + if let url = data.thumbnailPath{ cellImage.imageURL(url) } @@ -50,7 +75,11 @@ class FavouriteCell: UICollectionViewCell { func setOtherData(data : FavouriteListingDM.ResultData.Datum){ //heart.fill , heart , hand.thumbsup.fill , hand.thumbsup - cellTitle.text = data.title + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ + cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first?.title + }else{ + cellTitle.text = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first?.title + } totalLikes.text = data.likesCount?.toString() ?? "0" if let url = data.thumbnailPath{ cellImage.imageURL(url) diff --git a/WOKA/Home/View/FavouriteCell.xib b/WOKA/Home/View/FavouriteCell.xib index 4484b70..2ff7247 100644 --- a/WOKA/Home/View/FavouriteCell.xib +++ b/WOKA/Home/View/FavouriteCell.xib @@ -6,6 +6,7 @@ + @@ -38,57 +39,70 @@ - - + + - + - + + + + + + + + + - - + - + @@ -130,5 +144,8 @@ + + + diff --git a/WOKA/Home/ViewModel/MyListVM.swift b/WOKA/Home/ViewModel/MyListVM.swift index e3a3f5e..49810fb 100644 --- a/WOKA/Home/ViewModel/MyListVM.swift +++ b/WOKA/Home/ViewModel/MyListVM.swift @@ -14,9 +14,18 @@ class MyListVM{ var webSeriesHindi = [FavouriteListingDM.ResultData.ShowDatum]() + let refreshControl = UIRefreshControl() + let feedbackGenerator = UIImpactFeedbackGenerator(style: .light) + func initView(){ setupCell() + Utilities.startProgressHUD() getFavouriteListing() + NotificationCenter.default.addObserver(self, selector: #selector(languageChanged), name: .languageDidChange, object: nil) + } + + @objc func languageChanged(){ + self.reloadCollections() } func setupCell(){ @@ -44,7 +53,7 @@ class MyListVM{ // MARK: - Get Favourite Listing func getFavouriteListing(){ - Utilities.startProgressHUD() + let headers : HTTPHeaders = ["Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi", "access-token": AuthFunc.shareInstance.getAccessToken()] NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.favourite_listing, method: .post, headers: headers) { [weak self](result : Result, NetworkManager.APIError>) in @@ -53,11 +62,18 @@ class MyListVM{ guard let self else{return} switch data.success{ case 0: + self.refreshControl.endRefreshing() Utilities.dismissProgressHUD() self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + reloadCollections() + checkNil() case 1: + self.refreshControl.endRefreshing() Utilities.dismissProgressHUD() guard let data = data.data?.result else{return} + favListingData = nil + webSeriesHindi.removeAll() + favListingData = data if var hindiData = favListingData?.showData{ @@ -73,20 +89,142 @@ class MyListVM{ // Updating the showData with the filtered list favListingData?.showData = hindiData } - - vc.webSeriesCV.reloadData() - vc.webSeriesHindiCV.reloadData() - vc.audioBooksCV.reloadData() - vc.karaokeCV.reloadData() - vc.gamesCV.reloadData() + reloadCollections() + feedbackGenerator.impactOccurred() + checkNil() default: break } case .failure(let error): guard let self else{return} + self.refreshControl.endRefreshing() Utilities.dismissProgressHUD() + checkNil() self.vc.toast(msg: error.localizedDescription , time: 2) } } } + + // MARK: - Like , unlike + + func likePost(postID : Int, postType : Int, index : Int , onCompletion : @escaping (Bool) -> Void){ + Utilities.startProgressHUD() + let headers : HTTPHeaders = ["Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi", + "access-token": AuthFunc.shareInstance.getAccessToken()] + + let params : Parameters = ["post_id" : postID, + "post_type" : postType] + + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.post_like, method: .post, parameters: params, headers: headers) { [weak self](result : Result) in + switch result{ + case .success(let data): + guard let self else{return} + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + onCompletion(false) + case 1: + Utilities.dismissProgressHUD() + onCompletion(true) + default: + Utilities.dismissProgressHUD() + onCompletion(false) + } + case .failure(let error): + guard let self else{return} + Utilities.dismissProgressHUD() + self.vc.toast(msg: error.localizedDescription , time: 2) + onCompletion(false) + } + } + } + + func unlikePost(postID : Int, postType : Int , index : Int, onCompletion : @escaping (Bool) -> Void){ + Utilities.startProgressHUD() + let headers : HTTPHeaders = ["Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi", + "access-token": AuthFunc.shareInstance.getAccessToken()] + + let params : Parameters = ["post_id" : postID, + "post_type" : postType] + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.post_unlike, method: .post, parameters: params, headers: headers) { [weak self](result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + guard let self else{return} + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + onCompletion(false) + case 1: + Utilities.dismissProgressHUD() + onCompletion(true) + default: + Utilities.dismissProgressHUD() + onCompletion(false) + } + case .failure(let error): + guard let self else{return} + Utilities.dismissProgressHUD() + self.vc.toast(msg: error.localizedDescription , time: 2) + onCompletion(false) + } + } + } + + + // MARK: - Remove Favourite + + func removeFavourite(postID : Int, postType : Int, categoryID : String, index : Int , onCompletion : @escaping (Bool) -> Void){ + Utilities.startProgressHUD() + let headers : HTTPHeaders = ["Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi", + "access-token": AuthFunc.shareInstance.getAccessToken()] + + let params : Parameters = ["id" : postID, + "post_type" : postType, + "category_id" : categoryID] + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.favourite_remove, method: .post, parameters: params, headers: headers) { [weak self](result : Result) in + switch result{ + case .success(let data): + guard let self else{return} + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + onCompletion(false) + case 1: + Utilities.dismissProgressHUD() + onCompletion(true) + default: + Utilities.dismissProgressHUD() + onCompletion(false) + } + case .failure(let error): + guard let self else{return} + Utilities.dismissProgressHUD() + self.vc.toast(msg: error.localizedDescription , time: 2) + onCompletion(false) + } + } + } + + func checkNil(){ + guard let data = favListingData else{ + self.vc.noDataStack.isHidden = false + return + } + if data.showData?.count == 0 && data.singKaraokeData?.count == 0 && data.gameData?.count == 0 && data.audioData?.count == 0 && webSeriesHindi.count == 0{ + self.vc.noDataStack.isHidden = false + }else{ + self.vc.noDataStack.isHidden = true + } + } + + func reloadCollections(){ + vc.webSeriesCV.reloadData() + vc.webSeriesHindiCV.reloadData() + vc.audioBooksCV.reloadData() + vc.karaokeCV.reloadData() + vc.gamesCV.reloadData() + } } diff --git a/WOKA/Localized Module/en.lproj/Localizable.strings b/WOKA/Localized Module/en.lproj/Localizable.strings index 3cad313..636c00f 100644 --- a/WOKA/Localized Module/en.lproj/Localizable.strings +++ b/WOKA/Localized Module/en.lproj/Localizable.strings @@ -41,3 +41,14 @@ "कराओके" = "KARAOKE"; "दुकान" = "SHOP"; "वोका का अन्वेषण करें" = "Explore WOKA"; + + +/* + My List + */ + +"वेबसीरीज (अंग्रेजी)" = "WebSeries (English)"; +"वेबसीरीज (हिंदी)" = "WebSeries (Hindi)"; +"ऑडियो पुस्तकें" = "Audio Books"; +"कराओके" = "Karaoke"; +"खेल" = "Games"; diff --git a/WOKA/Localized Module/hi.lproj/Localizable.strings b/WOKA/Localized Module/hi.lproj/Localizable.strings index 89a8376..41e2a50 100644 --- a/WOKA/Localized Module/hi.lproj/Localizable.strings +++ b/WOKA/Localized Module/hi.lproj/Localizable.strings @@ -204,3 +204,14 @@ "KARAOKE" = "कराओके"; "SHOP" = "दुकान"; "Explore WOKA" = "वोका का अन्वेषण करें"; + + +/* + My List + */ +"WebSeries (English)" = "वेबसीरीज (अंग्रेजी)"; +"WebSeries (Hindi)" = "वेबसीरीज (हिंदी)"; +"Audio Books" = "ऑडियो पुस्तकें"; +"Karaoke" = "कराओके"; +"Games" = "खेल"; + diff --git a/WOKA/Network Adapter/APIEndPoints.swift b/WOKA/Network Adapter/APIEndPoints.swift index 3258ae4..4b406b3 100644 --- a/WOKA/Network Adapter/APIEndPoints.swift +++ b/WOKA/Network Adapter/APIEndPoints.swift @@ -69,6 +69,14 @@ struct APIEndPoints { static let song_listing = makeURL(path: "song_listing") static let get_user_notifications = makeURL(path: "get_user_notifications") static let favourite_listing = makeURL(path: "favourite_listing") + + //Post Like Unlike + static let post_like = makeURL(path: "post_like") + static let post_unlike = makeURL(path: "post_unlike") + + // Favourite + static let favourite_remove = makeURL(path: "favourite_remove") + static let favourite_add = makeURL(path: "favourite_add") } // Other endpoint categories... diff --git a/WOKA/Network Adapter/BaseResponseModel.swift b/WOKA/Network Adapter/BaseResponseModel.swift index 5f7567f..5c68046 100644 --- a/WOKA/Network Adapter/BaseResponseModel.swift +++ b/WOKA/Network Adapter/BaseResponseModel.swift @@ -25,7 +25,7 @@ class BaseResponseModel : Codable, ResponseProtocol{ } -struct CommonResponseModel : Codable { +struct CommonResponseModel : Codable ,ResponseProtocol{ let success: Int? let message: String? diff --git a/WOKA/TabBar & SideMenu/SideMenu/SideMenuController.swift b/WOKA/TabBar & SideMenu/SideMenu/SideMenuController.swift index 1b7fe50..f6a21e0 100644 --- a/WOKA/TabBar & SideMenu/SideMenu/SideMenuController.swift +++ b/WOKA/TabBar & SideMenu/SideMenu/SideMenuController.swift @@ -202,7 +202,17 @@ open class SideMenuController: UIViewController { setUpNotifications() let generator = UINotificationFeedbackGenerator() generator.notificationOccurred(.error) + + NotificationCenter.default.addObserver(self, selector: #selector(enableDisableSideBar), name: .enableDisableSideBar, object: nil) + } + + @objc func enableDisableSideBar(_ notification: NSNotification){ + if let isEnabled = notification.userInfo?["type"] as? Bool { + panGestureRecognizer?.isEnabled = isEnabled + } + } + private func resolveDirection(with view: UIView) { if shouldReverseDirection { @@ -343,6 +353,7 @@ open class SideMenuController: UIViewController { // MARK: Gesture Recognizer private func configureGesturesRecognizer() { + // The gesture will be added anyway, its delegate will tell whether it should be recognized let panGesture = UIPanGestureRecognizer(target: self, action: #selector(SideMenuController.handlePanGesture(_:))) panGesture.delegate = self diff --git a/WOKA/Theme/Base.lproj/Theme.storyboard b/WOKA/Theme/Base.lproj/Theme.storyboard index 97790dd..5615bb5 100644 --- a/WOKA/Theme/Base.lproj/Theme.storyboard +++ b/WOKA/Theme/Base.lproj/Theme.storyboard @@ -5,6 +5,7 @@ + @@ -830,12 +831,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -855,9 +982,15 @@ + + + + + + diff --git a/WOKA/Theme/CommonNwCall.swift b/WOKA/Theme/CommonNwCall.swift index a05488b..e0628fd 100644 --- a/WOKA/Theme/CommonNwCall.swift +++ b/WOKA/Theme/CommonNwCall.swift @@ -17,7 +17,7 @@ class CommonNwCall{ if isRefreshing == false || isRefreshing == nil{ Utilities.startProgressHUD() } - let headers : HTTPHeaders = ["access-token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3dva2FsYW5kLmNvbS9hZG1pbi9hcGkvbG9naW4iLCJpYXQiOjE3MTgxODgwNTMsImV4cCI6MTc0OTcyNDA1MywibmJmIjoxNzE4MTg4MDUzLCJqdGkiOiJaNHIyVTlPYUxZanlDZm1TIiwic3ViIjoiMjE2IiwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.09oMvLmPaSzSqI7tQTs0VblGeRxDYYdh4Bt-2z1RTKg"] + let headers : HTTPHeaders = ["access-token" : AuthFunc.shareInstance.getAccessToken()] NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Home.get_user_notifications, method: .get,headers : headers) {(result : Result, NetworkManager.APIError>) in switch result{ case .success(let data): diff --git a/WOKA/Theme/Controller/BlogDetailsVC.swift b/WOKA/Theme/Controller/BlogDetailsVC.swift new file mode 100644 index 0000000..4eb0ee3 --- /dev/null +++ b/WOKA/Theme/Controller/BlogDetailsVC.swift @@ -0,0 +1,55 @@ +// +// BlogDetailsVC.swift +// WOKA +// +// Created by Bilal on 14/06/2024. +// + +import UIKit + +class BlogDetailsVC: UIViewController { + + @IBOutlet weak var blogImage: UIImageView! + @IBOutlet weak var blogTitle: UILabel! + @IBOutlet weak var blogDescription: UITextView! + + var blogData : BlogDM.Blog? + + override func viewDidLoad() { + super.viewDidLoad() + updateUI() + } + + @IBAction func clostBtnTapped(_ sender: UIButton) { + self.dismiss(animated: true) + } + + func updateUI(){ + blogImage.roundCorner(radius: 10) + guard let data = blogData else{return} + if let url = data.thumbnailPath{ + self.blogImage.imageURL(url) + } + + if AuthFunc.shareInstance.getDefaultLanguage() == .english{ // 1 enlgish , 2 hindi + guard let languageData = data.contentMoreDetails?.filter({$0.languageMasterID == 1}).first else{return} + self.blogTitle.text = languageData.title + + if let desc = languageData.article?.htmlToAttributedString{ + let sizeText = NSMutableAttributedString(attributedString: desc) + sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Medium, size: 16)) + self.blogDescription.attributedText = sizeText + } + + }else{ + guard let languageData = data.contentMoreDetails?.filter({$0.languageMasterID == 2}).first else{return} + self.blogTitle.text = languageData.title + if let desc = languageData.article?.htmlToAttributedString{ + let sizeText = NSMutableAttributedString(attributedString: desc) + sizeText.setFontFace(font: FontCustom.shareInstance.customFont(fontName: .Exo2_Medium, size: 16)) + self.blogDescription.attributedText = sizeText + } + } + + } +} diff --git a/WOKA/Theme/Controller/MoreVC.swift b/WOKA/Theme/Controller/MoreVC.swift index ec15098..7de2164 100644 --- a/WOKA/Theme/Controller/MoreVC.swift +++ b/WOKA/Theme/Controller/MoreVC.swift @@ -24,7 +24,13 @@ class MoreVC: UIViewController { vm.initView() } + override func viewWillAppear(_ animated: Bool) { + NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": false]) + } + override func viewWillDisappear(_ animated: Bool) { + NotificationCenter.default.post(name: .enableDisableSideBar, object: nil, userInfo: ["type": true]) + vm.player?.pause() } } @@ -203,7 +209,13 @@ extension MoreVC : CollectionViewSRC{ } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - print(indexPath.row) + let data = vm.blogData[indexPath.row] + let sb = UIStoryboard(name: K.StoryBoard.theme, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Theme.blogDetailsVC) as! BlogDetailsVC + vcPush.blogData = data + vcPush.modalPresentationStyle = .overCurrentContext + vcPush.modalTransitionStyle = .crossDissolve + self.present(vcPush, animated: true) } } diff --git a/WOKA/Theme/Controller/ThemeOneVC.swift b/WOKA/Theme/Controller/ThemeOneVC.swift index c726a1f..7fe03e6 100644 --- a/WOKA/Theme/Controller/ThemeOneVC.swift +++ b/WOKA/Theme/Controller/ThemeOneVC.swift @@ -99,3 +99,19 @@ class NavigationController: UINavigationController { return self.topViewController } } + + +extension UINavigationController { + func pushWithPopInAnimation(_ viewController: UIViewController, duration: CFTimeInterval = 0.3) { + let transition = CATransition() + transition.duration = duration + transition.type = CATransitionType.push + transition.subtype = CATransitionSubtype.fromRight + + // Customize the animation to look like a "pop-in" + transition.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) + + self.view.layer.add(transition, forKey: kCATransition) + self.pushViewController(viewController, animated: false) + } +} diff --git a/WOKA/WOKA.entitlements b/WOKA/WOKA.entitlements new file mode 100644 index 0000000..8b1b443 --- /dev/null +++ b/WOKA/WOKA.entitlements @@ -0,0 +1,11 @@ + + + + + com.apple.developer.user-fonts + + app-usage + system-installation + + +