diff --git a/SynthReel.xcodeproj/project.pbxproj b/SynthReel.xcodeproj/project.pbxproj index 50c4aae..73e2c19 100644 --- a/SynthReel.xcodeproj/project.pbxproj +++ b/SynthReel.xcodeproj/project.pbxproj @@ -108,6 +108,21 @@ 370D2F092ED44A6D00571E77 /* SRListMenuCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F082ED44A6D00571E77 /* SRListMenuCell.swift */; }; 370D2F0C2ED44ACB00571E77 /* SRListMenuDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F0B2ED44ACB00571E77 /* SRListMenuDataSource.swift */; }; 370D2F102ED4534500571E77 /* SRUserViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F0F2ED4534500571E77 /* SRUserViewController.swift */; }; + 370D2F152ED457F000571E77 /* SRUserTopCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F142ED457F000571E77 /* SRUserTopCell.swift */; }; + 370D2F182ED45B3000571E77 /* SRUserSettingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F172ED45B3000571E77 /* SRUserSettingModel.swift */; }; + 370D2F1A2ED45CCA00571E77 /* SRUserSettingCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F192ED45CCA00571E77 /* SRUserSettingCell.swift */; }; + 370D2F1C2ED4770800571E77 /* SRUserInfoModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F1B2ED4770800571E77 /* SRUserInfoModel.swift */; }; + 370D2F1E2ED54C7F00571E77 /* SRHelpCenterController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F1D2ED54C7F00571E77 /* SRHelpCenterController.swift */; }; + 370D2F202ED54C8F00571E77 /* SRAboutUsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F1F2ED54C8F00571E77 /* SRAboutUsController.swift */; }; + 370D2F222ED54CA400571E77 /* SRPrivacyController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F212ED54CA400571E77 /* SRPrivacyController.swift */; }; + 370D2F252ED5807600571E77 /* SRAboutHeaderVIew.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F242ED5807600571E77 /* SRAboutHeaderVIew.swift */; }; + 370D2F272ED581BB00571E77 /* SRAboutCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F262ED581BB00571E77 /* SRAboutCell.swift */; }; + 370D2F292ED58EC400571E77 /* SRTopChartsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F282ED58EC400571E77 /* SRTopChartsViewController.swift */; }; + 370D2F2B2ED597F700571E77 /* SRTopChartsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F2A2ED597F700571E77 /* SRTopChartsCell.swift */; }; + 370D2F2D2ED5AA9700571E77 /* SRViralHitCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F2C2ED5AA9700571E77 /* SRViralHitCell.swift */; }; + 370D2F2F2ED5AB2500571E77 /* SRViralHitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370D2F2E2ED5AB2500571E77 /* SRViralHitController.swift */; }; + 3754ACBD2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754ACBC2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift */; }; + 3754ACBF2ED5B839009EBCAD /* SRNavgationTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754ACBE2ED5B839009EBCAD /* SRNavgationTitleView.swift */; }; 3779D0612ECF1CB8006B1698 /* SRShortHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3779D0602ECF1CB8006B1698 /* SRShortHeaderView.swift */; }; 47BB39E2DD30787FA591F8EB /* Pods_SynthReel.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9255BF4D4B1CFDDB5CFFB43 /* Pods_SynthReel.framework */; }; /* End PBXBuildFile section */ @@ -215,6 +230,21 @@ 370D2F082ED44A6D00571E77 /* SRListMenuCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRListMenuCell.swift; sourceTree = ""; }; 370D2F0B2ED44ACB00571E77 /* SRListMenuDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRListMenuDataSource.swift; sourceTree = ""; }; 370D2F0F2ED4534500571E77 /* SRUserViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRUserViewController.swift; sourceTree = ""; }; + 370D2F142ED457F000571E77 /* SRUserTopCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRUserTopCell.swift; sourceTree = ""; }; + 370D2F172ED45B3000571E77 /* SRUserSettingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRUserSettingModel.swift; sourceTree = ""; }; + 370D2F192ED45CCA00571E77 /* SRUserSettingCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRUserSettingCell.swift; sourceTree = ""; }; + 370D2F1B2ED4770800571E77 /* SRUserInfoModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRUserInfoModel.swift; sourceTree = ""; }; + 370D2F1D2ED54C7F00571E77 /* SRHelpCenterController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRHelpCenterController.swift; sourceTree = ""; }; + 370D2F1F2ED54C8F00571E77 /* SRAboutUsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRAboutUsController.swift; sourceTree = ""; }; + 370D2F212ED54CA400571E77 /* SRPrivacyController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRPrivacyController.swift; sourceTree = ""; }; + 370D2F242ED5807600571E77 /* SRAboutHeaderVIew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRAboutHeaderVIew.swift; sourceTree = ""; }; + 370D2F262ED581BB00571E77 /* SRAboutCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRAboutCell.swift; sourceTree = ""; }; + 370D2F282ED58EC400571E77 /* SRTopChartsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRTopChartsViewController.swift; sourceTree = ""; }; + 370D2F2A2ED597F700571E77 /* SRTopChartsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRTopChartsCell.swift; sourceTree = ""; }; + 370D2F2C2ED5AA9700571E77 /* SRViralHitCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRViralHitCell.swift; sourceTree = ""; }; + 370D2F2E2ED5AB2500571E77 /* SRViralHitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRViralHitController.swift; sourceTree = ""; }; + 3754ACBC2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationBar+SRAdd.swift"; sourceTree = ""; }; + 3754ACBE2ED5B839009EBCAD /* SRNavgationTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRNavgationTitleView.swift; sourceTree = ""; }; 3779D0602ECF1CB8006B1698 /* SRShortHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SRShortHeaderView.swift; sourceTree = ""; }; 59DC746604B26E9FF802D317 /* Pods-SynthReel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SynthReel.debug.xcconfig"; path = "Target Support Files/Pods-SynthReel/Pods-SynthReel.debug.xcconfig"; sourceTree = ""; }; AA88214030574193B51DE563 /* Pods-SynthReel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SynthReel.release.xcconfig"; path = "Target Support Files/Pods-SynthReel/Pods-SynthReel.release.xcconfig"; sourceTree = ""; }; @@ -299,6 +329,8 @@ 03B1A84F2EC5DB2E006C353F /* SRHomeViewController.swift */, 03B1A8D42EC6CF37006C353F /* SRHomeChildViewController.swift */, 03B1A92F2ECC10D1006C353F /* SRSearchViewController.swift */, + 370D2F282ED58EC400571E77 /* SRTopChartsViewController.swift */, + 370D2F2E2ED5AB2500571E77 /* SRViralHitController.swift */, ); path = VC; sourceTree = ""; @@ -321,6 +353,7 @@ 03B1A93D2ECC4568006C353F /* SRTableView.swift */, 03B1A93F2ECC45BA006C353F /* SRTableViewCell.swift */, 03B1A94B2ECC7A2D006C353F /* SRPanModalContentView.swift */, + 3754ACBE2ED5B839009EBCAD /* SRNavgationTitleView.swift */, ); path = View; sourceTree = ""; @@ -354,6 +387,8 @@ 03B1A9412ECC4632006C353F /* SRHotSearchCell.swift */, 03B1A9432ECC4ED9006C353F /* SRSearchResultView.swift */, 03B1A9452ECC5679006C353F /* SRSearchResultCell.swift */, + 370D2F2A2ED597F700571E77 /* SRTopChartsCell.swift */, + 370D2F2C2ED5AA9700571E77 /* SRViralHitCell.swift */, ); path = V; sourceTree = ""; @@ -569,6 +604,7 @@ 03E9A7F12EC4A8EC000D1067 /* UserDefaults+SRAdd.swift */, 03B1A91A2ECAFFCB006C353F /* UIView+SRAdd.swift */, 03B1A91C2ECB241B006C353F /* UIScrollView+SRAdd.swift */, + 3754ACBC2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift */, ); path = Extension; sourceTree = ""; @@ -594,6 +630,8 @@ 370D2F0D2ED4532100571E77 /* User */ = { isa = PBXGroup; children = ( + 370D2F162ED45B1C00571E77 /* model */, + 370D2F132ED457C900571E77 /* view */, 370D2F0E2ED4532A00571E77 /* VC */, ); path = User; @@ -603,10 +641,33 @@ isa = PBXGroup; children = ( 370D2F0F2ED4534500571E77 /* SRUserViewController.swift */, + 370D2F1D2ED54C7F00571E77 /* SRHelpCenterController.swift */, + 370D2F1F2ED54C8F00571E77 /* SRAboutUsController.swift */, + 370D2F212ED54CA400571E77 /* SRPrivacyController.swift */, ); path = VC; sourceTree = ""; }; + 370D2F132ED457C900571E77 /* view */ = { + isa = PBXGroup; + children = ( + 370D2F142ED457F000571E77 /* SRUserTopCell.swift */, + 370D2F192ED45CCA00571E77 /* SRUserSettingCell.swift */, + 370D2F242ED5807600571E77 /* SRAboutHeaderVIew.swift */, + 370D2F262ED581BB00571E77 /* SRAboutCell.swift */, + ); + path = view; + sourceTree = ""; + }; + 370D2F162ED45B1C00571E77 /* model */ = { + isa = PBXGroup; + children = ( + 370D2F172ED45B3000571E77 /* SRUserSettingModel.swift */, + 370D2F1B2ED4770800571E77 /* SRUserInfoModel.swift */, + ); + path = model; + sourceTree = ""; + }; 3779D05F2ECF1C8D006B1698 /* V */ = { isa = PBXGroup; children = ( @@ -761,7 +822,9 @@ 03B1A9402ECC45BA006C353F /* SRTableViewCell.swift in Sources */, 03E9A7EA2EC4995D000D1067 /* SRKeychain.swift in Sources */, 03E9A7D92EC47B90000D1067 /* SRNetworkReachableManager.swift in Sources */, + 370D2F2D2ED5AA9700571E77 /* SRViralHitCell.swift in Sources */, 03B1A8532EC5E12E006C353F /* UIScreen+SRAdd.swift in Sources */, + 370D2F182ED45B3000571E77 /* SRUserSettingModel.swift in Sources */, 03B1A8FB2EC818BE006C353F /* UIStackView+SRAdd.swift in Sources */, 03B1A8E12EC6D6D3006C353F /* SRHomeMenuDataSource.swift in Sources */, 03E9A7F82EC4AA54000D1067 /* SRUserDefaultsKey.swift in Sources */, @@ -775,16 +838,22 @@ 03B1A9172ECAF14F006C353F /* SRHomeHotView.swift in Sources */, 03B1A8FD2EC81C62006C353F /* SRHomeBannerCell.swift in Sources */, 03E9A7DB2EC485BE000D1067 /* SRNetwork.swift in Sources */, + 370D2F152ED457F000571E77 /* SRUserTopCell.swift in Sources */, + 3754ACBD2ED5B6B6009EBCAD /* UINavigationBar+SRAdd.swift in Sources */, 03E9A7F42EC4A94D000D1067 /* SRAccountToken.swift in Sources */, + 370D2F222ED54CA400571E77 /* SRPrivacyController.swift in Sources */, 370D2EF72ED000C400571E77 /* SRFavoritesViewController.swift in Sources */, 370D2F072ED3FEFA00571E77 /* SRFavoritesCell.swift in Sources */, 03B1A8E72EC7175D006C353F /* SRCategoryModel.swift in Sources */, + 370D2F2F2ED5AB2500571E77 /* SRViralHitController.swift in Sources */, 03B1A94A2ECC79AB006C353F /* SREpSelectorView.swift in Sources */, 03B1A94E2ECD604B006C353F /* SREpSelectorCell.swift in Sources */, 03B1A9262ECBFF31006C353F /* SRShortPlayerViewModel.swift in Sources */, + 370D2F202ED54C8F00571E77 /* SRAboutUsController.swift in Sources */, 03B1A9322ECC1167006C353F /* SRSearchHomeView.swift in Sources */, 03B1A8F32EC809C5006C353F /* SRHomeHeaderView.swift in Sources */, 03B1A9482ECC6669006C353F /* SRProgressView.swift in Sources */, + 370D2F1A2ED45CCA00571E77 /* SRUserSettingCell.swift in Sources */, 03B1A91D2ECB2424006C353F /* UIScrollView+SRAdd.swift in Sources */, 03E9A7C92EC47177000D1067 /* AppDelegate.swift in Sources */, 03E9A7FA2EC56D03000D1067 /* String+SRAdd.swift in Sources */, @@ -797,7 +866,10 @@ 03980F532ECEDEAB0006E317 /* SRRecommendPlayerControlView.swift in Sources */, 03B1A90F2ECAC768006C353F /* SRHomeBingeWorthyView.swift in Sources */, 03B1A9072EC86656006C353F /* SRGradientView.swift in Sources */, + 370D2F292ED58EC400571E77 /* SRTopChartsViewController.swift in Sources */, + 370D2F1E2ED54C7F00571E77 /* SRHelpCenterController.swift in Sources */, 03E9A7CA2EC47177000D1067 /* SceneDelegate.swift in Sources */, + 370D2F252ED5807600571E77 /* SRAboutHeaderVIew.swift in Sources */, 03B1A8402EC5CA37006C353F /* AppDelegate+Config.swift in Sources */, 03B1A9152ECAEE63006C353F /* SRHomeViralHitsCell.swift in Sources */, 03B1A8472EC5CBCF006C353F /* SRViewController.swift in Sources */, @@ -808,6 +880,7 @@ 03B1A90D2ECAC51A006C353F /* NSNumber+SRAdd.swift in Sources */, 03E9A7DD2EC485E1000D1067 /* SRNetworkModel.swift in Sources */, 03B1A9442ECC4ED9006C353F /* SRSearchResultView.swift in Sources */, + 3754ACBF2ED5B839009EBCAD /* SRNavgationTitleView.swift in Sources */, 03B1A8FF2EC81C92006C353F /* SRImageView.swift in Sources */, 03B1A83B2EC5C8E0006C353F /* SRToast.swift in Sources */, 03B1A9302ECC10D1006C353F /* SRSearchViewController.swift in Sources */, @@ -817,6 +890,7 @@ 370D2F102ED4534500571E77 /* SRUserViewController.swift in Sources */, 03B1A9112ECAC927006C353F /* SRHomeBingeWorthyCell.swift in Sources */, 03E9A7F22EC4A8F6000D1067 /* UserDefaults+SRAdd.swift in Sources */, + 370D2F2B2ED597F700571E77 /* SRTopChartsCell.swift in Sources */, 03B1A93A2ECC3F54006C353F /* SRSearchViewModel.swift in Sources */, 03E9A7F62EC4A9B1000D1067 /* SRUserInfo.swift in Sources */, 03B1A8F92EC813BC006C353F /* SRScrollView.swift in Sources */, @@ -852,6 +926,8 @@ 03980F4F2ECEB91C0006E317 /* SRRecommendPlayerViewModel.swift in Sources */, 03B1A9422ECC4632006C353F /* SRHotSearchCell.swift in Sources */, 03B1A9342ECC12D9006C353F /* SRSearchTextView.swift in Sources */, + 370D2F272ED581BB00571E77 /* SRAboutCell.swift in Sources */, + 370D2F1C2ED4770800571E77 /* SRUserInfoModel.swift in Sources */, 03B1A93C2ECC406E006C353F /* SRHotSearchView.swift in Sources */, 03B1A8E32EC6F577006C353F /* SRHomeMenuCell.swift in Sources */, ); diff --git a/SynthReel/Base/Extension/UINavigationBar+SRAdd.swift b/SynthReel/Base/Extension/UINavigationBar+SRAdd.swift new file mode 100644 index 0000000..860eb8a --- /dev/null +++ b/SynthReel/Base/Extension/UINavigationBar+SRAdd.swift @@ -0,0 +1,35 @@ +// +// UINavigationBar+SRAdd.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +extension UINavigationBar { + + static func uv_applyGlobalAppearance() { + + let navBar = UINavigationBar.appearance() + + navBar.tintColor = .white + navBar.titleTextAttributes = [ + .foregroundColor: UIColor.white, + .font: UIFont.boldSystemFont(ofSize: 18) + ] + + // 自定义返回按钮 + if let backImage = UIImage(named: "arrow_left_icon_01")?.withRenderingMode(.alwaysOriginal) { + navBar.backIndicatorImage = backImage + navBar.backIndicatorTransitionMaskImage = backImage + } + + // 隐藏返回文字 + UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment( + UIOffset(horizontal: -1000, vertical: 0), + for: .default + ) + } +} diff --git a/SynthReel/Base/Extension/UIView+SRAdd.swift b/SynthReel/Base/Extension/UIView+SRAdd.swift index df18b12..a53fa52 100644 --- a/SynthReel/Base/Extension/UIView+SRAdd.swift +++ b/SynthReel/Base/Extension/UIView+SRAdd.swift @@ -90,3 +90,66 @@ extension UIView { self.layer.mask = shapeLayer } } + +extension UIView { + + /// 绘制可旋转 + 可圆角的正六边形蒙版 + /// - Parameters: + /// - cornerRadius: 六边形边角圆角 + /// - rotationAngle: 六边形整体旋转角度(弧度制,如 π/6 = 30°) + func applyHexagonMask(cornerRadius: CGFloat = 0, rotationAngle: CGFloat = 0) { + let width = bounds.width + let height = bounds.height + let center = CGPoint(x: width / 2, y: height / 2) + + // 半径取最小边的一半,避免裁剪溢出 + let radius = min(width, height) / 2 + + let path = UIBezierPath() + var points: [CGPoint] = [] + + // 生成 6 个点(加入旋转 angle) + for i in 0..<6 { + let angle = CGFloat(i) * (.pi / 3) + rotationAngle + let x = center.x + radius * cos(angle) + let y = center.y + radius * sin(angle) + points.append(CGPoint(x: x, y: y)) + } + + // 处理圆角六边形 + for i in 0..<6 { + let prev = points[(i + 5) % 6] + let curr = points[i] + let next = points[(i + 1) % 6] + + let v1 = CGPoint(x: curr.x - prev.x, y: curr.y - prev.y) + let v2 = CGPoint(x: curr.x - next.x, y: curr.y - next.y) + + let l1 = sqrt(v1.x * v1.x + v1.y * v1.y) + let l2 = sqrt(v2.x * v2.x + v2.y * v2.y) + + let u1 = CGPoint(x: v1.x / l1, y: v1.y / l1) + let u2 = CGPoint(x: v2.x / l2, y: v2.y / l2) + + let p1 = CGPoint(x: curr.x - u1.x * cornerRadius, + y: curr.y - u1.y * cornerRadius) + let p2 = CGPoint(x: curr.x - u2.x * cornerRadius, + y: curr.y - u2.y * cornerRadius) + + if i == 0 { + path.move(to: p1) + } else { + path.addLine(to: p1) + } + + path.addQuadCurve(to: p2, controlPoint: curr) + } + + path.close() + + // 设置 mask + let maskLayer = CAShapeLayer() + maskLayer.path = path.cgPath + layer.mask = maskLayer + } +} diff --git a/SynthReel/Base/View/SRLabel.swift b/SynthReel/Base/View/SRLabel.swift index 41b8fad..8a551b5 100644 --- a/SynthReel/Base/View/SRLabel.swift +++ b/SynthReel/Base/View/SRLabel.swift @@ -19,9 +19,12 @@ class SRLabel: UILabel { override func layoutSubviews() { super.layoutSubviews() - let size = self.bounds.size - if let text = self.text, text.count > 0, let colors = self.textColors, let startPoint = self.textStartPoint, let endPoine = self.textEndPoint { - self.textColor = UIColor(patternImage: UIImage.sr_getGradientImage(size: size, colors: colors, startPoint: startPoint, endPoint: endPoine)) + DispatchQueue.main.async { [weak self] in + guard let self = self else { return } + let size = self.bounds.size + if let text = self.text, text.count > 0, let colors = self.textColors, let startPoint = self.textStartPoint, let endPoine = self.textEndPoint { + self.textColor = UIColor(patternImage: UIImage.sr_getGradientImage(size: size, colors: colors, startPoint: startPoint, endPoint: endPoine)) + } } } diff --git a/SynthReel/Base/View/SRNavgationTitleView.swift b/SynthReel/Base/View/SRNavgationTitleView.swift new file mode 100644 index 0000000..f412fe2 --- /dev/null +++ b/SynthReel/Base/View/SRNavgationTitleView.swift @@ -0,0 +1,89 @@ +// +// SRNavgationTitleView.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +import UIKit + +class SRNavgationTitleView: UIView { + + private let leftImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "闪光 1")) + imageView.contentMode = .scaleAspectFit + return imageView + }() + + private let rightImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "闪光 1")) + imageView.contentMode = .scaleAspectFit + return imageView + }() + + private let titleLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 18, weight: .bold) + label.textAlignment = .center + label.textColor = .white + return label + }() + + // MARK: - Init + init(title: String) { + super.init(frame: .zero) + titleLabel.text = title + addSubview(leftImageView) + addSubview(titleLabel) + addSubview(rightImageView) + sizeToFit() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: - Layout & Size + override func sizeThatFits(_ size: CGSize) -> CGSize { + let padding: CGFloat = 6 + let imageW: CGFloat = 20 + let height: CGFloat = 30 + + titleLabel.sizeToFit() + + let totalWidth = imageW + padding + titleLabel.bounds.width + padding + imageW + return CGSize(width: totalWidth, height: height) + } + + override func layoutSubviews() { + super.layoutSubviews() + + let padding: CGFloat = 10 + let imageW: CGFloat = 20 + let imageH: CGFloat = 20 + let height = bounds.height + + // 左图 + leftImageView.frame = CGRect(x: 0, + y: (height - imageH) / 2, + width: imageW, + height: imageH) + + // 标题 + let titleX = leftImageView.frame.maxX + padding + titleLabel.frame = CGRect(x: titleX, + y: 0, + width: titleLabel.bounds.width, + height: height) + + // 右图 + let rightX = titleLabel.frame.maxX + padding + rightImageView.frame = CGRect(x: rightX, + y: (height - imageH) / 2, + width: imageW, + height: imageH) + } +} diff --git a/SynthReel/Base/ViewController/SRNavigationController.swift b/SynthReel/Base/ViewController/SRNavigationController.swift index 33453e2..337be98 100644 --- a/SynthReel/Base/ViewController/SRNavigationController.swift +++ b/SynthReel/Base/ViewController/SRNavigationController.swift @@ -34,3 +34,28 @@ class SRNavigationController: UINavigationController { } } + +extension UINavigationController { + + func uv_setNavigationBarTransparent(_ transparent: Bool) { + if transparent { + self.navigationBar.setBackgroundImage(UIImage(), for: .default) + self.navigationBar.shadowImage = UIImage() + self.navigationBar.isTranslucent = true + } else { + self.navigationBar.setBackgroundImage(nil, for: .default) + self.navigationBar.shadowImage = nil + self.navigationBar.isTranslucent = false + } + } +} + +extension UINavigationController { + + func sr_setNavigationTitle(_ title: String?, for viewController: UIViewController) { + let titleText = title ?? "" + // 复用你的自定义标题视图(左右图片 + 文本) + let titleView = SRNavgationTitleView(title: titleText) + viewController.navigationItem.titleView = titleView + } +} diff --git a/SynthReel/Base/ViewController/SRTabBarController.swift b/SynthReel/Base/ViewController/SRTabBarController.swift index e90e470..b9d65a4 100644 --- a/SynthReel/Base/ViewController/SRTabBarController.swift +++ b/SynthReel/Base/ViewController/SRTabBarController.swift @@ -18,7 +18,7 @@ class SRTabBarController: ESTabBarController { let nav1 = createNavigationView(SRHomeViewController(), image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected")) let nav2 = createNavigationView(SRRecommendPlayerViewController(), image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected")) let nav3 = createNavigationView(SRMyShortViewController(), image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected")) - let nav4 = createNavigationView(SRViewController(), image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected")) + let nav4 = createNavigationView(SRUserViewController(), image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected")) viewControllers = [nav1, nav2, nav3, nav4] diff --git a/SynthReel/Class/Home/V/SRHomeHeaderView.swift b/SynthReel/Class/Home/V/SRHomeHeaderView.swift index 9b74866..c4a72f0 100644 --- a/SynthReel/Class/Home/V/SRHomeHeaderView.swift +++ b/SynthReel/Class/Home/V/SRHomeHeaderView.swift @@ -52,14 +52,21 @@ class SRHomeHeaderView: UIView { lazy var topChartsView: SRHomeTopChartsView = { let view = SRHomeTopChartsView() + view.showIndicator(true) view.didSelectedShort = { [weak self] model in self?.pushShortDetail(model) } + view.onButtonTapped = { [self] in + if let item = self.viewModel?.moduleArr.first(where: { $0.module_key == view.module_key }) { + pushTopCharts(item.list) + } + } return view }() lazy var bingeWorthyView: SRHomeBingeWorthyView = { let view = SRHomeBingeWorthyView() + view.showIndicator(false) view.didSelectedShort = { [weak self] model in self?.pushShortDetail(model) } @@ -68,14 +75,22 @@ class SRHomeHeaderView: UIView { lazy var viralHitsView: SRHomeViralHitsView = { let view = SRHomeViralHitsView() + view.showIndicator(true) view.didSelectedShort = { [weak self] model in self?.pushShortDetail(model) } + + view.onButtonTapped = { [self] in + if let item = self.viewModel?.moduleArr.first(where: { $0.module_key == view.module_key }) { + pushViralHits(item.list) + } + } return view }() lazy var premiereNowView: SRHomePremiereNowView = { let view = SRHomePremiereNowView() + view.showIndicator(false) view.didSelectedShort = { [weak self] model in self?.pushShortDetail(model) } @@ -126,6 +141,7 @@ class SRHomeHeaderView: UIView { stackView.addArrangedSubview(youLikeView) } else if $0.module_key == .popular { popularArr = $0.list + topChartsView.module_key = $0.module_key stackView.addArrangedSubview(topChartsView) } else if $0.module_key == .updates { updatesArr = $0.list @@ -135,6 +151,7 @@ class SRHomeHeaderView: UIView { stackView.addArrangedSubview(bingeWorthyView) } else if $0.module_key == .viralHits { viralHitsView.dataArr = $0.list + viralHitsView.module_key = $0.module_key stackView.addArrangedSubview(viralHitsView) } else if $0.module_key == .premiereNow { premiereNowView.dataArr = $0.list @@ -153,4 +170,16 @@ class SRHomeHeaderView: UIView { vc.shortId = model?.short_play_id self.viewController?.navigationController?.pushViewController(vc, animated: true) } + + func pushTopCharts(_ models: [SRShortModel]?) { + let vc = SRTopChartsViewController() + vc.dataArr = models ?? [] + self.viewController?.navigationController?.pushViewController(vc, animated: true) + } + + func pushViralHits(_ models: [SRShortModel]?) { + let vc = SRViralHitController() + vc.dataArr = models ?? [] + self.viewController?.navigationController?.pushViewController(vc, animated: true) + } } diff --git a/SynthReel/Class/Home/V/SRHomeModuleView.swift b/SynthReel/Class/Home/V/SRHomeModuleView.swift index 0bab06d..274bca8 100644 --- a/SynthReel/Class/Home/V/SRHomeModuleView.swift +++ b/SynthReel/Class/Home/V/SRHomeModuleView.swift @@ -13,6 +13,10 @@ class SRHomeModuleView: UIView { var didSelectedShort: ((_ model: SRShortModel?) -> Void)? + var onButtonTapped: (() -> Void)? + + var module_key: SRHomeModuleItem.ModuleKey? + lazy var titleLabel: UILabel = { let label = UILabel() label.font = .font(ofSize: 18, weight: .bold) @@ -20,13 +24,14 @@ class SRHomeModuleView: UIView { return label }() - lazy var indicatorImageView = UIImageView(image: UIImage(named: "arrow_right_icon_01")) - +// lazy var indicatorImageView = UIImageView(image: UIImage(named: "arrow_right_icon_01")) + private var indicatorImageView: UIImageView? lazy var button: UIControl = { - let button = UIControl(frame: .zero, primaryAction: UIAction(handler: { [weak self] _ in + let button = UIButton(frame: .zero, primaryAction: UIAction(handler: { [weak self] _ in guard let self = self else { return } - + onButtonTapped?() })) + return button }() @@ -34,10 +39,29 @@ class SRHomeModuleView: UIView { override init(frame: CGRect) { super.init(frame: frame) - +// addSubview(button) +// button.addSubview(titleLabel) +// button.addSubview(indicatorImageView) +// +// button.snp.makeConstraints { make in +// make.left.equalToSuperview().offset(15) +// make.right.equalToSuperview().offset(-15) +// make.top.equalToSuperview() +// make.height.equalTo(40) +// } +// +// titleLabel.snp.makeConstraints { make in +// make.centerY.equalToSuperview() +// make.left.equalToSuperview() +// } +// +// indicatorImageView.snp.makeConstraints { make in +// make.centerY.equalToSuperview() +// make.right.equalToSuperview() +// } +// addSubview(button) button.addSubview(titleLabel) - button.addSubview(indicatorImageView) button.snp.makeConstraints { make in make.left.equalToSuperview().offset(15) @@ -50,12 +74,6 @@ class SRHomeModuleView: UIView { make.centerY.equalToSuperview() make.left.equalToSuperview() } - - indicatorImageView.snp.makeConstraints { make in - make.centerY.equalToSuperview() - make.right.equalToSuperview() - } - } required init?(coder: NSCoder) { @@ -63,3 +81,30 @@ class SRHomeModuleView: UIView { } } + +// MARK: - Public API +extension SRHomeModuleView { + /// 控制箭头是否显示 + func showIndicator(_ show: Bool) { + if show { + // 已有就不重复添加 + if indicatorImageView != nil { return } + + let arrow = UIImageView(image: UIImage(named: "arrow_right_icon_01")) + arrow.contentMode = .scaleAspectFit + indicatorImageView = arrow + + button.addSubview(arrow) + + arrow.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalToSuperview() + } + + } else { + // 不需要箭头 + indicatorImageView?.removeFromSuperview() + indicatorImageView = nil + } + } +} diff --git a/SynthReel/Class/Home/V/SRSearchHomeView.swift b/SynthReel/Class/Home/V/SRSearchHomeView.swift index 3223680..9949bbe 100644 --- a/SynthReel/Class/Home/V/SRSearchHomeView.swift +++ b/SynthReel/Class/Home/V/SRSearchHomeView.swift @@ -20,7 +20,9 @@ class SRSearchHomeView: UIView { self.hotView.dataArr = self.viewModel?.hotDataArr ?? [] self.recordView.dataArr = self.viewModel?.recordList ?? [] - updateLayout() + DispatchQueue.main.async { + self.updateLayout() + } } } @@ -75,7 +77,10 @@ class SRSearchHomeView: UIView { } else if keyPath == "recordList" { self.recordView.dataArr = self.viewModel?.recordList ?? [] } - updateLayout() + DispatchQueue.main.async { + self.updateLayout() + } + } func updateLayout() { diff --git a/SynthReel/Class/Home/V/SRTopChartsCell.swift b/SynthReel/Class/Home/V/SRTopChartsCell.swift new file mode 100644 index 0000000..0948807 --- /dev/null +++ b/SynthReel/Class/Home/V/SRTopChartsCell.swift @@ -0,0 +1,150 @@ +// +// SRTopChartsCell.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRTopChartsCell: UICollectionViewCell { + + var model : SRShortModel? { + didSet { + titlelabel.text = model?.name + coverImageView.sr_setImage(model?.image_url) + detailLabel.text = model?.sr_description + let count = model?.watch_total ?? 0 + if count >= 1000 { + let value = Double(count) / 1000.0 + let text = String(format: "%.1fk", value) + + // 如果是 1.0k → 显示 1k + hotLabel.text = text.replacingOccurrences(of: ".0k", with: "k") + } else { + hotLabel.text = "\(count)" + } + } + } + + lazy var coverImageView: SRImageView = { + let imageView = SRImageView() + imageView.layer.cornerRadius = 2 + imageView.layer.masksToBounds = true + return imageView + }() + + lazy var bgIconImage : UIImageView = { + let imageview = UIImageView() + imageview.image = .topChartBg + imageview.contentMode = .scaleToFill + imageview.isUserInteractionEnabled = true + return imageview + }() + lazy var leftIconImage = UIImageView.init(image: .rankLeftIcon) + lazy var rightIconImage = UIImageView.init(image: .rankRightIcon) + lazy var hotIconImage = UIImageView.init(image: .fire) + + + lazy var titlelabel : UILabel = { + let labe = UILabel() + labe.textColor = .white + labe.font = .font(ofSize: 14, weight: .regular) + return labe + }() + + lazy var topLabel : UILabel = { + let labe = UILabel() + labe.textColor = UIColor.FFE_4_B_4 + labe.font = .font(ofSize: 12, weight: .semibold) + return labe + }() + + lazy var hotLabel : UILabel = { + let labe = UILabel() + labe.textColor = UIColor.FFE_4_B_4 + labe.font = .font(ofSize: 10, weight: .regular) + return labe + }() + + lazy var detailLabel : UILabel = { + let labe = UILabel() + labe.textColor = UIColor.A_6_A_6_A_6 + labe.font = .font(ofSize: 11, weight: .regular) + labe.numberOfLines = 1 + return labe + }() + + override init(frame: CGRect) { + super.init(frame: frame) + sr_setui() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension SRTopChartsCell { + func sr_setui (){ + titlelabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + hotLabel.setContentCompressionResistancePriority(.required, for: .horizontal) + + contentView.addSubview(bgIconImage) + contentView.addSubview(coverImageView) + contentView.addSubview(leftIconImage) + contentView.addSubview(topLabel) + contentView.addSubview(rightIconImage) + contentView.addSubview(titlelabel) + contentView.addSubview(hotIconImage) + contentView.addSubview(hotLabel) + contentView.addSubview(detailLabel) + + bgIconImage.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + coverImageView.snp.makeConstraints { make in + make.left.top.bottom.equalToSuperview().inset(4) + make.width.equalTo(90) + } + + leftIconImage.snp.makeConstraints { make in + make.top.equalTo(10) + make.left.equalTo(coverImageView.snp.right).offset(10) + } + + topLabel.snp.makeConstraints { make in + make.left.equalTo(leftIconImage.snp.right) + make.centerY.equalTo(leftIconImage) + } + + rightIconImage.snp.makeConstraints { make in + make.left.equalTo(topLabel.snp.right) + make.centerY.equalTo(leftIconImage) + } + + titlelabel.snp.makeConstraints { make in + make.left.equalTo(coverImageView.snp.right).offset(10) + make.top.equalTo(leftIconImage.snp.bottom).offset(10) + } + hotIconImage.snp.makeConstraints { make in + make.left.equalTo(titlelabel.snp.right).offset(10) + make.centerY.equalTo(titlelabel) + make.size.equalTo(CGSizeMake(10, 10)) + } + hotLabel.snp.makeConstraints { make in + make.left.equalTo(hotIconImage.snp.right).offset(2) + make.centerY.equalTo(hotIconImage) + make.right.lessThanOrEqualToSuperview().inset(10) + } + + detailLabel.snp.makeConstraints { make in + make.left.equalTo(titlelabel) + make.right.equalTo(-10) + make.top.equalTo(titlelabel.snp.bottom).offset(10) + } + } +} diff --git a/SynthReel/Class/Home/V/SRViralHitCell.swift b/SynthReel/Class/Home/V/SRViralHitCell.swift new file mode 100644 index 0000000..e2b8e6b --- /dev/null +++ b/SynthReel/Class/Home/V/SRViralHitCell.swift @@ -0,0 +1,86 @@ +// +// SRViralHitCell.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRViralHitCell: UICollectionViewCell { + var model : SRShortModel? { + didSet { + coverImageView.sr_setImage(model?.image_url) + let count = model?.watch_total ?? 0 + if count >= 1000 { + let value = Double(count) / 1000.0 + let text = String(format: "%.1fk", value) + + // 如果是 1.0k → 显示 1k + hotLabel.text = text.replacingOccurrences(of: ".0k", with: "k") + } else { + hotLabel.text = "\(count)" + } + } + } + + + lazy var bgImageView = UIImageView(image: UIImage(named: "home_viral_hits_cell_image")) + + lazy var coverImageView: SRImageView = { + let imageView = SRImageView() + imageView.layer.cornerRadius = 2 + imageView.layer.masksToBounds = true + return imageView + }() + + lazy var hotIconImage = UIImageView.init(image: .hotIcon01) + + lazy var hotLabel : UILabel = { + let labe = UILabel() + labe.textColor = .srBlue + labe.font = .font(ofSize: 10, weight: .regular) + return labe + }() + + override init(frame: CGRect) { + super.init(frame: frame) + sr_setui() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension SRViralHitCell { + func sr_setui (){ + + contentView.addSubview(bgImageView) + contentView.addSubview(coverImageView) + contentView.addSubview(hotIconImage) + contentView.addSubview(hotLabel) + + + bgImageView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + coverImageView.snp.makeConstraints { make in + make.edges.equalTo(UIEdgeInsets(top: 15, left: 8, bottom: 15, right: 8)) + } + + hotLabel.snp.makeConstraints { make in + make.right.equalTo(-10) + make.top.equalTo(18) + } + + hotIconImage.snp.makeConstraints { make in + make.right.equalTo(hotLabel.snp.left).offset(-3) + make.centerY.equalTo(hotLabel) + make.size.equalTo(CGSizeMake(9, 10)) + } + } +} diff --git a/SynthReel/Class/Home/VC/SRHomeViewController.swift b/SynthReel/Class/Home/VC/SRHomeViewController.swift index 7b9c349..a69ec72 100644 --- a/SynthReel/Class/Home/VC/SRHomeViewController.swift +++ b/SynthReel/Class/Home/VC/SRHomeViewController.swift @@ -152,7 +152,7 @@ extension SRHomeViewController { menuContentView.addSubview(menuView) menuContentView.addSubview(moreButton) moreButton.addSubview(moreTitleLabel) - moreButton.addSubview(moreIconImageView) +// moreButton.addSubview(moreIconImageView) menuView.listContainer = pageView.listContainerView @@ -196,10 +196,10 @@ extension SRHomeViewController { make.left.equalToSuperview() } - moreIconImageView.snp.makeConstraints { make in - make.centerY.equalToSuperview() - make.right.equalToSuperview() - } +// moreIconImageView.snp.makeConstraints { make in +// make.centerY.equalToSuperview() +// make.right.equalToSuperview() +// } } } diff --git a/SynthReel/Class/Home/VC/SRTopChartsViewController.swift b/SynthReel/Class/Home/VC/SRTopChartsViewController.swift new file mode 100644 index 0000000..ee4805d --- /dev/null +++ b/SynthReel/Class/Home/VC/SRTopChartsViewController.swift @@ -0,0 +1,102 @@ +// +// SRTopChartsViewController.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRTopChartsViewController: SRViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + sr_setui() + // Do any additional setup after loading the view. + } + + lazy var topImageview = UIImageView.init(image: .topChartsTop) + + var dataArr: [SRShortModel] = [] { + didSet { + self.collectionView.reloadData() + } + } + + lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let itemWidth = floor((UIScreen.width - 30)) + let itemHeight = 98.0 + + let layout = UICollectionViewFlowLayout() + layout.minimumInteritemSpacing = 6 + layout.minimumLineSpacing = 10 + layout.itemSize = .init(width: itemWidth, height: itemHeight) + layout.sectionInset = .init(top: 10, left: 15, bottom: 10, right: 15) + return layout + }() + + lazy var collectionView: SRCollectionView = { + let collectionView = SRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) + collectionView.delegate = self + collectionView.dataSource = self + collectionView.showsVerticalScrollIndicator = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.register(SRTopChartsCell.self, forCellWithReuseIdentifier: "cell") + collectionView.sr_addRefreshFooter { [weak self] in + self?.handleFooterRefresh(nil) + } + return collectionView + }() + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.isNavigationBarHidden = false + navigationController?.sr_setNavigationTitle("Top Charts".localized, for: self) + + } + +} + +extension SRTopChartsViewController { + func sr_setui() { + view.addSubview(topImageview) + topImageview.snp.makeConstraints { make in + make.top.equalTo(UIScreen.safeTop) + make.right.equalToSuperview() + } + + view.addSubview(collectionView) + collectionView.snp.makeConstraints { make in + make.top.equalTo(UIScreen.navBarHeight) + make.left.right.bottom.equalToSuperview() + } + } +} + +//MARK: UICollectionViewDelegate UICollectionViewDataSource +extension SRTopChartsViewController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SRTopChartsCell + cell.model = self.dataArr[indexPath.item] + cell.topLabel.text = String(format: "Top.%ld", indexPath.item + 1) + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.dataArr.count + } + + func scrollViewDidScroll(_ scrollView: UIScrollView) { + self.didScrollCallback?(scrollView) + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let model = dataArr[indexPath.row] + + let vc = SRDetailPlayerViewController() + vc.shortId = model.short_play_id + self.navigationController?.pushViewController(vc, animated: true) + } +} diff --git a/SynthReel/Class/Home/VC/SRViralHitController.swift b/SynthReel/Class/Home/VC/SRViralHitController.swift new file mode 100644 index 0000000..e81a7a9 --- /dev/null +++ b/SynthReel/Class/Home/VC/SRViralHitController.swift @@ -0,0 +1,92 @@ +// +// SRViralHitController.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRViralHitController: SRViewController { + + override func viewDidLoad() { + super.viewDidLoad() + sr_setui() + // Do any additional setup after loading the view. + } + + var dataArr: [SRShortModel] = [] { + didSet { + self.collectionView.reloadData() + } + } + + lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let itemWidth = floor((UIScreen.width - 30 - 12) / 3.0) + let itemHeight = 148.0 / 111 * itemWidth + + let layout = UICollectionViewFlowLayout() + layout.minimumInteritemSpacing = 6 + layout.minimumLineSpacing = 10 + layout.itemSize = .init(width: itemWidth, height: itemHeight) + layout.sectionInset = .init(top: 10, left: 15, bottom: 10, right: 15) + return layout + }() + + lazy var collectionView: SRCollectionView = { + let collectionView = SRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) + collectionView.delegate = self + collectionView.dataSource = self + collectionView.showsVerticalScrollIndicator = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.register(SRViralHitCell.self, forCellWithReuseIdentifier: "cell") + collectionView.sr_addRefreshFooter { [weak self] in + self?.handleFooterRefresh(nil) + } + return collectionView + }() + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.isNavigationBarHidden = false + navigationController?.sr_setNavigationTitle("Viral Hits".localized, for: self) + + } + +} + +extension SRViralHitController { + func sr_setui() { + view.addSubview(collectionView) + collectionView.snp.makeConstraints { make in + make.top.equalTo(UIScreen.navBarHeight) + make.left.right.bottom.equalToSuperview() + } + } +} + +//MARK: UICollectionViewDelegate UICollectionViewDataSource +extension SRViralHitController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SRViralHitCell + cell.model = self.dataArr[indexPath.item] + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.dataArr.count + } + + func scrollViewDidScroll(_ scrollView: UIScrollView) { + self.didScrollCallback?(scrollView) + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let model = dataArr[indexPath.row] + + let vc = SRDetailPlayerViewController() + vc.shortId = model.short_play_id + self.navigationController?.pushViewController(vc, animated: true) + } +} diff --git a/SynthReel/Class/MyShort/V/SRListMenuCell.swift b/SynthReel/Class/MyShort/V/SRListMenuCell.swift index a9ceeb6..6f4692b 100644 --- a/SynthReel/Class/MyShort/V/SRListMenuCell.swift +++ b/SynthReel/Class/MyShort/V/SRListMenuCell.swift @@ -35,12 +35,6 @@ class SRListMenuCell: JXSegmentedTitleCell/*JXSegmentedTitleCell*/ { override func reloadData(itemModel: JXSegmentedBaseItemModel, selectedType: JXSegmentedViewItemSelectedType) { super.reloadData(itemModel: itemModel, selectedType: selectedType) - -// if itemModel.isSelected { -// bgImageView.image = UIImage(named: "FavoritesSeleted") -// } else { -// bgImageView.image = UIImage(named: "Favorites") -// } if itemModel.index == 0 { if itemModel.isSelected { bgImageView.image = UIImage(named: "FavoritesSeleted") diff --git a/SynthReel/Class/User/VC/SRAboutUsController.swift b/SynthReel/Class/User/VC/SRAboutUsController.swift new file mode 100644 index 0000000..4faade7 --- /dev/null +++ b/SynthReel/Class/User/VC/SRAboutUsController.swift @@ -0,0 +1,96 @@ +// +// SRAboutUsController.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRAboutUsController: SRViewController { + + private lazy var dataArr: [SRUserSettingModel] = [ + SRUserSettingModel(type: .visitWebsite, name: "synthreel_visit_website".localized), + ] + + private lazy var tableView: SRTableView = { + let tableView = SRTableView(frame: .zero, style: .plain) + tableView.tableHeaderView = self.headerView + tableView.delegate = self + tableView.dataSource = self + tableView.separatorInset = .init(top: 0, left: 32, bottom: 0, right: 32) + tableView.register(SRAboutCell.self, forCellReuseIdentifier: "cell") + tableView.backgroundColor = .clear + return tableView + }() + + private lazy var headerView: SRAboutHeaderVIew = { + let view = SRAboutHeaderVIew(frame: .init(x: 0, y: 0, width: UIScreen.width, height: 186)) + return view + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.title = "About".localized + + sr_setupLayout() + } + +} + +extension SRAboutUsController { + + private func sr_setupLayout() { + view.addSubview(tableView) + + tableView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview().offset(UIScreen.navBarHeight) + } + } + +} + + +//MARK: UITableViewDelegate UITableViewDataSource +extension SRAboutUsController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return dataArr.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SRAboutCell + cell.item = dataArr[indexPath.row] + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let item = dataArr[indexPath.row] + var urlStr: String? = nil + + switch item.type { + case .privacyPolicy: + urlStr = SRWebBaseURL + "/private" + + case .userAgreement: + urlStr = SRWebBaseURL + "/user_policy" + + case .visitWebsite: + if let url = URL(string: SRWebBaseURL) { + UIApplication.shared.open(url) + } + default: + break + } + +// if let urlStr = urlStr { +// let vc = FABaseWebViewController() +// vc.webUrl = urlStr +// self.navigationController?.pushViewController(vc, animated: true) +// +// } + + } +} diff --git a/SynthReel/Class/User/VC/SRHelpCenterController.swift b/SynthReel/Class/User/VC/SRHelpCenterController.swift new file mode 100644 index 0000000..104f783 --- /dev/null +++ b/SynthReel/Class/User/VC/SRHelpCenterController.swift @@ -0,0 +1,30 @@ +// +// SRHelpCenterController.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRHelpCenterController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/SynthReel/Class/User/VC/SRPrivacyController.swift b/SynthReel/Class/User/VC/SRPrivacyController.swift new file mode 100644 index 0000000..2bf5248 --- /dev/null +++ b/SynthReel/Class/User/VC/SRPrivacyController.swift @@ -0,0 +1,30 @@ +// +// SRPrivacyController.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRPrivacyController: UIViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + + /* + // MARK: - Navigation + + // In a storyboard-based application, you will often want to do a little preparation before navigation + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + // Get the new view controller using segue.destination. + // Pass the selected object to the new view controller. + } + */ + +} diff --git a/SynthReel/Class/User/VC/SRUserViewController.swift b/SynthReel/Class/User/VC/SRUserViewController.swift index b1aab6d..9d4fe2a 100644 --- a/SynthReel/Class/User/VC/SRUserViewController.swift +++ b/SynthReel/Class/User/VC/SRUserViewController.swift @@ -10,11 +10,145 @@ import UIKit class SRUserViewController: SRViewController { + private lazy var dataArr: [SRUserSettingModel] = [] + + lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let layout = UICollectionViewFlowLayout() + return layout + }() + + lazy var collectionView: SRCollectionView = { + let collectionView = SRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) + collectionView.delegate = self + collectionView.dataSource = self + collectionView.showsVerticalScrollIndicator = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.register(SRUserSettingCell.self, forCellWithReuseIdentifier: "cell") + collectionView.register(SRUserTopCell.self, forCellWithReuseIdentifier: "topcell") + collectionView.sr_addRefreshHeader { [weak self] in + Task { + await SRAccountManager.manager.updateUserInfo() + self?.collectionView.reloadData() + } + } + return collectionView + }() + + override func viewDidLoad() { super.viewDidLoad() + set_ui() + setDataArr() // Do any additional setup after loading the view. } - } + +extension SRUserViewController { + func set_ui (){ + view.addSubview(collectionView) + + collectionView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } +} + +//MARK: UICollectionViewDelegate UICollectionViewDataSource +extension SRUserViewController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + + if(indexPath.section == 0){ + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "topcell", for: indexPath) as! SRUserTopCell +// cell.model = self.dataArr[indexPath.row]; + return cell + } + + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! SRUserSettingCell + cell.model = self.dataArr[indexPath.row]; + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + if section == 0 { + return 1 + } + return self.dataArr.count + } + + func numberOfSections(in collectionView: UICollectionView) -> Int { + return 2 + } + + func scrollViewDidScroll(_ scrollView: UIScrollView) { + self.didScrollCallback?(scrollView) + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let model = dataArr[indexPath.row] + + if (model.type == .about){ + + } + switch model.type { + case .about: + let aboutvc = SRAboutUsController (); + self.navigationController?.pushViewController(aboutvc, animated: true) + break + case .privacyPolicy: + if let url = URL(string: SRWebBaseURL + "/private") { + UIApplication.shared.open(url) + } + break + case .userAgreement: + if let url = URL(string: SRWebBaseURL + "/user_policy") { + UIApplication.shared.open(url) + } + break + default: break + } + } + +} + +extension SRUserViewController: UICollectionViewDelegateFlowLayout { + + func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { + if indexPath.section == 0 { return CGSizeMake(UIScreen.width, 278) } + return CGSizeMake(UIScreen.width, 60) + } +} + + +extension SRFavoritesViewController { + + private func requestDataArr(page: Int) async { + + if let dataArr = await SRHomeApi.requestFavoritesData(page: page) { + if page == 1 { + self.dataArr.removeAll() + } + self.dataArr += dataArr + self.page = page + self.collectionView.reloadData() + } + } + +} + +extension SRUserViewController { + + private func setDataArr() { + + let arr = [ +// SRUserSettingModel(type: .feedback, name: "synthreel_feedback".localized, icon: UIImage(named: "icon_feedback")), + SRUserSettingModel(type: .about, name: "synthreel_about_us".localized, icon: UIImage(named: "icon_about")), + SRUserSettingModel(type: .privacyPolicy, name: "synthreel_privacy_policy".localized, icon: UIImage(named: "icon_privacy")), + SRUserSettingModel(type: .userAgreement, name: "synthreel_user_agreement".localized, icon: UIImage(named: "icon_user")), + ] + self.dataArr = arr + self.collectionView.reloadData() + } +} + diff --git a/SynthReel/Class/User/model/SRUserInfoModel.swift b/SynthReel/Class/User/model/SRUserInfoModel.swift new file mode 100644 index 0000000..718c846 --- /dev/null +++ b/SynthReel/Class/User/model/SRUserInfoModel.swift @@ -0,0 +1,13 @@ +// +// SRUserInfoModel.swift +// SynthReel +// +// Created by CSGY on 2025/11/24. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRUserInfoModel: NSObject { + +} diff --git a/SynthReel/Class/User/model/SRUserSettingModel.swift b/SynthReel/Class/User/model/SRUserSettingModel.swift new file mode 100644 index 0000000..b8df5e3 --- /dev/null +++ b/SynthReel/Class/User/model/SRUserSettingModel.swift @@ -0,0 +1,34 @@ +// +// SRUserSettingModel.swift +// SynthReel +// +// Created by CSGY on 2025/11/24. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +struct SRUserSettingModel { + + enum ItemType { + case feedback + case about +// case setting + case privacyPolicy + case userAgreement + case visitWebsite +// ///消费记录 +// case consumptionRecords +// ///购买记录 +// case purchaseRecords +// ///金币奖励 +// case rewardCoins +// case deleteAccount +// case language + } + + + var type: ItemType? + var name: String? + var icon: UIImage? +} diff --git a/SynthReel/Class/User/view/SRAboutCell.swift b/SynthReel/Class/User/view/SRAboutCell.swift new file mode 100644 index 0000000..379bb18 --- /dev/null +++ b/SynthReel/Class/User/view/SRAboutCell.swift @@ -0,0 +1,47 @@ +// +// SRAboutCell.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRAboutCell: SRTableViewCell { + + var item : SRUserSettingModel? { + didSet { + titleLabe.text = item?.name + } + } + + lazy var titleLabe : UILabel = { + let label = UILabel () + label.textColor = UIColor.white + label.font = .font(ofSize: 18, weight: .regular) + return label + }() + + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + contentView.addSubview(titleLabe) + + titleLabe.snp.makeConstraints { make in + make.left.equalTo(15) + make.centerY.equalToSuperview() + } + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/SynthReel/Class/User/view/SRAboutHeaderVIew.swift b/SynthReel/Class/User/view/SRAboutHeaderVIew.swift new file mode 100644 index 0000000..e2c439b --- /dev/null +++ b/SynthReel/Class/User/view/SRAboutHeaderVIew.swift @@ -0,0 +1,68 @@ +// +// SRAboutHeaderVIew.swift +// SynthReel +// +// Created by CSGY on 2025/11/25. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRAboutHeaderVIew: UIView { + private lazy var appLogoView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "logo")) + imageView.layer.cornerRadius = 8 + imageView.layer.masksToBounds = true + return imageView + }() + + private lazy var nameLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 18, weight: .bold) + label.textColor = .white + label.text = kSRAPPName + return label + }() + + private lazy var versionLabel: UILabel = { + let label = UILabel() + label.font = .font(ofSize: 12, weight: .regular) + label.textColor = .white + label.text = "Version \(kSRAPPVersion)" + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + fa_setupLayout() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension SRAboutHeaderVIew { + private func fa_setupLayout() { + addSubview(appLogoView) + addSubview(nameLabel) + addSubview(versionLabel) + + appLogoView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalToSuperview().offset(30) + make.width.height.equalTo(84) + } + + nameLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(appLogoView.snp.bottom).offset(13) + } + + versionLabel.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.top.equalTo(nameLabel.snp.bottom).offset(6) + } + } +} diff --git a/SynthReel/Class/User/view/SRUserSettingCell.swift b/SynthReel/Class/User/view/SRUserSettingCell.swift new file mode 100644 index 0000000..cb8172f --- /dev/null +++ b/SynthReel/Class/User/view/SRUserSettingCell.swift @@ -0,0 +1,66 @@ +// +// SRUserSettingCell.swift +// SynthReel +// +// Created by CSGY on 2025/11/24. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRUserSettingCell: UICollectionViewCell { + + var model : SRUserSettingModel? { + didSet { + titleLabel.text = model?.name + iconImage.image = model?.icon + } + } + + lazy var iconImage = UIImageView() + + lazy var arrayImage = UIImageView.init(image: UIImage(named: "arrow_right_icon_01")) + + lazy var titleLabel : UILabel = { + let label = UILabel() + label.textColor = UIColor.B_5_DAE_6 + label.font = .font(ofSize: 14, weight: .regular) + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + sr_setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension SRUserSettingCell { + func sr_setupUI() { + contentView.addSubview(iconImage) + contentView.addSubview(titleLabel) + contentView.addSubview(arrayImage) + + iconImage.snp.makeConstraints { make in + make.left.equalTo(10) + make.centerY.equalToSuperview() + make.size.equalTo(CGSizeMake(20, 20)) + } + + titleLabel.snp.makeConstraints { make in + make.left.equalTo(iconImage.snp_rightMargin).offset(10) + make.centerY.equalToSuperview() + } + + arrayImage.snp.makeConstraints { make in + make.right.equalTo(-10) + make.centerY.equalToSuperview() + make.size.equalTo(CGSizeMake(14, 14)) + } + + } +} diff --git a/SynthReel/Class/User/view/SRUserTopCell.swift b/SynthReel/Class/User/view/SRUserTopCell.swift new file mode 100644 index 0000000..c5b595c --- /dev/null +++ b/SynthReel/Class/User/view/SRUserTopCell.swift @@ -0,0 +1,100 @@ +// +// SRUserTopCell.swift +// SynthReel +// +// Created by CSGY on 2025/11/24. +// Copyright © 2025 SR. All rights reserved. +// + +import UIKit + +class SRUserTopCell: UICollectionViewCell { + + lazy var topImageView : UIImageView = { + let image = UIImageView(image: .顶部bg) + image.contentMode = .scaleToFill + return image + }() + + lazy var titleLabel : UILabel = { + let label = UILabel() + label.text = "Visitor" + label.textColor = UIColor._51_D_4_FF + label.font = .font(ofSize: 18, weight: .regular) + label.backgroundColor = UIColor.init(patternImage: .userNameBg) + label.textAlignment = .center + return label + }() + + lazy var userId : UILabel = { + let label = UILabel() + label.textColor = UIColor.AAEAFF_0_5 + label.font = .font(ofSize: 13, weight: .regular) + label.text = SRAccountManager.manager.userInfo?.customer_id + return label + }() + + lazy var iconImageView: SRImageView = { + let imageView = SRImageView() + imageView.isUserInteractionEnabled = true + imageView.image = .logo + return imageView + }() + + lazy var iconBgImageView = UIImageView(image: UIImage(named: "头像框")) + + override init(frame: CGRect) { + super.init(frame: frame) + + sr_setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func layoutSubviews() { + super.layoutSubviews() + DispatchQueue.main.async { + self.iconImageView.applyHexagonMask(cornerRadius: 2, rotationAngle: .pi / 6) + } + } +} + + + +extension SRUserTopCell { + func sr_setupUI (){ + contentView.addSubview(topImageView) + contentView.addSubview(iconBgImageView) + iconBgImageView.addSubview(iconImageView) + contentView.addSubview(titleLabel) + contentView.addSubview(userId) + + topImageView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + iconBgImageView.snp.makeConstraints { make in + make.top.equalTo(UIScreen.safeTop + 12); + make.centerX.equalToSuperview() + make.size.equalTo(CGSizeMake(86 , 96)) + } + + iconImageView.snp.makeConstraints { make in + make.edges.equalTo(UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)) + } + + titleLabel.snp.makeConstraints { make in + make.top.equalTo(204); + make.centerX.equalToSuperview() + make.size.equalTo(CGSizeMake(136, 26)) + } + + userId.snp.makeConstraints { make in + make.top.equalTo(titleLabel.snp_bottomMargin).offset(7) + make.centerX.equalToSuperview() + make.height.equalTo(26) + } + } +} diff --git a/SynthReel/Delegate/SceneDelegate.swift b/SynthReel/Delegate/SceneDelegate.swift index e40e33e..eda41b8 100644 --- a/SynthReel/Delegate/SceneDelegate.swift +++ b/SynthReel/Delegate/SceneDelegate.swift @@ -21,7 +21,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { window?.rootViewController = SRTabBarController() window?.makeKeyAndVisible() - + UINavigationBar.uv_applyGlobalAppearance() + NotificationCenter.default.addObserver(self, selector: #selector(abcd), name: NSNotification.Name(rawValue: "abcd"), object: nil) diff --git a/SynthReel/Source/Assets.xcassets/Color/#AAEAFF_0_5.colorset/Contents.json b/SynthReel/Source/Assets.xcassets/Color/#AAEAFF_0_5.colorset/Contents.json new file mode 100644 index 0000000..c94fa7f --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/Color/#AAEAFF_0_5.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "0.600", + "blue" : "0xFF", + "green" : "0xEA", + "red" : "0xAA" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/Color/#B5DAE6.colorset/Contents.json b/SynthReel/Source/Assets.xcassets/Color/#B5DAE6.colorset/Contents.json new file mode 100644 index 0000000..b0e4472 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/Color/#B5DAE6.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xE6", + "green" : "0xDA", + "red" : "0xB5" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/Color/#C4C4C4.colorset/Contents.json b/SynthReel/Source/Assets.xcassets/Color/#C4C4C4.colorset/Contents.json index 22c4bb0..a85aba1 100644 --- a/SynthReel/Source/Assets.xcassets/Color/#C4C4C4.colorset/Contents.json +++ b/SynthReel/Source/Assets.xcassets/Color/#C4C4C4.colorset/Contents.json @@ -5,27 +5,9 @@ "color-space" : "srgb", "components" : { "alpha" : "1.000", - "blue" : "1.000", - "green" : "1.000", - "red" : "1.000" - } - }, - "idiom" : "universal" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "color" : { - "color-space" : "srgb", - "components" : { - "alpha" : "1.000", - "blue" : "1.000", - "green" : "1.000", - "red" : "1.000" + "blue" : "0xC4", + "green" : "0xC4", + "red" : "0xC4" } }, "idiom" : "universal" diff --git a/SynthReel/Source/Assets.xcassets/Color/#FFE4B4.colorset/Contents.json b/SynthReel/Source/Assets.xcassets/Color/#FFE4B4.colorset/Contents.json new file mode 100644 index 0000000..a5fa2e3 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/Color/#FFE4B4.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xB4", + "green" : "0xE4", + "red" : "0xFF" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/Image/logo.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/Image/logo.imageset/Contents.json new file mode 100644 index 0000000..71810bb --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/Image/logo.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "logo@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "logo@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/Image/logo.imageset/logo@2x.png b/SynthReel/Source/Assets.xcassets/Image/logo.imageset/logo@2x.png new file mode 100644 index 0000000..659b98e Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/Image/logo.imageset/logo@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/Image/logo.imageset/logo@3x.png b/SynthReel/Source/Assets.xcassets/Image/logo.imageset/logo@3x.png new file mode 100644 index 0000000..6eddf5d Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/Image/logo.imageset/logo@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/Contents.json new file mode 100644 index 0000000..337a5b3 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "topChartsTop@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "topChartsTop@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/topChartsTop@2x.png b/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/topChartsTop@2x.png new file mode 100644 index 0000000..3bd5de3 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/topChartsTop@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/topChartsTop@3x.png b/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/topChartsTop@3x.png new file mode 100644 index 0000000..fb2cf0e Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/Image/topChartsTop.imageset/topChartsTop@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/Contents.json new file mode 100644 index 0000000..f47bd8c --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "userNameBg@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "userNameBg@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/userNameBg@2x.png b/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/userNameBg@2x.png new file mode 100644 index 0000000..5be5091 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/userNameBg@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/userNameBg@3x.png b/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/userNameBg@3x.png new file mode 100644 index 0000000..1a37e5a Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/Image/userNameBg.imageset/userNameBg@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/Contents.json new file mode 100644 index 0000000..3b0d3e5 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "fire@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "fire@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/fire@2x.png b/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/fire@2x.png new file mode 100644 index 0000000..90d66d6 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/fire@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/fire@3x.png b/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/fire@3x.png new file mode 100644 index 0000000..91f00cd Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/fire.imageset/fire@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/Contents.json new file mode 100644 index 0000000..b131e99 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "icon_about@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "icon_about@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/icon_about@2x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/icon_about@2x.png new file mode 100644 index 0000000..4ae86f5 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/icon_about@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/icon_about@3x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/icon_about@3x.png new file mode 100644 index 0000000..5196b18 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_about.imageset/icon_about@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/Contents.json new file mode 100644 index 0000000..bdd80ac --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "icon_feedback@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "icon_feedback@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/icon_feedback@2x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/icon_feedback@2x.png new file mode 100644 index 0000000..11c5e23 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/icon_feedback@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/icon_feedback@3x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/icon_feedback@3x.png new file mode 100644 index 0000000..8c2a049 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_feedback.imageset/icon_feedback@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/Contents.json new file mode 100644 index 0000000..2926308 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "icon_privacy@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "icon_privacy@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/icon_privacy@2x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/icon_privacy@2x.png new file mode 100644 index 0000000..0123118 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/icon_privacy@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/icon_privacy@3x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/icon_privacy@3x.png new file mode 100644 index 0000000..f3b6035 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_privacy.imageset/icon_privacy@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/Contents.json new file mode 100644 index 0000000..482e766 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "icon_user@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "icon_user@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/icon_user@2x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/icon_user@2x.png new file mode 100644 index 0000000..8a87fd3 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/icon_user@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/icon_user@3x.png b/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/icon_user@3x.png new file mode 100644 index 0000000..a810d0a Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/icon_user.imageset/icon_user@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/Contents.json new file mode 100644 index 0000000..88ac3bd --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "rankLeftIcon@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "rankLeftIcon@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/rankLeftIcon@2x.png b/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/rankLeftIcon@2x.png new file mode 100644 index 0000000..d0886d8 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/rankLeftIcon@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/rankLeftIcon@3x.png b/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/rankLeftIcon@3x.png new file mode 100644 index 0000000..8c5ae0a Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/rankLeftIcon.imageset/rankLeftIcon@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/Contents.json new file mode 100644 index 0000000..d3c99db --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "rankRightIcon@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "rankRightIcon@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/rankRightIcon@2x.png b/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/rankRightIcon@2x.png new file mode 100644 index 0000000..fb319fb Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/rankRightIcon@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/rankRightIcon@3x.png b/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/rankRightIcon@3x.png new file mode 100644 index 0000000..d70f88b Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/rankRightIcon.imageset/rankRightIcon@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/Contents.json new file mode 100644 index 0000000..577e1f6 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "topChartBg@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "topChartBg@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/topChartBg@2x.png b/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/topChartBg@2x.png new file mode 100644 index 0000000..17ff928 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/topChartBg@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/topChartBg@3x.png b/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/topChartBg@3x.png new file mode 100644 index 0000000..81bca8a Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/topChartBg.imageset/topChartBg@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/Contents.json new file mode 100644 index 0000000..1176a41 --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/头像框.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/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/头像框@2x.png b/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/头像框@2x.png new file mode 100644 index 0000000..a41934c Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/头像框@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/头像框@3x.png b/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/头像框@3x.png new file mode 100644 index 0000000..642e3d5 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/头像框.imageset/头像框@3x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/Contents.json b/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/Contents.json new file mode 100644 index 0000000..b3858aa --- /dev/null +++ b/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "顶部bg@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "顶部bg@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/顶部bg@2x.png b/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/顶部bg@2x.png new file mode 100644 index 0000000..8d82e07 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/顶部bg@2x.png differ diff --git a/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/顶部bg@3x.png b/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/顶部bg@3x.png new file mode 100644 index 0000000..18b9cb9 Binary files /dev/null and b/SynthReel/Source/Assets.xcassets/myShort/顶部bg.imageset/顶部bg@3x.png differ diff --git a/SynthReel/Source/en.lproj/Localizable.strings b/SynthReel/Source/en.lproj/Localizable.strings index d8cfd06..9dd5fab 100644 --- a/SynthReel/Source/en.lproj/Localizable.strings +++ b/SynthReel/Source/en.lproj/Localizable.strings @@ -23,3 +23,10 @@ "Select Episode" = "Select Episode"; "all_episodes_text" = "(All ## episodes)"; "recommend_ep_text" = "Watch the complete series"; +"synthreel_feedback" = "Help Center"; +"synthreel_about_us" = "About Us"; +"synthreel_privacy_policy" = "Privacy Policy"; +"synthreel_user_agreement" = "User Agreement"; +"synthreel_visit_website" = "visit website"; +"Viral Hits" = "Viral Hits"; +