diff --git a/Veloria.xcodeproj/project.pbxproj b/Veloria.xcodeproj/project.pbxproj index c5cfb54..c298340 100644 --- a/Veloria.xcodeproj/project.pbxproj +++ b/Veloria.xcodeproj/project.pbxproj @@ -149,6 +149,9 @@ BF692AB52E0644B500A5C2DA /* VPRevolutionSelectedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692AB42E0644B500A5C2DA /* VPRevolutionSelectedView.swift */; }; BF692AB72E06450C00A5C2DA /* VPRevolutionSelectedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692AB62E06450C00A5C2DA /* VPRevolutionSelectedCell.swift */; }; BF692AB92E065B2100A5C2DA /* VPVipAlertItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692AB82E065B2100A5C2DA /* VPVipAlertItemView.swift */; }; + BF692ABB2E067F4A00A5C2DA /* VPVideoRevolutionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692ABA2E067F4A00A5C2DA /* VPVideoRevolutionManager.swift */; }; + BF692ABD2E0690F200A5C2DA /* VPVersionUpdateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692ABC2E0690F200A5C2DA /* VPVersionUpdateModel.swift */; }; + BF692ABF2E06934D00A5C2DA /* VPVersionUpdateAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692ABE2E06934D00A5C2DA /* VPVersionUpdateAlertView.swift */; }; BFA21D982E01477200B3573D /* VPStoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D972E01477200B3573D /* VPStoreViewController.swift */; }; BFA21D9A2E01497F00B3573D /* VPStoreVipBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */; }; BFA21D9C2E01628F00B3573D /* VPStoreCoinsBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */; }; @@ -424,6 +427,9 @@ BF692AB42E0644B500A5C2DA /* VPRevolutionSelectedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPRevolutionSelectedView.swift; sourceTree = ""; }; BF692AB62E06450C00A5C2DA /* VPRevolutionSelectedCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPRevolutionSelectedCell.swift; sourceTree = ""; }; BF692AB82E065B2100A5C2DA /* VPVipAlertItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipAlertItemView.swift; sourceTree = ""; }; + BF692ABA2E067F4A00A5C2DA /* VPVideoRevolutionManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVideoRevolutionManager.swift; sourceTree = ""; }; + BF692ABC2E0690F200A5C2DA /* VPVersionUpdateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVersionUpdateModel.swift; sourceTree = ""; }; + BF692ABE2E06934D00A5C2DA /* VPVersionUpdateAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVersionUpdateAlertView.swift; sourceTree = ""; }; BFA21D972E01477200B3573D /* VPStoreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreViewController.swift; sourceTree = ""; }; BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreVipBuyView.swift; sourceTree = ""; }; BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsBuyView.swift; sourceTree = ""; }; @@ -1027,6 +1033,7 @@ isa = PBXGroup; children = ( BF0FA74D2DDF067E00C9E5F2 /* VPVideoPlayViewModel.swift */, + BF692ABA2E067F4A00A5C2DA /* VPVideoRevolutionManager.swift */, ); path = ViewModel; sourceTree = ""; @@ -1142,6 +1149,7 @@ children = ( BF0FA7B02DE447EB00C9E5F2 /* VPMeItem.swift */, BFCCE1192DFAB7CA00EDE165 /* VPLanguageModel.swift */, + BF692ABC2E0690F200A5C2DA /* VPVersionUpdateModel.swift */, ); path = Model; sourceTree = ""; @@ -1325,6 +1333,7 @@ BFF5B2382DF014520044227A /* VPBaseAlertView.swift */, BFF5B2362DF013410044227A /* VPAlertWindowManager.swift */, BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */, + BF692ABE2E06934D00A5C2DA /* VPVersionUpdateAlertView.swift */, ); path = Alert; sourceTree = ""; @@ -1574,6 +1583,7 @@ BFF5AFCA2DE97B7A0044227A /* VPWalletViewController.swift in Sources */, BFF5B26C2DF28FD50044227A /* VPStatAPI.swift in Sources */, BF0FA71B2DDC7FF200C9E5F2 /* VPImageView.swift in Sources */, + BF692ABF2E06934D00A5C2DA /* VPVersionUpdateAlertView.swift in Sources */, BF0FA7522DDF134700C9E5F2 /* VPVideoPlayerControlView.swift in Sources */, BF0FA7852DE1561D00C9E5F2 /* VPSearchRecommendedCell.swift in Sources */, BF0FA7832DE1533E00C9E5F2 /* VPGradientLabel.swift in Sources */, @@ -1629,6 +1639,7 @@ BFF5B25E2DF1423F0044227A /* VPWalletBaseCell.swift in Sources */, 1B056E4D2DDAC7C1007EE38D /* VPTabBarController.swift in Sources */, BFF5B2522DF130E00044227A /* VPConsumptionRecordsCell.swift in Sources */, + BF692ABB2E067F4A00A5C2DA /* VPVideoRevolutionManager.swift in Sources */, BFF5AFDC2DEEA09F0044227A /* VPVideoUnlockModel.swift in Sources */, BF5E75C02DE5566200DE9DFE /* VPHomePageControlView.swift in Sources */, BFF5AFC22DE837FC0044227A /* VPPayTemplateItem.swift in Sources */, @@ -1697,6 +1708,7 @@ BFF5B2752DF2C3750044227A /* VPDetailRecommandView.swift in Sources */, BF0FA7A12DE1AA5100C9E5F2 /* VPTableView.swift in Sources */, 1B056E442DDAC355007EE38D /* UIDevice+VPAdd.swift in Sources */, + BF692ABD2E0690F200A5C2DA /* VPVersionUpdateModel.swift in Sources */, BF0FA7632DE006E700C9E5F2 /* VPDetailPlayerCell.swift in Sources */, BF0FA73F2DDEF26E00C9E5F2 /* VPHomeSearchButton.swift in Sources */, BFF5B2562DF139200044227A /* VPGiveCoinRecordsViewController.swift in Sources */, @@ -1786,7 +1798,7 @@ CODE_SIGN_ENTITLEMENTS = Veloria/Veloria.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = 394VH538M8; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Veloria/Source/Info.plist; @@ -1803,7 +1815,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.3; + MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = com.qjwl168.veloria.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1827,7 +1839,7 @@ CODE_SIGN_ENTITLEMENTS = Veloria/Veloria.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = 394VH538M8; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = Veloria/Source/Info.plist; @@ -1844,7 +1856,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.0.3; + MARKETING_VERSION = 1.0.4; PRODUCT_BUNDLE_IDENTIFIER = com.qjwl168.veloria.ios; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Veloria/Base/Controller/VPTabBarController.swift b/Veloria/Base/Controller/VPTabBarController.swift index 84b89de..743e7ea 100644 --- a/Veloria/Base/Controller/VPTabBarController.swift +++ b/Veloria/Base/Controller/VPTabBarController.swift @@ -55,6 +55,8 @@ class VPTabBarController: UITabBarController { vp_setup() self.tabBar.isTranslucent = true + checkUpdates() + } @@ -172,4 +174,37 @@ extension VPTabBarController { viewController?.showCollectPage() } } + + ///检查更新 + func checkUpdates() { +#if !DEBUG + if let date = UserDefaults.standard.object(forKey: kVPVersionUpdateAlertDefaultsKey) as? Date { + if date.vp_isToday { return } + } + UserDefaults.standard.set(Date(), forKey: kVPVersionUpdateAlertDefaultsKey) +#endif + + VPSettingAPI.requestVersionUpdateData { [weak self] model in + guard let self = self else { return } + guard let model = model else { return } + if model.canUpdate() { + self.showVersionUpdateAlert(model: model) + } + } + } + + private func showVersionUpdateAlert(model: VPVersionUpdateModel) { + let alert = VPVersionUpdateAlertView(model: model).show() + + alert.clickHighlightButton = { [weak self] in + guard let self = self else { return } + guard let url = URL(string: "https://apps.apple.com/app/id6746436168") else { return } + + if UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url) + } + } + } + + } diff --git a/Veloria/Base/Define/VPUserDefaultsKey.swift b/Veloria/Base/Define/VPUserDefaultsKey.swift index cb0013c..f6f58e9 100644 --- a/Veloria/Base/Define/VPUserDefaultsKey.swift +++ b/Veloria/Base/Define/VPUserDefaultsKey.swift @@ -22,8 +22,14 @@ let kVPWaitRestoreIAPDefaultsKey = "kVPWaitRestoreIAPDefaultsKey" ///推送提示 let kVPApnsAlertDefaultsKey = "kVPApnsAlertDefaultsKey" +///更新提示 +let kVPVersionUpdateAlertDefaultsKey = "kVPVersionUpdateAlertDefaultsKey" + ///vip弹窗时间 let kVPVipAlertDateDefaultsKey = "kVPVipAlertDateDefaultsKey" ///是否开启过APP let kVPHasBeenOpenedAPPDefaultsKey = "kVPHasBeenOpenedAPPDefaultsKey" + +///视频清晰度 +let kVPVideoRevolutionDefaultsKey = "kVPVideoRevolutionDefaultsKey" diff --git a/Veloria/Base/Extension/UIColor+VPAdd.swift b/Veloria/Base/Extension/UIColor+VPAdd.swift index 2012188..784ee73 100644 --- a/Veloria/Base/Extension/UIColor+VPAdd.swift +++ b/Veloria/Base/Extension/UIColor+VPAdd.swift @@ -333,4 +333,8 @@ extension UIColor { static func colorFF9500(alpha: CGFloat = 1) -> UIColor { return UIColor(rgb: 0xFF9500, alpha: alpha) } + + static func colorA3F0DE(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xA3F0DE, alpha: alpha) + } } diff --git a/Veloria/Base/Networking/API/VPSettingAPI.swift b/Veloria/Base/Networking/API/VPSettingAPI.swift index 5cb93d5..dd876d4 100644 --- a/Veloria/Base/Networking/API/VPSettingAPI.swift +++ b/Veloria/Base/Networking/API/VPSettingAPI.swift @@ -40,6 +40,18 @@ class VPSettingAPI { VPNetwork.request(parameters: param) { (response: VPNetworkResponse) in } + } + + + ///获取版本更新数据 + static func requestVersionUpdateData(completer: ((_ model: VPVersionUpdateModel?) -> Void)?) { + var param = VPNetworkParameters(path: "/customer/versionControl") + param.method = .get + param.isToast = false + + VPNetwork.request(parameters: param) { (response: VPNetworkResponse) in + completer?(response.data) + } } } diff --git a/Veloria/Base/Networking/API/VPVideoAPI.swift b/Veloria/Base/Networking/API/VPVideoAPI.swift index 3be2f4a..06c3747 100644 --- a/Veloria/Base/Networking/API/VPVideoAPI.swift +++ b/Veloria/Base/Networking/API/VPVideoAPI.swift @@ -51,15 +51,22 @@ class VPVideoAPI: NSObject { } ///推荐短剧 - static func requestRecommandsVideo(page: Int, completer: ((_ listModel: VPListModel?) -> Void)?) { + static func requestRecommandsVideo(page: Int, revolution: VPShortModel.VideoRevolution? = nil, completer: ((_ listModel: VPListModel?) -> Void)?) { - var param = VPNetworkParameters(path: "/getRecommands") - param.method = .get - param.parameters = [ + var parameters: [String : Any] = [ "page_size" : 20, "current_page" : page ] + if let revolution = revolution?.rawValue { + parameters["revolution"] = revolution + } + + var param = VPNetworkParameters(path: "/getRecommands") + param.method = .get + param.parameters = parameters + + VPNetwork.request(parameters: param) { (response: VPNetworkResponse>) in completer?(response.data) } diff --git a/Veloria/Class/Explore/Controller/VPExploreViewController.swift b/Veloria/Class/Explore/Controller/VPExploreViewController.swift index 99e13ea..adc5eb9 100644 --- a/Veloria/Class/Explore/Controller/VPExploreViewController.swift +++ b/Veloria/Class/Explore/Controller/VPExploreViewController.swift @@ -15,6 +15,9 @@ class VPExploreViewController: VPVideoPlayerViewController { var pagination: VPListPaginationModel? + ///需要更新数据 + private var needUpdateDate = false + private lazy var emptyView: VPEmptyView = { let view = VPEmptyView.createNoNetworkEmptyView { [weak self] in guard let self = self else { return } @@ -32,6 +35,8 @@ class VPExploreViewController: VPVideoPlayerViewController { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(loginStateDidChangeNotification), name: VPLoginManager.loginStateDidChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: VPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(didChangeRevolutionNotification), name: VPVideoRevolutionManager.didChangeRevolutionNotification, object: nil) + self.collectionView.vp_onRefrsh = true self.collectionView.vp_refreshDelegate = self self.delegate = self @@ -48,7 +53,8 @@ class VPExploreViewController: VPVideoPlayerViewController { } @objc private func loginStateDidChangeNotification() { - requestDataArr(page: 1) + self.needUpdateDate = true + updateData() } @objc private func reachabilityDidChangeNotification() { @@ -56,6 +62,22 @@ class VPExploreViewController: VPVideoPlayerViewController { requestDataArr(page: 1) } } + + ///分辨率发生变化 + @objc private func didChangeRevolutionNotification() { + self.needUpdateDate = true + updateData() + } + + private func updateData() { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { [weak self] in + guard let self = self else { return } + if self.needUpdateDate { + self.needUpdateDate = false + self.requestDataArr(page: 1) + } + } + } } @@ -125,7 +147,7 @@ extension VPExploreViewController { private func requestDataArr(page: Int, completer: (() -> Void)? = nil) { - VPVideoAPI.requestRecommandsVideo(page: page) { [weak self] listModel in + VPVideoAPI.requestRecommandsVideo(page: page, revolution: VPVideoRevolutionManager.manager.revolution) { [weak self] listModel in guard let self = self else { return } self.emptyView.isHidden = true self.collectionView.isHidden = false diff --git a/Veloria/Class/Me/Model/VPVersionUpdateModel.swift b/Veloria/Class/Me/Model/VPVersionUpdateModel.swift new file mode 100644 index 0000000..7568982 --- /dev/null +++ b/Veloria/Class/Me/Model/VPVersionUpdateModel.swift @@ -0,0 +1,31 @@ +// +// VPVersionUpdateModel.swift +// Veloria +// +// Created by 湖南秦九 on 2025/6/21. +// + +import UIKit +import SmartCodable + +class VPVersionUpdateModel: VPModel, SmartCodable { + + var version_code: String? + var des: String? + var version_name: String? + + + + func canUpdate() -> Bool { + let currentCode = NSNumber(string: kVPAPPBundleVersion)?.intValue ?? 0 + let serverCode = NSNumber(string: version_code ?? "0")?.intValue ?? 0 + return serverCode > currentCode + } + + + static func mappingForKey() -> [SmartKeyTransformer]? { + return [ + CodingKeys.des <--- ["description"] + ] + } +} diff --git a/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift b/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift index 28c07b4..0e82378 100644 --- a/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift +++ b/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift @@ -58,6 +58,7 @@ class VPDetailPlayerViewController: VPVideoPlayerViewController { self.delegate = self self.dataSource = self NotificationCenter.default.addObserver(self, selector: #selector(buyVipFinishNotification), name: VPIAPManager.buyVipFinishNotification, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(didChangeRevolutionNotification), name: VPVideoRevolutionManager.didChangeRevolutionNotification, object: nil) // self.jx_popDelegate = self self.jx_popGestureType = .disabled @@ -284,6 +285,10 @@ extension VPDetailPlayerViewController { self.isShowRecommand = true } + ///分辨率发生变化 + @objc private func didChangeRevolutionNotification() { + self.requestDetailData(indexPath: self.viewModel.currentIndexPath) + } } //MARK: -------------- VPPlayerListViewControllerDataSource -------------- @@ -348,7 +353,7 @@ extension VPDetailPlayerViewController { VPHUD.show(containerView: self.view) - VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId, revolution: self.viewModel.revolution) { [weak self] model in + VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId, revolution: VPVideoRevolutionManager.manager.revolution) { [weak self] model in VPHUD.dismiss() guard let self = self else { return } guard let model = model else { return } diff --git a/Veloria/Class/Player/View/VPRevolutionSelectedCell.swift b/Veloria/Class/Player/View/VPRevolutionSelectedCell.swift index 0d3227a..74ad829 100644 --- a/Veloria/Class/Player/View/VPRevolutionSelectedCell.swift +++ b/Veloria/Class/Player/View/VPRevolutionSelectedCell.swift @@ -29,16 +29,21 @@ class VPRevolutionSelectedCell: VPCollectionViewCell { var vp_isSelected: Bool = false { didSet { if vp_isSelected { - contentView.vp_setGradientBorder() - contentView.backgroundColor = .color1C2D2F(alpha: 0.6) + bgView.vp_setGradientBorder() + bgView.backgroundColor = .color1C2D2F(alpha: 0.6) } else { - contentView.vp_removeGradientBorder() - contentView.backgroundColor = .color000000(alpha: 0.3) + bgView.vp_removeGradientBorder() + bgView.backgroundColor = .color000000(alpha: 0.3) } } } + private lazy var bgView: UIView = { + let view = UIView() + return view + }() + private lazy var label: UILabel = { let label = UILabel() label.font = .fontRegular(ofSize: 14) @@ -65,14 +70,19 @@ class VPRevolutionSelectedCell: VPCollectionViewCell { extension VPRevolutionSelectedCell { private func vp_setupUI() { - contentView.layer.cornerRadius = 6 - contentView.layer.masksToBounds = false - + bgView.layer.cornerRadius = 6 + bgView.layer.masksToBounds = false + contentView.addSubview(bgView) contentView.addSubview(label) contentView.addSubview(markImageView) + + bgView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + label.snp.makeConstraints { make in make.center.equalToSuperview() } diff --git a/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift b/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift index 283abf1..8fc57f7 100644 --- a/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift +++ b/Veloria/Class/Player/ViewModel/VPVideoPlayViewModel.swift @@ -31,7 +31,7 @@ class VPVideoPlayViewModel: NSObject { } ///当前分辨率 - lazy var revolution: VPShortModel.VideoRevolution = .r_540 + lazy var revolution: VPShortModel.VideoRevolution = VPVideoRevolutionManager.manager.revolution ///设置进度 func seekToTime(toTime: Int) { @@ -59,12 +59,13 @@ extension VPVideoPlayViewModel { guard self.revolution != revolution else { return } let userInfo = VPLoginManager.manager.userInfo - if revolution.needLogin, userInfo?.is_tourist != false { + + if revolution.needLogin, userInfo?.is_tourist != false, userInfo?.is_vip != true { VPLoginManager.manager.openLogin { [weak self] in guard let self = self else { return } - self.revolution = revolution - self.updateDetailDataBlock?(self.currentIndexPath) + VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) + self.revolution = VPVideoRevolutionManager.manager.revolution } } else if revolution.needVip, userInfo?.is_vip != true { @@ -79,13 +80,13 @@ extension VPVideoPlayViewModel { } view.vipBuyFinishBlock = { [weak self] in guard let self = self else { return } - self.revolution = revolution - self.updateDetailDataBlock?(self.currentIndexPath) + VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) + self.revolution = VPVideoRevolutionManager.manager.revolution } view.present(in: nil) } else { - self.revolution = revolution - self.updateDetailDataBlock?(self.currentIndexPath) + VPVideoRevolutionManager.manager.setVideoRevolution(revolution: revolution) + self.revolution = VPVideoRevolutionManager.manager.revolution } } diff --git a/Veloria/Class/Player/ViewModel/VPVideoRevolutionManager.swift b/Veloria/Class/Player/ViewModel/VPVideoRevolutionManager.swift new file mode 100644 index 0000000..699130e --- /dev/null +++ b/Veloria/Class/Player/ViewModel/VPVideoRevolutionManager.swift @@ -0,0 +1,70 @@ +// +// VPVideoRevolutionManager.swift +// Veloria +// +// Created by 湖南秦九 on 2025/6/21. +// + +import UIKit + +class VPVideoRevolutionManager: NSObject { + + static let manager = VPVideoRevolutionManager() + + ///当前分辨率 + lazy var revolution: VPShortModel.VideoRevolution = { + let userInfo = VPLoginManager.manager.userInfo + + if let revolution = UserDefaults.standard.object(forKey: kVPVideoRevolutionDefaultsKey) as? String { + var revolution = verify(revolution: VPShortModel.VideoRevolution.init(rawValue: revolution) ?? .r_540) + return revolution + } + return .r_540 + }() + + override init() { + super.init() + NotificationCenter.default.addObserver(self, selector: #selector(userInfoUpdateNotification), name: VPLoginManager.userInfoUpdateNotification, object: nil) + } + + @objc private func userInfoUpdateNotification() { + self.setVideoRevolution(revolution: self.revolution) + } + + func setVideoRevolution(revolution: VPShortModel.VideoRevolution) { + let newRevolution = verify(revolution: revolution) + + if newRevolution != self.revolution { + self.revolution = newRevolution + NotificationCenter.default.post(name: VPVideoRevolutionManager.didChangeRevolutionNotification, object: nil) + UserDefaults.standard.set(newRevolution.rawValue, forKey: kVPVideoRevolutionDefaultsKey) + } + } + +} + +extension VPVideoRevolutionManager { + + ///校验分辨率是否可用,并返回可用分辨率 + func verify(revolution: VPShortModel.VideoRevolution) -> VPShortModel.VideoRevolution { + let userInfo = VPLoginManager.manager.userInfo + var newRevolution = revolution + if userInfo?.is_vip != true { + if newRevolution == .r_1080 { + newRevolution = .r_720 + } + if userInfo?.is_tourist != false, revolution != .r_540 { + newRevolution = .r_540 + } + } + return newRevolution + } + +} + + +extension VPVideoRevolutionManager { + + ///分辨率发生变化 + @objc static let didChangeRevolutionNotification = NSNotification.Name(rawValue: "VPVideoRevolutionManager.didChangeRevolutionNotification") +} diff --git a/Veloria/Libs/Alert/VPAlertView.swift b/Veloria/Libs/Alert/VPAlertView.swift index 5100b95..e8e5209 100644 --- a/Veloria/Libs/Alert/VPAlertView.swift +++ b/Veloria/Libs/Alert/VPAlertView.swift @@ -33,7 +33,7 @@ class VPAlertView: VPBaseAlertView { return imageView }() - private lazy var titleLabel: VPGradientLabel = { + private(set) lazy var titleLabel: VPGradientLabel = { let label = VPGradientLabel() label.gradientLayer.colors = [UIColor.color126B4E().cgColor, UIColor.color1A2D22().cgColor] label.gradientLayer.startPoint = .init(x: 0.5, y: 0) diff --git a/Veloria/Libs/Alert/VPVersionUpdateAlertView.swift b/Veloria/Libs/Alert/VPVersionUpdateAlertView.swift new file mode 100644 index 0000000..de44f4d --- /dev/null +++ b/Veloria/Libs/Alert/VPVersionUpdateAlertView.swift @@ -0,0 +1,53 @@ +// +// VPVersionUpdateAlertView.swift +// Veloria +// +// Created by 湖南秦九 on 2025/6/21. +// + +import UIKit + +class VPVersionUpdateAlertView: VPAlertView { + + + private lazy var versionView: UIView = { + let view = UIView() + view.backgroundColor = .colorA3F0DE() + view.layer.cornerRadius = 11 + view.layer.masksToBounds = true + return view + }() + + private lazy var versionLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .color000000() + return label + }() + + init(model: VPVersionUpdateModel) { + super.init(title: "veloria_update_title".localized, subtitle: model.des?.localized ?? "", icon: UIImage(named: "alert_icon_05"), normalButtonText: nil, highlightButtonText: "veloria_update_now".localized) + + versionLabel.text = model.version_name + + bgView.addSubview(versionView) + versionView.addSubview(versionLabel) + + versionView.snp.makeConstraints { make in + make.left.equalTo(titleLabel) + make.top.equalTo(titleLabel.snp.bottom).offset(8) + make.height.equalTo(22) + } + + versionLabel.snp.makeConstraints { make in + make.center.equalToSuperview() + make.left.equalToSuperview().offset(8) + } + + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} diff --git a/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/Contents.json b/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/Contents.json new file mode 100644 index 0000000..d7583b3 --- /dev/null +++ b/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "通知图标-切图图层@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "通知图标-切图图层@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/通知图标-切图图层@2x.png b/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/通知图标-切图图层@2x.png new file mode 100644 index 0000000..3a27331 Binary files /dev/null and b/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/通知图标-切图图层@2x.png differ diff --git a/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/通知图标-切图图层@3x.png b/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/通知图标-切图图层@3x.png new file mode 100644 index 0000000..108fd34 Binary files /dev/null and b/Veloria/Source/Assets.xcassets/icon/alert_icon_05.imageset/通知图标-切图图层@3x.png differ diff --git a/Veloria/Source/en.lproj/Localizable.strings b/Veloria/Source/en.lproj/Localizable.strings index 7d96a03..8c7a09e 100644 --- a/Veloria/Source/en.lproj/Localizable.strings +++ b/Veloria/Source/en.lproj/Localizable.strings @@ -95,6 +95,8 @@ "veloria_days_count_text" = "## days"; "veloria_last_play_episode" = "Last time Episode ##"; "veloria_coin_buy_title" = "Top Up | Indefinitely use"; +"veloria_update_title" = "Discover a new version"; +"veloria_update_now" = "Update Now"; "veloria_bonus_count_text" = "+## Bonus";