vip页面开发

This commit is contained in:
zjx 2025-05-29 16:23:33 +08:00
parent 7b0d677a42
commit 83d41497ec
61 changed files with 1274 additions and 31 deletions

View File

@ -151,7 +151,16 @@
BFF5AFA82DE704DC0044227A /* VPMeCoinCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */; };
BFF5AFAA2DE7070A0044227A /* VPMeCoinItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA92DE7070A0044227A /* VPMeCoinItemView.swift */; };
BFF5AFAC2DE70CE20044227A /* VPMeToolCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFAB2DE70CE20044227A /* VPMeToolCell.swift */; };
BFF5AFAE2DE717BB0044227A /* VPVipViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFAD2DE717BB0044227A /* VPVipViewController.swift */; };
BFF5AFAE2DE717BB0044227A /* VPVipPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFAD2DE717BB0044227A /* VPVipPageViewController.swift */; };
BFF5AFB02DE7F9A80044227A /* VPVipViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFAF2DE7F9A80044227A /* VPVipViewController.swift */; };
BFF5AFB22DE7FC130044227A /* CGMutablePath+VPAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFB12DE7FC0A0044227A /* CGMutablePath+VPAdd.swift */; };
BFF5AFB42DE7FF4E0044227A /* VPCoinsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFB32DE7FF4E0044227A /* VPCoinsViewController.swift */; };
BFF5AFB62DE803A30044227A /* VPVipPrivilegeItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFB52DE803A30044227A /* VPVipPrivilegeItemView.swift */; };
BFF5AFB82DE832580044227A /* VPVipBuyCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFB72DE832580044227A /* VPVipBuyCell.swift */; };
BFF5AFBA2DE837310044227A /* VPWalletAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFB92DE8372A0044227A /* VPWalletAPI.swift */; };
BFF5AFC02DE837D60044227A /* VPPayTemplateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFBF2DE837D60044227A /* VPPayTemplateModel.swift */; };
BFF5AFC22DE837FC0044227A /* VPPayTemplateItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFC12DE837FC0044227A /* VPPayTemplateItem.swift */; };
BFF5AFC42DE84F9C0044227A /* Aa厚底黑.ttf in Resources */ = {isa = PBXBuildFile; fileRef = BFF5AFC32DE84F9C0044227A /* Aa厚底黑.ttf */; };
F939C04AD4003BA127F15C28 /* Pods_Veloria.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F57E87E765BF8D72A43DCA /* Pods_Veloria.framework */; };
/* End PBXBuildFile section */
@ -309,7 +318,16 @@
BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeCoinCell.swift; sourceTree = "<group>"; };
BFF5AFA92DE7070A0044227A /* VPMeCoinItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeCoinItemView.swift; sourceTree = "<group>"; };
BFF5AFAB2DE70CE20044227A /* VPMeToolCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeToolCell.swift; sourceTree = "<group>"; };
BFF5AFAD2DE717BB0044227A /* VPVipViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipViewController.swift; sourceTree = "<group>"; };
BFF5AFAD2DE717BB0044227A /* VPVipPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipPageViewController.swift; sourceTree = "<group>"; };
BFF5AFAF2DE7F9A80044227A /* VPVipViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipViewController.swift; sourceTree = "<group>"; };
BFF5AFB12DE7FC0A0044227A /* CGMutablePath+VPAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CGMutablePath+VPAdd.swift"; sourceTree = "<group>"; };
BFF5AFB32DE7FF4E0044227A /* VPCoinsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPCoinsViewController.swift; sourceTree = "<group>"; };
BFF5AFB52DE803A30044227A /* VPVipPrivilegeItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipPrivilegeItemView.swift; sourceTree = "<group>"; };
BFF5AFB72DE832580044227A /* VPVipBuyCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipBuyCell.swift; sourceTree = "<group>"; };
BFF5AFB92DE8372A0044227A /* VPWalletAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPWalletAPI.swift; sourceTree = "<group>"; };
BFF5AFBF2DE837D60044227A /* VPPayTemplateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPayTemplateModel.swift; sourceTree = "<group>"; };
BFF5AFC12DE837FC0044227A /* VPPayTemplateItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPayTemplateItem.swift; sourceTree = "<group>"; };
BFF5AFC32DE84F9C0044227A /* Aa厚底黑.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Aa厚底黑.ttf"; sourceTree = "<group>"; };
E0BDA3570E00C90877E45AA0 /* Pods-VideoPlayer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VideoPlayer.debug.xcconfig"; path = "Target Support Files/Pods-VideoPlayer/Pods-VideoPlayer.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
@ -397,6 +415,7 @@
1B056E362DDAC1E8007EE38D /* Class */ = {
isa = PBXGroup;
children = (
BFF5AFBB2DE837710044227A /* Wallet */,
BF0FA7A62DE4437F00C9E5F2 /* Me */,
BF0FA7952DE1948A00C9E5F2 /* MyList */,
1B056E522DDACBF4007EE38D /* Home */,
@ -489,6 +508,7 @@
1B056E422DDAC32C007EE38D /* Extension */ = {
isa = PBXGroup;
children = (
BFF5AFB12DE7FC0A0044227A /* CGMutablePath+VPAdd.swift */,
BF5E75B22DE465EA00DE9DFE /* Dictionary+SPAdd.swift */,
BF0FA7BD2DE4591B00C9E5F2 /* UserDefaults+VPAdd.swift */,
BF0FA7B92DE451B000C9E5F2 /* UINavigationBar+VPAdd.swift */,
@ -621,6 +641,7 @@
BF0FA6F72DDC64CF00C9E5F2 /* API */ = {
isa = PBXGroup;
children = (
BFF5AFB92DE8372A0044227A /* VPWalletAPI.swift */,
BF0FA6F82DDC64E700C9E5F2 /* VPHomeAPI.swift */,
BF0FA73C2DDED2D000C9E5F2 /* VPVideoAPI.swift */,
BF0FA7C22DE45DE300C9E5F2 /* VPUserAPI.swift */,
@ -715,6 +736,7 @@
BF0FA7352DDECC4600C9E5F2 /* Font */ = {
isa = PBXGroup;
children = (
BFF5AFC32DE84F9C0044227A /* Aa厚底黑.ttf */,
BF0FA7362DDECC5400C9E5F2 /* PlayfairDisplay-VariableFont_wght.ttf */,
);
path = Font;
@ -848,7 +870,6 @@
BF0FA7AE2DE443E000C9E5F2 /* VPMeViewController.swift */,
BF5E75AE2DE4632200DE9DFE /* VPAboutUsViewController.swift */,
BF5E75B02DE4656600DE9DFE /* VPCampaignWebViewController.swift */,
BFF5AFAD2DE717BB0044227A /* VPVipViewController.swift */,
);
path = Controller;
sourceTree = "<group>";
@ -926,6 +947,44 @@
path = MarqueeView;
sourceTree = "<group>";
};
BFF5AFBB2DE837710044227A /* Wallet */ = {
isa = PBXGroup;
children = (
BFF5AFBC2DE837790044227A /* Controller */,
BFF5AFBD2DE837900044227A /* View */,
BFF5AFBE2DE837AD0044227A /* Model */,
);
path = Wallet;
sourceTree = "<group>";
};
BFF5AFBC2DE837790044227A /* Controller */ = {
isa = PBXGroup;
children = (
BFF5AFAD2DE717BB0044227A /* VPVipPageViewController.swift */,
BFF5AFAF2DE7F9A80044227A /* VPVipViewController.swift */,
BFF5AFB32DE7FF4E0044227A /* VPCoinsViewController.swift */,
);
path = Controller;
sourceTree = "<group>";
};
BFF5AFBD2DE837900044227A /* View */ = {
isa = PBXGroup;
children = (
BFF5AFB52DE803A30044227A /* VPVipPrivilegeItemView.swift */,
BFF5AFB72DE832580044227A /* VPVipBuyCell.swift */,
);
path = View;
sourceTree = "<group>";
};
BFF5AFBE2DE837AD0044227A /* Model */ = {
isa = PBXGroup;
children = (
BFF5AFBF2DE837D60044227A /* VPPayTemplateModel.swift */,
BFF5AFC12DE837FC0044227A /* VPPayTemplateItem.swift */,
);
path = Model;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -992,6 +1051,7 @@
1B056E2E2DDAC0FD007EE38D /* Assets.xcassets in Resources */,
1B056E642DDAD035007EE38D /* Localizable.strings in Resources */,
BF0FA7372DDECC5400C9E5F2 /* PlayfairDisplay-VariableFont_wght.ttf in Resources */,
BFF5AFC42DE84F9C0044227A /* Aa厚底黑.ttf in Resources */,
1B056E302DDAC0FD007EE38D /* LaunchScreen.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -1097,6 +1157,7 @@
BF0FA7B12DE447EB00C9E5F2 /* VPMeItem.swift in Sources */,
1B056E2C2DDAC0FD007EE38D /* SceneDelegate.swift in Sources */,
BFF5AFA42DE6F15E0044227A /* VPMeVipCell.swift in Sources */,
BFF5AFB02DE7F9A80044227A /* VPVipViewController.swift in Sources */,
BF0FA75D2DDF208400C9E5F2 /* VPExplorePlayerControlView.swift in Sources */,
BF5E75CB2DE5692D00DE9DFE /* UINavigationController+JXTransition.swift in Sources */,
BF5E75CC2DE5692D00DE9DFE /* JXTransitionDefine.swift in Sources */,
@ -1112,12 +1173,14 @@
BFF5AFAA2DE7070A0044227A /* VPMeCoinItemView.swift in Sources */,
BF0FA7692DE0502900C9E5F2 /* VPEpisodeCell.swift in Sources */,
BF5E75BE2DE54B2800DE9DFE /* VPAboutUsHeaderView.swift in Sources */,
BFF5AFB22DE7FC130044227A /* CGMutablePath+VPAdd.swift in Sources */,
BF0FA73D2DDED2D000C9E5F2 /* VPVideoAPI.swift in Sources */,
BF0FA6EE2DDC5F8700C9E5F2 /* JXUUID.m in Sources */,
BF5E75B12DE4656600DE9DFE /* VPCampaignWebViewController.swift in Sources */,
BF5E75BC2DE546AD00DE9DFE /* VPAboutUsCell.swift in Sources */,
BF0FA7BA2DE451B900C9E5F2 /* UINavigationBar+VPAdd.swift in Sources */,
BF0FA77D2DE078D400C9E5F2 /* VPSearchRecommendedView.swift in Sources */,
BFF5AFBA2DE837310044227A /* VPWalletAPI.swift in Sources */,
BF0FA7812DE150F700C9E5F2 /* VPSearchRecommendedContentView.swift in Sources */,
BF0FA7872DE1601200C9E5F2 /* VPTextField.swift in Sources */,
BF0FA7052DDC67AC00C9E5F2 /* VPHomeViewModel.swift in Sources */,
@ -1126,6 +1189,7 @@
BF0FA7732DE0671200C9E5F2 /* VPRateSelectedCell.swift in Sources */,
1B056E4D2DDAC7C1007EE38D /* VPTabBarController.swift in Sources */,
BF5E75C02DE5566200DE9DFE /* VPHomePageControlView.swift in Sources */,
BFF5AFC22DE837FC0044227A /* VPPayTemplateItem.swift in Sources */,
BF0FA6DA2DDC5CB600C9E5F2 /* VPLoginManager.swift in Sources */,
BF0FA74A2DDF04E200C9E5F2 /* VPPlayerProtocol.swift in Sources */,
BF0FA72C2DDD7B7300C9E5F2 /* VPHomeRankingContentCell.swift in Sources */,
@ -1141,7 +1205,7 @@
BF0FA7992DE1951A00C9E5F2 /* VPMyListViewController.swift in Sources */,
BF0FA7452DDF027900C9E5F2 /* VPPlayer.swift in Sources */,
BFF5AFA82DE704DC0044227A /* VPMeCoinCell.swift in Sources */,
BFF5AFAE2DE717BB0044227A /* VPVipViewController.swift in Sources */,
BFF5AFAE2DE717BB0044227A /* VPVipPageViewController.swift in Sources */,
BF0FA70E2DDC6ACC00C9E5F2 /* VPHomeItemContentCell.swift in Sources */,
BF0FA6D72DDC5BE100C9E5F2 /* VPURLPath.swift in Sources */,
1B056E5B2DDACD80007EE38D /* UIColor+VPAdd.swift in Sources */,
@ -1158,6 +1222,8 @@
BF0FA7BE2DE4592A00C9E5F2 /* UserDefaults+VPAdd.swift in Sources */,
BF0FA76F2DE062A700C9E5F2 /* VPRateSelectedView.swift in Sources */,
BF0FA7772DE0735800C9E5F2 /* VPSearchInputView.swift in Sources */,
BFF5AFB62DE803A30044227A /* VPVipPrivilegeItemView.swift in Sources */,
BFF5AFB82DE832580044227A /* VPVipBuyCell.swift in Sources */,
BF0FA7892DE161F200C9E5F2 /* VPSearchResultView.swift in Sources */,
1B056E792DDB365A007EE38D /* VPTabBarItemSelectedView.swift in Sources */,
1B056E722DDB022F007EE38D /* VPTabBarItem.swift in Sources */,
@ -1178,7 +1244,9 @@
BF0FA6D52DDC5B5D00C9E5F2 /* VPApi.swift in Sources */,
BF0FA7C12DE45D5D00C9E5F2 /* VPUserInfo.swift in Sources */,
BF0FA7392DDECF8900C9E5F2 /* VPHomeListViewController.swift in Sources */,
BFF5AFB42DE7FF4E0044227A /* VPCoinsViewController.swift in Sources */,
BF0FA6F62DDC616300C9E5F2 /* VPToast.swift in Sources */,
BFF5AFC02DE837D60044227A /* VPPayTemplateModel.swift in Sources */,
BF0FA7B62DE44E8000C9E5F2 /* VPWebView.swift in Sources */,
1B056E492DDAC3DF007EE38D /* VPAppTool.swift in Sources */,
BF0FA74E2DDF067E00C9E5F2 /* VPVideoPlayViewModel.swift in Sources */,

View File

@ -0,0 +1,65 @@
//
// CGMutablePath+VPAdd.swift
// Veloria
//
// Created by on 2025/5/29.
//
/** */
struct VPCirculars {
var topLeft:CGFloat = 0
var topRight:CGFloat = 0
var bottomLeft:CGFloat = 0
var bottomRight:CGFloat = 0
public static let zero = VPCirculars(topLeft: 0, topRight: 0, bottomLeft: 0, bottomRight: 0)
public init(topLeft: CGFloat, topRight:CGFloat, bottomLeft:CGFloat, bottomRight:CGFloat) {
self.topLeft = topLeft
self.topRight = topRight
self.bottomLeft = bottomLeft
self.bottomRight = bottomRight
}
static func ==(v1:VPCirculars, v2:VPCirculars) -> Bool {
return v1.bottomLeft == v2.bottomLeft
&& v1.bottomRight == v2.bottomRight
&& v1.topLeft == v2.topLeft
&& v1.topRight == v2.topRight
}
static func !=(v1:VPCirculars, v2:VPCirculars) -> Bool {
return !(v1 == v2)
}
}
extension CGMutablePath {
func addRadiusRectangle(_ circulars: VPCirculars, rect: CGRect) {
let minX = rect.minX
let minY = rect.minY
let maxX = rect.maxX
let maxY = rect.maxY
//
let topLeftCenterX = minX + circulars.topLeft
let topLeftCenterY = minY + circulars.topLeft
let topRightCenterX = maxX - circulars.topRight
let topRightCenterY = minY + circulars.topRight
let bottomLeftCenterX = minX + circulars.bottomLeft
let bottomLeftCenterY = maxY - circulars.bottomLeft
let bottomRightCenterX = maxX - circulars.bottomRight
let bottomRightCenterY = maxY - circulars.bottomRight
//
addArc(center: CGPoint(x: topLeftCenterX, y: topLeftCenterY), radius: circulars.topLeft, startAngle: CGFloat.pi, endAngle: CGFloat.pi * 3 / 2, clockwise: false)
//
addArc(center: CGPoint(x: topRightCenterX, y: topRightCenterY), radius: circulars.topRight, startAngle: CGFloat.pi * 3 / 2, endAngle: 0, clockwise: false)
//
addArc(center: CGPoint(x: bottomRightCenterX, y: bottomRightCenterY), radius: circulars.bottomRight, startAngle: 0, endAngle: CGFloat.pi / 2, clockwise: false)
//
addArc(center: CGPoint(x: bottomLeftCenterX, y: bottomLeftCenterY), radius: circulars.bottomLeft, startAngle: CGFloat.pi / 2, endAngle: CGFloat.pi, clockwise: false)
closeSubpath();
}
}

View File

@ -117,4 +117,48 @@ extension UIColor {
static func colorD3D3D3(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xD3D3D3, alpha: alpha)
}
static func colorBFBFBF(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xBFBFBF, alpha: alpha)
}
static func color033329(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x033329, alpha: alpha)
}
static func color045241(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x045241, alpha: alpha)
}
static func color64A3A7(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x64A3A7, alpha: alpha)
}
static func color416767(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x416767, alpha: alpha)
}
static func color9C7565(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x9C7565, alpha: alpha)
}
static func color573D31(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x573D31, alpha: alpha)
}
static func color647DA7(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x647DA7, alpha: alpha)
}
static func color414867(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x414867, alpha: alpha)
}
static func color9C6586(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x9C6586, alpha: alpha)
}
static func color57314F(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x57314F, alpha: alpha)
}
}

