退出登录,注销账号,alert弹窗
@ -178,6 +178,19 @@
|
||||
BFF5AFE22DEED2960044227A /* VPPlayerCoinBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFE12DEED2960044227A /* VPPlayerCoinBuyView.swift */; };
|
||||
BFF5AFE62DEEDB7F0044227A /* VPRewardsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFE52DEEDB7F0044227A /* VPRewardsViewController.swift */; };
|
||||
BFF5B21C2DEEDE130044227A /* VPWebViewController+Script.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B21B2DEEDE130044227A /* VPWebViewController+Script.swift */; };
|
||||
BFF5B2202DEEE2C50044227A /* VPLoginContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B21F2DEEE2C50044227A /* VPLoginContentView.swift */; };
|
||||
BFF5B2232DEEF8DA0044227A /* VPLoginButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2222DEEF8DA0044227A /* VPLoginButton.swift */; };
|
||||
BFF5B2252DEF02080044227A /* VPLoginManager+Apple.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2242DEF02080044227A /* VPLoginManager+Apple.swift */; };
|
||||
BFF5B2272DEF022F0044227A /* VPThirdSignModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2262DEF022F0044227A /* VPThirdSignModel.swift */; };
|
||||
BFF5B22A2DEFDDF10044227A /* VPMeFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2292DEFDDF10044227A /* VPMeFooterView.swift */; };
|
||||
BFF5B22C2DEFE8A80044227A /* VPDeleteAccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B22B2DEFE8A80044227A /* VPDeleteAccountViewController.swift */; };
|
||||
BFF5B22E2DEFEEAF0044227A /* VPDeleteAccountContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B22D2DEFEEAF0044227A /* VPDeleteAccountContentView.swift */; };
|
||||
BFF5B2302DEFEF0C0044227A /* VPDeleteAccountNormalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B22F2DEFEF0C0044227A /* VPDeleteAccountNormalView.swift */; };
|
||||
BFF5B2322DEFF1220044227A /* VPDeleteAccountDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2312DEFF1220044227A /* VPDeleteAccountDetailView.swift */; };
|
||||
BFF5B2342DEFF2030044227A /* VPDeleteAccountTipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2332DEFF2030044227A /* VPDeleteAccountTipView.swift */; };
|
||||
BFF5B2372DF013410044227A /* VPAlertWindowManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2362DF013410044227A /* VPAlertWindowManager.swift */; };
|
||||
BFF5B2392DF014520044227A /* VPBaseAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B2382DF014520044227A /* VPBaseAlertView.swift */; };
|
||||
BFF5B23B2DF018900044227A /* VPAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5B23A2DF018900044227A /* VPAlertView.swift */; };
|
||||
F939C04AD4003BA127F15C28 /* Pods_Veloria.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F57E87E765BF8D72A43DCA /* Pods_Veloria.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -362,6 +375,20 @@
|
||||
BFF5AFE12DEED2960044227A /* VPPlayerCoinBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPlayerCoinBuyView.swift; sourceTree = "<group>"; };
|
||||
BFF5AFE52DEEDB7F0044227A /* VPRewardsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPRewardsViewController.swift; sourceTree = "<group>"; };
|
||||
BFF5B21B2DEEDE130044227A /* VPWebViewController+Script.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VPWebViewController+Script.swift"; sourceTree = "<group>"; };
|
||||
BFF5B21F2DEEE2C50044227A /* VPLoginContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPLoginContentView.swift; sourceTree = "<group>"; };
|
||||
BFF5B2222DEEF8DA0044227A /* VPLoginButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPLoginButton.swift; sourceTree = "<group>"; };
|
||||
BFF5B2242DEF02080044227A /* VPLoginManager+Apple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VPLoginManager+Apple.swift"; sourceTree = "<group>"; };
|
||||
BFF5B2262DEF022F0044227A /* VPThirdSignModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPThirdSignModel.swift; sourceTree = "<group>"; };
|
||||
BFF5B2282DEFDAF00044227A /* Veloria.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Veloria.entitlements; sourceTree = "<group>"; };
|
||||
BFF5B2292DEFDDF10044227A /* VPMeFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeFooterView.swift; sourceTree = "<group>"; };
|
||||
BFF5B22B2DEFE8A80044227A /* VPDeleteAccountViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPDeleteAccountViewController.swift; sourceTree = "<group>"; };
|
||||
BFF5B22D2DEFEEAF0044227A /* VPDeleteAccountContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPDeleteAccountContentView.swift; sourceTree = "<group>"; };
|
||||
BFF5B22F2DEFEF0C0044227A /* VPDeleteAccountNormalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPDeleteAccountNormalView.swift; sourceTree = "<group>"; };
|
||||
BFF5B2312DEFF1220044227A /* VPDeleteAccountDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPDeleteAccountDetailView.swift; sourceTree = "<group>"; };
|
||||
BFF5B2332DEFF2030044227A /* VPDeleteAccountTipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPDeleteAccountTipView.swift; sourceTree = "<group>"; };
|
||||
BFF5B2362DF013410044227A /* VPAlertWindowManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPAlertWindowManager.swift; sourceTree = "<group>"; };
|
||||
BFF5B2382DF014520044227A /* VPBaseAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPBaseAlertView.swift; sourceTree = "<group>"; };
|
||||
BFF5B23A2DF018900044227A /* VPAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPAlertView.swift; 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 */
|
||||
|
||||
@ -398,6 +425,7 @@
|
||||
1B056E2A2DDAC0FD007EE38D /* Veloria */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFF5B2282DEFDAF00044227A /* Veloria.entitlements */,
|
||||
1B056E322DDAC18C007EE38D /* AppDelegate */,
|
||||
1B056E372DDAC1EF007EE38D /* Base */,
|
||||
1B056E362DDAC1E8007EE38D /* Class */,
|
||||
@ -434,6 +462,7 @@
|
||||
1B056E352DDAC1DE007EE38D /* Libs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFF5B2352DF013020044227A /* Alert */,
|
||||
BF5E75D92DE5B89300DE9DFE /* MarqueeView */,
|
||||
BF5E75B42DE46D9500DE9DFE /* Empty */,
|
||||
BF0FA7BF2DE45D4500C9E5F2 /* User */,
|
||||
@ -456,6 +485,7 @@
|
||||
1B056E522DDACBF4007EE38D /* Home */,
|
||||
BF0FA7422DDF024400C9E5F2 /* Explore */,
|
||||
BF0FA6FD2DDC65F300C9E5F2 /* Player */,
|
||||
BFF5B21D2DEEE28B0044227A /* Login */,
|
||||
);
|
||||
path = Class;
|
||||
sourceTree = "<group>";
|
||||
@ -637,7 +667,9 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA6D92DDC5CB600C9E5F2 /* VPLoginManager.swift */,
|
||||
BFF5B2242DEF02080044227A /* VPLoginManager+Apple.swift */,
|
||||
BF0FA6DB2DDC5CD700C9E5F2 /* VPTokenModel.swift */,
|
||||
BFF5B2262DEF022F0044227A /* VPThirdSignModel.swift */,
|
||||
);
|
||||
path = Login;
|
||||
sourceTree = "<group>";
|
||||
@ -910,6 +942,7 @@
|
||||
children = (
|
||||
BF0FA7AE2DE443E000C9E5F2 /* VPMeViewController.swift */,
|
||||
BF5E75AE2DE4632200DE9DFE /* VPAboutUsViewController.swift */,
|
||||
BFF5B22B2DEFE8A80044227A /* VPDeleteAccountViewController.swift */,
|
||||
);
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
@ -926,6 +959,11 @@
|
||||
BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */,
|
||||
BFF5AFA92DE7070A0044227A /* VPMeCoinItemView.swift */,
|
||||
BFF5AFAB2DE70CE20044227A /* VPMeToolCell.swift */,
|
||||
BFF5B2292DEFDDF10044227A /* VPMeFooterView.swift */,
|
||||
BFF5B22D2DEFEEAF0044227A /* VPDeleteAccountContentView.swift */,
|
||||
BFF5B22F2DEFEF0C0044227A /* VPDeleteAccountNormalView.swift */,
|
||||
BFF5B2312DEFF1220044227A /* VPDeleteAccountDetailView.swift */,
|
||||
BFF5B2332DEFF2030044227A /* VPDeleteAccountTipView.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@ -1052,6 +1090,41 @@
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFF5B21D2DEEE28B0044227A /* Login */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFF5B21E2DEEE2A50044227A /* Controller */,
|
||||
BFF5B2212DEEEB0C0044227A /* View */,
|
||||
);
|
||||
path = Login;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFF5B21E2DEEE2A50044227A /* Controller */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
);
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFF5B2212DEEEB0C0044227A /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFF5B21F2DEEE2C50044227A /* VPLoginContentView.swift */,
|
||||
BFF5B2222DEEF8DA0044227A /* VPLoginButton.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BFF5B2352DF013020044227A /* Alert */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BFF5B23A2DF018900044227A /* VPAlertView.swift */,
|
||||
BFF5B2382DF014520044227A /* VPBaseAlertView.swift */,
|
||||
BFF5B2362DF013410044227A /* VPAlertWindowManager.swift */,
|
||||
);
|
||||
path = Alert;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -1191,10 +1264,12 @@
|
||||
BF0FA7C32DE45DE300C9E5F2 /* VPUserAPI.swift in Sources */,
|
||||
BF0FA78B2DE164C100C9E5F2 /* VPSearchResultCell.swift in Sources */,
|
||||
BF0FA71D2DDC807200C9E5F2 /* UIImageView+VPAdd.swift in Sources */,
|
||||
BFF5B22C2DEFE8A80044227A /* VPDeleteAccountViewController.swift in Sources */,
|
||||
BF0FA6DC2DDC5CD700C9E5F2 /* VPTokenModel.swift in Sources */,
|
||||
BF0FA7572DDF159B00C9E5F2 /* VPExploreViewController.swift in Sources */,
|
||||
1B056E772DDB3641007EE38D /* VPTabBarItemNormalVew.swift in Sources */,
|
||||
1B056E4B2DDAC6BA007EE38D /* VPDefine.swift in Sources */,
|
||||
BFF5B2302DEFEF0C0044227A /* VPDeleteAccountNormalView.swift in Sources */,
|
||||
1B056E702DDB019B007EE38D /* VPTabBarItemContainer.swift in Sources */,
|
||||
BF0FA7752DE071B500C9E5F2 /* VPSearchViewController.swift in Sources */,
|
||||
BF0FA78D2DE16A8B00C9E5F2 /* VPSearchViewModel.swift in Sources */,
|
||||
@ -1208,6 +1283,7 @@
|
||||
BF0FA79B2DE1984B00C9E5F2 /* VPCollectListViewController.swift in Sources */,
|
||||
BF0FA7A32DE1AB1800C9E5F2 /* VPWatchHistoryCell.swift in Sources */,
|
||||
BF0FA76D2DE053C100C9E5F2 /* VPScrollView.swift in Sources */,
|
||||
BFF5B2202DEEE2C50044227A /* VPLoginContentView.swift in Sources */,
|
||||
1B056E5D2DDACD8E007EE38D /* UIFont+VPAdd.swift in Sources */,
|
||||
BF0FA7282DDC91F800C9E5F2 /* VPCollectionViewCell.swift in Sources */,
|
||||
BF0FA7672DE0469300C9E5F2 /* VPEpisodeView.swift in Sources */,
|
||||
@ -1234,15 +1310,18 @@
|
||||
BF5E75CD2DE5692D00DE9DFE /* JXTransitionDelegateBridge.swift in Sources */,
|
||||
BF5E75CE2DE5692D00DE9DFE /* JXPushAnimatedTransition.swift in Sources */,
|
||||
BF5E75CF2DE5692D00DE9DFE /* UIViewController+JXTransition.swift in Sources */,
|
||||
BFF5B23B2DF018900044227A /* VPAlertView.swift in Sources */,
|
||||
BF5E75D02DE5692D00DE9DFE /* UIGestureRecognizer+JXTransition.swift in Sources */,
|
||||
BFF5AFA62DE700420044227A /* VPMeVipPrivilegeItemView.swift in Sources */,
|
||||
BF5E75D12DE5692D00DE9DFE /* JXPopAnimatedTransition.swift in Sources */,
|
||||
BF5E75D22DE5692D00DE9DFE /* JXNavigationInteractiveTransition.swift in Sources */,
|
||||
BFF5B2342DEFF2030044227A /* VPDeleteAccountTipView.swift in Sources */,
|
||||
BF5E75D32DE5692D00DE9DFE /* JXBaseAnimatedTransition.swift in Sources */,
|
||||
1B056E462DDAC370007EE38D /* UIScreen+VPAdd.swift in Sources */,
|
||||
BFF5AFDE2DEEBF370044227A /* VPPlayerRechargeView.swift in Sources */,
|
||||
BFF5AFAA2DE7070A0044227A /* VPMeCoinItemView.swift in Sources */,
|
||||
BF0FA7692DE0502900C9E5F2 /* VPEpisodeCell.swift in Sources */,
|
||||
BFF5B2372DF013410044227A /* VPAlertWindowManager.swift in Sources */,
|
||||
BF5E75BE2DE54B2800DE9DFE /* VPAboutUsHeaderView.swift in Sources */,
|
||||
BFF5AFB22DE7FC130044227A /* CGMutablePath+VPAdd.swift in Sources */,
|
||||
BF0FA73D2DDED2D000C9E5F2 /* VPVideoAPI.swift in Sources */,
|
||||
@ -1276,11 +1355,14 @@
|
||||
BF0FA7A52DE4384100C9E5F2 /* AttributedString+VPAdd.swift in Sources */,
|
||||
BF0FA7652DE00A0E00C9E5F2 /* VPDetailPlayerControlView.swift in Sources */,
|
||||
BF0FA7342DDEC74500C9E5F2 /* VPCategoryModel.swift in Sources */,
|
||||
BFF5B2322DEFF1220044227A /* VPDeleteAccountDetailView.swift in Sources */,
|
||||
1B056E4F2DDAC7FC007EE38D /* VPNavigationController.swift in Sources */,
|
||||
1B056E3F2DDAC2DB007EE38D /* VPCryptorService.swift in Sources */,
|
||||
BF0FA7202DDC83AE00C9E5F2 /* JXButton.swift in Sources */,
|
||||
BF0FA7912DE16CBF00C9E5F2 /* VPSearchHistoryView.swift in Sources */,
|
||||
BFF5AFE22DEED2960044227A /* VPPlayerCoinBuyView.swift in Sources */,
|
||||
BFF5B2272DEF022F0044227A /* VPThirdSignModel.swift in Sources */,
|
||||
BFF5B22A2DEFDDF10044227A /* VPMeFooterView.swift in Sources */,
|
||||
BF0FA7992DE1951A00C9E5F2 /* VPMyListViewController.swift in Sources */,
|
||||
BF0FA7452DDF027900C9E5F2 /* VPPlayer.swift in Sources */,
|
||||
BFF5AFC62DE863C00044227A /* VPGradientButton.swift in Sources */,
|
||||
@ -1300,13 +1382,17 @@
|
||||
BF0FA7022DDC667C00C9E5F2 /* VPVideoInfoModel.swift in Sources */,
|
||||
BF0FA77B2DE0788A00C9E5F2 /* UIStackView+VPAdd.swift in Sources */,
|
||||
BF0FA7BE2DE4592A00C9E5F2 /* UserDefaults+VPAdd.swift in Sources */,
|
||||
BFF5B2232DEEF8DA0044227A /* VPLoginButton.swift in Sources */,
|
||||
BF0FA76F2DE062A700C9E5F2 /* VPRateSelectedView.swift in Sources */,
|
||||
BF0FA7772DE0735800C9E5F2 /* VPSearchInputView.swift in Sources */,
|
||||
BFF5AFB62DE803A30044227A /* VPVipPrivilegeItemView.swift in Sources */,
|
||||
BFF5AFB82DE832580044227A /* VPVipBuyCell.swift in Sources */,
|
||||
BFF5B22E2DEFEEAF0044227A /* VPDeleteAccountContentView.swift in Sources */,
|
||||
BFF5B2252DEF02080044227A /* VPLoginManager+Apple.swift in Sources */,
|
||||
BF0FA7892DE161F200C9E5F2 /* VPSearchResultView.swift in Sources */,
|
||||
1B056E792DDB365A007EE38D /* VPTabBarItemSelectedView.swift in Sources */,
|
||||
1B056E722DDB022F007EE38D /* VPTabBarItem.swift in Sources */,
|
||||
BFF5B2392DF014520044227A /* VPBaseAlertView.swift in Sources */,
|
||||
BFF5AFCC2DE98C7F0044227A /* VPOrderRecordsViewController.swift in Sources */,
|
||||
1B056E412DDAC30A007EE38D /* VPModel.swift in Sources */,
|
||||
BF0FA70A2DDC69C800C9E5F2 /* VPTableViewCell.swift in Sources */,
|
||||
@ -1370,6 +1456,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Veloria/Veloria.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@ -1407,6 +1494,7 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Veloria/Veloria.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Development";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
@ -193,4 +193,45 @@ extension UIColor {
|
||||
static func color00211A(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x00211A, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color333333(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x333333, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color585858(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x585858, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorB3B3B3(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0xB3B3B3, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color080B16(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x080B16, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color272A30(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x272A30, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color8B8B8B(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x8B8B8B, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color126B4E(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x126B4E, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color1A2D22(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x1A2D22, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorC8C8C8(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0xC8C8C8, alpha: alpha)
|
||||
}
|
||||
|
||||
static func color024E3D(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0x024E3D, alpha: alpha)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class VPUserAPI: NSObject {
|
||||
|
||||
@ -19,4 +20,39 @@ class VPUserAPI: NSObject {
|
||||
completer?(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
///登录
|
||||
static func requestThirdLogin(model: VPThirdSignModel, completer: ((_ token: VPTokenModel?) -> Void)?) {
|
||||
|
||||
var param = VPNetworkParameters(path: "/customer/login")
|
||||
param.parameters = model.toDictionary()
|
||||
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPTokenModel>) in
|
||||
completer?(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
///退出登录
|
||||
static func requestLogout(completer: ((_ token: VPTokenModel?) -> Void)?) {
|
||||
var param = VPNetworkParameters(path: "/customer/signout")
|
||||
param.isLoding = true
|
||||
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPTokenModel>) in
|
||||
completer?(response.data)
|
||||
}
|
||||
}
|
||||
|
||||
///注销账户
|
||||
static func requestDelete(completer: ((_ isFinish: Bool) -> Void)?) {
|
||||
var param = VPNetworkParameters(path: "/customer/logoff")
|
||||
param.isLoding = true
|
||||
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<String>) in
|
||||
if response.code == VPNetworkCodeSucceed {
|
||||
completer?(true)
|
||||
} else {
|
||||
completer?(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,8 +48,21 @@ class VPGradientLabel: UILabel {
|
||||
let textLayer = CATextLayer()
|
||||
textLayer.string = string
|
||||
textLayer.frame = bounds
|
||||
textLayer.alignmentMode = .center
|
||||
switch self.textAlignment {
|
||||
case .left:
|
||||
textLayer.alignmentMode = .left
|
||||
case .center:
|
||||
textLayer.alignmentMode = .center
|
||||
case .right:
|
||||
textLayer.alignmentMode = .right
|
||||
case .justified:
|
||||
textLayer.alignmentMode = .justified
|
||||
case .natural:
|
||||
textLayer.alignmentMode = .natural
|
||||
default: break
|
||||
}
|
||||
textLayer.contentsScale = UIScreen.main.scale
|
||||
textLayer.isWrapped = true
|
||||
gradientLayer.mask = textLayer
|
||||
|
||||
CATransaction.commit()
|
||||
|
72
Veloria/Class/Login/View/VPLoginButton.swift
Normal file
@ -0,0 +1,72 @@
|
||||
//
|
||||
// VPLoginButton.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/3.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPLoginButton: UIControl {
|
||||
|
||||
var icon: UIImage? {
|
||||
didSet {
|
||||
iconImageView.image = icon
|
||||
}
|
||||
}
|
||||
|
||||
var title: String? {
|
||||
didSet {
|
||||
titleLabel.text = title
|
||||
}
|
||||
}
|
||||
|
||||
override var intrinsicContentSize: CGSize {
|
||||
return .init(width: UIScreen.width, height: 48)
|
||||
}
|
||||
|
||||
private lazy var iconImageView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .color333333()
|
||||
return label
|
||||
}()
|
||||
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
layer.cornerRadius = 24
|
||||
layer.masksToBounds = true
|
||||
backgroundColor = .colorFFFFFF()
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPLoginButton {
|
||||
|
||||
private func vp_setupUI() {
|
||||
addSubview(iconImageView)
|
||||
addSubview(titleLabel)
|
||||
|
||||
|
||||
iconImageView.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(40)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.center.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
203
Veloria/Class/Login/View/VPLoginContentView.swift
Normal file
@ -0,0 +1,203 @@
|
||||
//
|
||||
// VPLoginContentView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/3.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPLoginContentView: HWPanModalContentView {
|
||||
|
||||
private lazy var bgView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "bg_image_01"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var closeButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "close_icon_02"), for: .normal)
|
||||
button.addTarget(self, action: #selector(handleCloseButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 16)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.text = String(format: "Welcome to %@".localized, "kAppName".localized)
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var agreementLabel: YYLabel = {
|
||||
let userAgreementText = "User Agreement".localized
|
||||
let privacyPolicyText = "Privacy Policy".localized
|
||||
let text = String(format: "kLoginAgreementText".localized, userAgreementText, privacyPolicyText)
|
||||
|
||||
let range1 = text.ocString().range(of: userAgreementText)
|
||||
let range2 = text.ocString().range(of: privacyPolicyText)
|
||||
|
||||
let string = NSMutableAttributedString(string: text)
|
||||
string.font = .fontRegular(ofSize: 12)
|
||||
string.color = .colorB5B5B5()
|
||||
string.alignment = .center
|
||||
string.setUnderlineColor(string.color, range: range1)
|
||||
string.setUnderlineColor(string.color, range: range2)
|
||||
string.setUnderlineStyle(.single, range: range1)
|
||||
string.setUnderlineStyle(.single, range: range2)
|
||||
string.setTextHighlight(range1, color: nil, backgroundColor: nil) { [weak self] _, _, _, _ in
|
||||
self?.openWebPage(url: kVPUserAgreementWebUrl)
|
||||
}
|
||||
|
||||
string.setTextHighlight(range2, color: nil, backgroundColor: nil) { [weak self] _, _, _, _ in
|
||||
self?.openWebPage(url: kVPPrivacyPolicyWebUrl)
|
||||
}
|
||||
|
||||
let textLayout = YYTextLayout(containerSize: .init(width: UIScreen.width - 30, height: 100), text: string)
|
||||
|
||||
let label = YYLabel()
|
||||
label.textLayout = textLayout
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var stackView: UIStackView = {
|
||||
let stackView = UIStackView(arrangedSubviews: [appleButton])
|
||||
stackView.axis = .vertical
|
||||
stackView.spacing = 20
|
||||
return stackView
|
||||
}()
|
||||
|
||||
private lazy var appleButton: VPLoginButton = {
|
||||
let button = VPLoginButton()
|
||||
button.icon = UIImage(named: "apple_icon_01")
|
||||
button.title = "Login with Apple".localized
|
||||
button.addTarget(self, action: #selector(handleAppleButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func handleCloseButton() {
|
||||
self.dismiss(animated: true) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//MARK: HWPanModalPresentable
|
||||
override func panScrollable() -> UIScrollView? {
|
||||
return nil
|
||||
}
|
||||
|
||||
override func longFormHeight() -> PanModalHeight {
|
||||
return PanModalHeightMake(.content, UIScreen.height * (2 / 3))
|
||||
}
|
||||
|
||||
override func showDragIndicator() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func backgroundConfig() -> HWBackgroundConfig {
|
||||
let config = HWBackgroundConfig()
|
||||
config.backgroundAlpha = 0.6
|
||||
return config
|
||||
}
|
||||
|
||||
override func allowsDragToDismiss() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func allowsTapBackgroundToDismiss() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func allowsPullDownWhenShortState() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func minVerticalVelocityToTriggerDismiss() -> CGFloat {
|
||||
return 0
|
||||
}
|
||||
|
||||
override func showsScrollableVerticalScrollIndicator() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPLoginContentView {
|
||||
private func openWebPage(url: String) {
|
||||
let vc = VPWebViewController()
|
||||
vc.configNavigationBack()
|
||||
vc.urlStr = url
|
||||
let nav = VPNavigationController(rootViewController: vc)
|
||||
nav.modalPresentationStyle = .fullScreen
|
||||
VPAppTool.rootViewController?.present(nav, animated: true)
|
||||
}
|
||||
|
||||
@objc private func handleAppleButton() {
|
||||
login(type: .apple)
|
||||
}
|
||||
|
||||
private func login(type: VPLoginManager.LoginType) {
|
||||
VPHUD.show()
|
||||
VPLoginManager.manager.login(type: type, presentingViewController: nil) { [weak self] isFinish in
|
||||
VPHUD.dismiss()
|
||||
guard let self = self else { return }
|
||||
if isFinish {
|
||||
self.dismiss(animated: true) {
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension VPLoginContentView {
|
||||
|
||||
private func vp_setupUI() {
|
||||
addSubview(bgView)
|
||||
addSubview(closeButton)
|
||||
addSubview(titleLabel)
|
||||
addSubview(agreementLabel)
|
||||
addSubview(stackView)
|
||||
|
||||
bgView.snp.makeConstraints { make in
|
||||
make.left.right.top.equalToSuperview()
|
||||
}
|
||||
|
||||
closeButton.snp.makeConstraints { make in
|
||||
make.right.equalToSuperview().offset(-15)
|
||||
make.top.equalToSuperview().offset(15)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.centerY.equalTo(closeButton)
|
||||
}
|
||||
|
||||
agreementLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 10))
|
||||
make.width.equalTo(agreementLabel.textLayout?.textBoundingSize.width ?? 0)
|
||||
make.height.equalTo(agreementLabel.textLayout?.textBoundingSize.height ?? 0)
|
||||
}
|
||||
|
||||
stackView.snp.makeConstraints { make in
|
||||
make.center.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(15)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
202
Veloria/Class/Me/Controller/VPDeleteAccountViewController.swift
Normal file
@ -0,0 +1,202 @@
|
||||
//
|
||||
// VPDeleteAccountViewController.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPDeleteAccountViewController: VPViewController {
|
||||
|
||||
private lazy var scrollView: VPScrollView = {
|
||||
let scrollView = VPScrollView()
|
||||
return scrollView
|
||||
}()
|
||||
|
||||
private lazy var iconImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "warning_icon_01"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var iconTextLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorBE0069()
|
||||
label.text = "DeleteAccount_tips_1".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var stackView: UIStackView = {
|
||||
let view = UIStackView()
|
||||
view.axis = .vertical
|
||||
view.spacing = 18
|
||||
|
||||
|
||||
view.addArrangedSubview(contentView1)
|
||||
view.addArrangedSubview(contentView3)
|
||||
view.addArrangedSubview(contentView2)
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var contentView1: VPDeleteAccountNormalView = {
|
||||
let view = VPDeleteAccountNormalView()
|
||||
view.text = "DeleteAccount_tips_2".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var contentView2: VPDeleteAccountNormalView = {
|
||||
let view = VPDeleteAccountNormalView()
|
||||
view.text = "DeleteAccount_tips_3".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var contentView3: VPDeleteAccountDetailView = {
|
||||
let view = VPDeleteAccountDetailView()
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var checkButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "choice_icon_01"), for: .normal)
|
||||
button.setImage(UIImage(named: "choice_icon_01_selected"), for: .selected)
|
||||
button.setImage(UIImage(named: "choice_icon_01_selected"), for: [.selected, .highlighted])
|
||||
button.addTarget(self, action: #selector(handleCheckButton), for: .touchUpInside)
|
||||
button.setContentHuggingPriority(.required, for: .horizontal)
|
||||
button.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var checkLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontMedium(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.numberOfLines = 0
|
||||
label.text = "DeleteAccount_tips_4".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var deleteButton: UIButton = {
|
||||
let config = UIButton.Configuration.plain()
|
||||
let button = VPGradientButton(configuration: config)
|
||||
button.layer.cornerRadius = 24
|
||||
button.layer.masksToBounds = true
|
||||
button.isEnabled = false
|
||||
button.locations = [0, 1]
|
||||
button.startPoint = .init(x: 0, y: 0.3)
|
||||
button.endPoint = .init(x: 1, y: 0.8)
|
||||
button.addTarget(self, action: #selector(handleDeleteButton), for: .touchUpInside)
|
||||
|
||||
button.configurationUpdateHandler = { button in
|
||||
guard let button = button as? VPGradientButton else { return }
|
||||
let title = "Delete Account".localized
|
||||
|
||||
if button.isEnabled {
|
||||
button.configuration?.attributedTitle = .createAttributedString(string: title, color: .colorFFFFFF(), font: .fontRegular(ofSize: 14))
|
||||
button.bt_setGradientBorder()
|
||||
button.colors = [UIColor.color05CEA0(alpha: 0.3).cgColor, UIColor.color7C174F(alpha: 0.3).cgColor]
|
||||
} else {
|
||||
button.configuration?.attributedTitle = .createAttributedString(string: title, color: .color8B8B8B(), font: .fontRegular(ofSize: 14))
|
||||
button.bt_removeGradientBorder()
|
||||
button.colors = [UIColor.color272A30().cgColor, UIColor.color272A30().cgColor]
|
||||
}
|
||||
}
|
||||
|
||||
return button
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.bgImageView.isHidden = true
|
||||
self.view.backgroundColor = .color080B16()
|
||||
self.title = "Account Deletion".localized
|
||||
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
||||
self.setNavigationNormalStyle()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension VPDeleteAccountViewController {
|
||||
|
||||
@objc private func handleCheckButton() {
|
||||
self.checkButton.isSelected = !self.checkButton.isSelected
|
||||
self.deleteButton.isEnabled = self.checkButton.isSelected
|
||||
}
|
||||
|
||||
@objc private func handleDeleteButton() {
|
||||
let alert = VPAlertView(title: "kDeleteAccountAlertTitle".localized, subtitle: "kDeleteAccountAlertText".localized, icon: UIImage(named: "alert_icon_01"), normalButtonText: "Delete Forever".localized, highlightButtonText: "Cancel".localized)
|
||||
alert.show()
|
||||
|
||||
alert.clickNormalButton = {
|
||||
VPLoginManager.manager.deleteAccount { [weak self] isFinish in
|
||||
guard let self = self else { return }
|
||||
if isFinish {
|
||||
self.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPDeleteAccountViewController {
|
||||
|
||||
private func vp_setupUI() {
|
||||
view.addSubview(scrollView)
|
||||
scrollView.addSubview(iconImageView)
|
||||
scrollView.addSubview(iconTextLabel)
|
||||
scrollView.addSubview(stackView)
|
||||
scrollView.addSubview(checkButton)
|
||||
scrollView.addSubview(checkLabel)
|
||||
scrollView.addSubview(deleteButton)
|
||||
|
||||
scrollView.snp.makeConstraints { make in
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(UIScreen.navBarHeight)
|
||||
}
|
||||
|
||||
iconImageView.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(10)
|
||||
}
|
||||
|
||||
iconTextLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalTo(iconImageView.snp.bottom).offset(12)
|
||||
}
|
||||
|
||||
stackView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalTo(iconTextLabel.snp.bottom).offset(18)
|
||||
}
|
||||
|
||||
checkButton.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
make.top.equalTo(stackView.snp.bottom).offset(25)
|
||||
}
|
||||
|
||||
checkLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(checkButton.snp.right).offset(10)
|
||||
make.right.lessThanOrEqualTo(stackView)
|
||||
make.top.equalTo(checkButton).offset(2)
|
||||
}
|
||||
|
||||
deleteButton.snp.makeConstraints { make in
|
||||
make.left.equalTo(stackView)
|
||||
make.right.equalTo(stackView)
|
||||
make.top.equalTo(checkLabel.snp.bottom).offset(20)
|
||||
make.height.equalTo(48)
|
||||
make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 20))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -10,28 +10,7 @@ import UIKit
|
||||
class VPMeViewController: VPViewController {
|
||||
|
||||
private lazy var dataArr: [[VPMeItem]] = {
|
||||
let arr = [
|
||||
[
|
||||
VPMeItem(cellKey: .userInfo),
|
||||
],
|
||||
[
|
||||
VPMeItem(cellKey: .vip)
|
||||
],
|
||||
[
|
||||
VPMeItem(cellKey: .coin)
|
||||
],
|
||||
[
|
||||
VPMeItem(cellKey: .tool)
|
||||
],
|
||||
[
|
||||
VPMeItem(icon: UIImage(named: "me_item_icon_05"), title: "Language".localized, type: .language, cellKey: .normal),
|
||||
VPMeItem(icon: UIImage(named: "me_item_icon_01"), title: "Privacy Policy".localized, type: .privacyPolicy, cellKey: .normal),
|
||||
VPMeItem(icon: UIImage(named: "me_item_icon_02"), title: "User Agreement".localized, type: .userAgreement, cellKey: .normal),
|
||||
// VPMeItem(icon: UIImage(named: "me_item_icon_04"), title: "Help Center".localized, type: .feedback, cellKey: .normal),
|
||||
VPMeItem(icon: UIImage(named: "me_item_icon_03"), title: "About Us".localized, type: .aboutUs, cellKey: .normal),
|
||||
]
|
||||
]
|
||||
return arr
|
||||
return self.createDataArr()
|
||||
}()
|
||||
|
||||
|
||||
@ -53,8 +32,20 @@ class VPMeViewController: VPViewController {
|
||||
return tableView
|
||||
}()
|
||||
|
||||
private lazy var footerView: VPMeFooterView = {
|
||||
let view = VPMeFooterView(frame: .init(x: 0, y: 0, width: UIScreen.width, height: 80))
|
||||
view.userInfo = VPLoginManager.manager.userInfo
|
||||
return view
|
||||
}()
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(userInfoUpdateNotification), name: VPLoginManager.userInfoUpdateNotification, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(loginStateDidChangeNotification), name: VPLoginManager.loginStateDidChangeNotification, object: nil)
|
||||
|
||||
vp_setupUI()
|
||||
|
||||
@ -80,11 +71,28 @@ class VPMeViewController: VPViewController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension VPMeViewController {
|
||||
|
||||
@objc private func userInfoUpdateNotification() {
|
||||
self.footerView.userInfo = VPLoginManager.manager.userInfo
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
|
||||
@objc private func loginStateDidChangeNotification() {
|
||||
self.dataArr = createDataArr()
|
||||
self.tableView.reloadData()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPMeViewController {
|
||||
|
||||
private func vp_setupUI() {
|
||||
tableView.tableFooterView = self.footerView
|
||||
|
||||
view.addSubview(tableView)
|
||||
|
||||
tableView.snp.makeConstraints { make in
|
||||
@ -150,6 +158,10 @@ extension VPMeViewController: UITableViewDelegate, UITableViewDataSource {
|
||||
let vc = VPAboutUsViewController()
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
case .deleteAccount:
|
||||
let vc = VPDeleteAccountViewController()
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
@ -163,10 +175,42 @@ extension VPMeViewController {
|
||||
|
||||
///获取用户信息
|
||||
private func requestUserInfo(completer: (() -> Void)? = nil) {
|
||||
VPLoginManager.manager.updateUserInfo { [weak self] in
|
||||
self?.tableView.reloadData()
|
||||
|
||||
VPLoginManager.manager.updateUserInfo {
|
||||
completer?()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func createDataArr() -> [[VPMeItem]] {
|
||||
var dataArr = [
|
||||
[
|
||||
VPMeItem(cellKey: .userInfo),
|
||||
],
|
||||
[
|
||||
VPMeItem(cellKey: .vip)
|
||||
],
|
||||
[
|
||||
VPMeItem(cellKey: .coin)
|
||||
],
|
||||
[
|
||||
VPMeItem(cellKey: .tool)
|
||||
]
|
||||
]
|
||||
|
||||
var cellArr: [VPMeItem] = []
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_05"), title: "Language".localized, type: .language, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_01"), title: "Privacy Policy".localized, type: .privacyPolicy, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_02"), title: "User Agreement".localized, type: .userAgreement, cellKey: .normal))
|
||||
// cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_04"), title: "Help Center".localized, type: .feedback, cellKey: .normal))
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_03"), title: "About Us".localized, type: .aboutUs, cellKey: .normal))
|
||||
|
||||
if VPLoginManager.manager.userInfo?.is_tourist == false {
|
||||
cellArr.append(VPMeItem(icon: UIImage(named: "me_item_icon_06"), title: "Delet Account".localized, type: .deleteAccount, cellKey: .normal))
|
||||
}
|
||||
|
||||
dataArr.append(cellArr)
|
||||
|
||||
|
||||
return dataArr
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ struct VPMeItem {
|
||||
case userAgreement
|
||||
case aboutUs
|
||||
case feedback
|
||||
case deleteAccount
|
||||
case informationProtection
|
||||
case civizatioConvention
|
||||
case informationSharing
|
||||
|
23
Veloria/Class/Me/View/VPDeleteAccountContentView.swift
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// VPDeleteAccountContentView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPDeleteAccountContentView: UIView {
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
backgroundColor = .color272A30()
|
||||
layer.cornerRadius = 8
|
||||
layer.masksToBounds = true
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
87
Veloria/Class/Me/View/VPDeleteAccountDetailView.swift
Normal file
@ -0,0 +1,87 @@
|
||||
//
|
||||
// VPDeleteAccountDetailView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPDeleteAccountDetailView: VPDeleteAccountContentView {
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF()
|
||||
label.numberOfLines = 0
|
||||
label.text = "DeleteAccount_tips_5".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var stackView: UIStackView = {
|
||||
let view = UIStackView(arrangedSubviews: [tipView1, tipView2, tipView3, tipView4])
|
||||
view.axis = .vertical
|
||||
view.spacing = 12
|
||||
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var tipView1: VPDeleteAccountTipView = {
|
||||
let view = VPDeleteAccountTipView()
|
||||
view.title = "DeleteAccount_tips_title_1".localized
|
||||
view.text = "DeleteAccount_tips_text_1".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var tipView2: VPDeleteAccountTipView = {
|
||||
let view = VPDeleteAccountTipView()
|
||||
view.title = "DeleteAccount_tips_title_2".localized
|
||||
view.text = "DeleteAccount_tips_text_2".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var tipView3: VPDeleteAccountTipView = {
|
||||
let view = VPDeleteAccountTipView()
|
||||
view.title = "DeleteAccount_tips_title_3".localized
|
||||
view.text = "DeleteAccount_tips_text_3".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var tipView4: VPDeleteAccountTipView = {
|
||||
let view = VPDeleteAccountTipView()
|
||||
view.title = "DeleteAccount_tips_title_4".localized
|
||||
// view.text = "DeleteAccount_tips_text_1".localized
|
||||
return view
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPDeleteAccountDetailView {
|
||||
|
||||
private func vp_setupUI() {
|
||||
addSubview(titleLabel)
|
||||
addSubview(stackView)
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(13)
|
||||
make.top.equalToSuperview().offset(12)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-13)
|
||||
}
|
||||
|
||||
stackView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview()
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(12)
|
||||
make.bottom.equalToSuperview().offset(-10)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
45
Veloria/Class/Me/View/VPDeleteAccountNormalView.swift
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// VPDeleteAccountNormalView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPDeleteAccountNormalView: VPDeleteAccountContentView {
|
||||
|
||||
var text: String? {
|
||||
didSet {
|
||||
let str = NSMutableAttributedString(string: text ?? "")
|
||||
str.lineSpacing = 4
|
||||
label.attributedText = str
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var label: UILabel = {
|
||||
let label = UILabel()
|
||||
label.numberOfLines = 0
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF()
|
||||
return label
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
addSubview(label)
|
||||
|
||||
label.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(12)
|
||||
make.centerY.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(12)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-12)
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
89
Veloria/Class/Me/View/VPDeleteAccountTipView.swift
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// VPDeleteAccountTipView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPDeleteAccountTipView: UIView {
|
||||
|
||||
var title: String? {
|
||||
didSet {
|
||||
titleLabel.text = title
|
||||
}
|
||||
}
|
||||
|
||||
var text: String? {
|
||||
didSet {
|
||||
let str = NSMutableAttributedString(string: text ?? "")
|
||||
str.lineSpacing = 4
|
||||
textLabel.attributedText = str
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var dotView: UIView = {
|
||||
let view = UIView()
|
||||
view.backgroundColor = .colorFFFFFF()
|
||||
view.layer.cornerRadius = 2
|
||||
view.layer.masksToBounds = true
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.textColor = .colorFFFFFF()
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var textLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.textColor = .color8B8B8B()
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension VPDeleteAccountTipView {
|
||||
|
||||
private func vp_setupUI() {
|
||||
addSubview(dotView)
|
||||
addSubview(titleLabel)
|
||||
addSubview(textLabel)
|
||||
|
||||
dotView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
make.centerY.equalTo(titleLabel)
|
||||
make.width.height.equalTo(4)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.top.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(24)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-24)
|
||||
}
|
||||
|
||||
textLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(titleLabel)
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(4)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-24)
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -50,9 +50,9 @@ class VPMeCoinCell: VPTableViewCell {
|
||||
extension VPMeCoinCell {
|
||||
|
||||
private func vp_setupUI() {
|
||||
addSubview(lineView)
|
||||
addSubview(coinView1)
|
||||
addSubview(coinView2)
|
||||
contentView.addSubview(lineView)
|
||||
contentView.addSubview(coinView1)
|
||||
contentView.addSubview(coinView2)
|
||||
|
||||
lineView.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
|
65
Veloria/Class/Me/View/VPMeFooterView.swift
Normal file
@ -0,0 +1,65 @@
|
||||
//
|
||||
// VPMeFooterView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPMeFooterView: UIView {
|
||||
|
||||
var userInfo: VPUserInfo? {
|
||||
didSet {
|
||||
button.isSelected = !(userInfo?.is_tourist ?? true)
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var button: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.layer.cornerRadius = 20
|
||||
button.layer.masksToBounds = true
|
||||
button.layer.borderColor = UIColor.color585858().cgColor
|
||||
button.layer.borderWidth = 1
|
||||
button.setTitle("Log In".localized, for: .normal)
|
||||
button.setTitle("Sign Out".localized, for: .selected)
|
||||
button.setTitle("Sign Out".localized, for: [.selected, .highlighted])
|
||||
button.setTitleColor(.colorB3B3B3(), for: .normal)
|
||||
button.titleLabel?.font = .fontRegular(ofSize: 14)
|
||||
button.addTarget(self, action: #selector(handleButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
addSubview(button)
|
||||
|
||||
button.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(15)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(20)
|
||||
make.height.equalTo(40)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func handleButton() {
|
||||
|
||||
if userInfo?.is_tourist == true {
|
||||
let view = VPLoginContentView()
|
||||
view.present(in: nil)
|
||||
} else {
|
||||
let alert = VPAlertView(title: "kLogoutAlertTitle".localized, subtitle: "kLogoutAlertText".localized, icon: UIImage(named: "alert_icon_02"), normalButtonText: "Log Out".localized, highlightButtonText: "Cancel".localized).show()
|
||||
alert.clickNormalButton = {
|
||||
VPLoginManager.manager.logout(completer: nil)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -21,6 +21,9 @@ class VPMeUserInfoCell: VPTableViewCell {
|
||||
}
|
||||
|
||||
idLabel.text = "ID \(userInfo?.customer_id ?? "")"
|
||||
|
||||
loginButton.isHidden = !(userInfo?.is_tourist ?? true)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +50,28 @@ class VPMeUserInfoCell: VPTableViewCell {
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var loginButton: VPGradientButton = {
|
||||
let title = AttributedString.createAttributedString(string: "Check in".localized, color: .colorFFFFFF(), font: .fontRegular(ofSize: 12))
|
||||
|
||||
var config = UIButton.Configuration.plain()
|
||||
config.imagePlacement = .leading
|
||||
config.imagePadding = 6
|
||||
config.image = UIImage(named: "login_icon_01")
|
||||
config.attributedTitle = title
|
||||
config.contentInsets = .init(top: 0, leading: 12, bottom: 0, trailing: 12)
|
||||
|
||||
let button = VPGradientButton(configuration: config)
|
||||
button.colors = [UIColor.color05CEA0(alpha: 0.3).cgColor, UIColor.color7C174F(alpha: 0.3).cgColor]
|
||||
button.locations = [0, 1]
|
||||
button.startPoint = .init(x: 0, y: 0.3)
|
||||
button.endPoint = .init(x: 1, y: 0.8)
|
||||
button.layer.cornerRadius = 17
|
||||
button.layer.masksToBounds = true
|
||||
button.bt_setGradientBorder()
|
||||
button.addTarget(self, action: #selector(handleLoginButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
@ -57,6 +82,11 @@ class VPMeUserInfoCell: VPTableViewCell {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc private func handleLoginButton() {
|
||||
let view = VPLoginContentView()
|
||||
view.present(in: nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPMeUserInfoCell {
|
||||
@ -65,6 +95,7 @@ extension VPMeUserInfoCell {
|
||||
contentView.addSubview(avatarImageView)
|
||||
contentView.addSubview(nicknameLabel)
|
||||
contentView.addSubview(idLabel)
|
||||
contentView.addSubview(loginButton)
|
||||
|
||||
avatarImageView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview()
|
||||
@ -84,6 +115,12 @@ extension VPMeUserInfoCell {
|
||||
make.bottom.equalTo(avatarImageView).offset(-3)
|
||||
}
|
||||
|
||||
loginButton.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(avatarImageView)
|
||||
make.right.equalToSuperview()
|
||||
make.height.equalTo(34)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
206
Veloria/Libs/Alert/VPAlertView.swift
Normal file
@ -0,0 +1,206 @@
|
||||
//
|
||||
// VPAlertView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPAlertView: VPBaseAlertView {
|
||||
|
||||
var clickNormalButton: (() -> Void)?
|
||||
var clickHighlightButton: (() -> Void)?
|
||||
|
||||
|
||||
private lazy var bgView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "alert_bg_image_01"))
|
||||
imageView.backgroundColor = .colorFFFFFF()
|
||||
imageView.layer.cornerRadius = 18
|
||||
imageView.layer.masksToBounds = true
|
||||
imageView.isUserInteractionEnabled = true
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var iconImageView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var titleIconImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "alert_title_icon_01"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var titleLabel: VPGradientLabel = {
|
||||
let label = VPGradientLabel()
|
||||
label.gradientLayer.colors = [UIColor.color126B4E().cgColor, UIColor.color1A2D22().cgColor]
|
||||
label.gradientLayer.startPoint = .init(x: 0.5, y: 0)
|
||||
label.gradientLayer.endPoint = .init(x: 0.5, y: 1)
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var textLabel: VPGradientLabel = {
|
||||
let label = VPGradientLabel()
|
||||
label.gradientLayer.colors = [UIColor.color126B4E().cgColor, UIColor.color1A2D22().cgColor]
|
||||
label.gradientLayer.startPoint = .init(x: 0.5, y: 0)
|
||||
label.gradientLayer.endPoint = .init(x: 0.5, y: 1)
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var normalButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setTitleColor(.colorC8C8C8(), for: .normal)
|
||||
button.titleLabel?.font = .fontMedium(ofSize: 14)
|
||||
button.layer.cornerRadius = 24
|
||||
button.layer.masksToBounds = true
|
||||
button.layer.borderWidth = 1
|
||||
button.layer.borderColor = UIColor.colorC8C8C8().cgColor
|
||||
button.addTarget(self, action: #selector(handleNormalButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var highlightButton: UIButton = {
|
||||
let button = VPGradientButton(type: .custom)
|
||||
button.setTitleColor(.colorFFFFFF(), for: .normal)
|
||||
button.titleLabel?.font = .fontMedium(ofSize: 14)
|
||||
button.locations = [0, 1]
|
||||
button.startPoint = .init(x: 0, y: 0.3)
|
||||
button.endPoint = .init(x: 1, y: 0.8)
|
||||
button.colors = [UIColor.color05CEA0().cgColor, UIColor.color7C174F().cgColor]
|
||||
button.layer.cornerRadius = 24
|
||||
button.layer.borderWidth = 1.5
|
||||
button.layer.borderColor = UIColor.colorFFFFFF().cgColor
|
||||
button.layer.shadowColor = UIColor.color024E3D(alpha: 0.4).cgColor
|
||||
button.layer.shadowOpacity = 1
|
||||
button.layer.shadowOffset = .init(width: 0, height: 4)
|
||||
button.addTarget(self, action: #selector(handleHighlightButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var buttonStackView: UIStackView = {
|
||||
let view = UIStackView()
|
||||
view.axis = .horizontal
|
||||
view.spacing = 10
|
||||
view.alignment = .fill
|
||||
view.distribution = .fillEqually
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var closeButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "close_icon_02"), for: .normal)
|
||||
button.addTarget(self, action: #selector(dismiss), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
|
||||
init(title: String, subtitle: String, icon: UIImage?, normalButtonText: String?, highlightButtonText: String?) {
|
||||
super.init(frame: UIScreen.main.bounds)
|
||||
iconImageView.image = icon
|
||||
|
||||
let titleStr = NSMutableAttributedString(string: title)
|
||||
titleStr.lineSpacing = 4
|
||||
titleStr.font = .fontMedium(ofSize: 20)
|
||||
titleLabel.attributedText = titleStr
|
||||
|
||||
let textStr = NSMutableAttributedString(string: subtitle)
|
||||
textStr.lineSpacing = 4
|
||||
textStr.font = .fontRegular(ofSize: 15)
|
||||
textLabel.attributedText = textStr
|
||||
|
||||
normalButton.setTitle(normalButtonText, for: .normal)
|
||||
highlightButton.setTitle(highlightButtonText, for: .normal)
|
||||
|
||||
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPAlertView {
|
||||
|
||||
@objc private func handleHighlightButton() {
|
||||
self.clickHighlightButton?()
|
||||
self.dismiss()
|
||||
}
|
||||
|
||||
@objc private func handleNormalButton() {
|
||||
self.clickNormalButton?()
|
||||
self.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
extension VPAlertView {
|
||||
|
||||
private func vp_setupUI() {
|
||||
contentView.addSubview(bgView)
|
||||
contentView.addSubview(iconImageView)
|
||||
bgView.addSubview(titleLabel)
|
||||
bgView.addSubview(titleIconImageView)
|
||||
bgView.addSubview(textLabel)
|
||||
bgView.addSubview(buttonStackView)
|
||||
contentView.addSubview(closeButton)
|
||||
|
||||
bgView.snp.makeConstraints { make in
|
||||
make.left.right.top.equalToSuperview()
|
||||
make.height.equalTo(290)
|
||||
make.width.equalTo(UIScreen.width - 70)
|
||||
make.bottom.equalToSuperview().offset(-50)
|
||||
}
|
||||
|
||||
iconImageView.snp.makeConstraints { make in
|
||||
make.top.equalToSuperview().offset(-43)
|
||||
make.right.equalToSuperview()
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(33)
|
||||
make.top.equalToSuperview().offset(36)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-100)
|
||||
}
|
||||
|
||||
titleIconImageView.snp.makeConstraints { make in
|
||||
make.left.equalTo(titleLabel).offset(-13)
|
||||
make.top.equalTo(titleLabel).offset(-8)
|
||||
}
|
||||
|
||||
textLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(33)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-33)
|
||||
make.centerY.equalTo(bgView.snp.top).offset(150)
|
||||
}
|
||||
|
||||
buttonStackView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(10)
|
||||
make.centerX.equalToSuperview()
|
||||
make.bottom.equalToSuperview().offset(-30)
|
||||
make.height.equalTo(48)
|
||||
}
|
||||
|
||||
closeButton.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
var buttons: [UIButton] = []
|
||||
|
||||
if let title = normalButton.title(for: .normal), title.count > 0 {
|
||||
buttons.append(normalButton)
|
||||
}
|
||||
if let title = highlightButton.title(for: .normal), title.count > 0 {
|
||||
buttons.append(highlightButton)
|
||||
}
|
||||
|
||||
buttons.forEach {
|
||||
buttonStackView.addArrangedSubview($0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
44
Veloria/Libs/Alert/VPAlertWindowManager.swift
Normal file
@ -0,0 +1,44 @@
|
||||
//
|
||||
// VPAlertWindowManager.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPAlertWindowManager {
|
||||
|
||||
static let manager = VPAlertWindowManager()
|
||||
|
||||
private var window: UIWindow?
|
||||
|
||||
private var count = 0
|
||||
|
||||
func createWindow() -> UIWindow {
|
||||
count += 1
|
||||
guard let window = window else {
|
||||
let window = UIWindow(windowScene: VPAppTool.windowScene!)
|
||||
window.backgroundColor = .clear
|
||||
window.windowLevel = .alert
|
||||
window.isHidden = false
|
||||
self.window = window
|
||||
return window
|
||||
}
|
||||
return window
|
||||
}
|
||||
|
||||
func dismissWindow() {
|
||||
// count -= 1
|
||||
guard let window = self.window else { return }
|
||||
if window.subviews.count <= 0 {
|
||||
window.isHidden = true
|
||||
self.window = nil
|
||||
}
|
||||
|
||||
// if count == 0 {
|
||||
// window?.isHidden = true
|
||||
// window = nil
|
||||
// }
|
||||
}
|
||||
}
|
67
Veloria/Libs/Alert/VPBaseAlertView.swift
Normal file
@ -0,0 +1,67 @@
|
||||
//
|
||||
// VPBaseAlertView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/4.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPBaseAlertView: UIView {
|
||||
|
||||
|
||||
private(set) var contentView: UIView = {
|
||||
let view = UIView()
|
||||
return view
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
backgroundColor = .color000000(alpha: 0.5)
|
||||
|
||||
addSubview(contentView)
|
||||
contentView.snp.makeConstraints { make in
|
||||
make.center.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
@objc func show(in view: UIView? = nil) -> Self {
|
||||
var inView: UIView
|
||||
if let view = view {
|
||||
inView = view
|
||||
} else {
|
||||
inView = VPAlertWindowManager.manager.createWindow()
|
||||
}
|
||||
|
||||
inView.addSubview(self)
|
||||
self.frame = inView.bounds
|
||||
creatShowAnimation()
|
||||
|
||||
return self
|
||||
}
|
||||
@objc func dismiss() {
|
||||
removeFromSuperview()
|
||||
VPAlertWindowManager.manager.dismissWindow()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPBaseAlertView {
|
||||
|
||||
private func creatShowAnimation() {
|
||||
contentView.layer.position = center
|
||||
contentView.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
|
||||
UIView.animate(withDuration: 0.2, animations: {
|
||||
self.contentView.transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
|
||||
}) { finished in
|
||||
UIView.animate(withDuration: 0.1, animations: {
|
||||
self.contentView.transform = CGAffineTransform.identity
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
112
Veloria/Libs/Login/VPLoginManager+Apple.swift
Normal file
@ -0,0 +1,112 @@
|
||||
//
|
||||
// VPLoginManager+Apple.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/3.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import AuthenticationServices
|
||||
|
||||
extension VPLoginManager {
|
||||
|
||||
private struct AssociatedKeys {
|
||||
static var signAppleHandle: Int?
|
||||
}
|
||||
|
||||
private var signAppleHandle: ((_ model: VPThirdSignModel?) -> Void)? {
|
||||
set {
|
||||
objc_setAssociatedObject(self, &AssociatedKeys.signAppleHandle, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
|
||||
}
|
||||
get {
|
||||
return objc_getAssociatedObject(self, &AssociatedKeys.signAppleHandle) as? ((_ model: VPThirdSignModel?) -> Void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///苹果登录
|
||||
func appleSignLogin(completer: ((_ model: VPThirdSignModel?) -> Void)?) {
|
||||
self.signAppleHandle = completer
|
||||
|
||||
let appleIDProvider = ASAuthorizationAppleIDProvider()
|
||||
let request = appleIDProvider.createRequest()
|
||||
request.requestedScopes = [.fullName, .email]
|
||||
|
||||
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
|
||||
authorizationController.delegate = self
|
||||
authorizationController.presentationContextProvider = self
|
||||
authorizationController.performRequests()
|
||||
}
|
||||
}
|
||||
|
||||
//MARK:-------------- ASAuthorizationControllerDelegate --------------
|
||||
extension VPLoginManager: ASAuthorizationControllerDelegate {
|
||||
|
||||
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
|
||||
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
|
||||
|
||||
let userIdentifier = appleIDCredential.user
|
||||
let fullName = appleIDCredential.fullName
|
||||
let email = appleIDCredential.email
|
||||
|
||||
let identityToken = appleIDCredential.identityToken.flatMap { String(data: $0, encoding: .utf8) }
|
||||
let identityTokenParams = self.jwtDecode(jwtStr: identityToken ?? "")
|
||||
|
||||
|
||||
let model = VPThirdSignModel()
|
||||
model.platform = .apple
|
||||
model.third_id = userIdentifier
|
||||
model.giving_name = fullName?.givenName
|
||||
model.family_name = fullName?.familyName
|
||||
model.avator = identityTokenParams?["picture"] as? String
|
||||
model.email = identityTokenParams?["email"] as? String
|
||||
|
||||
signAppleHandle?(model)
|
||||
}
|
||||
}
|
||||
|
||||
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
|
||||
signAppleHandle?(nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPLoginManager: ASAuthorizationControllerPresentationContextProviding {
|
||||
|
||||
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
|
||||
return VPAppTool.keyWindow!
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPLoginManager {
|
||||
|
||||
private func jwtDecode(jwtStr: String) -> [String: Any]? {
|
||||
let segments = jwtStr.components(separatedBy: ".")
|
||||
guard segments.count > 1 else { return nil }
|
||||
|
||||
var base64String = segments[1]
|
||||
|
||||
// 处理 Base64 补齐
|
||||
let requiredLength = 4 * Int(ceil(Double(base64String.count) / 4.0))
|
||||
let paddingLength = requiredLength - base64String.count
|
||||
if paddingLength > 0 {
|
||||
base64String += String(repeating: "=", count: paddingLength)
|
||||
}
|
||||
|
||||
// 替换 URL 安全字符
|
||||
base64String = base64String.replacingOccurrences(of: "-", with: "+")
|
||||
base64String = base64String.replacingOccurrences(of: "_", with: "/")
|
||||
|
||||
// 解码 Base64 数据
|
||||
guard let data = Data(base64Encoded: base64String),
|
||||
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
|
||||
let payload = jsonObject as? [String: Any] else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return payload
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,9 +6,17 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class VPLoginManager: NSObject {
|
||||
|
||||
enum LoginType: String, SmartCaseDefaultable {
|
||||
case apple = "Apple"
|
||||
case faceBook = "Facebook"
|
||||
case google = "Google"
|
||||
case tiktok = "Tiktok"
|
||||
}
|
||||
|
||||
|
||||
static let manager = VPLoginManager()
|
||||
|
||||
@ -30,6 +38,52 @@ class VPLoginManager: NSObject {
|
||||
UserDefaults.vp_setObject(token, forKey: kVPLoginTokenDefaultsKey)
|
||||
}
|
||||
|
||||
func login(type: LoginType, presentingViewController: UIViewController?, completer: ((_ isFinish: Bool) -> Void)?) {
|
||||
|
||||
switch type {
|
||||
case .apple:
|
||||
appleSignLogin { [weak self] model in
|
||||
self?.requestThirdLogin(thirdSignModel: model, completer: completer)
|
||||
}
|
||||
default: break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///退出登录
|
||||
func logout(completer: ((_ isFinish: Bool) -> Void)?) {
|
||||
VPUserAPI.requestLogout { [weak self] token in
|
||||
guard let self = self else { return }
|
||||
if let token = token {
|
||||
self.setLoginToken(token: token)
|
||||
self.userInfo?.is_tourist = true
|
||||
self.updateUserInfo(completer: nil)
|
||||
completer?(true)
|
||||
NotificationCenter.default.post(name: VPLoginManager.userInfoUpdateNotification, object: nil)
|
||||
NotificationCenter.default.post(name: VPLoginManager.loginStateDidChangeNotification, object: nil)
|
||||
} else {
|
||||
completer?(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///删除账号
|
||||
func deleteAccount(completer: ((_ isFinish: Bool) -> Void)?) {
|
||||
VPUserAPI.requestDelete { [weak self] isFinish in
|
||||
guard let self = self else { return }
|
||||
if isFinish {
|
||||
self.setLoginToken(token: nil)
|
||||
self.userInfo?.is_tourist = true
|
||||
self.updateUserInfo(completer: nil)
|
||||
completer?(true)
|
||||
NotificationCenter.default.post(name: VPLoginManager.userInfoUpdateNotification, object: nil)
|
||||
NotificationCenter.default.post(name: VPLoginManager.loginStateDidChangeNotification, object: nil)
|
||||
} else {
|
||||
completer?(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///更新用户信息
|
||||
func updateUserInfo(completer: (() -> Void)?) {
|
||||
@ -39,9 +93,47 @@ class VPLoginManager: NSObject {
|
||||
if let userInfo = userInfo {
|
||||
self.userInfo = userInfo
|
||||
UserDefaults.vp_setObject(userInfo, forKey: kVPLoginUserInfoDefaultsKey)
|
||||
NotificationCenter.default.post(name: VPLoginManager.userInfoUpdateNotification, object: nil)
|
||||
}
|
||||
completer?()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension VPLoginManager {
|
||||
|
||||
///请求第三方登录
|
||||
private func requestThirdLogin(thirdSignModel: VPThirdSignModel?, completer: ((_ isFinish: Bool) -> Void)?) {
|
||||
guard let thirdSignModel = thirdSignModel else {
|
||||
completer?(false)
|
||||
return
|
||||
}
|
||||
|
||||
VPUserAPI.requestThirdLogin(model: thirdSignModel) { [weak self] token in
|
||||
guard let self = self else { return }
|
||||
guard let token = token else {
|
||||
completer?(false)
|
||||
return
|
||||
}
|
||||
self.setLoginToken(token: token)
|
||||
self.userInfo?.is_tourist = false
|
||||
self.updateUserInfo(completer: nil)
|
||||
completer?(true)
|
||||
NotificationCenter.default.post(name: VPLoginManager.userInfoUpdateNotification, object: nil)
|
||||
NotificationCenter.default.post(name: VPLoginManager.loginStateDidChangeNotification, object: nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPLoginManager {
|
||||
|
||||
///登录状态发生变化
|
||||
@objc static let loginStateDidChangeNotification = NSNotification.Name(rawValue: "VPLoginManager.loginStateDidChangeNotification")
|
||||
///用户信息更新
|
||||
@objc static let userInfoUpdateNotification = NSNotification.Name(rawValue: "VPLoginManager.userInfoUpdateNotification")
|
||||
|
||||
}
|
||||
|
||||
|
24
Veloria/Libs/Login/VPThirdSignModel.swift
Normal file
@ -0,0 +1,24 @@
|
||||
//
|
||||
// VPThirdSignModel.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/3.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class VPThirdSignModel: VPModel, SmartCodable {
|
||||
|
||||
var third_id: String?
|
||||
var email: String?
|
||||
|
||||
//姓
|
||||
var family_name: String?
|
||||
//名
|
||||
var giving_name: String?
|
||||
|
||||
var avator: String?
|
||||
|
||||
var platform: VPLoginManager.LoginType?
|
||||
}
|
22
Veloria/Source/Assets.xcassets/icon/alert_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "提示1 1@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "提示1 1@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/alert_icon_01.imageset/提示1 1@2x.png
vendored
Normal file
After Width: | Height: | Size: 77 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/alert_icon_01.imageset/提示1 1@3x.png
vendored
Normal file
After Width: | Height: | Size: 162 KiB |
22
Veloria/Source/Assets.xcassets/icon/alert_icon_02.imageset/Contents.json
vendored
Normal file
@ -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
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/alert_icon_02.imageset/通知图标-切图图层@2x.png
vendored
Normal file
After Width: | Height: | Size: 44 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/alert_icon_02.imageset/通知图标-切图图层@3x.png
vendored
Normal file
After Width: | Height: | Size: 90 KiB |
22
Veloria/Source/Assets.xcassets/icon/alert_title_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame 6@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame 6@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/alert_title_icon_01.imageset/Frame 6@2x.png
vendored
Normal file
After Width: | Height: | Size: 664 B |
BIN
Veloria/Source/Assets.xcassets/icon/alert_title_icon_01.imageset/Frame 6@3x.png
vendored
Normal file
After Width: | Height: | Size: 932 B |
BIN
Veloria/Source/Assets.xcassets/icon/apple_icon_01.imageset/Apple@2x.png
vendored
Normal file
After Width: | Height: | Size: 508 B |
BIN
Veloria/Source/Assets.xcassets/icon/apple_icon_01.imageset/Apple@3x.png
vendored
Normal file
After Width: | Height: | Size: 741 B |
22
Veloria/Source/Assets.xcassets/icon/apple_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Apple@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Apple@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 16 KiB |
@ -5,12 +5,12 @@
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "未选中@2x.png",
|
||||
"filename" : "Ellipse 45@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "未选中@3x.png",
|
||||
"filename" : "Ellipse 45@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
|
BIN
Veloria/Source/Assets.xcassets/icon/choice_icon_01.imageset/Ellipse 45@2x.png
vendored
Normal file
After Width: | Height: | Size: 580 B |
BIN
Veloria/Source/Assets.xcassets/icon/choice_icon_01.imageset/Ellipse 45@3x.png
vendored
Normal file
After Width: | Height: | Size: 897 B |
Before Width: | Height: | Size: 958 B |
Before Width: | Height: | Size: 1.4 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/close_icon_02.imageset/Close.png
vendored
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/close_icon_02.imageset/Close@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.1 KiB |
22
Veloria/Source/Assets.xcassets/icon/close_icon_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Close.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Close@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
22
Veloria/Source/Assets.xcassets/icon/login_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame 74@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame 74@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/login_icon_01.imageset/Frame 74@2x.png
vendored
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/login_icon_01.imageset/Frame 74@3x.png
vendored
Normal file
After Width: | Height: | Size: 5.8 KiB |
22
Veloria/Source/Assets.xcassets/icon/me_item_icon_06.imageset/Contents.json
vendored
Normal 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
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/me_item_icon_06.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 440 B |
BIN
Veloria/Source/Assets.xcassets/icon/me_item_icon_06.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 623 B |
22
Veloria/Source/Assets.xcassets/icon/warning_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Vector@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Vector@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/warning_icon_01.imageset/Vector@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/warning_icon_01.imageset/Vector@3x.png
vendored
Normal file
After Width: | Height: | Size: 2.8 KiB |
22
Veloria/Source/Assets.xcassets/image/alert_bg_image_01.imageset/Contents.json
vendored
Normal 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
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/image/alert_bg_image_01.imageset/bg装饰@2x.png
vendored
Normal file
After Width: | Height: | Size: 305 KiB |
BIN
Veloria/Source/Assets.xcassets/image/alert_bg_image_01.imageset/bg装饰@3x.png
vendored
Normal file
After Width: | Height: | Size: 666 KiB |
@ -6,6 +6,8 @@
|
||||
|
||||
*/
|
||||
|
||||
"kAppName" = "Veloria";
|
||||
|
||||
"Home" = "Home";
|
||||
"Me" = "Me";
|
||||
"All" = "All";
|
||||
@ -64,6 +66,17 @@
|
||||
"Recharge" = "Recharge";
|
||||
"Unlocking costs %@ coins" = "Unlocking costs %@ coins";
|
||||
"Balance: %@ Coins | %@ Bonus" = "Balance: %@ Coins | %@ Bonus";
|
||||
"Check in" = "Check in";
|
||||
"Welcome to %@" = "Welcome to %@";
|
||||
"Login with Apple" = "Login with Apple";
|
||||
"Log In" = "Log In";
|
||||
"Sign Out" = "Sign Out";
|
||||
"Delet Account" = "Delet Account";
|
||||
"Account Deletion" = "Account Deletion";
|
||||
"Delete Account" = "Delete Account";
|
||||
"Delete Forever" = "Delete Forever";
|
||||
"Cancel" = "Cancel";
|
||||
"Log Out" = "Log Out";
|
||||
|
||||
|
||||
"kHomeTitleText" = "10,000+ addictive shorts await!";
|
||||
@ -77,6 +90,7 @@
|
||||
"kVipPrivilegeText4" = "Unlimited access to all series for %@ (No Ads)";
|
||||
"kVipPrivilegeText5" = "The donate coins will expire in %@";
|
||||
"kVipPrivilegeText6" = "Auto renew, cancel anytime";
|
||||
"kLoginAgreementText" = "By logging in you agree to: %@ & %@";
|
||||
//无网提示
|
||||
"kNetworkToast01" = "The service is abnormal. Check the network.";
|
||||
//解锁上一集提示
|
||||
@ -85,6 +99,7 @@
|
||||
"kLockFailText" = "Purchase failed, please try again later!";
|
||||
|
||||
|
||||
|
||||
"kStoreTips" = "1. Coins are virtual items and cannot be refunded. Use it for this product.
|
||||
2. Gold coins will never expire, the reward coins will expire 24 hours a day.
|
||||
3. Coins will be used first when unlocking episodes. If the amount is insufficient, reward coins will automatically be used.
|
||||
@ -93,3 +108,21 @@
|
||||
|
||||
//请选择需要删除的短剧
|
||||
"kToastText1" = "Please select the short plays that need to be deleted";
|
||||
|
||||
"kDeleteAccountAlertTitle" = "Confirm Account Deletion";
|
||||
"kDeleteAccountAlertText" = "This action cannot be undone.";
|
||||
"kLogoutAlertTitle" = "Ready to Leave?";
|
||||
"kLogoutAlertText" = "when you sign out, your watch history will not be synced to your account.";
|
||||
|
||||
"DeleteAccount_tips_1" = "Your account will be permanently deleted";
|
||||
"DeleteAccount_tips_2" = "You will not be able to log in with this user ID";
|
||||
"DeleteAccount_tips_3" = "Please log out of the account on other devices in time, otherwise the App on other devices will be unavailable.";
|
||||
"DeleteAccount_tips_4" = "I accept the deletion risk and agree to delete my account";
|
||||
"DeleteAccount_tips_5" = "All the following information will be deleted";
|
||||
"DeleteAccount_tips_title_1" = "Account Data";
|
||||
"DeleteAccount_tips_text_1" = "All your personal data will be deleted including username、Email address.";
|
||||
"DeleteAccount_tips_title_2" = "Balance&VIP";
|
||||
"DeleteAccount_tips_text_2" = "All your coins have been consumed and you can delete your account.";
|
||||
"DeleteAccount_tips_title_3" = "History";
|
||||
"DeleteAccount_tips_text_3" = "Consumption History, Recharge History, Chapter Unlock History, My Favorite.";
|
||||
"DeleteAccount_tips_title_4" = "Third Party Account Information";
|
||||
|
10
Veloria/Veloria.entitlements
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.developer.applesignin</key>
|
||||
<array>
|
||||
<string>Default</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|