多语言开发
This commit is contained in:
parent
2a71917084
commit
78f810498d
@ -148,6 +148,12 @@
|
||||
BF5E75DB2DE5B8B700DE9DFE /* VPMarqueeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75DA2DE5B8B700DE9DFE /* VPMarqueeView.swift */; };
|
||||
BFCCE10D2DF951F600EDE165 /* SceneDelegate+APNS.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE10C2DF951ED00EDE165 /* SceneDelegate+APNS.swift */; };
|
||||
BFCCE1122DF9638B00EDE165 /* VPVipAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1112DF9638B00EDE165 /* VPVipAlertView.swift */; };
|
||||
BFCCE1142DFAAC0900EDE165 /* VPLanguageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1132DFAAC0900EDE165 /* VPLanguageViewController.swift */; };
|
||||
BFCCE1162DFAB66F00EDE165 /* VPLanguageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1152DFAB66F00EDE165 /* VPLanguageCell.swift */; };
|
||||
BFCCE1182DFAB77500EDE165 /* VPSettingAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1172DFAB76E00EDE165 /* VPSettingAPI.swift */; };
|
||||
BFCCE11A2DFAB7CA00EDE165 /* VPLanguageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1192DFAB7CA00EDE165 /* VPLanguageModel.swift */; };
|
||||
BFCCE11C2DFAB83900EDE165 /* VPLocalizedModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE11B2DFAB83900EDE165 /* VPLocalizedModel.swift */; };
|
||||
BFCCE11F2DFAD18000EDE165 /* VPGuideViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE11E2DFAD18000EDE165 /* VPGuideViewController.swift */; };
|
||||
BFF5AFA42DE6F15E0044227A /* VPMeVipCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA32DE6F15E0044227A /* VPMeVipCell.swift */; };
|
||||
BFF5AFA62DE700420044227A /* VPMeVipPrivilegeItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA52DE700420044227A /* VPMeVipPrivilegeItemView.swift */; };
|
||||
BFF5AFA82DE704DC0044227A /* VPMeCoinCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */; };
|
||||
@ -376,6 +382,12 @@
|
||||
BF5E75DA2DE5B8B700DE9DFE /* VPMarqueeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMarqueeView.swift; sourceTree = "<group>"; };
|
||||
BFCCE10C2DF951ED00EDE165 /* SceneDelegate+APNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SceneDelegate+APNS.swift"; sourceTree = "<group>"; };
|
||||
BFCCE1112DF9638B00EDE165 /* VPVipAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipAlertView.swift; sourceTree = "<group>"; };
|
||||
BFCCE1132DFAAC0900EDE165 /* VPLanguageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPLanguageViewController.swift; sourceTree = "<group>"; };
|
||||
BFCCE1152DFAB66F00EDE165 /* VPLanguageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPLanguageCell.swift; sourceTree = "<group>"; };
|
||||
BFCCE1172DFAB76E00EDE165 /* VPSettingAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPSettingAPI.swift; sourceTree = "<group>"; };
|
||||
BFCCE1192DFAB7CA00EDE165 /* VPLanguageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPLanguageModel.swift; sourceTree = "<group>"; };
|
||||
BFCCE11B2DFAB83900EDE165 /* VPLocalizedModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPLocalizedModel.swift; sourceTree = "<group>"; };
|
||||
BFCCE11E2DFAD18000EDE165 /* VPGuideViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPGuideViewController.swift; sourceTree = "<group>"; };
|
||||
BFF5AFA32DE6F15E0044227A /* VPMeVipCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipCell.swift; sourceTree = "<group>"; };
|
||||
BFF5AFA52DE700420044227A /* VPMeVipPrivilegeItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipPrivilegeItemView.swift; sourceTree = "<group>"; };
|
||||
BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeCoinCell.swift; sourceTree = "<group>"; };
|
||||
@ -552,6 +564,7 @@
|
||||
BF0FA7422DDF024400C9E5F2 /* Explore */,
|
||||
BF0FA6FD2DDC65F300C9E5F2 /* Player */,
|
||||
BFF5B21D2DEEE28B0044227A /* Login */,
|
||||
BFCCE11D2DFAD14C00EDE165 /* Guide */,
|
||||
);
|
||||
path = Class;
|
||||
sourceTree = "<group>";
|
||||
@ -696,6 +709,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1B056E692DDAD0BF007EE38D /* VPLocalizedManager.swift */,
|
||||
BFCCE11B2DFAB83900EDE165 /* VPLocalizedModel.swift */,
|
||||
);
|
||||
path = LocalizedManager;
|
||||
sourceTree = "<group>";
|
||||
@ -780,6 +794,7 @@
|
||||
BF0FA6F72DDC64CF00C9E5F2 /* API */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFCCE1172DFAB76E00EDE165 /* VPSettingAPI.swift */,
|
||||
BFF5AFB92DE8372A0044227A /* VPWalletAPI.swift */,
|
||||
BF0FA6F82DDC64E700C9E5F2 /* VPHomeAPI.swift */,
|
||||
BF0FA73C2DDED2D000C9E5F2 /* VPVideoAPI.swift */,
|
||||
@ -1020,6 +1035,7 @@
|
||||
BF5E75AE2DE4632200DE9DFE /* VPAboutUsViewController.swift */,
|
||||
BFF5B22B2DEFE8A80044227A /* VPDeleteAccountViewController.swift */,
|
||||
BFF5B23C2DF034420044227A /* VPFeedbackViewController.swift */,
|
||||
BFCCE1132DFAAC0900EDE165 /* VPLanguageViewController.swift */,
|
||||
);
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
@ -1042,6 +1058,7 @@
|
||||
BFF5B2312DEFF1220044227A /* VPDeleteAccountDetailView.swift */,
|
||||
BFF5B2332DEFF2030044227A /* VPDeleteAccountTipView.swift */,
|
||||
BFCCE1112DF9638B00EDE165 /* VPVipAlertView.swift */,
|
||||
BFCCE1152DFAB66F00EDE165 /* VPLanguageCell.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@ -1050,6 +1067,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7B02DE447EB00C9E5F2 /* VPMeItem.swift */,
|
||||
BFCCE1192DFAB7CA00EDE165 /* VPLanguageModel.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
@ -1107,6 +1125,14 @@
|
||||
path = MarqueeView;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFCCE11D2DFAD14C00EDE165 /* Guide */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFCCE11E2DFAD18000EDE165 /* VPGuideViewController.swift */,
|
||||
);
|
||||
path = Guide;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFF5AFBB2DE837710044227A /* Wallet */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1382,12 +1408,14 @@
|
||||
1B056E772DDB3641007EE38D /* VPTabBarItemNormalVew.swift in Sources */,
|
||||
BFF5B2662DF16CF60044227A /* VPWaitRestoreModel.swift in Sources */,
|
||||
1B056E4B2DDAC6BA007EE38D /* VPDefine.swift in Sources */,
|
||||
BFCCE11A2DFAB7CA00EDE165 /* VPLanguageModel.swift in Sources */,
|
||||
BFF5B2302DEFEF0C0044227A /* VPDeleteAccountNormalView.swift in Sources */,
|
||||
1B056E702DDB019B007EE38D /* VPTabBarItemContainer.swift in Sources */,
|
||||
BF0FA7752DE071B500C9E5F2 /* VPSearchViewController.swift in Sources */,
|
||||
BF0FA78D2DE16A8B00C9E5F2 /* VPSearchViewModel.swift in Sources */,
|
||||
1B056E592DDACD44007EE38D /* VPTabBarItemContentView.swift in Sources */,
|
||||
1B056E2B2DDAC0FD007EE38D /* AppDelegate.swift in Sources */,
|
||||
BFCCE1162DFAB66F00EDE165 /* VPLanguageCell.swift in Sources */,
|
||||
1B056E6C2DDADAA1007EE38D /* VPTabBar.swift in Sources */,
|
||||
BF0FA72E2DDD7DD400C9E5F2 /* VPHomeRankingCell.swift in Sources */,
|
||||
BF0FA7792DE075FF00C9E5F2 /* VPSearchHomeView.swift in Sources */,
|
||||
@ -1401,6 +1429,7 @@
|
||||
BFF5B2202DEEE2C50044227A /* VPLoginContentView.swift in Sources */,
|
||||
1B056E5D2DDACD8E007EE38D /* UIFont+VPAdd.swift in Sources */,
|
||||
BF0FA7282DDC91F800C9E5F2 /* VPCollectionViewCell.swift in Sources */,
|
||||
BFCCE11C2DFAB83900EDE165 /* VPLocalizedModel.swift in Sources */,
|
||||
BF0FA7672DE0469300C9E5F2 /* VPEpisodeView.swift in Sources */,
|
||||
BF0FA6F92DDC64E700C9E5F2 /* VPHomeAPI.swift in Sources */,
|
||||
BF0FA6F42DDC604500C9E5F2 /* VPHUD.swift in Sources */,
|
||||
@ -1506,6 +1535,7 @@
|
||||
BF0FA78F2DE16B2A00C9E5F2 /* VPUserDefaultsKey.swift in Sources */,
|
||||
BF0FA7192DDC7F4900C9E5F2 /* VPHomeBannerCell.swift in Sources */,
|
||||
BF0FA7712DE062EB00C9E5F2 /* VPVideoRateModel.swift in Sources */,
|
||||
BFCCE1142DFAAC0900EDE165 /* VPLanguageViewController.swift in Sources */,
|
||||
BF0FA7022DDC667C00C9E5F2 /* VPVideoInfoModel.swift in Sources */,
|
||||
BF0FA77B2DE0788A00C9E5F2 /* UIStackView+VPAdd.swift in Sources */,
|
||||
BF0FA7BE2DE4592A00C9E5F2 /* UserDefaults+VPAdd.swift in Sources */,
|
||||
@ -1520,6 +1550,7 @@
|
||||
BF0FA7892DE161F200C9E5F2 /* VPSearchResultView.swift in Sources */,
|
||||
1B056E792DDB365A007EE38D /* VPTabBarItemSelectedView.swift in Sources */,
|
||||
1B056E722DDB022F007EE38D /* VPTabBarItem.swift in Sources */,
|
||||
BFCCE11F2DFAD18000EDE165 /* VPGuideViewController.swift in Sources */,
|
||||
BFF5B23D2DF034420044227A /* VPFeedbackViewController.swift in Sources */,
|
||||
BFF5B2392DF014520044227A /* VPBaseAlertView.swift in Sources */,
|
||||
BFF5AFCC2DE98C7F0044227A /* VPOrderRecordsViewController.swift in Sources */,
|
||||
@ -1532,6 +1563,7 @@
|
||||
BF0FA73F2DDEF26E00C9E5F2 /* VPHomeSearchButton.swift in Sources */,
|
||||
BFF5B2562DF139200044227A /* VPGiveCoinRecordsViewController.swift in Sources */,
|
||||
1B056E512DDACBE5007EE38D /* VPViewController.swift in Sources */,
|
||||
BFCCE1182DFAB77500EDE165 /* VPSettingAPI.swift in Sources */,
|
||||
BF0FA7122DDC6D2C00C9E5F2 /* VPHomeModuleItem.swift in Sources */,
|
||||
BFF5B2482DF051D90044227A /* AppDelegate+Thirdparty.swift in Sources */,
|
||||
BFF5AFAC2DE70CE20044227A /* VPMeToolCell.swift in Sources */,
|
||||
|
@ -39,7 +39,7 @@ extension SceneDelegate {
|
||||
private static var webpageURL: URL?
|
||||
|
||||
func vp_handleOpenAppMessage(webpageURL: URL?) {
|
||||
guard VPNetworkReachabilityManager.manager.isReachable == true, SceneDelegate.haveBeenShownAPNS else {
|
||||
guard VPNetworkReachabilityManager.manager.isReachable == true, SceneDelegate.haveBeenShownAPNS, self.isOpenApp else {
|
||||
if let webpageURL = webpageURL {
|
||||
SceneDelegate.webpageURL = webpageURL
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ extension SceneDelegate {
|
||||
}
|
||||
|
||||
private func showApnsAlert() {
|
||||
let alert = VPAlertView(title: "kAPNSAlertTitle".localized, subtitle: "kAPNSAlertText".localized, icon: UIImage(named: "alert_icon_03"), normalButtonText: nil, highlightButtonText: "Allow".localized)
|
||||
let alert = VPAlertView(title: "open_notice_at_watch_video".localized, subtitle: "veloria_open_notice_alert_text".localized, icon: UIImage(named: "alert_icon_03"), normalButtonText: nil, highlightButtonText: "veloria_allow".localized)
|
||||
alert.show()
|
||||
|
||||
alert.clickHighlightButton = { [weak self] in
|
||||
|
@ -12,15 +12,18 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
var window: UIWindow?
|
||||
|
||||
|
||||
private var timer: Timer?
|
||||
private var onLineTimer: Timer?
|
||||
|
||||
private(set) var isOpenApp = false
|
||||
|
||||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
guard let windowScene = (scene as? UIWindowScene) else { return }
|
||||
VPAppTool.windowScene = windowScene
|
||||
|
||||
timer = Timer.scheduledTimer(timeInterval: 60 * 10, target: YYWeakProxy(target: self), selector: #selector(handleOnLine), userInfo: nil, repeats: true)
|
||||
onLineTimer = Timer.scheduledTimer(timeInterval: 60 * 10, target: YYWeakProxy(target: self), selector: #selector(handleOnLine), userInfo: nil, repeats: true)
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: VPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(localizedDidChangeNotification), name: VPLocalizedManager.localizedDidChangeNotification, object: nil)
|
||||
|
||||
self.requestAPNS()
|
||||
|
||||
@ -30,11 +33,15 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
}
|
||||
|
||||
window = UIWindow(windowScene: windowScene)
|
||||
|
||||
startApp()
|
||||
|
||||
}
|
||||
|
||||
private func setTabBarController() {
|
||||
isOpenApp = true
|
||||
window?.rootViewController = VPTabBarController()
|
||||
window?.makeKeyAndVisible()
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
func sceneDidDisconnect(_ scene: UIScene) {
|
||||
@ -42,18 +49,17 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
}
|
||||
|
||||
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||
// vpLog(message: "++++++++++++++sceneDidBecomeActive")
|
||||
vpLog(message: "++++++++++++++sceneDidBecomeActive")
|
||||
enterForeground()
|
||||
}
|
||||
|
||||
func sceneWillResignActive(_ scene: UIScene) {
|
||||
// vpLog(message: "++++++++++++++sceneWillResignActive")
|
||||
vpLog(message: "++++++++++++++sceneWillResignActive")
|
||||
enterBackground()
|
||||
}
|
||||
|
||||
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||
// vpLog(message: "++++++++++++++sceneWillEnterForeground")
|
||||
// enterForeground()
|
||||
vpLog(message: "++++++++++++++sceneWillEnterForeground")
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
|
||||
self.vp_handleOpenAppMessage(webpageURL: nil)
|
||||
@ -61,17 +67,10 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
}
|
||||
|
||||
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||
// vpLog(message: "++++++++++++++sceneDidEnterBackground")
|
||||
// enterBackground()
|
||||
vpLog(message: "++++++++++++++sceneDidEnterBackground")
|
||||
}
|
||||
|
||||
// private var isEnterForeground = false
|
||||
|
||||
private func enterForeground() {
|
||||
// if !isEnterForeground {
|
||||
// vpLog(message: "++++++++++++++enterForeground")
|
||||
// }
|
||||
// isEnterForeground = true
|
||||
|
||||
handleOnLine()
|
||||
VPStatAPI.requestEnterApp()
|
||||
@ -89,18 +88,75 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||
|
||||
}
|
||||
|
||||
extension SceneDelegate {
|
||||
|
||||
private func startApp() {
|
||||
let localizedManager = VPLocalizedManager.shared
|
||||
|
||||
if localizedManager.localizedDataLocalizedKey != localizedManager.currentLocalizedKey,
|
||||
let lanuchVC = VPAppTool.lanuchViewController {
|
||||
window?.rootViewController = lanuchVC
|
||||
window?.makeKeyAndVisible()
|
||||
|
||||
self.requestLocalizedData()
|
||||
|
||||
} else {
|
||||
VPLocalizedManager.shared.updateLocalizedData(completer: nil)
|
||||
|
||||
setRootVC()
|
||||
}
|
||||
}
|
||||
|
||||
private func setRootVC() {
|
||||
let hasOpenApp = UserDefaults.standard.object(forKey: kVPHasBeenOpenedAPPDefaultsKey) as? Bool
|
||||
|
||||
if hasOpenApp != true {
|
||||
///引导页
|
||||
let guideVc = VPGuideViewController()
|
||||
guideVc.clickOpenButton = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
|
||||
self.setTabBarController()
|
||||
self.vp_retryHandleOpenAppMessage()
|
||||
|
||||
}
|
||||
window?.rootViewController = guideVc
|
||||
window?.makeKeyAndVisible()
|
||||
} else {
|
||||
setTabBarController()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension SceneDelegate {
|
||||
@objc private func handleOnLine() {
|
||||
VPStatAPI.requestStatOnLine()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@objc private func reachabilityDidChangeNotification() {
|
||||
vp_retryHandleOpenAppMessage()
|
||||
|
||||
if VPNetworkReachabilityManager.manager.isReachable == true {
|
||||
handleOnLine()
|
||||
|
||||
let data = VPLocalizedManager.shared.localizedData ?? [:]
|
||||
if data.isEmpty {
|
||||
requestLocalizedData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func localizedDidChangeNotification() {
|
||||
MJRefreshConfig.default.languageCode = VPLocalizedManager.shared.mjLocalizedKey
|
||||
setTabBarController()
|
||||
}
|
||||
|
||||
|
||||
private func requestLocalizedData() {
|
||||
VPLocalizedManager.shared.updateLocalizedData { [weak self] finish in
|
||||
guard let self = self else { return }
|
||||
self.setRootVC()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -84,10 +84,10 @@ extension VPTabBarController {
|
||||
|
||||
|
||||
|
||||
let nav1 = createNavigationController(viewController: VPHomePageViewController(), title: "Home".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected"))
|
||||
let nav2 = createNavigationController(viewController: VPExploreViewController(), title: "Explore".localized, image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected"))
|
||||
let nav3 = createNavigationController(viewController: VPMyListViewController(), title: "My List".localized, image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected"))
|
||||
let nav4 = createNavigationController(viewController: VPMeViewController(), title: "Me".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
||||
let nav1 = createNavigationController(viewController: VPHomePageViewController(), title: "veloria_home".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected"))
|
||||
let nav2 = createNavigationController(viewController: VPExploreViewController(), title: "veloria_explore".localized, image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected"))
|
||||
let nav3 = createNavigationController(viewController: VPMyListViewController(), title: "veloria_my_list".localized, image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected"))
|
||||
let nav4 = createNavigationController(viewController: VPMeViewController(), title: "veloria_me".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
||||
|
||||
viewControllers = [nav1, nav2, nav3, nav4]
|
||||
|
||||
|
@ -23,11 +23,11 @@ public let kVPAPPName: String = (Bundle.main.infoDictionary!["CFBundleDisplayNam
|
||||
|
||||
//MARK: ------- 打印信息 ----------
|
||||
#if DEBUG
|
||||
public func vpLog(message:Any? , file: String = #file, function: String = #function, line: Int = #line) {
|
||||
public func vpLog(message: Any? , file: String = #file, function: String = #function, line: Int = #line) {
|
||||
print("\n\(Date(timeIntervalSinceNow: 8 * 60 * 60)) \(file.components(separatedBy: "/").last ?? "") \(function) \(line): \(message ?? "")")
|
||||
}
|
||||
#else
|
||||
public func vpLog(message:Any?) { }
|
||||
public func vpLog(message: Any?) { }
|
||||
#endif
|
||||
|
||||
public func vp_swizzled_instanceMethod(_ prefix: String, oldClass: Swift.AnyClass!, oldSelector: String, newClass: Swift.AnyClass) {
|
||||
|
@ -24,3 +24,6 @@ let kVPApnsAlertDefaultsKey = "kVPApnsAlertDefaultsKey"
|
||||
|
||||
///vip弹窗时间
|
||||
let kVPVipAlertDateDefaultsKey = "kVPVipAlertDateDefaultsKey"
|
||||
|
||||
///是否开启过APP
|
||||
let kVPHasBeenOpenedAPPDefaultsKey = "kVPHasBeenOpenedAPPDefaultsKey"
|
||||
|
34
Veloria/Base/Networking/API/VPSettingAPI.swift
Normal file
34
Veloria/Base/Networking/API/VPSettingAPI.swift
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// VPSettingAPI.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/12.
|
||||
//
|
||||
|
||||
class VPSettingAPI {
|
||||
|
||||
///获取语言列表
|
||||
static func requestLanguageList(completer: ((_ list: [VPLanguageModel]?) -> Void)?) {
|
||||
|
||||
var param = VPNetworkParameters(path: "/languges")
|
||||
param.method = .get
|
||||
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPListModel<VPLanguageModel>>) in
|
||||
completer?(response.data?.list)
|
||||
}
|
||||
}
|
||||
|
||||
///获取本地化数据
|
||||
static func requestLocalizedData(key: String, completer: ((_ model: VPLocalizedModel?) -> Void)?) {
|
||||
var param = VPNetworkParameters(path: "/translates")
|
||||
param.method = .get
|
||||
param.parameters = [
|
||||
"lang_key" : key
|
||||
]
|
||||
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPLocalizedModel>) in
|
||||
completer?(response.data)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -95,7 +95,7 @@ class VPWalletAPI {
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPIAPOrderModel>) in
|
||||
if let message = response.data?.message, message.count > 0 {
|
||||
if response.data?.code == 30007 {
|
||||
VPToast.show(text: "kVipToast01".localized)
|
||||
VPToast.show(text: "veloria_vip_error_1".localized)
|
||||
} else {
|
||||
VPToast.show(text: message)
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ class VPNetwork: NSObject {
|
||||
completion?(res)
|
||||
} else {
|
||||
if code == 402, parameters.isToast {
|
||||
VPToast.show(text: "kNetworkToast02".localized)
|
||||
VPToast.show(text: "veloria_network_error_1".localized)
|
||||
}
|
||||
///重新获取token
|
||||
self.requestToken { token in
|
||||
@ -144,7 +144,7 @@ class VPNetwork: NSObject {
|
||||
var res = VPNetworkResponse<T>()
|
||||
res.code = -1
|
||||
if parameters.isToast {
|
||||
VPToast.show(text: "kNetworkToast01".localized)
|
||||
VPToast.show(text: "veloria_network".localized)
|
||||
}
|
||||
completion?(res)
|
||||
break
|
||||
|
@ -23,6 +23,7 @@ class VPNetworkReachabilityManager {
|
||||
|
||||
monitor.pathUpdateHandler = { [weak self] path in
|
||||
guard let self = self else { return }
|
||||
|
||||
if path.status == .satisfied {
|
||||
if self.isReachable == false {
|
||||
self.isReachable = true
|
||||
@ -32,7 +33,7 @@ class VPNetworkReachabilityManager {
|
||||
} else {
|
||||
self.isReachable = true
|
||||
}
|
||||
|
||||
vpLog(message: "+++++++++++++++网络变化==有网")
|
||||
} else {
|
||||
if self.isReachable == true {
|
||||
self.isReachable = false
|
||||
@ -42,6 +43,7 @@ class VPNetworkReachabilityManager {
|
||||
} else {
|
||||
self.isReachable = false
|
||||
}
|
||||
vpLog(message: "+++++++++++++++网络变化==无网")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,13 +19,13 @@ class VPCampaignWebViewController: VPWebViewController {
|
||||
super.viewDidLoad()
|
||||
autoTitle = false
|
||||
if urlStr == kVPFeedBackListWebUrl {
|
||||
self.title = "Feedback History".localized
|
||||
self.title = "veloria_my_feedback_history".localized
|
||||
} else if urlStr == kVPFeedBackHomeWebUrl {
|
||||
self.title = "Feedback".localized
|
||||
self.title = "veloria_my_feedback".localized
|
||||
} else if urlStr == kVPFeedBackDetailWebUrl {
|
||||
self.title = "Feedback Details".localized
|
||||
self.title = "veloria_my_feedback_details".localized
|
||||
} else if urlStr == kVPRewardsWebUrl {
|
||||
self.title = "Rewards".localized
|
||||
self.title = "veloria_rewards".localized
|
||||
}
|
||||
|
||||
self.webView.scrollView.vp_addRefreshHeader { [weak self] in
|
||||
|
@ -11,14 +11,15 @@ class VPExplorePlayerControlView: VPVideoPlayerControlView {
|
||||
|
||||
override var videoInfo: VPVideoInfoModel? {
|
||||
didSet {
|
||||
epLabel.text = String(format: "EP.%@".localized, videoInfo?.episode ?? "0")
|
||||
|
||||
epLabel.text = "veloria_EP.".localizedReplace(text: videoInfo?.episode ?? "0")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override var shortModel: VPShortModel? {
|
||||
didSet {
|
||||
allView.setTitle(String(format: "All %@ Episodes".localized, "\(shortModel?.episode_total ?? 0)"), for: .normal)
|
||||
allView.setTitle("veloria_all_episodes".localizedReplace(text: "\(shortModel?.episode_total ?? 0)"), for: .normal)
|
||||
videoNameLabel.text = shortModel?.name
|
||||
}
|
||||
}
|
||||
|
63
Veloria/Class/Guide/VPGuideViewController.swift
Normal file
63
Veloria/Class/Guide/VPGuideViewController.swift
Normal file
@ -0,0 +1,63 @@
|
||||
//
|
||||
// VPGuideViewController.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/12.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPGuideViewController: VPViewController {
|
||||
|
||||
var clickOpenButton: (() -> Void)?
|
||||
|
||||
private(set) lazy var lanuchVC: UIViewController? = {
|
||||
let vc = VPAppTool.lanuchViewController
|
||||
return vc
|
||||
}()
|
||||
|
||||
private lazy var openButton: VPGradientButton = {
|
||||
let button = VPGradientButton(type: .custom)
|
||||
button.colors = [UIColor.color05CEA0(alpha: 0.3).cgColor, UIColor.color7C174F(alpha: 0.3).cgColor]
|
||||
button.locations = [0, 1]
|
||||
button.startPoint = .init(x: 0, y: 0.3)
|
||||
button.endPoint = .init(x: 1, y: 0.8)
|
||||
button.bt_setGradientBorder()
|
||||
button.layer.cornerRadius = 24
|
||||
button.setTitle("veloria_get_started".localized, for: .normal)
|
||||
button.addTarget(self, action: #selector(handleOpenButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
@objc private func handleOpenButton() {
|
||||
UserDefaults.standard.set(true, forKey: kVPHasBeenOpenedAPPDefaultsKey)
|
||||
self.clickOpenButton?()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPGuideViewController {
|
||||
|
||||
private func vp_setupUI() {
|
||||
if let vc = lanuchVC {
|
||||
addChild(vc)
|
||||
view.addSubview(vc.view)
|
||||
}
|
||||
|
||||
view.addSubview(openButton)
|
||||
|
||||
openButton.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.height.equalTo(48)
|
||||
make.width.equalTo(180)
|
||||
make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 100))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -84,7 +84,7 @@ class VPHomePageViewController: VPViewController {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 17)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "kHomeMenuTitle".localized
|
||||
label.text = "veloria_select_categories".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -105,7 +105,7 @@ class VPHomePageViewController: VPViewController {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 16)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "kHomeTitleText".localized
|
||||
label.text = "veloria_addictive_short_await".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
|
@ -34,7 +34,7 @@ class VPHomeRankingContentCell: VPHomeItemContentCell {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 15)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "Drama Champions".localized
|
||||
label.text = "veloria_drama_champions".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -44,7 +44,7 @@ class VPHomeRankingContentCell: VPHomeItemContentCell {
|
||||
config.imagePlacement = .trailing
|
||||
config.contentInsets = .init(top: 5, leading: 0, bottom: 5, trailing: 0)
|
||||
config.image = UIImage(named: "arrow_right_icon_03")
|
||||
config.attributedTitle = AttributedString.createAttributedString(string: "More".localized, color: .colorFFFFFF(alpha: 0.5), font: .fontRegular(ofSize: 12))
|
||||
config.attributedTitle = AttributedString.createAttributedString(string: "veloria_more".localized, color: .colorFFFFFF(alpha: 0.5), font: .fontRegular(ofSize: 12))
|
||||
let button = UIButton(configuration: config)
|
||||
button.addTarget(self, action: #selector(handleMoreButton), for: .touchUpInside)
|
||||
return button
|
||||
|
@ -38,7 +38,7 @@ class VPHomeRecommandContentCell: VPHomeItemContentCell {
|
||||
config.imagePlacement = .trailing
|
||||
config.contentInsets = .init(top: 5, leading: 0, bottom: 5, trailing: 0)
|
||||
config.image = UIImage(named: "arrow_right_icon_03")
|
||||
config.attributedTitle = AttributedString.createAttributedString(string: "More".localized, color: .colorFFFFFF(alpha: 0.5), font: .fontRegular(ofSize: 12))
|
||||
config.attributedTitle = AttributedString.createAttributedString(string: "veloria_more".localized, color: .colorFFFFFF(alpha: 0.5), font: .fontRegular(ofSize: 12))
|
||||
let button = UIButton(configuration: config)
|
||||
button.addTarget(self, action: #selector(handleMoreButton), for: .touchUpInside)
|
||||
return button
|
||||
|
@ -34,7 +34,7 @@ class VPHomeSearchButton: UIControl {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF(alpha: 0.3)
|
||||
label.text = "kSearchPlaceholderText1".localized
|
||||
label.text = "veloria_search_dramas".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -87,7 +87,7 @@ extension VPHomeSearchButton: VPMarqueeViewDataSource {
|
||||
func marqueeView(_ marqueeView: VPMarqueeView, cellForItemAt index: Int) -> NSAttributedString {
|
||||
var text: String
|
||||
if marqueeArr.count == 0 {
|
||||
text = "kSearchPlaceholderText1".localized
|
||||
text = "veloria_search_dramas".localized
|
||||
} else {
|
||||
text = marqueeArr[index].name ?? ""
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class VPSearchHistoryView: UIView {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 13)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "Recent Searches".localized
|
||||
label.text = "veloria_recent_searches".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
|
@ -29,7 +29,7 @@ class VPSearchInputView: UIView {
|
||||
let textField = VPTextField()
|
||||
textField.font = .fontRegular(ofSize: 14)
|
||||
textField.returnKeyType = .search
|
||||
textField.vp_placeholder = "kSearchPlaceholderText2".localized
|
||||
textField.vp_placeholder = "veloria_recersal_of_fate".localized
|
||||
textField.vp_placeholderFont = textField.font
|
||||
textField.textDidChange = { [weak self] text in
|
||||
self?.textDidChange?(text)
|
||||
|
@ -18,7 +18,7 @@ class VPSearchRecommendedView: UIView {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 15)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "Recommended For You".localized
|
||||
label.text = "veloria_recommended".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -40,7 +40,7 @@ class VPSearchRecommendedView: UIView {
|
||||
view.borderColors = [UIColor.colorFBF2C7(alpha: 0.6).cgColor, UIColor.colorA8A38E(alpha: 0.4).cgColor, UIColor.color555555(alpha: 0.3).cgColor, UIColor.colorFBF2C7(alpha: 0.05).cgColor]
|
||||
view.titleColors = [UIColor.colorFBF2C7().cgColor, UIColor.colorA87A46().cgColor]
|
||||
view.iconImage = UIImage(named: "top_icon_01")
|
||||
view.title = "Trending Top 10".localized
|
||||
view.title = "veloria_trending_top".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
@ -49,7 +49,7 @@ class VPSearchRecommendedView: UIView {
|
||||
view.borderColors = [UIColor.colorFFBFBE(alpha: 0.6).cgColor, UIColor.colorFFBFBE(alpha: 0.4).cgColor, UIColor.color555555(alpha: 0.3).cgColor, UIColor.colorFFBFBE(alpha: 0.05).cgColor]
|
||||
view.titleColors = [UIColor.colorFFBFBE().cgColor, UIColor.colorD87675().cgColor]
|
||||
view.iconImage = UIImage(named: "hot_icon_02")
|
||||
view.title = "Latest Trends".localized
|
||||
view.title = "veloria_latest_trends".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
|
@ -24,7 +24,7 @@ class VPSearchResultView: UIView {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 13)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "Search Results".localized
|
||||
label.text = "veloria_search_results".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -42,7 +42,7 @@ class VPSearchResultView: UIView {
|
||||
collectionView.dataSource = self
|
||||
collectionView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin + 10, right: 0)
|
||||
collectionView.register(VPSearchResultCell.self, forCellWithReuseIdentifier: "cell")
|
||||
collectionView.vp_addNormalEmpty(image: UIImage(named: "empty_image_02"), title: "kEmptyTitle02".localized, des: "kEmptyDes02".localized)
|
||||
collectionView.vp_addNormalEmpty(image: UIImage(named: "empty_image_02"), title: "veloria_not_found".localized, des: "veloria_not_found_string".localized)
|
||||
collectionView.keyboardDismissMode = .onDrag
|
||||
return collectionView
|
||||
}()
|
||||
|
@ -29,7 +29,7 @@ class VPHomeViewModel: VPModel {
|
||||
var rawCategoryList: [VPCategoryModel] = [] {
|
||||
didSet {
|
||||
let allCategory = VPCategoryModel()
|
||||
allCategory.name = "All".localized
|
||||
allCategory.name = "veloria_all".localized
|
||||
allCategory.id = "0"
|
||||
|
||||
categoryList.removeAll()
|
||||
@ -65,7 +65,7 @@ class VPHomeViewModel: VPModel {
|
||||
categoryTitleList.removeAll()
|
||||
|
||||
let allCategory = VPCategoryModel()
|
||||
allCategory.name = "All".localized
|
||||
allCategory.name = "veloria_all".localized
|
||||
allCategory.id = "0"
|
||||
categoryList.append(allCategory)
|
||||
categoryList += ($0.categoryList ?? [])
|
||||
|
@ -25,14 +25,15 @@ class VPLoginContentView: HWPanModalContentView {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 16)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = String(format: "Welcome to %@".localized, "kAppName".localized)
|
||||
label.text = "veloria_welcome_to".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var agreementLabel: YYLabel = {
|
||||
let userAgreementText = "User Agreement".localized
|
||||
let privacyPolicyText = "Privacy Policy".localized
|
||||
let text = String(format: "kLoginAgreementText".localized, userAgreementText, privacyPolicyText)
|
||||
let userAgreementText = "veloria_my_agreement".localized
|
||||
let privacyPolicyText = "veloria_my_privacy".localized
|
||||
|
||||
let text = "veloria_login_hint_ios".localizedReplace(text1: userAgreementText, text2: privacyPolicyText)
|
||||
|
||||
let range1 = text.ocString().range(of: userAgreementText)
|
||||
let range2 = text.ocString().range(of: privacyPolicyText)
|
||||
@ -70,7 +71,7 @@ class VPLoginContentView: HWPanModalContentView {
|
||||
private lazy var appleButton: VPLoginButton = {
|
||||
let button = VPLoginButton()
|
||||
button.icon = UIImage(named: "apple_icon_01")
|
||||
button.title = "Login with Apple".localized
|
||||
button.title = "veloria_login_apple".localized
|
||||
button.addTarget(self, action: #selector(handleAppleButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
@ -78,7 +79,7 @@ class VPLoginContentView: HWPanModalContentView {
|
||||
private lazy var facebookButton: VPLoginButton = {
|
||||
let button = VPLoginButton()
|
||||
button.icon = UIImage(named: "facebook_icon_01")
|
||||
button.title = "Login with Facebook".localized
|
||||
button.title = "veloria_login_facebook".localized
|
||||
button.addTarget(self, action: #selector(handleFacebookButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
@ -11,12 +11,12 @@ class VPAboutUsViewController: VPViewController {
|
||||
|
||||
private lazy var dataArr: [VPMeItem] = {
|
||||
let arr = [
|
||||
VPMeItem(title: "User Agreement".localized, type: .userAgreement),
|
||||
VPMeItem(title: "Privacy Policy".localized, type: .privacyPolicy),
|
||||
VPMeItem(title: "Child Personal Information Protection Rules".localized, type: .informationProtection),
|
||||
VPMeItem(title: "Youth Internet Civility Convention".localized, type: .civizatioConvention),
|
||||
VPMeItem(title: "Third-party information sharing list".localized, type: .informationSharing),
|
||||
VPMeItem(title: "Explicit List of Personal Information Collection".localized, type: .persoInforDisclosure),
|
||||
VPMeItem(title: "veloria_my_agreement".localized, type: .userAgreement),
|
||||
VPMeItem(title: "veloria_my_privacy".localized, type: .privacyPolicy),
|
||||
VPMeItem(title: "veloria_child_protection_text".localized, type: .informationProtection),
|
||||
VPMeItem(title: "veloria_civizatio_convention_text".localized, type: .civizatioConvention),
|
||||
VPMeItem(title: "veloria_information_sharing_text".localized, type: .informationSharing),
|
||||
VPMeItem(title: "veloria_persoInfor_disclosure_text".localized, type: .persoInforDisclosure),
|
||||
]
|
||||
return arr
|
||||
}()
|
||||
@ -38,7 +38,7 @@ class VPAboutUsViewController: VPViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.title = "About Us".localized
|
||||
self.title = "veloria_me_about".localized
|
||||
|
||||
vp_setupUI()
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class VPDeleteAccountViewController: VPViewController {
|
||||
|
||||
button.configurationUpdateHandler = { button in
|
||||
guard let button = button as? VPGradientButton else { return }
|
||||
let title = "Delete Account".localized
|
||||
let title = "veloria_delete_account".localized
|
||||
|
||||
if button.isEnabled {
|
||||
button.configuration?.attributedTitle = .createAttributedString(string: title, color: .colorFFFFFF(), font: .fontRegular(ofSize: 14))
|
||||
@ -110,7 +110,7 @@ class VPDeleteAccountViewController: VPViewController {
|
||||
super.viewDidLoad()
|
||||
self.bgImageView.isHidden = true
|
||||
self.view.backgroundColor = .color080B16()
|
||||
self.title = "Account Deletion".localized
|
||||
self.title = "veloria_delete_account".localized
|
||||
|
||||
vp_setupUI()
|
||||
}
|
||||
@ -132,7 +132,7 @@ extension VPDeleteAccountViewController {
|
||||
}
|
||||
|
||||
@objc private func handleDeleteButton() {
|
||||
let alert = VPAlertView(title: "kDeleteAccountAlertTitle".localized, subtitle: "kDeleteAccountAlertText".localized, icon: UIImage(named: "alert_icon_01"), normalButtonText: "Delete Forever".localized, highlightButtonText: "Cancel".localized)
|
||||
let alert = VPAlertView(title: "veloria_confirm_deletion".localized, subtitle: "veloria_action_cannot_undone".localized, icon: UIImage(named: "alert_icon_01"), normalButtonText: "veloria_delete_forever".localized, highlightButtonText: "veloria_cancel".localized)
|
||||
alert.show()
|
||||
|
||||
alert.clickNormalButton = {
|
||||
|
102
Veloria/Class/Me/Controller/VPLanguageViewController.swift
Normal file
102
Veloria/Class/Me/Controller/VPLanguageViewController.swift
Normal file
@ -0,0 +1,102 @@
|
||||
//
|
||||
// VPLanguageViewController.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/12.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPLanguageViewController: VPViewController {
|
||||
|
||||
|
||||
private lazy var dataArr: [VPLanguageModel] = []
|
||||
|
||||
private lazy var currentLocalizedKey = VPLocalizedManager.shared.currentLocalizedKey
|
||||
|
||||
private lazy var tableView: VPTableView = {
|
||||
let tableView = VPTableView(frame: .zero, style: .plain)
|
||||
tableView.delegate = self
|
||||
tableView.dataSource = self
|
||||
tableView.rowHeight = 60
|
||||
tableView.separatorStyle = .none
|
||||
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin + 10, right: 0)
|
||||
tableView.register(VPLanguageCell.self, forCellReuseIdentifier: "cell")
|
||||
return tableView
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.title = "veloria_language".localized
|
||||
requestDataList()
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
||||
setNavigationNormalStyle()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPLanguageViewController {
|
||||
private func vp_setupUI() {
|
||||
view.addSubview(tableView)
|
||||
|
||||
tableView.snp.makeConstraints { make in
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(UIScreen.navBarHeight)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- UITableViewDelegate UITableViewDataSource --------------
|
||||
extension VPLanguageViewController: UITableViewDelegate, UITableViewDataSource {
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let model = dataArr[indexPath.row]
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! VPLanguageCell
|
||||
cell.model = model
|
||||
cell.vp_isSelected = model.lang_key == currentLocalizedKey
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return dataArr.count
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let model = dataArr[indexPath.row]
|
||||
|
||||
if model.lang_key == currentLocalizedKey { return }
|
||||
|
||||
if let key = model.lang_key {
|
||||
VPHUD.show()
|
||||
VPLocalizedManager.shared.updateLocalizedData(key: key) { (finish) in
|
||||
if finish {
|
||||
VPLocalizedManager.shared.currentLocalizedKey = key
|
||||
NotificationCenter.default.post(name: VPLocalizedManager.localizedDidChangeNotification, object: nil)
|
||||
}
|
||||
VPHUD.dismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPLanguageViewController {
|
||||
|
||||
private func requestDataList() {
|
||||
VPSettingAPI.requestLanguageList { [weak self] list in
|
||||
guard let self = self else { return }
|
||||
if let list = list {
|
||||
self.dataArr = list
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -192,6 +192,10 @@ extension VPMeViewController: UITableViewDelegate, UITableViewDataSource {
|
||||
let vc = VPWalletViewController()
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
case .language:
|
||||
let vc = VPLanguageViewController()
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -228,15 +232,15 @@ extension VPMeViewController {
|
||||
]
|
||||
|
||||
var cellArr: [VPMeItem] = []
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_07"), title: "Order Record".localized, type: .orderRecord, cellKey: .normal))
|
||||
// cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_05"), title: "Language".localized, type: .language, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_07"), title: "veloria_order_record".localized, type: .orderRecord, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_05"), title: "veloria_language".localized, type: .language, cellKey: .normal))
|
||||
if VPLoginManager.manager.userInfo?.is_tourist == false {
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_06"), title: "Delete Account".localized, type: .deleteAccount, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_06"), title: "veloria_delete_account".localized, type: .deleteAccount, cellKey: .normal))
|
||||
}
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_01"), title: "Privacy Policy".localized, type: .privacyPolicy, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_02"), title: "User Agreement".localized, type: .userAgreement, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_04"), title: "Feedback".localized, type: .feedback, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_03"), title: "About Us".localized, type: .aboutUs, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_01"), title: "veloria_my_privacy".localized, type: .privacyPolicy, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_02"), title: "veloria_my_agreement".localized, type: .userAgreement, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_04"), title: "veloria_my_feedback".localized, type: .feedback, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_03"), title: "veloria_me_about".localized, type: .aboutUs, cellKey: .normal))
|
||||
|
||||
|
||||
dataArr.append(cellArr)
|
||||
|
20
Veloria/Class/Me/Model/VPLanguageModel.swift
Normal file
20
Veloria/Class/Me/Model/VPLanguageModel.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// VPLanguageModel.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/12.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class VPLanguageModel: VPModel, SmartCodable {
|
||||
|
||||
var cn_name: String?
|
||||
var show_name: String?
|
||||
var id: String?
|
||||
var is_up_to_list: String?
|
||||
var lang_key: String?
|
||||
// var description: String?
|
||||
var is_default: Int?
|
||||
}
|
62
Veloria/Class/Me/View/VPLanguageCell.swift
Normal file
62
Veloria/Class/Me/View/VPLanguageCell.swift
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// VPLanguageCell.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/12.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPLanguageCell: VPTableViewCell {
|
||||
|
||||
var model: VPLanguageModel? {
|
||||
didSet {
|
||||
titleLabel.text = model?.show_name
|
||||
}
|
||||
}
|
||||
|
||||
var vp_isSelected: Bool = false {
|
||||
didSet {
|
||||
selectedVew.isSelected = vp_isSelected
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF()
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var selectedVew: UIButton = {
|
||||
let view = UIButton(type: .custom)
|
||||
view.isUserInteractionEnabled = false
|
||||
view.setImage(UIImage(named: "choice_icon_01"), for: .normal)
|
||||
view.setImage(UIImage(named: "choice_icon_01_selected"), for: .selected)
|
||||
return view
|
||||
}()
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
contentView.addSubview(titleLabel)
|
||||
contentView.addSubview(selectedVew)
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(15)
|
||||
}
|
||||
|
||||
selectedVew.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.right.equalToSuperview().offset(-15)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -24,13 +24,13 @@ class VPMeCoinCell: VPTableViewCell {
|
||||
|
||||
private lazy var coinView1: VPMeCoinItemView = {
|
||||
let view = VPMeCoinItemView()
|
||||
view.title = "Conins".localized
|
||||
view.title = "coins".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var coinView2: VPMeCoinItemView = {
|
||||
let view = VPMeCoinItemView()
|
||||
view.title = "Donate".localized
|
||||
view.title = "veloria_bonus".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
|
@ -21,9 +21,9 @@ class VPMeFooterView: UIView {
|
||||
button.layer.masksToBounds = true
|
||||
button.layer.borderColor = UIColor.color585858().cgColor
|
||||
button.layer.borderWidth = 1
|
||||
button.setTitle("Log In".localized, for: .normal)
|
||||
button.setTitle("Sign Out".localized, for: .selected)
|
||||
button.setTitle("Sign Out".localized, for: [.selected, .highlighted])
|
||||
button.setTitle("veloria_login".localized, for: .normal)
|
||||
button.setTitle("veloria_sign_out".localized, for: .selected)
|
||||
button.setTitle("veloria_sign_out".localized, for: [.selected, .highlighted])
|
||||
button.setTitleColor(.colorB3B3B3(), for: .normal)
|
||||
button.titleLabel?.font = .fontRegular(ofSize: 14)
|
||||
button.addTarget(self, action: #selector(handleButton), for: .touchUpInside)
|
||||
@ -53,7 +53,7 @@ class VPMeFooterView: UIView {
|
||||
if userInfo?.is_tourist == true {
|
||||
VPLoginManager.manager.openLogin()
|
||||
} else {
|
||||
let alert = VPAlertView(title: "kLogoutAlertTitle".localized, subtitle: "kLogoutAlertText".localized, icon: UIImage(named: "alert_icon_02"), normalButtonText: "Log Out".localized, highlightButtonText: "Cancel".localized).show()
|
||||
let alert = VPAlertView(title: "veloria_ready_to_leave".localized, subtitle: "veloria_ready_to_leave_text".localized, icon: UIImage(named: "alert_icon_02"), normalButtonText: "veloria_log_out".localized, highlightButtonText: "veloria_cancel".localized).show()
|
||||
alert.clickNormalButton = {
|
||||
VPLoginManager.manager.logout(completer: nil)
|
||||
}
|
||||
|
@ -19,25 +19,25 @@ class VPMeToolCell: VPTableViewCell {
|
||||
}()
|
||||
|
||||
private lazy var walletButton: UIButton = {
|
||||
let button = self.createButton(icon: UIImage(named: "wallet_icon_01"), title: "Wallet".localized)
|
||||
let button = self.createButton(icon: UIImage(named: "wallet_icon_01"), title: "veloria_wallet".localized)
|
||||
button.addTarget(self, action: #selector(handleWalletButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var storeButton: UIButton = {
|
||||
let button = self.createButton(icon: UIImage(named: "store_icon_01"), title: "Store".localized)
|
||||
let button = self.createButton(icon: UIImage(named: "store_icon_01"), title: "veloria_store".localized)
|
||||
button.addTarget(self, action: #selector(handleStoreButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var rewardsButton: UIButton = {
|
||||
let button = self.createButton(icon: UIImage(named: "rewards_icon_01"), title: "Rewards".localized)
|
||||
let button = self.createButton(icon: UIImage(named: "rewards_icon_01"), title: "veloria_rewards".localized)
|
||||
button.addTarget(self, action: #selector(handleRewardsButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var favoritesButton: UIButton = {
|
||||
let button = self.createButton(icon: UIImage(named: "favorites_icon_01"), title: "Favorites".localized)
|
||||
let button = self.createButton(icon: UIImage(named: "favorites_icon_01"), title: "veloria_favorites".localized)
|
||||
button.addTarget(self, action: #selector(handleFavoritesButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
@ -17,7 +17,7 @@ class VPMeUserInfoCell: VPTableViewCell {
|
||||
if let name = userInfo?.family_name, name.count > 0 {
|
||||
nicknameLabel.text = name
|
||||
} else {
|
||||
nicknameLabel.text = "Visitor".localized
|
||||
nicknameLabel.text = "veloria_visitor".localized
|
||||
}
|
||||
|
||||
idLabel.text = "ID \(userInfo?.customer_id ?? "")"
|
||||
@ -51,7 +51,7 @@ class VPMeUserInfoCell: VPTableViewCell {
|
||||
}()
|
||||
|
||||
private lazy var loginButton: VPGradientButton = {
|
||||
let title = AttributedString.createAttributedString(string: "Check in".localized, color: .colorFFFFFF(), font: .fontRegular(ofSize: 12))
|
||||
let title = AttributedString.createAttributedString(string: "veloria_check_in".localized, color: .colorFFFFFF(), font: .fontRegular(ofSize: 12))
|
||||
|
||||
var config = UIButton.Configuration.plain()
|
||||
config.imagePlacement = .leading
|
||||
|
@ -14,11 +14,11 @@ class VPMeVipCell: VPTableViewCell {
|
||||
didSet {
|
||||
if userInfo?.is_vip == true {
|
||||
let date = Date(timeIntervalSince1970: userInfo?.vip_end_time ?? 0)
|
||||
subtitleLabel.text = String(format: "kVipTipText2".localized, date.formatString(dateFormat: "yyyy-MM-dd"))
|
||||
titleLabel.text = "VIP Active".localized
|
||||
subtitleLabel.text = "veloria_vip_expires_date".localizedReplace(text: date.formatString(dateFormat: "yyyy-MM-dd"))
|
||||
titleLabel.text = "veloria_vip_active".localized
|
||||
} else {
|
||||
subtitleLabel.text = "kVipTipText1".localized
|
||||
titleLabel.text = "Join VIP".localized
|
||||
subtitleLabel.text = "veloria_unlock_exclusive".localized
|
||||
titleLabel.text = "veloria_vip_join".localized
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -63,21 +63,21 @@ class VPMeVipCell: VPTableViewCell {
|
||||
private lazy var itemView1: VPMeVipPrivilegeItemView = {
|
||||
let view = VPMeVipPrivilegeItemView()
|
||||
view.icon = UIImage(named: "privilege_icon_01")
|
||||
view.title = "kVipPrivilegeText1".localized
|
||||
view.title = "veloria_ad_free_streaming_ios".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var itemView2: VPMeVipPrivilegeItemView = {
|
||||
let view = VPMeVipPrivilegeItemView()
|
||||
view.icon = UIImage(named: "privilege_icon_02")
|
||||
view.title = "kVipPrivilegeText2".localized
|
||||
view.title = "veloria_exclusive_episodes_ios".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var itemView3: VPMeVipPrivilegeItemView = {
|
||||
let view = VPMeVipPrivilegeItemView()
|
||||
view.icon = UIImage(named: "privilege_icon_03")
|
||||
view.title = "kVipPrivilegeText3".localized
|
||||
view.title = "veloria_daily_free_coins_ios".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
|
@ -46,7 +46,8 @@ class VPVipAlertView: VPBaseAlertView {
|
||||
if let coin = model?.send_coins, coin > 0 {
|
||||
extraBgView.isHidden = false
|
||||
|
||||
let text = String(format: "Extra %@".localized, "\(coin)")
|
||||
let text = "veloria_extra".localized + " \(coin)"
|
||||
// let text = String(format: "Extra %@".localized, "\(coin)")
|
||||
extraLabel.text = "+" + text
|
||||
} else {
|
||||
extraBgView.isHidden = true
|
||||
@ -74,7 +75,7 @@ class VPVipAlertView: VPBaseAlertView {
|
||||
private lazy var unlockButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setBackgroundImage(UIImage(named: "vip_unlock_button"), for: .normal)
|
||||
button.setTitle("kUnlockButtonText".localized, for: .normal)
|
||||
button.setTitle("veloria_vip_splash_onclick".localized, for: .normal)
|
||||
button.setTitleColor(.color005D48(), for: .normal)
|
||||
button.titleLabel?.font = .fontMedium(ofSize: 14)
|
||||
button.addTarget(self, action: #selector(hadnleUnlockButton), for: .touchUpInside)
|
||||
@ -85,7 +86,7 @@ class VPVipAlertView: VPBaseAlertView {
|
||||
let label = UILabel()
|
||||
label.font = .fontBold(ofSize: 16)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "kVipAlertTitle".localized
|
||||
label.text = "veloria_vip_splash_title".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -93,7 +94,7 @@ class VPVipAlertView: VPBaseAlertView {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 14)
|
||||
label.textColor = .colorC5C5C5()
|
||||
label.text = "kVipAlertText".localized
|
||||
label.text = "veloria_vip_splash_content".localized
|
||||
label.numberOfLines = 0
|
||||
label.textAlignment = .center
|
||||
return label
|
||||
@ -182,13 +183,16 @@ extension VPVipAlertView {
|
||||
|
||||
@objc private func hadnleUnlockButton() {
|
||||
guard let model = model else { return }
|
||||
self.dismiss()
|
||||
let vc = VPVipPageViewController()
|
||||
VPAppTool.topViewController?.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
VPIAPManager.manager.start(model: model) { [weak self] finish in
|
||||
if finish {
|
||||
self?.dismiss()
|
||||
VPLoginManager.manager.updateUserInfo(completer: nil)
|
||||
}
|
||||
}
|
||||
// VPIAPManager.manager.start(model: model) { [weak self] finish in
|
||||
// if finish {
|
||||
// self?.dismiss()
|
||||
// VPLoginManager.manager.updateUserInfo(completer: nil)
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -72,7 +72,7 @@ class VPCollectListViewController: VPViewController {
|
||||
|
||||
private lazy var allSelectedButton: UIButton = {
|
||||
var config = UIButton.Configuration.plain()
|
||||
config.attributedTitle = AttributedString.createAttributedString(string: "Select All".localized, color: .colorFFFFFF(), font: .fontRegular(ofSize: 15))
|
||||
config.attributedTitle = AttributedString.createAttributedString(string: "veloria_all_select".localized, color: .colorFFFFFF(), font: .fontRegular(ofSize: 15))
|
||||
config.imagePadding = 6
|
||||
config.imagePlacement = .leading
|
||||
config.baseBackgroundColor = .clear
|
||||
@ -169,7 +169,7 @@ class VPCollectListViewController: VPViewController {
|
||||
if count > 0 {
|
||||
requestCancelCollect()
|
||||
} else {
|
||||
VPToast.show(text: "kToastText1".localized)
|
||||
VPToast.show(text: "veloria_delete_short_tip".localized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class VPMyListViewController: VPViewController {
|
||||
|
||||
private lazy var pageParam: WMZPageParam = {
|
||||
let param = WMZPageParam()
|
||||
param.wTitleArr = ["My List".localized, "History".localized]
|
||||
param.wTitleArr = ["veloria_my_list".localized, "veloria_history".localized]
|
||||
param.wViewController = { [weak self] index in
|
||||
return self?.viewControllers[index]
|
||||
}
|
||||
|
@ -18,13 +18,14 @@ class VPWatchHistoryCell: VPTableViewCell {
|
||||
|
||||
let epString = NSMutableAttributedString()
|
||||
|
||||
let currentEP = NSMutableAttributedString(string: String(format: "EP.%@".localized, model?.current_episode ?? ""))
|
||||
let currentEP = NSMutableAttributedString(string: "veloria_EP.".localizedReplace(text: model?.current_episode ?? ""))
|
||||
currentEP.color = .color05CEA0()
|
||||
epString.append(currentEP)
|
||||
|
||||
let totalEp = NSMutableAttributedString()
|
||||
totalEp.appendString(" / ")
|
||||
totalEp.appendString(String(format: "EP.%@".localized, "\(model?.episode_total ?? 0)"))
|
||||
|
||||
totalEp.appendString("veloria_all_episodes".localizedReplace(text: "\(model?.episode_total ?? 0)"))
|
||||
totalEp.color = .colorFFFFFF(alpha: 0.6)
|
||||
epString.append(totalEp)
|
||||
|
||||
|
@ -191,10 +191,10 @@ extension VPDetailPlayerViewController {
|
||||
|
||||
switch model.status {
|
||||
case .jump:
|
||||
VPToast.show(text: "kLockPreviousEpisodeText".localized)
|
||||
VPToast.show(text: "veloria_jump_unlock_error".localized)
|
||||
|
||||
case .noPlay:
|
||||
VPToast.show(text: "kLockFailText".localized)
|
||||
VPToast.show(text: "veloria_jump_unlock_error_1".localized)
|
||||
|
||||
case .notEnough:
|
||||
self.onRecharge()
|
||||
|
@ -26,7 +26,8 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView {
|
||||
|
||||
override var videoInfo: VPVideoInfoModel? {
|
||||
didSet {
|
||||
epView.setTitle(String(format: "EP.%@".localized, "\(videoInfo?.episode ?? "0")"), for: .normal)
|
||||
|
||||
epView.setTitle("veloria_EP.".localizedReplace(text: videoInfo?.episode ?? "0"), for: .normal)
|
||||
lockView.isHidden = !(videoInfo?.is_lock ?? false)
|
||||
lockView.videoInfo = videoInfo
|
||||
}
|
||||
@ -34,7 +35,7 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView {
|
||||
|
||||
override var shortModel: VPShortModel? {
|
||||
didSet {
|
||||
allEpView.setTitle(String(format: "All %@ Episodes".localized, "\(shortModel?.episode_total ?? 0)"), for: .normal)
|
||||
allEpView.setTitle("veloria_all_episodes".localizedReplace(text: "\(shortModel?.episode_total ?? 0)"), for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ class VPDetailRecommandView: HWPanModalContentView {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 16)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "kDetailRecommandTitle".localized
|
||||
label.text = "veloria_detail_recommand_title".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -117,7 +117,7 @@ class VPDetailRecommandView: HWPanModalContentView {
|
||||
button.startPoint = .init(x: 0, y: 0.3)
|
||||
button.endPoint = .init(x: 1, y: 0.8)
|
||||
button.bt_setGradientBorder()
|
||||
button.setTitle("Watch Now".localized, for: .normal)
|
||||
button.setTitle("veloria_watch_now".localized, for: .normal)
|
||||
button.setTitleColor(.colorFFFFFF(), for: .normal)
|
||||
button.titleLabel?.font = .fontMedium(ofSize: 14)
|
||||
button.layer.cornerRadius = 24
|
||||
|
@ -48,7 +48,7 @@ class VPPlayerCoinBuyView: UIView {
|
||||
label.numberOfLines = 0
|
||||
label.textColor = .colorFFFFFF(alpha: 0.5)
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.text = "kStoreTips".localized
|
||||
label.text = "veloria_store_tips_ios".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
|
@ -144,8 +144,8 @@ class VPPlayerRechargeView: HWPanModalContentView {
|
||||
extension VPPlayerRechargeView {
|
||||
|
||||
@objc private func updateCoin() {
|
||||
let coinCountStr = "\(VPLoginManager.manager.userInfo?.totalCoin ?? 0)"
|
||||
let text = String(format: "Coins: %@".localized, coinCountStr)
|
||||
let coinCountStr = " \(VPLoginManager.manager.userInfo?.totalCoin ?? 0)"
|
||||
let text = "veloria_your_coins".localized + coinCountStr
|
||||
let coinRange = text.ocString().range(of: coinCountStr)
|
||||
|
||||
let string = NSMutableAttributedString(string: text)
|
||||
|
@ -54,24 +54,24 @@ class VPPlayerVipBuyView: UIView {
|
||||
private lazy var tipLabel: UILabel = {
|
||||
|
||||
|
||||
let hText1 = "1 week".localized
|
||||
let text1 = "· " + String(format: "kVipPrivilegeText4".localized, hText1)
|
||||
// let hText1 = "1 week".localized
|
||||
let text1 = "· " + "veloria_store_no_ads".localized
|
||||
|
||||
let hText2 = "8 days".localized
|
||||
let text2 = "· " + String(format: "kVipPrivilegeText5".localized, hText2)
|
||||
// let hText2 = "8 days".localized
|
||||
let text2 = "· " + "veloria_store_donate_coins".localized
|
||||
|
||||
let text3 = "· " + String(format: "kVipPrivilegeText6".localized)
|
||||
let text3 = "· " + "veloria_store_auto_renew".localized
|
||||
|
||||
let text = text1 + "\n" + text2 + "\n" + text3
|
||||
|
||||
let hRange1 = text.ocString().range(of: hText1)
|
||||
let hRange2 = text.ocString().range(of: hText2)
|
||||
// let hRange1 = text.ocString().range(of: hText1)
|
||||
// let hRange2 = text.ocString().range(of: hText2)
|
||||
|
||||
let string = NSMutableAttributedString(string: text)
|
||||
string.lineSpacing = 5
|
||||
string.color = .colorFFFFFF(alpha: 0.8)
|
||||
string.setColor(.color05CEA0(), range: hRange1)
|
||||
string.setColor(.color05CEA0(), range: hRange2)
|
||||
// string.setColor(.color05CEA0(), range: hRange1)
|
||||
// string.setColor(.color05CEA0(), range: hRange2)
|
||||
|
||||
|
||||
|
||||
|
@ -41,9 +41,9 @@ class VPVideoLockView: UIView {
|
||||
guard let self = self else { return }
|
||||
let title: String
|
||||
if hasLastEpisodeUnlocked {
|
||||
title = "kVideoLockTipText".localized
|
||||
title = "veloria_video_lock_tip_text".localized
|
||||
} else {
|
||||
title = String(format: "Unlocking costs %@ coins".localized, "\(videoInfo?.coins ?? 0)")
|
||||
title = "veloria_unlocking_costs".localizedReplace(text: "\(videoInfo?.coins ?? 0)")
|
||||
}
|
||||
let string = AttributedString.createAttributedString(string: title, color: .colorFFFFFF(), font: .fontRegular(ofSize: 14))
|
||||
button.configuration?.attributedTitle = string
|
||||
@ -80,7 +80,7 @@ class VPVideoLockView: UIView {
|
||||
|
||||
@objc private func handleUnlockButton() {
|
||||
if hasLastEpisodeUnlocked {
|
||||
VPToast.show(text: "kUnlockVideoErrorToast01".localized)
|
||||
VPToast.show(text: "veloria_jump_unlock_error".localized)
|
||||
} else {
|
||||
self.clickUnlockButton?()
|
||||
}
|
||||
@ -88,8 +88,7 @@ class VPVideoLockView: UIView {
|
||||
|
||||
@objc private func userInfoUpdateNotification() {
|
||||
let userInfo = VPLoginManager.manager.userInfo
|
||||
|
||||
coinCountLabel.text = String(format: "Balance: %@ Coins | %@ Bonus".localized, "\(userInfo?.coin_left_total ?? 0)", "\(userInfo?.send_coin_left_total ?? 0)")
|
||||
coinCountLabel.text = "veloria_coins_count_text".localizedReplace(text1: "\(userInfo?.coin_left_total ?? 0)", text2: "\(userInfo?.send_coin_left_total ?? 0)")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -208,7 +208,7 @@ extension VPVideoPlayerControlView {
|
||||
if isCollect {
|
||||
self.collectShort(isCollect: isCollect)
|
||||
} else {
|
||||
let alert = VPAlertView(title: "kUnFavoritesAlertTitle".localized, subtitle: "kUnFavoritesAlertText".localized, icon: UIImage(named: "alert_icon_03"), normalButtonText: nil, highlightButtonText: "Confirm".localized)
|
||||
let alert = VPAlertView(title: "veloria_un_favorites".localized, subtitle: "veloria_un_favorites_text".localized, icon: UIImage(named: "alert_icon_03"), normalButtonText: nil, highlightButtonText: "veloria_confirm".localized)
|
||||
alert.show()
|
||||
|
||||
alert.clickHighlightButton = { [weak self] in
|
||||
|
@ -34,7 +34,7 @@ class VPCoinsViewController: VPViewController {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 15)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "Get More Coins".localized
|
||||
label.text = "veloria_get_more_coins".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -70,7 +70,7 @@ class VPCoinsViewController: VPViewController {
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.textColor = .colorFFFFFF(alpha: 0.5)
|
||||
label.numberOfLines = 0
|
||||
label.text = "kStoreTips".localized
|
||||
label.text = "veloria_store_tips_ios".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -92,8 +92,8 @@ class VPCoinsViewController: VPViewController {
|
||||
|
||||
|
||||
private func updateCoin() {
|
||||
let coinCountStr = "\(VPLoginManager.manager.userInfo?.totalCoin ?? 0)"
|
||||
let text = String(format: "Coins: %@".localized, coinCountStr)
|
||||
let coinCountStr = " \(VPLoginManager.manager.userInfo?.totalCoin ?? 0)"
|
||||
let text = "veloria_your_coins".localized + coinCountStr
|
||||
let coinRange = text.ocString().range(of: coinCountStr)
|
||||
|
||||
let string = NSMutableAttributedString(string: text)
|
||||
|
@ -18,8 +18,8 @@ class VPOrderRecordsViewController: WMZPageController {
|
||||
private lazy var pageParam: WMZPageParam = {
|
||||
let param = WMZPageParam()
|
||||
param.wTitleArr = [
|
||||
"Coin Record".localized,
|
||||
"VIP Record".localized
|
||||
"veloria_coin_record".localized,
|
||||
"veloria_vip_record".localized
|
||||
]
|
||||
param.wViewController = { [weak self] index in
|
||||
return self?.viewControllers[index]
|
||||
|
@ -47,7 +47,7 @@ class VPVipPageViewController: VPViewController {
|
||||
|
||||
private lazy var pageParam: WMZPageParam = {
|
||||
let param = WMZPageParam()
|
||||
param.wTitleArr = ["VIP".localized, "Coins".localized]
|
||||
param.wTitleArr = ["vip".localized, "coins".localized]
|
||||
param.wViewController = { [weak self] index in
|
||||
return self?.viewControllers[index]
|
||||
}
|
||||
@ -95,7 +95,7 @@ class VPVipPageViewController: VPViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
let rightBar = UIBarButtonItem(title: "Restore".localized, style: .plain, target: self, action: #selector(handleRestore))
|
||||
let rightBar = UIBarButtonItem(title: "veloria_restore".localized, style: .plain, target: self, action: #selector(handleRestore))
|
||||
self.navigationItem.rightBarButtonItem = rightBar
|
||||
|
||||
vp_setupUI()
|
||||
|
@ -33,7 +33,7 @@ class VPVipViewController: VPViewController {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 15)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = "Membership Benefits".localized
|
||||
label.text = "veloria_membership_benefits".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -49,12 +49,12 @@ class VPVipViewController: VPViewController {
|
||||
let view = VPVipPrivilegeItemView()
|
||||
view.icon = UIImage(named: "privilege_icon_04")
|
||||
|
||||
let hText = "1 week".localized
|
||||
let string = NSMutableAttributedString(string: String(format: "kVipPrivilegeText4".localized, hText))
|
||||
let hRange = string.string.ocString().range(of: hText)
|
||||
// let hText = "1 week".localized
|
||||
let string = NSMutableAttributedString(string: "veloria_store_no_ads".localized)
|
||||
// let hRange = string.string.ocString().range(of: hText)
|
||||
|
||||
string.color = .colorFFFFFF()
|
||||
string.setColor(.color05CEA0(), range: hRange)
|
||||
// string.setColor(.color05CEA0(), range: hRange)
|
||||
|
||||
view.string = string
|
||||
|
||||
@ -65,12 +65,12 @@ class VPVipViewController: VPViewController {
|
||||
let view = VPVipPrivilegeItemView()
|
||||
view.icon = UIImage(named: "privilege_icon_05")
|
||||
|
||||
let hText = "8 days".localized
|
||||
let string = NSMutableAttributedString(string: String(format: "kVipPrivilegeText5".localized, hText))
|
||||
let hRange = string.string.ocString().range(of: hText)
|
||||
// let hText = "8 days".localized
|
||||
let string = NSMutableAttributedString(string: "veloria_store_donate_coins".localized)
|
||||
// let hRange = string.string.ocString().range(of: hText)
|
||||
|
||||
string.color = .colorFFFFFF()
|
||||
string.setColor(.color05CEA0(), range: hRange)
|
||||
// string.setColor(.color05CEA0(), range: hRange)
|
||||
|
||||
view.string = string
|
||||
return view
|
||||
@ -80,7 +80,7 @@ class VPVipViewController: VPViewController {
|
||||
let view = VPVipPrivilegeItemView()
|
||||
view.icon = UIImage(named: "privilege_icon_06")
|
||||
|
||||
let string = NSMutableAttributedString(string: "kVipPrivilegeText6".localized)
|
||||
let string = NSMutableAttributedString(string: "veloria_store_auto_renew".localized)
|
||||
|
||||
string.color = .colorFFFFFF()
|
||||
|
||||
@ -111,7 +111,7 @@ class VPVipViewController: VPViewController {
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.textColor = .colorFFFFFF(alpha: 0.5)
|
||||
label.numberOfLines = 0
|
||||
label.text = "kStoreTips".localized
|
||||
label.text = "veloria_store_tips_ios".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
|
@ -22,19 +22,19 @@ class VPWalletViewController: WMZPageController {
|
||||
let param = WMZPageParam()
|
||||
param.wTitleArr = [
|
||||
[
|
||||
WMZPageBTNKey.keyName : "Order\nRecords".localized,
|
||||
WMZPageBTNKey.keyName : "veloria_order_records_1".localized,
|
||||
WMZPageBTNKey.keyImage : UIImage(named: "order_icon_01")!,
|
||||
WMZPageBTNKey.keySelectImage : UIImage(named: "order_icon_01_selected")!,
|
||||
WMZPageBTNKey.keyImageOffset : 6
|
||||
],
|
||||
[
|
||||
WMZPageBTNKey.keyName : "Consumption\nRecords".localized,
|
||||
WMZPageBTNKey.keyName : "veloria_consumption_records_1".localized,
|
||||
WMZPageBTNKey.keyImage : UIImage(named: "coin_icon_05")!,
|
||||
WMZPageBTNKey.keySelectImage : UIImage(named: "coin_icon_05_selected")!,
|
||||
WMZPageBTNKey.keyImageOffset : 6
|
||||
],
|
||||
[
|
||||
WMZPageBTNKey.keyName : "Reward\nCoins".localized,
|
||||
WMZPageBTNKey.keyName : "veloria_reward_coins_1".localized,
|
||||
WMZPageBTNKey.keyImage : UIImage(named: "coin_icon_06")!,
|
||||
WMZPageBTNKey.keySelectImage : UIImage(named: "coin_icon_06_selected")!,
|
||||
WMZPageBTNKey.keyImageOffset : 6
|
||||
@ -105,7 +105,7 @@ class VPWalletViewController: WMZPageController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.title = "My Wallet".localized
|
||||
self.title = "veloria_my_wallet".localized
|
||||
self.param = self.pageParam
|
||||
view.backgroundColor = .clear
|
||||
downSc?.backgroundColor = .clear
|
||||
|
@ -19,16 +19,16 @@ class VPPayTemplateItem: VPModel, SmartCodable {
|
||||
func getText() -> String {
|
||||
switch self {
|
||||
case .week:
|
||||
return "week".localized
|
||||
return "week_short_type".localized
|
||||
|
||||
case .month:
|
||||
return "month".localized
|
||||
return "month_short_type".localized
|
||||
|
||||
case .quarter:
|
||||
return "quarter".localized
|
||||
return "quarter_short_type".localized
|
||||
|
||||
case .year:
|
||||
return "year".localized
|
||||
return "year_short_type".localized
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class VPCoinsBuyCell: VPCollectionViewCell {
|
||||
sendBgView.isHidden = false
|
||||
sendCountLabel.isHidden = false
|
||||
|
||||
sendCountLabel.text = String(format: "kBonusCoinCount".localized, "\(sendCoins)")
|
||||
sendCountLabel.text = "veloria_bonus_count_text".localizedReplace(text: "\(sendCoins)")
|
||||
let percent = CGFloat(sendCoins) / CGFloat(coins) * 100
|
||||
|
||||
sendLabel.text = String(format: "+%.0f%%".localized, percent)
|
||||
|
@ -12,7 +12,7 @@ class VPConsumptionRecordsCell: VPWalletBaseCell {
|
||||
var model: VPConsumptionRecordsModel? {
|
||||
didSet {
|
||||
timeLabel.text = model?.created_at
|
||||
let episode = String(format: "EP.%@".localized, "\(model?.episode ?? "0")") + "\(model?.name ?? "")"
|
||||
let episode = "veloria_EP.".localizedReplace(text: "\(model?.episode ?? "0")") + "\(model?.name ?? "")"
|
||||
subtitleLabel.text = episode
|
||||
coinCountLabel.text = "-\(model?.coins ?? 0)"
|
||||
}
|
||||
@ -24,7 +24,7 @@ class VPConsumptionRecordsCell: VPWalletBaseCell {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF(alpha: 0.9)
|
||||
label.text = "Purchase Single Episode".localized
|
||||
label.text = "veloria_purchase_single_episode".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
|
@ -20,7 +20,7 @@ class VPGiveCoinRecordsCell: VPWalletBaseCell {
|
||||
let days = nowDate.differenceDay(date: expireDate)
|
||||
|
||||
if days > 0 {
|
||||
expiresLabel.text = String(format: "Expires in %@ days".localized, "\(days)")
|
||||
expiresLabel.text = "veloria_expires_days".localizedReplace(text: "\(days)")
|
||||
} else {
|
||||
expiresLabel.text = "Expired".localized
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class VPVIPRecordCell: VPWalletBaseCell {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF(alpha: 0.9)
|
||||
label.text = "Purchase VIP".localized
|
||||
label.text = "veloria_purchase_vip".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
|
@ -24,7 +24,7 @@ class VPVipBuyCell: VPCollectionViewCell {
|
||||
if let coin = item?.send_coins, coin > 0 {
|
||||
sendCoinBgView.isHidden = false
|
||||
sendCoinView.isHidden = false
|
||||
let text = String(format: "Extra %@".localized, "\(coin)")
|
||||
let text = "veloria_extra".localized + " \(coin)"
|
||||
sendCoinView.setTitle("+" + text, for: .normal)
|
||||
} else {
|
||||
sendCoinBgView.isHidden = true
|
||||
|
@ -40,7 +40,7 @@ class VPWalletHeaderView: UIView {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.textColor = .colorFFFFFF(alpha: 0.8)
|
||||
label.text = "Total Coins".localized
|
||||
label.text = "veloria_total_coins".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
@ -58,13 +58,13 @@ class VPWalletHeaderView: UIView {
|
||||
|
||||
private lazy var rechargeCoinView: VPWalletHeaderItemView = {
|
||||
let view = VPWalletHeaderItemView()
|
||||
view.title = "Recharge".localized
|
||||
view.title = "veloria_recharge".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var sendCoinView: VPWalletHeaderItemView = {
|
||||
let view = VPWalletHeaderItemView()
|
||||
view.title = "Donate".localized
|
||||
view.title = "veloria_bonus".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
|
@ -19,6 +19,13 @@ class VPAppTool: NSObject {
|
||||
return keyWindow?.rootViewController
|
||||
}
|
||||
|
||||
///获得启动图
|
||||
static var lanuchViewController: 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 {
|
||||
|
@ -9,7 +9,7 @@ import UIKit
|
||||
import EmptyDataSet_Swift
|
||||
|
||||
extension UIScrollView {
|
||||
func vp_addNormalEmpty(image: UIImage? = UIImage(named: "empty_image_01"), title: String? = "kEmptyTitle01".localized, des: String? = "kEmptyDes01".localized) {
|
||||
func vp_addNormalEmpty(image: UIImage? = UIImage(named: "empty_image_01"), title: String? = "veloria_no_data".localized, des: String? = "veloria_no_data_add".localized) {
|
||||
|
||||
let emptyView = VPEmptyView()
|
||||
emptyView.image = image
|
||||
|
@ -14,8 +14,6 @@ class VPLocalizedManager: NSObject {
|
||||
private let LocalizedDataUserDefaultsKey = "VPLocalizedManager.LocalizedDataUserDefaultsKey"
|
||||
private let LocalizedDataLocalizedKeyUserDefaultsKey = "VPLocalizedManager.LocalizedDataLocalizedKeyUserDefaultsKey"
|
||||
|
||||
///语言列表
|
||||
// var languageList: [SPLanguageModel]?
|
||||
|
||||
///多语言数据
|
||||
private(set) lazy var localizedData: [String : String]? = UserDefaults.standard.object(forKey: LocalizedDataUserDefaultsKey) as? [String : String]
|
||||
@ -37,17 +35,17 @@ class VPLocalizedManager: NSObject {
|
||||
// 获取当前语言代码(如果用户未手动设置,则返回系统语言)
|
||||
var currentLocalizedKey: String {
|
||||
get {
|
||||
// var key = (UserDefaults.standard.string(forKey: LocalizedUserDefaultsKey) ?? Locale.preferredLanguages.first) ?? "en"
|
||||
// if key.contains("zh-Hans") {
|
||||
// key = "zh"
|
||||
// } else if key.contains("zh-Hant") {
|
||||
// key = "zh_hk"
|
||||
// } else {
|
||||
// let arr = key.components(separatedBy: "-")
|
||||
// key = arr.first ?? "en"
|
||||
// }
|
||||
// return key
|
||||
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)
|
||||
@ -97,36 +95,50 @@ class VPLocalizedManager: NSObject {
|
||||
extension VPLocalizedManager {
|
||||
///获取本地化数据
|
||||
func updateLocalizedData(key: String = VPLocalizedManager.shared.currentLocalizedKey, completer: ((_ finish: Bool) -> Void)?) {
|
||||
// SPSettingAPI.requestLocalizedData(key: key) { [weak self] model in
|
||||
// guard let self = self else { return }
|
||||
// guard let model = model else {
|
||||
// completer?(false)
|
||||
// return
|
||||
// }
|
||||
// if let languageList = model.languages, languageList.count > 0 {
|
||||
// self.languageList = languageList
|
||||
// }
|
||||
//
|
||||
// if let localizedData = model.translates {
|
||||
// self.localizedDataLocalizedKey = key
|
||||
// self.localizedData = localizedData
|
||||
// completer?(true)
|
||||
// } else {
|
||||
// completer?(false)
|
||||
// }
|
||||
// }
|
||||
VPSettingAPI.requestLocalizedData(key: key) { [weak self] model in
|
||||
guard let self = self else { return }
|
||||
guard let model = model else {
|
||||
completer?(false)
|
||||
return
|
||||
}
|
||||
|
||||
if let localizedData = model.translates {
|
||||
self.localizedData = localizedData
|
||||
self.localizedDataLocalizedKey = key
|
||||
completer?(true)
|
||||
} else {
|
||||
completer?(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension VPLocalizedManager {
|
||||
|
||||
static let localizedDidChange = Notification.Name(rawValue: "VPLocalizedManager.localizedDidChange")
|
||||
static let localizedDidChangeNotification = Notification.Name(rawValue: "VPLocalizedManager.localizedDidChangeNotification")
|
||||
|
||||
}
|
||||
|
||||
extension String {
|
||||
var localized: String {
|
||||
return VPLocalizedManager.shared.localizedString(forKey: self)
|
||||
var text = VPLocalizedManager.shared.localizedString(forKey: self)
|
||||
text = text.replacingOccurrences(of: "<br>", with: "\n")
|
||||
return text
|
||||
}
|
||||
|
||||
|
||||
func localizedReplace(text: String) -> String {
|
||||
return self.localized.replacingOccurrences(of: "##", with: text)
|
||||
}
|
||||
|
||||
|
||||
func localizedReplace(text1: String, text2: String, text3: String? = nil) -> String {
|
||||
var string = self.localized.replacingOccurrences(of: "#1#", with: text1)
|
||||
string = string.replacingOccurrences(of: "#2#", with: text2)
|
||||
if let text = text3 {
|
||||
string = string.replacingOccurrences(of: "#3#", with: text)
|
||||
}
|
||||
return string
|
||||
}
|
||||
}
|
||||
|
||||
|
17
Veloria/Libs/LocalizedManager/VPLocalizedModel.swift
Normal file
17
Veloria/Libs/LocalizedManager/VPLocalizedModel.swift
Normal file
@ -0,0 +1,17 @@
|
||||
//
|
||||
// VPLocalizedModel.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/12.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class VPLocalizedModel: VPModel, SmartCodable {
|
||||
|
||||
///翻译数据
|
||||
var translates: [String : String]?
|
||||
|
||||
var languages: [VPLanguageModel]?
|
||||
}
|
@ -38,7 +38,7 @@ class VPIAPManager {
|
||||
func start(model: VPPayTemplateItem, shortPlayId: String? = nil, videoId: String? = nil, hudShowView: UIView? = nil, handler: CompletionHandler? = nil) {
|
||||
|
||||
if let _ = self.waitRestoreModel {
|
||||
VPToast.show(text: "kIapErrorToast01".localized)
|
||||
VPToast.show(text: "veloria_pay_error_1".localized)
|
||||
handler?(false)
|
||||
return
|
||||
}
|
||||
@ -80,7 +80,7 @@ class VPIAPManager {
|
||||
let receipt = waitRestoreModel.receipt
|
||||
else {
|
||||
if isLoding {
|
||||
VPToast.show(text: "kIapErrorToast03".localized)
|
||||
VPToast.show(text: "veloria_pay_error_3".localized)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -107,7 +107,7 @@ class VPIAPManager {
|
||||
}
|
||||
|
||||
if isLoding {
|
||||
VPToast.show(text: "Success".localized)
|
||||
VPToast.show(text: "veloria_succeed".localized)
|
||||
}
|
||||
completer?(true)
|
||||
if buyType == .subVip {
|
||||
@ -159,7 +159,7 @@ extension VPIAPManager: JXIAPManagerDelegate {
|
||||
VPLoginManager.manager.userInfo?.is_vip = true
|
||||
}
|
||||
|
||||
VPToast.show(text: "Success".localized)
|
||||
VPToast.show(text: "veloria_succeed".localized)
|
||||
self.completionHandler?(true)
|
||||
if buyType == .subVip {
|
||||
NotificationCenter.default.post(name: VPIAPManager.buyVipFinishNotification, object: nil)
|
||||
@ -179,9 +179,9 @@ extension VPIAPManager: JXIAPManagerDelegate {
|
||||
VPHUD.dismiss()
|
||||
|
||||
if code == .noProduct {
|
||||
VPToast.show(text: "kIapErrorToast02".localized)
|
||||
VPToast.show(text: "veloria_pay_error_2".localized)
|
||||
} else if code == .cancelled {
|
||||
VPToast.show(text: "kIapErrorToast04".localized)
|
||||
VPToast.show(text: "veloria_pay_error_4".localized)
|
||||
}
|
||||
self.completionHandler?(false)
|
||||
}
|
||||
|
@ -8,152 +8,139 @@
|
||||
|
||||
"kAppName" = "Veloria";
|
||||
|
||||
"Home" = "Home";
|
||||
"Me" = "Me";
|
||||
"All" = "All";
|
||||
"Drama Champions" = "Drama Champions";
|
||||
"Explore" = "Explore";
|
||||
"EP.%@" = "EP.%@";
|
||||
"All %@ Episodes" = "All %@ Episodes";
|
||||
"Recommended For You" = "Recommended For You";
|
||||
"Trending Top 10" = "Trending Top 10";
|
||||
"Latest Trends" = "Latest Trends";
|
||||
"Search Results" = "Search Results";
|
||||
"Recent Searches" = "Recent Searches";
|
||||
"My List" = "My List";
|
||||
"History" = "History";
|
||||
"Select All" = "Select All";
|
||||
"Privacy Policy" = "Privacy Policy";
|
||||
"User Agreement" = "User Agreement";
|
||||
"Child Personal Information Protection Rules" = "Child Personal Information Protection Rules";
|
||||
"Youth Internet Civility Convention" = "Youth Internet Civility Convention";
|
||||
"Third-party information sharing list" = "Third-party information sharing list";
|
||||
"Explicit List of Personal Information Collection" = "Explicit List of Personal Information Collection";
|
||||
"About Us" = "About Us";
|
||||
"Visitor" = "Visitor";
|
||||
"Feedback History" = "Feedback History";
|
||||
"Feedback" = "Feedback";
|
||||
"Feedback Details" = "Feedback Details";
|
||||
"Rewards" = "Rewards";
|
||||
"Join VIP" = "Join VIP";
|
||||
"VIP Active" = "VIP Active";
|
||||
"Conins" = "Conins";
|
||||
"Donate" = "Donate";
|
||||
"Wallet" = "Wallet";
|
||||
"Store" = "Store";
|
||||
"Favorites" = "Favorites";
|
||||
"Language" = "Language";
|
||||
"VIP" = "VIP";
|
||||
"Coins" = "Coins";
|
||||
"Membership Benefits" = "Membership Benefits";
|
||||
"1 week" = "1 week";
|
||||
"8 days" = "8 days";
|
||||
"week" = "week";
|
||||
"month" = "month";
|
||||
"quarter" = "quarter";
|
||||
"year" = "year";
|
||||
"Error" = "Error";
|
||||
"Extra %@" = "Extra %@";
|
||||
"Get More Coins" = "Get More Coins";
|
||||
"Coins: %@" = "Coins: %@";
|
||||
"My Wallet" = "My Wallet";
|
||||
"Order\nRecords" = "Order\nRecords";
|
||||
"Consumption\nRecords" = "Consumption\nRecords";
|
||||
"Reward\nCoins" = "Reward\nCoins";
|
||||
"Coin Record" = "Coin Record";
|
||||
"VIP Record" = "VIP Record";
|
||||
"Total Coins" = "Total Coins";
|
||||
"Recharge" = "Recharge";
|
||||
"Unlocking costs %@ coins" = "Unlocking costs %@ coins";
|
||||
"Balance: %@ Coins | %@ Bonus" = "Balance: %@ Coins | %@ Bonus";
|
||||
"Check in" = "Check in";
|
||||
"Welcome to %@" = "Welcome to %@";
|
||||
"Login with Apple" = "Login with Apple";
|
||||
"Login with Facebook" = "Login with Facebook";
|
||||
"Log In" = "Log In";
|
||||
"Sign Out" = "Sign Out";
|
||||
"Delete Account" = "Delete Account";
|
||||
"Account Deletion" = "Account Deletion";
|
||||
"Delete Account" = "Delete Account";
|
||||
"Delete Forever" = "Delete Forever";
|
||||
"Cancel" = "Cancel";
|
||||
"Log Out" = "Log Out";
|
||||
"Recharge Coins" = "Recharge Coins";
|
||||
"Purchase VIP" = "Purchase VIP";
|
||||
"Purchase Single Episode" = "Purchase Single Episode";
|
||||
"Check in" = "Check in";
|
||||
"Expires in %@ days" = "Expires in 30 days";
|
||||
"veloria_home" = "Home";
|
||||
"veloria_me" = "Me";
|
||||
"veloria_all" = "All";
|
||||
"veloria_drama_champions" = "Drama Champions";
|
||||
"veloria_explore" = "Explore";
|
||||
"veloria_EP." = "EP.##";
|
||||
"veloria_all_episodes" = "All ## Episodes";
|
||||
"veloria_recommended" = "Recommended For You";
|
||||
"veloria_trending_top" = "Trending Top 10";
|
||||
"veloria_latest_trends" = "Latest Trends";
|
||||
"veloria_search_results" = "Search Results";
|
||||
"veloria_recent_searches" = "Recent Searches";
|
||||
"veloria_my_list" = "My List";
|
||||
"veloria_history" = "History";
|
||||
"veloria_all_select" = "Select All";
|
||||
"veloria_my_privacy" = "Privacy Policy";
|
||||
"veloria_my_agreement" = "User Agreement";
|
||||
"veloria_child_protection_text" = "Child Personal Information Protection Rules";
|
||||
"veloria_civizatio_convention_text" = "Youth Internet Civility Convention";
|
||||
"veloria_information_sharing_text" = "Third-party information sharing list";
|
||||
"veloria_persoInfor_disclosure_text" = "Explicit List of Personal Information Collection";
|
||||
"veloria_me_about" = "About Us";
|
||||
"veloria_visitor" = "Visitor";
|
||||
"veloria_my_feedback_history" = "Feedback History";
|
||||
"veloria_my_feedback" = "Feedback";
|
||||
"veloria_my_feedback_details" = "Feedback Details";
|
||||
"veloria_rewards" = "Rewards";
|
||||
"veloria_vip_join" = "Join VIP";
|
||||
"veloria_vip_active" = "VIP Active";
|
||||
"coins" = "Coins";
|
||||
"veloria_bonus" = "Donate";
|
||||
"veloria_wallet" = "Wallet";
|
||||
"veloria_store" = "Store";
|
||||
"veloria_favorites" = "Favorites";
|
||||
"veloria_language" = "Language";
|
||||
"vip" = "VIP";
|
||||
"veloria_membership_benefits" = "Membership Benefits";
|
||||
"week_short_type" = "Weekly";
|
||||
"month_short_type" = "Monthly";
|
||||
"quarter_short_type" = "Quarterly";
|
||||
"year_short_type" = "Yearly";
|
||||
"veloria_error" = "Error";
|
||||
"veloria_extra" = "Extra";
|
||||
"veloria_get_more_coins" = "Get More Coins";
|
||||
"veloria_your_coins" = "Your Coins:";
|
||||
"veloria_my_wallet" = "My Wallet";
|
||||
"veloria_order_records_1" = "Order<br>Records";
|
||||
"veloria_consumption_records_1" = "Consumption<br>Records";
|
||||
"veloria_reward_coins_1" = "Reward<br>Coins";
|
||||
"veloria_coin_record" = "Coin Record";
|
||||
"veloria_vip_record" = "VIP Record";
|
||||
"veloria_total_coins" = "Total Coins";
|
||||
"veloria_recharge" = "Recharge";
|
||||
"veloria_unlocking_costs" = "Unlocking costs ## coins";
|
||||
"veloria_coins_count_text" = "Balance: #1# Coins | #2# Bonus";
|
||||
"veloria_check_in" = "Check in";
|
||||
"veloria_welcome_to" = "Welcome to Veloria";
|
||||
"veloria_login_apple" = "Login with Apple";
|
||||
"veloria_login_facebook" = "Login with Facebook";
|
||||
"veloria_login" = "Log In";
|
||||
"veloria_sign_out" = "Sign Out";
|
||||
"veloria_delete_account" = "Delete Account";
|
||||
"veloria_delete_forever" = "Delete Forever";
|
||||
"veloria_cancel" = "Cancel";
|
||||
"veloria_log_out" = "Log Out";
|
||||
"veloria_purchase_vip" = "Purchase VIP";
|
||||
"veloria_purchase_single_episode" = "Purchase Single Episode";
|
||||
"veloria_expires_days" = "Expires in ## days";
|
||||
"Expired" = "Expired";
|
||||
"Success" = "Success";
|
||||
"Restore" = "Restore";
|
||||
"Watch Now" = "Watch Now";
|
||||
"More" = "More";
|
||||
"Confirm" = "Confirm";
|
||||
"Order Record" = "Order Record";
|
||||
"Allow" = "Allow";
|
||||
"veloria_succeed" = "Success";
|
||||
"veloria_restore" = "Restore";
|
||||
"veloria_watch_now" = "Watch Now";
|
||||
"veloria_more" = "More";
|
||||
"veloria_confirm" = "Confirm";
|
||||
"veloria_order_record" = "Order Record";
|
||||
"veloria_allow" = "Allow";
|
||||
"veloria_get_started" = "Get Started";
|
||||
|
||||
|
||||
"kBonusCoinCount" = "+%@ Bonus";
|
||||
"kEmptyTitle01" = "Nothing Here Yet";
|
||||
"kEmptyDes01" = "Start exploring and add something!";
|
||||
"kEmptyTitle02" = "Not Found";
|
||||
"kEmptyDes02" = "Sorry, we couldn't find anything.";
|
||||
"kDetailRecommandTitle" = "Picked Just for You";
|
||||
"kHomeTitleText" = "10,000+ Addictive Shorts Await!";
|
||||
"kSearchPlaceholderText1" = "Search dramas";
|
||||
"kSearchPlaceholderText2" = "#Recersal of fate";
|
||||
"kHomeMenuTitle" = "Select Categories";
|
||||
"kVipTipText1" = "unlock exclusive dramas";
|
||||
"kVipTipText2" = "vip expires: %@";
|
||||
"kVipPrivilegeText1" = "Ad-Free\nStreaming";
|
||||
"kVipPrivilegeText2" = "Exclusive\nEpisodes";
|
||||
"kVipPrivilegeText3" = "Daily free\ncoins";
|
||||
"kVipPrivilegeText4" = "Unlimited access to all series for %@ (No Ads)";
|
||||
"kVipPrivilegeText5" = "The donate coins will expire in %@";
|
||||
"kVipPrivilegeText6" = "Auto renew, cancel anytime";
|
||||
"kLoginAgreementText" = "By logging in you agree to: %@ & %@";
|
||||
"kVideoLockTipText" = "Please unlock the previous episode";
|
||||
"veloria_bonus_count_text" = "+## Bonus";
|
||||
"veloria_no_data" = "Nothing Here Yet";
|
||||
"veloria_no_data_add" = "Start exploring and add something!";
|
||||
"veloria_not_found" = "Not Found";
|
||||
"veloria_not_found_string" = "Sorry, we couldn't find anything.";
|
||||
"veloria_detail_recommand_title" = "Picked Just for You";
|
||||
"veloria_addictive_short_await" = "10,000+ Addictive Shorts Await!";
|
||||
"veloria_search_dramas" = "Search dramas";
|
||||
"veloria_recersal_of_fate" = "#Recersal of fate";
|
||||
"veloria_select_categories" = "Select Categories";
|
||||
"veloria_unlock_exclusive" = "unlock exclusive dramas";
|
||||
"veloria_vip_expires_date" = "VIP expires: ##";
|
||||
"veloria_ad_free_streaming_ios" = "Ad-Free<br>Streaming";
|
||||
"veloria_exclusive_episodes_ios" = "Exclusive<br>Episodes";
|
||||
"veloria_daily_free_coins_ios" = "Daily free<br>coins";
|
||||
"veloria_store_no_ads" = "Unlimited access to all series for 1 week (No Ads)";
|
||||
"veloria_store_donate_coins" = "The donate coins will expire in 8 days";
|
||||
"veloria_store_auto_renew" = "Auto renew, cancel anytime";
|
||||
"veloria_login_hint_ios" = "By logging in you agree to: #1# & #2#";
|
||||
"veloria_video_lock_tip_text" = "Please unlock the previous episode";
|
||||
//无网提示
|
||||
"kNetworkToast01" = "The service is abnormal. Check the network.";
|
||||
"kNetworkToast02" = "Your account is already logged in on another device~";
|
||||
"veloria_network" = "The service is abnormal. Check the network.";
|
||||
"veloria_network_error_1" = "Your account is already logged in on another device~";
|
||||
//解锁上一集提示
|
||||
"kLockPreviousEpisodeText" = "The prequel to this series is not unlocked. Please unlock the prequel before unlocking this series";
|
||||
"veloria_jump_unlock_error" = "The prequel to this series is not unlocked. Please unlock the prequel before unlocking this series";
|
||||
//解锁失败
|
||||
"kLockFailText" = "Purchase failed, please try again later!";
|
||||
"veloria_jump_unlock_error_1" = "Purchase failed, please try again later!";
|
||||
//已是会员
|
||||
"kVipToast01" = "You are already a member!";
|
||||
"veloria_vip_error_1" = "You are already a member!";
|
||||
//还有未完成购买
|
||||
"kIapErrorToast01" = "You have unfinished in-app purchases, please restore them first.";
|
||||
"kIapErrorToast02" = "Invalid in-app purchase";
|
||||
"veloria_pay_error_1" = "You have unfinished in-app purchases, please restore them first.";
|
||||
"veloria_pay_error_2" = "Invalid in-app purchase";
|
||||
///没有可恢复购买
|
||||
"kIapErrorToast03" = "There are no in-app purchases to restore.";
|
||||
"kIapErrorToast04" = "Payment has been cancelled.";
|
||||
///请购买上一集
|
||||
"kUnlockVideoErrorToast01" = "The prequel to this series is not unlocked. Please unlock the prequel before unlocking this series";
|
||||
"veloria_pay_error_3" = "No in-app purchases can be restored";
|
||||
"veloria_pay_error_4" = "Payment has been cancelled";
|
||||
|
||||
|
||||
|
||||
"kStoreTips" = "1. Coins are virtual items and cannot be refunded. Use it for this product.
|
||||
2. Gold coins will never expire, the reward coins will expire 24 hours a day.
|
||||
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 <Restore> to refresh.
|
||||
5. For other questions, contact us via Me>Feedback.";
|
||||
"veloria_store_tips_ios" = "1. Coins are virtual items and cannot be refunded. Use it for this product.<br>2. Gold coins will never expire, the reward coins will expire 24 hours a day.<br>3. Coins will be used first when unlocking episodes. If the amount is insufficient, reward coins will automatically be used.<br>4. The purchase has not been credited, click <Restore> to refresh.<br>5. For other questions, contact us via Me>Feedback.";
|
||||
|
||||
//请选择需要删除的短剧
|
||||
"kToastText1" = "Please select the short plays that need to be deleted";
|
||||
"veloria_delete_short_tip" = "Please select the short plays that need to be deleted";
|
||||
|
||||
"kUnlockButtonText" = "Unlock VIP Benefits";
|
||||
"veloria_vip_splash_onclick" = "Unlock VIP Benefits";
|
||||
|
||||
"kDeleteAccountAlertTitle" = "Confirm Account Deletion";
|
||||
"kDeleteAccountAlertText" = "This action cannot be undone.";
|
||||
"kUnFavoritesAlertTitle" = "UnFavorites";
|
||||
"kUnFavoritesAlertText" = "You may not find this collection after you uncollect it";
|
||||
"kAPNSAlertTitle" = "Turn on Notifications?";
|
||||
"kAPNSAlertText" = "Get alerts for new episodes and exclusive offers.";
|
||||
"kVipAlertTitle" = "Unlock VIP Privileges!";
|
||||
"kVipAlertText" = "Enjoy ad-free streaming, early access, and exclusive content!";
|
||||
"kLogoutAlertTitle" = "Ready to Leave?";
|
||||
"kLogoutAlertText" = "when you sign out, your watch history will not be synced to your account.";
|
||||
"veloria_confirm_deletion" = "Confirm Account Deletion";
|
||||
"veloria_action_cannot_undone" = "This action cannot be undone.";
|
||||
"veloria_un_favorites" = "UnFavorites";
|
||||
"veloria_un_favorites_text" = "You may not find this collection after you uncollect it";
|
||||
"open_notice_at_watch_video" = "Turn on Notifications?";
|
||||
"veloria_open_notice_alert_text" = "Get alerts for new episodes and exclusive offers.";
|
||||
"veloria_vip_splash_title" = "Unlock VIP Privileges!";
|
||||
"veloria_vip_splash_content" = "Enjoy ad-free streaming, early access, and exclusive content!";
|
||||
"veloria_ready_to_leave" = "Ready to Leave?";
|
||||
"veloria_ready_to_leave_text" = "when you sign out, your watch history will not be synced to your account.";
|
||||
|
||||
"DeleteAccount_tips_1" = "Your account will be permanently deleted";
|
||||
"DeleteAccount_tips_2" = "You will not be able to log in with this user ID";
|
||||
|
Loading…
x
Reference in New Issue
Block a user