From cd6b6f7dcfb2d682e4fb0dddeea6a691a964b493 Mon Sep 17 00:00:00 2001 From: zjx Date: Mon, 16 Jun 2025 16:44:03 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B6=88=E6=81=AF=E9=80=9A=E7=9F=A5=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NotificationService/Info.plist | 18 ++ NotificationService/NotificationService.swift | 67 +++++++ Veloria.xcodeproj/project.pbxproj | 168 ++++++++++++++++++ Veloria/AppDelegate/SceneDelegate+APNS.swift | 2 +- Veloria/Base/Networking/Base/VPApi.swift | 2 - .../Controller/VPHomePageViewController.swift | 12 ++ .../Home/View/VPHomePlayHistoricalView.swift | 46 +++++ Veloria/Libs/Alert/VPAlertView.swift | 4 +- Veloria/Libs/Alert/VPAnpsAlertView.swift | 35 ++++ .../switch_icon_01.imageset/Contents.json | 22 +++ .../icon/switch_icon_01.imageset/Frame@2x.png | Bin 0 -> 1791 bytes .../icon/switch_icon_01.imageset/Frame@3x.png | Bin 0 -> 2542 bytes Veloria/Source/en.lproj/Localizable.strings | 2 +- 13 files changed, 372 insertions(+), 6 deletions(-) create mode 100644 NotificationService/Info.plist create mode 100644 NotificationService/NotificationService.swift create mode 100644 Veloria/Class/Home/View/VPHomePlayHistoricalView.swift create mode 100644 Veloria/Libs/Alert/VPAnpsAlertView.swift create mode 100644 Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Contents.json create mode 100644 Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Frame@2x.png create mode 100644 Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Frame@3x.png diff --git a/NotificationService/Info.plist b/NotificationService/Info.plist new file mode 100644 index 0000000..fe81721 --- /dev/null +++ b/NotificationService/Info.plist @@ -0,0 +1,18 @@ + + + + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + NSExtension + + NSExtensionPointIdentifier + com.apple.usernotifications.service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).NotificationService + + + diff --git a/NotificationService/NotificationService.swift b/NotificationService/NotificationService.swift new file mode 100644 index 0000000..1841d33 --- /dev/null +++ b/NotificationService/NotificationService.swift @@ -0,0 +1,67 @@ +// +// NotificationService.swift +// NotificationService +// +// Created by 湖南秦九 on 2025/6/16. +// + +import UserNotifications + +class NotificationService: UNNotificationServiceExtension { + var contentHandler: ((UNNotificationContent) -> Void)? + var bestAttemptContent: UNMutableNotificationContent? + + override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { + + self.contentHandler = contentHandler + bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) + + guard let bestAttemptContent = bestAttemptContent else { + contentHandler(request.content) + return + } + + if let options = request.content.userInfo["fcm_options"] as? [String : Any], + let imageURLString = options["image"] as? String, + let imageURL = URL(string: imageURLString) { + + downloadImage(from: imageURL) { attachment in + if let attachment = attachment { + bestAttemptContent.attachments = [attachment] + } + contentHandler(bestAttemptContent) + } + } else { + contentHandler(bestAttemptContent) + } + } + + override func serviceExtensionTimeWillExpire() { + if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { + contentHandler(bestAttemptContent) + } + } + + // 下载图片 + private func downloadImage(from url: URL, completion: @escaping (UNNotificationAttachment?) -> Void) { + let task = URLSession.shared.downloadTask(with: url) { (downloadedUrl, _, error) in + guard let downloadedUrl = downloadedUrl else { + completion(nil) + return + } + + let tmpDir = FileManager.default.temporaryDirectory + let tmpFile = tmpDir.appendingPathComponent(url.lastPathComponent) + + do { + try FileManager.default.moveItem(at: downloadedUrl, to: tmpFile) + let attachment = try UNNotificationAttachment(identifier: UUID().uuidString, url: tmpFile, options: nil) + completion(attachment) + } catch { + completion(nil) + } + } + task.resume() + } +} + diff --git a/Veloria.xcodeproj/project.pbxproj b/Veloria.xcodeproj/project.pbxproj index 5650b2d..07812e9 100644 --- a/Veloria.xcodeproj/project.pbxproj +++ b/Veloria.xcodeproj/project.pbxproj @@ -158,6 +158,10 @@ BFCCE1242DFBF57B00EDE165 /* FirebaseCore in Frameworks */ = {isa = PBXBuildFile; productRef = BFCCE1232DFBF57B00EDE165 /* FirebaseCore */; }; BFCCE1262DFBF57B00EDE165 /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = BFCCE1252DFBF57B00EDE165 /* FirebaseMessaging */; }; BFCCE1282DFC080200EDE165 /* HWPanModalContentView+VPAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1272DFC07FB00EDE165 /* HWPanModalContentView+VPAdd.swift */; }; + BFCCE1342DFFFAB600EDE165 /* NotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = BFCCE12D2DFFFAB600EDE165 /* NotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + BFCCE13D2DFFFAC500EDE165 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE13B2DFFFAC500EDE165 /* NotificationService.swift */; }; + BFCCE1402E000ACE00EDE165 /* VPAnpsAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */; }; + BFCCE1422E000F4800EDE165 /* VPHomePlayHistoricalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1412E000F4800EDE165 /* VPHomePlayHistoricalView.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 */; }; @@ -235,6 +239,30 @@ F939C04AD4003BA127F15C28 /* Pods_Veloria.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F57E87E765BF8D72A43DCA /* Pods_Veloria.framework */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + BFCCE1322DFFFAB600EDE165 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 1B056DEC2DDABE2B007EE38D /* Project object */; + proxyType = 1; + remoteGlobalIDString = BFCCE12C2DFFFAB600EDE165; + remoteInfo = NotificationService; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + BFCCE1352DFFFAB600EDE165 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + BFCCE1342DFFFAB600EDE165 /* NotificationService.appex in Embed Foundation Extensions */, + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 1B056DF42DDABE2B007EE38D /* Veloria.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Veloria.app; sourceTree = BUILT_PRODUCTS_DIR; }; 1B056E212DDAC0FD007EE38D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -394,6 +422,11 @@ BFCCE11E2DFAD18000EDE165 /* VPGuideViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPGuideViewController.swift; sourceTree = ""; }; BFCCE1202DFBF33500EDE165 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; BFCCE1272DFC07FB00EDE165 /* HWPanModalContentView+VPAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HWPanModalContentView+VPAdd.swift"; sourceTree = ""; }; + BFCCE12D2DFFFAB600EDE165 /* NotificationService.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = NotificationService.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + BFCCE13A2DFFFAC500EDE165 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + BFCCE13B2DFFFAC500EDE165 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = ""; }; + BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPAnpsAlertView.swift; sourceTree = ""; }; + BFCCE1412E000F4800EDE165 /* VPHomePlayHistoricalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPHomePlayHistoricalView.swift; sourceTree = ""; }; BFF5AFA32DE6F15E0044227A /* VPMeVipCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipCell.swift; sourceTree = ""; }; BFF5AFA52DE700420044227A /* VPMeVipPrivilegeItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipPrivilegeItemView.swift; sourceTree = ""; }; BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeCoinCell.swift; sourceTree = ""; }; @@ -483,6 +516,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BFCCE12A2DFFFAB600EDE165 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -490,6 +530,7 @@ isa = PBXGroup; children = ( 1B056E2A2DDAC0FD007EE38D /* Veloria */, + BFCCE13C2DFFFAC500EDE165 /* NotificationService */, 1B056DF52DDABE2B007EE38D /* Products */, 97790501CCBF987017A55C80 /* Pods */, AEE348721F7DD68AB45E7964 /* Frameworks */, @@ -500,6 +541,7 @@ isa = PBXGroup; children = ( 1B056DF42DDABE2B007EE38D /* Veloria.app */, + BFCCE12D2DFFFAB600EDE165 /* NotificationService.appex */, ); name = Products; sourceTree = ""; @@ -879,6 +921,7 @@ BF0FA78A2DE164C100C9E5F2 /* VPSearchResultCell.swift */, BF0FA7902DE16CBF00C9E5F2 /* VPSearchHistoryView.swift */, BF5E75BF2DE5566200DE9DFE /* VPHomePageControlView.swift */, + BFCCE1412E000F4800EDE165 /* VPHomePlayHistoricalView.swift */, ); path = View; sourceTree = ""; @@ -1143,6 +1186,15 @@ path = Guide; sourceTree = ""; }; + BFCCE13C2DFFFAC500EDE165 /* NotificationService */ = { + isa = PBXGroup; + children = ( + BFCCE13A2DFFFAC500EDE165 /* Info.plist */, + BFCCE13B2DFFFAC500EDE165 /* NotificationService.swift */, + ); + path = NotificationService; + sourceTree = ""; + }; BFF5AFBB2DE837710044227A /* Wallet */ = { isa = PBXGroup; children = ( @@ -1245,6 +1297,7 @@ BFF5B23A2DF018900044227A /* VPAlertView.swift */, BFF5B2382DF014520044227A /* VPBaseAlertView.swift */, BFF5B2362DF013410044227A /* VPAlertWindowManager.swift */, + BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */, ); path = Alert; sourceTree = ""; @@ -1280,16 +1333,37 @@ 1B056DF12DDABE2B007EE38D /* Frameworks */, 1B056DF22DDABE2B007EE38D /* Resources */, D1E2E0FAE9833666668F2F70 /* [CP] Embed Pods Frameworks */, + BFCCE1352DFFFAB600EDE165 /* Embed Foundation Extensions */, ); buildRules = ( ); dependencies = ( + BFCCE1332DFFFAB600EDE165 /* PBXTargetDependency */, ); name = Veloria; productName = VideoPlayer; productReference = 1B056DF42DDABE2B007EE38D /* Veloria.app */; productType = "com.apple.product-type.application"; }; + BFCCE12C2DFFFAB600EDE165 /* NotificationService */ = { + isa = PBXNativeTarget; + buildConfigurationList = BFCCE1392DFFFAB600EDE165 /* Build configuration list for PBXNativeTarget "NotificationService" */; + buildPhases = ( + BFCCE1292DFFFAB600EDE165 /* Sources */, + BFCCE12A2DFFFAB600EDE165 /* Frameworks */, + BFCCE12B2DFFFAB600EDE165 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NotificationService; + packageProductDependencies = ( + ); + productName = NotificationService; + productReference = BFCCE12D2DFFFAB600EDE165 /* NotificationService.appex */; + productType = "com.apple.product-type.app-extension"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -1305,6 +1379,9 @@ CreatedOnToolsVersion = 16.2; LastSwiftMigration = 1620; }; + BFCCE12C2DFFFAB600EDE165 = { + CreatedOnToolsVersion = 16.2; + }; }; }; buildConfigurationList = 1B056DEF2DDABE2B007EE38D /* Build configuration list for PBXProject "Veloria" */; @@ -1326,6 +1403,7 @@ projectRoot = ""; targets = ( 1B056DF32DDABE2B007EE38D /* Veloria */, + BFCCE12C2DFFFAB600EDE165 /* NotificationService */, ); }; /* End PBXProject section */ @@ -1344,6 +1422,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BFCCE12B2DFFFAB600EDE165 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ @@ -1468,6 +1553,7 @@ BF5E75CC2DE5692D00DE9DFE /* JXTransitionDefine.swift in Sources */, BF5E75CD2DE5692D00DE9DFE /* JXTransitionDelegateBridge.swift in Sources */, BF5E75CE2DE5692D00DE9DFE /* JXPushAnimatedTransition.swift in Sources */, + BFCCE1402E000ACE00EDE165 /* VPAnpsAlertView.swift in Sources */, BF5E75CF2DE5692D00DE9DFE /* UIViewController+JXTransition.swift in Sources */, BFF5B26E2DF297680044227A /* VPOpenAppModel.swift in Sources */, BFF5B23F2DF0443B0044227A /* VPWebScriptModel.swift in Sources */, @@ -1586,6 +1672,7 @@ BFCCE1122DF9638B00EDE165 /* VPVipAlertView.swift in Sources */, BF0FA7172DDC78FF00C9E5F2 /* ZKCycleScrollView.swift in Sources */, BFF5B4AF2DF6B6630044227A /* VPMutualCollectionView.swift in Sources */, + BFCCE1422E000F4800EDE165 /* VPHomePlayHistoricalView.swift in Sources */, BF0FA7612DDFFE7100C9E5F2 /* VPVideoDetailModel.swift in Sources */, BFF5AFD22DE9A58A0044227A /* VPVIPRecordViewController.swift in Sources */, BFF5AFDA2DEE90350044227A /* VPVideoLockView.swift in Sources */, @@ -1611,8 +1698,24 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + BFCCE1292DFFFAB600EDE165 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BFCCE13D2DFFFAC500EDE165 /* NotificationService.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + BFCCE1332DFFFAB600EDE165 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = BFCCE12C2DFFFAB600EDE165 /* NotificationService */; + targetProxy = BFCCE1322DFFFAB600EDE165 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 1B056E252DDAC0FD007EE38D /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; @@ -1833,6 +1936,62 @@ }; name = Release; }; + BFCCE1362DFFFAB600EDE165 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 394VH538M8; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = NotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = NotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.qjwl168.veloria.ios.NotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + BFCCE1372DFFFAB600EDE165 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 394VH538M8; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = NotificationService/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = NotificationService; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.qjwl168.veloria.ios.NotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1854,6 +2013,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + BFCCE1392DFFFAB600EDE165 /* Build configuration list for PBXNativeTarget "NotificationService" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + BFCCE1362DFFFAB600EDE165 /* Debug */, + BFCCE1372DFFFAB600EDE165 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ diff --git a/Veloria/AppDelegate/SceneDelegate+APNS.swift b/Veloria/AppDelegate/SceneDelegate+APNS.swift index d414657..3576cdb 100644 --- a/Veloria/AppDelegate/SceneDelegate+APNS.swift +++ b/Veloria/AppDelegate/SceneDelegate+APNS.swift @@ -51,7 +51,7 @@ extension AppDelegate { } private func showApnsAlert() { - 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) + let alert = VPAnpsAlertView(title: "veloria_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 diff --git a/Veloria/Base/Networking/Base/VPApi.swift b/Veloria/Base/Networking/Base/VPApi.swift index b8cf0d3..617f5d2 100644 --- a/Veloria/Base/Networking/Base/VPApi.swift +++ b/Veloria/Base/Networking/Base/VPApi.swift @@ -83,14 +83,12 @@ extension VPApi: TargetType { "lang-key" : VPLocalizedManager.shared.currentLocalizedKey,//当前语言 "time-zone" : String.timeZone(), //时区 "app-version" : kVPAPPVersion, -// "device-id" : JXUUID.systemUUID(), //设备id "device-id" : JXUUID.uuid(), //设备id "brand" : "apple", //品牌 "app-name" : kVPAPPBundleIdentifier, "system-type" : "ios", "idfa" : JXUUID.idfa(), "model" : UIDevice.vp_machineModelName(), -// "security" : "false", ] //登录信息 dic["authorization"] = userToken diff --git a/Veloria/Class/Home/Controller/VPHomePageViewController.swift b/Veloria/Class/Home/Controller/VPHomePageViewController.swift index 37f7d81..dd0d24f 100644 --- a/Veloria/Class/Home/Controller/VPHomePageViewController.swift +++ b/Veloria/Class/Home/Controller/VPHomePageViewController.swift @@ -138,6 +138,11 @@ class VPHomePageViewController: VPViewController { return view }() + private lazy var playHistoricalView: VPHomePlayHistoricalView = { + let view = VPHomePlayHistoricalView() + return view + }() + override func viewDidLoad() { super.viewDidLoad() @@ -237,6 +242,7 @@ extension VPHomePageViewController { view.addSubview(searchButton) view.addSubview(historyButton) view.addSubview(pageView) + view.addSubview(playHistoricalView) titleLabel.snp.makeConstraints { make in make.centerX.equalToSuperview() @@ -257,6 +263,12 @@ extension VPHomePageViewController { make.width.height.equalTo(40) make.centerY.equalTo(searchButton) } + + playHistoricalView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.right.equalToSuperview().offset(15) + make.bottom.equalToSuperview().offset(-(UIScreen.customTabBarHeight + 10)) + } } } diff --git a/Veloria/Class/Home/View/VPHomePlayHistoricalView.swift b/Veloria/Class/Home/View/VPHomePlayHistoricalView.swift new file mode 100644 index 0000000..a3c5aba --- /dev/null +++ b/Veloria/Class/Home/View/VPHomePlayHistoricalView.swift @@ -0,0 +1,46 @@ +// +// VPHomePlayHistoricalView.swift +// Veloria +// +// Created by 湖南秦九 on 2025/6/16. +// + +import UIKit + +class VPHomePlayHistoricalView: UIView { + + private lazy var bgView: UIView = { + let view = UIView() + view.layer.cornerRadius = 10 + view.layer.masksToBounds = true + view.addEffectView(style: .dark) + return view + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + + vp_setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + +} + +extension VPHomePlayHistoricalView { + + private func vp_setupUI() { + addSubview(bgView) + + bgView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview().offset(12) + make.height.equalTo(56) + } + } + +} diff --git a/Veloria/Libs/Alert/VPAlertView.swift b/Veloria/Libs/Alert/VPAlertView.swift index 980fa79..5100b95 100644 --- a/Veloria/Libs/Alert/VPAlertView.swift +++ b/Veloria/Libs/Alert/VPAlertView.swift @@ -14,7 +14,7 @@ class VPAlertView: VPBaseAlertView { var clickCloseButton: (() -> Void)? - private lazy var bgView: UIImageView = { + private(set) lazy var bgView: UIImageView = { let imageView = UIImageView(image: UIImage(named: "alert_bg_image_01")) imageView.backgroundColor = .colorFFFFFF() imageView.layer.cornerRadius = 18 @@ -169,7 +169,7 @@ extension VPAlertView { titleLabel.snp.makeConstraints { make in make.left.equalToSuperview().offset(33) make.top.equalToSuperview().offset(36) - make.right.lessThanOrEqualToSuperview().offset(-100) + make.right.lessThanOrEqualToSuperview().offset(-130) } titleIconImageView.snp.makeConstraints { make in diff --git a/Veloria/Libs/Alert/VPAnpsAlertView.swift b/Veloria/Libs/Alert/VPAnpsAlertView.swift new file mode 100644 index 0000000..cb7172d --- /dev/null +++ b/Veloria/Libs/Alert/VPAnpsAlertView.swift @@ -0,0 +1,35 @@ +// +// VPAnpsAlertView.swift +// Veloria +// +// Created by 湖南秦九 on 2025/6/16. +// + +import UIKit + +class VPAnpsAlertView: VPAlertView { + + + private lazy var switchIconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "switch_icon_01")) + return imageView + }() + + override init(title: String, subtitle: String, icon: UIImage?, normalButtonText: String?, highlightButtonText: String?) { + super.init(title: title, subtitle: subtitle, icon: icon, normalButtonText: normalButtonText, highlightButtonText: highlightButtonText) + + bgView.addSubview(switchIconImageView) + + switchIconImageView.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-13) + make.top.equalToSuperview().offset(63) + } + + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + +} diff --git a/Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Contents.json b/Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Frame@2x.png b/Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Frame@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..592b9c259cbbf40e9d9c47d251bae47944a53642 GIT binary patch literal 1791 zcmV6*6in#kP^AcF3ku%4+g^koOhCP9lY^3^g=~(Vy1|1757`B2Dm^6i z>Y)j!MQF1lhze4=tyr<5d2M^hp|)GBl73{z=b4?Yli8W=ezlo>^ZZ~sv+r~!Gw*+% z=Xt*YK@bE%5ClOG1VIo4K@bE%5ClOG1VIo4K@bF?lNjhA1!NMyy<{2dNxJnA-JJFg zrNM$8DBc{PMDKUrglVVoiH#1@wjdP|Zl~xWr{D^J1hyFT?u(R_OZ#zj0d3N+lxLy$1WLK;VB&?HR>QovzyP3!Z}Cnjv5*Ln`y zhhIkD&;Yh2`_Yql(oL(frvCD_>$vgFC6w&n+~0LzVMa)pA{wM&K?;~;tH?n!dJ<1z zU@DCrqpxkq{6@J|yoxLNWn5dlfP1BXL;nwnl5Nyl9w>K1r*=3f@AwQqE`?ne>ar++AEB6$g(k2VdkUGB zf_A%b&_9>X)dc*gKwl$B0ppefV+ESPuIbftA8d*kRjw_b$4?`l)}$M7D4ra%{b@BZ zgv2O7BX-Tcxv63>+lPljV+!TvaOo=uxveR`mG~^gJP3`fgT>fvR~5wlNU}8_Ny2X>_XW|-I^yE0 zg7i=At4Z@)i7Ut%jE_Pi>j?4Hv4I;bxdAf(S;_5DJ}@i)m~TKM;ubrC41`(Ad$|-2XGkae| zH^6OOLCP?PP4Zbo(1@NyFS>!=owaV&K-n^#$}k;m;26>kYzuu(V~B&g1$`(ztbUG8 z!*L{pgm!|UyGfYP3xzI6H$gZaDs%x+!-rUqZZ~s3EJ#Tri zWMxv{Zo{MMx`0IK`#-wk1H1X{?_tlWxTgLmG~)7yrxfB(>Bi|_RWQ+Ur#JvQSqQG3 zx@ghPMvVFA=hb5PcsECJ(}@j@pw1p{#$G~%o{>@lPZ7J>ms6D)e^lLbu9 zQ?c0g31g#qO5Sy8zRxlhv#AiV;sBYb3rLKa{gk&+=Np)(K9Qk6FbhrLz)HJ3w<9@@ zJ0yx*VNjRTgR0};aUV$taA@qV5S~z3F5~K{G&WzShvM$>Y(VImrRrw8wuEr z&@n;$R7xUiEDDuIOv_8&iSFhmZ6(Tl1*}t%_i5FRB?y8b2!bF8f*=TjAP9mW2!bF8 hf*=TjAP7R|_zyB=8r&65z{UUo002ovPDHLkV1lgvH!lDH literal 0 HcmV?d00001 diff --git a/Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Frame@3x.png b/Veloria/Source/Assets.xcassets/icon/switch_icon_01.imageset/Frame@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..004f24e34d4247063ae082866542b5f16ed5e222 GIT binary patch literal 2542 zcma)8_ct2~1C3oO^lP6PquOfi5>dM~YE_Fy8ZjHK8N1Y`wo;xVqV(BXBN3qzYStDs zX2f`S_DoS)o6q|X-aY5ud+t5w{(ck8Obmb=f*b$<0BB_R5PIR5e|d@ZLNyqC<}Zxh z+tAV%01#98mkfFs1>{A^;0ra-0pKY@YZrmpS^J4L08o{3`NW>(Vi0ZgP#YG=K%XA) z0=WvXZEyAKL$suWh}UHcsV3aEuBJX*mpqBJ-I|cpI-PW;Qg%bKh^qK~A9rc9hHqkA z=UUMnuOi3H6L<`TP%(p#SX@h@Vw>En2G1TT=S-|*36%J|5A>^_{cmdb)G%Qrc=9ua zHgMdyb;9`ezrrQgQbiBwo*7Y8o#O0x2**U^-~;G<_3gJob0lZo!?LG^MYbey&SeP~l02WAhd?sHd9)zvXLh(2|2L=|Tr!}7=b_sn3Mgu`=UVU^QTp0xMoc;wn3 z-#^=ODpP$=m|ojs6L+Vm+Z#rQ`Df1Q5np*JxMfQhB`!D;K6X{x`km=A?u_BNLu>9gX=D4UJH@ikP=rEp7P-*n0^Qj|I!!?u0_#hr z*LXh@9IuP~BSCjglu&hp+=n(>|D1us=unM59<|7vLwpeEe|o?jInmk!+&IJ}t}nfe zTx>UK{vA~cYj`D|`qbT25xjaBQ!qHga4hvw?f7GCu2k|5=y3T*t=oQMGx>LpS&h2} zc_yBHVFed%?V&}x9uJjcz0l0VUbdBcA%$K9My|-OfBi-ssWg)IPdkXp6;?w-veUs) zpA5pHbn_LapA?Di>T^?vCOjCsyGL^4aCZ>Z79ng7kFnIo;W;zzHGzll#aa`11s+*t zwY1PbcO?+o3o2P$@UGZZu8-X@{-ivgbCqR|B!`Cn@?JN4CC%Eu( zydH>k3OZJUUoR3)PS8+jgAKn^-+DyOm>haM5gaD;LBLukQ!`$NJ6Zq@&Luo@h->W~U;=g^pUUM0nO@DK zA*-Itmt4!e%^^c?^WcQv7sPc-lydS>er>MamvQLPj+7o-5e@$flZC;*Jmqod$DWSq zY7@^62GB^B6gmLI241G0nZ&p2z>n{=yiwjc7ydR@Fu1SP6^h^q8aLPpJb$y&)B$v7 z#>D5GU6RF@DHIDdbV=F65&szS!oBZb4% z%-NR2+UMe$qu&j7gnVBI-VIZnr4HB=<~RHsuD`s$sT4Hcd9rUs;Q6Y8k#= zrCY&2eXSp*y zkmzpDOP?DEtX!aU76YLJ(xZGVo3(LQ&_s^arqe|>gaHI%(r&Urc%)Y_`FEO`V^eBq z;K)u*GI+*amE$+A`8GgVj0^och=*UEJp;_a z`^`Ifk{nT{;*fE$!1GYMZ#XXStyFrh^!lR@f5zh)BRN_`+sz~wkdnV`UW)apk2TAf zi0)Z~(g~Nx9Fx zZc11_W$~47Q?BF5y&L4D>6XuSBHaG&81HI*aMRb;_(nUw5do$F`4L5RyRG+3Do}B2 zkhZb~lGPM3g0^%|Ybol|sHh;py<0cA;nqwbY3-VA3x+2}Rm|lc?yabInYaBiBSqd1 zEG3Lk6ETpJXdjkxkImNgKP(h-SQQ=8i|p0j%WDF7x#P0dvOc&F)Lg~Wm9i7LZ7@{l zc+CmJn0KG9-lB0;j`BmgZL?TaiO63?ipCnxtG%@ZR