View File

@ -35,4 +35,8 @@ extension UIFont {
static func numberFont(ofSize: CGFloat) -> UIFont {
return UIFont(name: "Playfair Display", size: ofSize) ?? fontMedium(ofSize: ofSize)
}
static func fontAaHouDiHei(ofSize: CGFloat) -> UIFont {
return UIFont(name: "AaHouDiHei", size: ofSize) ?? fontMedium(ofSize: ofSize)
}
}

View File

@ -25,6 +25,8 @@ extension UIView {
@objc func vp_layoutSubviews() {
vp_layoutSubviews()
_updateRadius()
if let effectView = effectView, effectView.frame != self.bounds {
effectView.frame = self.bounds
}
@ -37,6 +39,39 @@ extension UIView {
}
}
//MARK: -------------- --------------
extension UIView {
private var circulars: VPCirculars? {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.vp_circulars) as? VPCirculars
}
set {
objc_setAssociatedObject(self, &AssociatedKeys.vp_circulars, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
func addRadius(topLeft: CGFloat, topRight: CGFloat, bottomLeft: CGFloat, bottomRight: CGFloat) {
//
self.circulars = VPCirculars(topLeft: topLeft, topRight: topRight, bottomLeft: bottomLeft, bottomRight: bottomRight)
_updateRadius()
}
private func _updateRadius() {
guard let circulars = self.circulars else { return }
let rect = self.bounds
let path = CGMutablePath()
path.addRadiusRectangle(circulars, rect: rect)
let maskLayer = CAShapeLayer()
maskLayer.frame = self.bounds
maskLayer.path = path
self.layer.mask = maskLayer
}
}
//MARK: -------------- --------------
extension UIView {

View File

@ -0,0 +1,26 @@
//
// VPWalletAPI.swift
// Veloria
//
// Created by on 2025/5/29.
//
import SmartCodable
class VPWalletAPI {
enum BuyType: String, SmartCaseDefaultable {
case coins = "coins"
case subVip = "sub_vip"
}
///
static func requestPayTemplate(completer: ((_ model: VPPayTemplateModel?) -> Void)?) {
var param = VPNetworkParameters(path: "/paySettingsV3")
param.method = .get
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPPayTemplateModel>) in
completer?(response.data)
}
}
}

View File

@ -24,6 +24,8 @@ class VPGradientLabel: UILabel {
override init(frame: CGRect) {
super.init(frame: frame)
self.textColor = .clear
layer.addSublayer(gradientLayer)
}
@ -36,10 +38,12 @@ class VPGradientLabel: UILabel {
super.layoutSubviews()
gradientLayer.frame = bounds
let string = NSMutableAttributedString(attributedString: attributedText ?? NSAttributedString(string: text ?? ""))
string.color = .colorFFFFFF()
//
let textLayer = CATextLayer()
textLayer.string = attributedText ?? NSAttributedString(string: text ?? "")
textLayer.string = string
textLayer.frame = bounds
textLayer.alignmentMode = .center
textLayer.contentsScale = UIScreen.main.scale

View File

@ -1,25 +0,0 @@
//
// VPVipViewController.swift
// Veloria
//
// Created by on 2025/5/28.
//
import UIKit
class VPVipViewController: VPViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
setNavigationNormalStyle()
}
}

View File

@ -92,7 +92,7 @@ class VPMeVipCell: VPTableViewCell {
}
@objc private func handleBgView() {
let vc = VPVipViewController()
let vc = VPVipPageViewController()
self.viewController?.navigationController?.pushViewController(vc, animated: true)
}

View File

@ -0,0 +1,37 @@
//
// VPCoinsViewController.swift
// Veloria
//
// Created by on 2025/5/29.
//
import UIKit
class VPCoinsViewController: VPViewController {
var dataArr: [VPPayTemplateItem] = [] {
didSet {
// self.collectionView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.bgImageView.isHidden = true
self.view.backgroundColor = .clear
}
/*
// 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.
}
*/
}

View File

@ -0,0 +1,168 @@
//
// VPVipPageViewController.swift
// Veloria
//
// Created by on 2025/5/28.
//
import UIKit
class VPVipPageViewController: VPViewController {
private lazy var topImageSize = topImageView.image?.size ?? .zero
private lazy var topImageHeight = floor(topImageSize.height / topImageSize.width * UIScreen.width)
private lazy var vipVC = VPVipViewController()
private lazy var coinsVC = VPCoinsViewController()
private lazy var viewControllers: [UIViewController] = {
return [vipVC, coinsVC]
}()
//MARK: UI
private lazy var topImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "vip_icon_03"))
return imageView
}()
private lazy var vipTipImageView1: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "vip_tip_icon_01"))
return imageView
}()
private lazy var vipTipImageView2: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "vip_tip_icon_02"))
return imageView
}()
private lazy var pageBgView: VPGradientView = {
let view = VPGradientView()
view.colors = [UIColor.color045241().cgColor, UIColor.color000000().cgColor, UIColor.color000000().cgColor]
view.locations = [0, 0.5, 1]
view.startPoint = .init(x: 0, y: 0)
view.endPoint = .init(x: 1, y: 1)
return view
}()
private lazy var pageParam: WMZPageParam = {
let param = WMZPageParam()
param.wTitleArr = ["VIP".localized, "Coins".localized]
param.wViewController = { [weak self] index in
return self?.viewControllers[index]
}
param.wMenuTitleWidth = UIScreen.width / 2
param.wMenuHeight = 46
param.wMenuTitleUIFont = .fontRegular(ofSize: 15)
param.wMenuTitleSelectUIFont = .fontMedium(ofSize: 16)
param.wMenuTitleColor = .colorBFBFBF()
param.wMenuTitleSelectColor = .colorFFFFFF()
param.wMenuBgColor = .clear
param.wBgColor = .clear
param.wCustomMenuTitle = { [weak self] buttons in
buttons?.forEach({ button in
self?.setButtonState(button: button)
})
}
// param.wCustomMenuSelectTitle = { [weak self] buttons in
// buttons?.forEach({ button in
// self?.setButtonState(button: button)
// })
// }
param.wCustomNaviBarY = { _ in
return 0
}
param.wCustomTabbarY = { _ in
return 0
}
param.wCustomDataViewTopOffset = 0
return param
}()
private lazy var pageView: WMZPageView = {
let y = topImageHeight - 54
let view = WMZPageView(frame: .init(x: 0, y: y, width: UIScreen.width, height: UIScreen.height - y), param: pageParam, parentReponder: self)
view.downSc?.backgroundColor = .clear
view.backgroundColor = .clear
view.addRadius(topLeft: 24, topRight: 24, bottomLeft: 0, bottomRight: 0)
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
vp_setupUI()
requestData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
setNavigationNormalStyle()
}
private func setButtonState(button: UIButton) {
vpLog(message: button.tag)
if button.tag == 0 {
button.setBackgroundImage(UIImage(named: "vip_menu_left_selected"), for: .selected)
} else {
button.setBackgroundImage(UIImage(named: "vip_menu_right_selected"), for: .selected)
}
}
}
extension VPVipPageViewController {
private func vp_setupUI() {
view.addSubview(topImageView)
view.addSubview(vipTipImageView1)
view.addSubview(vipTipImageView2)
view.addSubview(pageView)
pageView.addSubview(pageBgView)
pageView.sendSubviewToBack(pageBgView)
topImageView.snp.makeConstraints { make in
make.top.left.right.equalToSuperview()
make.height.equalTo(topImageHeight)
}
vipTipImageView1.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalTo(topImageView).offset(-81)
}
vipTipImageView2.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalTo(vipTipImageView1.snp.top).offset(-12)
}
pageBgView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
}
}
extension VPVipPageViewController {
private func requestData() {
VPWalletAPI.requestPayTemplate { [weak self] model in
guard let self = self else { return }
if let model = model {
self.vipVC.dataArr = model.list_sub_vip ?? []
self.coinsVC.dataArr = model.list_coins ?? []
}
}
}
}

