Compare commits
No commits in common. "main" and "1.0" have entirely different histories.
3
.gitignore
vendored
3
.gitignore
vendored
@ -66,7 +66,7 @@ xcuserdata/
|
|||||||
|
|
||||||
## Playgrounds
|
## Playgrounds
|
||||||
timeline.xctimeline
|
timeline.xctimeline
|
||||||
*.xcworkspace
|
playground.xcworkspace
|
||||||
|
|
||||||
# Swift Package Manager
|
# Swift Package Manager
|
||||||
#
|
#
|
||||||
@ -89,7 +89,6 @@ timeline.xctimeline
|
|||||||
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||||
#
|
#
|
||||||
Pods/
|
Pods/
|
||||||
Podfile.lock
|
|
||||||
#
|
#
|
||||||
# Add this line if you want to avoid checking in source code from the Xcode workspace
|
# Add this line if you want to avoid checking in source code from the Xcode workspace
|
||||||
# *.xcworkspace
|
# *.xcworkspace
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
Thimra 开发者账号信息
|
|
||||||
认证人 :陈佳
|
|
||||||
认证设备 :Mac min
|
|
||||||
设备型号 :MU9D3CH/A
|
|
||||||
序列号 :TVJJ97WWHH
|
|
||||||
手机号码 :190 7319 2960
|
|
||||||
|
|
||||||
企业邮箱 :thimra@thimratv.com 密码:9oldpGT_y0qR
|
|
||||||
D-U-N-S:457012112
|
|
||||||
公司主体 :Changsha Jiaer Network Technology Co., Ltd.
|
|
||||||
公司地址 :Room 15006, Xijing Commercial Plaza, No. 383 Jinxing Middle Road
|
|
||||||
官网 :https://www.thimratv.com
|
|
||||||
appleId :cs.jiaer.developer@icloud.com
|
|
||||||
密码 :Discover2024
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
账户持有人:
|
|
||||||
Hong Kong Qin Jiu Media Culture Co., Limited
|
|
||||||
银行账号:
|
|
||||||
9558851001034420709
|
|
||||||
复制
|
|
||||||
币种:
|
|
||||||
USD
|
|
||||||
费率:
|
|
||||||
0.7%
|
|
||||||
银行名称:
|
|
||||||
Industrial And Commercial Bank Of China Shanghai Pilot Free Trade Zone Branch Xinling Road Sub-Branch
|
|
||||||
Swift Code:
|
|
||||||
ICBKCNBJSHI
|
|
||||||
CNAPS代码
|
|
||||||
102290019237
|
|
||||||
银行所在国家/地区:
|
|
||||||
China
|
|
||||||
银行地址:
|
|
||||||
NO.118 Xinling Rd Shanghai Branch
|
|
||||||
|
|
||||||
|
|
||||||
沙盒账号:
|
|
||||||
jiaer@test.com
|
|
||||||
Cje12345
|
|
45
Podfile
45
Podfile
@ -1,38 +1,41 @@
|
|||||||
# Uncomment the next line to define a global platform for your project
|
# Uncomment the next line to define a global platform for your project
|
||||||
source 'https://github.com/CocoaPods/Specs.git'
|
platform :ios, '15.6'
|
||||||
platform :ios, '15.0'
|
#source 'https://github.com/CocoaPods/Specs'
|
||||||
|
source 'https://cdn.cocoapods.org/'
|
||||||
|
|
||||||
post_install do |installer|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
target.build_configurations.each do |config|
|
target.build_configurations.each do |config|
|
||||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||||
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
|
||||||
config.build_settings['EXCLUDED_ARCHITECTURES'] = 'i386'
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
installer.pods_project.build_configurations.each do |config|
|
||||||
|
config.build_settings["EXCLUDED_ARCHS[sdk=iphonesimulator*]"] = "arm64"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
target 'ThimraTV' do
|
|
||||||
|
target 'Thimra' do
|
||||||
# Comment the next line if you don't want to use dynamic frameworks
|
# Comment the next line if you don't want to use dynamic frameworks
|
||||||
use_frameworks!
|
use_frameworks!
|
||||||
|
|
||||||
pod 'Moya' #网络框架
|
pod 'Moya' #网络框架
|
||||||
pod 'SnapKit' #布局
|
pod 'SnapKit' #布局
|
||||||
pod 'SmartCodable' #数据解析
|
pod 'SmartCodable' #数据解析
|
||||||
pod 'YYKit' #工具类
|
pod 'YYKit' #工具类
|
||||||
pod 'MJRefresh' #刷新控件
|
pod 'MJRefresh' #刷新控件
|
||||||
pod 'Toast' #吐司提示
|
pod 'Toast' #吐司提示
|
||||||
pod 'ZFPlayer/AVPlayer' #播放器
|
pod 'ZFPlayer/AVPlayer' #播放器
|
||||||
pod 'KTVHTTPCache' #视频缓存
|
pod 'KTVHTTPCache' #视频缓存
|
||||||
pod 'HWPanModal' #底部弹出控制器
|
pod 'HWPanModal' #底部弹出控制器
|
||||||
pod 'Kingfisher' #图片加载
|
pod 'Kingfisher' #图片加载
|
||||||
# pod 'KingfisherWebP'
|
pod 'EmptyStateKit' #空数据页面
|
||||||
pod 'EmptyDataSet-Swift' #空数据页面
|
pod 'ReachabilitySwift' #网络状态监控
|
||||||
pod 'ReachabilitySwift' #网络状态监控
|
pod 'WMZPageController' #分页控制器
|
||||||
pod 'WMZPageController' #分页控制器
|
pod 'SVProgressHUD' #HUD
|
||||||
pod 'SVProgressHUD' #HUD
|
|
||||||
pod 'TZImagePickerController' #相册
|
|
||||||
pod 'Adjust' # Adjust
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
40
Podfile.lock
40
Podfile.lock
@ -1,14 +1,9 @@
|
|||||||
PODS:
|
PODS:
|
||||||
- Adjust (5.4.0):
|
|
||||||
- Adjust/Adjust (= 5.4.0)
|
|
||||||
- Adjust/Adjust (5.4.0):
|
|
||||||
- AdjustSignature (= 3.35.2)
|
|
||||||
- AdjustSignature (3.35.2)
|
|
||||||
- Alamofire (5.10.2)
|
- Alamofire (5.10.2)
|
||||||
- CocoaAsyncSocket (7.6.5)
|
- CocoaAsyncSocket (7.6.5)
|
||||||
- EmptyDataSet-Swift (5.0.0)
|
- EmptyStateKit (1.1.0)
|
||||||
- HWPanModal (0.9.9)
|
- HWPanModal (0.9.9)
|
||||||
- Kingfisher (8.3.2)
|
- Kingfisher (8.3.1)
|
||||||
- KTVHTTPCache (3.0.2):
|
- KTVHTTPCache (3.0.2):
|
||||||
- CocoaAsyncSocket
|
- CocoaAsyncSocket
|
||||||
- MJRefresh (3.7.9)
|
- MJRefresh (3.7.9)
|
||||||
@ -17,19 +12,12 @@ PODS:
|
|||||||
- Moya/Core (15.0.0):
|
- Moya/Core (15.0.0):
|
||||||
- Alamofire (~> 5.0)
|
- Alamofire (~> 5.0)
|
||||||
- ReachabilitySwift (5.2.4)
|
- ReachabilitySwift (5.2.4)
|
||||||
- SmartCodable (5.0.9):
|
- SmartCodable (4.3.2)
|
||||||
- SmartCodable/Core (= 5.0.9)
|
|
||||||
- SmartCodable/Core (5.0.9)
|
|
||||||
- SnapKit (5.7.1)
|
- SnapKit (5.7.1)
|
||||||
- SVProgressHUD (2.3.1):
|
- SVProgressHUD (2.3.1):
|
||||||
- SVProgressHUD/Core (= 2.3.1)
|
- SVProgressHUD/Core (= 2.3.1)
|
||||||
- SVProgressHUD/Core (2.3.1)
|
- SVProgressHUD/Core (2.3.1)
|
||||||
- Toast (4.1.1)
|
- Toast (4.1.1)
|
||||||
- TZImagePickerController (3.8.8):
|
|
||||||
- TZImagePickerController/Basic (= 3.8.8)
|
|
||||||
- TZImagePickerController/Location (= 3.8.8)
|
|
||||||
- TZImagePickerController/Basic (3.8.8)
|
|
||||||
- TZImagePickerController/Location (3.8.8)
|
|
||||||
- WMZPageController (1.5.5)
|
- WMZPageController (1.5.5)
|
||||||
- YYKit (1.0.9):
|
- YYKit (1.0.9):
|
||||||
- YYKit/no-arc (= 1.0.9)
|
- YYKit/no-arc (= 1.0.9)
|
||||||
@ -39,8 +27,7 @@ PODS:
|
|||||||
- ZFPlayer/Core (4.1.4)
|
- ZFPlayer/Core (4.1.4)
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- Adjust
|
- EmptyStateKit
|
||||||
- EmptyDataSet-Swift
|
|
||||||
- HWPanModal
|
- HWPanModal
|
||||||
- Kingfisher
|
- Kingfisher
|
||||||
- KTVHTTPCache
|
- KTVHTTPCache
|
||||||
@ -51,18 +38,15 @@ DEPENDENCIES:
|
|||||||
- SnapKit
|
- SnapKit
|
||||||
- SVProgressHUD
|
- SVProgressHUD
|
||||||
- Toast
|
- Toast
|
||||||
- TZImagePickerController
|
|
||||||
- WMZPageController
|
- WMZPageController
|
||||||
- YYKit
|
- YYKit
|
||||||
- ZFPlayer/AVPlayer
|
- ZFPlayer/AVPlayer
|
||||||
|
|
||||||
SPEC REPOS:
|
SPEC REPOS:
|
||||||
https://github.com/CocoaPods/Specs.git:
|
trunk:
|
||||||
- Adjust
|
|
||||||
- AdjustSignature
|
|
||||||
- Alamofire
|
- Alamofire
|
||||||
- CocoaAsyncSocket
|
- CocoaAsyncSocket
|
||||||
- EmptyDataSet-Swift
|
- EmptyStateKit
|
||||||
- HWPanModal
|
- HWPanModal
|
||||||
- Kingfisher
|
- Kingfisher
|
||||||
- KTVHTTPCache
|
- KTVHTTPCache
|
||||||
@ -73,32 +57,28 @@ SPEC REPOS:
|
|||||||
- SnapKit
|
- SnapKit
|
||||||
- SVProgressHUD
|
- SVProgressHUD
|
||||||
- Toast
|
- Toast
|
||||||
- TZImagePickerController
|
|
||||||
- WMZPageController
|
- WMZPageController
|
||||||
- YYKit
|
- YYKit
|
||||||
- ZFPlayer
|
- ZFPlayer
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
Adjust: a5f881d0cbfe9a6df979b076dc7116fe19ece797
|
|
||||||
AdjustSignature: 23b9e5d4adcadffc303bb6b410fde617dd88504f
|
|
||||||
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
|
||||||
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
|
||||||
EmptyDataSet-Swift: eb382c0c87a2d9c678077385a595cec52da38171
|
EmptyStateKit: dc41e9ce5c6089f67a49d063bce73ade9f2ba73f
|
||||||
HWPanModal: b57a6717d3cdcd666bff44f9dd2a5be9f4d6f5d2
|
HWPanModal: b57a6717d3cdcd666bff44f9dd2a5be9f4d6f5d2
|
||||||
Kingfisher: 0621d0ac0c78fecb19f6dc5303bde2b52abaf2f5
|
Kingfisher: 3204d23de16b5ea53541c44ca5a8efb55741dec3
|
||||||
KTVHTTPCache: 5711692cdf9a5ecfe829b1e16577deb3ffe3dc86
|
KTVHTTPCache: 5711692cdf9a5ecfe829b1e16577deb3ffe3dc86
|
||||||
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
|
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
|
||||||
Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee
|
Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee
|
||||||
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
|
ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
|
||||||
SmartCodable: 68b3598438181a938eed8ee5623e58ef3e3ea443
|
SmartCodable: 88fbf3d65207c2376fdbce4b080a3d578cb51be8
|
||||||
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
|
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
|
||||||
SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
|
SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
|
||||||
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
|
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
|
||||||
TZImagePickerController: d084a7b97c82d387e7669dd86dc9a9057500aacf
|
|
||||||
WMZPageController: 87dd82d1e3528cd362de19b9a74fd6890d6e1906
|
WMZPageController: 87dd82d1e3528cd362de19b9a74fd6890d6e1906
|
||||||
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
|
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
|
||||||
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
|
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
|
||||||
|
|
||||||
PODFILE CHECKSUM: 25e7f44d27dd18aad94fde84cae1f0c157c60341
|
PODFILE CHECKSUM: a2c39b60a617ef47e0a8a03d4115500405588542
|
||||||
|
|
||||||
COCOAPODS: 1.16.2
|
COCOAPODS: 1.16.2
|
||||||
|
437
Thimra.xcodeproj/project.pbxproj
Normal file
437
Thimra.xcodeproj/project.pbxproj
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 77;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
510C67DE404B0A4C9F4E89C3 /* Pods_Thimra.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EF2D7FDB1FE86E5CD9908162 /* Pods_Thimra.framework */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
1DBC40592DA4EDFC0093FCB0 /* Thimra.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Thimra.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
EF2D7FDB1FE86E5CD9908162 /* Pods_Thimra.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Thimra.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
F7763FEFB6BEB1A75D6FBA0A /* Pods-Thimra.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Thimra.debug.xcconfig"; path = "Target Support Files/Pods-Thimra/Pods-Thimra.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
FEA583158A7C05D8D7C5A9FC /* Pods-Thimra.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Thimra.release.xcconfig"; path = "Target Support Files/Pods-Thimra/Pods-Thimra.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
1DBC41052DA4F98D0093FCB0 /* Exceptions for "Thimra" folder in "Thimra" target */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
|
||||||
|
membershipExceptions = (
|
||||||
|
Source/Info.plist,
|
||||||
|
);
|
||||||
|
target = 1DBC40582DA4EDFC0093FCB0 /* Thimra */;
|
||||||
|
};
|
||||||
|
/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */
|
||||||
|
|
||||||
|
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
1DBC40FB2DA4F98D0093FCB0 /* Thimra */ = {
|
||||||
|
isa = PBXFileSystemSynchronizedRootGroup;
|
||||||
|
exceptions = (
|
||||||
|
1DBC41052DA4F98D0093FCB0 /* Exceptions for "Thimra" folder in "Thimra" target */,
|
||||||
|
);
|
||||||
|
path = Thimra;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXFileSystemSynchronizedRootGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
1DBC40562DA4EDFC0093FCB0 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
510C67DE404B0A4C9F4E89C3 /* Pods_Thimra.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
0061C3496D158807460301A9 /* Pods */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
F7763FEFB6BEB1A75D6FBA0A /* Pods-Thimra.debug.xcconfig */,
|
||||||
|
FEA583158A7C05D8D7C5A9FC /* Pods-Thimra.release.xcconfig */,
|
||||||
|
);
|
||||||
|
path = Pods;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
1DBC40502DA4EDFC0093FCB0 = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1DBC40FB2DA4F98D0093FCB0 /* Thimra */,
|
||||||
|
1DBC405A2DA4EDFC0093FCB0 /* Products */,
|
||||||
|
0061C3496D158807460301A9 /* Pods */,
|
||||||
|
B6C9E282BAC4C4B3E926A853 /* Frameworks */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
1DBC405A2DA4EDFC0093FCB0 /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1DBC40592DA4EDFC0093FCB0 /* Thimra.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
B6C9E282BAC4C4B3E926A853 /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
EF2D7FDB1FE86E5CD9908162 /* Pods_Thimra.framework */,
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
1DBC40582DA4EDFC0093FCB0 /* Thimra */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 1DBC40822DA4EE010093FCB0 /* Build configuration list for PBXNativeTarget "Thimra" */;
|
||||||
|
buildPhases = (
|
||||||
|
801A3E3FF53193556BBE9EBF /* [CP] Check Pods Manifest.lock */,
|
||||||
|
1DBC40552DA4EDFC0093FCB0 /* Sources */,
|
||||||
|
1DBC40562DA4EDFC0093FCB0 /* Frameworks */,
|
||||||
|
1DBC40572DA4EDFC0093FCB0 /* Resources */,
|
||||||
|
99BF4E2B3615B1F54D05DA28 /* [CP] Embed Pods Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
fileSystemSynchronizedGroups = (
|
||||||
|
1DBC40FB2DA4F98D0093FCB0 /* Thimra */,
|
||||||
|
);
|
||||||
|
name = Thimra;
|
||||||
|
productName = ShortPlay;
|
||||||
|
productReference = 1DBC40592DA4EDFC0093FCB0 /* Thimra.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
1DBC40512DA4EDFC0093FCB0 /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
BuildIndependentTargetsInParallel = 1;
|
||||||
|
LastSwiftUpdateCheck = 1620;
|
||||||
|
LastUpgradeCheck = 1620;
|
||||||
|
TargetAttributes = {
|
||||||
|
1DBC40582DA4EDFC0093FCB0 = {
|
||||||
|
CreatedOnToolsVersion = 16.2;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = 1DBC40542DA4EDFC0093FCB0 /* Build configuration list for PBXProject "Thimra" */;
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = 1DBC40502DA4EDFC0093FCB0;
|
||||||
|
minimizedProjectReferenceProxies = 1;
|
||||||
|
preferredProjectObjectVersion = 77;
|
||||||
|
productRefGroup = 1DBC405A2DA4EDFC0093FCB0 /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
1DBC40582DA4EDFC0093FCB0 /* Thimra */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
1DBC40572DA4EDFC0093FCB0 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXShellScriptBuildPhase section */
|
||||||
|
801A3E3FF53193556BBE9EBF /* [CP] Check Pods Manifest.lock */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
);
|
||||||
|
inputPaths = (
|
||||||
|
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||||
|
"${PODS_ROOT}/Manifest.lock",
|
||||||
|
);
|
||||||
|
name = "[CP] Check Pods Manifest.lock";
|
||||||
|
outputFileListPaths = (
|
||||||
|
);
|
||||||
|
outputPaths = (
|
||||||
|
"$(DERIVED_FILE_DIR)/Pods-Thimra-checkManifestLockResult.txt",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
99BF4E2B3615B1F54D05DA28 /* [CP] Embed Pods Frameworks */ = {
|
||||||
|
isa = PBXShellScriptBuildPhase;
|
||||||
|
buildActionMask = 12;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
inputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Thimra/Pods-Thimra-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||||
|
);
|
||||||
|
name = "[CP] Embed Pods Frameworks";
|
||||||
|
outputFileListPaths = (
|
||||||
|
"${PODS_ROOT}/Target Support Files/Pods-Thimra/Pods-Thimra-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
shellPath = /bin/sh;
|
||||||
|
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Thimra/Pods-Thimra-frameworks.sh\"\n";
|
||||||
|
showEnvVarsInLog = 0;
|
||||||
|
};
|
||||||
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
1DBC40552DA4EDFC0093FCB0 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
1DBC40832DA4EE010093FCB0 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = F7763FEFB6BEB1A75D6FBA0A /* Pods-Thimra.debug.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$(ARCHS_STANDARD)";
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = TWDZ3MP9DV;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = Thimra/Source/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Thimra;
|
||||||
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
|
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
||||||
|
INFOPLIST_KEY_UIStatusBarHidden = YES;
|
||||||
|
INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleLightContent;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "Thimra/Source/Thimra-Bridging-Header.h";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
|
VALID_ARCHS = "arm64 arm64e armv7s x86_64";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
1DBC40842DA4EE010093FCB0 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
baseConfigurationReference = FEA583158A7C05D8D7C5A9FC /* Pods-Thimra.release.xcconfig */;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$(ARCHS_STANDARD)";
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = TWDZ3MP9DV;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = NO;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = Thimra/Source/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = Thimra;
|
||||||
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
|
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
|
||||||
|
INFOPLIST_KEY_UIMainStoryboardFile = "";
|
||||||
|
INFOPLIST_KEY_UIStatusBarHidden = YES;
|
||||||
|
INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleLightContent;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.6;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = com.thimratv.app;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OBJC_BRIDGING_HEADER = "Thimra/Source/Thimra-Bridging-Header.h";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
|
VALID_ARCHS = "arm64 arm64e armv7s x86_64";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
1DBC40852DA4EE010093FCB0 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 18.2;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)";
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
1DBC40862DA4EE010093FCB0 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
|
||||||
|
CLANG_ANALYZER_NONNULL = YES;
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_USER_SCRIPT_SANDBOXING = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu17;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 18.2;
|
||||||
|
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = NO;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
SDKROOT = iphoneos;
|
||||||
|
SWIFT_COMPILATION_MODE = wholemodule;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
1DBC40542DA4EDFC0093FCB0 /* Build configuration list for PBXProject "Thimra" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
1DBC40852DA4EE010093FCB0 /* Debug */,
|
||||||
|
1DBC40862DA4EE010093FCB0 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
1DBC40822DA4EE010093FCB0 /* Build configuration list for PBXNativeTarget "Thimra" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
1DBC40832DA4EE010093FCB0 /* Debug */,
|
||||||
|
1DBC40842DA4EE010093FCB0 /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = 1DBC40512DA4EDFC0093FCB0 /* Project object */;
|
||||||
|
}
|
@ -16,9 +16,9 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "1DBC40582DA4EDFC0093FCB0"
|
BlueprintIdentifier = "1DBC40582DA4EDFC0093FCB0"
|
||||||
BuildableName = "ThimraTV.app"
|
BuildableName = "Thimra.app"
|
||||||
BlueprintName = "ThimraTV"
|
BlueprintName = "Thimra"
|
||||||
ReferencedContainer = "container:ThimraTV.xcodeproj">
|
ReferencedContainer = "container:Thimra.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildActionEntry>
|
</BuildActionEntry>
|
||||||
</BuildActionEntries>
|
</BuildActionEntries>
|
||||||
@ -45,9 +45,9 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "1DBC40582DA4EDFC0093FCB0"
|
BlueprintIdentifier = "1DBC40582DA4EDFC0093FCB0"
|
||||||
BuildableName = "ThimraTV.app"
|
BuildableName = "Thimra.app"
|
||||||
BlueprintName = "ThimraTV"
|
BlueprintName = "Thimra"
|
||||||
ReferencedContainer = "container:ThimraTV.xcodeproj">
|
ReferencedContainer = "container:Thimra.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</LaunchAction>
|
</LaunchAction>
|
||||||
@ -62,9 +62,9 @@
|
|||||||
<BuildableReference
|
<BuildableReference
|
||||||
BuildableIdentifier = "primary"
|
BuildableIdentifier = "primary"
|
||||||
BlueprintIdentifier = "1DBC40582DA4EDFC0093FCB0"
|
BlueprintIdentifier = "1DBC40582DA4EDFC0093FCB0"
|
||||||
BuildableName = "ThimraTV.app"
|
BuildableName = "Thimra.app"
|
||||||
BlueprintName = "ThimraTV"
|
BlueprintName = "Thimra"
|
||||||
ReferencedContainer = "container:ThimraTV.xcodeproj">
|
ReferencedContainer = "container:Thimra.xcodeproj">
|
||||||
</BuildableReference>
|
</BuildableReference>
|
||||||
</BuildableProductRunnable>
|
</BuildableProductRunnable>
|
||||||
</ProfileAction>
|
</ProfileAction>
|
@ -2,7 +2,7 @@
|
|||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:ThimraTV.xcodeproj">
|
location = "group:Thimra.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Pods/Pods.xcodeproj">
|
location = "group:Pods/Pods.xcodeproj">
|
@ -0,0 +1,5 @@
|
|||||||
|
<?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/>
|
||||||
|
</plist>
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// AppDelegate+Config.swift
|
// AppDelegate+Config.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -17,8 +17,6 @@ extension AppDelegate {
|
|||||||
SPToast.config()
|
SPToast.config()
|
||||||
|
|
||||||
SPHUD.config()
|
SPHUD.config()
|
||||||
|
|
||||||
UIBarButtonItem.appearance().sp_setTitleTextAttributes()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -72,6 +70,8 @@ extension AppDelegate {
|
|||||||
if #available(iOS 15.0, *) {
|
if #available(iOS 15.0, *) {
|
||||||
tabBar.scrollEdgeAppearance = appearance
|
tabBar.scrollEdgeAppearance = appearance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// AppDelegate.swift
|
// AppDelegate.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -13,24 +13,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
|
||||||
SPAPPTool.appDelegate = self
|
|
||||||
|
|
||||||
self.registThirdparty(application, didFinishLaunchingWithOptions: launchOptions)
|
|
||||||
|
|
||||||
self.appConfig()
|
self.appConfig()
|
||||||
|
|
||||||
|
SPLoginManager.manager.requestVisitorLogin(completer: nil)
|
||||||
///开启网络监控
|
///开启网络监控
|
||||||
SPNetworkReachabilityManager.manager.startMonitoring()
|
// SPNetworkReachabilityManager.manager.startMonitoring()
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||||
|
|
||||||
let _ = JXIAPManager.manager
|
|
||||||
|
|
||||||
// SPLoginManager.manager.requestVisitorLogin(completer: nil)
|
SPNetworkReachabilityManager.manager.startMonitoring()
|
||||||
SPLoginManager.manager.updateUserInfo(completer: nil)
|
|
||||||
///注册消息通知
|
|
||||||
registerAPNS()
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -52,8 +46,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
|||||||
|
|
||||||
@objc private func reachabilityDidChangeNotification() {
|
@objc private func reachabilityDidChangeNotification() {
|
||||||
if SPNetworkReachabilityManager.manager.isReachable == true {
|
if SPNetworkReachabilityManager.manager.isReachable == true {
|
||||||
// SPLoginManager.manager.requestVisitorLogin(completer: nil)
|
SPLoginManager.manager.requestVisitorLogin(completer: nil)
|
||||||
SPLoginManager.manager.updateUserInfo(completer: nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
55
Thimra/AppDelegate/SceneDelegate.swift
Normal file
55
Thimra/AppDelegate/SceneDelegate.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// SceneDelegate.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
||||||
|
|
||||||
|
var window: UIWindow?
|
||||||
|
|
||||||
|
|
||||||
|
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||||
|
guard let windowScene = (scene as? UIWindowScene) else { return }
|
||||||
|
let tabBarController = SPTabBarController()
|
||||||
|
SPAPPTool.mainTabBarController = tabBarController
|
||||||
|
|
||||||
|
window = UIWindow(windowScene: windowScene)
|
||||||
|
window?.rootViewController = tabBarController
|
||||||
|
window?.makeKeyAndVisible()
|
||||||
|
}
|
||||||
|
|
||||||
|
func sceneDidDisconnect(_ scene: UIScene) {
|
||||||
|
// Called as the scene is being released by the system.
|
||||||
|
// This occurs shortly after the scene enters the background, or when its session is discarded.
|
||||||
|
// Release any resources associated with this scene that can be re-created the next time the scene connects.
|
||||||
|
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
|
||||||
|
}
|
||||||
|
|
||||||
|
func sceneDidBecomeActive(_ scene: UIScene) {
|
||||||
|
// Called when the scene has moved from an inactive state to an active state.
|
||||||
|
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
|
||||||
|
}
|
||||||
|
|
||||||
|
func sceneWillResignActive(_ scene: UIScene) {
|
||||||
|
// Called when the scene will move from an active state to an inactive state.
|
||||||
|
// This may occur due to temporary interruptions (ex. an incoming phone call).
|
||||||
|
}
|
||||||
|
|
||||||
|
func sceneWillEnterForeground(_ scene: UIScene) {
|
||||||
|
// Called as the scene transitions from the background to the foreground.
|
||||||
|
// Use this method to undo the changes made on entering the background.
|
||||||
|
}
|
||||||
|
|
||||||
|
func sceneDidEnterBackground(_ scene: UIScene) {
|
||||||
|
// Called as the scene transitions from the foreground to the background.
|
||||||
|
// Use this method to save data, release shared resources, and store enough scene-specific state information
|
||||||
|
// to restore the scene back to its current state.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPNavigationController.swift
|
// SPNavigationController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -33,14 +33,5 @@ class SPNavigationController: UINavigationController {
|
|||||||
}
|
}
|
||||||
super.setViewControllers(viewControllers, animated: animated)
|
super.setViewControllers(viewControllers, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK:-------------- 状态栏样式 --------------
|
|
||||||
override var childForStatusBarStyle: UIViewController? {
|
|
||||||
return self.topViewController
|
|
||||||
}
|
|
||||||
|
|
||||||
override var childForStatusBarHidden: UIViewController? {
|
|
||||||
return self.topViewController
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,39 +1,28 @@
|
|||||||
//
|
//
|
||||||
// SPTabBarController.swift
|
// SPTabBarController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import WebKit
|
|
||||||
|
|
||||||
class SPTabBarController: UITabBarController {
|
class SPTabBarController: UITabBarController {
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
self.view.backgroundColor = .backgroundColor()
|
self.view.backgroundColor = .backgroundColor()
|
||||||
|
|
||||||
let nav1 = createNavigationController(viewController: SPHomeViewController(), title: "movia_home".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected"))
|
let nav1 = createNavigationController(viewController: SPHomeViewController(), title: "Home".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected"))
|
||||||
|
|
||||||
let nav2 = createNavigationController(viewController: SPExplorePageController(), title: "movia_for_you".localized, image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected"))
|
let nav2 = createNavigationController(viewController: SPExplorePageController(), title: "For You".localized, image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected"))
|
||||||
|
|
||||||
let nav3 = createNavigationController(viewController: SPMyListViewController(), title: "movia_my_list".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
let nav4 = createNavigationController(viewController: SPMyListViewController(), title: "My list".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
||||||
|
|
||||||
let nav4 = createNavigationController(viewController: SPRewardsViewController(), title: "movia_rewards".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected"))
|
|
||||||
|
|
||||||
let nav5 = createNavigationController(viewController: SPMineViewController(), title: "movia_profile".localized, image: UIImage(named: "tabbar_icon_05"), selectedImage: UIImage(named: "tabbar_icon_05_selected"))
|
let nav5 = createNavigationController(viewController: SPMineViewController(), title: "Profile".localized, image: UIImage(named: "tabbar_icon_05"), selectedImage: UIImage(named: "tabbar_icon_05_selected"))
|
||||||
|
|
||||||
self.viewControllers = [nav1, nav2, nav3, nav4, nav5]
|
self.viewControllers = [nav1, nav2, nav4, nav5]
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
|
|
||||||
SPAPPTool.checkUpdates()
|
|
||||||
}
|
|
||||||
|
|
||||||
///授权idfa
|
|
||||||
SPAPPTool.requestIDFAAuthorization { idfa in
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -68,21 +57,6 @@ extension SPTabBarController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///选择活动页面
|
|
||||||
func selectedReward() {
|
|
||||||
var index: Int?
|
|
||||||
self.viewControllers?.enumerated().forEach({
|
|
||||||
guard let nav = $1 as? UINavigationController else { return }
|
|
||||||
if let _ = nav.viewControllers.first as? SPRewardsViewController {
|
|
||||||
index = $0
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if let index = index {
|
|
||||||
self.selectedIndex = index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SPTabBarController {
|
extension SPTabBarController {
|
||||||
@ -98,5 +72,3 @@ extension SPTabBarController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPViewController.swift
|
// SPViewController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -22,22 +22,15 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
|
|||||||
|
|
||||||
private(set) var isViewDidLoad = false
|
private(set) var isViewDidLoad = false
|
||||||
private(set) var isDidAppear = false
|
private(set) var isDidAppear = false
|
||||||
private(set) var hasViewDidAppear = false
|
|
||||||
|
|
||||||
private(set) lazy var bgImageView: UIImageView = {
|
private(set) lazy var _bgImageView: UIImageView = {
|
||||||
let imageView = UIImageView(image: UIImage(named: "main_bg_image_01"))
|
let imageView = UIImageView(image: UIImage(named: "main_bg_image_01"))
|
||||||
imageView.isUserInteractionEnabled = true
|
imageView.isUserInteractionEnabled = true
|
||||||
return imageView;
|
return imageView;
|
||||||
}()
|
}()
|
||||||
|
|
||||||
///无网空页面
|
|
||||||
private(set) lazy var noNetworkEmptyView: SPNoNetworkEmptyView = {
|
|
||||||
let view = SPNoNetworkEmptyView()
|
|
||||||
return view
|
|
||||||
}()
|
|
||||||
|
|
||||||
///头部渐变色
|
///头部渐变色
|
||||||
private lazy var topGradientView: SPGradientView = {
|
private lazy var toGradientView: SPGradientView = {
|
||||||
let view = SPGradientView()
|
let view = SPGradientView()
|
||||||
view.colors = [UIColor.color290D0F().cgColor, UIColor.color230E11().cgColor, UIColor.color181115().cgColor, UIColor.color121317(alpha: 0).cgColor]
|
view.colors = [UIColor.color290D0F().cgColor, UIColor.color230E11().cgColor, UIColor.color181115().cgColor, UIColor.color121317(alpha: 0).cgColor]
|
||||||
view.startPoint = .init(x: 0.5, y: 0)
|
view.startPoint = .init(x: 0.5, y: 0)
|
||||||
@ -51,19 +44,8 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
|
|||||||
self.isViewDidLoad = true
|
self.isViewDidLoad = true
|
||||||
self.edgesForExtendedLayout = []
|
self.edgesForExtendedLayout = []
|
||||||
|
|
||||||
view.addSubview(topGradientView)
|
|
||||||
view.addSubview(bgImageView)
|
|
||||||
|
|
||||||
topGradientView.snp.makeConstraints { make in
|
setBgImageView()
|
||||||
make.left.right.top.equalToSuperview()
|
|
||||||
make.height.equalTo(kSPStatusbarHeight + 420)
|
|
||||||
}
|
|
||||||
|
|
||||||
bgImageView.snp.makeConstraints { make in
|
|
||||||
make.left.right.top.equalToSuperview()
|
|
||||||
}
|
|
||||||
|
|
||||||
setBackgroundView()
|
|
||||||
|
|
||||||
if let navi = navigationController {
|
if let navi = navigationController {
|
||||||
if navi.visibleViewController == self {
|
if navi.visibleViewController == self {
|
||||||
@ -74,17 +56,20 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setBackgroundView(isShowGradient: Bool = true, bgImage: UIImage? = UIImage(named: "main_bg_image_01"), backgroundColor: UIColor = UIColor.backgroundColor()) {
|
func setBgImageView() {
|
||||||
topGradientView.isHidden = !isShowGradient
|
self.view.backgroundColor = .backgroundColor()
|
||||||
bgImageView.isHidden = isShowGradient
|
|
||||||
bgImageView.image = bgImage
|
self.view.addSubview(toGradientView)
|
||||||
view.backgroundColor = backgroundColor
|
|
||||||
|
toGradientView.snp.makeConstraints { make in
|
||||||
|
make.left.right.top.equalToSuperview()
|
||||||
|
make.height.equalTo(kSPStatusbarHeight + 420)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
isDidAppear = true
|
isDidAppear = true
|
||||||
hasViewDidAppear = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewWillDisappear(_ animated: Bool) {
|
override func viewWillDisappear(_ animated: Bool) {
|
||||||
@ -126,24 +111,6 @@ class SPViewController: UIViewController, JYPageChildContollerProtocol {
|
|||||||
func handleHeaderRefresh(_ completer: (() -> Void)?) {}
|
func handleHeaderRefresh(_ completer: (() -> Void)?) {}
|
||||||
|
|
||||||
func handleFooterRefresh(_ completer: (() -> Void)?) {}
|
func handleFooterRefresh(_ completer: (() -> Void)?) {}
|
||||||
|
|
||||||
///添加无网空页面
|
|
||||||
func addNoNetworkEmptyView(clickButton: (() -> Void)?) {
|
|
||||||
noNetworkEmptyView.clickButton = {
|
|
||||||
clickButton?()
|
|
||||||
}
|
|
||||||
view.addSubview(noNetworkEmptyView)
|
|
||||||
|
|
||||||
noNetworkEmptyView.snp.makeConstraints { make in
|
|
||||||
make.centerX.equalToSuperview()
|
|
||||||
make.centerY.equalToSuperview().offset(-50)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///删除无网空页面
|
|
||||||
func removeNoNetworkEmptyView() {
|
|
||||||
noNetworkEmptyView.removeFromSuperview()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +171,7 @@ extension UIViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///设置标题样式
|
///设置当行标题样式
|
||||||
func setNavigationTitleStyle(color: UIColor? = nil, font: UIFont? = nil) {
|
func setNavigationTitleStyle(color: UIColor? = nil, font: UIFont? = nil) {
|
||||||
guard let nav = navigationController else { return }
|
guard let nav = navigationController else { return }
|
||||||
if nav.visibleViewController == self {
|
if nav.visibleViewController == self {
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPDefine.swift
|
// SPDefine.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
14
Thimra/Base/Define/SPUserDefaultsKey.swift
Normal file
14
Thimra/Base/Define/SPUserDefaultsKey.swift
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// SPUserDefaultsKey.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/9.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
///登录的用户信息
|
||||||
|
let kSPLoginTokenDefaultsKey = "kSPLoginTokenDefaultsKey"
|
||||||
|
|
||||||
|
///首页搜索记录
|
||||||
|
let kSPHomeSearchHistoryDefaultsKey = "kSPHomeSearchHistoryDefaultsKey"
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// CGMutablePath+SPAdd.swift
|
// CGMutablePath+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// Int+SPAdd.swift
|
// Int+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
36
Thimra/Base/Extension/String+SPAdd.swift
Normal file
36
Thimra/Base/Extension/String+SPAdd.swift
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// String+SPAdd.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import SmartCodable
|
||||||
|
|
||||||
|
extension String: SmartCodable {
|
||||||
|
|
||||||
|
func length() -> Int {
|
||||||
|
return self.ocString().length
|
||||||
|
}
|
||||||
|
|
||||||
|
func ocString() -> NSString {
|
||||||
|
return self as NSString
|
||||||
|
}
|
||||||
|
|
||||||
|
static func timeZone() -> String {
|
||||||
|
let timeZone = NSTimeZone.local as NSTimeZone
|
||||||
|
let timeZoneAbbreviation = timeZone.name.length() > 0 ? timeZone.name : "Unknown"
|
||||||
|
let timeZoneSecondsFromGMT = timeZone.secondsFromGMT / 3600
|
||||||
|
return String(format: "GMT+0%d:00", timeZoneSecondsFromGMT)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
///获取文字Size
|
||||||
|
func size(font: UIFont, size: CGSize = CGSize(width: CGFloat(MAXFLOAT), height: CGFloat(MAXFLOAT))) -> CGSize{
|
||||||
|
let string: NSString = self as NSString
|
||||||
|
return string.size(for: font, size: size, mode: .byWordWrapping)
|
||||||
|
}
|
||||||
|
}
|
196
Thimra/Base/Extension/UIColor+SPAdd.swift
Normal file
196
Thimra/Base/Extension/UIColor+SPAdd.swift
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
//
|
||||||
|
// UIColor+SPAdd.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension UIColor {
|
||||||
|
|
||||||
|
static func color(hex: UInt32, alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return UIColor(rgb: hex, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func backgroundColor() -> UIColor {
|
||||||
|
return color121317()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func themeColor() -> UIColor {
|
||||||
|
return .color121317()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func placeholderColor() -> UIColor {
|
||||||
|
return .colorFFFFFF(alpha: 0.6)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UIColor {
|
||||||
|
static func colorFFFFFF(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xFFFFFF, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color000000(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x000000, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorFF0089(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xFF0089, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color7F7F80(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x7F7F80, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorD2D2D2(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xD2D2D2, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorBF6BFF(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xBF6BFF, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color121418(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x121418, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorF564B6(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xF564B6, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorF56490(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xF56490, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color9D9D9D(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x9D9D9D, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color545454(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x545454, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorD568D2(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xD568D2, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color8A899F(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x8A899F, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color888888(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x888888, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color201A1A(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x201A1A, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color828284(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x828284, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color121317(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x121317, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color290D0F(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x290D0F, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color230E11(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x230E11, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color181115(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x181115, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorFF5100(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xFF5100, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorAFAFAF(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xAFAFAF, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorA8A5AA(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xA8A5AA, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorD9D9D9(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xD9D9D9, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorEAF7FF(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xEAF7FF, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorFF4B5A(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xFF4B5A, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color1E1F2C(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x1E1F2C, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorE7F5FF(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xE7F5FF, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorAFB8BF(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xAFB8BF, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorFF0000(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xFF0000, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color1C1A1C(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x1C1A1C, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color621C14(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x621C14, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color5A5C67(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x5A5C67, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color3D4556(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x3D4556, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color1C1C1E(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x1C1C1E, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorEC3324(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xEC3324, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorCCCCCC(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xCCCCCC, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color6D7A8F(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x6D7A8F, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color8B6C6C(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x8B6C6C, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func color58484B(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0x58484B, alpha: alpha)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func colorE6334B(alpha: CGFloat = 1) -> UIColor {
|
||||||
|
return color(hex: 0xE6334B, alpha: alpha)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// UIDevice+SPAdd.swift
|
// UIDevice+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// UIFont+SPAdd.swift
|
// UIFont+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -9,18 +9,6 @@ import UIKit
|
|||||||
|
|
||||||
extension UIFont {
|
extension UIFont {
|
||||||
|
|
||||||
static func regularFontName() -> String {
|
|
||||||
return ".AppleSystemUIFont"
|
|
||||||
}
|
|
||||||
|
|
||||||
static func mediumFontName() -> String {
|
|
||||||
return ".AppleSystemUIFontMedium"
|
|
||||||
}
|
|
||||||
|
|
||||||
static func boldFontName() -> String {
|
|
||||||
return ".AppleSystemUIFontBold"
|
|
||||||
}
|
|
||||||
|
|
||||||
static func fontRegular(ofSize: CGFloat) -> UIFont {
|
static func fontRegular(ofSize: CGFloat) -> UIFont {
|
||||||
return .systemFont(ofSize: ofSize, weight: .regular)
|
return .systemFont(ofSize: ofSize, weight: .regular)
|
||||||
}
|
}
|
||||||
@ -40,9 +28,4 @@ extension UIFont {
|
|||||||
static func fontWeight(ofSize: CGFloat, weight: CGFloat) -> UIFont {
|
static func fontWeight(ofSize: CGFloat, weight: CGFloat) -> UIFont {
|
||||||
return .systemFont(ofSize: ofSize, weight: UIFont.Weight(weight))
|
return .systemFont(ofSize: ofSize, weight: UIFont.Weight(weight))
|
||||||
}
|
}
|
||||||
|
|
||||||
static func fontInterExtraBold(ofSize: CGFloat) -> UIFont {
|
|
||||||
|
|
||||||
return .init(name: "Inter-ExtraBold", size: ofSize) ?? fontBold(ofSize: ofSize)
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -1,18 +1,16 @@
|
|||||||
//
|
//
|
||||||
// UIImageView+SPAdd.swift
|
// UIImageView+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Kingfisher
|
import Kingfisher
|
||||||
//import KingfisherWebP
|
|
||||||
|
|
||||||
extension UIImageView {
|
extension UIImageView {
|
||||||
func sp_setImage(url: String?, placeholder: UIImage? = nil, completer: ((_ image: UIImage?, _ url: URL?) -> Void)? = nil) {
|
func sp_setImage(url: String?, placeholder: UIImage? = nil, completer: ((_ image: UIImage?, _ url: URL?) -> Void)? = nil) {
|
||||||
|
|
||||||
// self.kf.setImage(with: URL(string: url ?? ""), placeholder: placeholder, options: [.processor(WebPProcessor.default)]) { result in
|
|
||||||
self.kf.setImage(with: URL(string: url ?? ""), placeholder: placeholder, options: nil) { result in
|
self.kf.setImage(with: URL(string: url ?? ""), placeholder: placeholder, options: nil) { result in
|
||||||
switch result {
|
switch result {
|
||||||
case .success(let value):
|
case .success(let value):
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// UINavigationBar+SPAdd.swift
|
// UINavigationBar+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// UINavigationController+SPAdd.swift
|
// UINavigationController+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -19,12 +19,12 @@ extension UINavigationController {
|
|||||||
self.setViewControllers(viewControllers, animated: animated)
|
self.setViewControllers(viewControllers, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
// //MARK:-------------- 状态栏样式 --------------
|
//MARK:-------------- 状态栏样式 --------------
|
||||||
// open override var childForStatusBarStyle: UIViewController? {
|
open override var childForStatusBarStyle: UIViewController? {
|
||||||
// return self.topViewController
|
return self.topViewController
|
||||||
// }
|
}
|
||||||
// open override var childForStatusBarHidden: UIViewController? {
|
open override var childForStatusBarHidden: UIViewController? {
|
||||||
// return self.topViewController
|
return self.topViewController
|
||||||
// }
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// UIScrollView+SPRefresh.swift
|
// UIScrollView+SPRefresh.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/19.
|
// Created by 曾觉新 on 2025/4/19.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// UIStackView+SPAdd.swift
|
// UIStackView+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// UIView+SPAdd.swift
|
// UIView+SPAdd.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/9.
|
// Created by 曾觉新 on 2025/4/9.
|
||||||
//
|
//
|
||||||
@ -109,30 +109,3 @@ extension UIView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: -------------- 添加点击事件 --------------
|
|
||||||
extension UIView {
|
|
||||||
|
|
||||||
private var sp_tapGestureBlock: ((_ view: UIView) -> Void)? {
|
|
||||||
get {
|
|
||||||
return objc_getAssociatedObject(self,&AssociatedKeys.sp_tapGesture) as? ((_ view: UIView) -> Void)
|
|
||||||
}
|
|
||||||
set {
|
|
||||||
objc_setAssociatedObject(self,&AssociatedKeys.sp_tapGesture, newValue, .OBJC_ASSOCIATION_COPY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func sp_addTapGestureRecognizer(_ block: ((_ view: UIView) -> Void)?) {
|
|
||||||
if sp_tapGestureBlock == nil {
|
|
||||||
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGestureRecognizer(tap:)))
|
|
||||||
self.addGestureRecognizer(tap)
|
|
||||||
}
|
|
||||||
self.sp_tapGestureBlock = block
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private func handleTapGestureRecognizer(tap: UITapGestureRecognizer) {
|
|
||||||
if tap.state == .recognized {
|
|
||||||
self.sp_tapGestureBlock?(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPListModel.swift
|
// SPListModel.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/9.
|
// Created by 曾觉新 on 2025/4/9.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPModel.swift
|
// SPModel.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeAPI.swift
|
// SPHomeAPI.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -37,12 +37,13 @@ class SPHomeAPI: NSObject {
|
|||||||
|
|
||||||
///首页模块接口
|
///首页模块接口
|
||||||
static func requestHomeModuleData(completer: ((_ model: SPHomeModuleModel?) -> Void)?) {
|
static func requestHomeModuleData(completer: ((_ model: SPHomeModuleModel?) -> Void)?) {
|
||||||
var param = SPNetworkParameters(path: "/homeModuleData")
|
let param = SPNetworkParameters(path: "/homeBannerAndNineSquare")
|
||||||
param.method = .get
|
// param.method = .get
|
||||||
|
|
||||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPHomeModuleModel>) in
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPHomeModuleModel>) in
|
||||||
completer?(response.data)
|
completer?(response.data)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///首页列表数据
|
///首页列表数据
|
23
Thimra/Base/Networking/API/SPUserAPI.swift
Normal file
23
Thimra/Base/Networking/API/SPUserAPI.swift
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// SPUserAPI.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/18.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPUserAPI: NSObject {
|
||||||
|
|
||||||
|
|
||||||
|
static func requestUserInfo(completer: ((_ userInfo: SPUserInfo?) -> Void)?) {
|
||||||
|
|
||||||
|
var param = SPNetworkParameters(path: "/customer/info")
|
||||||
|
param.method = .get
|
||||||
|
|
||||||
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPUserInfo>) in
|
||||||
|
completer?(response.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPVideoAPI.swift
|
// SPVideoAPI.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/10.
|
// Created by 曾觉新 on 2025/4/10.
|
||||||
//
|
//
|
||||||
@ -10,22 +10,17 @@ import UIKit
|
|||||||
class SPVideoAPI: NSObject {
|
class SPVideoAPI: NSObject {
|
||||||
|
|
||||||
///获取视频详情
|
///获取视频详情
|
||||||
static func requestVideoDetail(videoId: String?, shortPlayId: String, activityId: String? = nil, completer: ((_ model: SPVideoDetailModel?) -> Void)?) {
|
static func requestVideoDetail(videoId: String?, shortPlayId: String, completer: ((_ model: SPVideoDetailModel?) -> Void)?) {
|
||||||
var parameters: [String : Any] = [
|
var parameters: [String : Any] = [
|
||||||
"short_play_id" : shortPlayId
|
"short_play_id" : shortPlayId
|
||||||
]
|
]
|
||||||
|
|
||||||
// if let videoId = videoId {
|
if let videoId = videoId {
|
||||||
// }
|
parameters["video_id"] = videoId
|
||||||
parameters["video_id"] = "0"
|
|
||||||
if let activityId = activityId {
|
|
||||||
parameters["activity_id"] = activityId
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var param = SPNetworkParameters(path: "/getVideoDetails")
|
var param = SPNetworkParameters(path: "/getVideoDetails")
|
||||||
param.method = .get
|
param.method = .get
|
||||||
param.parameters = parameters
|
param.parameters = parameters
|
||||||
param.isLoding = true
|
|
||||||
|
|
||||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPVideoDetailModel>) in
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPVideoDetailModel>) in
|
||||||
completer?(response.data)
|
completer?(response.data)
|
||||||
@ -33,46 +28,13 @@ class SPVideoAPI: NSObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///创建播放记录
|
///创建播放记录
|
||||||
static func requestCreateVideoPlayHistory(videoId: String?, shortPlayId: String) {
|
static func requestRequestVideoPlayHistory(videoId: String, shortPlayId: String) {
|
||||||
var param = SPNetworkParameters(path: "/createHistory")
|
var param = SPNetworkParameters(path: "/createHistory")
|
||||||
param.isLoding = false
|
param.isLoding = false
|
||||||
param.isToast = false
|
param.isToast = false
|
||||||
param.parameters = [
|
|
||||||
"video_id" : videoId ?? "0",
|
|
||||||
"short_play_id" : shortPlayId
|
|
||||||
]
|
|
||||||
|
|
||||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///视频观看结束
|
|
||||||
static func requestViewingFinish(shortPlayId: String, videoId: String, activityId: String) {
|
|
||||||
var param = SPNetworkParameters(path: "/activeAfterWatchingVideo")
|
|
||||||
param.isLoding = false
|
|
||||||
param.isToast = false
|
|
||||||
param.parameters = [
|
|
||||||
"short_play_video_id" : videoId,
|
|
||||||
"short_play_id" : shortPlayId,
|
|
||||||
"activity_id" : activityId
|
|
||||||
]
|
|
||||||
|
|
||||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///上报播放时长
|
|
||||||
static func requestUploadPlayTime(shortPlayId: String, videoId: String, seconds: Int) {
|
|
||||||
|
|
||||||
var param = SPNetworkParameters(path: "/uploadHistorySeconds")
|
|
||||||
param.isLoding = false
|
|
||||||
param.isToast = false
|
|
||||||
param.parameters = [
|
param.parameters = [
|
||||||
"video_id" : videoId,
|
"video_id" : videoId,
|
||||||
"short_play_id" : shortPlayId,
|
"short_play_id" : shortPlayId
|
||||||
"play_seconds" : seconds
|
|
||||||
]
|
]
|
||||||
|
|
||||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<String>) in
|
||||||
@ -152,7 +114,7 @@ class SPVideoAPI: NSObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///获取分类短剧
|
///获取分类短剧
|
||||||
static func requestCategoryShortList(page: Int, id: String, completer: ((_ listModel: SPListModel<SPShortModel>?) -> Void)?) {
|
static func requestCategoryShortList(page: Int, id: String, completer: ((_ listModel: SPListModel<SPShortModel>?) -> Void)?) {
|
||||||
var param = SPNetworkParameters(path: "/videoList")
|
var param = SPNetworkParameters(path: "/videoList")
|
||||||
param.method = .get
|
param.method = .get
|
||||||
@ -166,17 +128,6 @@ class SPVideoAPI: NSObject {
|
|||||||
completer?(response.data)
|
completer?(response.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///视频推荐
|
|
||||||
static func requestPlayerDetailsRecommand(completer: ((_ list: [SPShortModel]?) -> Void)?) {
|
|
||||||
|
|
||||||
var param = SPNetworkParameters(path: "/getDetailsRecommand")
|
|
||||||
param.method = .get
|
|
||||||
|
|
||||||
SPNetwork.request(parameters: param) { (response: SPNetworkResponse<SPListModel<SPShortModel>>) in
|
|
||||||
completer?(response.data?.list)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SPVideoAPI {
|
extension SPVideoAPI {
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPApi.swift
|
// SPApi.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -84,12 +84,11 @@ extension SPApi: TargetType {
|
|||||||
"lang-key" : SPLocalizedManager.shared.currentLocalizedKey,//当前语言
|
"lang-key" : SPLocalizedManager.shared.currentLocalizedKey,//当前语言
|
||||||
"time-zone" : String.timeZone(), //时区
|
"time-zone" : String.timeZone(), //时区
|
||||||
"app-version" : kSPAPPVersion,
|
"app-version" : kSPAPPVersion,
|
||||||
// "device-id" : JXUUID.systemUUID(), //设备id
|
"device-id" : JXUUID.systemUUID(), //设备id
|
||||||
"device-id" : JXUUID.uuid(), //设备id
|
|
||||||
"brand" : "apple", //品牌
|
"brand" : "apple", //品牌
|
||||||
"app-name" : kSPAPPBundleIdentifier,
|
"app-name" : "",
|
||||||
"system-type" : "ios",
|
"system-type" : "ios",
|
||||||
"idfa" : SPAPPTool.getIdfa(),
|
"idfa" : JXUUID.idfa(),
|
||||||
"model" : UIDevice.sp_machineModelName(),
|
"model" : UIDevice.sp_machineModelName(),
|
||||||
// "security" : "false",
|
// "security" : "false",
|
||||||
]
|
]
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPCryptService.swift
|
// SPCryptService.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/10.
|
// Created by 曾觉新 on 2025/4/10.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPNetwork.swift
|
// SPNetwork.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -76,21 +76,12 @@ class SPNetwork: NSObject {
|
|||||||
var res = SPNetworkResponse<T>()
|
var res = SPNetworkResponse<T>()
|
||||||
res.code = -1
|
res.code = -1
|
||||||
if parameters.isToast {
|
if parameters.isToast {
|
||||||
SPToast.show(text: "movia_error".localized)
|
SPToast.show(text: "Error".localized)
|
||||||
}
|
}
|
||||||
completion?(res)
|
completion?(res)
|
||||||
} else {
|
} else {
|
||||||
if code == 402, parameters.isToast {
|
|
||||||
SPToast.show(text: "movia_network_toast_02".localized)
|
|
||||||
}
|
|
||||||
///重新获取token
|
///重新获取token
|
||||||
self.requestToken { token in
|
self.requestToken(completer: nil)
|
||||||
if token != nil {
|
|
||||||
SPLoginManager.manager.updateUserInfo(completer: nil)
|
|
||||||
SPStatAPI.requestEnterApp()
|
|
||||||
SPStatAPI.requestStatOnLine()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
///将请求失败数据重新请求
|
///将请求失败数据重新请求
|
||||||
if let tokenOperation = self.tokenOperation, parameters.path != "/customer/register" {
|
if let tokenOperation = self.tokenOperation, parameters.path != "/customer/register" {
|
||||||
@ -137,7 +128,7 @@ class SPNetwork: NSObject {
|
|||||||
var res = SPNetworkResponse<T>()
|
var res = SPNetworkResponse<T>()
|
||||||
res.code = -1
|
res.code = -1
|
||||||
if parameters.isToast {
|
if parameters.isToast {
|
||||||
SPToast.show(text: "movia_error".localized)
|
SPToast.show(text: "Error".localized)
|
||||||
}
|
}
|
||||||
completion?(res)
|
completion?(res)
|
||||||
}
|
}
|
||||||
@ -146,7 +137,7 @@ class SPNetwork: NSObject {
|
|||||||
var res = SPNetworkResponse<T>()
|
var res = SPNetworkResponse<T>()
|
||||||
res.code = -1
|
res.code = -1
|
||||||
if parameters.isToast {
|
if parameters.isToast {
|
||||||
SPToast.show(text: "movia_network_toast_01".localized)
|
SPToast.show(text: "Error".localized)
|
||||||
}
|
}
|
||||||
completion?(res)
|
completion?(res)
|
||||||
break
|
break
|
||||||
@ -171,7 +162,7 @@ class SPNetwork: NSObject {
|
|||||||
} else {
|
} else {
|
||||||
var response = SPNetworkResponse<T>()
|
var response = SPNetworkResponse<T>()
|
||||||
response.code = -1
|
response.code = -1
|
||||||
response.msg = "movia_error".localized
|
response.msg = "Error".localized
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPNetworkReachabilityManager.swift
|
// SPNetworkReachabilityManager.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/19.
|
// Created by Overseas on 2025/4/19.
|
||||||
//
|
//
|
||||||
@ -54,24 +54,16 @@ class SPNetworkReachabilityManager {
|
|||||||
if path.status == .satisfied {
|
if path.status == .satisfied {
|
||||||
if self.isReachable == false {
|
if self.isReachable == false {
|
||||||
print("++++++有网")
|
print("++++++有网")
|
||||||
self.isReachable = true
|
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.isReachable = true
|
|
||||||
}
|
}
|
||||||
|
self.isReachable = true
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if self.isReachable == true {
|
if self.isReachable == true {
|
||||||
print("++++++无网")
|
print("++++++无网")
|
||||||
self.isReachable = false
|
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||||
DispatchQueue.main.async {
|
|
||||||
NotificationCenter.default.post(name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.isReachable = false
|
|
||||||
}
|
}
|
||||||
|
self.isReachable = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// if path.usesInterfaceType(.wifi) {
|
// if path.usesInterfaceType(.wifi) {
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPURLPath.swift
|
// SPURLPath.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -17,16 +17,14 @@ import UIKit
|
|||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
let SPBaseURL = "https://api-thimratv.thimratv.com"
|
let SPBaseURL = "https://api-thimratv.thimratv.com"
|
||||||
let SPURLPathPrefix = "/93f03506"
|
let SPURLPathPrefix = "/0a2c5b02"
|
||||||
|
|
||||||
let SPWebBaseURL = "https://www.thimratv.com"
|
let SPWebBaseURL = "https://www.thimratv.com"
|
||||||
let SPCampaignWebURL = "https://campaign.moviatv.com"
|
|
||||||
#else
|
#else
|
||||||
let SPBaseURL = "https://api-thimratv.thimratv.com"
|
let SPBaseURL = "https://api-thimratv.thimratv.com"
|
||||||
let SPURLPathPrefix = "/93f03506"
|
let SPURLPathPrefix = "/0a2c5b02"
|
||||||
|
|
||||||
let SPWebBaseURL = "https://www.thimratv.com"
|
let SPWebBaseURL = "https://www.thimratv.com"
|
||||||
let SPCampaignWebURL = "https://campaign.moviatv.com"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -42,16 +40,6 @@ let SPInformationSharingWebUrl = SPWebBaseURL + "/information_sharing"
|
|||||||
let SPPersoInforDisclosureWebUrl = SPWebBaseURL + "/persoInfor_disclosure"
|
let SPPersoInforDisclosureWebUrl = SPWebBaseURL + "/persoInfor_disclosure"
|
||||||
///全国青少年互联网文明公约
|
///全国青少年互联网文明公约
|
||||||
let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention"
|
let SPCivizatioConventionWebUrl = SPWebBaseURL + "/civizatio_convention"
|
||||||
///会员服务协议
|
|
||||||
let SPMemberShipAgreement = SPWebBaseURL + "/member_ship_agreement"
|
|
||||||
|
|
||||||
///反馈首页
|
|
||||||
let SPFeedBackHomeWebUrl = SPCampaignWebURL + "/pages/leave/index"
|
|
||||||
///反馈列表
|
|
||||||
let SPFeedBackListWebUrl = SPCampaignWebURL + "/pages/leave/list"
|
|
||||||
///反馈详情
|
|
||||||
let SPFeedBackDetailWebUrl = SPCampaignWebURL + "/pages/leave/detail"
|
|
||||||
///活动页面
|
|
||||||
let SPRewardsWebUrl = SPCampaignWebURL + "/pages/reward/theme2"
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPCollectionView.swift
|
// SPCollectionView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/9.
|
// Created by 曾觉新 on 2025/4/9.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPCollectionViewCell.swift
|
// SPCollectionViewCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/9.
|
// Created by 曾觉新 on 2025/4/9.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPGradientView.swift
|
// SPGradientView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPImageView.swift
|
// SPImageView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/9.
|
// Created by 曾觉新 on 2025/4/9.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPScrollView.swift
|
// SPScrollView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPTableView.swift
|
// SPTableView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
||||||
@ -13,8 +13,7 @@ class SPTableView: UITableView {
|
|||||||
|
|
||||||
override init(frame: CGRect, style: UITableView.Style) {
|
override init(frame: CGRect, style: UITableView.Style) {
|
||||||
super.init(frame: frame, style: style)
|
super.init(frame: frame, style: style)
|
||||||
separatorColor = .colorFFFFFF(alpha: 0.1)
|
// separatorColor = .lineColor()
|
||||||
separatorInset = .init(top: 0, left: 16, bottom: 0, right: 16)
|
|
||||||
self.backgroundColor = .clear
|
self.backgroundColor = .clear
|
||||||
self.contentInsetAdjustmentBehavior = .never
|
self.contentInsetAdjustmentBehavior = .never
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPTableViewCell.swift
|
// SPTableViewCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPTextField.swift
|
// SPTextField.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
107
Thimra/Base/View/SPZoomCollectionViewLayout.swift
Normal file
107
Thimra/Base/View/SPZoomCollectionViewLayout.swift
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
//
|
||||||
|
// SPZoomCollectionViewLayout.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPZoomCollectionViewLayout: UICollectionViewFlowLayout {
|
||||||
|
|
||||||
|
let minimumScale: CGFloat = 0.08 // 调整缩放大小
|
||||||
|
|
||||||
|
private(set) var currentIndexPath: IndexPath = IndexPath(row: 0, section: 0)
|
||||||
|
|
||||||
|
|
||||||
|
private var cellWidth: CGFloat {
|
||||||
|
return itemSize.width + minimumLineSpacing
|
||||||
|
}
|
||||||
|
|
||||||
|
override func prepare() {
|
||||||
|
super.prepare()
|
||||||
|
scrollDirection = .horizontal
|
||||||
|
self.collectionView?.decelerationRate = .fast
|
||||||
|
let screenWidth = UIScreen.main.bounds.size.width
|
||||||
|
let insetLeft = (screenWidth - self.itemSize.width) / 2
|
||||||
|
collectionView?.contentInset = UIEdgeInsets(top: 0, left: insetLeft, bottom: 0, right: insetLeft)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
|
||||||
|
guard let collectionView = collectionView else { return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) }
|
||||||
|
|
||||||
|
let proposedRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionView.bounds.width, height: collectionView.bounds.height)
|
||||||
|
|
||||||
|
guard let layoutAttributes = layoutAttributesForElements(in: proposedRect) else {
|
||||||
|
return super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
|
||||||
|
}
|
||||||
|
|
||||||
|
let horizontalCenterX = proposedContentOffset.x + collectionView.bounds.width / 2
|
||||||
|
var offsetAdjustment = CGFloat.greatestFiniteMagnitude
|
||||||
|
// ydLog(message: "offsetAdjustment = \(offsetAdjustment)")
|
||||||
|
// ydLog(message: "horizontalCenterX = \(horizontalCenterX)")
|
||||||
|
|
||||||
|
var currentIndexPath: IndexPath = IndexPath(row: 0, section: 0)
|
||||||
|
for attributes in layoutAttributes {
|
||||||
|
let itemHorizontalCenterX = attributes.center.x
|
||||||
|
let distance = itemHorizontalCenterX - horizontalCenterX
|
||||||
|
// ydLog(message: "distance = \(distance)")
|
||||||
|
//离中心距离最近的
|
||||||
|
if abs(distance) < abs(offsetAdjustment) {
|
||||||
|
offsetAdjustment = distance
|
||||||
|
currentIndexPath = attributes.indexPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.currentIndexPath = currentIndexPath
|
||||||
|
|
||||||
|
let point = CGPoint(x: proposedContentOffset.x + offsetAdjustment, y: proposedContentOffset.y)
|
||||||
|
// ydLog(message: "proposedContentOffset = \(proposedContentOffset)")
|
||||||
|
// ydLog(message: "offsetAdjustment = \(offsetAdjustment)")
|
||||||
|
// ydLog(message: "point = \(point)")
|
||||||
|
// ydLog(message: "currentIndex = \(currentIndex)")
|
||||||
|
|
||||||
|
return point
|
||||||
|
}
|
||||||
|
|
||||||
|
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
|
||||||
|
guard let collectionView = collectionView else { return nil }
|
||||||
|
|
||||||
|
let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
|
||||||
|
let attributes = super.layoutAttributesForElements(in: rect)?.compactMap { $0.copy() as? UICollectionViewLayoutAttributes }
|
||||||
|
|
||||||
|
for attribute in attributes ?? [] {
|
||||||
|
let distance = visibleRect.midX - attribute.center.x
|
||||||
|
let normalizedDistance = distance / (collectionView.bounds.width * 0.5)
|
||||||
|
let zoom = 1 - abs(normalizedDistance) * minimumScale
|
||||||
|
|
||||||
|
//缩放
|
||||||
|
let scaleTransform = CGAffineTransform(scaleX: zoom, y: zoom)
|
||||||
|
|
||||||
|
|
||||||
|
//旋转
|
||||||
|
let rotationAngle = kSPAngleToRadians(angle: -normalizedDistance * 4)
|
||||||
|
let rotationTransform = CGAffineTransform(rotationAngle: rotationAngle)
|
||||||
|
|
||||||
|
// 组合旋转和缩放变换
|
||||||
|
let combinedTransform = rotationTransform.concatenating(scaleTransform)
|
||||||
|
// 应用变换
|
||||||
|
attribute.transform = combinedTransform
|
||||||
|
|
||||||
|
var alpha = 1.8 - abs(normalizedDistance)
|
||||||
|
if alpha < 0 {
|
||||||
|
alpha = 0
|
||||||
|
} else if alpha > 1 {
|
||||||
|
alpha = 1
|
||||||
|
}
|
||||||
|
attribute.alpha = alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes
|
||||||
|
}
|
||||||
|
|
||||||
|
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPWebView.swift
|
// SPWebView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
||||||
@ -13,10 +13,7 @@ class SPWebView: WKWebView {
|
|||||||
weak var delegate: SPWebViewDelegate?
|
weak var delegate: SPWebViewDelegate?
|
||||||
|
|
||||||
private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [
|
private(set) var scriptMessageHandlerArray: [SPWebViewMessageName] = [
|
||||||
WebMessageAPP,
|
WebMessageGetUserInfo,
|
||||||
WebMessageOpenFeedbackList,
|
|
||||||
WebMessageOpenFeedbackDetail,
|
|
||||||
WebMessageOpenPhotoPicker,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
28
Thimra/Base/WebView/SPWebViewController+ScriptMessage.swift
Normal file
28
Thimra/Base/WebView/SPWebViewController+ScriptMessage.swift
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// SPWebViewController+ScriptMessage.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/24.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import WebKit
|
||||||
|
|
||||||
|
typealias SPWebViewMessageName = String
|
||||||
|
|
||||||
|
///获取用户信息
|
||||||
|
let WebMessageGetUserInfo: SPWebViewMessageName = "getUserInfo"
|
||||||
|
|
||||||
|
|
||||||
|
extension SPWebViewController {
|
||||||
|
|
||||||
|
func _webViewUserContentController(didReceive message: WKScriptMessage) {
|
||||||
|
let name = message.name
|
||||||
|
let body = message.body
|
||||||
|
|
||||||
|
|
||||||
|
// let js = "window.returnGPSposition('{\"longitude\":\(placemark.longitude ?? 0),\"latitude\":\(placemark.latitude ?? 0)}')"
|
||||||
|
// self.webView.evaluateJavaScript(js, completionHandler: nil)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPWebViewController.swift
|
// SPWebViewController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
||||||
@ -12,10 +12,7 @@ class SPWebViewController: SPViewController {
|
|||||||
|
|
||||||
var urlStr: String?
|
var urlStr: String?
|
||||||
|
|
||||||
///自动设置标题
|
private lazy var webView: SPWebView = {
|
||||||
var autoTitle = true
|
|
||||||
|
|
||||||
private(set) lazy var webView: SPWebView = {
|
|
||||||
let controller = WKUserContentController()
|
let controller = WKUserContentController()
|
||||||
|
|
||||||
let config = WKWebViewConfiguration()
|
let config = WKWebViewConfiguration()
|
||||||
@ -31,16 +28,18 @@ class SPWebViewController: SPViewController {
|
|||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
// self.edgesForExtendedLayout = .top
|
// self.edgesForExtendedLayout = .top
|
||||||
// configNavigationBack()
|
configNavigationBack()
|
||||||
|
|
||||||
setBackgroundView(isShowGradient: false, bgImage: nil)
|
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
|
|
||||||
if let url = urlStr {
|
if let url = urlStr {
|
||||||
self.load(urlString: url)
|
self.load(urlString: url)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func setBgImageView() {
|
||||||
|
self.view.backgroundColor = .backgroundColor()
|
||||||
|
}
|
||||||
|
|
||||||
override func viewWillAppear(_ animated: Bool) {
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
@ -52,14 +51,10 @@ class SPWebViewController: SPViewController {
|
|||||||
let str: String = urlString
|
let str: String = urlString
|
||||||
|
|
||||||
guard let url = URL(string: str) else { return }
|
guard let url = URL(string: str) else { return }
|
||||||
let request = URLRequest(url: url, timeoutInterval: 30)
|
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 30)
|
||||||
|
|
||||||
self.webView.load(request)
|
self.webView.load(request)
|
||||||
}
|
}
|
||||||
|
|
||||||
func reload() {
|
|
||||||
self.webView.reload()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,22 +72,14 @@ extension SPWebViewController {
|
|||||||
extension SPWebViewController: SPWebViewDelegate {
|
extension SPWebViewController: SPWebViewDelegate {
|
||||||
|
|
||||||
func webView(webView: SPWebView, didChangeTitle title: String) {
|
func webView(webView: SPWebView, didChangeTitle title: String) {
|
||||||
if autoTitle {
|
self.title = title
|
||||||
self.title = title
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func webView(_ webView: SPWebView, didFailLoadWithError error: any Error) {
|
func webView(_ webView: SPWebView, didFailLoadWithError error: any Error) {
|
||||||
spLog(message: error)
|
spLog(message: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func webViewDidFinishLoad(_ webView: SPWebView) {
|
|
||||||
spLog(message: "网页加载完成")
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
|
||||||
_webViewUserContentController(didReceive: message)
|
_webViewUserContentController(didReceive: message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPAllShortViewController.swift
|
// SPAllShortViewController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/23.
|
// Created by Overseas on 2025/4/23.
|
||||||
//
|
//
|
||||||
@ -13,7 +13,7 @@ class SPAllShortViewController: SPViewController {
|
|||||||
private lazy var allCategoryModel: SPCategoryModel = {
|
private lazy var allCategoryModel: SPCategoryModel = {
|
||||||
let model = SPCategoryModel()
|
let model = SPCategoryModel()
|
||||||
model.id = "0"
|
model.id = "0"
|
||||||
model.name = "movia_all".localized
|
model.name = "All".localized
|
||||||
return model
|
return model
|
||||||
}()
|
}()
|
||||||
private lazy var categoryArr: [SPCategoryModel] = [self.allCategoryModel]
|
private lazy var categoryArr: [SPCategoryModel] = [self.allCategoryModel]
|
||||||
@ -98,7 +98,6 @@ class SPAllShortViewController: SPViewController {
|
|||||||
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
collectionView.dataSource = self
|
collectionView.dataSource = self
|
||||||
collectionView.showNormalEmpty()
|
|
||||||
collectionView.contentInset = .init(top: 10, left: 0, bottom: 10, right: 0)
|
collectionView.contentInset = .init(top: 10, left: 0, bottom: 10, right: 0)
|
||||||
collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in
|
collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in
|
||||||
self?.handleHeaderRefresh(nil)
|
self?.handleHeaderRefresh(nil)
|
||||||
@ -112,7 +111,7 @@ class SPAllShortViewController: SPViewController {
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
setBackgroundView(isShowGradient: false, bgImage: nil, backgroundColor: .clear)
|
self.view.backgroundColor = .clear
|
||||||
|
|
||||||
requestCategoryList()
|
requestCategoryList()
|
||||||
requestDataArr(page: 1, completer: nil)
|
requestDataArr(page: 1, completer: nil)
|
||||||
@ -123,10 +122,19 @@ class SPAllShortViewController: SPViewController {
|
|||||||
override func viewDidLayoutSubviews() {
|
override func viewDidLayoutSubviews() {
|
||||||
super.viewDidLayoutSubviews()
|
super.viewDidLayoutSubviews()
|
||||||
|
|
||||||
|
let widht: CGFloat = 100
|
||||||
|
let height = self.tagView.tagHeight
|
||||||
|
let x = self.tagView.width - widht
|
||||||
|
let y = self.tagView.height - height
|
||||||
|
|
||||||
|
// openGradientLayer.frame = CGRect(x: x, y: y, width: widht, height: height)
|
||||||
openGradientLayer.frame = self.tagView.bounds
|
openGradientLayer.frame = self.tagView.bounds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func setBgImageView() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
|
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
|
||||||
requestDataArr(page: 1) { [weak self] in
|
requestDataArr(page: 1) { [weak self] in
|
||||||
self?.collectionView.sp_endHeaderRefreshing()
|
self?.collectionView.sp_endHeaderRefreshing()
|
||||||
@ -163,8 +171,7 @@ extension SPAllShortViewController {
|
|||||||
|
|
||||||
tagView.snp.makeConstraints { make in
|
tagView.snp.makeConstraints { make in
|
||||||
make.left.right.equalToSuperview()
|
make.left.right.equalToSuperview()
|
||||||
// make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12)
|
make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12)
|
||||||
make.top.equalToSuperview().offset(kSPNavBarHeight + 12)
|
|
||||||
make.height.lessThanOrEqualTo(tagMaxHeight)
|
make.height.lessThanOrEqualTo(tagMaxHeight)
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPExplorePageController.swift
|
// SPExplorePageController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/21.
|
// Created by Overseas on 2025/4/21.
|
||||||
//
|
//
|
||||||
@ -11,7 +11,7 @@ import UIKit
|
|||||||
class SPExplorePageController: SPViewController {
|
class SPExplorePageController: SPViewController {
|
||||||
|
|
||||||
private lazy var titles: [String] = {
|
private lazy var titles: [String] = {
|
||||||
let arr = ["movia_shorts".localized, "movia_all".localized]
|
let arr = ["Shorts".localized, "All".localized]
|
||||||
return arr
|
return arr
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -69,7 +69,6 @@ class SPExplorePageController: SPViewController {
|
|||||||
return pageView
|
return pageView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
||||||
private lazy var menuBgView: UIView = {
|
private lazy var menuBgView: UIView = {
|
||||||
let view = UIView()
|
let view = UIView()
|
||||||
view.addEffectView(style: .light)
|
view.addEffectView(style: .light)
|
||||||
@ -78,21 +77,11 @@ class SPExplorePageController: SPViewController {
|
|||||||
return view
|
return view
|
||||||
}()
|
}()
|
||||||
|
|
||||||
deinit {
|
|
||||||
NotificationCenter.default.removeObserver(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
_setupUI()
|
||||||
|
|
||||||
if SPNetworkReachabilityManager.manager.isReachable != true {
|
|
||||||
setEmptyView()
|
|
||||||
} else {
|
|
||||||
_setupUI()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,35 +89,7 @@ class SPExplorePageController: SPViewController {
|
|||||||
super.viewWillAppear(animated)
|
super.viewWillAppear(animated)
|
||||||
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension SPExplorePageController {
|
|
||||||
|
|
||||||
///设置无网空页面
|
|
||||||
private func setEmptyView() {
|
|
||||||
if SPNetworkReachabilityManager.manager.isReachable != true {
|
|
||||||
self.addNoNetworkEmptyView { [weak self] in
|
|
||||||
self?.updateEmptyState()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private func reachabilityDidChangeNotification() {
|
|
||||||
updateEmptyState()
|
|
||||||
}
|
|
||||||
|
|
||||||
private func updateEmptyState() {
|
|
||||||
if self.pageView.view.superview != nil { return }
|
|
||||||
|
|
||||||
if SPNetworkReachabilityManager.manager.isReachable == true {
|
|
||||||
self._setupUI()
|
|
||||||
self.removeNoNetworkEmptyView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension SPExplorePageController {
|
extension SPExplorePageController {
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPExploreViewController.swift
|
// SPExploreViewController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/9.
|
// Created by 曾觉新 on 2025/4/9.
|
||||||
//
|
//
|
||||||
@ -36,7 +36,7 @@ extension SPExploreViewController: SPPlayerListViewControllerDelegate {
|
|||||||
guard let pagination = self.pagination else { return }
|
guard let pagination = self.pagination else { return }
|
||||||
guard let page = self.pagination?.current_page else { return }
|
guard let page = self.pagination?.current_page else { return }
|
||||||
let pageSize = pagination.page_size ?? 0
|
let pageSize = pagination.page_size ?? 0
|
||||||
if pagination.total_size ?? 0 <= pageSize * page {
|
if pagination.page_total ?? 0 <= pageSize * page {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.requestDataArr(page: page + 1)
|
self.requestDataArr(page: page + 1)
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPCategoryModel.swift
|
// SPCategoryModel.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/23.
|
// Created by Overseas on 2025/4/23.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPAllShortCell.swift
|
// SPAllShortCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/23.
|
// Created by Overseas on 2025/4/23.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPExplorePlayerCell.swift
|
// SPExplorePlayerCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPExplorePlayerControlView.swift
|
// SPExplorePlayerControlView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
||||||
@ -52,7 +52,7 @@ class SPExplorePlayerControlView: SPPlayerControlView {
|
|||||||
|
|
||||||
private lazy var allEpisodeButton: UIButton = {
|
private lazy var allEpisodeButton: UIButton = {
|
||||||
let button = JXButton(type: .custom)
|
let button = JXButton(type: .custom)
|
||||||
button.setTitle("movia_full_episodes".localized, for: .normal)
|
button.setTitle("Full Episodes".localized, for: .normal)
|
||||||
button.setTitleColor(.colorEC3324(), for: .normal)
|
button.setTitleColor(.colorEC3324(), for: .normal)
|
||||||
button.setImage(UIImage(named: "arrow_right_icon_01"), for: .normal)
|
button.setImage(UIImage(named: "arrow_right_icon_01"), for: .normal)
|
||||||
button.jx_font = .fontMedium(ofSize: 12)
|
button.jx_font = .fontMedium(ofSize: 12)
|
||||||
@ -74,9 +74,8 @@ class SPExplorePlayerControlView: SPPlayerControlView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func updateEpisodeLabel() {
|
private func updateEpisodeLabel() {
|
||||||
// let totalEpisode = String(format: "movia_text_episcode_ios".localized, "\(self.shortModel?.episode_total ?? 0)")
|
let totalEpisode = String(format: "EP%@".localized, "\(self.shortModel?.episode_total ?? 0)")
|
||||||
let totalEpisode = "\(self.shortModel?.episode_total ?? 0)"
|
let currentEpisode = String(format: "EP%@".localized, self.videoInfo?.episode ?? "0")
|
||||||
let currentEpisode = String(format: "movia_text_episcode_ios".localized, self.videoInfo?.episode ?? "0")
|
|
||||||
let episodeStr = "\(currentEpisode)/\(totalEpisode)"
|
let episodeStr = "\(currentEpisode)/\(totalEpisode)"
|
||||||
let range = NSRange(location: episodeStr.length() - totalEpisode.length(), length: totalEpisode.length())
|
let range = NSRange(location: episodeStr.length() - totalEpisode.length(), length: totalEpisode.length())
|
||||||
|
|
||||||
@ -98,9 +97,6 @@ extension SPExplorePlayerControlView {
|
|||||||
self.viewController?.navigationController?.pushViewController(vc, animated: true)
|
self.viewController?.navigationController?.pushViewController(vc, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func handleEpisodeButton() {
|
|
||||||
self.handleAllEpisodeButton()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPVideoPlayerInfoView.swift
|
// SPVideoPlayerInfoView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
24
Thimra/Class/Home/Controller/SPHomeChildController.swift
Normal file
24
Thimra/Class/Home/Controller/SPHomeChildController.swift
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
//
|
||||||
|
// SPHomeChildController.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPHomeChildController: SPViewController {
|
||||||
|
|
||||||
|
var topMargins: CGFloat = 10
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// override func setBgImageView() { }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomePageController.swift
|
// SPHomePageController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
@ -14,16 +14,15 @@ class SPHomePageController: SPViewController {
|
|||||||
///是否在请求中
|
///是否在请求中
|
||||||
private var isRequesting = false
|
private var isRequesting = false
|
||||||
|
|
||||||
private lazy var categoryArr: [SPHomeCategoryModel] = []
|
private lazy var categoryArr: [SPHomeCategoryModel] = {
|
||||||
// {
|
let arr = [
|
||||||
// let arr = [
|
SPHomeCategoryModel(category_name: "Hot Picks".localized, category_id: nil, viewController: SPHomeViewController()),
|
||||||
// SPHomeCategoryModel(category_name: "Hot Picks".localized, category_id: nil, viewController: SPHomeViewController()),
|
SPHomeCategoryModel(category_name: "Top 10".localized, category_id: nil, viewController: nil),
|
||||||
// SPHomeCategoryModel(category_name: "Top 10".localized, category_id: nil, viewController: nil),
|
SPHomeCategoryModel(category_name: "Fresh Drops".localized, category_id: nil, viewController: nil),
|
||||||
// SPHomeCategoryModel(category_name: "Fresh Drops".localized, category_id: nil, viewController: nil),
|
SPHomeCategoryModel(category_name: "Free".localized, category_id: nil, viewController: nil),
|
||||||
// SPHomeCategoryModel(category_name: "Free".localized, category_id: nil, viewController: nil),
|
]
|
||||||
// ]
|
return arr
|
||||||
// return arr
|
}()
|
||||||
// }()
|
|
||||||
|
|
||||||
private lazy var searchButton: SPHomeSearchButton = {
|
private lazy var searchButton: SPHomeSearchButton = {
|
||||||
let button = SPHomeSearchButton()
|
let button = SPHomeSearchButton()
|
||||||
@ -124,7 +123,7 @@ extension SPHomePageController: JYPageControllerDelegate, JYPageControllerDataSo
|
|||||||
|
|
||||||
func childController(atIndex index: Int) -> any JYPageChildContollerProtocol {
|
func childController(atIndex index: Int) -> any JYPageChildContollerProtocol {
|
||||||
let vc = SPHomeViewController()
|
let vc = SPHomeViewController()
|
||||||
// vc.topMargins = 15
|
vc.topMargins = 15
|
||||||
return vc
|
return vc
|
||||||
}
|
}
|
||||||
|
|
@ -1,22 +1,19 @@
|
|||||||
//
|
//
|
||||||
// SPHomeViewController.swift
|
// SPHomeViewController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class SPHomeViewController: SPViewController {
|
class SPHomeViewController: SPHomeChildController {
|
||||||
|
|
||||||
|
|
||||||
private lazy var viewModel: SPHomeViewModel = SPHomeViewModel()
|
private lazy var viewModel: SPHomeViewModel = SPHomeViewModel()
|
||||||
|
|
||||||
|
private lazy var page = 1
|
||||||
|
private lazy var dataArr: [SPShortModel] = []
|
||||||
private lazy var requestGroup = DispatchGroup()
|
|
||||||
|
|
||||||
private var isSetupUI = false
|
|
||||||
|
|
||||||
//MARK: UI属性
|
//MARK: UI属性
|
||||||
private lazy var logoImageView: UIImageView = {
|
private lazy var logoImageView: UIImageView = {
|
||||||
@ -32,24 +29,6 @@ class SPHomeViewController: SPViewController {
|
|||||||
return button
|
return button
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var allButton: UIButton = {
|
|
||||||
let button = UIButton(type: .custom)
|
|
||||||
button.setImage(UIImage(named: "all_icon_01"), for: .normal)
|
|
||||||
button.setContentHuggingPriority(.required, for: .horizontal)
|
|
||||||
button.setContentCompressionResistancePriority(.required, for: .horizontal)
|
|
||||||
button.addTarget(self, action: #selector(handleAllButton), for: .touchUpInside)
|
|
||||||
return button
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var rewardButton: UIButton = {
|
|
||||||
let button = UIButton(type: .custom)
|
|
||||||
button.setImage(UIImage(named: "reward_icon_01"), for: .normal)
|
|
||||||
button.setContentHuggingPriority(.required, for: .horizontal)
|
|
||||||
button.setContentCompressionResistancePriority(.required, for: .horizontal)
|
|
||||||
button.addTarget(self, action: #selector(handleRewardButton), for: .touchUpInside)
|
|
||||||
return button
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var layout: UICollectionViewFlowLayout = {
|
private lazy var layout: UICollectionViewFlowLayout = {
|
||||||
let width = floor((kSPScreenWidth - 32 - 13) / 2)
|
let width = floor((kSPScreenWidth - 32 - 13) / 2)
|
||||||
let height = 221 / 165 * width + 44
|
let height = 221 / 165 * width + 44
|
||||||
@ -78,28 +57,15 @@ class SPHomeViewController: SPViewController {
|
|||||||
return collectionView
|
return collectionView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private var headerView: SPHomeHeaderView?
|
|
||||||
|
|
||||||
private lazy var playHistoricalView: SPHomePlayHistoricalView = {
|
|
||||||
let view = SPHomePlayHistoricalView()
|
|
||||||
view.isHidden = true
|
|
||||||
return view
|
|
||||||
}()
|
|
||||||
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
|
||||||
|
|
||||||
|
|
||||||
|
updateAllData(completer: nil)
|
||||||
|
|
||||||
if SPNetworkReachabilityManager.manager.isReachable == true {
|
_setupUI()
|
||||||
updateAllData(completer: nil)
|
|
||||||
_setupUI()
|
|
||||||
} else {
|
|
||||||
setEmptyView()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,20 +74,6 @@ class SPHomeViewController: SPViewController {
|
|||||||
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
|
||||||
if hasViewDidAppear {
|
|
||||||
requestPlayHistory()
|
|
||||||
}
|
|
||||||
super.viewDidAppear(animated)
|
|
||||||
|
|
||||||
self.headerView?.isDidAppear = self.isDidAppear
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidDisappear(_ animated: Bool) {
|
|
||||||
super.viewDidDisappear(animated)
|
|
||||||
self.headerView?.isDidAppear = self.isDidAppear
|
|
||||||
}
|
|
||||||
|
|
||||||
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
|
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
|
||||||
|
|
||||||
updateAllData { [weak self] in
|
updateAllData { [weak self] in
|
||||||
@ -130,7 +82,7 @@ class SPHomeViewController: SPViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func handleFooterRefresh(_ completer: (() -> Void)?) {
|
override func handleFooterRefresh(_ completer: (() -> Void)?) {
|
||||||
requestListDataArr(page: self.viewModel.page + 1) { [weak self] in
|
requestListDataArr(page: self.page + 1) { [weak self] in
|
||||||
self?.collectionView.sp_endFooterRefreshing()
|
self?.collectionView.sp_endFooterRefreshing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,42 +90,22 @@ class SPHomeViewController: SPViewController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extension SPHomeViewController {
|
extension SPHomeViewController {
|
||||||
|
|
||||||
private func _setupUI() {
|
private func _setupUI() {
|
||||||
if isSetupUI { return }
|
view.addSubview(logoImageView)
|
||||||
isSetupUI = true
|
|
||||||
|
|
||||||
// view.addSubview(logoImageView)
|
|
||||||
view.addSubview(searchButton)
|
view.addSubview(searchButton)
|
||||||
view.addSubview(allButton)
|
|
||||||
view.addSubview(rewardButton)
|
|
||||||
view.addSubview(self.collectionView)
|
view.addSubview(self.collectionView)
|
||||||
view.addSubview(playHistoricalView)
|
|
||||||
|
|
||||||
// logoImageView.snp.makeConstraints { make in
|
logoImageView.snp.makeConstraints { make in
|
||||||
// make.left.equalToSuperview().offset(16)
|
make.left.equalToSuperview().offset(16)
|
||||||
// make.centerY.equalTo(searchButton)
|
make.centerY.equalTo(searchButton)
|
||||||
// }
|
}
|
||||||
|
|
||||||
searchButton.snp.makeConstraints { make in
|
searchButton.snp.makeConstraints { make in
|
||||||
// make.left.equalTo(logoImageView.snp.right).offset(6)
|
make.left.equalTo(logoImageView.snp.right).offset(6)
|
||||||
make.left.equalToSuperview().offset(16)
|
|
||||||
// make.right.equalToSuperview().offset(-16)
|
|
||||||
make.right.equalTo(allButton.snp.left).offset(-4)
|
|
||||||
make.top.equalToSuperview().offset(kSPStatusbarHeight + 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
allButton.snp.makeConstraints { make in
|
|
||||||
make.centerY.equalTo(searchButton)
|
|
||||||
// make.right.equalToSuperview().offset(-16)
|
|
||||||
make.right.equalTo(rewardButton.snp.left).offset(-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
rewardButton.snp.makeConstraints { make in
|
|
||||||
make.centerY.equalTo(searchButton)
|
|
||||||
make.right.equalToSuperview().offset(-16)
|
make.right.equalToSuperview().offset(-16)
|
||||||
|
make.top.equalToSuperview().offset(kSPStatusbarHeight + 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.collectionView.snp.makeConstraints { make in
|
self.collectionView.snp.makeConstraints { make in
|
||||||
@ -181,12 +113,6 @@ extension SPHomeViewController {
|
|||||||
// make.top.equalToSuperview().offset(kSPStatusbarHeight + 66)
|
// make.top.equalToSuperview().offset(kSPStatusbarHeight + 66)
|
||||||
make.top.equalTo(searchButton.snp.bottom).offset(34)
|
make.top.equalTo(searchButton.snp.bottom).offset(34)
|
||||||
}
|
}
|
||||||
|
|
||||||
playHistoricalView.snp.makeConstraints { make in
|
|
||||||
make.left.equalToSuperview().offset(16)
|
|
||||||
make.centerX.equalToSuperview()
|
|
||||||
make.bottom.equalToSuperview().offset(-4)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,45 +122,11 @@ extension SPHomeViewController {
|
|||||||
self.navigationController?.pushViewController(vc, animated: true)
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
///设置无网空页面
|
|
||||||
private func setEmptyView() {
|
|
||||||
if SPNetworkReachabilityManager.manager.isReachable != true {
|
|
||||||
self.addNoNetworkEmptyView { [weak self] in
|
|
||||||
guard let self = self else { return }
|
|
||||||
self.updateEmptyState()
|
|
||||||
if self.viewModel.isEmptyData, SPNetworkReachabilityManager.manager.isReachable == true {
|
|
||||||
self.updateAllData(completer: nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private func reachabilityDidChangeNotification() {
|
@objc private func reachabilityDidChangeNotification() {
|
||||||
updateEmptyState()
|
if SPNetworkReachabilityManager.manager.isReachable == true, self.viewModel.moduleModel == nil {
|
||||||
|
updateAllData(completer: nil)
|
||||||
if viewModel.isEmptyData, SPNetworkReachabilityManager.manager.isReachable == true {
|
|
||||||
self.updateAllData(completer: nil)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///更新空白页面状态
|
|
||||||
private func updateEmptyState() {
|
|
||||||
if SPNetworkReachabilityManager.manager.isReachable == true {
|
|
||||||
self._setupUI()
|
|
||||||
self.removeNoNetworkEmptyView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private func handleAllButton() {
|
|
||||||
let vc = SPAllViewController()
|
|
||||||
self.navigationController?.pushViewController(vc, animated: true)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc private func handleRewardButton() {
|
|
||||||
let vc = SPRewardsViewController()
|
|
||||||
self.navigationController?.pushViewController(vc, animated: true)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -243,26 +135,25 @@ extension SPHomeViewController: UICollectionViewDelegate, UICollectionViewDataSo
|
|||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
let cell = SPHomeShortCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
let cell = SPHomeShortCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
||||||
cell.model = viewModel.dataArr[indexPath.row]
|
cell.model = dataArr[indexPath.row]
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
return viewModel.dataArr.count
|
return dataArr.count
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
|
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
|
||||||
if let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerView", for: indexPath) as? SPHomeHeaderView {
|
if let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerView", for: indexPath) as? SPHomeHeaderView {
|
||||||
headerView.viewModel = self.viewModel
|
headerView.viewModel = self.viewModel
|
||||||
self.headerView = headerView
|
|
||||||
return headerView
|
return headerView
|
||||||
}
|
}
|
||||||
return UICollectionReusableView()
|
return UICollectionReusableView()
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
let model = viewModel.dataArr[indexPath.row]
|
let model = self.dataArr[indexPath.row]
|
||||||
|
|
||||||
let vc = SPPlayerDetailViewController()
|
let vc = SPPlayerDetailViewController()
|
||||||
vc.shortPlayId = model.short_play_id
|
vc.shortPlayId = model.short_play_id
|
||||||
@ -275,35 +166,14 @@ extension SPHomeViewController: UICollectionViewDelegate, UICollectionViewDataSo
|
|||||||
|
|
||||||
extension SPHomeViewController {
|
extension SPHomeViewController {
|
||||||
private func updateAllData(completer: (() -> Void)?) {
|
private func updateAllData(completer: (() -> Void)?) {
|
||||||
self.requestGroup.enter()
|
requestModuleData()
|
||||||
requestModuleData { [weak self] in
|
requestPlayHistory()
|
||||||
self?.requestGroup.leave()
|
requestListDataArr(page: 1) {
|
||||||
}
|
|
||||||
self.requestGroup.enter()
|
|
||||||
requestPlayHistory { [weak self] in
|
|
||||||
self?.requestGroup.leave()
|
|
||||||
}
|
|
||||||
self.requestGroup.enter()
|
|
||||||
requestListDataArr(page: 1) { [weak self] in
|
|
||||||
self?.requestGroup.leave()
|
|
||||||
}
|
|
||||||
self.requestGroup.enter()
|
|
||||||
requestCategoryShortList(id: "3") { [weak self] in
|
|
||||||
self?.requestGroup.leave()
|
|
||||||
}
|
|
||||||
// self.requestGroup.enter()
|
|
||||||
// requestCategoryShortList(id: "1") { [weak self] in
|
|
||||||
// self?.requestGroup.leave()
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
self.requestGroup.notify(queue: DispatchQueue.main) {
|
|
||||||
completer?()
|
completer?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///获取模版数据 包括banner 九宫格等
|
private func requestModuleData() {
|
||||||
private func requestModuleData(completer: (() -> Void)? = nil) {
|
|
||||||
SPHomeAPI.requestHomeModuleData { [weak self] model in
|
SPHomeAPI.requestHomeModuleData { [weak self] model in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
if let model = model {
|
if let model = model {
|
||||||
@ -312,49 +182,18 @@ extension SPHomeViewController {
|
|||||||
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
}
|
}
|
||||||
self.updateEmptyState()
|
|
||||||
completer?()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///甜宠ID= 3
|
|
||||||
///虐恋ID=1
|
|
||||||
private func requestCategoryShortList(id: String, completer: (() -> Void)?) {
|
|
||||||
|
|
||||||
SPVideoAPI.requestCategoryShortList(page: 1, id: id) { [weak self] listModel in
|
|
||||||
guard let self = self else { return }
|
|
||||||
|
|
||||||
if let list = listModel?.list {
|
|
||||||
if id == "3" {
|
|
||||||
self.viewModel.categoryDataArr1 = list
|
|
||||||
} else {
|
|
||||||
self.viewModel.categoryDataArr2 = list
|
|
||||||
}
|
|
||||||
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
|
||||||
self.collectionView.reloadData()
|
|
||||||
}
|
|
||||||
self.updateEmptyState()
|
|
||||||
completer?()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///获取播放记录
|
///获取播放记录
|
||||||
private func requestPlayHistory(completer: (() -> Void)? = nil) {
|
private func requestPlayHistory() {
|
||||||
SPVideoAPI.requestPlayHistoryList(page: 1) { [weak self] listModel in
|
SPVideoAPI.requestPlayHistoryList(page: 1) { [weak self] listModel in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
if let list = listModel?.list {
|
if let list = listModel?.list {
|
||||||
self.viewModel.playHistoryArr = list
|
self.viewModel.playHistoryArr = list
|
||||||
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
self.layout.headerReferenceSize = CGSize(width: kSPScreenWidth, height: SPHomeHeaderView.contentHeight(viewModel: self.viewModel))
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
|
|
||||||
if let model = listModel?.list?.first {
|
|
||||||
self.playHistoricalView.model = model
|
|
||||||
self.playHistoricalView.isHidden = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.updateEmptyState()
|
|
||||||
completer?()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,18 +204,15 @@ extension SPHomeViewController {
|
|||||||
|
|
||||||
if let list = listModel?.list {
|
if let list = listModel?.list {
|
||||||
if page == 1 {
|
if page == 1 {
|
||||||
self.viewModel.dataArr.removeAll()
|
self.dataArr.removeAll()
|
||||||
}
|
}
|
||||||
self.viewModel.dataArr += list
|
self.dataArr += list
|
||||||
|
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
self.viewModel.page = page
|
self.page = page
|
||||||
}
|
}
|
||||||
self.updateEmptyState()
|
|
||||||
completer?()
|
completer?()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchViewController.swift
|
// SPSearchViewController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
||||||
@ -60,8 +60,6 @@ class SPSearchViewController: SPViewController {
|
|||||||
|
|
||||||
searchInputView.textField.becomeFirstResponder()
|
searchInputView.textField.becomeFirstResponder()
|
||||||
|
|
||||||
setBackgroundView(isShowGradient: false, bgImage: nil)
|
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeCategoryModel.swift
|
// SPHomeCategoryModel.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/8.
|
// Created by 曾觉新 on 2025/4/8.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeModuleModel.swift
|
// SPHomeModuleModel.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeTopModel.swift
|
// SPHomeTopModel.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeBannerCell.swift
|
// SPHomeBannerCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeDataItemView.swift
|
// SPHomeDataItemView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
||||||
@ -30,7 +30,7 @@ class SPHomeDataItemView: UIView {
|
|||||||
|
|
||||||
private(set) lazy var titleLabel: UILabel = {
|
private(set) lazy var titleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = .fontMedium(ofSize: 18)
|
label.font = .fontWeight(ofSize: 18, weight: 400)
|
||||||
label.textColor = .colorFFFFFF()
|
label.textColor = .colorFFFFFF()
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
@ -42,7 +42,7 @@ class SPHomeDataItemView: UIView {
|
|||||||
|
|
||||||
private lazy var moreButton: UIButton = {
|
private lazy var moreButton: UIButton = {
|
||||||
let button = UIButton(type: .custom)
|
let button = UIButton(type: .custom)
|
||||||
button.setTitle("movia_more".localized, for: .normal)
|
button.setTitle("More".localized, for: .normal)
|
||||||
button.setTitleColor(.colorF564B6(), for: .normal)
|
button.setTitleColor(.colorF564B6(), for: .normal)
|
||||||
button.titleLabel?.font = .fontLight(ofSize: 12)
|
button.titleLabel?.font = .fontLight(ofSize: 12)
|
||||||
return button
|
return button
|
65
Thimra/Class/Home/View/SPHomeExploreCell.swift
Normal file
65
Thimra/Class/Home/View/SPHomeExploreCell.swift
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
//
|
||||||
|
// SPHomeExploreCell.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPHomeExploreCell: SPCollectionViewCell {
|
||||||
|
|
||||||
|
var model: SPShortModel? {
|
||||||
|
didSet {
|
||||||
|
coverImageView.sp_setImage(url: model?.image_url)
|
||||||
|
titleLabel.text = model?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: UI属性
|
||||||
|
private lazy var coverImageView: SPImageView = {
|
||||||
|
let imageView = SPImageView()
|
||||||
|
imageView.layer.cornerRadius = 4
|
||||||
|
imageView.layer.masksToBounds = true
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontRegular(ofSize: 12)
|
||||||
|
label.textColor = .colorFFFFFF()
|
||||||
|
label.numberOfLines = 2
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPHomeExploreCell {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
contentView.addSubview(coverImageView)
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
|
||||||
|
coverImageView.snp.makeConstraints { make in
|
||||||
|
make.left.right.top.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview().offset(-36)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview()
|
||||||
|
make.top.equalTo(coverImageView.snp.bottom).offset(8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeExploreView.swift
|
// SPHomeExploreView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
||||||
@ -62,7 +62,7 @@ class SPHomeExploreView: SPHomeDataItemView {
|
|||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
titleLabel.text = "movia_explore_for_you".localized
|
titleLabel.text = "Explore For You".localized
|
||||||
iconImageView.image = UIImage(named: "mark_icon_01")
|
iconImageView.image = UIImage(named: "mark_icon_01")
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
193
Thimra/Class/Home/View/SPHomeHeaderView.swift
Normal file
193
Thimra/Class/Home/View/SPHomeHeaderView.swift
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
//
|
||||||
|
// SPHomeHeaderView.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPHomeHeaderView: UICollectionReusableView {
|
||||||
|
|
||||||
|
var viewModel: SPHomeViewModel? {
|
||||||
|
didSet {
|
||||||
|
let moduleModel = viewModel?.moduleModel
|
||||||
|
|
||||||
|
stackView.removeAllArrangedSubview()
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(bannerView)
|
||||||
|
bannerView.reloadData()
|
||||||
|
|
||||||
|
if let historyList = viewModel?.playHistoryArr, historyList.count > 0 {
|
||||||
|
stackView.addArrangedSubview(playHistoryView)
|
||||||
|
playHistoryView.dataArr = historyList
|
||||||
|
}
|
||||||
|
|
||||||
|
if let list = moduleModel?.nineSquare?.list, list.count > 0 {
|
||||||
|
stackView.addArrangedSubview(exploreView)
|
||||||
|
exploreView.titleLabel.text = moduleModel?.nineSquare?.title
|
||||||
|
exploreView.dataArr = list
|
||||||
|
}
|
||||||
|
|
||||||
|
// stackView.addArrangedSubview(trendingView)
|
||||||
|
// trendingView.dataArr = moduleModel?.bannerData
|
||||||
|
//
|
||||||
|
// stackView.addArrangedSubview(hotView)
|
||||||
|
// hotView.dataArr = moduleModel?.bannerData
|
||||||
|
//
|
||||||
|
// stackView.addArrangedSubview(shortsForYouView)
|
||||||
|
// shortsForYouView.dataArr = moduleModel?.bannerData
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(titleView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private lazy var stackView: UIStackView = {
|
||||||
|
let view = UIStackView()
|
||||||
|
view.axis = .vertical
|
||||||
|
view.spacing = 25
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var bannerLayout: SPZoomCollectionViewLayout = {
|
||||||
|
let layout = SPZoomCollectionViewLayout()
|
||||||
|
layout.itemSize = .init(width: 234, height: Self.bannerHeight())
|
||||||
|
layout.minimumLineSpacing = 10
|
||||||
|
layout.minimumInteritemSpacing = 0
|
||||||
|
return layout
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var bannerView: SPCollectionView = {
|
||||||
|
let view = SPCollectionView(frame: .zero, collectionViewLayout: bannerLayout)
|
||||||
|
view.delegate = self
|
||||||
|
view.dataSource = self
|
||||||
|
view.showsVerticalScrollIndicator = false
|
||||||
|
view.showsHorizontalScrollIndicator = false
|
||||||
|
SPHomeZoomBannerCell.registerCell(collectionView: view)
|
||||||
|
|
||||||
|
view.snp.makeConstraints { make in
|
||||||
|
make.width.equalTo(kSPScreenWidth)
|
||||||
|
make.height.equalTo(Self.bannerHeight())
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var playHistoryView: SPHomePlayHistoryView = {
|
||||||
|
let view = SPHomePlayHistoryView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var exploreView: SPHomeExploreView = {
|
||||||
|
let view = SPHomeExploreView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var trendingView: SPHomeTrendingView = {
|
||||||
|
let view = SPHomeTrendingView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var hotView: SPHomeHotView = {
|
||||||
|
let view = SPHomeHotView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var shortsForYouView: SPHomeShortsForYouView = {
|
||||||
|
let view = SPHomeShortsForYouView()
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var titleView: SPHomeDataItemView = {
|
||||||
|
let view = SPHomeDataItemView()
|
||||||
|
view.titleLabel.text = "More for you!".localized
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPHomeHeaderView {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
addSubview(stackView)
|
||||||
|
|
||||||
|
stackView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource --------------
|
||||||
|
extension SPHomeHeaderView: UICollectionViewDelegate, UICollectionViewDataSource {
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
|
let cell = SPHomeZoomBannerCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
||||||
|
cell.model = self.viewModel?.moduleModel?.bannerData?[indexPath.row]
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
|
return self.viewModel?.moduleModel?.bannerData?.count ?? 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func numberOfSections(in collectionView: UICollectionView) -> Int {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||||
|
let model = self.viewModel?.moduleModel?.bannerData?[indexPath.row]
|
||||||
|
|
||||||
|
let vc = SPPlayerDetailViewController()
|
||||||
|
vc.shortPlayId = model?.short_play_id
|
||||||
|
self.viewController?.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension SPHomeHeaderView {
|
||||||
|
|
||||||
|
static func contentHeight(viewModel: SPHomeViewModel) -> CGFloat {
|
||||||
|
var height = bannerHeight()
|
||||||
|
let moduleModel = viewModel.moduleModel
|
||||||
|
|
||||||
|
///历史记录
|
||||||
|
if let historyList = viewModel.playHistoryArr, historyList.count > 0 {
|
||||||
|
height = height + SPHomePlayHistoryView.contentHeight(dataArr: historyList) + 25
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///九宫格数据
|
||||||
|
if let list = moduleModel?.nineSquare?.list, list.count > 0 {
|
||||||
|
height = height + SPHomeExploreView.contentHeight(dataArr: list) + 25
|
||||||
|
}
|
||||||
|
|
||||||
|
// height = height + SPHomeTrendingView.contentHeight(dataArr: moduleModel?.bannerData ?? []) + 25
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// height = height + SPHomeHotView.contentHeight(dataArr: moduleModel?.bannerData ?? []) + 25
|
||||||
|
//
|
||||||
|
// height = height + SPHomeShortsForYouView.contentHeight(dataArr: moduleModel?.bannerData ?? []) + 25
|
||||||
|
|
||||||
|
///标题高度
|
||||||
|
height = height + SPHomeDataItemView.contentHeight(dataArr: []) + 25
|
||||||
|
|
||||||
|
return height
|
||||||
|
}
|
||||||
|
|
||||||
|
static func bannerHeight() -> CGFloat {
|
||||||
|
return 336
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeHotCell.swift
|
// SPHomeHotCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeHotSearchCell.swift
|
// SPHomeHotSearchCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeHotSearchView.swift
|
// SPHomeHotSearchView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
||||||
@ -25,7 +25,7 @@ class SPHomeHotSearchView: UIView {
|
|||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = .fontMedium(ofSize: 16)
|
label.font = .fontMedium(ofSize: 16)
|
||||||
label.textColor = .colorFFFFFF()
|
label.textColor = .colorFFFFFF()
|
||||||
label.text = "movia_top_search".localized
|
label.text = "Top Search".localized
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ extension SPHomeHotSearchView {
|
|||||||
|
|
||||||
bgView.snp.makeConstraints { make in
|
bgView.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(16)
|
make.left.equalToSuperview().offset(16)
|
||||||
make.centerX.equalToSuperview()
|
make.centerY.equalToSuperview()
|
||||||
make.top.equalToSuperview()
|
make.top.equalToSuperview()
|
||||||
make.bottom.equalToSuperview()
|
make.bottom.equalToSuperview()
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeHotView.swift
|
// SPHomeHotView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
||||||
@ -46,7 +46,7 @@ class SPHomeHotView: SPHomeDataItemView {
|
|||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
self.titleLabel.text = "movia_editors_hotlist".localized
|
self.titleLabel.text = "Editor's Hotlist".localized
|
||||||
_setupUI()
|
_setupUI()
|
||||||
}
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomePlayHistoryCell.swift
|
// SPHomePlayHistoryCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
||||||
@ -18,7 +18,7 @@ class SPHomePlayHistoryCell: SPCollectionViewCell {
|
|||||||
// model?.episode_total
|
// model?.episode_total
|
||||||
|
|
||||||
let episode_total = "\(model?.episode_total ?? 0)"
|
let episode_total = "\(model?.episode_total ?? 0)"
|
||||||
let episode = String(format: "movia_text_episcode_ios".localized, "\(model?.current_episode ?? "0")") + "/\(episode_total)"
|
let episode = String(format: "EP.%@/%@", "\(model?.current_episode ?? "0")", episode_total)
|
||||||
|
|
||||||
let episodeString = NSMutableAttributedString(string: episode)
|
let episodeString = NSMutableAttributedString(string: episode)
|
||||||
episodeString.color = .colorFF5100()
|
episodeString.color = .colorFF5100()
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomePlayHistoryView.swift
|
// SPHomePlayHistoryView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
||||||
@ -42,7 +42,7 @@ class SPHomePlayHistoryView: SPHomeDataItemView {
|
|||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
self.titleLabel.text = "movia_continue_watching".localized
|
self.titleLabel.text = "Continue watching".localized
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeSearchButton.swift
|
// SPHomeSearchButton.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
||||||
@ -23,7 +23,7 @@ class SPHomeSearchButton: UIControl {
|
|||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = .fontRegular(ofSize: 12)
|
label.font = .fontRegular(ofSize: 12)
|
||||||
label.textColor = .colorFFFFFF(alpha: 0.52)
|
label.textColor = .colorFFFFFF(alpha: 0.52)
|
||||||
label.text = "movia_search_tips".localized
|
label.text = "Love Me Like You Do It".localized
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeSearchHistoryView.swift
|
// SPHomeSearchHistoryView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
||||||
@ -30,7 +30,7 @@ class SPHomeSearchHistoryView: UIView {
|
|||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = .fontBold(ofSize: 16)
|
label.font = .fontBold(ofSize: 16)
|
||||||
label.textColor = .colorE7F5FF()
|
label.textColor = .colorE7F5FF()
|
||||||
label.text = "movia_Historical_search".localized
|
label.text = "Historical search".localized
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeShortCell.swift
|
// SPHomeShortCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
||||||
@ -13,18 +13,6 @@ class SPHomeShortCell: SPCollectionViewCell {
|
|||||||
didSet {
|
didSet {
|
||||||
coverImageView.sp_setImage(url: model?.image_url)
|
coverImageView.sp_setImage(url: model?.image_url)
|
||||||
titleLabel.text = model?.name
|
titleLabel.text = model?.name
|
||||||
|
|
||||||
if model?.tag_type == .hot {
|
|
||||||
markView.isHidden = false
|
|
||||||
markView.colors = [UIColor.color3E23DE(alpha: 0.17).cgColor, UIColor.color4629F1(alpha: 0.74).cgColor, UIColor.color3D1DFF().cgColor]
|
|
||||||
markLabel.text = "HOT"
|
|
||||||
} else if model?.tag_type == .new {
|
|
||||||
markView.isHidden = false
|
|
||||||
markView.colors = [UIColor.colorDE2326(alpha: 0.17).cgColor, UIColor.colorF1298A(alpha: 0.74).cgColor, UIColor.colorFF1DE8().cgColor]
|
|
||||||
markLabel.text = "NEW"
|
|
||||||
} else {
|
|
||||||
markView.isHidden = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,22 +21,6 @@ class SPHomeShortCell: SPCollectionViewCell {
|
|||||||
return imageView
|
return imageView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private lazy var markView: SPGradientView = {
|
|
||||||
let view = SPGradientView()
|
|
||||||
view.locations = [0, 0.3, 1]
|
|
||||||
view.startPoint = .init(x: 0, y: 0.7)
|
|
||||||
view.endPoint = .init(x: 1, y: 0.5)
|
|
||||||
view.addRadius(topLeft: 0, topRight: 4, bottomLeft: 12, bottomRight: 0)
|
|
||||||
return view
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var markLabel: UILabel = {
|
|
||||||
let label = UILabel()
|
|
||||||
label.font = .fontBold(ofSize: 12)
|
|
||||||
label.textColor = .colorFFFFFF()
|
|
||||||
return label
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var titleLabel: UILabel = {
|
private lazy var titleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = .fontMedium(ofSize: 12)
|
label.font = .fontMedium(ofSize: 12)
|
||||||
@ -75,8 +47,6 @@ class SPHomeShortCell: SPCollectionViewCell {
|
|||||||
extension SPHomeShortCell {
|
extension SPHomeShortCell {
|
||||||
private func _setupUI() {
|
private func _setupUI() {
|
||||||
contentView.addSubview(coverImageView)
|
contentView.addSubview(coverImageView)
|
||||||
coverImageView.addSubview(markView)
|
|
||||||
markView.addSubview(markLabel)
|
|
||||||
contentView.addSubview(titleLabel)
|
contentView.addSubview(titleLabel)
|
||||||
|
|
||||||
coverImageView.snp.makeConstraints { make in
|
coverImageView.snp.makeConstraints { make in
|
||||||
@ -84,17 +54,6 @@ extension SPHomeShortCell {
|
|||||||
make.bottom.equalToSuperview().offset(-44)
|
make.bottom.equalToSuperview().offset(-44)
|
||||||
}
|
}
|
||||||
|
|
||||||
markView.snp.makeConstraints { make in
|
|
||||||
make.top.equalToSuperview().offset(6)
|
|
||||||
make.right.equalToSuperview().offset(-6)
|
|
||||||
make.width.equalTo(46)
|
|
||||||
make.height.equalTo(18)
|
|
||||||
}
|
|
||||||
|
|
||||||
markLabel.snp.makeConstraints { make in
|
|
||||||
make.center.equalToSuperview()
|
|
||||||
}
|
|
||||||
|
|
||||||
titleLabel.snp.makeConstraints { make in
|
titleLabel.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(8)
|
make.left.equalToSuperview().offset(8)
|
||||||
make.right.lessThanOrEqualToSuperview().offset(-8)
|
make.right.lessThanOrEqualToSuperview().offset(-8)
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeShortsForYouCell.swift
|
// SPHomeShortsForYouCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPHomeShortsForYouView.swift
|
// SPHomeShortsForYouView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
||||||
@ -43,7 +43,7 @@ class SPHomeShortsForYouView: SPHomeDataItemView {
|
|||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
self.titleLabel.text = "movia_shorts_for_you".localized
|
self.titleLabel.text = "Shorts for You".localized
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
}
|
}
|
91
Thimra/Class/Home/View/SPHomeTrendingCell.swift
Normal file
91
Thimra/Class/Home/View/SPHomeTrendingCell.swift
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// SPHomeTrendingCell.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPHomeTrendingCell: SPCollectionViewCell {
|
||||||
|
|
||||||
|
var model: SPShortModel? {
|
||||||
|
didSet {
|
||||||
|
coverImageView.sp_setImage(url: model?.image_url)
|
||||||
|
titleLabel.text = model?.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private lazy var coverImageView: SPImageView = {
|
||||||
|
let imageView = SPImageView()
|
||||||
|
imageView.layer.cornerRadius = 10
|
||||||
|
imageView.layer.masksToBounds = true
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var titleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = .fontLight(ofSize: 13)
|
||||||
|
label.textColor = .colorFFFFFF(alpha: 0.9)
|
||||||
|
label.numberOfLines = 2
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var hotBgView: SPGradientView = {
|
||||||
|
let view = SPGradientView()
|
||||||
|
view.colors = [UIColor.colorF56490().cgColor, UIColor.colorBF6BFF().cgColor]
|
||||||
|
view.startPoint = .init(x: 0.5, y: 0)
|
||||||
|
view.endPoint = .init(x: 0.5, y: 1)
|
||||||
|
view.locations = [0, 1]
|
||||||
|
view.addRadius(topLeft: 0, topRight: 0, bottomLeft: 0, bottomRight: 6)
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var hotIconImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView(image: UIImage(named: "hot_icon_01"))
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPHomeTrendingCell {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
contentView.addSubview(coverImageView)
|
||||||
|
contentView.addSubview(titleLabel)
|
||||||
|
coverImageView.addSubview(hotBgView)
|
||||||
|
hotBgView.addSubview(hotIconImageView)
|
||||||
|
|
||||||
|
coverImageView.snp.makeConstraints { make in
|
||||||
|
make.left.right.top.equalToSuperview()
|
||||||
|
make.bottom.equalToSuperview().offset(-38)
|
||||||
|
}
|
||||||
|
|
||||||
|
titleLabel.snp.makeConstraints { make in
|
||||||
|
make.left.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview()
|
||||||
|
make.top.equalTo(coverImageView.snp.bottom).offset(5)
|
||||||
|
}
|
||||||
|
|
||||||
|
hotBgView.snp.makeConstraints { make in
|
||||||
|
make.left.top.equalToSuperview()
|
||||||
|
make.width.equalTo(22)
|
||||||
|
make.height.equalTo(16)
|
||||||
|
}
|
||||||
|
|
||||||
|
hotIconImageView.snp.makeConstraints { make in
|
||||||
|
make.center.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,50 +1,53 @@
|
|||||||
//
|
//
|
||||||
// SPHomeTrendingView.swift
|
// SPHomeTrendingView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/14.
|
// Created by 曾觉新 on 2025/4/14.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class SPHomeTrendingView: UIView {
|
class SPHomeTrendingView: SPHomeDataItemView {
|
||||||
|
|
||||||
private static func itemSize() -> CGSize {
|
private static func itemSize() -> CGSize {
|
||||||
|
let width = floor((kSPScreenWidth - 15 * 2 - 12 * 2) / 3)
|
||||||
|
let imageScale: CGFloat = 153 / 107
|
||||||
|
let height = width * imageScale + 38
|
||||||
|
|
||||||
return CGSize(width: 224, height: 106)
|
return CGSize(width: width, height: height)
|
||||||
}
|
}
|
||||||
|
|
||||||
class func contentHeight(dataArr: [SPShortModel]) -> CGFloat {
|
override class func contentHeight(dataArr: [SPShortModel]) -> CGFloat {
|
||||||
return 388
|
|
||||||
|
var height = self.contentToTop
|
||||||
|
|
||||||
|
var lineCount = dataArr.count / 3
|
||||||
|
if dataArr.count % 3 > 0 {
|
||||||
|
lineCount += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
let contentHeight = itemSize().height * CGFloat(lineCount) + 12 * CGFloat(lineCount - 1)
|
||||||
|
if contentHeight > 0 {
|
||||||
|
height += contentHeight
|
||||||
|
} else {
|
||||||
|
height += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return height
|
||||||
}
|
}
|
||||||
|
|
||||||
var dataArr: [SPShortModel]? {
|
override var dataArr: [SPShortModel]? {
|
||||||
didSet {
|
didSet {
|
||||||
self.collectionView.reloadData()
|
self.collectionView.reloadData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//MARK: UI属性
|
|
||||||
private lazy var bgView: UIImageView = {
|
|
||||||
let view = UIImageView(image: UIImage(named: "category_bg_image_03"))
|
|
||||||
return view
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var titleLabel: UILabel = {
|
|
||||||
let label = UILabel()
|
|
||||||
label.font = .fontMedium(ofSize: 18)
|
|
||||||
label.textColor = .colorFFC234()
|
|
||||||
return label
|
|
||||||
}()
|
|
||||||
|
|
||||||
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
||||||
let layout = UICollectionViewFlowLayout()
|
let layout = UICollectionViewFlowLayout()
|
||||||
layout.minimumLineSpacing = 12
|
layout.minimumLineSpacing = 12
|
||||||
layout.minimumInteritemSpacing = 12
|
layout.minimumInteritemSpacing = 12
|
||||||
layout.itemSize = Self.itemSize()
|
layout.itemSize = Self.itemSize()
|
||||||
layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
|
layout.sectionInset = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15)
|
||||||
layout.scrollDirection = .horizontal
|
|
||||||
return layout
|
return layout
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -52,9 +55,7 @@ class SPHomeTrendingView: UIView {
|
|||||||
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||||
collectionView.delegate = self
|
collectionView.delegate = self
|
||||||
collectionView.dataSource = self
|
collectionView.dataSource = self
|
||||||
// collectionView.isScrollEnabled = false
|
collectionView.isScrollEnabled = false
|
||||||
collectionView.showsVerticalScrollIndicator = false
|
|
||||||
collectionView.showsHorizontalScrollIndicator = false
|
|
||||||
SPHomeTrendingCell.registerCell(collectionView: collectionView)
|
SPHomeTrendingCell.registerCell(collectionView: collectionView)
|
||||||
return collectionView
|
return collectionView
|
||||||
}()
|
}()
|
||||||
@ -62,7 +63,8 @@ class SPHomeTrendingView: UIView {
|
|||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
self.titleLabel.text = "movia_trending_now".localized
|
|
||||||
|
self.titleLabel.text = "Trending Now".localized
|
||||||
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
}
|
}
|
||||||
@ -75,23 +77,10 @@ class SPHomeTrendingView: UIView {
|
|||||||
extension SPHomeTrendingView {
|
extension SPHomeTrendingView {
|
||||||
|
|
||||||
private func _setupUI() {
|
private func _setupUI() {
|
||||||
addSubview(bgView)
|
contentView.addSubview(collectionView)
|
||||||
addSubview(titleLabel)
|
|
||||||
addSubview(collectionView)
|
|
||||||
|
|
||||||
titleLabel.snp.makeConstraints { make in
|
|
||||||
make.left.equalToSuperview().offset(16)
|
|
||||||
make.top.equalToSuperview().offset(14)
|
|
||||||
}
|
|
||||||
|
|
||||||
bgView.snp.makeConstraints { make in
|
|
||||||
make.left.equalToSuperview()
|
|
||||||
make.top.equalToSuperview()
|
|
||||||
}
|
|
||||||
|
|
||||||
collectionView.snp.makeConstraints { make in
|
collectionView.snp.makeConstraints { make in
|
||||||
make.left.right.bottom.equalToSuperview()
|
make.edges.equalToSuperview()
|
||||||
make.top.equalToSuperview().offset(46)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,17 +90,12 @@ extension SPHomeTrendingView {
|
|||||||
extension SPHomeTrendingView: UICollectionViewDataSource, UICollectionViewDelegate {
|
extension SPHomeTrendingView: UICollectionViewDataSource, UICollectionViewDelegate {
|
||||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||||
let cell = SPHomeTrendingCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
let cell = SPHomeTrendingCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
|
||||||
cell.row = indexPath.row
|
|
||||||
cell.model = dataArr?[indexPath.row]
|
cell.model = dataArr?[indexPath.row]
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||||
var count = self.dataArr?.count ?? 0
|
return dataArr?.count ?? 0
|
||||||
if count > 9 {
|
|
||||||
count = 9
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
@ -1,23 +1,18 @@
|
|||||||
//
|
//
|
||||||
// SPHomeZoomBannerCell.swift
|
// SPHomeZoomBannerCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/22.
|
// Created by Overseas on 2025/4/22.
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class SPHomeZoomBannerCell: ZKCycleScrollViewCell {
|
class SPHomeZoomBannerCell: SPCollectionViewCell {
|
||||||
|
|
||||||
var model: SPShortModel? {
|
var model: SPShortModel? {
|
||||||
didSet {
|
didSet {
|
||||||
coverImageView.sp_setImage(url: model?.image_url)
|
coverImageView.sp_setImage(url: model?.image_url)
|
||||||
titleLabel.text = model?.name
|
titleLabel.text = model?.name
|
||||||
if model?.tag_type == .new {
|
|
||||||
iconImageView.isHidden = false
|
|
||||||
} else {
|
|
||||||
iconImageView.isHidden = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +78,7 @@ extension SPHomeZoomBannerCell {
|
|||||||
|
|
||||||
titleLabel.snp.makeConstraints { make in
|
titleLabel.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(15)
|
make.left.equalToSuperview().offset(15)
|
||||||
make.right.lessThanOrEqualToSuperview().offset(-40)
|
make.right.lessThanOrEqualToSuperview().offset(-15)
|
||||||
make.centerY.equalToSuperview()
|
make.centerY.equalToSuperview()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchAssociativeCell.swift
|
// SPSearchAssociativeCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/18.
|
// Created by 曾觉新 on 2025/4/18.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchAssociativeView.swift
|
// SPSearchAssociativeView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/18.
|
// Created by 曾觉新 on 2025/4/18.
|
||||||
//
|
//
|
||||||
@ -24,7 +24,6 @@ class SPSearchAssociativeView: UIView {
|
|||||||
tableView.separatorInset = .init(top: 0, left: 16, bottom: 0, right: 16)
|
tableView.separatorInset = .init(top: 0, left: 16, bottom: 0, right: 16)
|
||||||
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
tableView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: kSPTabbarSafeBottomMargin, right: 0)
|
||||||
tableView.keyboardDismissMode = .onDrag
|
tableView.keyboardDismissMode = .onDrag
|
||||||
tableView.showNormalEmpty(image: UIImage(named: "empty_image_03"))
|
|
||||||
SPSearchAssociativeCell.registerCell(tableView: tableView)
|
SPSearchAssociativeCell.registerCell(tableView: tableView)
|
||||||
return tableView
|
return tableView
|
||||||
}()
|
}()
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchHomeView.swift
|
// SPSearchHomeView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchInputView.swift
|
// SPSearchInputView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchResultCell.swift
|
// SPSearchResultCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/18.
|
// Created by 曾觉新 on 2025/4/18.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchResultView.swift
|
// SPSearchResultView.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/18.
|
// Created by 曾觉新 on 2025/4/18.
|
||||||
//
|
//
|
19
Thimra/Class/Home/ViewModel/SPHomeViewModel.swift
Normal file
19
Thimra/Class/Home/ViewModel/SPHomeViewModel.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// SPHomeViewModel.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by Overseas on 2025/4/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPHomeViewModel: NSObject {
|
||||||
|
|
||||||
|
var moduleModel: SPHomeModuleModel?
|
||||||
|
|
||||||
|
///历史记录
|
||||||
|
var playHistoryArr: [SPShortModel]?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPSearchViewModel.swift
|
// SPSearchViewModel.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/18.
|
// Created by 曾觉新 on 2025/4/18.
|
||||||
//
|
//
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPAboutUsViewController.swift
|
// SPAboutUsViewController.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/19.
|
// Created by Overseas on 2025/4/19.
|
||||||
//
|
//
|
||||||
@ -11,12 +11,12 @@ class SPAboutUsViewController: SPViewController {
|
|||||||
|
|
||||||
private lazy var dataArr: [SPMineItem] = {
|
private lazy var dataArr: [SPMineItem] = {
|
||||||
let arr = [
|
let arr = [
|
||||||
SPMineItem(type: .userAgreement, title: "movia_profile_User_Agreement".localized),
|
SPMineItem(type: .userAgreement, title: "User Agreement".localized),
|
||||||
SPMineItem(type: .privacyPolicy, title: "movia_profile_Privacy_Policy".localized),
|
SPMineItem(type: .privacyPolicy, title: "Privacy Policy".localized),
|
||||||
SPMineItem(type: .informationProtection, title: "movia_child_protection_text".localized),
|
SPMineItem(type: .informationProtection, title: "Child Personal Information Protection Rules".localized),
|
||||||
SPMineItem(type: .civizatioConvention, title: "movia_civizatio_convention_text".localized),
|
SPMineItem(type: .civizatioConvention, title: "Youth Civilization Convention".localized),
|
||||||
SPMineItem(type: .informationSharing, title: "movia_information_sharing_text".localized),
|
SPMineItem(type: .informationSharing, title: "List of Third-Party Sharing of Personal Information".localized),
|
||||||
SPMineItem(type: .persoInforDisclosure, title: "movia_persoInfor_disclosure_text".localized),
|
SPMineItem(type: .persoInforDisclosure, title: "Explicit List of Personal Information Collection".localized),
|
||||||
]
|
]
|
||||||
return arr
|
return arr
|
||||||
}()
|
}()
|
||||||
@ -37,8 +37,8 @@ class SPAboutUsViewController: SPViewController {
|
|||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
self.title = "movia_profile_About_Us".localized
|
self.title = "About Us".localized
|
||||||
setBackgroundView(isShowGradient: false, bgImage: nil)
|
|
||||||
_setupUI()
|
_setupUI()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,6 +47,10 @@ class SPAboutUsViewController: SPViewController {
|
|||||||
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
self.navigationController?.setNavigationBarHidden(false, animated: true)
|
||||||
setNavigationNormalStyle()
|
setNavigationNormalStyle()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func setBgImageView() {
|
||||||
|
self.view.backgroundColor = .backgroundColor()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
153
Thimra/Class/Mine/Controller/SPMineViewController.swift
Normal file
153
Thimra/Class/Mine/Controller/SPMineViewController.swift
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
//
|
||||||
|
// SPMineViewController.swift
|
||||||
|
// Thimra
|
||||||
|
//
|
||||||
|
// Created by 曾觉新 on 2025/4/10.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class SPMineViewController: SPViewController {
|
||||||
|
|
||||||
|
private lazy var dataArr: [SPMineItem] = {
|
||||||
|
let arr = [
|
||||||
|
// SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "Language".localized),
|
||||||
|
SPMineItem(type: .privacyPolicy, iconImage: UIImage(named: "privacy_policy_icon_01"), title: "Privacy Policy".localized),
|
||||||
|
SPMineItem(type: .userAgreement, iconImage: UIImage(named: "user_agreement_icon_01"), title: "User Agreement".localized),
|
||||||
|
SPMineItem(type: .aboutUs, iconImage: UIImage(named: "about_us_icon_01"), title: "About Us".localized),
|
||||||
|
]
|
||||||
|
return arr
|
||||||
|
}()
|
||||||
|
|
||||||
|
///是否进入过
|
||||||
|
private var isHaveEntered = false
|
||||||
|
|
||||||
|
//MARK: UI 属性
|
||||||
|
private lazy var headerView: SPMineHeaderView = {
|
||||||
|
let view = SPMineHeaderView()
|
||||||
|
view.frame = CGRect(x: 0, y: 0, width: kSPScreenWidth, height: view.contentHeight)
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
private lazy var tableView: SPTableView = {
|
||||||
|
let tableView = SPTableView(frame: .zero, style: .plain)
|
||||||
|
tableView.delegate = self
|
||||||
|
tableView.dataSource = self
|
||||||
|
tableView.rowHeight = 50
|
||||||
|
SPMineCell.registerCell(tableView: tableView)
|
||||||
|
return tableView
|
||||||
|
}()
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
requestData()
|
||||||
|
|
||||||
|
_setupUI()
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewWillAppear(_ animated: Bool) {
|
||||||
|
super.viewWillAppear(animated)
|
||||||
|
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
if isHaveEntered {
|
||||||
|
requestData()
|
||||||
|
}
|
||||||
|
|
||||||
|
isHaveEntered = true
|
||||||
|
}
|
||||||
|
|
||||||
|
private func updateHeaderView() {
|
||||||
|
tableView.tableHeaderView = nil
|
||||||
|
self.headerView.height = self.headerView.contentHeight
|
||||||
|
|
||||||
|
tableView.tableHeaderView = headerView
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPMineViewController {
|
||||||
|
|
||||||
|
private func _setupUI() {
|
||||||
|
tableView.tableHeaderView = self.headerView
|
||||||
|
|
||||||
|
view.addSubview(tableView)
|
||||||
|
|
||||||
|
tableView.snp.makeConstraints { make in
|
||||||
|
make.edges.equalToSuperview()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: -------------- UITableViewDelegate & UITableViewDataSource --------------
|
||||||
|
extension SPMineViewController: UITableViewDelegate, UITableViewDataSource {
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||||
|
let cell = SPMineCell.dequeueReusableCell(tableView: tableView, indexPath: indexPath)
|
||||||
|
cell.item = dataArr[indexPath.row]
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||||
|
return dataArr.count
|
||||||
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
let item = dataArr[indexPath.row]
|
||||||
|
switch item.type {
|
||||||
|
case .privacyPolicy:
|
||||||
|
let vc = SPWebViewController()
|
||||||
|
vc.urlStr = SPPrivacyPolicyWebUrl
|
||||||
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
|
||||||
|
case .userAgreement:
|
||||||
|
let vc = SPWebViewController()
|
||||||
|
vc.urlStr = SPUserAgreementWebUrl
|
||||||
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
|
||||||
|
case .aboutUs:
|
||||||
|
let vc = SPAboutUsViewController()
|
||||||
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SPMineViewController {
|
||||||
|
|
||||||
|
private func requestData() {
|
||||||
|
requestUserInfo()
|
||||||
|
requestPlayHistoryList()
|
||||||
|
}
|
||||||
|
|
||||||
|
///获取用户信息
|
||||||
|
private func requestUserInfo() {
|
||||||
|
SPUserAPI.requestUserInfo { [weak self] userInfo in
|
||||||
|
guard let self = self else { return }
|
||||||
|
if let userInfo = userInfo {
|
||||||
|
self.headerView.userInfo = userInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///获取播放记录
|
||||||
|
private func requestPlayHistoryList() {
|
||||||
|
SPVideoAPI.requestPlayHistoryList(page: 1, pageSize: 3) { [weak self] listModel in
|
||||||
|
guard let self = self else { return }
|
||||||
|
if let list = listModel?.list {
|
||||||
|
self.headerView.playHistoryArr = list
|
||||||
|
|
||||||
|
self.updateHeaderView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPMineItem.swift
|
// SPMineItem.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by 曾觉新 on 2025/4/17.
|
// Created by 曾觉新 on 2025/4/17.
|
||||||
//
|
//
|
||||||
@ -29,27 +29,12 @@ struct SPMineItem {
|
|||||||
case informationSharing
|
case informationSharing
|
||||||
///收集个人信息明示清单
|
///收集个人信息明示清单
|
||||||
case persoInforDisclosure
|
case persoInforDisclosure
|
||||||
///反馈
|
|
||||||
case feedBack
|
|
||||||
///设置
|
|
||||||
case settings
|
|
||||||
///消费记录
|
|
||||||
case consumptionRecords
|
|
||||||
///赠币记录
|
|
||||||
case rewardCoins
|
|
||||||
///清理缓存
|
|
||||||
case clearCache
|
|
||||||
///注销账户
|
|
||||||
case deleteAccount
|
|
||||||
///退出登录
|
|
||||||
case logout
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var type: ItemType?
|
var type: ItemType?
|
||||||
var iconImage: UIImage?
|
var iconImage: UIImage?
|
||||||
var title: String?
|
var title: String?
|
||||||
var subtitle: String?
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,6 @@
|
|||||||
//
|
//
|
||||||
// SPAboutUsCell.swift
|
// SPAboutUsCell.swift
|
||||||
// ThimraTV
|
// Thimra
|
||||||
//
|
//
|
||||||
// Created by Overseas on 2025/4/23.
|
// Created by Overseas on 2025/4/23.
|
||||||
//
|
//
|
||||||
@ -44,7 +44,6 @@ extension SPAboutUsCell {
|
|||||||
titleLabel.snp.makeConstraints { make in
|
titleLabel.snp.makeConstraints { make in
|
||||||
make.centerY.equalToSuperview()
|
make.centerY.equalToSuperview()
|
||||||
make.left.equalToSuperview().offset(16)
|
make.left.equalToSuperview().offset(16)
|
||||||
make.right.lessThanOrEqualToSuperview().offset(-80)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user