diff --git a/Fableon.xcodeproj/project.pbxproj b/Fableon.xcodeproj/project.pbxproj index d2428a9..4a14494 100644 --- a/Fableon.xcodeproj/project.pbxproj +++ b/Fableon.xcodeproj/project.pbxproj @@ -209,7 +209,7 @@ 03E23AB42EAA1A7F004A8CEC /* FAPagerViewTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AA42EAA1A7F004A8CEC /* FAPagerViewTransformer.swift */; }; 03E23AB52EAA1A7F004A8CEC /* FAToast.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AA82EAA1A7F004A8CEC /* FAToast.swift */; }; 03E23AB62EAA1A7F004A8CEC /* FAUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AA02EAA1A7F004A8CEC /* FAUserInfo.swift */; }; - 03E23AB72EAA1A7F004A8CEC /* FALocalized.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23A9C2EAA1A7F004A8CEC /* FALocalized.swift */; }; + 03E23AB72EAA1A7F004A8CEC /* FALanguageManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23A9C2EAA1A7F004A8CEC /* FALanguageManager.swift */; }; 03E23AB82EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AAA2EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift */; }; 03E23ABA2EAA1D85004A8CEC /* MNNItemController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E23AB92EAA1D85004A8CEC /* MNNItemController.swift */; }; 03E9A7362EB44F26000D1067 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = 03E9A7352EB44F26000D1067 /* FirebaseMessaging */; }; @@ -217,6 +217,16 @@ 03E9A73A2EB45154000D1067 /* AppDelegate+FAApns.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7392EB45149000D1067 /* AppDelegate+FAApns.swift */; }; 03E9A73C2EB45507000D1067 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 03E9A73B2EB45507000D1067 /* GoogleService-Info.plist */; }; 03E9A73E2EB460F2000D1067 /* FAApnsAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A73D2EB460F2000D1067 /* FAApnsAlert.swift */; }; + 03E9A7402EB49BE6000D1067 /* FAUpdatesAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A73F2EB49BE6000D1067 /* FAUpdatesAlert.swift */; }; + 03E9A7422EB4A603000D1067 /* FAVersionUpdateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7412EB4A603000D1067 /* FAVersionUpdateModel.swift */; }; + 03E9A7442EB4B80B000D1067 /* FADetailRecommendView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7432EB4B80B000D1067 /* FADetailRecommendView.swift */; }; + 03E9A7462EB5ACE5000D1067 /* FADetailRecommendCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7452EB5ACE5000D1067 /* FADetailRecommendCell.swift */; }; + 03E9A7482EB5D2CB000D1067 /* FALogoutAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7472EB5D2CB000D1067 /* FALogoutAlert.swift */; }; + 03E9A74A2EB5DA7E000D1067 /* FALanguageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7492EB5DA7E000D1067 /* FALanguageViewController.swift */; }; + 03E9A74C2EB5DB92000D1067 /* FALanguageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A74B2EB5DB92000D1067 /* FALanguageCell.swift */; }; + 03E9A74E2EB5E0F7000D1067 /* FALanguageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A74D2EB5E0F7000D1067 /* FALanguageModel.swift */; }; + 03E9A7502EB5EAC0000D1067 /* FALanguageDataModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A74F2EB5EAC0000D1067 /* FALanguageDataModel.swift */; }; + 03E9A7522EB83A58000D1067 /* FAAppStartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03E9A7512EB83A58000D1067 /* FAAppStartViewController.swift */; }; B86XD3O90WO2R4725L084287 /* Pods_Fableon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */; }; F3019606DA7P36H41G408X13 /* ZStreamCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F38E33739F391364D0151P7Z /* ZStreamCell.swift */; }; F30470W590T8274E1642349G /* CControlCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32MR5F8X6Q3HSZ560BD0159 /* CControlCell.swift */; }; @@ -518,7 +528,7 @@ 03E23A972EAA1A7F004A8CEC /* FAEmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAEmpty.swift; sourceTree = ""; }; 03E23A992EAA1A7F004A8CEC /* FADeviceIDManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FADeviceIDManager.swift; sourceTree = ""; }; 03E23A9A2EAA1A7F004A8CEC /* FAKeychainHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAKeychainHelper.swift; sourceTree = ""; }; - 03E23A9C2EAA1A7F004A8CEC /* FALocalized.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALocalized.swift; sourceTree = ""; }; + 03E23A9C2EAA1A7F004A8CEC /* FALanguageManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALanguageManager.swift; sourceTree = ""; }; 03E23A9E2EAA1A7F004A8CEC /* FALogin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALogin.swift; sourceTree = ""; }; 03E23A9F2EAA1A7F004A8CEC /* FATokenModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FATokenModel.swift; sourceTree = ""; }; 03E23AA02EAA1A7F004A8CEC /* FAUserInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAUserInfo.swift; sourceTree = ""; }; @@ -532,6 +542,16 @@ 03E9A7392EB45149000D1067 /* AppDelegate+FAApns.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+FAApns.swift"; sourceTree = ""; }; 03E9A73B2EB45507000D1067 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 03E9A73D2EB460F2000D1067 /* FAApnsAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAApnsAlert.swift; sourceTree = ""; }; + 03E9A73F2EB49BE6000D1067 /* FAUpdatesAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAUpdatesAlert.swift; sourceTree = ""; }; + 03E9A7412EB4A603000D1067 /* FAVersionUpdateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAVersionUpdateModel.swift; sourceTree = ""; }; + 03E9A7432EB4B80B000D1067 /* FADetailRecommendView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FADetailRecommendView.swift; sourceTree = ""; }; + 03E9A7452EB5ACE5000D1067 /* FADetailRecommendCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FADetailRecommendCell.swift; sourceTree = ""; }; + 03E9A7472EB5D2CB000D1067 /* FALogoutAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALogoutAlert.swift; sourceTree = ""; }; + 03E9A7492EB5DA7E000D1067 /* FALanguageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALanguageViewController.swift; sourceTree = ""; }; + 03E9A74B2EB5DB92000D1067 /* FALanguageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALanguageCell.swift; sourceTree = ""; }; + 03E9A74D2EB5E0F7000D1067 /* FALanguageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALanguageModel.swift; sourceTree = ""; }; + 03E9A74F2EB5EAC0000D1067 /* FALanguageDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FALanguageDataModel.swift; sourceTree = ""; }; + 03E9A7512EB83A58000D1067 /* FAAppStartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAAppStartViewController.swift; sourceTree = ""; }; 19196I43BR665O55RD205171 /* Pods-Fableon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fableon.debug.xcconfig"; path = "Target Support Files/Pods-Fableon/Pods-Fableon.debug.xcconfig"; sourceTree = ""; }; C4THBP0A1283PFXW440071Q5 /* Pods_Fableon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fableon.framework; sourceTree = BUILT_PRODUCTS_DIR; }; DCD59738B6J31K33W4Z524S0 /* Pods-Fableon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fableon.release.xcconfig"; path = "Target Support Files/Pods-Fableon/Pods-Fableon.release.xcconfig"; sourceTree = ""; }; @@ -665,6 +685,8 @@ 031FDEEB2EB35DF600F4CAC7 /* FACoinsPackAlert.swift */, 031FDEED2EB3682000F4CAC7 /* FAVipRetainAlert.swift */, 03E9A73D2EB460F2000D1067 /* FAApnsAlert.swift */, + 03E9A73F2EB49BE6000D1067 /* FAUpdatesAlert.swift */, + 03E9A7472EB5D2CB000D1067 /* FALogoutAlert.swift */, ); path = Alert; sourceTree = ""; @@ -750,6 +772,7 @@ 03E239672EAA1A29004A8CEC /* FANavigationController.swift */, 03E239682EAA1A29004A8CEC /* FATabBarController.swift */, 03E239692EAA1A29004A8CEC /* FAViewController.swift */, + 03E9A7512EB83A58000D1067 /* FAAppStartViewController.swift */, ); path = Controller; sourceTree = ""; @@ -955,6 +978,7 @@ 03E239EA2EAA1A4E004A8CEC /* FAMeViewController.swift */, 03E239EB2EAA1A4E004A8CEC /* FASettingViewController.swift */, 031FDEC12EB1E19D00F4CAC7 /* FACoinPackViewController.swift */, + 03E9A7492EB5DA7E000D1067 /* FALanguageViewController.swift */, ); path = C; sourceTree = ""; @@ -963,6 +987,7 @@ isa = PBXGroup; children = ( 03E239ED2EAA1A4E004A8CEC /* FAMeItemModel.swift */, + 03E9A7412EB4A603000D1067 /* FAVersionUpdateModel.swift */, ); path = M; sourceTree = ""; @@ -988,6 +1013,7 @@ 031FDED72EB30D6E00F4CAC7 /* FASettingCell.swift */, 031FDED82EB30D6E00F4CAC7 /* FASettingCell.xib */, 031FDEDB2EB3141E00F4CAC7 /* FASettingFooterView.swift */, + 03E9A74B2EB5DB92000D1067 /* FALanguageCell.swift */, ); path = V; sourceTree = ""; @@ -1063,6 +1089,8 @@ 03E23A102EAA1A4E004A8CEC /* FAVideoLockView.swift */, 031FDEBB2EB0C97A00F4CAC7 /* FAOldVideoRechargeView.swift */, 031FDEBD2EB0C99900F4CAC7 /* FANewVideoRechargeView.swift */, + 03E9A7432EB4B80B000D1067 /* FADetailRecommendView.swift */, + 03E9A7452EB5ACE5000D1067 /* FADetailRecommendCell.swift */, ); path = V; sourceTree = ""; @@ -1220,7 +1248,9 @@ 03E23A9D2EAA1A7F004A8CEC /* FALocalized */ = { isa = PBXGroup; children = ( - 03E23A9C2EAA1A7F004A8CEC /* FALocalized.swift */, + 03E23A9C2EAA1A7F004A8CEC /* FALanguageManager.swift */, + 03E9A74D2EB5E0F7000D1067 /* FALanguageModel.swift */, + 03E9A74F2EB5EAC0000D1067 /* FALanguageDataModel.swift */, ); path = FALocalized; sourceTree = ""; @@ -1945,6 +1975,7 @@ F3019606DA7P36H41G408X13 /* ZStreamCell.swift in Sources */, F392T441X031FH7N0HA03SZ7 /* WPSectionView.swift in Sources */, F3D05387002315ZAQC97D7BT /* JHYHeader.swift in Sources */, + 03E9A7422EB4A603000D1067 /* FAVersionUpdateModel.swift in Sources */, F33IOYM854R4C48ZU602K4L2 /* CHelper.swift in Sources */, F3327L1BJ30974SY08905774 /* KDelegateOllectionView.swift in Sources */, F3P6F8433LVRV052SEY9W3N1 /* KWMptyLaunchController.swift in Sources */, @@ -1974,6 +2005,7 @@ F3N346893L1U6DP8228XK227 /* UOLaunch.swift in Sources */, F39S0H806843N21RM0O95488 /* VARResultController.swift in Sources */, F3D03219Y8NV50N2S66014LX /* GPOOllectionFableon.swift in Sources */, + 03E9A74E2EB5E0F7000D1067 /* FALanguageModel.swift in Sources */, F399V72654D56W408WQO18D5 /* OOSelectorSection.swift in Sources */, F31RUU6I99967458M4X40V5C /* HNFDramaController.swift in Sources */, F3MIE47471I04686Y131BPU5 /* TGleeScreenView.swift in Sources */, @@ -1992,8 +2024,9 @@ 039CE6242EAB29D1007B5EED /* FAPayDataRequest.swift in Sources */, 03E23AB52EAA1A7F004A8CEC /* FAToast.swift in Sources */, 03E23AB62EAA1A7F004A8CEC /* FAUserInfo.swift in Sources */, - 03E23AB72EAA1A7F004A8CEC /* FALocalized.swift in Sources */, + 03E23AB72EAA1A7F004A8CEC /* FALanguageManager.swift in Sources */, 039CE6222EAB1340007B5EED /* FAUserDefaultsKey.swift in Sources */, + 03E9A7442EB4B80B000D1067 /* FADetailRecommendView.swift in Sources */, 03E23AB82EAA1A7F004A8CEC /* FAWaterfallFlowLayout.swift in Sources */, 031FDEC62EB1E4E600F4CAC7 /* FACoinPackTitleView.swift in Sources */, F3K238643L913I6RK4G7S006 /* CSceneRegister.swift in Sources */, @@ -2040,11 +2073,13 @@ 03E23A512EAA1A4E004A8CEC /* FAConsumptionRecordsCell.swift in Sources */, 03E23A522EAA1A4E004A8CEC /* FARankingListHeaderView.swift in Sources */, 03E23A532EAA1A4E004A8CEC /* FAVideoLockView.swift in Sources */, + 03E9A7482EB5D2CB000D1067 /* FALogoutAlert.swift in Sources */, 03E23A542EAA1A4E004A8CEC /* FAHomeViewController.swift in Sources */, 03E23A552EAA1A4E004A8CEC /* FAPopularListViewController.swift in Sources */, 039CE6042EAA2621007B5EED /* AppDelegate+FAAdjust.swift in Sources */, 03E23A562EAA1A4E004A8CEC /* FAPlayerEpUIButton.swift in Sources */, 031FDEE42EB348AA00F4CAC7 /* FABaseAlert.swift in Sources */, + 03E9A74C2EB5DB92000D1067 /* FALanguageCell.swift in Sources */, 03E23A572EAA1A4E004A8CEC /* FAHistoryCell.swift in Sources */, 03E23A582EAA1A4E004A8CEC /* FASearchViewController.swift in Sources */, 03E23A592EAA1A4E004A8CEC /* FAWalletCell.swift in Sources */, @@ -2087,6 +2122,7 @@ 03E23A762EAA1A4E004A8CEC /* FASearchHomeView.swift in Sources */, 03E23A772EAA1A4E004A8CEC /* FAHomeNewContentCell.swift in Sources */, 03E23A782EAA1A4E004A8CEC /* FAOrderRecordsViewController.swift in Sources */, + 03E9A7462EB5ACE5000D1067 /* FADetailRecommendCell.swift in Sources */, 03E23A792EAA1A4E004A8CEC /* FAEpMenuView.swift in Sources */, 03E23A7A2EAA1A4E004A8CEC /* FASearchRecordView.swift in Sources */, 03E23A7B2EAA1A4E004A8CEC /* FACollectViewController.swift in Sources */, @@ -2122,6 +2158,7 @@ F3774560U03XA8151BTQ2Z61 /* HYLLayoutView.swift in Sources */, F3N85463XSRG9VFK665G9028 /* XKRefreshCell.swift in Sources */, 039CE6282EAB50A9007B5EED /* FAStoreCoinsView.swift in Sources */, + 03E9A7402EB49BE6000D1067 /* FAUpdatesAlert.swift in Sources */, F35K41930D96476I83FHZ0D9 /* YLZFableonAlignmentCell.swift in Sources */, F3M8439X72Q55JY9G8U502D9 /* DXYFire.swift in Sources */, 03E239912EAA1A29004A8CEC /* Dictionary+FAAdd.swift in Sources */, @@ -2132,6 +2169,7 @@ 031FDEDA2EB30D6E00F4CAC7 /* FASettingCell.swift in Sources */, 03E239942EAA1A29004A8CEC /* UserDefaults+FAAdd.swift in Sources */, 039CE6322EAB796F007B5EED /* FALabel.swift in Sources */, + 03E9A7502EB5EAC0000D1067 /* FALanguageDataModel.swift in Sources */, 03E239952EAA1A29004A8CEC /* Font+FAAdd.swift in Sources */, 031FDEEE2EB3682000F4CAC7 /* FAVipRetainAlert.swift in Sources */, 03E239962EAA1A29004A8CEC /* FACryptorService.swift in Sources */, @@ -2169,12 +2207,14 @@ 031FDECA2EB1F8F200F4CAC7 /* FACoinsPackReceiveModel.swift in Sources */, 03E239B02EAA1A29004A8CEC /* FAWebView.swift in Sources */, 039CE61C2EAB0F29007B5EED /* FAIapOrderModel.swift in Sources */, + 03E9A7522EB83A58000D1067 /* FAAppStartViewController.swift in Sources */, 03E239B12EAA1A29004A8CEC /* FANetworkMonitor.swift in Sources */, 03E239B22EAA1A29004A8CEC /* UINavigationBar+FAAdd.swift in Sources */, F3EKB04Y9O2888900KQEO504 /* NHCornerController.swift in Sources */, F32A7R4096386F976XT2W958 /* YKConfigMain.swift in Sources */, F3NKHD424DW5B04NK4D6ZC43 /* SCCrollFddebcdbeeffcebdf.swift in Sources */, F3374375770O0338ZQOL63EF /* OControlView.swift in Sources */, + 03E9A74A2EB5DA7E000D1067 /* FALanguageViewController.swift in Sources */, F3224PD65IO4R5M40JGK6Z59 /* TOkenView.swift in Sources */, F3C25CQ448629S8947842301 /* JXMInfoCell.swift in Sources */, F33732269456Q82561503YIR /* KZOgin.swift in Sources */, diff --git a/Fableon/App/AppDelegate+FAAdjust.swift b/Fableon/App/AppDelegate+FAAdjust.swift index 97d493b..38d1e0a 100644 --- a/Fableon/App/AppDelegate+FAAdjust.swift +++ b/Fableon/App/AppDelegate+FAAdjust.swift @@ -69,7 +69,7 @@ extension SceneDelegate { var statUrlStr: String? = webpageURL?.absoluteString var data: [String : Any]? = webpageURL?.query?.urlQuryToDictionary() - if statUrlStr == nil, let pasteStr = UIPasteboard.general.string, pasteStr.contains("movia") { + if statUrlStr == nil, let pasteStr = UIPasteboard.general.string, pasteStr.contains("fableon") { let tempArr = pasteStr.components(separatedBy: "?") let query = tempArr.last diff --git a/Fableon/App/AppDelegate+FAApns.swift b/Fableon/App/AppDelegate+FAApns.swift index 5d2b5b0..24e06f7 100644 --- a/Fableon/App/AppDelegate+FAApns.swift +++ b/Fableon/App/AppDelegate+FAApns.swift @@ -75,7 +75,6 @@ extension AppDelegate { //MARK: -------------- UNUserNotificationCenterDelegate -------------- extension SceneDelegate: UNUserNotificationCenterDelegate { - ///APP处于前台是接收通知消息 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.badge, .banner]) diff --git a/Fableon/App/AppDelegate+FAConfig.swift b/Fableon/App/AppDelegate+FAConfig.swift index 4a3e658..bbcf3a2 100644 --- a/Fableon/App/AppDelegate+FAConfig.swift +++ b/Fableon/App/AppDelegate+FAConfig.swift @@ -20,7 +20,7 @@ extension AppDelegate { FAToast.config() //设置刷新控件的语言 - MJRefreshConfig.default.languageCode = "en" + MJRefreshConfig.default.languageCode = FALanguageManager.manager.mjLanguageKey IQKeyboardManager.shared.isEnabled = true IQKeyboardManager.shared.resignOnTouchOutside = true diff --git a/Fableon/App/SceneDelegate.swift b/Fableon/App/SceneDelegate.swift index 52130d4..89f4e4e 100644 --- a/Fableon/App/SceneDelegate.swift +++ b/Fableon/App/SceneDelegate.swift @@ -7,6 +7,7 @@ import UIKit import YYText +import MJRefresh class SceneDelegate: UIResponder, UIWindowSceneDelegate { @@ -17,13 +18,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: FANetworkMonitor.networkStatusDidChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(languageDidChange), name: FALanguageManager.languageDidChange, object: nil) + FATool.sceneDelegate = self FATool.windowScene = windowScene window = UIWindow(windowScene: windowScene) - window?.rootViewController = FATabBarController() - window?.makeKeyAndVisible() - FAAdjustStateManager.manager.isOpenApp = true + startApp() onLineTimer = Timer.scheduledTimer(timeInterval: 60 * 10, target: YYTextWeakProxy(target: self), selector: #selector(handleOnLine), userInfo: nil, repeats: true) @@ -66,6 +67,55 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { } +extension SceneDelegate { + + private func startApp() { + setRootVC() + let languageManager = FALanguageManager.manager + + if languageManager.languageDataLanguageKey != languageManager.currentLanguageKey { + let vc = FATool.getLanuchViewController() + window?.rootViewController = vc + window?.makeKeyAndVisible() + + languageManager.updateLanguageData { [weak self] finish in + guard let self = self else { return } + self.setRootVC() + } + } else { + languageManager.updateLanguageData(completer: nil) + setRootVC() + } + } + + private func setRootVC() { + ///是否首次开启过 + let hasOpenApp = UserDefaults.standard.object(forKey: kFAHasBeenOpenedAPPDefaultsKey) as? Bool + + if hasOpenApp != true { + let vc = FAAppStartViewController() + vc.openAppBlock = { [weak self] in + guard let self = self else { return } + UserDefaults.standard.set(true, forKey: kFAHasBeenOpenedAPPDefaultsKey) + self.setTabBarController() + self.retryHandleOpenAppMessage() + } + window?.rootViewController = vc + window?.makeKeyAndVisible() + } else { + self.setTabBarController() + self.retryHandleOpenAppMessage() + } + } + + private func setTabBarController() { + FAAdjustStateManager.manager.isOpenApp = true + + window?.rootViewController = FATabBarController() + window?.makeKeyAndVisible() + } +} + extension SceneDelegate { @objc private func handleOnLine() { @@ -73,7 +123,15 @@ extension SceneDelegate { } @objc private func networkStatusDidChangeNotification() { - FATool.requestIDFAAuthorization(nil) - self.retryHandleOpenAppMessage() + if FANetworkMonitor.manager.isReachable == true { + FATool.requestIDFAAuthorization(nil) + self.retryHandleOpenAppMessage() + FAIapManager.manager.preloadingProducts() + } + } + + @objc private func languageDidChange() { + MJRefreshConfig.default.languageCode = FALanguageManager.manager.mjLanguageKey + setTabBarController() } } diff --git a/Fableon/Fableon.entitlements b/Fableon/Fableon.entitlements index 0a2e231..56de1c5 100644 --- a/Fableon/Fableon.entitlements +++ b/Fableon/Fableon.entitlements @@ -2,6 +2,8 @@ + aps-environment + development com.apple.developer.applesignin Default diff --git a/Fableon/Object/Base/Controller/FAAppStartViewController.swift b/Fableon/Object/Base/Controller/FAAppStartViewController.swift new file mode 100644 index 0000000..7e50b0e --- /dev/null +++ b/Fableon/Object/Base/Controller/FAAppStartViewController.swift @@ -0,0 +1,59 @@ +// +// FAAppStartViewController.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/3. +// + +import UIKit + +class FAAppStartViewController: FAViewController { + + var openAppBlock: (() -> Void)? + + private lazy var lanuchVC: UIViewController? = { + let vc = FATool.getLanuchViewController() + return vc + }() + + private lazy var startButton: UIButton = { + let button = FAGradientButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in + guard let self = self else { return } + self.openAppBlock?() + })) + button.layer.cornerRadius = 24 + button.layer.masksToBounds = true + button.fa_colors = [UIColor.BEDFFF.cgColor, UIColor._52_A_2_F_1.cgColor] + button.fa_locations = [0, 1] + button.fa_startPoint = .init(x: 0, y: 0.5) + button.fa_endPoint = .init(x: 1, y: 0.5) + button.setTitle("fableon_open".localized, for: .normal) + button.setTitleColor(._000000, for: .normal) + button.titleLabel?.font = .font(ofSize: 18, weight: .semibold) + return button + }() + + override func viewDidLoad() { + super.viewDidLoad() + + if let vc = lanuchVC { + addChild(vc) + view.addSubview(vc.view) + } + + view.addSubview(startButton) + + startButton.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.height.equalTo(48) + make.bottom.equalToSuperview().offset(-(UIScreen.safeBottom + 110)) + make.width.equalTo(150) + } + + + } + + + + +} diff --git a/Fableon/Object/Base/Controller/FATabBarController.swift b/Fableon/Object/Base/Controller/FATabBarController.swift index 3b56e8b..cbea90b 100644 --- a/Fableon/Object/Base/Controller/FATabBarController.swift +++ b/Fableon/Object/Base/Controller/FATabBarController.swift @@ -12,10 +12,10 @@ class FATabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() - let nav1 = getNavigation(FAHomeViewController(), "Home".localized, UIImage(named: "tabbar_home_icon"), UIImage(named: "tabbar_home_icon_selected")) - let nav2 = getNavigation(FARecommendViewController(), "Recommend".localized, UIImage(named: "tabbar_recommend_icon"), UIImage(named: "tabbar_recommend_icon_selected")) - let nav3 = getNavigation(FACollectViewController(), "Collect".localized, UIImage(named: "tabbar_collect_icon"), UIImage(named: "tabbar_collect_icon_selected")) - let nav4 = getNavigation(FAMeViewController(), "Me".localized, UIImage(named: "tabbar_me_icon"), UIImage(named: "tabbar_me_icon_selected")) + let nav1 = getNavigation(FAHomeViewController(), "fableon_home".localized, UIImage(named: "tabbar_home_icon"), UIImage(named: "tabbar_home_icon_selected")) + let nav2 = getNavigation(FARecommendViewController(), "fableon_recommend".localized, UIImage(named: "tabbar_recommend_icon"), UIImage(named: "tabbar_recommend_icon_selected")) + let nav3 = getNavigation(FACollectViewController(), "fableon_collect".localized, UIImage(named: "tabbar_collect_icon"), UIImage(named: "tabbar_collect_icon_selected")) + let nav4 = getNavigation(FAMeViewController(), "fableon_me".localized, UIImage(named: "tabbar_me_icon"), UIImage(named: "tabbar_me_icon_selected")) viewControllers = [nav1, nav2, nav3, nav4] @@ -47,6 +47,8 @@ class FATabBarController: UITabBarController { FALogin.manager.requestUserInfo(completer: nil) } } + FATool.checkUpdates() +// FATool.requestIDFAAuthorization(nil) } override var childForStatusBarStyle: UIViewController? { diff --git a/Fableon/Object/Base/Define/FAUserDefaultsKey.swift b/Fableon/Object/Base/Define/FAUserDefaultsKey.swift index 469bf48..7827df1 100644 --- a/Fableon/Object/Base/Define/FAUserDefaultsKey.swift +++ b/Fableon/Object/Base/Define/FAUserDefaultsKey.swift @@ -9,3 +9,7 @@ let kFAWaitRestoreIAPDefaultsKey = "kFAWaitRestoreIAPDefaultsKey" let kFAApnsAlertDefaultsKey = "kFAApnsAlertDefaultsKey" + +let kFAVersionUpdateAlertDefaultsKey = "kFAVersionUpdateAlertDefaultsKey" + +let kFAHasBeenOpenedAPPDefaultsKey = "kFAHasBeenOpenedAPPDefaultsKey" diff --git a/Fableon/Object/Base/Request/FAAPI/FAAPI.swift b/Fableon/Object/Base/Request/FAAPI/FAAPI.swift index b5289e1..71ffed0 100644 --- a/Fableon/Object/Base/Request/FAAPI/FAAPI.swift +++ b/Fableon/Object/Base/Request/FAAPI/FAAPI.swift @@ -130,6 +130,17 @@ struct FAAPI { } } + static func requestDetailRecommendVideo( completer: ((_ list: [FAShortPlayModel]?) -> Void)?) { + + FANetworkManager.manager.request(FABaseURL + "/getDetailsRecommand", + method: .get, + parameters: nil, + isLoding: false, + isToast: false) { (response: FANetworkManager.Response>) in + completer?(response.data?.list) + } + } + ///收藏列表 static func requestCollectList(page: Int, completer: ((_ listModel: FANetworkManager.List?) -> Void)?) { let parameters: [String : Any] = [ @@ -251,6 +262,45 @@ struct FAAPI { } } + static func requestVersionUpdateData(completer: ((_ model: FAVersionUpdateModel?) -> Void)?) { + + FANetworkManager.manager.request(FABaseURL + "/customer/versionControl", + method: .get, + parameters: nil, + isLoding: false, + isToast: false) { (response: FANetworkManager.Response) in + completer?(response.data) + } + } + + ///获取语言列表 + static func requestLanguageList(completer: ((_ list: [FALanguageModel]?) -> Void)?) { + + FANetworkManager.manager.request(FABaseURL + "/languges", + method: .get, + parameters: nil, + isLoding: false, + isToast: true) { (response: FANetworkManager.Response>) in + completer?(response.data?.list) + } + } + + ///获取语言列表 + static func requestLanguageDataList(key: String, completer: ((_ model: FALanguageDataModel?) -> Void)?) { + + var parameters = [ + "lang_key" : key + ] + + FANetworkManager.manager.request(FABaseURL + "/translates", + method: .get, + parameters: parameters, + isLoding: false, + isToast: true) { (response: FANetworkManager.Response) in + completer?(response.data) + } + } + } diff --git a/Fableon/Object/Base/Request/FANetworkManager.swift b/Fableon/Object/Base/Request/FANetworkManager.swift index 977247b..a0510a4 100644 --- a/Fableon/Object/Base/Request/FANetworkManager.swift +++ b/Fableon/Object/Base/Request/FANetworkManager.swift @@ -96,7 +96,7 @@ class FANetworkManager { completion?(response) } else { if isToast { - FAToast.show(text: "Error".localized) + FAToast.show(text: "fableon_error".localized) } var res = FANetworkManager.Response() res.code = -1 @@ -177,7 +177,7 @@ extension FANetworkManager { let dic = [ "authorization" : token, "system-version" : UIDevice.current.systemVersion, - "lang-key" : "en", + "lang-key" : FALanguageManager.manager.currentLanguageKey, "time-zone" : String.timeZone(), "app-version" : (Bundle.main.infoDictionary!["CFBundleShortVersionString"] as? String) ?? "", "brand" : "apple", //品牌 diff --git a/Fableon/Object/Base/Request/FANetworkMonitor.swift b/Fableon/Object/Base/Request/FANetworkMonitor.swift index 77cd6e0..6afb9c4 100644 --- a/Fableon/Object/Base/Request/FANetworkMonitor.swift +++ b/Fableon/Object/Base/Request/FANetworkMonitor.swift @@ -12,10 +12,10 @@ class FANetworkMonitor { static let manager = FANetworkMonitor() ///是否有网 - var isReachable: Bool? + private(set) var isReachable: Bool? - private var connectionType: NWInterface.InterfaceType? - private var status: NWPath.Status? + private(set) var connectionType: NWInterface.InterfaceType? + private(set) var status: NWPath.Status? private let monitor = NWPathMonitor() private let queue = DispatchQueue(label: "NetworkMonitorQueue") @@ -36,7 +36,6 @@ class FANetworkMonitor { self.connectionType = nil } - if path.status == .satisfied, self.connectionType != nil { if self.isReachable == false { self.isReachable = true diff --git a/Fableon/Object/Base/View/FATableView.swift b/Fableon/Object/Base/View/FATableView.swift index 96082ac..c66c092 100644 --- a/Fableon/Object/Base/View/FATableView.swift +++ b/Fableon/Object/Base/View/FATableView.swift @@ -18,14 +18,14 @@ class FATableView: UITableView { self.backgroundColor = .clear self.contentInsetAdjustmentBehavior = .never - if style == .insetGrouped { + if style == .insetGrouped || style == .grouped { sectionFooterHeight = 14 sectionHeaderHeight = 0.1 } else if style == .plain { if #available(iOS 15.0, *) { sectionHeaderTopPadding = 0 } - } + } } required init?(coder: NSCoder) { diff --git a/Fableon/Object/Base/WebView/FAAppWebViewController.swift b/Fableon/Object/Base/WebView/FAAppWebViewController.swift index a641bc4..28d0315 100644 --- a/Fableon/Object/Base/WebView/FAAppWebViewController.swift +++ b/Fableon/Object/Base/WebView/FAAppWebViewController.swift @@ -21,13 +21,13 @@ class FAAppWebViewController: FABaseWebViewController { self.autoTitle = false if webUrl == kFAFeedBackListWebUrl { - self.title = "Feedback History".localized + self.title = "fableon_feedback_history".localized } else if webUrl == kFAFeedBackHomeWebUrl { - self.title = "Feedback".localized + self.title = "fableon_feedback".localized } else if webUrl == kFAFeedBackDetailWebUrl { - self.title = "Feedback Details".localized + self.title = "fableon_feedback_detail".localized } else if webUrl == kFALogoutWebUrl { - self.title = "Account Deletion".localized + self.title = "fableon_account_deletion".localized } } @@ -51,7 +51,7 @@ extension FAAppWebViewController { var dic = [ "token" : FALogin.manager.token?.token ?? "", "time_zone" : String.timeZone(), - "lang" : FALocalized.manager.currentLocalizedKey, + "lang" : FALanguageManager.manager.currentLanguageKey, "type" : "ios", "device-id" : FADeviceIDManager.shared.id ] diff --git a/Fableon/Object/Class/Home/C/FANewListViewController.swift b/Fableon/Object/Class/Home/C/FANewListViewController.swift index 2732cc5..d84d9e3 100644 --- a/Fableon/Object/Class/Home/C/FANewListViewController.swift +++ b/Fableon/Object/Class/Home/C/FANewListViewController.swift @@ -41,7 +41,7 @@ class FANewListViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "New".localized + self.title = "fableon_new".localized fa_setupLayout() diff --git a/Fableon/Object/Class/Home/C/FAPopularListViewController.swift b/Fableon/Object/Class/Home/C/FAPopularListViewController.swift index da6952b..d3f27a9 100644 --- a/Fableon/Object/Class/Home/C/FAPopularListViewController.swift +++ b/Fableon/Object/Class/Home/C/FAPopularListViewController.swift @@ -41,7 +41,7 @@ class FAPopularListViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Popular".localized + self.title = "fableon_popular".localized fa_setupLayout() diff --git a/Fableon/Object/Class/Home/UI/FAHomeMustSeeContentView.swift b/Fableon/Object/Class/Home/UI/FAHomeMustSeeContentView.swift index b44451a..120ad29 100644 --- a/Fableon/Object/Class/Home/UI/FAHomeMustSeeContentView.swift +++ b/Fableon/Object/Class/Home/UI/FAHomeMustSeeContentView.swift @@ -19,7 +19,7 @@ struct FAHomeMustSeeContentView: View { var body: some View { VStack(spacing: 15) { HStack { - Text("Editor's Picks".localized) + Text("fableon_editor's_picks".localized) .font(Font.font(size: 16, weight: .medium)) .foregroundStyle(Color(String.color_FFFFFF)) .padding(.leading, 10) diff --git a/Fableon/Object/Class/Home/UI/FAHomeMustSeeShortView.swift b/Fableon/Object/Class/Home/UI/FAHomeMustSeeShortView.swift index 2afd841..42dd6f2 100644 --- a/Fableon/Object/Class/Home/UI/FAHomeMustSeeShortView.swift +++ b/Fableon/Object/Class/Home/UI/FAHomeMustSeeShortView.swift @@ -47,7 +47,7 @@ struct FAHomeMustSeeShortView: View { HStack(spacing: 4) { Image("Frame 2920") - Text("Watch".localized) + Text("fableon_watch".localized) .font(Font.font(size: 12, weight: .medium)) .foregroundStyle(Color(String.color_000000)) diff --git a/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift b/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift index e9860fd..259b9f1 100644 --- a/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift +++ b/Fableon/Object/Class/Home/UI/FAHomeMustSeeView.swift @@ -18,7 +18,7 @@ struct FAHomeMustSeeView: View { var body: some View { VStack { HStack { - Text("Must-see TV series".localized) + Text("fableon_must_see_tv_series".localized) .font(Font.font(size: 18, weight: .medium)) .foregroundStyle(Color(String.color_FFFFFF)) .padding(.leading, 16) diff --git a/Fableon/Object/Class/Home/UI/FAHomeNewView.swift b/Fableon/Object/Class/Home/UI/FAHomeNewView.swift index 817e32a..c36809d 100644 --- a/Fableon/Object/Class/Home/UI/FAHomeNewView.swift +++ b/Fableon/Object/Class/Home/UI/FAHomeNewView.swift @@ -24,7 +24,7 @@ struct FAHomeNewView: View { let list = viewModel.homeNewItem?.list ?? [] VStack(spacing: 15) { - Text("New Releases".localized) + Text("fableon_home_new".localized) .font(.font(size: 18, weight: .medium)) .foregroundStyle(Color(String.color_FFFFFF)) .padding(.leading, 16) @@ -60,7 +60,7 @@ struct FAHomeNewView: View { HStack(spacing: 4) { Image("Frame 2921") - Text("Watch".localized) + Text("fableon_watch".localized) .font(.font(size: 14, weight: .medium)) .foregroundStyle(Color(String.color_000000)) } diff --git a/Fableon/Object/Class/Home/V/FAHomeCoinsPackButton.swift b/Fableon/Object/Class/Home/V/FAHomeCoinsPackButton.swift index 6333b3c..2216151 100644 --- a/Fableon/Object/Class/Home/V/FAHomeCoinsPackButton.swift +++ b/Fableon/Object/Class/Home/V/FAHomeCoinsPackButton.swift @@ -17,7 +17,7 @@ class FAHomeCoinsPackButton: UIControl { let label = UILabel() label.font = .font(ofSize: 10, weight: .init(900)).withBoldItalic() label.textColor = .FFFFFF - label.text = "Daily Coins".localized + label.text = "fableon_daily_coins".localized return label }() diff --git a/Fableon/Object/Class/Home/V/FAHomePlayHistoryView.swift b/Fableon/Object/Class/Home/V/FAHomePlayHistoryView.swift index d54166f..b440766 100644 --- a/Fableon/Object/Class/Home/V/FAHomePlayHistoryView.swift +++ b/Fableon/Object/Class/Home/V/FAHomePlayHistoryView.swift @@ -13,7 +13,7 @@ class FAHomePlayHistoryView: UIView { didSet { coverImageView.fa_setImage(model?.image_url) titleLabel.text = model?.name - epLabel.text = "Last Watch:Ep.##".localizedReplace(text: model?.current_episode ?? "") + epLabel.text = "fableon_last_watch_ep".localizedReplace(text: model?.current_episode ?? "") } } diff --git a/Fableon/Object/Class/Home/V/FARankingListCell.swift b/Fableon/Object/Class/Home/V/FARankingListCell.swift index de75b56..b215904 100644 --- a/Fableon/Object/Class/Home/V/FARankingListCell.swift +++ b/Fableon/Object/Class/Home/V/FARankingListCell.swift @@ -13,7 +13,7 @@ class FARankingListCell: UICollectionViewCell { didSet { coverImageView.fa_setImage(model?.image_url) nameLabel.text = model?.name - epLabel.text = "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") countLabel.text = "\(model?.watch_total ?? 0)" } } diff --git a/Fableon/Object/Class/Home/V/FASearchInputView.swift b/Fableon/Object/Class/Home/V/FASearchInputView.swift index 5e00976..3f29cd5 100644 --- a/Fableon/Object/Class/Home/V/FASearchInputView.swift +++ b/Fableon/Object/Class/Home/V/FASearchInputView.swift @@ -40,7 +40,7 @@ class FASearchInputView: UIView { textField.returnKeyType = .search textField.font = .font(ofSize: 12, weight: .medium) textField.textColor = .FFFFFF - textField.attributedPlaceholder = NSAttributedString(string: "Search".localized, attributes: [ + textField.attributedPlaceholder = NSAttributedString(string: "fableon_search".localized, attributes: [ .font : UIFont.font(ofSize: 12, weight: .medium), .foregroundColor : UIColor.FFFFFF.withAlphaComponent(0.5) ]) diff --git a/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift b/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift index e4e06ee..3070c93 100644 --- a/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift +++ b/Fableon/Object/Class/Home/V/FASearchRecommendCell.swift @@ -15,7 +15,7 @@ class FASearchRecommendCell: UICollectionViewCell { coverImageView.fa_setImage(model?.image_url) titleLabel.text = model?.name countLabel.text = "\(model?.watch_total ?? 0)" - epLabel.text = "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") } } diff --git a/Fableon/Object/Class/Home/V/FASearchRecordView.swift b/Fableon/Object/Class/Home/V/FASearchRecordView.swift index 921df98..124efcb 100644 --- a/Fableon/Object/Class/Home/V/FASearchRecordView.swift +++ b/Fableon/Object/Class/Home/V/FASearchRecordView.swift @@ -23,7 +23,7 @@ class FASearchRecordView: UIView { let label = UILabel() label.font = .font(ofSize: 14, weight: .medium) label.textColor = .FFFFFF - label.text = "Historical search".localized + label.text = "fableon_search_history".localized return label }() diff --git a/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift b/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift index 70fa0dd..f536dfa 100644 --- a/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift +++ b/Fableon/Object/Class/Home/VM/FAHomeViewModel.swift @@ -38,7 +38,7 @@ class FAHomeViewModel: ObservableObject { if $0.module_key == .banner { self.bannerItem = $0 } else if $0.module_key == .v3_recommand { - $0.title = "Popular".localized + $0.title = "fableon_popular".localized popularItem = $0 } else if $0.module_key == .week_ranking { $0.title = "Rankings".localized @@ -47,7 +47,7 @@ class FAHomeViewModel: ObservableObject { $0.title = "Genres".localized genresItem = $0 } else if $0.module_key == .new_recommand { - $0.title = "New".localized + $0.title = "fableon_new".localized newItem = $0 self.homeNewItem = $0 } else if $0.module_key == .week_recommend { diff --git a/Fableon/Object/Class/Me/C/FAAboutViewController.swift b/Fableon/Object/Class/Me/C/FAAboutViewController.swift index b0e1ca7..a6b7bc3 100644 --- a/Fableon/Object/Class/Me/C/FAAboutViewController.swift +++ b/Fableon/Object/Class/Me/C/FAAboutViewController.swift @@ -11,9 +11,9 @@ class FAAboutViewController: FAViewController { private lazy var dataArr: [FAMeItemModel] = [ - FAMeItemModel(type: .privacyPolicy, name: "Privacy Policy".localized), - FAMeItemModel(type: .userAgreement, name: "User Agreement".localized), - FAMeItemModel(type: .visitWebsite, name: "Visit Website".localized), + FAMeItemModel(type: .privacyPolicy, name: "fableon_privacy_policy".localized), + FAMeItemModel(type: .userAgreement, name: "fableon_user_agreement".localized), + FAMeItemModel(type: .visitWebsite, name: "fableon_visit_website".localized), ] private lazy var tableView: FATableView = { diff --git a/Fableon/Object/Class/Me/C/FACoinPackViewController.swift b/Fableon/Object/Class/Me/C/FACoinPackViewController.swift index 2bbfd63..867f9bc 100644 --- a/Fableon/Object/Class/Me/C/FACoinPackViewController.swift +++ b/Fableon/Object/Class/Me/C/FACoinPackViewController.swift @@ -115,7 +115,7 @@ class FACoinPackViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "My Refills".localized + self.title = "fableon_my_refills".localized payDataModel = FAIapManager.manager.payDateModel fa_setupLayout() diff --git a/Fableon/Object/Class/Me/C/FALanguageViewController.swift b/Fableon/Object/Class/Me/C/FALanguageViewController.swift new file mode 100644 index 0000000..aad5c0e --- /dev/null +++ b/Fableon/Object/Class/Me/C/FALanguageViewController.swift @@ -0,0 +1,99 @@ +// +// FALanguageViewController.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/1. +// + +import UIKit + +class FALanguageViewController: FAViewController { + + private var dataArr: [FALanguageModel] = [] + + private lazy var tableView: FATableView = { + let tableView = FATableView(frame: .zero, style: .grouped) + tableView.delegate = self + tableView.dataSource = self + tableView.separatorStyle = .none + tableView.rowHeight = 60 + tableView.contentInset = .init(top: 20, left: 0, bottom: UIScreen.safeBottom, right: 0) + tableView.register(FALanguageCell.self, forCellReuseIdentifier: "cell") + return tableView + }() + + override func viewDidLoad() { + super.viewDidLoad() + title = "fableon_language".localized + + view.addSubview(tableView) + tableView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview().offset(UIScreen.navBarHeight) + } + self.tableView.contentOffset = .init(x: 0, y: -self.tableView.contentInset.top) + + requestDataArr() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: true) + fa_setNavigationStyle() + } +} + +//MARK: UITableViewDelegate UITableViewDataSource +extension FALanguageViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let model = dataArr[indexPath.section] + + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FALanguageCell + cell.fa_isSelected = true + cell.model = model + cell.fa_isSelected = model.lang_key == FALanguageManager.manager.currentLanguageKey + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 1 + } + + func numberOfSections(in tableView: UITableView) -> Int { + return dataArr.count + } + + func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat { + return 12 + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 1 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let model = dataArr[indexPath.section] + guard let key = model.lang_key else { return } + + FALanguageManager.manager.switchLanguage(key) { finish in + + } + } + + + +} + +extension FALanguageViewController { + + private func requestDataArr() { + FAAPI.requestLanguageList { [weak self] list in + guard let self = self else { return } + guard let list = list else { return } + self.dataArr = list + self.tableView.reloadData() + } + } + +} diff --git a/Fableon/Object/Class/Me/C/FAMeListViewController.swift b/Fableon/Object/Class/Me/C/FAMeListViewController.swift index b9db860..410a2c4 100644 --- a/Fableon/Object/Class/Me/C/FAMeListViewController.swift +++ b/Fableon/Object/Class/Me/C/FAMeListViewController.swift @@ -14,14 +14,15 @@ class FAMeListViewController: FAViewController, JXPagingViewListViewDelegate { private lazy var dataArr: [FAMeItemModel] = { let arr = [ - FAMeItemModel(type: .feedback, name: "Feedback".localized, icon: UIImage(named: "icon_feedback")), - FAMeItemModel(type: .about, name: "About".localized, icon: UIImage(named: "icon_about")), + FAMeItemModel(type: .language, name: "fableon_language".localized, icon: UIImage(named: "icon_language")), + FAMeItemModel(type: .feedback, name: "fableon_feedback".localized, icon: UIImage(named: "icon_feedback")), + FAMeItemModel(type: .about, name: "fableon_about_us".localized, icon: UIImage(named: "icon_about")), - FAMeItemModel(type: .privacyPolicy, name: "Privacy Policy".localized, icon: UIImage(named: "icon_privacy")), - FAMeItemModel(type: .userAgreement, name: "User Agreement".localized, icon: UIImage(named: "icon_user")), - FAMeItemModel(type: .visitWebsite, name: "Visit Website".localized, icon: UIImage(named: "icon_visit")), + FAMeItemModel(type: .privacyPolicy, name: "fableon_privacy_policy".localized, icon: UIImage(named: "icon_privacy")), + FAMeItemModel(type: .userAgreement, name: "fableon_user_agreement".localized, icon: UIImage(named: "icon_user")), +// FAMeItemModel(type: .visitWebsite, name: "fableon_visit_website".localized, icon: UIImage(named: "icon_visit")), - FAMeItemModel(type: .setting, name: "Setting".localized, icon: UIImage(named: "icon_setting")) + FAMeItemModel(type: .setting, name: "fableon_settings".localized, icon: UIImage(named: "icon_setting")) ] return arr }() @@ -147,6 +148,11 @@ extension FAMeListViewController: UITableViewDelegate, UITableViewDataSource { UIApplication.shared.open(url) } + case .language: + let vc = FALanguageViewController() + self.navigationController?.pushViewController(vc, animated: true) + + default: break } diff --git a/Fableon/Object/Class/Me/C/FASettingViewController.swift b/Fableon/Object/Class/Me/C/FASettingViewController.swift index 0fd9e4d..bf94ac8 100644 --- a/Fableon/Object/Class/Me/C/FASettingViewController.swift +++ b/Fableon/Object/Class/Me/C/FASettingViewController.swift @@ -10,7 +10,7 @@ import UIKit class FASettingViewController: FAViewController { private lazy var dataArr: [FAMeItemModel] = [ - FAMeItemModel(type: .deleteAccount, name: "Account Deletion".localized, icon: nil) + FAMeItemModel(type: .deleteAccount, name: "fableon_account_deletion".localized, icon: nil) ] private lazy var tableView: FATableView = { @@ -31,7 +31,7 @@ class FASettingViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Settings".localized + self.title = "fableon_settings".localized NotificationCenter.default.addObserver(self, selector: #selector(userInfoUpdateNotification), name: FALogin.userInfoUpdateNotification, object: nil) diff --git a/Fableon/Object/Class/Me/M/FAMeItemModel.swift b/Fableon/Object/Class/Me/M/FAMeItemModel.swift index 163787e..1a4bd45 100644 --- a/Fableon/Object/Class/Me/M/FAMeItemModel.swift +++ b/Fableon/Object/Class/Me/M/FAMeItemModel.swift @@ -23,6 +23,7 @@ struct FAMeItemModel { ///金币奖励 case rewardCoins case deleteAccount + case language } diff --git a/Fableon/Object/Class/Me/M/FAVersionUpdateModel.swift b/Fableon/Object/Class/Me/M/FAVersionUpdateModel.swift new file mode 100644 index 0000000..00e8219 --- /dev/null +++ b/Fableon/Object/Class/Me/M/FAVersionUpdateModel.swift @@ -0,0 +1,38 @@ +// +// FAVersionUpdateModel.swift +// Fableon +// +// Created by 湖北秦九 on 2025/10/31. +// + +import UIKit +import SmartCodable + +struct FAVersionUpdateModel: SmartCodable { + + var version_code: String? + var des: String? + var version_name: String? + + var force: Bool? + + + func canUpdate() -> Bool { + guard let version = version_code else { return false } + + let result = kFAAPPVersion.compare(version, options: .numeric) + if result == .orderedAscending { + return true + } else { + return false + } + } + + + static func mappingForKey() -> [SmartKeyTransformer]? { + return [ + CodingKeys.des <--- ["description"] + ] + } + +} diff --git a/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift b/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift index 5e4ae1c..97802fa 100644 --- a/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift +++ b/Fableon/Object/Class/Me/V/FACoinPackHeaderView.swift @@ -33,20 +33,20 @@ class FACoinPackHeaderView: UIView { view.dotColor = .C_5_DDF_5 view.font = .font(ofSize: 14, weight: .regular) view.textColors = [UIColor.C_5_DDF_5.cgColor, UIColor.C_5_DDF_5.cgColor] - view.text = "REWARDS OVERVIEW".localized + view.text = "fableon_rewards_overview".localized.uppercased() return view }() private lazy var coinsView1: CoinsView = { let view = CoinsView() - view.title = "Weekly Total".localized + view.title = "fableon_weekly_total".localized view.coins = 0 return view }() private lazy var coinsView2: CoinsView = { let view = CoinsView() - view.title = "Claimable Coins".localized + view.title = "fableon_claimable_coins".localized view.coins = 0 return view }() @@ -65,7 +65,7 @@ class FACoinPackHeaderView: UIView { let label = UILabel() label.font = .font(ofSize: 12, weight: .regular) label.textColor = .FFFFFF.withAlphaComponent(0.5) - label.text = "Active Refills".localized + ": " + label.text = "fableon_active_refills".localized + ": " return label }() @@ -99,7 +99,7 @@ class FACoinPackHeaderView: UIView { coinText.bounds = .init(x: 0, y: -2.5, width: coinImage.size.width, height: coinImage.size.height) let coinAtt = AttributedString(NSAttributedString(attachment: coinText)) - let textAtt = AttributedString("Claim All".localized + " ", attributes: AttributeContainer([ + let textAtt = AttributedString("fableon_claim_all".localized + " ", attributes: AttributeContainer([ .font : UIFont.font(ofSize: 14, weight: .bold), .foregroundColor : UIColor.FFFFFF ])) @@ -114,7 +114,7 @@ class FACoinPackHeaderView: UIView { } else { button.fa_colors = [UIColor._6_D_6_D_6_D.cgColor, UIColor._6_D_6_D_6_D.cgColor] - button.configuration?.attributedTitle = AttributedString("Get a Refill to Claim".localized, attributes: AttributeContainer([ + button.configuration?.attributedTitle = AttributedString("fableon_get_refill_button_text".localized, attributes: AttributeContainer([ .font : UIFont.font(ofSize: 14, weight: .bold), .foregroundColor : UIColor.FFFFFF.withAlphaComponent(0.5) ])) diff --git a/Fableon/Object/Class/Me/V/FACoinsPackBuyView.swift b/Fableon/Object/Class/Me/V/FACoinsPackBuyView.swift index 9694e6b..5fc1ed4 100644 --- a/Fableon/Object/Class/Me/V/FACoinsPackBuyView.swift +++ b/Fableon/Object/Class/Me/V/FACoinsPackBuyView.swift @@ -18,7 +18,7 @@ class FACoinsPackBuyView: UIView { view.dotColor = .C_5_DDF_5 view.textColors = [UIColor.C_5_DDF_5.cgColor, UIColor.C_5_DDF_5.cgColor] view.font = .font(ofSize: 14, weight: .regular) - view.text = "Weekly Refill".localized.uppercased() + view.text = "fableo_weekly_refill".localized.uppercased() return view }() diff --git a/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift b/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift index b691f5d..9051045 100644 --- a/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift +++ b/Fableon/Object/Class/Me/V/FACoinsPackClaimListCell.swift @@ -63,13 +63,13 @@ class FACoinsPackClaimListCell: UICollectionViewCell { private lazy var coinsView1: CoinsView = { let view = CoinsView() - view.title = "Total Reward".localized + view.title = "fableon_total_reward".localized return view }() private lazy var coinsView2: CoinsView = { let view = CoinsView() - view.title = "Remaining".localized + view.title = "fableon_remaining".localized return view }() @@ -103,7 +103,7 @@ class FACoinsPackClaimListCell: UICollectionViewCell { ])) - button.configuration?.attributedTitle = AttributedString("Claim".localized, attributes: AttributeContainer([ + button.configuration?.attributedTitle = AttributedString("fableon_claim".localized, attributes: AttributeContainer([ .font : UIFont.font(ofSize: 14, weight: .bold), .foregroundColor : UIColor._114_CEE ])) @@ -112,7 +112,7 @@ class FACoinsPackClaimListCell: UICollectionViewCell { } else { button.fa_colors = [UIColor.BCBCBC.cgColor, UIColor.BCBCBC.cgColor] - button.configuration?.attributedTitle = AttributedString("Claim".localized, attributes: AttributeContainer([ + button.configuration?.attributedTitle = AttributedString("fableon_claim".localized, attributes: AttributeContainer([ .font : UIFont.font(ofSize: 14, weight: .bold), .foregroundColor : UIColor.FFFFFF_0_8 ])) diff --git a/Fableon/Object/Class/Me/V/FACoinsPackClaimListView.swift b/Fableon/Object/Class/Me/V/FACoinsPackClaimListView.swift index a497b53..08b0db1 100644 --- a/Fableon/Object/Class/Me/V/FACoinsPackClaimListView.swift +++ b/Fableon/Object/Class/Me/V/FACoinsPackClaimListView.swift @@ -22,7 +22,7 @@ class FACoinsPackClaimListView: UIView { view.dotColor = .C_5_DDF_5 view.textColors = [UIColor.C_5_DDF_5.cgColor, UIColor.C_5_DDF_5.cgColor] view.font = .font(ofSize: 14, weight: .regular) - view.text = "Active Refills".localized.uppercased() + view.text = "fableon_active_refills".localized.uppercased() return view }() diff --git a/Fableon/Object/Class/Me/V/FALanguageCell.swift b/Fableon/Object/Class/Me/V/FALanguageCell.swift new file mode 100644 index 0000000..9f34899 --- /dev/null +++ b/Fableon/Object/Class/Me/V/FALanguageCell.swift @@ -0,0 +1,78 @@ +// +// FALanguageCell.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/1. +// + +import UIKit + +class FALanguageCell: FATableViewCell { + + var model: FALanguageModel? { + didSet { + titleLabel.text = model?.show_name + } + } + + + var fa_isSelected: Bool = false { + didSet { + if fa_isSelected { + selectedImageView.image = UIImage(named: "Vector") + } else { + selectedImageView.image = UIImage(named: "Ellipse 45") + } + } + } + + private lazy var bgView: UIView = { + let view = UIView() + view.backgroundColor = ._5_CA_8_FF_0_2 + view.layer.cornerRadius = 12 + view.layer.masksToBounds = true + return view + }() + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 14, weight: .semibold) + label.textColor = .FFFFFF + return label + }() + + private lazy var selectedImageView: UIImageView = { + let imageView = UIImageView() + return imageView + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + contentView.addSubview(bgView) + bgView.addSubview(titleLabel) + bgView.addSubview(selectedImageView) + + bgView.snp.makeConstraints { make in + make.top.bottom.equalToSuperview() + make.left.equalToSuperview().offset(16) + make.centerX.equalToSuperview() + } + + titleLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.left.equalToSuperview().offset(16) + } + + selectedImageView.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalToSuperview().offset(-16) + } + + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} diff --git a/Fableon/Object/Class/Me/V/FALoginView.swift b/Fableon/Object/Class/Me/V/FALoginView.swift index 0063ef5..236339a 100644 --- a/Fableon/Object/Class/Me/V/FALoginView.swift +++ b/Fableon/Object/Class/Me/V/FALoginView.swift @@ -22,7 +22,7 @@ class FALoginView: FAPanModalContentView { }() private lazy var appleButton: UIButton = { - let button = self.createButton(image: UIImage(named: "apple_logo_icon_01"), title: "Login with Apple".localized) + let button = self.createButton(image: UIImage(named: "apple_logo_icon_01"), title: "fableon_login_title_apple".localized) button.addAction(UIAction(handler: { [weak self] _ in self?.login(type: .apple) }), for: .touchUpInside) @@ -30,7 +30,7 @@ class FALoginView: FAPanModalContentView { }() private lazy var facebookButton: UIButton = { - let button = self.createButton(image: UIImage(named: "facebook_logo_icon_01"), title: "Login with Facebook".localized) + let button = self.createButton(image: UIImage(named: "facebook_logo_icon_01"), title: "fableon_login_title_facebook".localized) button.addAction(UIAction(handler: { [weak self] _ in self?.login(type: .faceBook) }), for: .touchUpInside) diff --git a/Fableon/Object/Class/Me/V/FAMeCoinsPackButton.swift b/Fableon/Object/Class/Me/V/FAMeCoinsPackButton.swift index 5a338f3..5c6b56f 100644 --- a/Fableon/Object/Class/Me/V/FAMeCoinsPackButton.swift +++ b/Fableon/Object/Class/Me/V/FAMeCoinsPackButton.swift @@ -34,7 +34,7 @@ class FAMeCoinsPackButton: UIControl { label.textColors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor] label.textStartPoint = .init(x: 0, y: 0.5) label.textEndPoint = .init(x: 0.7, y: 0.5) - label.text = "Daily reward ready!".localized + label.text = "fableo_me_daily_1".localized return label }() @@ -42,7 +42,7 @@ class FAMeCoinsPackButton: UIControl { let label = UILabel() label.font = .font(ofSize: 12, weight: .medium).withBoldItalic() label.textColor = .FFFFFF - label.text = "Claim your rewards now.".localized + label.text = "fableo_me_daily_2".localized return label }() diff --git a/Fableon/Object/Class/Me/V/FAMeHeaderView.swift b/Fableon/Object/Class/Me/V/FAMeHeaderView.swift index 95ef447..edfdf26 100644 --- a/Fableon/Object/Class/Me/V/FAMeHeaderView.swift +++ b/Fableon/Object/Class/Me/V/FAMeHeaderView.swift @@ -49,7 +49,7 @@ class FAMeHeaderView: UIView { private lazy var coinsView: FAMeCoinsView = { let view = FAMeCoinsView() - view.title = "Coins".localized + view.title = "fableon_coins".localized view.count = 0 view.addAction(UIAction(handler: { [weak self] _ in guard let self = self else { return } @@ -61,7 +61,7 @@ class FAMeHeaderView: UIView { private lazy var bonusCoinsView: FAMeCoinsView = { let view = FAMeCoinsView() - view.title = "Bonus" + view.title = "fableon_bonus".localized view.count = 0 view.addAction(UIAction(handler: { [weak self] _ in guard let self = self else { return } @@ -91,7 +91,7 @@ class FAMeHeaderView: UIView { button.layer.masksToBounds = true button.layer.borderWidth = 1 button.layer.borderColor = UIColor.FFFEE_9.cgColor - button.setTitle("Log in".localized, for: .normal) + button.setTitle("fableon_login".localized, for: .normal) button.setTitleColor(.FFFFFF, for: .normal) button.titleLabel?.font = .font(ofSize: 14, weight: .medium) return button diff --git a/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift b/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift index 24f3d7a..9123892 100644 --- a/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift +++ b/Fableon/Object/Class/Me/V/FAMeTableViewHeaderView.swift @@ -15,13 +15,13 @@ class FAMeTableViewHeaderView: UIView { subscribeView.isHidden = true expirationView.isHidden = false vipImageView.image = UIImage(named: "vip_image_02") - titleLabel.text = "Activated".localized + titleLabel.text = "fableon_activated".localized subtitleLabel.text = "vip_tip_01".localized } else { subscribeView.isHidden = false expirationView.isHidden = true vipImageView.image = UIImage(named: "vip_image_01") - titleLabel.text = "Not Activated".localized + titleLabel.text = "fableon_not_activated".localized subtitleLabel.text = "vip_tip_02".localized } @@ -61,7 +61,7 @@ class FAMeTableViewHeaderView: UIView { private lazy var subscribeView: UIButton = { var config = UIButton.Configuration.plain() - config.attributedTitle = AttributedString("Subscribe".localized, attributes: AttributeContainer([ + config.attributedTitle = AttributedString("fableon_subscribe".localized, attributes: AttributeContainer([ .font : UIFont.font(ofSize: 14, weight: .bold), .foregroundColor : UIColor._333333 ])) diff --git a/Fableon/Object/Class/Me/V/FASettingFooterView.swift b/Fableon/Object/Class/Me/V/FASettingFooterView.swift index 33bba15..b603748 100644 --- a/Fableon/Object/Class/Me/V/FASettingFooterView.swift +++ b/Fableon/Object/Class/Me/V/FASettingFooterView.swift @@ -13,7 +13,7 @@ class FASettingFooterView: UIView { private lazy var logoutButton: UIButton = { let button = FAGradientButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in guard let self = self else { return } - FALogin.manager.logout(completer: nil) + self.handleLogoutButton() })) button.layer.cornerRadius = 24 button.layer.masksToBounds = true @@ -21,7 +21,7 @@ class FASettingFooterView: UIView { button.fa_locations = [0, 1] button.fa_startPoint = .init(x: 0, y: 0.5) button.fa_endPoint = .init(x: 1, y: 0.5) - button.setTitle("Log out".localized, for: .normal) + button.setTitle("fableon_logout".localized, for: .normal) button.setTitleColor(._000000, for: .normal) button.titleLabel?.font = .font(ofSize: 18, weight: .semibold) return button @@ -43,6 +43,16 @@ class FASettingFooterView: UIView { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + private func handleLogoutButton() { + + + let view = FALogoutAlert() + view.clickHighlightButton = { + FALogin.manager.logout(completer: nil) + } + view.show() + } } diff --git a/Fableon/Object/Class/MyShort/C/FACollectViewController.swift b/Fableon/Object/Class/MyShort/C/FACollectViewController.swift index 30230d4..659b38a 100644 --- a/Fableon/Object/Class/MyShort/C/FACollectViewController.swift +++ b/Fableon/Object/Class/MyShort/C/FACollectViewController.swift @@ -70,7 +70,7 @@ class FACollectViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() self.edgesForExtendedLayout = .top - self.title = "Collect".localized + self.title = "fableon_collect".localized self.navigationItem.rightBarButtonItems = [historyButton, spaceButton, editBarButton] diff --git a/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift b/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift index 0d8dfae..cc5498b 100644 --- a/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift +++ b/Fableon/Object/Class/MyShort/C/FAHistoryViewController.swift @@ -39,7 +39,7 @@ class FAHistoryViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "History".localized + self.title = "fableon_history".localized self.edgesForExtendedLayout = .top fa_setupLayout() diff --git a/Fableon/Object/Class/MyShort/V/FACollectCell.swift b/Fableon/Object/Class/MyShort/V/FACollectCell.swift index 1fbe949..703e793 100644 --- a/Fableon/Object/Class/MyShort/V/FACollectCell.swift +++ b/Fableon/Object/Class/MyShort/V/FACollectCell.swift @@ -16,7 +16,7 @@ class FACollectCell: UICollectionViewCell { didSet { nameLabel.text = model?.name coverImageView.fa_setImage(model?.image_url) - epLabel.text = "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") } } diff --git a/Fableon/Object/Class/MyShort/V/FAHistoryCell.swift b/Fableon/Object/Class/MyShort/V/FAHistoryCell.swift index 612c0b8..625cfe0 100644 --- a/Fableon/Object/Class/MyShort/V/FAHistoryCell.swift +++ b/Fableon/Object/Class/MyShort/V/FAHistoryCell.swift @@ -13,7 +13,7 @@ class FAHistoryCell: UICollectionViewCell { didSet { coverImageView.fa_setImage(model?.image_url) nameLabel.text = model?.name - epLabel.text = "Ep.##".localizedReplace(text: model?.current_episode) + "/" + "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + epLabel.text = "fableon_episode_set".localizedReplace(text: model?.current_episode) + "/" + "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") } } diff --git a/Fableon/Object/Class/Player/M/FAShortPlayModel.swift b/Fableon/Object/Class/Player/M/FAShortPlayModel.swift index 325b469..db6af31 100644 --- a/Fableon/Object/Class/Player/M/FAShortPlayModel.swift +++ b/Fableon/Object/Class/Player/M/FAShortPlayModel.swift @@ -25,6 +25,7 @@ class FAShortPlayModel: NSObject, Identifiable, SmartCodable { var short_play_id: String? var short_play_video_id: String? var video_info: FAVideoInfoModel? + var video_url: String? @SmartIgnored var cellHeight: CGFloat = 0 diff --git a/Fableon/Object/Class/Player/V/FADetailRecommendCell.swift b/Fableon/Object/Class/Player/V/FADetailRecommendCell.swift new file mode 100644 index 0000000..4eed2eb --- /dev/null +++ b/Fableon/Object/Class/Player/V/FADetailRecommendCell.swift @@ -0,0 +1,57 @@ +// +// FADetailRecommendCell.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/1. +// + +import UIKit +import FSPagerView +import JXPlayer + +class FADetailRecommendCell: FSPagerViewCell { + + var model: FAShortPlayModel? { + didSet { + player.coverImageView?.fa_setImage(model?.image_url) + player.setPlayUrl(url: model?.video_url ?? "") + } + } + + private lazy var player: JXPlayer = { + let player = JXPlayer(controlView: nil) + player.playerView = self.playerView + return player + }() + + private lazy var playerView: UIView = { + let view = UIView() + view.isUserInteractionEnabled = false + return view + }() + + + + override init(frame: CGRect) { + super.init(frame: frame) + + addSubview(playerView) + + playerView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } + + @MainActor required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func play() { + self.player.start() + } + + func pause() { + self.player.pause() + } + +} diff --git a/Fableon/Object/Class/Player/V/FADetailRecommendView.swift b/Fableon/Object/Class/Player/V/FADetailRecommendView.swift new file mode 100644 index 0000000..e2f841c --- /dev/null +++ b/Fableon/Object/Class/Player/V/FADetailRecommendView.swift @@ -0,0 +1,160 @@ +// +// FADetailRecommendView.swift +// Fableon +// +// Created by 湖北秦九 on 2025/10/31. +// + +import UIKit +import FSPagerView + +class FADetailRecommendView: FABaseAlert { + + var clickCloseButton: (() -> Void)? + var didSelectedVideo: ((_ model: FAShortPlayModel) -> Void)? + + var dataArr: [FAShortPlayModel] = [] { + didSet { + self.pagerView.reloadData() + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in + self?.updateCurrentData() + } + } + } + + private weak var currentCell: FADetailRecommendCell? { + didSet { + oldValue?.pause() + + currentCell?.play() + } + } + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 18, weight: .init(900)) + label.textColor = .FFFFFF + label.text = "fableon_recommend_for_you".localized + return label + }() + + private lazy var bgView: UIImageView = { + let view = UIImageView(image: UIImage(named: "bj")) + view.isUserInteractionEnabled = true + return view + }() + + private lazy var cancelButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "close_icon_04"), for: .normal) + button.addTarget(self, action: #selector(handleCancelButton), for: .touchUpInside) + return button + }() + + private lazy var pagerView: FSPagerView = { + let transformer = FSPagerViewTransformer(type: .crossFading) + + let view = FSPagerView() + view.layer.cornerRadius = 6 + view.layer.masksToBounds = true + view.itemSize = .init(width: 178, height: 267) + view.transformer = transformer + view.delegate = self + view.dataSource = self + view.isInfinite = true + view.interitemSpacing = 0 + view.register(FADetailRecommendCell.self, forCellWithReuseIdentifier: "cell") + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + contentWidth = UIScreen.width + self.closeButton.isHidden = true + + self.contentView.backgroundColor = .clear + self.contentView.layer.cornerRadius = 0 + self.contentView.layer.masksToBounds = false + + fa_setupLayout() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + + @objc private func handleCancelButton() { + + self.dismiss() + self.clickCloseButton?() + } + + ///更新当前数据 + private func updateCurrentData() { + guard let cell = self.pagerView.cellForItem(at: self.pagerView.currentIndex) as? FADetailRecommendCell else { return } + + self.currentCell = cell +// let model = cell.model +// self.videoNameLabel.text = model?.name + } + +} + +extension FADetailRecommendView { + + private func fa_setupLayout() { + contentView.addSubview(titleLabel) + contentView.addSubview(bgView) + contentView.addSubview(cancelButton) + bgView.addSubview(pagerView) + + titleLabel.snp.makeConstraints { make in + make.top.equalToSuperview() + make.centerX.equalToSuperview() + } + + bgView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalToSuperview().offset(-25) + make.bottom.equalToSuperview() + } + + cancelButton.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.bottom.equalTo(bgView).offset(-10) + } + + pagerView.snp.makeConstraints { make in + make.width.equalTo(178) + make.height.equalTo(267) + make.center.equalToSuperview() + } + } + +} + +//MARK: FSPagerViewDelegate FSPagerViewDataSource +extension FADetailRecommendView: FSPagerViewDelegate, FSPagerViewDataSource { + + func pagerView(_ pagerView: FSPagerView, cellForItemAt index: Int) -> FSPagerViewCell { + let cell = pagerView.dequeueReusableCell(withReuseIdentifier: "cell", at: index) as! FADetailRecommendCell + cell.model = self.dataArr[index] + return cell + } + + func numberOfItems(in pagerView: FSPagerView) -> Int { + return self.dataArr.count + } + + func pagerView(_ pagerView: FSPagerView, didSelectItemAt index: Int) { + didSelectedVideo?(self.dataArr[index]) + self.dismiss() + } + + func pagerViewDidEndDecelerating(_ pagerView: FSPagerView) { + self.updateCurrentData() + } + +} diff --git a/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift b/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift index 98a494a..da0ab27 100644 --- a/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift +++ b/Fableon/Object/Class/Player/V/FAOldVideoRechargeView.swift @@ -106,13 +106,13 @@ class FAOldVideoRechargeView: FAPanModalContentView { private lazy var videoCoinsView: FAOldVideoRechargeView.CoinsView = { let view = FAOldVideoRechargeView.CoinsView() - view.title = "Price".localized + ":" + view.title = "fableo_price".localized + ":" return view }() private lazy var totalCoinsView: FAOldVideoRechargeView.CoinsView = { let view = FAOldVideoRechargeView.CoinsView() - view.title = "Balance".localized + ":" + view.title = "fableo_balance".localized + ":" view.coins = FALogin.manager.userInfo?.totalCoins ?? 0 return view }() diff --git a/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift b/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift index 445b90f..ba84531 100644 --- a/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift +++ b/Fableon/Object/Class/Player/V/FAPlayerDetailControlView.swift @@ -159,7 +159,7 @@ class FAPlayerDetailControlView: JXPlayerListControlView { private func updateEp() { let model = self.model as? FAVideoInfoModel - let text = "Ep.##".localizedReplace(text: model?.episode ?? "") + "/" + "Ep.##".localizedReplace(text: "\(shortModel?.episode_total ?? 0)") + let text = "fableon_episode_set".localizedReplace(text: model?.episode ?? "") + "/" + "fableon_episode_set".localizedReplace(text: "\(shortModel?.episode_total ?? 0)") var view = FAPlayerEpUIButton(text: text) view.clickHandle = { [weak self] in self?.fa_viewModel?.onEpSelectorView() diff --git a/Fableon/Object/Class/Player/V/FAVideoLockView.swift b/Fableon/Object/Class/Player/V/FAVideoLockView.swift index e8f1ae9..9d04aed 100644 --- a/Fableon/Object/Class/Player/V/FAVideoLockView.swift +++ b/Fableon/Object/Class/Player/V/FAVideoLockView.swift @@ -41,7 +41,7 @@ class FAVideoLockView: UIView { if hasLastEpisodeUnlocked { button.configuration?.attributedTitle = .init("video_lock_tip_text".localized, attributes: attributeContainer) } else { - button.configuration?.attributedTitle = .init("Unlocking costs ## coins".localizedReplace(text: "\(videoInfo?.coins ?? 0)"), attributes: attributeContainer) + button.configuration?.attributedTitle = .init("fableon_unlocking_coins_notice".localizedReplace(text: "\(videoInfo?.coins ?? 0)"), attributes: attributeContainer) } } button.layer.cornerRadius = 26 diff --git a/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift b/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift index 0d9568b..370cdcb 100644 --- a/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift +++ b/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift @@ -12,7 +12,14 @@ import FDFullscreenPopGesture class FAPlayerDetailViewController: JXPlayerListViewController { - var shortPlayId: String? + var shortPlayId: String? { + set { + self.fa_viewModel.shortPlayId = newValue ?? "" + } + get { + return self.fa_viewModel.shortPlayId + } + } var activityId: String? override var ViewModelClass: JXPlayerListViewModel.Type { @@ -27,7 +34,7 @@ class FAPlayerDetailViewController: JXPlayerListViewController { let button = UIButton(type: .custom) button.setImage(UIImage(named: "Frame 3011"), for: .normal) button.addAction(UIAction(handler: { [weak self] _ in - self?.navigationController?.popViewController(animated: true) + self?.handleBackButton() }), for: .touchUpInside) return button }() @@ -44,7 +51,7 @@ class FAPlayerDetailViewController: JXPlayerListViewController { super.viewDidLoad() self.fd_interactivePopDisabled = true view.backgroundColor = .init(named: .color_000000) - self.fa_viewModel.shortPlayId = shortPlayId ?? "" +// self.fa_viewModel.shortPlayId = shortPlayId ?? "" self.register(FAPlayerDetailCell.self, forCellWithReuseIdentifier: "FAPlayerDetailCell") self.delegate = self self.dataSource = self @@ -53,6 +60,8 @@ class FAPlayerDetailViewController: JXPlayerListViewController { requestDetailList() fa_setupLayout() + + self.fa_viewModel.requestRecommandData() } override func viewWillAppear(_ animated: Bool) { @@ -101,6 +110,26 @@ class FAPlayerDetailViewController: JXPlayerListViewController { } } } + + @objc private func handleBackButton() { + self.pause() + + if !self.fa_viewModel.recommandDataArr.isEmpty { + let view = FADetailRecommendView() + view.dataArr = self.fa_viewModel.recommandDataArr + view.clickCloseButton = { [weak self] in + self?.handleNavigationBack() + } + view.didSelectedVideo = { [weak self] model in + guard let self = self else { return } + self.shortPlayId = model.short_play_id + self.requestDetailList() + } + view.show(in: FATool.keyWindow) + } + +// self.handleNavigationBack() + } } extension FAPlayerDetailViewController { diff --git a/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift b/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift index 0d1bde7..78f8337 100644 --- a/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift +++ b/Fableon/Object/Class/Player/VM/FAShortDetailViewModel.swift @@ -13,6 +13,8 @@ class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject { private(set) var dataArr: [FAShortDetailModel] = [] + private(set) var recommandDataArr: [FAShortPlayModel] = [] + var shortPlayId: String = "" ///上一次上报播放时长的节点 @@ -242,4 +244,13 @@ extension FAShortDetailViewModel { } } + ///请求推荐数据 + func requestRecommandData() { + FAAPI.requestDetailRecommendVideo { [weak self] list in + guard let self = self else { return } + guard let list = list else { return } + self.recommandDataArr = list + } + } + } diff --git a/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift b/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift index 5d037ce..5a8084d 100644 --- a/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift +++ b/Fableon/Object/Class/Recommend/V/FARecommendPlayerControlView.swift @@ -159,7 +159,7 @@ class FARecommendPlayerControlView: JXPlayerListControlView { let videoInfo = model?.video_info - let text = "Ep.##".localizedReplace(text: videoInfo?.episode ?? "") + "/" + "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + let text = "fableon_episode_set".localizedReplace(text: videoInfo?.episode ?? "") + "/" + "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") var view = FAPlayerEpUIButton(text: text) view.clickHandle = { [weak self] in self?.fa_viewModel?.pushPlayerDetail(self?.shortModel) diff --git a/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift b/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift index 099fbbc..895c2d9 100644 --- a/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift +++ b/Fableon/Object/Class/Store/C/FACoinRecordViewController.swift @@ -66,9 +66,9 @@ extension FACoinRecordViewController: UITableViewDelegate, UITableViewDataSource let model = self.dataArr[indexPath.row] let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FAOrderRecordCell if model.type == "send" { - cell.titleLabel.text = "Bonus Coins".localized + cell.titleLabel.text = "fableo_bonus_coins".localized } else { - cell.titleLabel.text = "Recharge Coins".localized + cell.titleLabel.text = "fableo_recharge_coins".localized } cell.dateLabel.text = model.created_at cell.countLabel.text = "+\(model.value ?? "0")" diff --git a/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift b/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift index 9a16466..7bf4a35 100644 --- a/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift +++ b/Fableon/Object/Class/Store/C/FAConsumptionRecordsViewController.swift @@ -33,7 +33,7 @@ class FAConsumptionRecordsViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Consumption Records".localized + self.title = "fableo_consumption_records".localized fa_setupLayout() diff --git a/Fableon/Object/Class/Store/C/FAOrderRecordsViewController.swift b/Fableon/Object/Class/Store/C/FAOrderRecordsViewController.swift index 6c7632f..2a7e4f7 100644 --- a/Fableon/Object/Class/Store/C/FAOrderRecordsViewController.swift +++ b/Fableon/Object/Class/Store/C/FAOrderRecordsViewController.swift @@ -10,7 +10,7 @@ import JXSegmentedView class FAOrderRecordsViewController: FAViewController { - private lazy var titles = ["Coin Record".localized, "VIP Record".localized] + private lazy var titles = ["fableo_coin_record".localized, "fableo_VIP_Record".localized] private lazy var viewControllers = [FACoinRecordViewController(), FAVipRecordViewController()] private lazy var segmentedDataSource: JXSegmentedTitleDataSource = { @@ -56,7 +56,7 @@ class FAOrderRecordsViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Order Records".localized + self.title = "fableo_order_records".localized fa_setupLayout() } diff --git a/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift b/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift index a9a4b96..89991fa 100644 --- a/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift +++ b/Fableon/Object/Class/Store/C/FARewardCoinsViewController.swift @@ -33,7 +33,7 @@ class FARewardCoinsViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Reward coins" + self.title = "fableo_reward_coins".localized view.addSubview(tableView) diff --git a/Fableon/Object/Class/Store/C/FAStoreViewController.swift b/Fableon/Object/Class/Store/C/FAStoreViewController.swift index 0a22f9d..cfa9e16 100644 --- a/Fableon/Object/Class/Store/C/FAStoreViewController.swift +++ b/Fableon/Object/Class/Store/C/FAStoreViewController.swift @@ -88,8 +88,8 @@ class FAStoreViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "Store".localized - let barButtonItem = UIBarButtonItem(title: "Restore".localized, style: .plain, target: self, action: #selector(handleRestore)) + self.title = "fableon_store".localized + let barButtonItem = UIBarButtonItem(title: "fableo_restore".localized, style: .plain, target: self, action: #selector(handleRestore)) barButtonItem.tintColor = .FFFFFF self.navigationItem.rightBarButtonItem = barButtonItem diff --git a/Fableon/Object/Class/Store/C/FAWalletViewController.swift b/Fableon/Object/Class/Store/C/FAWalletViewController.swift index 5844b29..9ca8426 100644 --- a/Fableon/Object/Class/Store/C/FAWalletViewController.swift +++ b/Fableon/Object/Class/Store/C/FAWalletViewController.swift @@ -10,9 +10,9 @@ import UIKit class FAWalletViewController: FAViewController { private lazy var dataArr: [FAMeItemModel] = [ - FAMeItemModel(type: .consumptionRecords, name: "Consumption Records".localized), - FAMeItemModel(type: .purchaseRecords, name: "Purchase Records".localized), - FAMeItemModel(type: .rewardCoins, name: "Reward Coins".localized), + FAMeItemModel(type: .consumptionRecords, name: "fableo_consumption_records".localized), + FAMeItemModel(type: .purchaseRecords, name: "fableo_purchase_records".localized), + FAMeItemModel(type: .rewardCoins, name: "fableo_reward_coins".localized), ] private lazy var tableView: FATableView = { @@ -38,7 +38,7 @@ class FAWalletViewController: FAViewController { override func viewDidLoad() { super.viewDidLoad() - self.title = "My Wallet".localized + self.title = "fableo_my_wallet".localized NotificationCenter.default.addObserver(self, selector: #selector(userInfoUpdateNotification), name: FALogin.userInfoUpdateNotification, object: nil) fa_setupLayout() diff --git a/Fableon/Object/Class/Store/M/FAPayDateModel.swift b/Fableon/Object/Class/Store/M/FAPayDateModel.swift index bbaf865..797fc81 100644 --- a/Fableon/Object/Class/Store/M/FAPayDateModel.swift +++ b/Fableon/Object/Class/Store/M/FAPayDateModel.swift @@ -116,16 +116,16 @@ class FAPayItem: NSObject, SmartCodable { func getTimeString() -> String? { switch self.vip_type_key { case .week: - return "week".localized + return "w_complex".localized case .month: - return "month".localized + return "m_complex".localized case .quarter: - return "quarter".localized + return "q_complex".localized case .year: - return "year".localized + return "Y_complex".localized default: return nil @@ -135,16 +135,16 @@ class FAPayItem: NSObject, SmartCodable { func getVipTitle() -> String? { switch self.vip_type_key { case .week: - return "Weekly VIP".localized + return "fableon_weekly_vip".localized case .month: - return "Monthly VIP".localized + return "fableon_monthly_vip".localized case .quarter: - return "Quarterly VIP".localized + return "fableon_quarterly_vip".localized case .year: - return "Yearly VIP".localized + return "fableon_yearly_vip".localized default: return nil diff --git a/Fableon/Object/Class/Store/V/FACoinPackConfirmItem1View.swift b/Fableon/Object/Class/Store/V/FACoinPackConfirmItem1View.swift index f86deac..da4e233 100644 --- a/Fableon/Object/Class/Store/V/FACoinPackConfirmItem1View.swift +++ b/Fableon/Object/Class/Store/V/FACoinPackConfirmItem1View.swift @@ -11,10 +11,10 @@ class FACoinPackConfirmItem1View: FACoinPackConfirmItemView { override init(frame: CGRect) { super.init(frame: frame) - titleLabel.text = "Bonus You Get".localized + titleLabel.text = "fableo_bonus_you_get".localized - let view1 = getItemView(image: UIImage(named: "Group 2072750450"), text: "Weekly Refill Package".localized) - let view2 = getItemView(image: UIImage(named: "Group 2072750451"), text: "Dailu Bonuses".localized) + let view1 = getItemView(image: UIImage(named: "Group 2072750450"), text: "fableo_weekly_refill_package".localized) + let view2 = getItemView(image: UIImage(named: "Group 2072750451"), text: "fableo_dailu_bonuses".localized) addSubview(view1) addSubview(view2) diff --git a/Fableon/Object/Class/Store/V/FACoinPackConfirmView.swift b/Fableon/Object/Class/Store/V/FACoinPackConfirmView.swift index 7f68890..6a3cbb7 100644 --- a/Fableon/Object/Class/Store/V/FACoinPackConfirmView.swift +++ b/Fableon/Object/Class/Store/V/FACoinPackConfirmView.swift @@ -47,7 +47,7 @@ class FACoinPackConfirmView: FAPanModalContentView { label.textColors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor] label.textStartPoint = .init(x: 0, y: 0.5) label.textEndPoint = .init(x: 1, y: 0.5) - label.text = "What You Get".localized + label.text = "fableo_what_you_get".localized return label }() @@ -105,7 +105,7 @@ class FACoinPackConfirmView: FAPanModalContentView { button.fa_locations = [0, 1] button.fa_startPoint = .init(x: 0, y: 0.5) button.fa_endPoint = .init(x: 1, y: 0.5) - button.setTitle("Continue".localized, for: .normal) + button.setTitle("fableo_continue".localized, for: .normal) button.setTitleColor(.FFFFFF, for: .normal) button.titleLabel?.font = .font(ofSize: 14, weight: .bold) return button diff --git a/Fableon/Object/Class/Store/V/FAConsumptionRecordsCell.swift b/Fableon/Object/Class/Store/V/FAConsumptionRecordsCell.swift index c1a7760..9f8547e 100644 --- a/Fableon/Object/Class/Store/V/FAConsumptionRecordsCell.swift +++ b/Fableon/Object/Class/Store/V/FAConsumptionRecordsCell.swift @@ -11,10 +11,10 @@ class FAConsumptionRecordsCell: FATableViewCell { var model: FABuyRecordsModel? { didSet { - titleLabel.text = "Purchase Single Episode".localized - subtitleLabel.text = "Ep.##".localizedReplace(text: "\(model?.episode ?? "")") + " " + "\(model?.name ?? "")" + titleLabel.text = "fableo_single_episode".localized + subtitleLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode ?? "")") + " " + "\(model?.name ?? "")" dateLabel.text = model?.created_at - coinsLabel.text = "-\(model?.coins ?? 0)" + "Coins".localized + coinsLabel.text = "-\(model?.coins ?? 0)" + "fableon_coins".localized } } diff --git a/Fableon/Object/Class/Store/V/FARewardCoinsCell.swift b/Fableon/Object/Class/Store/V/FARewardCoinsCell.swift index 00b2230..4d0ba60 100644 --- a/Fableon/Object/Class/Store/V/FARewardCoinsCell.swift +++ b/Fableon/Object/Class/Store/V/FARewardCoinsCell.swift @@ -20,7 +20,7 @@ class FARewardCoinsCell: FATableViewCell { expiresIconImageView.isHidden = false expiresLabel.isHidden = false expiredLabel.isHidden = true - expiresLabel.text = "Expires in ## days".localizedReplace(text: model?.diff_datetime ?? "") + expiresLabel.text = "fableo_expires_#_days".localizedReplace(text: model?.diff_datetime ?? "") } else { expiresIconImageView.isHidden = true expiresLabel.isHidden = true diff --git a/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift b/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift index 70f9e6b..942193c 100644 --- a/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift +++ b/Fableon/Object/Class/Store/V/FAStoreCoinsBigCell.swift @@ -31,7 +31,7 @@ class FAStoreCoinsBigCell: FAStoreCoinsCell { if sendCoins > 0 { sendCoinsLabel.isHidden = false sendCoinsRatioImageView.isHidden = false - sendCoinsLabel.text = "+\(sendCoins) " + "Coins".localized + sendCoinsLabel.text = "+\(sendCoins) " + "fableon_coins".localized let ratio = String(format: "%.0f", CGFloat(sendCoins) / CGFloat(coins) * 100) sendCoinsRatioLabel.text = "+\(ratio)%" diff --git a/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift b/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift index 5c01335..d74654c 100644 --- a/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift +++ b/Fableon/Object/Class/Store/V/FAStoreCoinsPackCell.swift @@ -51,7 +51,7 @@ class FAStoreCoinsPackCell: FAStoreCoinsCell { let label = UILabel() label.font = .font(ofSize: 14, weight: .init(700)) label.textColor = .FFFFFF - label.text = "Weekly Refill".localized + label.text = "fableo_weekly_refill".localized return label }() diff --git a/Fableon/Object/Class/Store/V/FAStoreCoinsSmallCell.swift b/Fableon/Object/Class/Store/V/FAStoreCoinsSmallCell.swift index 52fe138..56fb695 100644 --- a/Fableon/Object/Class/Store/V/FAStoreCoinsSmallCell.swift +++ b/Fableon/Object/Class/Store/V/FAStoreCoinsSmallCell.swift @@ -27,7 +27,7 @@ class FAStoreCoinsSmallCell: FAStoreCoinsCell { if sendCoins > 0 { sendCoinsLabel.isHidden = false sendCoinsRatioView.isHidden = false - sendCoinsLabel.text = "+\(sendCoins) " + "Coins".localized + sendCoinsLabel.text = "+\(sendCoins) " + "fableon_coins".localized let ratio = String(format: "%.0f", CGFloat(sendCoins) / CGFloat(coins) * 100) sendCoinsRatioLabel.text = "+\(ratio)%" diff --git a/Fableon/Object/Class/Store/V/FAStoreVipCell.swift b/Fableon/Object/Class/Store/V/FAStoreVipCell.swift index d58b61f..9d30eb9 100644 --- a/Fableon/Object/Class/Store/V/FAStoreVipCell.swift +++ b/Fableon/Object/Class/Store/V/FAStoreVipCell.swift @@ -17,7 +17,7 @@ class FAStoreVipCell: UICollectionViewCell { // coinTimeLabel.text = item?.auto_sub if let coins = item?.send_coins, coins > 0 { - sendCoinLabel.text = "+\("extra".localized) \(coins)" + sendCoinLabel.text = "+\("fableo_extra".localized) \(coins)" sendCoinLabel.isHidden = false coinImageView.isHidden = false } else { diff --git a/Fableon/Object/Class/Store/V/FAWalletHeaderView.swift b/Fableon/Object/Class/Store/V/FAWalletHeaderView.swift index e0bae7a..7ff9115 100644 --- a/Fableon/Object/Class/Store/V/FAWalletHeaderView.swift +++ b/Fableon/Object/Class/Store/V/FAWalletHeaderView.swift @@ -36,7 +36,7 @@ class FAWalletHeaderView: UIView { button.fa_locations = [0, 1] button.fa_startPoint = .init(x: 0, y: 0.5) button.fa_endPoint = .init(x: 1, y: 0.5) - button.setTitle("Store".localized, for: .normal) + button.setTitle("fableon_store".localized, for: .normal) button.setTitleColor(._000000, for: .normal) button.titleLabel?.font = .font(ofSize: 18, weight: .bold) return button @@ -52,7 +52,7 @@ class FAWalletHeaderView: UIView { var config = UIButton.Configuration.plain() config.image = UIImage(named: "coins_icon_02") config.imagePadding = 11 - config.attributedTitle = AttributedString("Coins".localized, attributes: AttributeContainer([ + config.attributedTitle = AttributedString("fableon_coins".localized, attributes: AttributeContainer([ .font : UIFont.font(ofSize: 10, weight: .bold), .foregroundColor : UIColor.F_7_F_497 ])) @@ -77,7 +77,7 @@ class FAWalletHeaderView: UIView { config.imagePadding = 11 config.imagePlacement = .trailing config.titleAlignment = .leading - config.attributedTitle = AttributedString("Bonus".localized, attributes: AttributeContainer([ + config.attributedTitle = AttributedString("fableon_bonus".localized, attributes: AttributeContainer([ .font : UIFont.font(ofSize: 10, weight: .bold), .foregroundColor : UIColor.F_7_F_497 ])) diff --git a/Fableon/Object/Libs/Alert/FAApnsAlert.swift b/Fableon/Object/Libs/Alert/FAApnsAlert.swift index 5939040..f6273b0 100644 --- a/Fableon/Object/Libs/Alert/FAApnsAlert.swift +++ b/Fableon/Object/Libs/Alert/FAApnsAlert.swift @@ -37,7 +37,7 @@ class FAApnsAlert: FABaseAlert { button.layer.masksToBounds = true button.layer.borderWidth = 1 button.layer.borderColor = UIColor.FFFFFF.cgColor - button.setTitle("Later".localized, for: .normal) + button.setTitle("fableon_open_notification_later".localized, for: .normal) button.setTitleColor(.FFFFFF, for: .normal) button.titleLabel?.font = .font(ofSize: 14, weight: .semibold) button.addTarget(self, action: #selector(dismiss), for: .touchUpInside) @@ -46,7 +46,7 @@ class FAApnsAlert: FABaseAlert { override init(frame: CGRect) { super.init(frame: frame) - highlightButton.setTitle("Open".localized, for: .normal) + highlightButton.setTitle("fableon_open".localized, for: .normal) fa_setupLayout() } diff --git a/Fableon/Object/Libs/Alert/FACoinsPackAlert.swift b/Fableon/Object/Libs/Alert/FACoinsPackAlert.swift index 3bed598..29ba4b8 100644 --- a/Fableon/Object/Libs/Alert/FACoinsPackAlert.swift +++ b/Fableon/Object/Libs/Alert/FACoinsPackAlert.swift @@ -50,7 +50,7 @@ class FACoinsPackAlert: FABaseAlert { button.layer.masksToBounds = true button.layer.borderColor = UIColor._777777.cgColor button.layer.borderWidth = 1 - button.setTitle("Later".localized, for: .normal) + button.setTitle("fableon_open_notification_later".localized, for: .normal) button.setTitleColor(._777777, for: .normal) button.titleLabel?.font = .font(ofSize: 14, weight: .bold) button.addTarget(self, action: #selector(dismiss), for: .touchUpInside) @@ -60,7 +60,7 @@ class FACoinsPackAlert: FABaseAlert { override init(frame: CGRect) { super.init(frame: frame) - self.highlightButton.setTitle("Claim Now".localized, for: .normal) + self.highlightButton.setTitle("fableon_claim_now".localized, for: .normal) self.highlightButton.setTitleColor(.FFFFFF, for: .normal) self.highlightButton.fa_colors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor] self.highlightButton.layer.cornerRadius = 24 diff --git a/Fableon/Object/Libs/Alert/FALogoutAlert.swift b/Fableon/Object/Libs/Alert/FALogoutAlert.swift new file mode 100644 index 0000000..b6b2289 --- /dev/null +++ b/Fableon/Object/Libs/Alert/FALogoutAlert.swift @@ -0,0 +1,92 @@ +// +// FALogoutAlert.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/1. +// + +import UIKit + +class FALogoutAlert: FABaseAlert { + + private lazy var imageView = UIImageView(image: UIImage(named: "退出登录")) + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 18, weight: .semibold) + label.textColor = .FFFFFF + label.text = "logout_alert_title".localized + label.numberOfLines = 0 + label.textAlignment = .center + return label + }() + + private lazy var textLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 12, weight: .regular) + label.textColor = .FFFFFF + label.numberOfLines = 0 + label.textAlignment = .center + label.text = "logout_alert_text".localized + return label + }() + + private lazy var cancelButton: UIButton = { + let button = UIButton(type: .custom) + button.layer.cornerRadius = 18 + button.layer.masksToBounds = true + button.layer.borderWidth = 1 + button.layer.borderColor = UIColor.FFFFFF.cgColor + button.setTitle("fableon_cancel".localized, for: .normal) + button.setTitleColor(.FFFFFF, for: .normal) + button.titleLabel?.font = .font(ofSize: 14, weight: .medium) + button.addTarget(self, action: #selector(dismiss), for: .touchUpInside) + return button + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + highlightButton.setTitle("fableon_logout".localized, for: .normal) + + containerView.addSubview(imageView) + contentView.addSubview(titleLabel) + contentView.addSubview(textLabel) + contentView.addSubview(cancelButton) + contentView.addSubview(highlightButton) + + imageView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalToSuperview().offset(-62) + } + + titleLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(imageView.snp.bottom).offset(10) + make.right.lessThanOrEqualToSuperview().offset(-10) + } + + textLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.right.lessThanOrEqualToSuperview().offset(-20) + make.top.equalTo(titleLabel.snp.bottom).offset(12) + } + + cancelButton.snp.makeConstraints { make in + make.left.equalToSuperview().offset(24) + make.top.equalTo(textLabel.snp.bottom).offset(21) + make.bottom.equalTo(-20) + make.height.equalTo(36) + } + + highlightButton.snp.makeConstraints { make in + make.left.equalTo(cancelButton.snp.right).offset(11) + make.right.equalToSuperview().offset(-24) + make.width.height.top.equalTo(cancelButton) + } + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/Fableon/Object/Libs/Alert/FARemoveCollectAlert.swift b/Fableon/Object/Libs/Alert/FARemoveCollectAlert.swift index a23141f..c6a3ff3 100644 --- a/Fableon/Object/Libs/Alert/FARemoveCollectAlert.swift +++ b/Fableon/Object/Libs/Alert/FARemoveCollectAlert.swift @@ -38,7 +38,7 @@ class FARemoveCollectAlert: FABaseAlert { button.layer.masksToBounds = true button.layer.borderWidth = 1 button.layer.borderColor = UIColor.FFFFFF.cgColor - button.setTitle("Cancel".localized, for: .normal) + button.setTitle("fableon_cancel".localized, for: .normal) button.setTitleColor(.FFFFFF, for: .normal) button.titleLabel?.font = .font(ofSize: 14, weight: .medium) button.addTarget(self, action: #selector(dismiss), for: .touchUpInside) @@ -48,7 +48,7 @@ class FARemoveCollectAlert: FABaseAlert { override init(frame: CGRect) { super.init(frame: frame) - highlightButton.setTitle("Remove".localized, for: .normal) + highlightButton.setTitle("fableon_remove".localized, for: .normal) containerView.addSubview(imageView) contentView.addSubview(titleLabel) diff --git a/Fableon/Object/Libs/Alert/FAUpdatesAlert.swift b/Fableon/Object/Libs/Alert/FAUpdatesAlert.swift new file mode 100644 index 0000000..550a685 --- /dev/null +++ b/Fableon/Object/Libs/Alert/FAUpdatesAlert.swift @@ -0,0 +1,127 @@ +// +// FAUpdatesAlert.swift +// Fableon +// +// Created by 湖北秦九 on 2025/10/31. +// + +import UIKit + +class FAUpdatesAlert: FABaseAlert { + + var model: FAVersionUpdateModel? { + didSet { + textLabel.text = model?.des + + versionLabel.text = "v\(model?.version_name ?? "")" + closeButton.isHidden = model?.force ?? false + + } + } + + private lazy var imageView = UIImageView(image: UIImage(named: "__New")) + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 18, weight: .semibold) + label.textColor = .FFFFFF + label.textAlignment = .center + label.numberOfLines = 0 + label.text = "updates_alert_title".localized + return label + }() + + private lazy var textLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 12, weight: .regular) + label.textColor = .FFFFFF + label.numberOfLines = 0 + return label + }() + + private lazy var versionView: UIView = { + let view = UIView() + view.backgroundColor = .E_4275_D + view.layer.cornerRadius = 9 + view.layer.masksToBounds = true + return view + }() + + private lazy var versionLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 12, weight: .regular) + label.textColor = .FFFFFF + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + highlightButton.layer.cornerRadius = 18 + highlightButton.setTitle("fableon_update_now", for: .normal) + fa_setupLayout() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func handleHighlightButton() { +// if self.model?.force != true { +// super.handleHighlightButton() +// } + guard let url = URL(string: "https://apps.apple.com/app/id6754154359") else { return } + let application = UIApplication.shared + if application.canOpenURL(url) { + application.open(url) + } + } +} + +extension FAUpdatesAlert { + + private func fa_setupLayout() { + containerView.addSubview(imageView) + contentView.addSubview(titleLabel) + contentView.addSubview(textLabel) + contentView.addSubview(highlightButton) + contentView.addSubview(versionView) + versionView.addSubview(versionLabel) + + imageView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalToSuperview().offset(-100) + } + + titleLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.right.lessThanOrEqualToSuperview().offset(-20) + make.top.equalTo(imageView.snp.bottom).offset(20) + } + + versionView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(titleLabel.snp.bottom).offset(10) + make.height.equalTo(18) + } + + versionLabel.snp.makeConstraints { make in + make.center.equalToSuperview() + make.left.equalToSuperview().offset(7) + } + + textLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.right.lessThanOrEqualToSuperview().offset(-20) +// make.top.equalTo(titleLabel.snp.bottom).offset(15) + make.top.equalTo(versionView.snp.bottom).offset(10) + } + + highlightButton.snp.makeConstraints { make in + make.left.equalToSuperview().offset(24) + make.centerX.equalToSuperview() + make.top.equalTo(textLabel.snp.bottom).offset(20) + make.bottom.equalToSuperview().offset(-20) + make.height.equalTo(36) + } + } + +} diff --git a/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift b/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift index 4bd9f8c..ac566c5 100644 --- a/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift +++ b/Fableon/Object/Libs/Alert/FAVipRetainAlert.swift @@ -27,7 +27,7 @@ class FAVipRetainAlert: FABaseAlert { view.dotColor = ._20_A_1_FF view.textColors = [UIColor._53_A_2_F_1.cgColor, UIColor.C_5_DDF_5.cgColor] view.font = .font(ofSize: 24, weight: .init(900)) - view.text = "Weekly Refill".localized.uppercased() + view.text = "fableo_weekly_refill".localized.uppercased() return view }() @@ -66,7 +66,7 @@ class FAVipRetainAlert: FABaseAlert { button.fa_locations = [0, 1] button.fa_startPoint = .init(x: 0, y: 0.5) button.fa_endPoint = .init(x: 0.7, y: 0.5) - button.setTitle("Buy Now".localized, for: .normal) + button.setTitle("fableon_buy_now".localized, for: .normal) button.setTitleColor(.FFFFFF, for: .normal) button.titleLabel?.font = .font(ofSize: 14, weight: .bold) return button diff --git a/Fableon/Object/Libs/FAIap/FAIapManager.swift b/Fableon/Object/Libs/FAIap/FAIapManager.swift index 560c2b1..b854826 100644 --- a/Fableon/Object/Libs/FAIap/FAIapManager.swift +++ b/Fableon/Object/Libs/FAIap/FAIapManager.swift @@ -152,7 +152,7 @@ class FAIapManager { } if isLoding { - FAToast.show(text: "success".localized) + FAToast.show(text: "fableo_success".localized) } completer?(true, buyType) if buyType == .subVip { @@ -223,7 +223,7 @@ extension FAIapManager: JXIAPManagerDelegate { FALogin.manager.userInfo?.is_vip = true } - FAToast.show(text: "success".localized) + FAToast.show(text: "fableo_success".localized) self.completionHandler?(true) if buyType == .subVip { NotificationCenter.default.post(name: FAIapManager.buyVipFinishNotification, object: nil) diff --git a/Fableon/Object/Libs/FALocalized/FALanguageDataModel.swift b/Fableon/Object/Libs/FALocalized/FALanguageDataModel.swift new file mode 100644 index 0000000..28a4897 --- /dev/null +++ b/Fableon/Object/Libs/FALocalized/FALanguageDataModel.swift @@ -0,0 +1,16 @@ +// +// FALanguageDataModel.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/1. +// + +import UIKit +import SmartCodable + +struct FALanguageDataModel: SmartCodable { + + ///翻译数据 + var translates: [String : String]? + +} diff --git a/Fableon/Object/Libs/FALocalized/FALanguageManager.swift b/Fableon/Object/Libs/FALocalized/FALanguageManager.swift new file mode 100644 index 0000000..f4d1324 --- /dev/null +++ b/Fableon/Object/Libs/FALocalized/FALanguageManager.swift @@ -0,0 +1,152 @@ +// +// FALanguageManager.swift +// Fableon +// +// Created by 湖北秦九 on 2025/10/15. +// + + +import UIKit + + +class FALanguageManager { + + static let manager = FALanguageManager() + + private let LanguageUserDefaultsKey = "FALanguageManager.LanguageUserDefaultsKey" + private let LanguageDataUserDefaultsKey = "FALanguageManager.LanguageDataUserDefaultsKey" + private let LanguageDataLanguageKeyUserDefaultsKey = "FALanguageManager.LanguageDataLanguageKeyUserDefaultsKey" + + + ///多语言数据 + private(set) lazy var languageData: [String : String]? = UserDefaults.standard.object(forKey: LanguageDataUserDefaultsKey) as? [String : String] + { + didSet { + UserDefaults.standard.set(languageData, forKey: LanguageDataUserDefaultsKey) + UserDefaults.standard.synchronize() + } + } + ///当前语言数据对应的key + private(set) lazy var languageDataLanguageKey: String? = UserDefaults.standard.object(forKey: LanguageDataLanguageKeyUserDefaultsKey) as? String + { + didSet { + UserDefaults.standard.set(languageDataLanguageKey, forKey: LanguageDataLanguageKeyUserDefaultsKey) + UserDefaults.standard.synchronize() + } + } + + // 获取当前语言代码(如果用户未手动设置,则返回系统语言) + var currentLanguageKey: String { + get { + var key = UserDefaults.standard.string(forKey: LanguageUserDefaultsKey) ?? Locale.preferredLanguages.first + + if key?.contains("zh-Hans") == true { + key = "zh" + } else if key?.contains("zh-Hant") == true { + key = "zh_hk" + } else { + let arr = key?.components(separatedBy: "-") + key = arr?.first + } + return key ?? "en" + } + set { + UserDefaults.standard.set(newValue, forKey: LanguageUserDefaultsKey) + UserDefaults.standard.synchronize() + } + } + + var mjLanguageKey: String { + let key = currentLanguageKey + if key == "zh" { + return "zh-Hans" + } else if key == "zh_hk" { + return "zh-Hant" + } + return key + } + + // 判断是否跟随系统 + var isFollowingSystem: Bool { + return UserDefaults.standard.string(forKey: LanguageUserDefaultsKey) == nil + } + + // 还原为系统默认语言 + func resetToSystemLanguage() { + UserDefaults.standard.removeObject(forKey: LanguageUserDefaultsKey) + UserDefaults.standard.synchronize() + } + + //切换语言 + func switchLanguage(_ key: String, completer: ((_ finish: Bool) -> Void)?) { + FAHUD.show() + + FAAPI.requestLanguageDataList(key: key) { [weak self] model in + FAHUD.dismiss() + guard let self = self else { return } + guard let list = model?.translates, list.count > 0 else { + completer?(false) + return + } + currentLanguageKey = key + languageDataLanguageKey = key + languageData = list + completer?(true) + NotificationCenter.default.post(name: FALanguageManager.languageDidChange, object: nil) + } + } + + //更新本地语言数据 + func updateLanguageData(completer: ((_ finish: Bool) -> Void)?) { + let key = self.currentLanguageKey + FAAPI.requestLanguageDataList(key: key) { [weak self] model in + guard let self = self else { + completer?(false) + return + } + guard let list = model?.translates, list.count > 0 else { + completer?(false) + return + } + languageDataLanguageKey = key + languageData = list + completer?(true) + } + } + + // 获取本地化字符串 + func localizedString(forKey key: String, tableName: String? = nil) -> String { + if let languageData = languageData, + let text = languageData[key] { + return text + + } else if let selectedLanguage = UserDefaults.standard.string(forKey: LanguageUserDefaultsKey), + let bundlePath = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj"), + let bundle = Bundle(path: bundlePath) { + + return bundle.localizedString(forKey: key, value: nil, table: tableName) + } else { + return NSLocalizedString(key, tableName: tableName, bundle: .main, value: "", comment: "") + } + } + +} + +extension FALanguageManager { + + static let languageDidChange = Notification.Name(rawValue: "FALanguageManager.languageDidChange") + +} + + +extension String { + var localized: String { + var text = FALanguageManager.manager.localizedString(forKey: self) + text = text.replacingOccurrences(of: "
", with: "\n") + return text + } + + func localizedReplace(text: String?) -> String { + return self.localized.replacingOccurrences(of: "##", with: text ?? "") + } +} diff --git a/Fableon/Object/Libs/FALocalized/FALanguageModel.swift b/Fableon/Object/Libs/FALocalized/FALanguageModel.swift new file mode 100644 index 0000000..c8d509a --- /dev/null +++ b/Fableon/Object/Libs/FALocalized/FALanguageModel.swift @@ -0,0 +1,18 @@ +// +// FALanguageModel.swift +// Fableon +// +// Created by 湖北秦九 on 2025/11/1. +// + +import UIKit +import SmartCodable + +struct FALanguageModel: SmartCodable { + + var cn_name: String? + var show_name: String? + var id: String? + var is_up_to_list: String? + var lang_key: String? +} diff --git a/Fableon/Object/Libs/FALocalized/FALocalized.swift b/Fableon/Object/Libs/FALocalized/FALocalized.swift deleted file mode 100644 index b57f5fc..0000000 --- a/Fableon/Object/Libs/FALocalized/FALocalized.swift +++ /dev/null @@ -1,110 +0,0 @@ -// -// FALocalized.swift -// Fableon -// -// Created by 湖北秦九 on 2025/10/15. -// - - -import UIKit - - -class FALocalized { - - static let manager = FALocalized() - - private let LocalizedUserDefaultsKey = "FALocalized.LocalizedUserDefaultsKey" - private let LocalizedDataUserDefaultsKey = "FALocalized.LocalizedDataUserDefaultsKey" - private let LocalizedDataLocalizedKeyUserDefaultsKey = "FALocalized.LocalizedDataLocalizedKeyUserDefaultsKey" - - - ///多语言数据 - private(set) lazy var localizedData: [String : String]? = UserDefaults.standard.object(forKey: LocalizedDataUserDefaultsKey) as? [String : String] - { - didSet { - UserDefaults.standard.set(localizedData, forKey: LocalizedDataUserDefaultsKey) - UserDefaults.standard.synchronize() - } - } - ///当前语言数据对应的key - private(set) lazy var localizedDataLocalizedKey: String? = UserDefaults.standard.object(forKey: LocalizedDataLocalizedKeyUserDefaultsKey) as? String - { - didSet { - UserDefaults.standard.set(localizedDataLocalizedKey, forKey: LocalizedDataLocalizedKeyUserDefaultsKey) - UserDefaults.standard.synchronize() - } - } - - // 获取当前语言代码(如果用户未手动设置,则返回系统语言) - var currentLocalizedKey: String { - get { - return "en" -// var key = UserDefaults.standard.string(forKey: LocalizedUserDefaultsKey) ?? Locale.preferredLanguages.first -// -// if key?.contains("zh-Hans") == true { -// key = "zh" -// } else if key?.contains("zh-Hant") == true { -// key = "zh_hk" -// } else { -// let arr = key?.components(separatedBy: "-") -// key = arr?.first -// } -// return key ?? "en" - } - set { - UserDefaults.standard.set(newValue, forKey: LocalizedUserDefaultsKey) - UserDefaults.standard.synchronize() - } - } - - var mjLocalizedKey: String { - let key = currentLocalizedKey - if key == "zh" { - return "zh-Hans" - } else if key == "zh_hk" { - return "zh-Hant" - } - return key - } - - // 判断是否跟随系统 - var isFollowingSystem: Bool { - return UserDefaults.standard.string(forKey: LocalizedUserDefaultsKey) == nil - } - - // 还原为系统默认语言 - func resetToSystemLanguage() { - UserDefaults.standard.removeObject(forKey: LocalizedUserDefaultsKey) - UserDefaults.standard.synchronize() - } - - // 获取本地化字符串 - func localizedString(forKey key: String, tableName: String? = nil) -> String { - if let localizedData = localizedData, - let text = localizedData[key] { - return text - - } else if let selectedLanguage = UserDefaults.standard.string(forKey: LocalizedUserDefaultsKey), - let bundlePath = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj"), - let bundle = Bundle(path: bundlePath) { - - return bundle.localizedString(forKey: key, value: nil, table: tableName) - } else { - return NSLocalizedString(key, tableName: tableName, bundle: .main, value: "", comment: "") - } - } - -} - - -extension String { - var localized: String { - var text = FALocalized.manager.localizedString(forKey: self) - text = text.replacingOccurrences(of: "
", with: "\n") - return text - } - - func localizedReplace(text: String?) -> String { - return self.localized.replacingOccurrences(of: "##", with: text ?? "") - } -} diff --git a/Fableon/Object/Libs/FATool/FATool.swift b/Fableon/Object/Libs/FATool/FATool.swift index 0b2d5aa..58daa7f 100644 --- a/Fableon/Object/Libs/FATool/FATool.swift +++ b/Fableon/Object/Libs/FATool/FATool.swift @@ -32,6 +32,13 @@ class FATool { return keyWindow?.rootViewController } + ///获得启动图 + static func getLanuchViewController() -> UIViewController? { + let storyboard = UIStoryboard(name: "LaunchScreen", bundle: nil) + let vc = storyboard.instantiateInitialViewController() + return vc + } + static var topViewController: UIViewController? { var resultVC: UIViewController? = self.rootViewController if let rootNav = resultVC as? UINavigationController { @@ -64,7 +71,7 @@ extension FATool { completion?(ASIdentifierManager.shared().advertisingIdentifier.uuidString) return } - guard FANetworkMonitor.manager.isReachable == true, FAAdjustStateManager.manager.apnsAuthorizationFinish, FAAdjustStateManager.manager.isOpenApp else { + guard FANetworkMonitor.manager.isReachable == true, FAAdjustStateManager.manager.apnsAuthorizationFinish else { return } @@ -91,3 +98,33 @@ extension FATool { } } } + +//MARK: 检查更新 +extension FATool { + + static func checkUpdates() { + FAAPI.requestVersionUpdateData { model in + guard let model = model else { return } + self.showUpdatesAlert(model) + } + } + + static func showUpdatesAlert(_ model: FAVersionUpdateModel) { +#if !DEBUG + if model.force != true { + if let date = UserDefaults.standard.object(forKey: kFAVersionUpdateAlertDefaultsKey) as? Date { + if date.fa_isToday { return } + } + UserDefaults.standard.set(Date(), forKey: kFAVersionUpdateAlertDefaultsKey) + } +#endif // !DEBUG + + + if model.canUpdate() { + let view = FAUpdatesAlert() + view.model = model + view.show() + } + } + +} diff --git a/Fableon/Source/Assets.xcassets/color/#E4275D.colorset/Contents.json b/Fableon/Source/Assets.xcassets/color/#E4275D.colorset/Contents.json new file mode 100644 index 0000000..c20a55b --- /dev/null +++ b/Fableon/Source/Assets.xcassets/color/#E4275D.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0x5D", + "green" : "0x27", + "red" : "0xE4" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Contents.json new file mode 100644 index 0000000..7978ebd --- /dev/null +++ b/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Ellipse 45@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Ellipse 45@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Ellipse 45@2x.png b/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Ellipse 45@2x.png new file mode 100644 index 0000000..e9f12f4 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Ellipse 45@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Ellipse 45@3x.png b/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Ellipse 45@3x.png new file mode 100644 index 0000000..af7f56e Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/Ellipse 45.imageset/Ellipse 45@3x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/Vector.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/Vector.imageset/Contents.json new file mode 100644 index 0000000..6a4d508 --- /dev/null +++ b/Fableon/Source/Assets.xcassets/image/Vector.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Vector@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Vector@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/Vector.imageset/Vector@2x.png b/Fableon/Source/Assets.xcassets/image/Vector.imageset/Vector@2x.png new file mode 100644 index 0000000..f2e2435 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/Vector.imageset/Vector@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/Vector.imageset/Vector@3x.png b/Fableon/Source/Assets.xcassets/image/Vector.imageset/Vector@3x.png new file mode 100644 index 0000000..4af0486 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/Vector.imageset/Vector@3x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/__New.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/__New.imageset/Contents.json new file mode 100644 index 0000000..9fefa35 --- /dev/null +++ b/Fableon/Source/Assets.xcassets/image/__New.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "__New@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "__New@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/__New.imageset/__New@2x.png b/Fableon/Source/Assets.xcassets/image/__New.imageset/__New@2x.png new file mode 100644 index 0000000..b4871bf Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/__New.imageset/__New@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/__New.imageset/__New@3x.png b/Fableon/Source/Assets.xcassets/image/__New.imageset/__New@3x.png new file mode 100644 index 0000000..eca335c Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/__New.imageset/__New@3x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/bj.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/bj.imageset/Contents.json new file mode 100644 index 0000000..5a3afd3 --- /dev/null +++ b/Fableon/Source/Assets.xcassets/image/bj.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "bj@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "bj@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/bj.imageset/bj@2x.png b/Fableon/Source/Assets.xcassets/image/bj.imageset/bj@2x.png new file mode 100644 index 0000000..da3c58d Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/bj.imageset/bj@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/bj.imageset/bj@3x.png b/Fableon/Source/Assets.xcassets/image/bj.imageset/bj@3x.png new file mode 100644 index 0000000..d00ef43 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/bj.imageset/bj@3x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Frame@2x.png b/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Frame@2x.png new file mode 100644 index 0000000..32e42b3 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Frame@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Frame@3x.png b/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Frame@3x.png new file mode 100644 index 0000000..7e465c2 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/close_icon_04.imageset/Frame@3x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/icon_language.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/icon_language.imageset/Contents.json new file mode 100644 index 0000000..08268d1 --- /dev/null +++ b/Fableon/Source/Assets.xcassets/image/icon_language.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "路径 139@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "路径 139@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/icon_language.imageset/路径 139@2x.png b/Fableon/Source/Assets.xcassets/image/icon_language.imageset/路径 139@2x.png new file mode 100644 index 0000000..d02bad7 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/icon_language.imageset/路径 139@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/icon_language.imageset/路径 139@3x.png b/Fableon/Source/Assets.xcassets/image/icon_language.imageset/路径 139@3x.png new file mode 100644 index 0000000..f34067f Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/icon_language.imageset/路径 139@3x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/退出登录.imageset/Contents.json b/Fableon/Source/Assets.xcassets/image/退出登录.imageset/Contents.json new file mode 100644 index 0000000..b35baad --- /dev/null +++ b/Fableon/Source/Assets.xcassets/image/退出登录.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "退出登录@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "退出登录@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Fableon/Source/Assets.xcassets/image/退出登录.imageset/退出登录@2x.png b/Fableon/Source/Assets.xcassets/image/退出登录.imageset/退出登录@2x.png new file mode 100644 index 0000000..3e3f6f7 Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/退出登录.imageset/退出登录@2x.png differ diff --git a/Fableon/Source/Assets.xcassets/image/退出登录.imageset/退出登录@3x.png b/Fableon/Source/Assets.xcassets/image/退出登录.imageset/退出登录@3x.png new file mode 100644 index 0000000..a7cf69c Binary files /dev/null and b/Fableon/Source/Assets.xcassets/image/退出登录.imageset/退出登录@3x.png differ diff --git a/Fableon/Source/en.lproj/Localizable.strings b/Fableon/Source/en.lproj/Localizable.strings index e0ddfe1..af56ca0 100644 --- a/Fableon/Source/en.lproj/Localizable.strings +++ b/Fableon/Source/en.lproj/Localizable.strings @@ -1,85 +1,96 @@ -"Ep.##" = "Ep.##"; -"Error" = "Error"; -"Feedback" = "Feedback"; -"Collect" = "Collect"; -"History" = "History"; -"Search" = "Search"; -"Historical search" = "Historical search"; -"About" = "About"; -"Privacy Policy" = "Privacy Policy"; -"User Agreement" = "User Agreement"; -"Visit Website" = "Visit Website"; -"Setting" = "Setting"; -"Settings" = "Settings"; -"Last Watch:Ep.##" = "Last Watch:Ep.##"; -"Genres" = "Genres"; -"Popular" = "Popular"; -"New" = "New"; -"Coins" = "Coins"; -"Bonus" = "Bonus"; -"Unlocking costs ## coins" = "Unlocking costs ## coins"; +"fableon_episode_set" = "Ep.##"; +"fableon_error" = "Error"; +"fableon_feedback" = "Feedback"; +"fableon_collect" = "Collect"; +"fableon_history" = "History"; +"fableon_search" = "Search"; +"fableon_search_history" = "Historical search"; +"fableon_about_us" = "About"; +"fableon_privacy_policy" = "Privacy Policy"; +"fableon_user_agreement" = "User Agreement"; +"fableon_visit_website" = "Visit Website"; +"fableon_settings" = "Settings"; +"fableon_last_watch_ep" = "Last Watch:Ep.##"; +"fableon_genres" = "Genres"; +"fableon_popular" = "Popular"; +"fableon_new" = "New"; +"fableon_coins" = "Coins"; +"fableon_bonus" = "Bonus"; +"fableon_unlocking_coins_notice" = "Unlocking costs ## coins"; "video_lock_tip_text" = "Pre.locked"; -"Activated" = "Activated"; -"Not Activated" = "Not Activated"; -"Subscribe" = "Subscribe"; +"fableon_activated" = "Activated"; +"fableon_not_activated" = "Not Activated"; +"fableon_subscribe" = "Subscribe"; "vip_expires_date" = "Expiration Time:##"; -"Store" = "Store"; -"Feedback History" = "Feedback History"; -"Feedback Details" = "Feedback Details"; -"My Wallet" = "My Wallet"; -"Consumption Records" = "Consumption Records"; -"Purchase Records" = "Purchase Records"; -"Reward Coins" = "Reward Coins"; -"Order Records" = "Order Records"; -"Coin Record" = "Coin Record"; -"VIP Record" = "VIP Record"; +"fableon_store" = "Store"; +"fableon_feedback_history" = "Feedback History"; +"fableon_feedback_detail" = "Feedback Details"; +"fableo_my_wallet" = "My Wallet"; +"fableo_consumption_records" = "Consumption Records"; +"fableo_purchase_records" = "Purchase Records"; +"fableo_reward_coins" = "Reward Coins"; +"fableo_order_records" = "Order Records"; +"fableo_coin_record" = "Coin Record"; +"fableo_VIP_Record" = "VIP Record"; "Expired" = "Expired"; -"Weekly Refill" = "Weekly Refill"; -"week" = "week"; -"month" = "month"; -"quarter" = "quarter"; -"year" = "year"; -"extra" = "Extra"; -"success" = "Success"; -"Restore" = "Restore"; -"Bonus Coins" = "Bonus Coins"; -"Recharge Coins" = "Recharge Coins"; -"Expires in ## days" = "Expires in ## days"; -"What You Get" = "What You Get"; -"Bonus You Get" = "Bonus You Get"; -"Weekly Refill Package" = "Weekly Refill Package"; -"Dailu Bonuses" = "Dailu Bonuses"; -"Continue" = "Continue"; -"Purchase Single Episode" = "Purchase Single Episode"; -"Price" = "Price"; -"Balance" = "Balance"; -"Daily reward ready!" = "Daily reward ready!"; -"Claim your rewards now." = "Claim your rewards now."; -"My Refills" = "My Refills"; -"Weekly Total" = "Weekly Total"; -"Claimable Coins" = "Claimable Coins"; -"Active Refills" = "Active Refills"; -"Get a Refill to Claim" = "Get a Refill to Claim"; -"Claim All" = "Claim All"; -"Total Reward" = "Total Reward"; -"Remaining" = "Remaining"; -"Claim" = "Claim"; -"Log in" = "Log in"; -"Login with Apple" = "Login with Apple"; -"Login with Facebook" = "Login with Facebook"; -"Account Deletion" = "Account Deletion"; -"Cancel" = "Cancel"; -"Remove" = "Remove"; -"Daily Coins" = "Daily Coins"; -"Claim Now" = "Claim Now"; -"Later" = "Later"; -"Buy Now" = "Buy Now"; -"Weekly VIP" = "Weekly VIP"; -"Monthly VIP" = "Monthly VIP"; -"Quarterly VIP" = "Quarterly VIP"; -"Yearly VIP" = "Yearly VIP"; -"Open" = "Open"; +"fableo_weekly_refill" = "Weekly Refill"; +"w_complex" = "week"; +"m_complex" = "month"; +"q_complex" = "quarter"; +"Y_complex" = "year"; +"fableo_extra" = "Extra"; +"fableo_success" = "Success"; +"fableo_restore" = "Restore"; +"fableo_bonus_coins" = "Bonus Coins"; +"fableo_recharge_coins" = "Recharge Coins"; +"fableo_expires_#_days" = "Expires in ## days"; +"fableo_what_you_get" = "What You Get"; +"fableo_bonus_you_get" = "Bonus You Get"; +"fableo_weekly_refill_package" = "Weekly Refill Package"; +"fableo_dailu_bonuses" = "Daily Bonuses"; +"fableo_continue" = "Continue"; +"fableo_single_episode" = "Purchase Single Episode"; +"fableo_price" = "Price"; +"fableo_balance" = "Balance"; +"fableo_me_daily_1" = "Daily reward ready!"; +"fableo_me_daily_2" = "Claim your rewards now."; +"fableon_my_refills" = "My Refills"; +"fableon_weekly_total" = "Weekly Total"; +"fableon_claimable_coins" = "Claimable Coins"; +"fableon_active_refills" = "Active Refills"; +"fableon_get_refill_button_text" = "Get a Refill to Claim"; +"fableon_claim_all" = "Claim All"; +"fableon_total_reward" = "Total Reward"; +"fableon_remaining" = "Remaining"; +"fableon_claim" = "Claim"; +"fableon_login" = "Log in"; +"fableon_logout" = "Log out"; +"fableon_login_title_apple" = "Login with Apple"; +"fableon_login_title_facebook" = "Login with Facebook"; +"fableon_account_deletion" = "Account Deletion"; +"fableon_cancel" = "Cancel"; +"fableon_remove" = "Remove"; +"fableon_daily_coins" = "Daily Coins"; +"fableon_claim_now" = "Claim Now"; +"fableon_open_notification_later" = "Later"; +"fableon_buy_now" = "Buy Now"; +"fableon_weekly_vip" = "Weekly VIP"; +"fableon_monthly_vip" = "Monthly VIP"; +"fableon_quarterly_vip" = "Quarterly VIP"; +"fableon_yearly_vip" = "Yearly VIP"; +"fableon_open" = "Open"; +"fableon_update_now" = "Update Now"; +"fableon_recommend_for_you" = "Recommend For You"; +"fableon_language" = "Language"; +"fableon_rewards_overview" = "REWARDS OVERVIEW"; +"fableon_home" = "Home"; +"fableon_recommend" = "Recommend"; +"fableon_me" = "Me"; +"fableon_must_see_tv_series" = "Must-see TV series"; +"fableon_editor's_picks" = "Editor's Picks"; +"fableon_home_new" = "New Releases"; +"fableon_watch" = "Watch"; "remove_collect_alert_title" = "Remove from Favorites?"; "remove_collect_alert_text" = "This drama will be removed from your favorites."; @@ -87,10 +98,11 @@ "vip_retain_alert_text" = "Unlock every show you love!"; "apns_alert_title" = "Enable Notifications"; "apns_alert_text" = "Stay informed with popular recommendations and latest updates!"; +"updates_alert_title" = "Discover A New Version"; +"logout_alert_title" = "Leaving So Soon?"; +"logout_alert_text" = "You'll need to sign in again"; -"REWARDS OVERVIEW" = "REWARDS OVERVIEW"; - "store_title_1" = "VIP Auto renew,cancel anytime"; "network_error_01" = "The service is abnormal. Check the network."; @@ -108,11 +120,14 @@ "pay_error_2" = "Invalid in-app purchase"; "pay_error_3" = "Payment has been cancelled"; "pay_error_4" = "Purchase Failed"; -"pay_error_5" = "No in-app purchases can be restored"; +"pay_error_5" = "There are no recoverable in-app purchases."; "pay_error_6" = "You have unfinished in-app purchases, please restore them first."; -"store_tips_title" = "Tips"; -"store_tips" = "1. Coins are virtual items and cannot be refunded. Use it for this product.
2. Both the coins and the reward coins will never expire.
3. Coins will be used first when unlocking episodes. If the amount is insufficient, reward coins will automatically be used.
4. The purchase has not been credited, click torefresh.
5. For other questions, contact us via Profile>Help &feedback."; +"fableon_tips" = "Tips"; +"store_tips" = "1. Coins are virtual items and cannot be refunded. Use it for this product.
2. Both the coins and the reward coins will never expire.
3. Coins will be used first when unlocking episodes. If the amount is insufficient, reward coins will automatically be used.
4. The purchase has not been credited, click torefresh.
5. For other questions, contact us via Profile > Feedback."; + + + "coins_pack_tips_title" = "Subscription Rules"; "coins_pack_tips" = "1.Up to 2 subscriptions can be active at once.
2.Coins are delivered instantly upon purchase.
3.Daily bonus coins available from the next day.
4.All coins will be revoked when the subscription expires, including both initial and daily coins."; diff --git a/Fableon/firstpass/getsockaddr/zpbiquads/CControlCell.swift b/Fableon/firstpass/getsockaddr/zpbiquads/CControlCell.swift index 18f75f3..1db0169 100644 --- a/Fableon/firstpass/getsockaddr/zpbiquads/CControlCell.swift +++ b/Fableon/firstpass/getsockaddr/zpbiquads/CControlCell.swift @@ -19,7 +19,7 @@ private var paning_sum: Int? = 0 didSet { nameLabel.text = model?.name coverImageView.fa_setImage(model?.image_url) - epLabel.text = "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") } } diff --git a/Fableon/firstpass/getsockaddr/zpbiquads/ZFGEtworkCell.swift b/Fableon/firstpass/getsockaddr/zpbiquads/ZFGEtworkCell.swift index ea964f3..7ed2fbe 100644 --- a/Fableon/firstpass/getsockaddr/zpbiquads/ZFGEtworkCell.swift +++ b/Fableon/firstpass/getsockaddr/zpbiquads/ZFGEtworkCell.swift @@ -14,7 +14,7 @@ var numElaris_arr: [Any]? didSet { coverImageView.fa_setImage(model?.image_url) nameLabel.text = model?.name - epLabel.text = "Ep.##".localizedReplace(text: model?.current_episode) + "/" + "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + epLabel.text = "fableon_episode_set".localizedReplace(text: model?.current_episode) + "/" + "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") } } diff --git a/Fableon/firstpass/grey/preservesYoga/FFCheck.swift b/Fableon/firstpass/grey/preservesYoga/FFCheck.swift index f56373c..cedcd6c 100644 --- a/Fableon/firstpass/grey/preservesYoga/FFCheck.swift +++ b/Fableon/firstpass/grey/preservesYoga/FFCheck.swift @@ -166,7 +166,7 @@ withUnsafeMutablePointer(to: &writeclearWatchdog) { pointer in if $0.module_key == .banner { self.bannerItem = $0 } else if $0.module_key == .v3_recommand { - $0.title = "Popular".localized + $0.title = "fableon_popular".localized popularItem = $0 } else if $0.module_key == .week_ranking { $0.title = "Rankings".localized @@ -175,7 +175,7 @@ withUnsafeMutablePointer(to: &writeclearWatchdog) { pointer in $0.title = "veloriaDetailPath".localized genresItem = $0 } else if $0.module_key == .new_recommand { - $0.title = "New".localized + $0.title = "fableon_new".localized newItem = $0 self.homeNewItem = $0 } else if $0.module_key == .week_recommend { diff --git a/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift b/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift index 2acae42..1937fbc 100644 --- a/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift +++ b/Fableon/firstpass/grey/stationaritySumd/CSGleeView.swift @@ -21,7 +21,7 @@ var deceleratingMax: Double = 0.0 var body: some View { VStack { HStack { - Text("Must-see TV series".localized) + Text("fableon_must_see_tv_series".localized) .font(Font.font(size: 18, weight: .medium)) .foregroundStyle(Color(String.color_FFFFFF)) .padding(.leading, 16) diff --git a/Fableon/firstpass/grey/stationaritySumd/GAMainRecommendedView.swift b/Fableon/firstpass/grey/stationaritySumd/GAMainRecommendedView.swift index b8348f7..d03e751 100644 --- a/Fableon/firstpass/grey/stationaritySumd/GAMainRecommendedView.swift +++ b/Fableon/firstpass/grey/stationaritySumd/GAMainRecommendedView.swift @@ -51,7 +51,7 @@ var playIdx: Int = 0 HStack(spacing: 4) { Image("homeContentOken") - Text("Watch".localized) + Text("fableon_watch".localized) .font(Font.font(size: 12, weight: .medium)) .foregroundStyle(Color(String.color_000000)) diff --git a/Fableon/firstpass/grey/stationaritySumd/QCenterEfineView.swift b/Fableon/firstpass/grey/stationaritySumd/QCenterEfineView.swift index 2e6b7ce..fbb85b9 100644 --- a/Fableon/firstpass/grey/stationaritySumd/QCenterEfineView.swift +++ b/Fableon/firstpass/grey/stationaritySumd/QCenterEfineView.swift @@ -29,7 +29,7 @@ var connection_min: Float = 0.0 let list = viewModel.homeNewItem?.list ?? [] VStack(spacing: 15) { - Text("New Releases".localized) + Text("fableon_home_new".localized) .font(.font(size: 18, weight: .medium)) .foregroundStyle(Color(String.color_FFFFFF)) .padding(.leading, 16) @@ -66,7 +66,7 @@ var connection_min: Float = 0.0 HStack(spacing: 4) { Image("playerCrollConfig") - Text("Watch".localized) + Text("fableon_watch".localized) .font(.font(size: 14, weight: .medium)) .foregroundStyle(Color(String.color_000000)) } diff --git a/Fableon/firstpass/grey/stationaritySumd/XLoginView.swift b/Fableon/firstpass/grey/stationaritySumd/XLoginView.swift index 83fcbe1..3e19d84 100644 --- a/Fableon/firstpass/grey/stationaritySumd/XLoginView.swift +++ b/Fableon/firstpass/grey/stationaritySumd/XLoginView.swift @@ -22,7 +22,7 @@ var byte_z: Double = 0.0 var body: some View { VStack(spacing: 15) { HStack { - Text("Editor's Picks".localized) + Text("fableon_editor's_picks".localized) .font(Font.font(size: 16, weight: .medium)) .foregroundStyle(Color(String.color_FFFFFF)) .padding(.leading, 10) diff --git a/Fableon/firstpass/grey/zpbiquads/LGHiveModuleView.swift b/Fableon/firstpass/grey/zpbiquads/LGHiveModuleView.swift index 2b753e0..cb2b10c 100644 --- a/Fableon/firstpass/grey/zpbiquads/LGHiveModuleView.swift +++ b/Fableon/firstpass/grey/zpbiquads/LGHiveModuleView.swift @@ -15,7 +15,7 @@ private var alignment_margin: Double? = 0.0 didSet { coverImageView.fa_setImage(model?.image_url) titleLabel.text = model?.name - epLabel.text = "Last Watch:Ep.##".localizedReplace(text: model?.current_episode ?? "") + epLabel.text = "fableon_last_watch_ep".localizedReplace(text: model?.current_episode ?? "") } } diff --git a/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift b/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift index 741c334..e8316ff 100644 --- a/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift +++ b/Fableon/firstpass/grey/zpbiquads/TCFableonCell.swift @@ -17,7 +17,7 @@ var bottomProgressDict: [String: Any]? coverImageView.fa_setImage(model?.image_url) titleLabel.text = model?.name countLabel.text = "\(model?.watch_total ?? 0)" - epLabel.text = "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + epLabel.text = "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") } } diff --git a/Fableon/firstpass/oriBytestream/zpbiquads/TGleeScreenView.swift b/Fableon/firstpass/oriBytestream/zpbiquads/TGleeScreenView.swift index 6106b18..568fac3 100644 --- a/Fableon/firstpass/oriBytestream/zpbiquads/TGleeScreenView.swift +++ b/Fableon/firstpass/oriBytestream/zpbiquads/TGleeScreenView.swift @@ -472,7 +472,7 @@ withUnsafeMutablePointer(to: &deniedConsume) { pointer in let videoInfo = model?.video_info - let text = "Ep.##".localizedReplace(text: videoInfo?.episode ?? "") + "/" + "Ep.##".localizedReplace(text: "\(model?.episode_total ?? 0)") + let text = "fableon_episode_set".localizedReplace(text: videoInfo?.episode ?? "") + "/" + "fableon_episode_set".localizedReplace(text: "\(model?.episode_total ?? 0)") var view = IHAVeloriaButton(text: text) view.clickHandle = { [weak self] in self?.fa_viewModel?.pushPlayerDetail(self?.shortModel) diff --git a/Fableon/firstpass/proresdata/zpbiquads/JOLayoutRyptorView.swift b/Fableon/firstpass/proresdata/zpbiquads/JOLayoutRyptorView.swift index c7946e8..731ead4 100644 --- a/Fableon/firstpass/proresdata/zpbiquads/JOLayoutRyptorView.swift +++ b/Fableon/firstpass/proresdata/zpbiquads/JOLayoutRyptorView.swift @@ -409,7 +409,7 @@ _ = chinSerialized private func readDismissPopGraphics() { let model = self.model as? AVMonitor - let text = "Ep.##".localizedReplace(text: model?.episode ?? "") + "/" + "Ep.##".localizedReplace(text: "\(shortModel?.episode_total ?? 0)") + let text = "fableon_episode_set".localizedReplace(text: model?.episode ?? "") + "/" + "fableon_episode_set".localizedReplace(text: "\(shortModel?.episode_total ?? 0)") var view = IHAVeloriaButton(text: text) view.clickHandle = { [weak self] in self?.fa_viewModel?.onEpSelectorView()