View File

@ -0,0 +1,170 @@
//
// VPVipViewController.swift
// Veloria
//
// Created by on 2025/5/29.
//
import UIKit
class VPVipViewController: VPViewController {
var dataArr: [VPPayTemplateItem] = [] {
didSet {
self.collectionView.reloadData()
}
}
private lazy var scrollView: UIScrollView = {
let scrollView = VPScrollView()
return scrollView
}()
private lazy var iconImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "vip_icon_04"))
return imageView
}()
private lazy var iconTextLabel: UILabel = {
let label = UILabel()
label.font = .fontMedium(ofSize: 15)
label.textColor = .colorFFFFFF()
label.text = "Membership Benefits".localized
return label
}()
private lazy var stackView: UIStackView = {
let view = UIStackView(arrangedSubviews: [privilegeView1, privilegeView2, privilegeView3])
view.axis = .horizontal
view.distribution = .fillEqually
view.spacing = 7
return view
}()
private lazy var privilegeView1: VPVipPrivilegeItemView = {
let view = VPVipPrivilegeItemView()
view.icon = UIImage(named: "privilege_icon_04")
let hText = "1 week".localized
let string = NSMutableAttributedString(string: String(format: "kVipPrivilegeText4".localized, hText))
let hRange = string.string.ocString().range(of: hText)
string.color = .colorFFFFFF()
string.setColor(.color05CEA0(), range: hRange)
view.string = string
return view
}()
private lazy var privilegeView2: VPVipPrivilegeItemView = {
let view = VPVipPrivilegeItemView()
view.icon = UIImage(named: "privilege_icon_05")
let hText = "8 days".localized
let string = NSMutableAttributedString(string: String(format: "kVipPrivilegeText5".localized, hText))
let hRange = string.string.ocString().range(of: hText)
string.color = .colorFFFFFF()
string.setColor(.color05CEA0(), range: hRange)
view.string = string
return view
}()
private lazy var privilegeView3: VPVipPrivilegeItemView = {
let view = VPVipPrivilegeItemView()
view.icon = UIImage(named: "privilege_icon_06")
let string = NSMutableAttributedString(string: "kVipPrivilegeText6".localized)
string.color = .colorFFFFFF()
view.string = string
return view
}()
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 10
layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15)
layout.itemSize = .init(width: 332, height: 138)
return layout
}()
private lazy var collectionView: VPCollectionView = {
let collectionView = VPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsHorizontalScrollIndicator = false
collectionView.register(VPVipBuyCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.bgImageView.isHidden = true
self.view.backgroundColor = .clear
vp_setupUI()
}
}
extension VPVipViewController {
private func vp_setupUI() {
view.addSubview(scrollView)
scrollView.addSubview(iconImageView)
scrollView.addSubview(iconTextLabel)
scrollView.addSubview(stackView)
scrollView.addSubview(collectionView)
scrollView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
iconImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.top.equalToSuperview().offset(20)
}
iconTextLabel.snp.makeConstraints { make in
make.centerY.equalTo(iconImageView)
make.left.equalTo(iconImageView.snp.right).offset(7)
}
stackView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.centerX.equalToSuperview()
make.top.equalTo(iconImageView.snp.bottom).offset(18)
}
collectionView.snp.makeConstraints { make in
make.left.equalToSuperview()
make.centerX.equalToSuperview()
make.top.equalTo(stackView.snp.bottom).offset(7)
make.height.equalTo(collectionViewLayout.itemSize.height)
make.bottom.equalToSuperview()
}
}
}
//MARK: -------------- UICollectionViewDelegate UICollectionViewDataSource --------------
extension VPVipViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! VPVipBuyCell
cell.item = dataArr[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return dataArr.count
}
}

