我的页面
11
Podfile
@ -16,17 +16,20 @@ target 'Veloria' do
|
||||
|
||||
use_frameworks!
|
||||
|
||||
pod 'SVProgressHUD' #HUD
|
||||
pod 'Moya' #网络框架
|
||||
pod 'SnapKit' #布局
|
||||
pod 'SmartCodable' #数据解析
|
||||
pod 'YYKit' #工具类
|
||||
pod 'MJRefresh' #刷新控件
|
||||
pod 'SnapKit' #布局
|
||||
pod 'Toast' #吐司提示
|
||||
pod 'ZFPlayer/AVPlayer' #播放器
|
||||
pod 'KTVHTTPCache' #视频缓存
|
||||
pod 'HWPanModal' #底部弹出控制器
|
||||
pod 'Kingfisher' #图片加载
|
||||
pod 'HWPanModal' #底部弹出控制器
|
||||
pod "ESTabBarController-swift"
|
||||
pod 'WMZPageController' #分页控制器
|
||||
|
||||
pod 'ZFPlayer/AVPlayer' #播放器
|
||||
pod 'EmptyDataSet-Swift' #空数据页面
|
||||
|
||||
|
||||
end
|
||||
|
12
Podfile.lock
@ -1,6 +1,7 @@
|
||||
PODS:
|
||||
- Alamofire (5.10.2)
|
||||
- CocoaAsyncSocket (7.6.5)
|
||||
- EmptyDataSet-Swift (5.0.0)
|
||||
- ESTabBarController-swift (2.8.0)
|
||||
- HWPanModal (0.9.9)
|
||||
- Kingfisher (8.3.2)
|
||||
@ -15,6 +16,9 @@ PODS:
|
||||
- SmartCodable/Core (= 5.0.9)
|
||||
- SmartCodable/Core (5.0.9)
|
||||
- SnapKit (5.7.1)
|
||||
- SVProgressHUD (2.3.1):
|
||||
- SVProgressHUD/Core (= 2.3.1)
|
||||
- SVProgressHUD/Core (2.3.1)
|
||||
- Toast (4.1.1)
|
||||
- WMZPageController (1.5.5)
|
||||
- YYKit (1.0.9):
|
||||
@ -25,6 +29,7 @@ PODS:
|
||||
- ZFPlayer/Core (4.1.4)
|
||||
|
||||
DEPENDENCIES:
|
||||
- EmptyDataSet-Swift
|
||||
- ESTabBarController-swift
|
||||
- HWPanModal
|
||||
- Kingfisher
|
||||
@ -33,6 +38,7 @@ DEPENDENCIES:
|
||||
- Moya
|
||||
- SmartCodable
|
||||
- SnapKit
|
||||
- SVProgressHUD
|
||||
- Toast
|
||||
- WMZPageController
|
||||
- YYKit
|
||||
@ -42,6 +48,7 @@ SPEC REPOS:
|
||||
trunk:
|
||||
- Alamofire
|
||||
- CocoaAsyncSocket
|
||||
- EmptyDataSet-Swift
|
||||
- ESTabBarController-swift
|
||||
- HWPanModal
|
||||
- Kingfisher
|
||||
@ -50,6 +57,7 @@ SPEC REPOS:
|
||||
- Moya
|
||||
- SmartCodable
|
||||
- SnapKit
|
||||
- SVProgressHUD
|
||||
- Toast
|
||||
- WMZPageController
|
||||
- YYKit
|
||||
@ -58,6 +66,7 @@ SPEC REPOS:
|
||||
SPEC CHECKSUMS:
|
||||
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||
EmptyDataSet-Swift: eb382c0c87a2d9c678077385a595cec52da38171
|
||||
ESTabBarController-swift: 05593a6ad64700b03c0eb60ff625916370aa4136
|
||||
HWPanModal: b57a6717d3cdcd666bff44f9dd2a5be9f4d6f5d2
|
||||
Kingfisher: 0621d0ac0c78fecb19f6dc5303bde2b52abaf2f5
|
||||
@ -66,11 +75,12 @@ SPEC CHECKSUMS:
|
||||
Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee
|
||||
SmartCodable: 68b3598438181a938eed8ee5623e58ef3e3ea443
|
||||
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
|
||||
SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
|
||||
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
|
||||
WMZPageController: 87dd82d1e3528cd362de19b9a74fd6890d6e1906
|
||||
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
|
||||
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
|
||||
|
||||
PODFILE CHECKSUM: e5cac55fd92698becba7d142dc17ec724cd6313f
|
||||
PODFILE CHECKSUM: 5a8b71939b2bf65623c166084b1e01d877b2979d
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
|
@ -119,6 +119,21 @@
|
||||
BF0FA7A12DE1AA5100C9E5F2 /* VPTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7A02DE1AA5100C9E5F2 /* VPTableView.swift */; };
|
||||
BF0FA7A32DE1AB1800C9E5F2 /* VPWatchHistoryCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7A22DE1AB1800C9E5F2 /* VPWatchHistoryCell.swift */; };
|
||||
BF0FA7A52DE4384100C9E5F2 /* AttributedString+VPAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7A42DE4384100C9E5F2 /* AttributedString+VPAdd.swift */; };
|
||||
BF0FA7AF2DE443E000C9E5F2 /* VPMeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7AE2DE443E000C9E5F2 /* VPMeViewController.swift */; };
|
||||
BF0FA7B12DE447EB00C9E5F2 /* VPMeItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7B02DE447EB00C9E5F2 /* VPMeItem.swift */; };
|
||||
BF0FA7B32DE447FE00C9E5F2 /* VPMeCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7B22DE447FE00C9E5F2 /* VPMeCell.swift */; };
|
||||
BF0FA7B62DE44E8000C9E5F2 /* VPWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7B52DE44E8000C9E5F2 /* VPWebView.swift */; };
|
||||
BF0FA7B82DE44FCC00C9E5F2 /* VPWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7B72DE44FCC00C9E5F2 /* VPWebViewController.swift */; };
|
||||
BF0FA7BA2DE451B900C9E5F2 /* UINavigationBar+VPAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7B92DE451B000C9E5F2 /* UINavigationBar+VPAdd.swift */; };
|
||||
BF0FA7BC2DE4563300C9E5F2 /* VPMeUserInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7BB2DE4563300C9E5F2 /* VPMeUserInfoCell.swift */; };
|
||||
BF0FA7BE2DE4592A00C9E5F2 /* UserDefaults+VPAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7BD2DE4591B00C9E5F2 /* UserDefaults+VPAdd.swift */; };
|
||||
BF0FA7C12DE45D5D00C9E5F2 /* VPUserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7C02DE45D5D00C9E5F2 /* VPUserInfo.swift */; };
|
||||
BF0FA7C32DE45DE300C9E5F2 /* VPUserAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0FA7C22DE45DE300C9E5F2 /* VPUserAPI.swift */; };
|
||||
BF5E75AF2DE4632200DE9DFE /* VPAboutUsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75AE2DE4632200DE9DFE /* VPAboutUsViewController.swift */; };
|
||||
BF5E75B12DE4656600DE9DFE /* VPCampaignWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75B02DE4656600DE9DFE /* VPCampaignWebViewController.swift */; };
|
||||
BF5E75B32DE465EC00DE9DFE /* Dictionary+SPAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75B22DE465EA00DE9DFE /* Dictionary+SPAdd.swift */; };
|
||||
BF5E75B62DE46DB600DE9DFE /* UIScrollView+Empty.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75B52DE46DB600DE9DFE /* UIScrollView+Empty.swift */; };
|
||||
BF5E75B82DE46F7100DE9DFE /* VPNetworkReachabilityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75B72DE46F7100DE9DFE /* VPNetworkReachabilityManager.swift */; };
|
||||
F939C04AD4003BA127F15C28 /* Pods_Veloria.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 34F57E87E765BF8D72A43DCA /* Pods_Veloria.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -244,6 +259,21 @@
|
||||
BF0FA7A02DE1AA5100C9E5F2 /* VPTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPTableView.swift; sourceTree = "<group>"; };
|
||||
BF0FA7A22DE1AB1800C9E5F2 /* VPWatchHistoryCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPWatchHistoryCell.swift; sourceTree = "<group>"; };
|
||||
BF0FA7A42DE4384100C9E5F2 /* AttributedString+VPAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttributedString+VPAdd.swift"; sourceTree = "<group>"; };
|
||||
BF0FA7AE2DE443E000C9E5F2 /* VPMeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeViewController.swift; sourceTree = "<group>"; };
|
||||
BF0FA7B02DE447EB00C9E5F2 /* VPMeItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeItem.swift; sourceTree = "<group>"; };
|
||||
BF0FA7B22DE447FE00C9E5F2 /* VPMeCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeCell.swift; sourceTree = "<group>"; };
|
||||
BF0FA7B52DE44E8000C9E5F2 /* VPWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPWebView.swift; sourceTree = "<group>"; };
|
||||
BF0FA7B72DE44FCC00C9E5F2 /* VPWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPWebViewController.swift; sourceTree = "<group>"; };
|
||||
BF0FA7B92DE451B000C9E5F2 /* UINavigationBar+VPAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationBar+VPAdd.swift"; sourceTree = "<group>"; };
|
||||
BF0FA7BB2DE4563300C9E5F2 /* VPMeUserInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeUserInfoCell.swift; sourceTree = "<group>"; };
|
||||
BF0FA7BD2DE4591B00C9E5F2 /* UserDefaults+VPAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserDefaults+VPAdd.swift"; sourceTree = "<group>"; };
|
||||
BF0FA7C02DE45D5D00C9E5F2 /* VPUserInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPUserInfo.swift; sourceTree = "<group>"; };
|
||||
BF0FA7C22DE45DE300C9E5F2 /* VPUserAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPUserAPI.swift; sourceTree = "<group>"; };
|
||||
BF5E75AE2DE4632200DE9DFE /* VPAboutUsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPAboutUsViewController.swift; sourceTree = "<group>"; };
|
||||
BF5E75B02DE4656600DE9DFE /* VPCampaignWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPCampaignWebViewController.swift; sourceTree = "<group>"; };
|
||||
BF5E75B22DE465EA00DE9DFE /* Dictionary+SPAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+SPAdd.swift"; sourceTree = "<group>"; };
|
||||
BF5E75B52DE46DB600DE9DFE /* UIScrollView+Empty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+Empty.swift"; sourceTree = "<group>"; };
|
||||
BF5E75B72DE46F7100DE9DFE /* VPNetworkReachabilityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPNetworkReachabilityManager.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 */
|
||||
|
||||
@ -316,6 +346,8 @@
|
||||
1B056E352DDAC1DE007EE38D /* Libs */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF5E75B42DE46D9500DE9DFE /* Empty */,
|
||||
BF0FA7BF2DE45D4500C9E5F2 /* User */,
|
||||
BF0FA7432DDF025A00C9E5F2 /* Player */,
|
||||
BF0FA6F22DDC603200C9E5F2 /* HUD */,
|
||||
BF0FA6D82DDC5C8200C9E5F2 /* Login */,
|
||||
@ -328,6 +360,7 @@
|
||||
1B056E362DDAC1E8007EE38D /* Class */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7A62DE4437F00C9E5F2 /* Me */,
|
||||
BF0FA7952DE1948A00C9E5F2 /* MyList */,
|
||||
1B056E522DDACBF4007EE38D /* Home */,
|
||||
BF0FA7422DDF024400C9E5F2 /* Explore */,
|
||||
@ -344,6 +377,7 @@
|
||||
1B056E3A2DDAC21E007EE38D /* Model */,
|
||||
1B056E422DDAC32C007EE38D /* Extension */,
|
||||
1B056E3C2DDAC23D007EE38D /* Define */,
|
||||
BF0FA7B42DE44E5100C9E5F2 /* WebView */,
|
||||
1B056E3B2DDAC22D007EE38D /* Networking */,
|
||||
);
|
||||
path = Base;
|
||||
@ -410,6 +444,7 @@
|
||||
BF0FA6D42DDC5B5D00C9E5F2 /* VPApi.swift */,
|
||||
BF0FA6D62DDC5BE100C9E5F2 /* VPURLPath.swift */,
|
||||
BF0FA6F02DDC600200C9E5F2 /* VPNetwork.swift */,
|
||||
BF5E75B72DE46F7100DE9DFE /* VPNetworkReachabilityManager.swift */,
|
||||
);
|
||||
path = Base;
|
||||
sourceTree = "<group>";
|
||||
@ -417,6 +452,9 @@
|
||||
1B056E422DDAC32C007EE38D /* Extension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF5E75B22DE465EA00DE9DFE /* Dictionary+SPAdd.swift */,
|
||||
BF0FA7BD2DE4591B00C9E5F2 /* UserDefaults+VPAdd.swift */,
|
||||
BF0FA7B92DE451B000C9E5F2 /* UINavigationBar+VPAdd.swift */,
|
||||
1B056E432DDAC355007EE38D /* UIDevice+VPAdd.swift */,
|
||||
1B056E452DDAC370007EE38D /* UIScreen+VPAdd.swift */,
|
||||
1B056E5A2DDACD80007EE38D /* UIColor+VPAdd.swift */,
|
||||
@ -547,6 +585,7 @@
|
||||
children = (
|
||||
BF0FA6F82DDC64E700C9E5F2 /* VPHomeAPI.swift */,
|
||||
BF0FA73C2DDED2D000C9E5F2 /* VPVideoAPI.swift */,
|
||||
BF0FA7C22DE45DE300C9E5F2 /* VPUserAPI.swift */,
|
||||
);
|
||||
path = API;
|
||||
sourceTree = "<group>";
|
||||
@ -755,6 +794,68 @@
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF0FA7A62DE4437F00C9E5F2 /* Me */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7A72DE4438600C9E5F2 /* Controller */,
|
||||
BF0FA7AC2DE443AE00C9E5F2 /* View */,
|
||||
BF0FA7AD2DE443B700C9E5F2 /* Model */,
|
||||
);
|
||||
path = Me;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF0FA7A72DE4438600C9E5F2 /* Controller */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7AE2DE443E000C9E5F2 /* VPMeViewController.swift */,
|
||||
BF5E75AE2DE4632200DE9DFE /* VPAboutUsViewController.swift */,
|
||||
BF5E75B02DE4656600DE9DFE /* VPCampaignWebViewController.swift */,
|
||||
);
|
||||
path = Controller;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF0FA7AC2DE443AE00C9E5F2 /* View */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7B22DE447FE00C9E5F2 /* VPMeCell.swift */,
|
||||
BF0FA7BB2DE4563300C9E5F2 /* VPMeUserInfoCell.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF0FA7AD2DE443B700C9E5F2 /* Model */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7B02DE447EB00C9E5F2 /* VPMeItem.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF0FA7B42DE44E5100C9E5F2 /* WebView */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7B52DE44E8000C9E5F2 /* VPWebView.swift */,
|
||||
BF0FA7B72DE44FCC00C9E5F2 /* VPWebViewController.swift */,
|
||||
);
|
||||
path = WebView;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF0FA7BF2DE45D4500C9E5F2 /* User */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF0FA7C02DE45D5D00C9E5F2 /* VPUserInfo.swift */,
|
||||
);
|
||||
path = User;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BF5E75B42DE46D9500DE9DFE /* Empty */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BF5E75B52DE46DB600DE9DFE /* UIScrollView+Empty.swift */,
|
||||
);
|
||||
path = Empty;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@ -877,13 +978,18 @@
|
||||
1B056E742DDB2DD7007EE38D /* UIView+VPAdd.swift in Sources */,
|
||||
BF0FA6F12DDC600200C9E5F2 /* VPNetwork.swift in Sources */,
|
||||
BF0FA7502DDF0A9900C9E5F2 /* VPVideoPlayerCell.swift in Sources */,
|
||||
BF5E75B62DE46DB600DE9DFE /* UIScrollView+Empty.swift in Sources */,
|
||||
1B056E572DDACC6B007EE38D /* VPHomePageViewController.swift in Sources */,
|
||||
BF0FA7BC2DE4563300C9E5F2 /* VPMeUserInfoCell.swift in Sources */,
|
||||
BF0FA7B82DE44FCC00C9E5F2 /* VPWebViewController.swift in Sources */,
|
||||
BF0FA72A2DDC922F00C9E5F2 /* VPHomeRecommandCell.swift in Sources */,
|
||||
BF0FA7322DDEBD6400C9E5F2 /* AppDelegate+Config.swift in Sources */,
|
||||
BF0FA7B32DE447FE00C9E5F2 /* VPMeCell.swift in Sources */,
|
||||
BF0FA6DF2DDC5E4D00C9E5F2 /* String+VPAdd.swift in Sources */,
|
||||
BF0FA7002DDC665300C9E5F2 /* VPShortModel.swift in Sources */,
|
||||
1B056E7B2DDB37BA007EE38D /* VPGradientView.swift in Sources */,
|
||||
BF0FA7262DDC8F7600C9E5F2 /* VPCollectionView.swift in Sources */,
|
||||
BF0FA7C32DE45DE300C9E5F2 /* VPUserAPI.swift in Sources */,
|
||||
BF0FA78B2DE164C100C9E5F2 /* VPSearchResultCell.swift in Sources */,
|
||||
BF0FA71D2DDC807200C9E5F2 /* UIImageView+VPAdd.swift in Sources */,
|
||||
BF0FA6DC2DDC5CD700C9E5F2 /* VPTokenModel.swift in Sources */,
|
||||
@ -916,12 +1022,15 @@
|
||||
BF0FA7522DDF134700C9E5F2 /* VPVideoPlayerControlView.swift in Sources */,
|
||||
BF0FA7852DE1561D00C9E5F2 /* VPSearchRecommendedCell.swift in Sources */,
|
||||
BF0FA7832DE1533E00C9E5F2 /* VPGradientLabel.swift in Sources */,
|
||||
BF0FA7B12DE447EB00C9E5F2 /* VPMeItem.swift in Sources */,
|
||||
1B056E2C2DDAC0FD007EE38D /* SceneDelegate.swift in Sources */,
|
||||
BF0FA75D2DDF208400C9E5F2 /* VPExplorePlayerControlView.swift in Sources */,
|
||||
1B056E462DDAC370007EE38D /* UIScreen+VPAdd.swift in Sources */,
|
||||
BF0FA7692DE0502900C9E5F2 /* VPEpisodeCell.swift in Sources */,
|
||||
BF0FA73D2DDED2D000C9E5F2 /* VPVideoAPI.swift in Sources */,
|
||||
BF0FA6EE2DDC5F8700C9E5F2 /* JXUUID.m in Sources */,
|
||||
BF5E75B12DE4656600DE9DFE /* VPCampaignWebViewController.swift in Sources */,
|
||||
BF0FA7BA2DE451B900C9E5F2 /* UINavigationBar+VPAdd.swift in Sources */,
|
||||
BF0FA77D2DE078D400C9E5F2 /* VPSearchRecommendedView.swift in Sources */,
|
||||
BF0FA7812DE150F700C9E5F2 /* VPSearchRecommendedContentView.swift in Sources */,
|
||||
BF0FA7872DE1601200C9E5F2 /* VPTextField.swift in Sources */,
|
||||
@ -933,6 +1042,7 @@
|
||||
BF0FA6DA2DDC5CB600C9E5F2 /* VPLoginManager.swift in Sources */,
|
||||
BF0FA74A2DDF04E200C9E5F2 /* VPPlayerProtocol.swift in Sources */,
|
||||
BF0FA72C2DDD7B7300C9E5F2 /* VPHomeRankingContentCell.swift in Sources */,
|
||||
BF0FA7AF2DE443E000C9E5F2 /* VPMeViewController.swift in Sources */,
|
||||
BF0FA7942DE16E9300C9E5F2 /* JXTagView.swift in Sources */,
|
||||
BF0FA7A52DE4384100C9E5F2 /* AttributedString+VPAdd.swift in Sources */,
|
||||
BF0FA7652DE00A0E00C9E5F2 /* VPDetailPlayerControlView.swift in Sources */,
|
||||
@ -951,11 +1061,13 @@
|
||||
BF0FA79D2DE198C600C9E5F2 /* VPWatchHistoryViewController.swift in Sources */,
|
||||
1B056E6A2DDAD0BF007EE38D /* VPLocalizedManager.swift in Sources */,
|
||||
BF0FA7242DDC888F00C9E5F2 /* VPHomeRecommandContentCell.swift in Sources */,
|
||||
BF5E75AF2DE4632200DE9DFE /* VPAboutUsViewController.swift in Sources */,
|
||||
BF0FA78F2DE16B2A00C9E5F2 /* VPUserDefaultsKey.swift in Sources */,
|
||||
BF0FA7192DDC7F4900C9E5F2 /* VPHomeBannerCell.swift in Sources */,
|
||||
BF0FA7712DE062EB00C9E5F2 /* VPVideoRateModel.swift in Sources */,
|
||||
BF0FA7022DDC667C00C9E5F2 /* VPVideoInfoModel.swift in Sources */,
|
||||
BF0FA77B2DE0788A00C9E5F2 /* UIStackView+VPAdd.swift in Sources */,
|
||||
BF0FA7BE2DE4592A00C9E5F2 /* UserDefaults+VPAdd.swift in Sources */,
|
||||
BF0FA76F2DE062A700C9E5F2 /* VPRateSelectedView.swift in Sources */,
|
||||
BF0FA7772DE0735800C9E5F2 /* VPSearchInputView.swift in Sources */,
|
||||
BF0FA7892DE161F200C9E5F2 /* VPSearchResultView.swift in Sources */,
|
||||
@ -969,13 +1081,17 @@
|
||||
BF0FA73F2DDEF26E00C9E5F2 /* VPHomeSearchButton.swift in Sources */,
|
||||
1B056E512DDACBE5007EE38D /* VPViewController.swift in Sources */,
|
||||
BF0FA7122DDC6D2C00C9E5F2 /* VPHomeModuleItem.swift in Sources */,
|
||||
BF5E75B32DE465EC00DE9DFE /* Dictionary+SPAdd.swift in Sources */,
|
||||
BF0FA7162DDC78FF00C9E5F2 /* ZKCycleScrollViewFlowLayout.swift in Sources */,
|
||||
BF0FA7172DDC78FF00C9E5F2 /* ZKCycleScrollView.swift in Sources */,
|
||||
BF0FA7612DDFFE7100C9E5F2 /* VPVideoDetailModel.swift in Sources */,
|
||||
BF5E75B82DE46F7100DE9DFE /* VPNetworkReachabilityManager.swift in Sources */,
|
||||
BF0FA6D52DDC5B5D00C9E5F2 /* VPApi.swift in Sources */,
|
||||
BF0FA7C12DE45D5D00C9E5F2 /* VPUserInfo.swift in Sources */,
|
||||
BF0FA6FC2DDC657500C9E5F2 /* VPHomeDataModel.swift in Sources */,
|
||||
BF0FA7392DDECF8900C9E5F2 /* VPHomeListViewController.swift in Sources */,
|
||||
BF0FA6F62DDC616300C9E5F2 /* VPToast.swift in Sources */,
|
||||
BF0FA7B62DE44E8000C9E5F2 /* VPWebView.swift in Sources */,
|
||||
1B056E492DDAC3DF007EE38D /* VPAppTool.swift in Sources */,
|
||||
BF0FA74E2DDF067E00C9E5F2 /* VPVideoPlayViewModel.swift in Sources */,
|
||||
BF0FA75B2DDF206000C9E5F2 /* VPExplorePlayerCell.swift in Sources */,
|
||||
|
@ -12,6 +12,8 @@ extension AppDelegate {
|
||||
func appConfig() {
|
||||
UIButton.vp_bt_Awake()
|
||||
UIView.vp_Awake()
|
||||
|
||||
VPToast.config()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||
|
||||
appConfig()
|
||||
///开启网络监控
|
||||
VPNetworkReachabilityManager.manager.startMonitoring()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: VPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||
|
||||
VPLoginManager.manager.updateUserInfo(completer: nil)
|
||||
|
||||
return true
|
||||
}
|
||||
@ -36,3 +41,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
|
||||
}
|
||||
|
||||
extension AppDelegate {
|
||||
|
||||
@objc private func reachabilityDidChangeNotification() {
|
||||
if VPNetworkReachabilityManager.manager.isReachable == true {
|
||||
VPLoginManager.manager.updateUserInfo(completer: nil)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import ESTabBarController_swift
|
||||
|
||||
class VPTabBarController: UITabBarController {
|
||||
|
||||
@ -53,7 +52,6 @@ class VPTabBarController: UITabBarController {
|
||||
|
||||
view.backgroundColor = .color000000()
|
||||
|
||||
// ESTabBarController
|
||||
vp_setup()
|
||||
self.tabBar.isTranslucent = true
|
||||
|
||||
@ -89,7 +87,7 @@ extension VPTabBarController {
|
||||
let nav1 = createNavigationController(viewController: VPHomePageViewController(), title: "Home".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected"))
|
||||
let nav2 = createNavigationController(viewController: VPExploreViewController(), title: "Explore".localized, image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected"))
|
||||
let nav3 = createNavigationController(viewController: VPMyListViewController(), title: "My List".localized, image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected"))
|
||||
let nav4 = createNavigationController(viewController: VPHomePageViewController(), title: "Home".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
||||
let nav4 = createNavigationController(viewController: VPMeViewController(), title: "Me".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
||||
|
||||
viewControllers = [nav1, nav2, nav3, nav4]
|
||||
|
||||
@ -97,13 +95,6 @@ extension VPTabBarController {
|
||||
|
||||
private func createNavigationController(viewController: UIViewController, title: String?, image: UIImage?, selectedImage: UIImage?) -> UINavigationController {
|
||||
|
||||
// let tabBarContentView = VPTabBarItemContentView()
|
||||
// let tabBarItem = ESTabBarItem(tabBarContentView, title: title, image: image, selectedImage: selectedImage)
|
||||
//
|
||||
// tabBarItem.contentView?.renderingMode = .alwaysOriginal
|
||||
// tabBarItem.contentView?.textColor = .colorFFFFFF()
|
||||
// tabBarItem.contentView?.highlightTextColor = .colorFFFFFF()
|
||||
// tabBarItem.contentView?.titleLabel.font = .fontRegular(ofSize: 13)
|
||||
|
||||
let tabBarItem = VPTabBarItem()
|
||||
tabBarItem.title = title
|
||||
@ -111,7 +102,6 @@ extension VPTabBarController {
|
||||
tabBarItem.selectedImage = selectedImage
|
||||
|
||||
let nav = VPNavigationController(rootViewController: viewController)
|
||||
// nav.tabBarItem.title = title
|
||||
nav.tabBarItem = tabBarItem
|
||||
return nav
|
||||
}
|
||||
@ -124,11 +114,6 @@ extension VPTabBarController {
|
||||
guard let idx = tabBar.items?.firstIndex(of: item) else {
|
||||
return;
|
||||
}
|
||||
// if idx == tabBar.items!.count - 1, ESTabBarController.isShowingMore(self) {
|
||||
// ignoreNextSelection = true
|
||||
// selectedViewController = moreNavigationController
|
||||
// return;
|
||||
// }
|
||||
if let vc = viewControllers?[idx] {
|
||||
ignoreNextSelection = true
|
||||
selectedIndex = idx
|
||||
@ -149,3 +134,24 @@ extension VPTabBarController {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension VPTabBarController {
|
||||
func openHistoryPage() {
|
||||
|
||||
var index: Int?
|
||||
var viewController: VPMyListViewController?
|
||||
self.viewControllers?.enumerated().forEach({
|
||||
guard let nav = $1 as? UINavigationController else { return }
|
||||
if let vc = nav.viewControllers.first as? VPMyListViewController {
|
||||
index = $0
|
||||
viewController = vc
|
||||
}
|
||||
|
||||
})
|
||||
if let index = index {
|
||||
self.selectedIndex = index
|
||||
viewController?.showHistoryPage()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,3 +92,40 @@ extension VPViewController {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension UIViewController {
|
||||
///设置导航默认样式
|
||||
func setNavigationNormalStyle(backgroundColor: UIColor = .clear,
|
||||
isTranslucent: Bool = true,
|
||||
prefersLargeTitles: Bool = false)
|
||||
{
|
||||
self.setNavigationBackgroundColor(color: backgroundColor, isTranslucent: isTranslucent)
|
||||
self.setNavigationTitleStyle()
|
||||
self.navigationController?.navigationBar.prefersLargeTitles = prefersLargeTitles
|
||||
}
|
||||
|
||||
///设置导航背景色
|
||||
func setNavigationBackgroundColor(color: UIColor?, isTranslucent: Bool = false) {
|
||||
guard let nav = navigationController else { return }
|
||||
if nav.visibleViewController == self {
|
||||
nav.navigationBar.vp_setBackgroundColor(backgroundColor: color)
|
||||
nav.navigationBar.vp_setTranslucent(isTranslucent: isTranslucent)
|
||||
}
|
||||
}
|
||||
|
||||
///设置标题样式
|
||||
func setNavigationTitleStyle(color: UIColor? = nil, font: UIFont? = nil) {
|
||||
guard let nav = navigationController else { return }
|
||||
if nav.visibleViewController == self {
|
||||
//标题样式
|
||||
var titleTextAttributes = UINavigationBar.vp_normalTitleTextAttributes
|
||||
if let color = color {
|
||||
titleTextAttributes[NSAttributedString.Key.foregroundColor] = color
|
||||
}
|
||||
if let font = font {
|
||||
titleTextAttributes[NSAttributedString.Key.font] = font
|
||||
}
|
||||
nav.navigationBar.vp_setTitleTextAttributes(titleTextAttributes: titleTextAttributes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,3 +9,9 @@ import UIKit
|
||||
|
||||
///搜索记录
|
||||
let kVPSearchHistoryDefaultsKey = "kVPSearchHistoryDefaultsKey"
|
||||
|
||||
///登录token
|
||||
let kVPLoginTokenDefaultsKey = "kVPLoginTokenDefaultsKey"
|
||||
|
||||
///用户信息
|
||||
let kVPLoginUserInfoDefaultsKey = "kSPLoginUserInfoDefaultsKey"
|
||||
|
23
Veloria/Base/Extension/Dictionary+SPAdd.swift
Normal file
@ -0,0 +1,23 @@
|
||||
//
|
||||
// Dictionary+SPAdd.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension Dictionary {
|
||||
|
||||
func toJsonString() -> String? {
|
||||
do {
|
||||
let data = try JSONSerialization.data(withJSONObject: self)
|
||||
let jsonStr = String(data: data, encoding: .utf8)
|
||||
return jsonStr
|
||||
} catch {
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
@ -97,4 +97,8 @@ extension UIColor {
|
||||
static func colorD87675(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0xD87675, alpha: alpha)
|
||||
}
|
||||
|
||||
static func colorB5B5B5(alpha: CGFloat = 1) -> UIColor {
|
||||
return UIColor(rgb: 0xB5B5B5, alpha: alpha)
|
||||
}
|
||||
}
|
||||
|
88
Veloria/Base/Extension/UINavigationBar+VPAdd.swift
Normal file
@ -0,0 +1,88 @@
|
||||
//
|
||||
// UINavigationBar+VPAdd.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UINavigationBar {
|
||||
|
||||
static let vp_normalTitleFont = UIFont.fontBold(ofSize: 16)
|
||||
static var vp_normalTitleColor: UIColor {
|
||||
get {
|
||||
return .colorFFFFFF()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
默认标题样式
|
||||
*/
|
||||
static var vp_normalTitleTextAttributes: [NSAttributedString.Key : Any] {
|
||||
get {
|
||||
return [
|
||||
NSAttributedString.Key.font : vp_normalTitleFont,
|
||||
NSAttributedString.Key.foregroundColor : vp_normalTitleColor
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
默认背景色
|
||||
*/
|
||||
static var vp_normalBackgroundColor: UIColor {
|
||||
get {
|
||||
return .black
|
||||
}
|
||||
}
|
||||
|
||||
@available(iOS 13.0, *)
|
||||
static let navBarAppearance: UINavigationBarAppearance = {
|
||||
let navBarAppearance = UINavigationBarAppearance()
|
||||
navBarAppearance.configureWithOpaqueBackground()
|
||||
// 背景色
|
||||
navBarAppearance.backgroundColor = vp_normalBackgroundColor
|
||||
// 去掉半透明效果
|
||||
navBarAppearance.backgroundEffect = nil
|
||||
// 去除导航栏阴影(如果不设置clear,导航栏底下会有一条阴影线)
|
||||
navBarAppearance.shadowColor = UIColor.clear
|
||||
// 字体颜色
|
||||
navBarAppearance.titleTextAttributes = vp_normalTitleTextAttributes
|
||||
|
||||
return navBarAppearance
|
||||
}()
|
||||
|
||||
|
||||
func vp_setTranslucent(isTranslucent: Bool) {
|
||||
self.isTranslucent = isTranslucent
|
||||
}
|
||||
|
||||
func vp_setBackgroundColor(backgroundColor: UIColor?) {
|
||||
if #available(iOS 15.0, *) {
|
||||
UINavigationBar.navBarAppearance.backgroundColor = backgroundColor
|
||||
self.standardAppearance = UINavigationBar.navBarAppearance
|
||||
self.scrollEdgeAppearance = UINavigationBar.navBarAppearance
|
||||
}
|
||||
|
||||
if let backgroundColor = backgroundColor {
|
||||
self.setBackgroundImage(UIImage(color: backgroundColor), for: .default)
|
||||
} else {
|
||||
self.setBackgroundImage(UIImage(), for: .default)
|
||||
}
|
||||
}
|
||||
|
||||
func vp_setTitleTextAttributes(titleTextAttributes: [NSAttributedString.Key : Any]?) {
|
||||
|
||||
if #available(iOS 15.0, *) {
|
||||
if let titleTextAttributes = titleTextAttributes {
|
||||
UINavigationBar.navBarAppearance.titleTextAttributes = titleTextAttributes
|
||||
}
|
||||
self.scrollEdgeAppearance = UINavigationBar.navBarAppearance
|
||||
self.standardAppearance = UINavigationBar.navBarAppearance
|
||||
} else {
|
||||
|
||||
self.titleTextAttributes = titleTextAttributes
|
||||
}
|
||||
}
|
||||
}
|
45
Veloria/Base/Extension/UserDefaults+VPAdd.swift
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// UserDefaults+VPAdd.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
extension UserDefaults {
|
||||
|
||||
static func vp_setObject(_ obj: NSSecureCoding?, forKey key: String) {
|
||||
let defaults = UserDefaults.standard
|
||||
|
||||
guard let obj = obj else {
|
||||
defaults.removeObject(forKey: key)
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
let data = try NSKeyedArchiver.archivedData(withRootObject: obj, requiringSecureCoding: true)
|
||||
defaults.set(data, forKey: key)
|
||||
} catch {
|
||||
print("Error archiving object: \(error)")
|
||||
}
|
||||
}
|
||||
|
||||
static func vp_object<T: NSObject & NSSecureCoding>(forKey key: String, as type: T.Type) -> T? {
|
||||
let defaults = UserDefaults.standard
|
||||
|
||||
guard let data = defaults.data(forKey: key) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
do {
|
||||
let object = try NSKeyedUnarchiver.unarchivedObject(ofClass: type, from: data)
|
||||
return object
|
||||
} catch {
|
||||
print("Error unarchiving object: \(error)")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -13,7 +13,7 @@ class VPHomeAPI: NSObject {
|
||||
static func requestHomeData(completer: ((_ list: [VPHomeModuleItem]?) -> Void)?) {
|
||||
var param = VPNetworkParameters(path: "/home/all-modules")
|
||||
param.method = .get
|
||||
|
||||
param.isToast = true
|
||||
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPListModel<VPHomeModuleItem>>) in
|
||||
completer?(response.data?.list)
|
||||
|
22
Veloria/Base/Networking/API/VPUserAPI.swift
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// VPUserAPI.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPUserAPI: NSObject {
|
||||
|
||||
///获取用户信息
|
||||
static func requestUserInfo(completer: ((_ userInfo: VPUserInfo?) -> Void)?) {
|
||||
|
||||
var param = VPNetworkParameters(path: "/customer/info")
|
||||
param.method = .get
|
||||
|
||||
VPNetwork.request(parameters: param) { (response: VPNetworkResponse<VPUserInfo>) in
|
||||
completer?(response.data)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
//
|
||||
// VPNetworkReachabilityManager.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Network
|
||||
|
||||
class VPNetworkReachabilityManager {
|
||||
|
||||
static let manager = VPNetworkReachabilityManager()
|
||||
|
||||
///是否有网
|
||||
var isReachable: Bool?
|
||||
|
||||
|
||||
private let monitor = NWPathMonitor()
|
||||
private let queue = DispatchQueue(label: "NetworkMonitorQueue")
|
||||
|
||||
func startMonitoring() {
|
||||
|
||||
monitor.pathUpdateHandler = { [weak self] path in
|
||||
guard let self = self else { return }
|
||||
if path.status == .satisfied {
|
||||
if self.isReachable == false {
|
||||
self.isReachable = true
|
||||
DispatchQueue.main.async {
|
||||
NotificationCenter.default.post(name: VPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||
}
|
||||
} else {
|
||||
self.isReachable = true
|
||||
}
|
||||
|
||||
} else {
|
||||
if self.isReachable == true {
|
||||
self.isReachable = false
|
||||
DispatchQueue.main.async {
|
||||
NotificationCenter.default.post(name: VPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||
}
|
||||
} else {
|
||||
self.isReachable = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
monitor.start(queue: queue)
|
||||
}
|
||||
|
||||
func stopMonitoring() {
|
||||
monitor.cancel()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPNetworkReachabilityManager {
|
||||
///网络发生变化
|
||||
@objc static let reachabilityDidChangeNotification = NSNotification.Name(rawValue: "VPNetworkReachabilityManager.reachabilityDidChangeNotification")
|
||||
}
|
@ -22,25 +22,25 @@ let VPCampaignWebURL = "https://campaign.moviatv.com"
|
||||
#endif
|
||||
|
||||
///用户协议
|
||||
let VPUserAgreementWebUrl = VPWebBaseURL + "/user_policy"
|
||||
let kVPUserAgreementWebUrl = VPWebBaseURL + "/user_policy"
|
||||
///隐私协议
|
||||
let VPPrivacyPolicyWebUrl = VPWebBaseURL + "/private"
|
||||
let kVPPrivacyPolicyWebUrl = VPWebBaseURL + "/private"
|
||||
///儿童个人信息保护规则
|
||||
let VPInformationProtectionWebUrl = VPWebBaseURL + "/information_protection"
|
||||
let kVPInformationProtectionWebUrl = VPWebBaseURL + "/information_protection"
|
||||
///第三方共享清单
|
||||
let VPInformationSharingWebUrl = VPWebBaseURL + "/information_sharing"
|
||||
let kVPInformationSharingWebUrl = VPWebBaseURL + "/information_sharing"
|
||||
///收集个人信息明示清单
|
||||
let VPPersoInforDisclosureWebUrl = VPWebBaseURL + "/persoInfor_disclosure"
|
||||
let kVPPersoInforDisclosureWebUrl = VPWebBaseURL + "/persoInfor_disclosure"
|
||||
///全国青少年互联网文明公约
|
||||
let VPCivizatioConventionWebUrl = VPWebBaseURL + "/civizatio_convention"
|
||||
let kVPCivizatioConventionWebUrl = VPWebBaseURL + "/civizatio_convention"
|
||||
///会员服务协议
|
||||
let VPMemberShipAgreement = VPWebBaseURL + "/member_ship_agreement"
|
||||
let kVPMemberShipAgreement = VPWebBaseURL + "/member_ship_agreement"
|
||||
|
||||
///反馈首页
|
||||
let VPFeedBackHomeWebUrl = VPCampaignWebURL + "/pages/leave/index"
|
||||
let kVPFeedBackHomeWebUrl = VPCampaignWebURL + "/pages/leave/index"
|
||||
///反馈列表
|
||||
let VPFeedBackListWebUrl = VPCampaignWebURL + "/pages/leave/list"
|
||||
let kVPFeedBackListWebUrl = VPCampaignWebURL + "/pages/leave/list"
|
||||
///反馈详情
|
||||
let VPFeedBackDetailWebUrl = VPCampaignWebURL + "/pages/leave/detail"
|
||||
let kVPFeedBackDetailWebUrl = VPCampaignWebURL + "/pages/leave/detail"
|
||||
///活动页面
|
||||
let VPRewardsWebUrl = VPCampaignWebURL
|
||||
let kVPRewardsWebUrl = VPCampaignWebURL
|
||||
|
@ -39,11 +39,9 @@ class VPTableView: UITableView {
|
||||
}
|
||||
get {
|
||||
var margins = super.layoutMargins
|
||||
if #available(iOS 13.0, *) {
|
||||
if self.style == .insetGrouped {
|
||||
margins.left = self.safeAreaInsets.left + insetGroupedMargins
|
||||
margins.right = self.safeAreaInsets.right + insetGroupedMargins
|
||||
}
|
||||
if self.style == .insetGrouped {
|
||||
margins.left = self.safeAreaInsets.left + insetGroupedMargins
|
||||
margins.right = self.safeAreaInsets.right + insetGroupedMargins
|
||||
}
|
||||
return margins
|
||||
}
|
||||
|
@ -9,6 +9,11 @@ import UIKit
|
||||
|
||||
class VPTableViewCell: UITableViewCell {
|
||||
|
||||
private(set) lazy var indicatorImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "arrow_right_icon_02"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
|
197
Veloria/Base/WebView/VPWebView.swift
Normal file
@ -0,0 +1,197 @@
|
||||
//
|
||||
// VPWebView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
@preconcurrency import WebKit
|
||||
|
||||
//MARK:-------------- VPWebViewDelegate --------------
|
||||
@objc protocol VPWebViewDelegate: NSObjectProtocol {
|
||||
|
||||
@objc optional func webView(_ webView: VPWebView, shouldStartLoadWith navigationAction: WKNavigationAction) -> Bool
|
||||
|
||||
@objc optional func webViewDidStartLoad(_ webView: VPWebView)
|
||||
|
||||
@objc optional func webViewDidFinishLoad(_ webView: VPWebView)
|
||||
|
||||
@objc optional func webView(_ webView: VPWebView, didFailLoadWithError error: Error)
|
||||
|
||||
///进度
|
||||
@objc optional func webView(webView: VPWebView, didChangeProgress progress: CGFloat)
|
||||
///标题
|
||||
@objc optional func webView(webView: VPWebView, didChangeTitle title: String)
|
||||
|
||||
///web交互用
|
||||
@objc optional func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
|
||||
|
||||
}
|
||||
|
||||
class VPWebView: WKWebView {
|
||||
|
||||
weak var delegate: VPWebViewDelegate?
|
||||
|
||||
// private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [
|
||||
// WebMessageAPP,
|
||||
// WebMessageOpenFeedbackList,
|
||||
// WebMessageOpenFeedbackDetail,
|
||||
// WebMessageOpenPhotoPicker,
|
||||
// ]
|
||||
|
||||
|
||||
deinit {
|
||||
|
||||
self.removeObserver(self, forKeyPath: "estimatedProgress")
|
||||
self.removeObserver(self, forKeyPath: "title")
|
||||
|
||||
}
|
||||
|
||||
override init(frame: CGRect, configuration: WKWebViewConfiguration) {
|
||||
super.init(frame: frame, configuration: configuration)
|
||||
// addScriptMessageHandler()
|
||||
_setupInit()
|
||||
}
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
private func _setupInit() {
|
||||
|
||||
self.isOpaque = false
|
||||
self.uiDelegate = self
|
||||
self.navigationDelegate = self
|
||||
self.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil)
|
||||
self.addObserver(self, forKeyPath: "title", options: .new, context: nil)
|
||||
|
||||
}
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
if object as? VPWebView == self {
|
||||
if keyPath == "estimatedProgress", let progress = change?[NSKeyValueChangeKey.newKey] as? CGFloat {
|
||||
self.delegate?.webView?(webView: self, didChangeProgress: progress)
|
||||
} else if keyPath == "title", let title = change?[NSKeyValueChangeKey.newKey] as? String {
|
||||
self.delegate?.webView?(webView: self, didChangeTitle: title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func load(urlStr: String) {
|
||||
guard let url = URL(string: urlStr) else { return }
|
||||
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 30)
|
||||
self.load(request)
|
||||
}
|
||||
|
||||
// func removeScriptMessageHandler() {
|
||||
// self.scriptMessageHandlerArray.forEach{
|
||||
// configuration.userContentController.removeScriptMessageHandler(forName: $0)
|
||||
// }
|
||||
// }
|
||||
// func addScriptMessageHandler() {
|
||||
// self.scriptMessageHandlerArray.forEach{
|
||||
// configuration.userContentController.add(YYWeakProxy(target: self) as! WKScriptMessageHandler, name: $0)
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
//MARK:-------------- WKUIDelegate --------------
|
||||
extension VPWebView: WKUIDelegate {
|
||||
|
||||
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
|
||||
let alertController = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
|
||||
alertController.addAction(UIAlertAction(title: "确认", style: .default, handler: { (action) in
|
||||
completionHandler()
|
||||
}))
|
||||
self.viewController?.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
|
||||
let alertController = UIAlertController(title: "提示", message: message, preferredStyle: .alert)
|
||||
alertController.addAction(UIAlertAction(title: "取消", style: .cancel, handler: { (action) in
|
||||
completionHandler(false)
|
||||
}))
|
||||
alertController.addAction(UIAlertAction(title: "确认", style: .default, handler: { (action) in
|
||||
completionHandler(true)
|
||||
}))
|
||||
self.viewController?.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
|
||||
let alertController = UIAlertController(title: prompt, message: "", preferredStyle: .alert)
|
||||
alertController.addTextField { (textField) in
|
||||
textField.text = defaultText
|
||||
}
|
||||
alertController.addAction(UIAlertAction(title: "完成", style: .default, handler: { (action) in
|
||||
completionHandler(alertController.textFields?.first?.text)
|
||||
}))
|
||||
self.viewController?.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
}
|
||||
|
||||
//MARK:-------------- WKNavigationDelegate --------------
|
||||
extension VPWebView: WKNavigationDelegate {
|
||||
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
|
||||
|
||||
decisionHandler(.allow);
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
|
||||
vpLog(message: navigationAction.request.url)
|
||||
|
||||
if let url = navigationAction.request.url,
|
||||
url.scheme != "http",
|
||||
url.scheme != "https"
|
||||
{
|
||||
UIApplication.shared.open(url)
|
||||
decisionHandler(.cancel)
|
||||
return
|
||||
}
|
||||
|
||||
//防止抓包
|
||||
// if JXRequestHttpProxy.isIntercept() {
|
||||
// decisionHandler(.cancel)
|
||||
// return
|
||||
// }
|
||||
|
||||
|
||||
if let result = self.delegate?.webView?(self, shouldStartLoadWith: navigationAction) {
|
||||
if result {
|
||||
decisionHandler(.allow)
|
||||
} else {
|
||||
decisionHandler(.cancel)
|
||||
}
|
||||
} else {
|
||||
decisionHandler(.allow)
|
||||
}
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
|
||||
self.delegate?.webViewDidStartLoad?(self)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
self.delegate?.webViewDidFinishLoad?(self)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
|
||||
self.delegate?.webView?(self, didFailLoadWithError: error)
|
||||
}
|
||||
|
||||
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
|
||||
self.delegate?.webView?(self, didFailLoadWithError: error)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//MARK:-------------- WKScriptMessageHandler --------------
|
||||
extension VPWebView: WKScriptMessageHandler {
|
||||
|
||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||
self.delegate?.userContentController?(userContentController, didReceive: message)
|
||||
}
|
||||
|
||||
}
|
99
Veloria/Base/WebView/VPWebViewController.swift
Normal file
@ -0,0 +1,99 @@
|
||||
//
|
||||
// VPWebViewController.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import WebKit
|
||||
|
||||
class VPWebViewController: VPViewController {
|
||||
|
||||
var urlStr: String?
|
||||
|
||||
///自动设置标题
|
||||
var autoTitle = true
|
||||
|
||||
private(set) lazy var webView: VPWebView = {
|
||||
let controller = WKUserContentController()
|
||||
|
||||
let config = WKWebViewConfiguration()
|
||||
config.userContentController = controller
|
||||
config.preferences.javaScriptEnabled = true
|
||||
/** 默认是不能通过JS自动打开窗口的,必须通过用户交互才能打开 */
|
||||
config.preferences.javaScriptCanOpenWindowsAutomatically = true
|
||||
let webView = VPWebView(frame: self.view.bounds, configuration: config)
|
||||
webView.delegate = self
|
||||
return webView
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
|
||||
_setupUI()
|
||||
|
||||
if let url = urlStr {
|
||||
self.load(urlString: url)
|
||||
}
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
||||
self.setNavigationNormalStyle()
|
||||
}
|
||||
|
||||
func load(urlString: String) {
|
||||
let str: String = urlString
|
||||
|
||||
guard let url = URL(string: str) else { return }
|
||||
let request = URLRequest(url: url, timeoutInterval: 30)
|
||||
|
||||
self.webView.load(request)
|
||||
}
|
||||
|
||||
func reload() {
|
||||
self.webView.reload()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPWebViewController {
|
||||
|
||||
private func _setupUI() {
|
||||
self.view.addSubview(webView)
|
||||
|
||||
self.webView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(0)
|
||||
make.right.equalToSuperview().offset(0)
|
||||
make.top.equalToSuperview().offset(UIScreen.navBarHeight)
|
||||
make.bottom.equalToSuperview().offset(0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- VPWebViewDelegate --------------
|
||||
extension VPWebViewController: VPWebViewDelegate {
|
||||
|
||||
func webView(webView: VPWebView, didChangeTitle title: String) {
|
||||
if autoTitle {
|
||||
self.title = title
|
||||
}
|
||||
}
|
||||
|
||||
func webView(_ webView: VPWebView, didFailLoadWithError error: any Error) {
|
||||
vpLog(message: error)
|
||||
}
|
||||
|
||||
func webViewDidFinishLoad(_ webView: VPWebView) {
|
||||
vpLog(message: "网页加载完成")
|
||||
|
||||
}
|
||||
|
||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||
// _webViewUserContentController(didReceive: message)
|
||||
}
|
||||
}
|
@ -118,17 +118,19 @@ class VPHomePageViewController: VPViewController {
|
||||
private lazy var historyButton: UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "history_icon_01"), for: .normal)
|
||||
button.addTarget(self, action: #selector(handleHistoryButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: VPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||
|
||||
requestHomeData()
|
||||
|
||||
setupPageView()
|
||||
vp_setupUI()
|
||||
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@ -172,6 +174,21 @@ class VPHomePageViewController: VPViewController {
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
@objc private func handleHistoryButton() {
|
||||
(VPAppTool.rootViewController as? VPTabBarController)?.openHistoryPage()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPHomePageViewController {
|
||||
@objc private func reachabilityDidChangeNotification() {
|
||||
if VPNetworkReachabilityManager.manager.isReachable == true {
|
||||
if self.viewModel.oldModuleList == nil {
|
||||
requestHomeData()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extension VPHomePageViewController {
|
||||
@ -199,8 +216,6 @@ extension VPHomePageViewController {
|
||||
make.width.height.equalTo(40)
|
||||
make.centerY.equalTo(searchButton)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,8 +35,19 @@ class VPHomeModuleItem: VPModel, SmartCodable {
|
||||
self.list = [VPShortModel].deserialize(from: data)
|
||||
}
|
||||
} else if let data = data as? [String : Any] {
|
||||
title = data["title"] as? String
|
||||
list = [VPShortModel].deserialize(from: data["list"] as? [[String : Any]])
|
||||
var dataList: [[String : Any]]?
|
||||
if let list = data["list"] as? [[String : Any]] {
|
||||
self.title = data["title"] as? String
|
||||
dataList = list
|
||||
|
||||
} else if let list = data["shortPlayList"] as? [[String : Any]] {
|
||||
dataList = list
|
||||
}
|
||||
|
||||
if let dataList = dataList {
|
||||
self.list = [VPShortModel].deserialize(from: dataList)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
25
Veloria/Class/Me/Controller/VPAboutUsViewController.swift
Normal file
@ -0,0 +1,25 @@
|
||||
//
|
||||
// VPAboutUsViewController.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPAboutUsViewController: VPViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.title = "About Us".localized
|
||||
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
||||
setNavigationNormalStyle()
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
//
|
||||
// VPCampaignWebViewController.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPCampaignWebViewController: VPWebViewController {
|
||||
|
||||
var id: String?
|
||||
|
||||
///重试次数
|
||||
private var receiveDataCount = 0
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
autoTitle = false
|
||||
if urlStr == kVPFeedBackListWebUrl {
|
||||
self.title = "Feedback History".localized
|
||||
} else if urlStr == kVPFeedBackHomeWebUrl {
|
||||
self.title = "Feedback".localized
|
||||
} else if urlStr == kVPFeedBackDetailWebUrl {
|
||||
self.title = "Feedback Details".localized
|
||||
} else if urlStr == kVPRewardsWebUrl {
|
||||
self.title = "Rewards".localized
|
||||
}
|
||||
|
||||
self.webView.scrollView.vp_addRefreshHeader { [weak self] in
|
||||
self?.handleHeaderRefresh(nil)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
|
||||
self.reload()
|
||||
self.webView.scrollView.vp_endHeaderRefreshing()
|
||||
}
|
||||
|
||||
|
||||
override func webViewDidFinishLoad(_ webView: VPWebView) {
|
||||
super.webViewDidFinishLoad(webView)
|
||||
receiveDataCount = 0
|
||||
receiveDataFromNative()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPCampaignWebViewController {
|
||||
///设置登录信息
|
||||
func receiveDataFromNative() {
|
||||
receiveDataCount += 1
|
||||
if receiveDataCount > 10 { return }
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
var dic = [
|
||||
"token" : VPLoginManager.manager.token?.token ?? "",
|
||||
"time_zone" : String.timeZone(),
|
||||
"lang" : VPLocalizedManager.shared.currentLocalizedKey,
|
||||
"type" : "ios",
|
||||
"theme" : "theme_1",
|
||||
]
|
||||
if let id = id {
|
||||
dic["id"] = id
|
||||
}
|
||||
|
||||
|
||||
if let json = dic.toJsonString() {
|
||||
let js = "receiveDataFromNative(\(json))"
|
||||
self.webView.evaluateJavaScript(js) { [weak self] _, error in
|
||||
guard let self = self else { return }
|
||||
if error != nil {
|
||||
self.receiveDataFromNative()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
152
Veloria/Class/Me/Controller/VPMeViewController.swift
Normal file
@ -0,0 +1,152 @@
|
||||
//
|
||||
// VPMeViewController.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPMeViewController: VPViewController {
|
||||
|
||||
private lazy var dataArr: [[VPMeItem]] = {
|
||||
let arr = [
|
||||
[
|
||||
VPMeItem(cellKey: .userInfo),
|
||||
],
|
||||
[
|
||||
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
|
||||
}()
|
||||
|
||||
|
||||
|
||||
private lazy var tableView: VPTableView = {
|
||||
let tableView = VPTableView(frame: .zero, style: .insetGrouped)
|
||||
tableView.delegate = self
|
||||
tableView.dataSource = self
|
||||
tableView.separatorStyle = .none
|
||||
tableView.vp_addRefreshHeader { [weak self] in
|
||||
self?.handleHeaderRefresh(nil)
|
||||
}
|
||||
tableView.register(VPMeCell.self, forCellReuseIdentifier: VPMeItem.CellKey.normal.rawValue)
|
||||
tableView.register(VPMeUserInfoCell.self, forCellReuseIdentifier: VPMeItem.CellKey.userInfo.rawValue)
|
||||
return tableView
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
vp_setupUI()
|
||||
|
||||
requestUserInfo()
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
super.viewWillAppear(animated)
|
||||
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
if hasViewDidAppear {
|
||||
requestUserInfo()
|
||||
}
|
||||
super.viewDidAppear(animated)
|
||||
}
|
||||
|
||||
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
|
||||
self.requestUserInfo()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPMeViewController {
|
||||
|
||||
private func vp_setupUI() {
|
||||
view.addSubview(tableView)
|
||||
|
||||
tableView.snp.makeConstraints { make in
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.top.equalTo(UIScreen.statusBarHeight)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- UITableViewDelegate UITableViewDataSource --------------
|
||||
extension VPMeViewController: UITableViewDelegate, UITableViewDataSource {
|
||||
|
||||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let item = self.dataArr[indexPath.section][indexPath.row]
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: item.cellKey?.rawValue ?? VPMeItem.CellKey.normal.rawValue, for: indexPath)
|
||||
if let cell = cell as? VPMeCell {
|
||||
cell.item = item
|
||||
} else if let cell = cell as? VPMeUserInfoCell {
|
||||
cell.userInfo = VPLoginManager.manager.userInfo
|
||||
}
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return self.dataArr[section].count
|
||||
}
|
||||
|
||||
func numberOfSections(in tableView: UITableView) -> Int {
|
||||
return self.dataArr.count
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||
if section == 0 {
|
||||
return 0.1
|
||||
} else {
|
||||
return 14
|
||||
}
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
|
||||
return 0.1
|
||||
}
|
||||
|
||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
let item = dataArr[indexPath.section][indexPath.row]
|
||||
|
||||
switch item.type {
|
||||
case .privacyPolicy:
|
||||
let vc = VPWebViewController()
|
||||
vc.urlStr = kVPPrivacyPolicyWebUrl
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
case .userAgreement:
|
||||
let vc = VPWebViewController()
|
||||
vc.urlStr = kVPUserAgreementWebUrl
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
case .aboutUs:
|
||||
let vc = VPAboutUsViewController()
|
||||
self.navigationController?.pushViewController(vc, animated: true)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPMeViewController {
|
||||
|
||||
|
||||
///获取用户信息
|
||||
private func requestUserInfo() {
|
||||
VPLoginManager.manager.updateUserInfo { [weak self] in
|
||||
self?.tableView.reloadData()
|
||||
}
|
||||
}
|
||||
}
|
27
Veloria/Class/Me/Model/VPMeItem.swift
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// VPMeItem.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
struct VPMeItem {
|
||||
enum ItemType {
|
||||
case privacyPolicy
|
||||
case userAgreement
|
||||
case aboutUs
|
||||
case feedback
|
||||
}
|
||||
|
||||
enum CellKey: String {
|
||||
case normal
|
||||
case userInfo
|
||||
}
|
||||
|
||||
var icon: UIImage?
|
||||
var title: String?
|
||||
var type: ItemType?
|
||||
var cellKey: CellKey?
|
||||
}
|
69
Veloria/Class/Me/View/VPMeCell.swift
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// VPMeCell.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPMeCell: VPTableViewCell {
|
||||
|
||||
var item: VPMeItem? {
|
||||
didSet {
|
||||
titleLabel.text = item?.title
|
||||
iconImageView.image = item?.icon
|
||||
}
|
||||
}
|
||||
|
||||
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 = .colorFFFFFF()
|
||||
return label
|
||||
}()
|
||||
|
||||
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
contentView.backgroundColor = .colorFFFFFF(alpha: 0.1)
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
extension VPMeCell {
|
||||
|
||||
private func vp_setupUI() {
|
||||
contentView.addSubview(iconImageView)
|
||||
contentView.addSubview(titleLabel)
|
||||
contentView.addSubview(indicatorImageView)
|
||||
|
||||
iconImageView.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(10)
|
||||
make.width.height.equalTo(20)
|
||||
make.top.equalToSuperview().offset(18)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(39)
|
||||
}
|
||||
|
||||
indicatorImageView.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.right.equalToSuperview().offset(-10)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
89
Veloria/Class/Me/View/VPMeUserInfoCell.swift
Normal file
@ -0,0 +1,89 @@
|
||||
//
|
||||
// VPMeUserInfoCell.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPMeUserInfoCell: VPTableViewCell {
|
||||
|
||||
|
||||
var userInfo: VPUserInfo? {
|
||||
didSet {
|
||||
avatarImageView.vp_setImage(url: userInfo?.avator, placeholder: UIImage(named: "avatar_placeholder_icon_01"))
|
||||
|
||||
if let name = userInfo?.family_name, name.count > 0 {
|
||||
nicknameLabel.text = name
|
||||
} else {
|
||||
nicknameLabel.text = "Visitor".localized
|
||||
}
|
||||
|
||||
idLabel.text = "ID \(userInfo?.customer_id ?? "")"
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var avatarImageView: VPImageView = {
|
||||
let imageView = VPImageView()
|
||||
imageView.layer.cornerRadius = 22
|
||||
imageView.layer.masksToBounds = true
|
||||
imageView.layer.borderWidth = 1
|
||||
imageView.layer.borderColor = UIColor.colorFFFFFF().cgColor
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var nicknameLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontBold(ofSize: 16)
|
||||
label.textColor = .colorFFFFFF()
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var idLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
label.textColor = .colorB5B5B5()
|
||||
return label
|
||||
}()
|
||||
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
|
||||
bc_setupUI()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPMeUserInfoCell {
|
||||
|
||||
private func bc_setupUI() {
|
||||
contentView.addSubview(avatarImageView)
|
||||
contentView.addSubview(nicknameLabel)
|
||||
contentView.addSubview(idLabel)
|
||||
|
||||
avatarImageView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview()
|
||||
make.bottom.equalToSuperview()
|
||||
make.width.height.equalTo(44)
|
||||
make.top.equalToSuperview().offset(36)
|
||||
}
|
||||
|
||||
nicknameLabel.snp.makeConstraints { make in
|
||||
make.top.equalTo(avatarImageView).offset(3)
|
||||
make.left.equalTo(avatarImageView.snp.right).offset(10)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-170)
|
||||
}
|
||||
|
||||
idLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(nicknameLabel)
|
||||
make.bottom.equalTo(avatarImageView).offset(-3)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -14,14 +14,18 @@ class VPCollectListViewController: VPViewController {
|
||||
didSet {
|
||||
allSelectedButton.isHidden = editState == .normal
|
||||
if editState == .normal {
|
||||
collectionView.snp.updateConstraints { make in
|
||||
make.top.equalToSuperview().offset(0)
|
||||
if collectionView.superview != nil {
|
||||
collectionView.snp.updateConstraints { make in
|
||||
make.top.equalToSuperview().offset(0)
|
||||
}
|
||||
}
|
||||
isAllSelected = false
|
||||
allSelectedButton.isSelected = false
|
||||
} else {
|
||||
collectionView.snp.updateConstraints { make in
|
||||
make.top.equalToSuperview().offset(30)
|
||||
if collectionView.superview != nil {
|
||||
collectionView.snp.updateConstraints { make in
|
||||
make.top.equalToSuperview().offset(30)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,6 +105,7 @@ class VPCollectListViewController: VPViewController {
|
||||
collectionView.delegate = self
|
||||
collectionView.dataSource = self
|
||||
collectionView.contentInset = .init(top: 5, left: 0, bottom: 0, right: 0)
|
||||
collectionView.vp_addNormalEmpty()
|
||||
collectionView.vp_addRefreshHeader(insetTop: collectionView.top) { [weak self] in
|
||||
self?.handleHeaderRefresh(nil)
|
||||
}
|
||||
@ -146,7 +151,7 @@ class VPCollectListViewController: VPViewController {
|
||||
if count > 0 {
|
||||
requestCancelCollect()
|
||||
} else {
|
||||
VPToast.show(text: "kToastText1")
|
||||
VPToast.show(text: "kToastText1".localized)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ class VPMyListViewController: VPViewController {
|
||||
return param
|
||||
}()
|
||||
|
||||
private lazy var pageView: WMZPageView = {
|
||||
private(set) lazy var pageView: WMZPageView = {
|
||||
let y = UIScreen.statusBarHeight + 10
|
||||
let height = UIScreen.height - y - UIScreen.customTabBarHeight
|
||||
|
||||
@ -120,6 +120,7 @@ class VPMyListViewController: VPViewController {
|
||||
super.viewDidLoad()
|
||||
|
||||
vp_setupUI()
|
||||
// pageView.selectMenu(with: 1)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@ -131,6 +132,12 @@ class VPMyListViewController: VPViewController {
|
||||
super.viewDidDisappear(animated)
|
||||
self.editState = .normal
|
||||
}
|
||||
|
||||
func showHistoryPage() {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in
|
||||
self?.pageView.selectMenu(with: 1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@ class VPWatchHistoryViewController: VPViewController {
|
||||
tableView.dataSource = self
|
||||
tableView.separatorStyle = .none
|
||||
tableView.rowHeight = 118
|
||||
tableView.vp_addNormalEmpty()
|
||||
tableView.vp_addRefreshHeader { [weak self] in
|
||||
self?.handleHeaderRefresh(nil)
|
||||
}
|
||||
|
@ -194,9 +194,7 @@ extension VPVideoPlayerCell: VPPlayerDelegate {
|
||||
}
|
||||
|
||||
func vp_player(_ player: VPPlayer, playStateDidChanged state: VPPlayer.PlayState) {
|
||||
if state == .playing {
|
||||
self.coverImageView.isHidden = true
|
||||
}
|
||||
updateCoverShowState()
|
||||
}
|
||||
|
||||
func vp_player(_ player: VPPlayer, loadStateDidChange state: VPPlayer.LoadState) {
|
||||
@ -205,10 +203,19 @@ extension VPVideoPlayerCell: VPPlayerDelegate {
|
||||
} else {
|
||||
self.controlView.isLoading = false
|
||||
}
|
||||
updateCoverShowState()
|
||||
}
|
||||
|
||||
func vp_playerReadyToPlay(_ player: VPPlayer) {
|
||||
self.seekToTime(toTime: (videoInfo?.play_seconds ?? 0) / 1000)
|
||||
}
|
||||
|
||||
private func updateCoverShowState() {
|
||||
let loadState = self.player.loadState
|
||||
let playState = self.player.playState
|
||||
if isCurrent && (loadState == .playable || loadState == .playthroughOK) && (playState == .playing) {
|
||||
self.coverImageView.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
20
Veloria/Libs/Empty/UIScrollView+Empty.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// UIScrollView+Empty.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import EmptyDataSet_Swift
|
||||
|
||||
extension UIScrollView {
|
||||
func vp_addNormalEmpty(image: UIImage? = UIImage(named: "empty_image_01"), title: String? = nil, titleColor: UIColor? = nil) {
|
||||
|
||||
self.emptyDataSetView { view in
|
||||
view.image(image)
|
||||
.isScrollAllowed(true)
|
||||
.verticalOffset(-100)
|
||||
}
|
||||
}
|
||||
}
|
@ -8,16 +8,13 @@
|
||||
import UIKit
|
||||
|
||||
class VPHUD: NSObject {
|
||||
static func config() {
|
||||
// SVProgressHUD.setDefaultMaskType(.clear)
|
||||
}
|
||||
|
||||
static func show() {
|
||||
// SVProgressHUD.setDefaultMaskType(.clear)
|
||||
// SVProgressHUD.show()
|
||||
SVProgressHUD.setDefaultMaskType(.clear)
|
||||
SVProgressHUD.show()
|
||||
}
|
||||
|
||||
static func dismiss() {
|
||||
// SVProgressHUD.dismiss()
|
||||
SVProgressHUD.dismiss()
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,6 @@ class VPToast: NSObject {
|
||||
|
||||
static func show(text: String?) {
|
||||
guard let text = text else { return }
|
||||
// SPAPPTool.getKeyWindow()?.makeToast(text)
|
||||
VPAppTool.keyWindow?.makeToast(text)
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,35 @@ class VPLoginManager: NSObject {
|
||||
static let manager = VPLoginManager()
|
||||
|
||||
private(set) var token: VPTokenModel?
|
||||
private(set) var userInfo: VPUserInfo?
|
||||
|
||||
///是否正在刷新token
|
||||
private(set) var isRefreshingToken = false
|
||||
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
token = UserDefaults.vp_object(forKey: kVPLoginTokenDefaultsKey, as: VPTokenModel.self)
|
||||
userInfo = UserDefaults.vp_object(forKey: kVPLoginUserInfoDefaultsKey, as: VPUserInfo.self)
|
||||
}
|
||||
|
||||
func setLoginToken(token: VPTokenModel?) {
|
||||
self.token = token
|
||||
// UserDefaults.jx_setObject(token, forKey: kSPLoginTokenDefaultsKey)
|
||||
UserDefaults.vp_setObject(token, forKey: kVPLoginTokenDefaultsKey)
|
||||
}
|
||||
|
||||
|
||||
///更新用户信息
|
||||
func updateUserInfo(completer: (() -> Void)?) {
|
||||
|
||||
VPUserAPI.requestUserInfo { [weak self] userInfo in
|
||||
guard let self = self else { return }
|
||||
if let userInfo = userInfo {
|
||||
self.userInfo = userInfo
|
||||
UserDefaults.vp_setObject(userInfo, forKey: kVPLoginUserInfoDefaultsKey)
|
||||
}
|
||||
completer?()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
67
Veloria/Libs/User/VPUserInfo.swift
Normal file
@ -0,0 +1,67 @@
|
||||
//
|
||||
// VPUserInfo.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/5/26.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
class VPUserInfo: VPModel, SmartCodable, NSSecureCoding {
|
||||
|
||||
var id: String?
|
||||
var customer_id: String?
|
||||
var is_guide_vip: String?
|
||||
///是否为游客登录
|
||||
var is_tourist: Bool?
|
||||
var family_name: String?
|
||||
var giving_name: String?
|
||||
var vip_end_time: TimeInterval?
|
||||
var third_access_id: String?
|
||||
var is_vip: Bool?
|
||||
var coin_left_total: Int?
|
||||
var send_coin_left_total: Int?
|
||||
var vip_type: String?
|
||||
var email: String?
|
||||
var third_access_platform: String?
|
||||
var ip_address: String?
|
||||
var country_code: String?
|
||||
var user_level: String?
|
||||
var avator: String?
|
||||
var sign_in_status: String?
|
||||
var registered_days: String?
|
||||
var ln: String?
|
||||
var country: String?
|
||||
|
||||
|
||||
required init() { }
|
||||
|
||||
static var supportsSecureCoding: Bool {
|
||||
get {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func encode(with coder: NSCoder) {
|
||||
// coder.encode(id, forKey: "id")
|
||||
// coder.encode(phone, forKey: "phone")
|
||||
// coder.encode(userToken, forKey: "userToken")
|
||||
// coder.encode(ipAddress, forKey: "ipAddress")
|
||||
// coder.encode(audioNum, forKey: "audioNum")
|
||||
// coder.encode(audioSeconds, forKey: "audioSeconds")
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init()
|
||||
|
||||
// id = coder.decodeObject(of: NSString.self, forKey: "id") as? String
|
||||
// phone = coder.decodeObject(of: NSString.self, forKey: "phone") as? String
|
||||
// userToken = coder.decodeObject(of: NSString.self, forKey: "userToken") as? String
|
||||
// ipAddress = coder.decodeObject(of: NSString.self, forKey: "ipAddress") as? String
|
||||
// audioNum = coder.decodeObject(of: NSNumber.self, forKey: "audioNum")?.intValue
|
||||
// audioSeconds = coder.decodeObject(of: NSNumber.self, forKey: "audioSeconds")?.intValue
|
||||
}
|
||||
|
||||
}
|
@ -18,5 +18,8 @@
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "original"
|
||||
}
|
||||
}
|
||||
|
22
Veloria/Source/Assets.xcassets/icon/arrow_right_icon_02.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/arrow_right_icon_02.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 312 B |
BIN
Veloria/Source/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 458 B |
22
Veloria/Source/Assets.xcassets/icon/avatar_placeholder_icon_01.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/avatar_placeholder_icon_01.imageset/头像@2x.png
vendored
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/avatar_placeholder_icon_01.imageset/头像@3x.png
vendored
Normal file
After Width: | Height: | Size: 30 KiB |
22
Veloria/Source/Assets.xcassets/icon/me_item_icon_01.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_01.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/me_item_icon_01.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.7 KiB |
22
Veloria/Source/Assets.xcassets/icon/me_item_icon_02.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_02.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 943 B |
BIN
Veloria/Source/Assets.xcassets/icon/me_item_icon_02.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.3 KiB |
22
Veloria/Source/Assets.xcassets/icon/me_item_icon_03.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_03.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/me_item_icon_03.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.8 KiB |
22
Veloria/Source/Assets.xcassets/icon/me_item_icon_04.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_04.imageset/Frame@2x.png
vendored
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/me_item_icon_04.imageset/Frame@3x.png
vendored
Normal file
After Width: | Height: | Size: 1.8 KiB |
22
Veloria/Source/Assets.xcassets/image/empty_image_01.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/image/empty_image_01.imageset/缺省页-内容为空-切图图层@2x.png
vendored
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
Veloria/Source/Assets.xcassets/image/empty_image_01.imageset/缺省页-内容为空-切图图层@3x.png
vendored
Normal file
After Width: | Height: | Size: 74 KiB |
@ -10,3 +10,4 @@
|
||||
#import <ZFPlayer.h>
|
||||
#import <KTVHTTPCache/KTVHTTPCache.h>
|
||||
#import <HWPanModal/HWPanModal.h>
|
||||
#import <SVProgressHUD/SVProgressHUD.h>
|
||||
|
@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
"Home" = "Home";
|
||||
"Me" = "Me";
|
||||
"All" = "All";
|
||||
"Drama Champions" = "Drama Champions";
|
||||
"Explore" = "Explore";
|
||||
@ -20,6 +21,15 @@
|
||||
"My List" = "My List";
|
||||
"History" = "History";
|
||||
"Select All" = "Select All";
|
||||
"Privacy Policy" = "Privacy Policy";
|
||||
"User Agreement" = "User Agreement";
|
||||
"About Us" = "About Us";
|
||||
"Visitor" = "Visitor";
|
||||
"Help Center" = "Help Center";
|
||||
"Feedback History" = "Feedback History";
|
||||
"Feedback" = "Feedback";
|
||||
"Feedback Details" = "Feedback Details";
|
||||
"Rewards" = "Rewards";
|
||||
|
||||
|
||||
"kHomeTitleText" = "10,000+ addictive shorts await!";
|
||||
|