diff --git a/WOKA.xcodeproj/project.pbxproj b/WOKA.xcodeproj/project.pbxproj index 192b8e6..f0c5884 100644 --- a/WOKA.xcodeproj/project.pbxproj +++ b/WOKA.xcodeproj/project.pbxproj @@ -12,6 +12,12 @@ 5202AB012BDFA7900043B7BD /* EmailValidation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5202AB002BDFA7900043B7BD /* EmailValidation.swift */; }; 520346962C64E29A00D0BD20 /* MyListViewAllCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 520346952C64E29A00D0BD20 /* MyListViewAllCell.xib */; }; 520346972C64E29A00D0BD20 /* MyListViewAllCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520346942C64E29A00D0BD20 /* MyListViewAllCell.swift */; }; + 520B15092C74652D00C14E5E /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 520B15072C74652D00C14E5E /* WOKA.xcdatamodeld */; }; + 520B150B2C746A2700C14E5E /* UsernameCheckVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520B150A2C746A2700C14E5E /* UsernameCheckVC.swift */; }; + 520B150D2C746AFF00C14E5E /* UserNameDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520B150C2C746AFF00C14E5E /* UserNameDM.swift */; }; + 520CE6AD2C7483CE00974228 /* PopViewControllerGeneric.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520CE6AC2C7483CE00974228 /* PopViewControllerGeneric.swift */; }; + 520CE6AF2C74999200974228 /* AppUpdateDM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520CE6AE2C74999200974228 /* AppUpdateDM.swift */; }; + 520CE6B12C74BB9D00974228 /* AppUpdateVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 520CE6B02C74BB9D00974228 /* AppUpdateVC.swift */; }; 5219C2C22C086D9C00A1DF4D /* DataTypeConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5219C2C12C086D9B00A1DF4D /* DataTypeConversion.swift */; }; 521CB1002C493DB80085BDF8 /* JWPlayerKit in Frameworks */ = {isa = PBXBuildFile; productRef = 521CB0FF2C493DB80085BDF8 /* JWPlayerKit */; }; 522242662BFC74380085C632 /* MyListVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 522242632BFC74380085C632 /* MyListVC.swift */; }; @@ -337,7 +343,6 @@ 9CBE1B432C0F37B300CA6E61 /* DropDown.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBE1B382C0F37B200CA6E61 /* DropDown.swift */; }; 9CBE1B442C0F37B300CA6E61 /* DropDown+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBE1B392C0F37B200CA6E61 /* DropDown+Appearance.swift */; }; 9CBE1B452C0F37B300CA6E61 /* DropDownCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CBE1B3A2C0F37B200CA6E61 /* DropDownCell.swift */; }; - 9CC0D2F82C6F339D0019DF73 /* WOKA.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 9CC0D2F62C6F339D0019DF73 /* WOKA.xcdatamodeld */; }; 9CC0D2FA2C6F33BE0019DF73 /* AuthFuncUserVideoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CC0D2F92C6F33BE0019DF73 /* AuthFuncUserVideoView.swift */; }; 9CC0D2FC2C6F5CAE0019DF73 /* PlayerVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CC0D2FB2C6F5CAE0019DF73 /* PlayerVM.swift */; }; 9CDAEB032C53B97B00890C47 /* VersionTexts.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CDAEB022C53B97B00890C47 /* VersionTexts.swift */; }; @@ -398,8 +403,14 @@ 5202AB002BDFA7900043B7BD /* EmailValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmailValidation.swift; sourceTree = ""; }; 520346942C64E29A00D0BD20 /* MyListViewAllCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MyListViewAllCell.swift; sourceTree = ""; }; 520346952C64E29A00D0BD20 /* MyListViewAllCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MyListViewAllCell.xib; sourceTree = ""; }; + 520B15082C74652D00C14E5E /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = ""; }; + 520B150A2C746A2700C14E5E /* UsernameCheckVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsernameCheckVC.swift; sourceTree = ""; }; + 520B150C2C746AFF00C14E5E /* UserNameDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserNameDM.swift; sourceTree = ""; }; 520B6E3E2C0751E90091C478 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Theme.strings; sourceTree = ""; }; 520B6E402C0751EF0091C478 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Theme.strings; sourceTree = ""; }; + 520CE6AC2C7483CE00974228 /* PopViewControllerGeneric.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PopViewControllerGeneric.swift; sourceTree = ""; }; + 520CE6AE2C74999200974228 /* AppUpdateDM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdateDM.swift; sourceTree = ""; }; + 520CE6B02C74BB9D00974228 /* AppUpdateVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppUpdateVC.swift; sourceTree = ""; }; 5219C2C12C086D9B00A1DF4D /* DataTypeConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataTypeConversion.swift; sourceTree = ""; }; 522242632BFC74380085C632 /* MyListVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MyListVC.swift; sourceTree = ""; }; 522242652BFC74380085C632 /* TabBarVC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TabBarVC.swift; sourceTree = ""; }; @@ -720,7 +731,6 @@ 9CBE1B392C0F37B200CA6E61 /* DropDown+Appearance.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DropDown+Appearance.swift"; sourceTree = ""; }; 9CBE1B3A2C0F37B200CA6E61 /* DropDownCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DropDownCell.swift; sourceTree = ""; }; 9CBE1B3C2C0F37B200CA6E61 /* DropDown.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DropDown.h; sourceTree = ""; }; - 9CC0D2F72C6F339D0019DF73 /* WOKA.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = WOKA.xcdatamodel; sourceTree = ""; }; 9CC0D2F92C6F33BE0019DF73 /* AuthFuncUserVideoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthFuncUserVideoView.swift; sourceTree = ""; }; 9CC0D2FB2C6F5CAE0019DF73 /* PlayerVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerVM.swift; sourceTree = ""; }; 9CDAEB022C53B97B00890C47 /* VersionTexts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VersionTexts.swift; sourceTree = ""; }; @@ -934,7 +944,7 @@ 9C535DC82C00C34000DA6DCD /* Theme */, 52DAC6462C21761700E2F85B /* WebSeries */, 9C834ED92C1C20EC00B29A9C /* WOKA.entitlements */, - 9CC0D2F62C6F339D0019DF73 /* WOKA.xcdatamodeld */, + 520B15072C74652D00C14E5E /* WOKA.xcdatamodeld */, 52ACC1292C610EC900791528 /* PersistentStorage.swift */, ); path = WOKA; @@ -975,6 +985,7 @@ 9C27E16A2BDB774D00EC1DA9 /* CarouselData.swift */, 529B0DD52C070C0F00CFC54B /* GuestDataDM.swift */, 9C23FB782C62164600F4DC5C /* URLStaticDM.swift */, + 520CE6AE2C74999200974228 /* AppUpdateDM.swift */, ); path = Model; sourceTree = ""; @@ -1480,6 +1491,7 @@ 9CB4C5A82C118EF300737C00 /* NavBarColor.swift */, 525861CF2C4F9E3200C33C79 /* SwipeTableViewFont.swift */, 9CDAEB022C53B97B00890C47 /* VersionTexts.swift */, + 520CE6AC2C7483CE00974228 /* PopViewControllerGeneric.swift */, ); path = Helpers; sourceTree = ""; @@ -1764,6 +1776,7 @@ 5259545B2BEBB80400191286 /* AvatarDM.swift */, 52A3F6A42BECBA8D0000BB0B /* LinkedChildDM.swift */, 9C0A853E2BEE35340093783D /* ForgotPassDM.swift */, + 520B150C2C746AFF00C14E5E /* UserNameDM.swift */, ); path = Model; sourceTree = ""; @@ -1810,6 +1823,8 @@ 9CBCB2A42BE50D49007D7934 /* NewPasswordVC.swift */, 52A3F6AA2BECBF550000BB0B /* LinkedChildVC.swift */, 529B0DD32C06156B00CFC54B /* LoginNavVC.swift */, + 520B150A2C746A2700C14E5E /* UsernameCheckVC.swift */, + 520CE6B02C74BB9D00974228 /* AppUpdateVC.swift */, ); path = Controller; sourceTree = ""; @@ -2251,6 +2266,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 520B15092C74652D00C14E5E /* WOKA.xcdatamodeld in Sources */, 9C535DC62C00BF2400DA6DCD /* HomeExploreCell.swift in Sources */, 52D774EF2BDFC50D001D87DE /* StringValidations.swift in Sources */, 52A6DCC52C4F8EA800F63C51 /* CartListVC.swift in Sources */, @@ -2315,12 +2331,12 @@ 5202AB012BDFA7900043B7BD /* EmailValidation.swift in Sources */, 52D6A24E2C22B3AB00145908 /* WebSeriesShowListDM.swift in Sources */, 52B8D4E12C04A25E00ED65F3 /* BasicTransitionAnimator.swift in Sources */, + 520CE6B12C74BB9D00974228 /* AppUpdateVC.swift in Sources */, 52AF71F02C36B29A00BC5972 /* GamesListDM.swift in Sources */, 52BC3BF02C1701F8002FACA6 /* BlogDM.swift in Sources */, 52A6DCA02C4E3AA600F63C51 /* ShopListingCell.swift in Sources */, 525954192BE8CC3400191286 /* ConstantString.swift in Sources */, 52D774EB2BDFC0BF001D87DE /* OTPVC.swift in Sources */, - 9CC0D2F82C6F339D0019DF73 /* WOKA.xcdatamodeld in Sources */, 9C8446872C40FC6E003E3E53 /* AVPlayerTesting.swift in Sources */, 52AF71F42C36C40B00BC5972 /* GamesWebViewVC.swift in Sources */, 9C007F202C255DF200F798C2 /* EpisodeListingDM.swift in Sources */, @@ -2469,6 +2485,7 @@ 9C27E1722BDB86B600EC1DA9 /* OnBoardCell.swift in Sources */, 525861D82C4FD38D00C33C79 /* CartPaymentOptionsCell.swift in Sources */, 529B0DD42C06156B00CFC54B /* LoginNavVC.swift in Sources */, + 520B150B2C746A2700C14E5E /* UsernameCheckVC.swift in Sources */, 9C23FB792C62164600F4DC5C /* URLStaticDM.swift in Sources */, 52A981D72C1B0E27000E0BEC /* FavouriteCell.swift in Sources */, 52BFB0652C5B5B4F0038D750 /* BlogsVC.swift in Sources */, @@ -2478,6 +2495,7 @@ 52663FF72BDFACF60001D8CE /* ShadowView.swift in Sources */, 522D65602C1ACD8D0021E505 /* UserNotificationVC.swift in Sources */, 52AC2D252C295A7900337473 /* TeaserDM.swift in Sources */, + 520B150D2C746AFF00C14E5E /* UserNameDM.swift in Sources */, 9C535DC22C00B36900DA6DCD /* ThemeTwoVC.swift in Sources */, 9CA7C6C22C1095B600D73742 /* ProfileVM.swift in Sources */, 9CB3D0912C37D6930062869D /* KaraokeDetailsVC.swift in Sources */, @@ -2486,6 +2504,7 @@ 9C9BE46E2C663B1600C48D6A /* JWKaraokePlayerVM.swift in Sources */, 9CBE1B3F2C0F37B300CA6E61 /* DPDConstants.swift in Sources */, 9CDAEB102C53F12800890C47 /* SwiftyInnerShadowLayer.swift in Sources */, + 520CE6AD2C7483CE00974228 /* PopViewControllerGeneric.swift in Sources */, 52A6DCA42C4E48AF00F63C51 /* ShopSuperCategoryDM.swift in Sources */, 52B8D4DA2C04A25E00ED65F3 /* Preferences.swift in Sources */, 52FB2D8F2BDF898F0009B0C7 /* TextFieldPadding.swift in Sources */, @@ -2505,6 +2524,7 @@ 527A2BCA2C57776A0080DF9B /* AddNewAddressVC.swift in Sources */, 9C56E8462BDBEE6400E4CA14 /* EmailVC.swift in Sources */, 52A6DCC92C4F906900F63C51 /* CartListingDM.swift in Sources */, + 520CE6AF2C74999200974228 /* AppUpdateDM.swift in Sources */, 522D65622C1ACDA40021E505 /* CommonNwCall.swift in Sources */, 52D6A2482C21A3A500145908 /* WebSeriesVM.swift in Sources */, 525327D92BFCDDF700F64283 /* AuthFuncStartupSoundHandling.swift in Sources */, @@ -3076,14 +3096,14 @@ /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ - 9CC0D2F62C6F339D0019DF73 /* WOKA.xcdatamodeld */ = { + 520B15072C74652D00C14E5E /* WOKA.xcdatamodeld */ = { isa = XCVersionGroup; children = ( - 9CC0D2F72C6F339D0019DF73 /* WOKA.xcdatamodel */, + 520B15082C74652D00C14E5E /* WOKA.xcdatamodel */, ); - currentVersion = 9CC0D2F72C6F339D0019DF73 /* WOKA.xcdatamodel */; + currentVersion = 520B15082C74652D00C14E5E /* WOKA.xcdatamodel */; name = WOKA.xcdatamodeld; - path = /Users/bilal/Desktop/woka_native_ios_swift/WOKA/WOKA.xcdatamodeld; + path = /Users/macbookpro/Desktop/WOKA/WOKA/WOKA.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; }; diff --git a/WOKA/Assets/Assets.xcassets/Authentication/AppUpdate.imageset/Contents.json b/WOKA/Assets/Assets.xcassets/Authentication/AppUpdate.imageset/Contents.json new file mode 100644 index 0000000..6a6c1a4 --- /dev/null +++ b/WOKA/Assets/Assets.xcassets/Authentication/AppUpdate.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Group 52572.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/WOKA/Assets/Assets.xcassets/Authentication/AppUpdate.imageset/Group 52572.png b/WOKA/Assets/Assets.xcassets/Authentication/AppUpdate.imageset/Group 52572.png new file mode 100644 index 0000000..a39dce6 Binary files /dev/null and b/WOKA/Assets/Assets.xcassets/Authentication/AppUpdate.imageset/Group 52572.png differ diff --git a/WOKA/Authentication/AuthenticationStringConstant.swift b/WOKA/Authentication/AuthenticationStringConstant.swift index 56dfafb..06c0f20 100644 --- a/WOKA/Authentication/AuthenticationStringConstant.swift +++ b/WOKA/Authentication/AuthenticationStringConstant.swift @@ -24,5 +24,8 @@ extension K{ static let enterChildName = "Enter your child name" static let enterPassword = "Enter your password" + + static let forgotUsername = "Forgot Username" + } } diff --git a/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard b/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard index 3f423aa..740d9a1 100644 --- a/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard +++ b/WOKA/Authentication/Base.lproj/AuthenticationSB.storyboard @@ -51,40 +51,75 @@ - + - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -141,6 +176,8 @@ + + @@ -833,14 +870,14 @@ Sent to Your Parent’s Email - + - + - + @@ -888,7 +925,7 @@ Sent to Your Parent’s Email - + @@ -926,21 +963,37 @@ Sent to Your Parent’s Email - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1463,6 +1732,9 @@ Sent to Your Parent’s Email + + + @@ -1477,10 +1749,14 @@ Sent to Your Parent’s Email + + + + diff --git a/WOKA/Authentication/Controller/AppUpdateVC.swift b/WOKA/Authentication/Controller/AppUpdateVC.swift new file mode 100644 index 0000000..50fa904 --- /dev/null +++ b/WOKA/Authentication/Controller/AppUpdateVC.swift @@ -0,0 +1,126 @@ +// +// AppUpdateVC.swift +// WOKA +// +// Created by MacBook Pro on 20/08/24. +// + +import UIKit +import Alamofire + +class AppUpdateVC: UIViewController { + + @IBOutlet weak var updateBtn: LocalisedElementsButton! + @IBOutlet weak var skipBtn: LocalisedElementsButton! + + var isForceUpdate = Bool() + var forceUpdateVer = String() + override func viewDidLoad() { + super.viewDidLoad() + handleViewUpdate() + } + + func handleViewUpdate(){ + let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) + let color2 = #colorLiteral(red: 0.6901960784, green: 0.2745098039, blue: 0.7568627451, alpha: 1) + updateBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) + updateBtn.roundCorner() + + skipBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) + skipBtn.roundCorner() + + if isForceUpdate{ + skipBtn.isHidden = true + }else{ + skipBtn.isHidden = false + } + } + + @IBAction func btnTapped(_ sender: LocalisedElementsButton) { + if sender == updateBtn{ + print("Update") + // take user to appstore + redirectToAppStore() + }else{ + //if user clicks skip update it to our user defaults + UserDefaults.standard.set(forceUpdateVer, forKey: K.UserDefaultsStruct.appUpdateSkipVer) +// getUserData() + if AuthFunc.shareInstance.checkLogin(){ + getUserData() + }else{ + //check if the static url data is fetched + UIApplication.setRootView(LoginNavVC.instantiate(from: .AuthenticationSB)) + } + } + } + + func redirectToAppStore() { + let appID = "6465305185" // Replace with your actual App Store ID + let appStoreURL = "https://apps.apple.com/app/id\(appID)" + + if let url = URL(string: appStoreURL), UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url, options: [:], completionHandler: { success in + if success { + print("Redirected to the App Store.") + } else { + print("Failed to open the App Store URL.") + } + }) + } else { + print("Invalid App Store URL.") + } + } + + func getUserData(){ + /* + If user is guest then dont do the nw call + */ + if AuthFunc.shareInstance.getUserType() == 3{ + //setusertype + AuthFunc.shareInstance.userData = UserDataDM.ResultData(id: nil, genderData: nil, birthdate: nil, email: nil, avtar: nil, avtarURL: nil, userType: "3", languageMasterID: nil, lastLogin: nil, rememberToken: nil, childDetail: nil, language: nil, alreadyLoggedIn: nil, isDeactive: nil) + UIApplication.setRootView(SideMenuController.instantiate(from: .Home)) + return + } + + +// if AuthFunc.shareInstance.getUserType() == 3{ +// UIApplication.setRootView(SideMenuController.instantiate(from: .Home)) +// return +// } + Utilities.startProgressHUD() + let headers : HTTPHeaders = ["Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi", + "access-token": AuthFunc.shareInstance.getAccessToken()] + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.get_user_data, method: .get, 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: + self.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + guard let data = data.data?.result else{ + Utilities.dismissProgressHUD() + return + } + AuthFunc.shareInstance.userData = data + Utilities.dismissProgressHUD() + //check if the static url data is fetched + if AuthFunc.shareInstance.staticURLs == nil{ + AuthFunc.shareInstance.getStaticURLs() + } + DispatchQueue.main.async { + UIApplication.setRootView(SideMenuController.instantiate(from: .Home)) + } + print("User Token --> ", AuthFunc.shareInstance.getAccessToken()) + default: + Utilities.dismissProgressHUD() + break + } + case .failure(let error): + Utilities.dismissProgressHUD() + guard let self else{return} + self.toast(msg: error.localizedDescription , time: 2) + } + } + } +} diff --git a/WOKA/Authentication/Controller/EmailVC.swift b/WOKA/Authentication/Controller/EmailVC.swift index 6e47999..a8c1983 100644 --- a/WOKA/Authentication/Controller/EmailVC.swift +++ b/WOKA/Authentication/Controller/EmailVC.swift @@ -12,6 +12,8 @@ class EmailVC: UIViewController { @IBOutlet weak var nextBtn: LocalisedElementsButton! @IBOutlet weak var enterEmailTF: UITextField! @IBOutlet weak var wokaLogoTopConstriant: NSLayoutConstraint! + @IBOutlet weak var userType: UITextField! + @IBOutlet weak var userTypeStack: UIStackView! @IBOutlet weak var beSafeLabel: UILabel! @IBOutlet weak var emailLabel: UILabel! @@ -44,11 +46,11 @@ class EmailVC: UIViewController { @IBAction func nextBtnTapped(_ sender: LocalisedElementsButton) { PersistentStorage.shared.addOthersCount() + /* If child registers dont call api to check email, directly hit sendotp and navigate to otp screen if parent registers check if the email exist or not and then hit sendotp */ - Utilities.startProgressHUD() DispatchQueue.main.async { [weak self] in guard let self else{return} //validate email fiirst @@ -60,10 +62,19 @@ class EmailVC: UIViewController { return } + if vm.forgetUsername != nil{ + if userType.text == ""{ + self.toast(msg: K.ConstantString.userType, time: 1.5) + } + Utilities.startProgressHUD() + vm.getUserName() + return + } + /* as per the user type */ - + Utilities.startProgressHUD() switch AuthFunc.shareInstance.userType{ //if parent verify the email case .adult: @@ -99,6 +110,8 @@ extension EmailVC : UITextFieldDelegate{ } return ValidatorClass.sharedInstanec.limitCharacter(length: 255,textField, shouldChangeCharactersIn: range, replacementString: string) + case userType: + return false default: return true } diff --git a/WOKA/Authentication/Controller/LoginVC.swift b/WOKA/Authentication/Controller/LoginVC.swift index 528d0d1..7d92387 100644 --- a/WOKA/Authentication/Controller/LoginVC.swift +++ b/WOKA/Authentication/Controller/LoginVC.swift @@ -83,6 +83,15 @@ class LoginVC: UIViewController { let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.resetPassUserNameVC) as! ResetPassUserNameVC self.navigationController?.pushViewController(vc, animated: true) } + + @IBAction func forgotUsername(_ sender: LocalisedElementsButton) { + vm.hideErrors() + PersistentStorage.shared.addOthersCount() + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.emailVC) as! EmailVC + vc.vm.forgetUsername = true + self.navigationController?.pushViewController(vc, animated: true) + } } diff --git a/WOKA/Authentication/Controller/UsernameCheckVC.swift b/WOKA/Authentication/Controller/UsernameCheckVC.swift new file mode 100644 index 0000000..aa5b5d6 --- /dev/null +++ b/WOKA/Authentication/Controller/UsernameCheckVC.swift @@ -0,0 +1,62 @@ +// +// UsernameCheckVC.swift +// WOKA +// +// Created by MacBook Pro on 20/08/24. +// + +import UIKit +import Alamofire + +class UsernameCheckVC: UIViewController { + + var userData = [UserNameDM]() + @IBOutlet weak var tableView: UITableView! + @IBOutlet weak var nextBtn: LocalisedElementsButton! + + override func viewDidLoad() { + super.viewDidLoad() + setupCell() + let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) + let color2 = #colorLiteral(red: 0.6901960784, green: 0.2745098039, blue: 0.7568627451, alpha: 1) + nextBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) + nextBtn.roundCorner() + self.title = "" + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + navigationController?.setNavigationBarHidden(false, animated: animated) + } + + func setupCell(){ + tableView.register(UINib(nibName: K.CellIdentifier.Authentication.linkedChildCell, bundle: nil), forCellReuseIdentifier: K.CellIdentifier.Authentication.linkedChildCell) + tableView.delegate = self + tableView.dataSource = self + } + + + @IBAction func goToLoginTapped(_ sender: LocalisedElementsButton) { + navigationController?.setNavigationBarHidden(true, animated: true) + self.navigationController?.popToViewController(of: LoginVC.self, animated: true) + } +} + +// MARK: - TableView + +extension UsernameCheckVC : TableViewSRC{ + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return userData.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: K.CellIdentifier.Authentication.linkedChildCell, for: indexPath) as! LinkedChildCell + cell.setLinkedData(data: userData[indexPath.row]) + return cell + } + + func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 100 + } +} diff --git a/WOKA/Authentication/Model/UserNameDM.swift b/WOKA/Authentication/Model/UserNameDM.swift new file mode 100644 index 0000000..28d3349 --- /dev/null +++ b/WOKA/Authentication/Model/UserNameDM.swift @@ -0,0 +1,13 @@ +// +// UserNameDM.swift +// WOKA +// +// Created by MacBook Pro on 20/08/24. +// + +import Foundation + +// MARK: - UserNameDM +struct UserNameDM: Codable { + let username: String? +} diff --git a/WOKA/Authentication/View/LinkedChildCell.swift b/WOKA/Authentication/View/LinkedChildCell.swift index 5ef78b7..081dc5c 100644 --- a/WOKA/Authentication/View/LinkedChildCell.swift +++ b/WOKA/Authentication/View/LinkedChildCell.swift @@ -33,4 +33,9 @@ class LinkedChildCell: UITableViewCell { } self.childName.text = data.username } + + func setLinkedData(data : UserNameDM){ + self.childName.text = data.username + self.childAvatarImage.image = UIImage(named: "DefaultAvatar") + } } diff --git a/WOKA/Authentication/ViewModel/EmailVM.swift b/WOKA/Authentication/ViewModel/EmailVM.swift index c805df0..c4307bc 100644 --- a/WOKA/Authentication/ViewModel/EmailVM.swift +++ b/WOKA/Authentication/ViewModel/EmailVM.swift @@ -12,12 +12,17 @@ class EmailVM{ weak var vc : EmailVC! + var forgetUsername : Bool? + let dropDownModule = DropDown() + var dataSource = [String]() + func initView(){ let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) let color2 = #colorLiteral(red: 0.6901960784, green: 0.2745098039, blue: 0.7568627451, alpha: 1) vc.nextBtn.applyGradient(colors: [color1, color2], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 0.8, y: 0)) vc.nextBtn.roundCorner() vc.enterEmailTF.roundCorner() + vc.userType.roundCorner() // Set up text field delegate vc.enterEmailTF.delegate = vc.self @@ -38,6 +43,42 @@ class EmailVM{ vc.beSafeLabel.text = K.AuthenticationStringConstant.safeBelow.localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) vc.emailLabel.text = K.AuthenticationStringConstant.emailBelow.localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) } + + + if forgetUsername != nil{ // if user is coming from forget username + vc.userTypeStack.isHidden = false + vc.beSafeLabel.text = K.AuthenticationStringConstant.forgotUsername.localized(loc: AuthFunc.shareInstance.languageSelected.rawValue) + vc.userType.delegate = self.vc + dataSource = ["I am above 16 years" , "I am below 16 years"] + vc.userType.addRightButton(title: "", tintColor: UIColor.appColor(.TextDarkBlue)!, btnImage: UIImage(named: "SupportBottomArrow"),rightPadding: 15, target: self, action: #selector(dropDownTapped)) + initDropDown() + } + } + + // this func will initialize the dropdown menu + func initDropDown(){ + dropDownModule.anchorView = vc.userType + dropDownModule.dataSource = dataSource + dropDownModule.cornerRadius = 10 + dropDownModule.bottomOffset = CGPoint(x: 0, y:(dropDownModule.anchorView?.plainView.bounds.height)!) + dropDownModule.topOffset = CGPoint(x: 0, y:-(dropDownModule.anchorView?.plainView.bounds.height)!) + dropDownModule.direction = .bottom + dropDownModule.textFont = FontCustom.shareInstance.customFont(fontName: .Exo2_Medium, size: 16) + dropDownModule.shadowColor = UIColor.appColor(.TextDarkBlue)! + dropDownModule.backgroundColor = .white + dropDownModule.shadowOffset = CGSize(width: 0, height: 1) + dropDownModule.separatorColor = UIColor.lightGray + dropDownModule.width = vc.userType.frame.width - 20 + dropDownModule.selectionBackgroundColor = UIColor.appColor(.TextDarkBlue)! + dropDownModule.selectedTextColor = UIColor.white + dropDownModule.selectionAction = { [weak self] (index: Int, item: String) in + self?.vc.userType.text = item + } + } + + @objc func dropDownTapped(){ + self.vc.enterEmailTF.resignFirstResponder() + self.dropDownModule.show() } // Function to handle tap on validation icon @@ -48,6 +89,39 @@ class EmailVM{ } } + // MARK: - After all checks do the api call + + func getUserName(){ + let params: Parameters = ["email": vc.enterEmailTF.text!, + "user_type": dropDownModule.indexForSelectedRow == 0 ? 2 : 1] + let header : HTTPHeaders = ["device-id" : AuthFunc.shareInstance.getDeviceUUID(), + "Accept-Language" : AuthFunc.shareInstance.languageSelected == .english ? "English" : "Hindi"] + + Utilities.startProgressHUD() + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.forgot_username, method: .post ,parameters: params, headers: header) {(result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + switch data.success{ + case 0: + Utilities.dismissProgressHUD() + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + Utilities.dismissProgressHUD() + guard let dataResult = data.data else{return} + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vc = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.usernameCheckVC) as! UsernameCheckVC + vc.userData = dataResult + self.vc.navigationController?.pushViewController(vc, animated: true) + default: + break + } + case .failure(let error): + Utilities.dismissProgressHUD() + self.vc.toast(msg: error.localizedDescription, time: 2) + } + } + } + func checkEmail(){ let params: Parameters = [ "email": vc.enterEmailTF.text!, diff --git a/WOKA/Constants K/ConstantString.swift b/WOKA/Constants K/ConstantString.swift index 52019a4..70a1bc3 100644 --- a/WOKA/Constants K/ConstantString.swift +++ b/WOKA/Constants K/ConstantString.swift @@ -30,6 +30,8 @@ extension K{ static let dob = "Please select DOB." static let registerUser = "Please wait registering user." + static let userType = "Please select user type." + static let error = "Error" static let rupeeSign = "₹" diff --git a/WOKA/Constants K/StoryBoardID.swift b/WOKA/Constants K/StoryBoardID.swift index 2e8b257..16d4ae3 100644 --- a/WOKA/Constants K/StoryBoardID.swift +++ b/WOKA/Constants K/StoryBoardID.swift @@ -27,6 +27,8 @@ extension K{ static let resetPassUserNameVC = "ResetPassUserNameVC" static let newPasswordVC = "NewPasswordVC" static let linkedChildVC = "LinkedChildVC" + static let usernameCheckVC = "UsernameCheckVC" + static let appUpdateVC = "AppUpdateVC" } struct Home{ diff --git a/WOKA/Constants K/UserDefaultsStruct.swift b/WOKA/Constants K/UserDefaultsStruct.swift index 6257f42..ca1a907 100644 --- a/WOKA/Constants K/UserDefaultsStruct.swift +++ b/WOKA/Constants K/UserDefaultsStruct.swift @@ -22,6 +22,8 @@ extension K{ static let userAccessToken = "userAccessToken" static let defaultLanguage = "defaultLanguage" static let userType = "userType" + + static let skippedVersion = "skippedVersion" } } diff --git a/WOKA/Helpers/PopViewControllerGeneric.swift b/WOKA/Helpers/PopViewControllerGeneric.swift new file mode 100644 index 0000000..508fddc --- /dev/null +++ b/WOKA/Helpers/PopViewControllerGeneric.swift @@ -0,0 +1,22 @@ +// +// PopViewControllerGeneric.swift +// WOKA +// +// Created by MacBook Pro on 20/08/24. +// + +import UIKit + +/* + this helps in navigation back or pop the viewcontroller as generic type + */ +extension UINavigationController { + func getViewController(of type: T.Type) -> UIViewController? { + return self.viewControllers.first(where: { $0 is T }) + } + + func popToViewController(of type: T.Type, animated: Bool) { + guard let viewController = self.getViewController(of: type) else { return } + self.popToViewController(viewController, animated: animated) + } +} diff --git a/WOKA/Helpers/UIElements Helper/TextFieldImage.swift b/WOKA/Helpers/UIElements Helper/TextFieldImage.swift index b4fd2e5..bfad22b 100644 --- a/WOKA/Helpers/UIElements Helper/TextFieldImage.swift +++ b/WOKA/Helpers/UIElements Helper/TextFieldImage.swift @@ -36,7 +36,7 @@ extension UITextField { extension UITextField { - func addRightButton(title: String?, tintColor : UIColor, btnImage : UIImage?, selectedImage : UIImage? = nil, target: Any?, action: Selector) { + func addRightButton(title: String?, tintColor : UIColor, btnImage : UIImage?, selectedImage : UIImage? = nil,rightPadding : CGFloat? = 10, target: Any?, action: Selector) { // Create a button let button = UIButton(type: .system) button.setTitle(title, for: .normal) @@ -46,7 +46,7 @@ extension UITextField { button.setImage(selectedImage, for: .selected) } button.tintColor = tintColor - button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 10) + button.contentEdgeInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: rightPadding ?? 10) // Set the button as the right view of the text field self.rightView = button self.rightViewMode = .always diff --git a/WOKA/Localized Module/hi.lproj/Localizable.strings b/WOKA/Localized Module/hi.lproj/Localizable.strings index 66f45dd..253cf01 100644 --- a/WOKA/Localized Module/hi.lproj/Localizable.strings +++ b/WOKA/Localized Module/hi.lproj/Localizable.strings @@ -20,7 +20,13 @@ "Login to WOKA" = "WOKA में लॉग इन करें"; "Enter your username" = "अपना उपयोगकर्ता नाम दर्ज करें"; "Enter your password" = "अपना उपयोगकर्ता नाम दर्ज करें"; -"Forgot Password" = "पासवर्ड भूल गए?"; +"Forgot Password?" = "पासवर्ड भूल गए?"; +"Forgot Username" = "उपयोगकर्ता नाम भूल गए"; +"Forgot Username?" = "उपयोगकर्ता नाम भूल गए?"; +"SELECT USER TYPE" = "उपयोगकर्ता प्रकार चुनें"; +"Username Found" = "उपयोगकर्ता नाम मिला"; +"Username linked to your account" = "आपके खाते से जुड़ा उपयोगकर्ता नाम"; +"Go to login?" = "लॉगिन पर जाएं?"; /* Forgot Password VC diff --git a/WOKA/Network Adapter/APIEndPoints.swift b/WOKA/Network Adapter/APIEndPoints.swift index bef2f9c..ed5de1a 100644 --- a/WOKA/Network Adapter/APIEndPoints.swift +++ b/WOKA/Network Adapter/APIEndPoints.swift @@ -61,6 +61,16 @@ struct APIEndPoints { UserData */ static let get_user_data = makeURL(path: "get_user_data") + + /* + Get username + */ + static let forgot_username = makeURL(path: "forgot_username") + + /* + + */ + static let version_history = makeURL(path: "version_history") } struct SideBarNav{ diff --git a/WOKA/OnBoarding Module/Controller/SplashVC.swift b/WOKA/OnBoarding Module/Controller/SplashVC.swift index 4031fb5..385ec55 100644 --- a/WOKA/OnBoarding Module/Controller/SplashVC.swift +++ b/WOKA/OnBoarding Module/Controller/SplashVC.swift @@ -79,29 +79,35 @@ class SplashVC: UIViewController { If user is loggined no need to shift the woka logo upside to new constant. Directly Navigate user to home */ - if AuthFunc.shareInstance.checkLogin(){ - vm.getUserData() - return - } else{ - //check if the static url data is fetched - if AuthFunc.shareInstance.staticURLs == nil{ - AuthFunc.shareInstance.getStaticURLs() - } +// vm.getVersionHistory() + animateForward() + } + } + + func animateForward(){ + if AuthFunc.shareInstance.checkLogin(){ + vm.getUserData() + return + }else{ + //check if the static url data is fetched + if AuthFunc.shareInstance.staticURLs == nil{ + AuthFunc.shareInstance.getStaticURLs() } - UIView.animate(withDuration: 0.5, animations: { - // Update the constant value of the top constraint - self.wokaOriginY.constant = newConstant - // Inform the layout system to update - self.view.layoutIfNeeded() - }) { _ in - if !AuthFunc.shareInstance.checkLogin(){ - UIView.animate(withDuration: 0.3, delay: 0,options : [.transitionCrossDissolve],animations: { - // Set the isHidden property of the view - self.languageBtnStack.isHidden = false - }) {_ in - // Inform the stack view to update its layout - self.languageBtnStack.layoutIfNeeded() - } + } + UIView.animate(withDuration: 0.5, animations: { [weak self] in + guard let self else{return} + // Update the constant value of the top constraint + self.wokaOriginY.constant = wokaOriginY.constant - 50 + // Inform the layout system to update + self.view.layoutIfNeeded() + }) { _ in + if !AuthFunc.shareInstance.checkLogin(){ + UIView.animate(withDuration: 0.3, delay: 0,options : [.transitionCrossDissolve],animations: { + // Set the isHidden property of the view + self.languageBtnStack.isHidden = false + }) {_ in + // Inform the stack view to update its layout + self.languageBtnStack.layoutIfNeeded() } } } diff --git a/WOKA/OnBoarding Module/Model/AppUpdateDM.swift b/WOKA/OnBoarding Module/Model/AppUpdateDM.swift new file mode 100644 index 0000000..36be709 --- /dev/null +++ b/WOKA/OnBoarding Module/Model/AppUpdateDM.swift @@ -0,0 +1,41 @@ +// +// AppUpdateDM.swift +// WOKA +// +// Created by MacBook Pro on 20/08/24. +// + +import Foundation + +// MARK: - AppUpdateDM +struct AppUpdateDM: Codable { + let the0: The0? + let msg: String? + let url: String? + + enum CodingKeys: String, CodingKey { + case the0 = "0" + case msg, url + } + + // MARK: - The0 + struct The0: Codable { + let id: Int? + let versionID, releaseDate: String? + let oldVersion: Int? + let newVersion, forceUpdateVersion: Double? + let forceUpdate: Int? + let releaseNotes: String? + + enum CodingKeys: String, CodingKey { + case id + case versionID = "version_id" + case releaseDate = "release_date" + case oldVersion = "old_version" + case newVersion = "new_version" + case forceUpdateVersion = "force_update_version" + case forceUpdate = "force_update" + case releaseNotes = "release_notes" + } + } +} diff --git a/WOKA/OnBoarding Module/ViewModel/SplashVM.swift b/WOKA/OnBoarding Module/ViewModel/SplashVM.swift index b6180dd..f72a70f 100644 --- a/WOKA/OnBoarding Module/ViewModel/SplashVM.swift +++ b/WOKA/OnBoarding Module/ViewModel/SplashVM.swift @@ -16,7 +16,9 @@ class SplashVM{ var player: AVAudioPlayer? func initView(){ - AuthFunc.shareInstance.getStaticURLs() + if AuthFunc.shareInstance.staticURLs == nil{ + AuthFunc.shareInstance.getStaticURLs() + } vc.activityIndicator.hidesWhenStopped = true let color1 = #colorLiteral(red: 0.144693464, green: 0.1426281333, blue: 0.6686832905, alpha: 1) let color2 = #colorLiteral(red: 0.4862745098, green: 0.1960784314, blue: 0.7019607843, alpha: 1) @@ -111,6 +113,72 @@ class SplashVM{ } } + func getVersionHistory(){ + let newVersion = "25.1.7" + let forceUpdateVersion = "25.1.7" + let forceUpdate = false + let currentAppVersion = Bundle.main.appVersionLong + + /* + If user is guest then dont do the nw call + */ + let params : Parameters = ["device" : "2"] //1-android , 2- iOS + NetworkManager.shareInstance.apiRequest(url: APIEndPoints.Auth.version_history, method: .get,parameters: params) { [weak self](result : Result, NetworkManager.APIError>) in + switch result{ + case .success(let data): + guard let self else{return} + switch data.success{ + case 0: + self.vc.toast(msg: data.message ?? "Unrecognised error" , time: 2) + case 1: + guard let data = data.data?.the0 else{return} + if newVersion.isVersion(greaterThan: currentAppVersion) { + // Case: New version is greater than the current version + print("New version is greater than current version.") + + /* + Check if user has skipped the force update version + */ + let skippedVer = UserDefaults.standard.string(forKey: K.UserDefaultsStruct.appUpdateSkipVer) + if skippedVer == forceUpdateVersion{ + // it means user has skipped this version. + vc.animateForward() + return + } + + // If ver is not skipped let user navigate to app update vc + if forceUpdate { + print("Force update required by the API.") + // nav user to force update screen + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.appUpdateVC) as! AppUpdateVC + vcPush.forceUpdateVer = forceUpdateVersion + self.vc.navigationController?.pushViewController(vcPush, animated: true) + } else { + print("Update available, but not mandatory.") + // Optional update let user skip + let sb = UIStoryboard(name: K.StoryBoard.authenticationSB, bundle: nil) + let vcPush = sb.instantiateViewController(withIdentifier: K.StoryBoardID.Authentication.appUpdateVC) as! AppUpdateVC + vcPush.forceUpdateVer = forceUpdateVersion + self.vc.navigationController?.pushViewController(vcPush, animated: true) + } + } else { + // Case: Current version is equal to the new version + print("Current version is up-to-date.") + vc.animateForward() + } + + print("data:- ", data.forceUpdateVersion) + default: + break + } + case .failure(let error): + guard let self else{return} + self.vc.toast(msg: error.localizedDescription , time: 2) + } + } + } + // handling activity indicator func startStopIndicator(start : Bool , hide : Bool = false){ @@ -131,3 +199,25 @@ class SplashVM{ } } } + + +extension String { + func isVersion(greaterThan version: String) -> Bool { + let versionComponents = self.split(separator: ".").compactMap { Int($0) } + let comparisonComponents = version.split(separator: ".").compactMap { Int($0) } + + for (index, component) in versionComponents.enumerated() { + if index < comparisonComponents.count { + if component > comparisonComponents[index] { + return true + } else if component < comparisonComponents[index] { + return false + } + } else { + return true + } + } + + return versionComponents.count > comparisonComponents.count + } +} diff --git a/WOKA/Theme/Base.lproj/Theme.storyboard b/WOKA/Theme/Base.lproj/Theme.storyboard index c323fda..73c3bc9 100644 --- a/WOKA/Theme/Base.lproj/Theme.storyboard +++ b/WOKA/Theme/Base.lproj/Theme.storyboard @@ -397,6 +397,7 @@ + @@ -464,6 +465,7 @@ + @@ -562,16 +564,16 @@ - + - + @@ -605,7 +607,7 @@ - + - + @@ -659,16 +661,16 @@ - + - + @@ -1331,7 +1333,7 @@ - +