View File

@ -0,0 +1,71 @@
//
// VPPayTemplateItem.swift
// Veloria
//
// Created by on 2025/5/29.
//
import UIKit
import SmartCodable
class VPPayTemplateItem: VPModel, SmartCodable {
enum VipTypeKey: String, SmartCaseDefaultable {
case week = "week"
case month = "month"
case quarter = "quarter"
case year = "year"
func getText() -> String {
switch self {
case .week:
return "Weekly VIP".localized
case .month:
return "Monthly VIP".localized
case .quarter:
return "Quarterly VIP".localized
case .year:
return "Yearly VIP".localized
}
}
}
var id: String?
var status: String?
var price: String?
var origin_price: String?
var backhaul_price: String?
var coins: Int?
var send_coins: Int?
///coins sub_vip
var buy_type: VPWalletAPI.BuyType?
var sort: String?
var title: String?
var brief: String?
var sp_description: String?
var vip_type: String?
var vip_type_key: VipTypeKey?
var ios_template_id: String?
///
var currency: String?
///
var platform: String?
///
var corner_marker: String?
static func mappingForKey() -> [SmartKeyTransformer]? {
return [
CodingKeys.sp_description <--- ["description"]
]
}
}

View File

@ -0,0 +1,15 @@
//
// VPPayTemplateModel.swift
// Veloria
//
// Created by on 2025/5/29.
//
import UIKit
import SmartCodable
class VPPayTemplateModel: VPModel, SmartCodable {
var list_coins: [VPPayTemplateItem]?
var list_sub_vip: [VPPayTemplateItem]?
}

View File

@ -0,0 +1,116 @@
//
// VPVipBuyCell.swift
// Veloria
//
// Created by on 2025/5/29.
//
import UIKit
class VPVipBuyCell: VPCollectionViewCell {
var item: VPPayTemplateItem? {
didSet {
if let key = item?.vip_type_key?.rawValue {
bgImageView.image = UIImage(named: "vip_buy_bg_\(key)")
}
vipNameLabel.text = item?.vip_type_key?.getText()
unitLabel.text = item?.currency
moneyLabel.text = item?.price
var colors: [CGColor] = []
switch item?.vip_type_key {
case .week:
colors = [UIColor.color64A3A7().cgColor, UIColor.color416767().cgColor]
case .month:
colors = [UIColor.color9C7565().cgColor, UIColor.color573D31().cgColor]
case .quarter:
colors = [UIColor.color647DA7().cgColor, UIColor.color414867().cgColor]
case .year:
colors = [UIColor.color9C6586().cgColor, UIColor.color57314F().cgColor]
default:
break
}
vipNameLabel.gradientLayer.colors = colors
unitLabel.gradientLayer.colors = colors
moneyLabel.gradientLayer.colors = colors
durationLabel.gradientLayer.colors = colors
}
}
private lazy var bgImageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
private lazy var vipNameLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontBold(ofSize: 16)
return label
}()
private lazy var unitLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontRegular(ofSize: 14)
return label
}()
private lazy var moneyLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontAaHouDiHei(ofSize: 22)
return label
}()
private lazy var durationLabel: VPGradientLabel = {
let label = VPGradientLabel()
label.font = .fontRegular(ofSize: 14)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
vp_setupUI()
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension VPVipBuyCell {
private func vp_setupUI() {
contentView.addSubview(bgImageView)
contentView.addSubview(vipNameLabel)
contentView.addSubview(unitLabel)
contentView.addSubview(moneyLabel)
bgImageView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
vipNameLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(14)
make.top.equalToSuperview().offset(31)
make.height.equalTo(22)
}
unitLabel.snp.makeConstraints { make in
make.left.equalTo(vipNameLabel)
make.top.equalTo(vipNameLabel.snp.bottom).offset(20)
make.height.equalTo(20)
}
moneyLabel.snp.makeConstraints { make in
make.left.equalTo(unitLabel.snp.right)
make.bottom.equalTo(unitLabel).offset(-1)
}
}
}

View File

@ -0,0 +1,83 @@
//
// VPVipPrivilegeItemView.swift
// Veloria
//
// Created by on 2025/5/29.
//
import UIKit
class VPVipPrivilegeItemView: UIView {
var icon: UIImage? {
didSet {
iconImageView.image = icon
}
}
var string: NSAttributedString? {
didSet {
guard let string = string else { return }
let str = NSMutableAttributedString(attributedString: string)
str.lineSpacing = 3
str.alignment = .center
textLabel.attributedText = str
}
}
private lazy var iconImageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
private lazy var bgView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "privilege_bg_image_01"))
return imageView
}()
private lazy var textLabel: UILabel = {
let label = UILabel()
label.numberOfLines = 0
label.textAlignment = .center
label.font = .fontRegular(ofSize: 12)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
vp_setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension VPVipPrivilegeItemView {
private func vp_setupUI() {
addSubview(bgView)
addSubview(iconImageView)
addSubview(textLabel)
bgView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalToSuperview().offset(5)
make.height.equalTo(115)
}
iconImageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(-10)
}
textLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.right.lessThanOrEqualToSuperview().offset(-8)
make.centerY.equalTo(self.bgView.snp.bottom).offset(-42)
}
}
}

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "No Ads@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "No Ads@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "donate coins@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "donate coins@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "cancel@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "cancel@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 836 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,44 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Rectangle 422@2x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"left" : 80,
"right" : 66
},
"center" : {
"mode" : "tile",
"width" : 1
},
"mode" : "3-part-horizontal"
},
"scale" : "2x"
},
{
"filename" : "Rectangle 422@3x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"left" : 138,
"right" : 130
},
"center" : {
"mode" : "tile",
"width" : 1
},
"mode" : "3-part-horizontal"
},
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,44 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Rectangle 422@2x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"left" : 42,
"right" : 85
},
"center" : {
"mode" : "tile",
"width" : 1
},
"mode" : "3-part-horizontal"
},
"scale" : "2x"
},
{
"filename" : "Rectangle 422@3x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"left" : 114,
"right" : 125
},
"center" : {
"mode" : "tile",
"width" : 1
},
"mode" : "3-part-horizontal"
},
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Recharge & Unlock More@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Recharge & Unlock More@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Limited Time Offer@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Limited Time Offer@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Rectangle 424@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Rectangle 424@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 KiB

View File

@ -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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

Binary file not shown.

View File

@ -7,6 +7,7 @@
<key>UIAppFonts</key>
<array>
<string>PlayfairDisplay-VariableFont_wght.ttf</string>
<string>Aa厚底黑.ttf</string>
</array>
<key>UIApplicationSceneManifest</key>
<dict>

View File

@ -42,6 +42,12 @@
"Rewards" = "Rewards";
"Favorites" = "Favorites";
"Language" = "Language";
"VIP" = "VIP";
"Coins" = "Coins";
"Membership Benefits" = "Membership Benefits";
"1 week" = "1 week";
"8 days" = "8 days";
"Weekly VIP" = "Weekly VIP";
"kHomeTitleText" = "10,000+ addictive shorts await!";
@ -52,6 +58,9 @@
"kVipPrivilegeText1" = "Ad-Free\nStreaming";
"kVipPrivilegeText2" = "Exclusive\nEpisodes";
"kVipPrivilegeText3" = "Daily free\ncoins";
"kVipPrivilegeText4" = "Unlimited access to all series for %@ (No Ads)";
"kVipPrivilegeText5" = "The donate coins will expire in %@";
"kVipPrivilegeText6" = "Auto renew, cancel anytime";
//请选择需要删除的短剧
"kToastText1" = "Please select the short plays that need to be deleted";