w2a,推送

This commit is contained in:
zeng 2025-07-28 19:36:03 +08:00
parent 688a992aab
commit 219b70a6f0
92 changed files with 3237 additions and 40 deletions

View File

@ -175,7 +175,36 @@
F398554E2E34699F00E2D28D /* BRVideoLockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398554D2E34699F00E2D28D /* BRVideoLockView.swift */; }; F398554E2E34699F00E2D28D /* BRVideoLockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398554D2E34699F00E2D28D /* BRVideoLockView.swift */; };
F39855502E34782200E2D28D /* BRVideoUnlockModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398554F2E34782200E2D28D /* BRVideoUnlockModel.swift */; }; F39855502E34782200E2D28D /* BRVideoUnlockModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398554F2E34782200E2D28D /* BRVideoUnlockModel.swift */; };
F39855522E347BDE00E2D28D /* BRVideoRechargeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855512E347BDE00E2D28D /* BRVideoRechargeView.swift */; }; F39855522E347BDE00E2D28D /* BRVideoRechargeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855512E347BDE00E2D28D /* BRVideoRechargeView.swift */; };
F39855542E34A49500E2D28D /* VPPayDataRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855532E34A49500E2D28D /* VPPayDataRequest.swift */; }; F39855542E34A49500E2D28D /* BRPayDataRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855532E34A49500E2D28D /* BRPayDataRequest.swift */; };
F39855562E34BD6000E2D28D /* BRWalletViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855552E34BD6000E2D28D /* BRWalletViewController.swift */; };
F39855582E34CA2C00E2D28D /* BROrderRecordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855572E34CA2C00E2D28D /* BROrderRecordViewController.swift */; };
F398555A2E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855592E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift */; };
F398555C2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398555B2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift */; };
F398555E2E37040D00E2D28D /* BRVipOrderRecordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398555D2E37040D00E2D28D /* BRVipOrderRecordViewController.swift */; };
F39855602E37046100E2D28D /* BRVipOrderRecordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398555F2E37046100E2D28D /* BRVipOrderRecordCell.swift */; };
F39855622E3705E700E2D28D /* BRConsumptionRecordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855612E3705E700E2D28D /* BRConsumptionRecordViewController.swift */; };
F39855642E37065200E2D28D /* BRConsumptionRecordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855632E37065200E2D28D /* BRConsumptionRecordCell.swift */; };
F39855662E37083100E2D28D /* BRRewardCoinsRecordViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855652E37083100E2D28D /* BRRewardCoinsRecordViewController.swift */; };
F39855682E37087500E2D28D /* BRRewardCoinsRecordCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855672E37087500E2D28D /* BRRewardCoinsRecordCell.swift */; };
F398556A2E3709C500E2D28D /* BRWalletHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855692E3709C500E2D28D /* BRWalletHeaderView.swift */; };
F398556C2E3717A500E2D28D /* BRWalletHeaderItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398556B2E3717A500E2D28D /* BRWalletHeaderItemView.swift */; };
F398556E2E3743FC00E2D28D /* BRLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398556D2E3743FC00E2D28D /* BRLoginView.swift */; };
F39855702E374BD800E2D28D /* BRLoginButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398556F2E374BD800E2D28D /* BRLoginButton.swift */; };
F39855722E3758F800E2D28D /* BRLoginManager+Apple.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855712E3758F800E2D28D /* BRLoginManager+Apple.swift */; };
F39855742E3759C600E2D28D /* BRThirdSignModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855732E3759C600E2D28D /* BRThirdSignModel.swift */; };
F39855762E375DA600E2D28D /* BRAppWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855752E375DA600E2D28D /* BRAppWebViewController.swift */; };
F39855782E375E7000E2D28D /* Dictionary+BRAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855772E375E6B00E2D28D /* Dictionary+BRAdd.swift */; };
F398557A2E3761DB00E2D28D /* BRWebViewController+Script.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855792E3761D300E2D28D /* BRWebViewController+Script.swift */; };
F398557C2E37635400E2D28D /* BRWebScriptModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398557B2E37635400E2D28D /* BRWebScriptModel.swift */; };
F398557E2E3766A300E2D28D /* BRStatAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398557D2E37669F00E2D28D /* BRStatAPI.swift */; };
F39855802E376B4900E2D28D /* SceneDelegate+Open.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398557F2E376B4500E2D28D /* SceneDelegate+Open.swift */; };
F39855822E376CB000E2D28D /* BROpenAppModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855812E376CB000E2D28D /* BROpenAppModel.swift */; };
F39855842E37705700E2D28D /* AppDelegate+Thirdparty.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855832E37704600E2D28D /* AppDelegate+Thirdparty.swift */; };
F39855862E37724800E2D28D /* AppDelegate+APNS.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855852E37724000E2D28D /* AppDelegate+APNS.swift */; };
F39855892E37732600E2D28D /* BRGuideViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855882E37732600E2D28D /* BRGuideViewController.swift */; };
F398558B2E37792700E2D28D /* Date+BRAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398558A2E37792200E2D28D /* Date+BRAdd.swift */; };
F398558E2E37857D00E2D28D /* FirebaseMessaging in Frameworks */ = {isa = PBXBuildFile; productRef = F398558D2E37857D00E2D28D /* FirebaseMessaging */; };
F39855902E37862200E2D28D /* BRSettingAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398558F2E37861D00E2D28D /* BRSettingAPI.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
@ -362,7 +391,35 @@
F398554D2E34699F00E2D28D /* BRVideoLockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoLockView.swift; sourceTree = "<group>"; }; F398554D2E34699F00E2D28D /* BRVideoLockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoLockView.swift; sourceTree = "<group>"; };
F398554F2E34782200E2D28D /* BRVideoUnlockModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoUnlockModel.swift; sourceTree = "<group>"; }; F398554F2E34782200E2D28D /* BRVideoUnlockModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoUnlockModel.swift; sourceTree = "<group>"; };
F39855512E347BDE00E2D28D /* BRVideoRechargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoRechargeView.swift; sourceTree = "<group>"; }; F39855512E347BDE00E2D28D /* BRVideoRechargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoRechargeView.swift; sourceTree = "<group>"; };
F39855532E34A49500E2D28D /* VPPayDataRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPayDataRequest.swift; sourceTree = "<group>"; }; F39855532E34A49500E2D28D /* BRPayDataRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPayDataRequest.swift; sourceTree = "<group>"; };
F39855552E34BD6000E2D28D /* BRWalletViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWalletViewController.swift; sourceTree = "<group>"; };
F39855572E34CA2C00E2D28D /* BROrderRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BROrderRecordViewController.swift; sourceTree = "<group>"; };
F39855592E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRCoinOrderRecordViewController.swift; sourceTree = "<group>"; };
F398555B2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRCoinOrderRecordCell.swift; sourceTree = "<group>"; };
F398555D2E37040D00E2D28D /* BRVipOrderRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVipOrderRecordViewController.swift; sourceTree = "<group>"; };
F398555F2E37046100E2D28D /* BRVipOrderRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVipOrderRecordCell.swift; sourceTree = "<group>"; };
F39855612E3705E700E2D28D /* BRConsumptionRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRConsumptionRecordViewController.swift; sourceTree = "<group>"; };
F39855632E37065200E2D28D /* BRConsumptionRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRConsumptionRecordCell.swift; sourceTree = "<group>"; };
F39855652E37083100E2D28D /* BRRewardCoinsRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRRewardCoinsRecordViewController.swift; sourceTree = "<group>"; };
F39855672E37087500E2D28D /* BRRewardCoinsRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRRewardCoinsRecordCell.swift; sourceTree = "<group>"; };
F39855692E3709C500E2D28D /* BRWalletHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWalletHeaderView.swift; sourceTree = "<group>"; };
F398556B2E3717A500E2D28D /* BRWalletHeaderItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWalletHeaderItemView.swift; sourceTree = "<group>"; };
F398556D2E3743FC00E2D28D /* BRLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRLoginView.swift; sourceTree = "<group>"; };
F398556F2E374BD800E2D28D /* BRLoginButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRLoginButton.swift; sourceTree = "<group>"; };
F39855712E3758F800E2D28D /* BRLoginManager+Apple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BRLoginManager+Apple.swift"; sourceTree = "<group>"; };
F39855732E3759C600E2D28D /* BRThirdSignModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRThirdSignModel.swift; sourceTree = "<group>"; };
F39855752E375DA600E2D28D /* BRAppWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAppWebViewController.swift; sourceTree = "<group>"; };
F39855772E375E6B00E2D28D /* Dictionary+BRAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+BRAdd.swift"; sourceTree = "<group>"; };
F39855792E3761D300E2D28D /* BRWebViewController+Script.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BRWebViewController+Script.swift"; sourceTree = "<group>"; };
F398557B2E37635400E2D28D /* BRWebScriptModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWebScriptModel.swift; sourceTree = "<group>"; };
F398557D2E37669F00E2D28D /* BRStatAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRStatAPI.swift; sourceTree = "<group>"; };
F398557F2E376B4500E2D28D /* SceneDelegate+Open.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SceneDelegate+Open.swift"; sourceTree = "<group>"; };
F39855812E376CB000E2D28D /* BROpenAppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BROpenAppModel.swift; sourceTree = "<group>"; };
F39855832E37704600E2D28D /* AppDelegate+Thirdparty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Thirdparty.swift"; sourceTree = "<group>"; };
F39855852E37724000E2D28D /* AppDelegate+APNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+APNS.swift"; sourceTree = "<group>"; };
F39855882E37732600E2D28D /* BRGuideViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRGuideViewController.swift; sourceTree = "<group>"; };
F398558A2E37792200E2D28D /* Date+BRAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+BRAdd.swift"; sourceTree = "<group>"; };
F398558F2E37861D00E2D28D /* BRSettingAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRSettingAPI.swift; sourceTree = "<group>"; };
F70FA1F4169364C4C53534CE /* Pods-BeeReel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BeeReel.release.xcconfig"; path = "Target Support Files/Pods-BeeReel/Pods-BeeReel.release.xcconfig"; sourceTree = "<group>"; }; F70FA1F4169364C4C53534CE /* Pods-BeeReel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BeeReel.release.xcconfig"; path = "Target Support Files/Pods-BeeReel/Pods-BeeReel.release.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@ -371,6 +428,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
F398558E2E37857D00E2D28D /* FirebaseMessaging in Frameworks */,
440A41A6E6A22A02807AE759 /* Pods_BeeReel.framework in Frameworks */, 440A41A6E6A22A02807AE759 /* Pods_BeeReel.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -475,6 +533,9 @@
children = ( children = (
BF02B81D2E2F99D900172177 /* BRWebView.swift */, BF02B81D2E2F99D900172177 /* BRWebView.swift */,
BF02B81F2E2F9B1000172177 /* BRWebViewController.swift */, BF02B81F2E2F9B1000172177 /* BRWebViewController.swift */,
F39855752E375DA600E2D28D /* BRAppWebViewController.swift */,
F39855792E3761D300E2D28D /* BRWebViewController+Script.swift */,
F398557B2E37635400E2D28D /* BRWebScriptModel.swift */,
); );
path = WebView; path = WebView;
sourceTree = "<group>"; sourceTree = "<group>";
@ -611,6 +672,9 @@
children = ( children = (
BF692AE12E0A475D00A5C2DA /* AppDelegate.swift */, BF692AE12E0A475D00A5C2DA /* AppDelegate.swift */,
BF692AE82E0A475D00A5C2DA /* SceneDelegate.swift */, BF692AE82E0A475D00A5C2DA /* SceneDelegate.swift */,
F39855832E37704600E2D28D /* AppDelegate+Thirdparty.swift */,
F39855852E37724000E2D28D /* AppDelegate+APNS.swift */,
F398557F2E376B4500E2D28D /* SceneDelegate+Open.swift */,
BF692B662E0BC6BC00A5C2DA /* AppDelegate+BRConfig.swift */, BF692B662E0BC6BC00A5C2DA /* AppDelegate+BRConfig.swift */,
); );
path = Delegate; path = Delegate;
@ -640,6 +704,7 @@
BF3338ED2E15566C00B10F76 /* Explore */, BF3338ED2E15566C00B10F76 /* Explore */,
BF692B682E0BC78C00A5C2DA /* Home */, BF692B682E0BC78C00A5C2DA /* Home */,
BF692B4A2E0AA84C00A5C2DA /* Player */, BF692B4A2E0AA84C00A5C2DA /* Player */,
F39855872E3772F600E2D28D /* Guide */,
); );
path = Class; path = Class;
sourceTree = "<group>"; sourceTree = "<group>";
@ -691,8 +756,12 @@
BF692B022E0A769C00A5C2DA /* Login */ = { BF692B022E0A769C00A5C2DA /* Login */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F398556D2E3743FC00E2D28D /* BRLoginView.swift */,
F398556F2E374BD800E2D28D /* BRLoginButton.swift */,
BF692B032E0A76D200A5C2DA /* BRLoginManager.swift */, BF692B032E0A76D200A5C2DA /* BRLoginManager.swift */,
F39855712E3758F800E2D28D /* BRLoginManager+Apple.swift */,
BF692B082E0A775500A5C2DA /* BRLoginToken.swift */, BF692B082E0A775500A5C2DA /* BRLoginToken.swift */,
F39855732E3759C600E2D28D /* BRThirdSignModel.swift */,
); );
path = Login; path = Login;
sourceTree = "<group>"; sourceTree = "<group>";
@ -702,6 +771,7 @@
children = ( children = (
BF692B062E0A771C00A5C2DA /* BRModel.swift */, BF692B062E0A771C00A5C2DA /* BRModel.swift */,
BF692B742E0D39D000A5C2DA /* BRListModel.swift */, BF692B742E0D39D000A5C2DA /* BRListModel.swift */,
F39855812E376CB000E2D28D /* BROpenAppModel.swift */,
); );
path = Model; path = Model;
sourceTree = "<group>"; sourceTree = "<group>";
@ -709,6 +779,8 @@
BF692B0C2E0A7A9A00A5C2DA /* Extension */ = { BF692B0C2E0A7A9A00A5C2DA /* Extension */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F398558A2E37792200E2D28D /* Date+BRAdd.swift */,
F39855772E375E6B00E2D28D /* Dictionary+BRAdd.swift */,
BF3338FA2E161CF000B10F76 /* NSNumber+BRAdd.swift */, BF3338FA2E161CF000B10F76 /* NSNumber+BRAdd.swift */,
BF3338E72E15218F00B10F76 /* UINavigationBar+BRAdd.swift */, BF3338E72E15218F00B10F76 /* UINavigationBar+BRAdd.swift */,
BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */, BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */,
@ -934,6 +1006,8 @@
BF692B712E0D395300A5C2DA /* API */ = { BF692B712E0D395300A5C2DA /* API */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F398558F2E37861D00E2D28D /* BRSettingAPI.swift */,
F398557D2E37669F00E2D28D /* BRStatAPI.swift */,
F398553A2E336C4F00E2D28D /* BRStoreAPI.swift */, F398553A2E336C4F00E2D28D /* BRStoreAPI.swift */,
BFC676882E122FDB006659E5 /* BRVideoAPI.swift */, BFC676882E122FDB006659E5 /* BRVideoAPI.swift */,
BFC676682E0E34D9006659E5 /* BRUserAPI.swift */, BFC676682E0E34D9006659E5 /* BRUserAPI.swift */,
@ -1063,6 +1137,12 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F39855362E33699900E2D28D /* BRStoreViewController.swift */, F39855362E33699900E2D28D /* BRStoreViewController.swift */,
F39855552E34BD6000E2D28D /* BRWalletViewController.swift */,
F39855572E34CA2C00E2D28D /* BROrderRecordViewController.swift */,
F39855592E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift */,
F398555D2E37040D00E2D28D /* BRVipOrderRecordViewController.swift */,
F39855612E3705E700E2D28D /* BRConsumptionRecordViewController.swift */,
F39855652E37083100E2D28D /* BRRewardCoinsRecordViewController.swift */,
); );
path = Controller; path = Controller;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1076,6 +1156,12 @@
F39855492E33929C00E2D28D /* BRStoreCoinCell.swift */, F39855492E33929C00E2D28D /* BRStoreCoinCell.swift */,
F39855472E33928400E2D28D /* BRStoreCoinBigCell.swift */, F39855472E33928400E2D28D /* BRStoreCoinBigCell.swift */,
F398554B2E3392C200E2D28D /* BRStoreCoinSmallCell.swift */, F398554B2E3392C200E2D28D /* BRStoreCoinSmallCell.swift */,
F398555B2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift */,
F398555F2E37046100E2D28D /* BRVipOrderRecordCell.swift */,
F39855632E37065200E2D28D /* BRConsumptionRecordCell.swift */,
F39855672E37087500E2D28D /* BRRewardCoinsRecordCell.swift */,
F39855692E3709C500E2D28D /* BRWalletHeaderView.swift */,
F398556B2E3717A500E2D28D /* BRWalletHeaderItemView.swift */,
); );
path = View; path = View;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1084,11 +1170,19 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
F398553D2E336D3000E2D28D /* BRPayDateModel.swift */, F398553D2E336D3000E2D28D /* BRPayDateModel.swift */,
F39855532E34A49500E2D28D /* VPPayDataRequest.swift */, F39855532E34A49500E2D28D /* BRPayDataRequest.swift */,
); );
path = Model; path = Model;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
F39855872E3772F600E2D28D /* Guide */ = {
isa = PBXGroup;
children = (
F39855882E37732600E2D28D /* BRGuideViewController.swift */,
);
path = Guide;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -1135,6 +1229,9 @@
); );
mainGroup = BF692AC02E0A475500A5C2DA; mainGroup = BF692AC02E0A475500A5C2DA;
minimizedProjectReferenceProxies = 1; minimizedProjectReferenceProxies = 1;
packageReferences = (
F398558C2E37857D00E2D28D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
);
preferredProjectObjectVersion = 77; preferredProjectObjectVersion = 77;
productRefGroup = BF692ACA2E0A475500A5C2DA /* Products */; productRefGroup = BF692ACA2E0A475500A5C2DA /* Products */;
projectDirPath = ""; projectDirPath = "";
@ -1218,23 +1315,27 @@
F39855332E33629000E2D28D /* BRMineStoreItemView.swift in Sources */, F39855332E33629000E2D28D /* BRMineStoreItemView.swift in Sources */,
BFC676B12E137D2F006659E5 /* BRPopularPicksViewController.swift in Sources */, BFC676B12E137D2F006659E5 /* BRPopularPicksViewController.swift in Sources */,
BF02B7FC2E2F262F00172177 /* BRGradientView.swift in Sources */, BF02B7FC2E2F262F00172177 /* BRGradientView.swift in Sources */,
F398557A2E3761DB00E2D28D /* BRWebViewController+Script.swift in Sources */,
BFC676692E0E34DA006659E5 /* BRUserAPI.swift in Sources */, BFC676692E0E34DA006659E5 /* BRUserAPI.swift in Sources */,
F398554E2E34699F00E2D28D /* BRVideoLockView.swift in Sources */, F398554E2E34699F00E2D28D /* BRVideoLockView.swift in Sources */,
F39855642E37065200E2D28D /* BRConsumptionRecordCell.swift in Sources */,
BFC676782E0E9553006659E5 /* BRSpotlightMainBaseCell.swift in Sources */, BFC676782E0E9553006659E5 /* BRSpotlightMainBaseCell.swift in Sources */,
BFC676732E0E938B006659E5 /* BRTableView.swift in Sources */, BFC676732E0E938B006659E5 /* BRTableView.swift in Sources */,
BFC676932E126A62006659E5 /* BRSpotlightNewMainCell.swift in Sources */, BFC676932E126A62006659E5 /* BRSpotlightNewMainCell.swift in Sources */,
BFC6768D2E123D6E006659E5 /* AttributedString+BRAdd.swift in Sources */, BFC6768D2E123D6E006659E5 /* AttributedString+BRAdd.swift in Sources */,
BF02B8392E30B30400172177 /* AlignedCollectionViewFlowLayout.swift in Sources */, BF02B8392E30B30400172177 /* AlignedCollectionViewFlowLayout.swift in Sources */,
BF3A56882E30E0DD009E5CF9 /* BREmpty.swift in Sources */, BF3A56882E30E0DD009E5CF9 /* BREmpty.swift in Sources */,
F39855542E34A49500E2D28D /* VPPayDataRequest.swift in Sources */, F39855542E34A49500E2D28D /* BRPayDataRequest.swift in Sources */,
BF3338F52E1616B200B10F76 /* BRExploreControlView.swift in Sources */, BF3338F52E1616B200B10F76 /* BRExploreControlView.swift in Sources */,
F398552D2E33126D00E2D28D /* BRMineCoinItemView.swift in Sources */, F398552D2E33126D00E2D28D /* BRMineCoinItemView.swift in Sources */,
BF692B132E0A7B9000A5C2DA /* BRUserInfo.swift in Sources */, BF692B132E0A7B9000A5C2DA /* BRUserInfo.swift in Sources */,
BF692B042E0A76D200A5C2DA /* BRLoginManager.swift in Sources */, BF692B042E0A76D200A5C2DA /* BRLoginManager.swift in Sources */,
BFC6769D2E129794006659E5 /* BRHomeTop10ViewController.swift in Sources */, BFC6769D2E129794006659E5 /* BRHomeTop10ViewController.swift in Sources */,
F398556C2E3717A500E2D28D /* BRWalletHeaderItemView.swift in Sources */,
BF02B80D2E2F63ED00172177 /* BRFavoritesCell.swift in Sources */, BF02B80D2E2F63ED00172177 /* BRFavoritesCell.swift in Sources */,
BF692AEB2E0A475D00A5C2DA /* AppDelegate.swift in Sources */, BF692AEB2E0A475D00A5C2DA /* AppDelegate.swift in Sources */,
F39855372E33699900E2D28D /* BRStoreViewController.swift in Sources */, F39855372E33699900E2D28D /* BRStoreViewController.swift in Sources */,
F39855622E3705E700E2D28D /* BRConsumptionRecordViewController.swift in Sources */,
BF02B81B2E2F8FDF00172177 /* BRMineUserInfoCell.swift in Sources */, BF02B81B2E2F8FDF00172177 /* BRMineUserInfoCell.swift in Sources */,
F398554C2E3392C200E2D28D /* BRStoreCoinSmallCell.swift in Sources */, F398554C2E3392C200E2D28D /* BRStoreCoinSmallCell.swift in Sources */,
BF02B8202E2F9B1000172177 /* BRWebViewController.swift in Sources */, BF02B8202E2F9B1000172177 /* BRWebViewController.swift in Sources */,
@ -1249,23 +1350,29 @@
F39855292E322B1800E2D28D /* BRAlertWindowManager.swift in Sources */, F39855292E322B1800E2D28D /* BRAlertWindowManager.swift in Sources */,
BF02B82D2E30855300172177 /* BRSearchTextView.swift in Sources */, BF02B82D2E30855300172177 /* BRSearchTextView.swift in Sources */,
F398552B2E322C7C00E2D28D /* BRAlert.swift in Sources */, F398552B2E322C7C00E2D28D /* BRAlert.swift in Sources */,
F39855742E3759C600E2D28D /* BRThirdSignModel.swift in Sources */,
BF692B472E0A9B7900A5C2DA /* BRPlayer.swift in Sources */, BF692B472E0A9B7900A5C2DA /* BRPlayer.swift in Sources */,
BF692B6E2E0BD4CB00A5C2DA /* BRHomeHeaderView.swift in Sources */, BF692B6E2E0BD4CB00A5C2DA /* BRHomeHeaderView.swift in Sources */,
BF692AFA2E0A6F0900A5C2DA /* BRNetwork.swift in Sources */, BF692AFA2E0A6F0900A5C2DA /* BRNetwork.swift in Sources */,
BF02B7E52E2E1E6100172177 /* BREpisodeSelectorView.swift in Sources */, BF02B7E52E2E1E6100172177 /* BREpisodeSelectorView.swift in Sources */,
F39855662E37083100E2D28D /* BRRewardCoinsRecordViewController.swift in Sources */,
BF692B6B2E0BC85300A5C2DA /* BRHomeViewController.swift in Sources */, BF692B6B2E0BC85300A5C2DA /* BRHomeViewController.swift in Sources */,
BF692B7C2E0D3C1300A5C2DA /* BRVideoInfoModel.swift in Sources */, BF692B7C2E0D3C1300A5C2DA /* BRVideoInfoModel.swift in Sources */,
F39855702E374BD800E2D28D /* BRLoginButton.swift in Sources */,
BFC6766D2E0E3A8D006659E5 /* BRImageView.swift in Sources */, BFC6766D2E0E3A8D006659E5 /* BRImageView.swift in Sources */,
BF02B7ED2E2E390500172177 /* BRScrollView.swift in Sources */, BF02B7ED2E2E390500172177 /* BRScrollView.swift in Sources */,
F39855562E34BD6000E2D28D /* BRWalletViewController.swift in Sources */,
BF3A56812E30C08F009E5CF9 /* BRHotSearchTagCell.swift in Sources */, BF3A56812E30C08F009E5CF9 /* BRHotSearchTagCell.swift in Sources */,
BF02B8132E2F83C200172177 /* BRMineViewController.swift in Sources */, BF02B8132E2F83C200172177 /* BRMineViewController.swift in Sources */,
BF02B8222E2FAB1600172177 /* BRAboutUsViewController.swift in Sources */, BF02B8222E2FAB1600172177 /* BRAboutUsViewController.swift in Sources */,
BFC6766F2E0E3B5C006659E5 /* UIImageView+BRAdd.swift in Sources */, BFC6766F2E0E3B5C006659E5 /* UIImageView+BRAdd.swift in Sources */,
BF692B782E0D3A1200A5C2DA /* BRHomeModuleItem.swift in Sources */, BF692B782E0D3A1200A5C2DA /* BRHomeModuleItem.swift in Sources */,
BF692B5A2E0AAADD00A5C2DA /* BRPlayerListCell.swift in Sources */, BF692B5A2E0AAADD00A5C2DA /* BRPlayerListCell.swift in Sources */,
F398555C2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift in Sources */,
BF02B8312E30897700172177 /* BRSearchHomeView.swift in Sources */, BF02B8312E30897700172177 /* BRSearchHomeView.swift in Sources */,
F39855502E34782200E2D28D /* BRVideoUnlockModel.swift in Sources */, F39855502E34782200E2D28D /* BRVideoUnlockModel.swift in Sources */,
F398554A2E33929C00E2D28D /* BRStoreCoinCell.swift in Sources */, F398554A2E33929C00E2D28D /* BRStoreCoinCell.swift in Sources */,
F39855842E37705700E2D28D /* AppDelegate+Thirdparty.swift in Sources */,
BF3A568C2E30EBA2009E5CF9 /* BRHomePlayRecordButton.swift in Sources */, BF3A568C2E30EBA2009E5CF9 /* BRHomePlayRecordButton.swift in Sources */,
BF692B162E0A7CD600A5C2DA /* BRHUD.swift in Sources */, BF692B162E0A7CD600A5C2DA /* BRHUD.swift in Sources */,
BF3338F72E16176900B10F76 /* BRDetailPlayerCell.swift in Sources */, BF3338F72E16176900B10F76 /* BRDetailPlayerCell.swift in Sources */,
@ -1279,14 +1386,17 @@
BFC676852E122D9E006659E5 /* BRVideoDetailViewController.swift in Sources */, BFC676852E122D9E006659E5 /* BRVideoDetailViewController.swift in Sources */,
BFC676912E126248006659E5 /* BRSpotlightTopCell.swift in Sources */, BFC676912E126248006659E5 /* BRSpotlightTopCell.swift in Sources */,
BFC676B72E137DFC006659E5 /* BRPopularPicksCell.swift in Sources */, BFC676B72E137DFC006659E5 /* BRPopularPicksCell.swift in Sources */,
F398556A2E3709C500E2D28D /* BRWalletHeaderView.swift in Sources */,
BF692B422E0A8FB500A5C2DA /* UIFont+BRAdd.swift in Sources */, BF692B422E0A8FB500A5C2DA /* UIFont+BRAdd.swift in Sources */,
BF02B8362E30ACEE00172177 /* BRSearchViewModel.swift in Sources */, BF02B8362E30ACEE00172177 /* BRSearchViewModel.swift in Sources */,
F39855762E375DA600E2D28D /* BRAppWebViewController.swift in Sources */,
BF692AEC2E0A475D00A5C2DA /* SceneDelegate.swift in Sources */, BF692AEC2E0A475D00A5C2DA /* SceneDelegate.swift in Sources */,
BF692B492E0A9D0E00A5C2DA /* UIView+BRAdd.swift in Sources */, BF692B492E0A9D0E00A5C2DA /* UIView+BRAdd.swift in Sources */,
BF02B7F82E2F211A00172177 /* BRHomeCategoriesMainCell.swift in Sources */, BF02B7F82E2F211A00172177 /* BRHomeCategoriesMainCell.swift in Sources */,
BF02B8192E2F8B1100172177 /* BRMineCell.swift in Sources */, BF02B8192E2F8B1100172177 /* BRMineCell.swift in Sources */,
BFC676812E122733006659E5 /* BRPlayerProtocol.swift in Sources */, BFC676812E122733006659E5 /* BRPlayerProtocol.swift in Sources */,
BFC676BC2E138ABB006659E5 /* BRNewReleasesViewController.swift in Sources */, BFC676BC2E138ABB006659E5 /* BRNewReleasesViewController.swift in Sources */,
F39855602E37046100E2D28D /* BRVipOrderRecordCell.swift in Sources */,
BF692B5F2E0B812800A5C2DA /* BRTabBarItemContainer.swift in Sources */, BF692B5F2E0B812800A5C2DA /* BRTabBarItemContainer.swift in Sources */,
BF3338EC2E154BFE00B10F76 /* BRPlayerControlView.swift in Sources */, BF3338EC2E154BFE00B10F76 /* BRPlayerControlView.swift in Sources */,
BF692B652E0BC53900A5C2DA /* CGMutablePath+BRRoundedCorner.swift in Sources */, BF692B652E0BC53900A5C2DA /* CGMutablePath+BRRoundedCorner.swift in Sources */,
@ -1302,12 +1412,17 @@
F39855312E33620200E2D28D /* BRMineStoreCell.swift in Sources */, F39855312E33620200E2D28D /* BRMineStoreCell.swift in Sources */,
BF692B182E0A7D8900A5C2DA /* BRToast.swift in Sources */, BF692B182E0A7D8900A5C2DA /* BRToast.swift in Sources */,
BF692B0E2E0A7AF300A5C2DA /* UserDefaults+BRAdd.swift in Sources */, BF692B0E2E0A7AF300A5C2DA /* UserDefaults+BRAdd.swift in Sources */,
F39855682E37087500E2D28D /* BRRewardCoinsRecordCell.swift in Sources */,
F398555A2E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift in Sources */,
F39855522E347BDE00E2D28D /* BRVideoRechargeView.swift in Sources */, F39855522E347BDE00E2D28D /* BRVideoRechargeView.swift in Sources */,
BF02B8082E2F616E00172177 /* BRFavoritesViewController.swift in Sources */, BF02B8082E2F616E00172177 /* BRFavoritesViewController.swift in Sources */,
BF3338FD2E1626B000B10F76 /* BRPlayerControlProtocol.swift in Sources */, BF3338FD2E1626B000B10F76 /* BRPlayerControlProtocol.swift in Sources */,
BF692B582E0AAA6F00A5C2DA /* UIScreen+BRAdd.swift in Sources */, BF692B582E0AAA6F00A5C2DA /* UIScreen+BRAdd.swift in Sources */,
F398555E2E37040D00E2D28D /* BRVipOrderRecordViewController.swift in Sources */,
BF692B1F2E0A804600A5C2DA /* BRLocalizedManager.swift in Sources */, BF692B1F2E0A804600A5C2DA /* BRLocalizedManager.swift in Sources */,
F39855862E37724800E2D28D /* AppDelegate+APNS.swift in Sources */,
F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */, F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */,
F398557C2E37635400E2D28D /* BRWebScriptModel.swift in Sources */,
BF02B7E92E2E29E900172177 /* BREpisodeSelectorCell.swift in Sources */, BF02B7E92E2E29E900172177 /* BREpisodeSelectorCell.swift in Sources */,
F39855462E338FDA00E2D28D /* BRStoreCoinView.swift in Sources */, F39855462E338FDA00E2D28D /* BRStoreCoinView.swift in Sources */,
F398553B2E336C5700E2D28D /* BRStoreAPI.swift in Sources */, F398553B2E336C5700E2D28D /* BRStoreAPI.swift in Sources */,
@ -1318,10 +1433,14 @@
BF692B012E0A74A200A5C2DA /* BRDefine.swift in Sources */, BF692B012E0A74A200A5C2DA /* BRDefine.swift in Sources */,
BFC6767B2E0E973B006659E5 /* UIStackView+BRAdd.swift in Sources */, BFC6767B2E0E973B006659E5 /* UIStackView+BRAdd.swift in Sources */,
BF3338F32E16169A00B10F76 /* BRExplorePlayerCell.swift in Sources */, BF3338F32E16169A00B10F76 /* BRExplorePlayerCell.swift in Sources */,
F398556E2E3743FC00E2D28D /* BRLoginView.swift in Sources */,
F398558B2E37792700E2D28D /* Date+BRAdd.swift in Sources */,
BF3338F92E16178700B10F76 /* BRDetailControlView.swift in Sources */, BF3338F92E16178700B10F76 /* BRDetailControlView.swift in Sources */,
BFC676AB2E1372BD006659E5 /* BRHomeTop3Cell.swift in Sources */, BFC676AB2E1372BD006659E5 /* BRHomeTop3Cell.swift in Sources */,
BFC676892E122FDD006659E5 /* BRVideoAPI.swift in Sources */, BFC676892E122FDD006659E5 /* BRVideoAPI.swift in Sources */,
BFC6769B2E1285C5006659E5 /* BRPagerViewTransformer.swift in Sources */, BFC6769B2E1285C5006659E5 /* BRPagerViewTransformer.swift in Sources */,
F39855892E37732600E2D28D /* BRGuideViewController.swift in Sources */,
F39855782E375E7000E2D28D /* Dictionary+BRAdd.swift in Sources */,
BFC676832E122CC5006659E5 /* BRPlayerViewModel.swift in Sources */, BFC676832E122CC5006659E5 /* BRPlayerViewModel.swift in Sources */,
BF02B7EF2E2E4BFD00172177 /* BRRateModel.swift in Sources */, BF02B7EF2E2E4BFD00172177 /* BRRateModel.swift in Sources */,
BF692B672E0BC6C700A5C2DA /* AppDelegate+BRConfig.swift in Sources */, BF692B672E0BC6C700A5C2DA /* AppDelegate+BRConfig.swift in Sources */,
@ -1341,9 +1460,11 @@
BFC676642E0E2C8E006659E5 /* WMZBannerFlowLayout.m in Sources */, BFC676642E0E2C8E006659E5 /* WMZBannerFlowLayout.m in Sources */,
BF02B81E2E2F99D900172177 /* BRWebView.swift in Sources */, BF02B81E2E2F99D900172177 /* BRWebView.swift in Sources */,
BFC676652E0E2C8E006659E5 /* WMZBannerControl.m in Sources */, BFC676652E0E2C8E006659E5 /* WMZBannerControl.m in Sources */,
F39855722E3758F800E2D28D /* BRLoginManager+Apple.swift in Sources */,
BFC676972E127D3C006659E5 /* BRSpotlightRecommandMainCell.swift in Sources */, BFC676972E127D3C006659E5 /* BRSpotlightRecommandMainCell.swift in Sources */,
BFC6767F2E121A72006659E5 /* BRSpotlightHotCell.swift in Sources */, BFC6767F2E121A72006659E5 /* BRSpotlightHotCell.swift in Sources */,
BFC6767D2E0E9809006659E5 /* BRSpotlightHotMainCell.swift in Sources */, BFC6767D2E0E9809006659E5 /* BRSpotlightHotMainCell.swift in Sources */,
F39855802E376B4900E2D28D /* SceneDelegate+Open.swift in Sources */,
BF02B7EB2E2E388800172177 /* BREpisodeMenuView.swift in Sources */, BF02B7EB2E2E388800172177 /* BREpisodeMenuView.swift in Sources */,
BF02B8042E2F5B4B00172177 /* BRCategorieShortCell.swift in Sources */, BF02B8042E2F5B4B00172177 /* BRCategorieShortCell.swift in Sources */,
BFC676662E0E2C8E006659E5 /* WMZBannerFadeLayout.m in Sources */, BFC676662E0E2C8E006659E5 /* WMZBannerFadeLayout.m in Sources */,
@ -1352,6 +1473,7 @@
BFC676672E0E2C8E006659E5 /* WMZBannerParam.m in Sources */, BFC676672E0E2C8E006659E5 /* WMZBannerParam.m in Sources */,
BF692B732E0D397700A5C2DA /* BRHomeAPI.swift in Sources */, BF692B732E0D397700A5C2DA /* BRHomeAPI.swift in Sources */,
BF692B7A2E0D3BD300A5C2DA /* BRShortModel.swift in Sources */, BF692B7A2E0D3BD300A5C2DA /* BRShortModel.swift in Sources */,
F39855822E376CB000E2D28D /* BROpenAppModel.swift in Sources */,
BFC676712E0E9234006659E5 /* BRSpotlightViewViewController.swift in Sources */, BFC676712E0E9234006659E5 /* BRSpotlightViewViewController.swift in Sources */,
BF3338F02E15569600B10F76 /* BRExploreViewController.swift in Sources */, BF3338F02E15569600B10F76 /* BRExploreViewController.swift in Sources */,
BF0DBDD12E0D4E150035F6B4 /* BRTabBar.swift in Sources */, BF0DBDD12E0D4E150035F6B4 /* BRTabBar.swift in Sources */,
@ -1363,17 +1485,20 @@
BF692B752E0D39D000A5C2DA /* BRListModel.swift in Sources */, BF692B752E0D39D000A5C2DA /* BRListModel.swift in Sources */,
BF02B8172E2F881200172177 /* BRMineItem.swift in Sources */, BF02B8172E2F881200172177 /* BRMineItem.swift in Sources */,
BFC676B92E1385FC006659E5 /* BRPopularPicksSmallCell.swift in Sources */, BFC676B92E1385FC006659E5 /* BRPopularPicksSmallCell.swift in Sources */,
F39855582E34CA2C00E2D28D /* BROrderRecordViewController.swift in Sources */,
BF692B512E0AA8C600A5C2DA /* BRPlayerListViewController.swift in Sources */, BF692B512E0AA8C600A5C2DA /* BRPlayerListViewController.swift in Sources */,
BF02B8282E30821B00172177 /* BRSearchViewController.swift in Sources */, BF02B8282E30821B00172177 /* BRSearchViewController.swift in Sources */,
F39855422E3374B500E2D28D /* BRStoreVipCell.swift in Sources */, F39855422E3374B500E2D28D /* BRStoreVipCell.swift in Sources */,
BFC676522E0D4EFD006659E5 /* BRHomeViewModel.swift in Sources */, BFC676522E0D4EFD006659E5 /* BRHomeViewModel.swift in Sources */,
BFC676A72E12AF04006659E5 /* WaterfallMutiSectionFlowLayout.swift in Sources */, BFC676A72E12AF04006659E5 /* WaterfallMutiSectionFlowLayout.swift in Sources */,
F398552F2E33179800E2D28D /* BRMineVipCell.swift in Sources */, F398552F2E33179800E2D28D /* BRMineVipCell.swift in Sources */,
F39855902E37862200E2D28D /* BRSettingAPI.swift in Sources */,
BF692B2A2E0A84F700A5C2DA /* JXUUID.m in Sources */, BF692B2A2E0A84F700A5C2DA /* JXUUID.m in Sources */,
BF692B2B2E0A84F700A5C2DA /* PDKeyChain.m in Sources */, BF692B2B2E0A84F700A5C2DA /* PDKeyChain.m in Sources */,
BF3A56852E30CA78009E5CF9 /* BRSearchResultCell.swift in Sources */, BF3A56852E30CA78009E5CF9 /* BRSearchResultCell.swift in Sources */,
BF02B7FA2E2F225D00172177 /* BRHomeCategoryModel.swift in Sources */, BF02B7FA2E2F225D00172177 /* BRHomeCategoryModel.swift in Sources */,
BFC6766B2E0E395F006659E5 /* BRHomeHeaderBannerCell.swift in Sources */, BFC6766B2E0E395F006659E5 /* BRHomeHeaderBannerCell.swift in Sources */,
F398557E2E3766A300E2D28D /* BRStatAPI.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@ -1405,6 +1530,9 @@
INFOPLIST_FILE = BeeReel/Sources/Info.plist; INFOPLIST_FILE = BeeReel/Sources/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = BeeReel; INFOPLIST_KEY_CFBundleDisplayName = BeeReel;
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience.";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = ""; INFOPLIST_KEY_UIMainStoryboardFile = "";
@ -1441,6 +1569,9 @@
INFOPLIST_FILE = BeeReel/Sources/Info.plist; INFOPLIST_FILE = BeeReel/Sources/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = BeeReel; INFOPLIST_KEY_CFBundleDisplayName = BeeReel;
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
INFOPLIST_KEY_NSCameraUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSPhotoLibraryUsageDescription = "The APP needs to access your album to provide screenshots for feedback.";
INFOPLIST_KEY_NSUserTrackingUsageDescription = "We will use your advertising identifier (IDFA) to provide a personalized advertising experience.";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = ""; INFOPLIST_KEY_UIMainStoryboardFile = "";
@ -1608,6 +1739,25 @@
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
F398558C2E37857D00E2D28D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/firebase/firebase-ios-sdk";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 12.0.0;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
F398558D2E37857D00E2D28D /* FirebaseMessaging */ = {
isa = XCSwiftPackageProductDependency;
package = F398558C2E37857D00E2D28D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */;
productName = FirebaseMessaging;
};
/* End XCSwiftPackageProductDependency section */
}; };
rootObject = BF692AC12E0A475500A5C2DA /* Project object */; rootObject = BF692AC12E0A475500A5C2DA /* Project object */;
} }

View File

@ -53,6 +53,11 @@ class BRTabBarController: UITabBarController {
br_setup() br_setup()
///idfa
BRAppTool.requestIDFAAuthorization { idfa in
}
} }

View File

@ -15,3 +15,7 @@ let kBRLoginUserInfoDefaultsKey = "kBRLoginUserInfoDefaultsKey"
/// ///
let kBRVideoRevolutionDefaultsKey = "kBRVideoRevolutionDefaultsKey" let kBRVideoRevolutionDefaultsKey = "kBRVideoRevolutionDefaultsKey"
///APP
let kBRHasBeenOpenedAPPDefaultsKey = "kBRHasBeenOpenedAPPDefaultsKey"
let kBRApnsAlertDefaultsKey = "kBRApnsAlertDefaultsKey"

View File

@ -0,0 +1,30 @@
//
// Date+BRAdd.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
extension Date {
///
func differenceDay(date: Date) -> Int {
let dateComponents = Calendar.current.dateComponents([.day], from: self, to: date)
return dateComponents.day ?? 0
}
func formatString(dateFormat: String) -> String {
let formatter = DateFormatter()
formatter.dateFormat = dateFormat
return formatter.string(from: self)
}
///
var br_isToday: Bool {
get {
return Calendar.current.isDateInToday(self)
}
}
}

View File

@ -0,0 +1,23 @@
//
// Dictionary+BRAdd.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
extension Dictionary {
func toJsonString() -> String? {
do {
let data = try JSONSerialization.data(withJSONObject: self)
let jsonStr = String(data: data, encoding: .utf8)
return jsonStr
} catch {
}
return nil
}
}

View File

@ -31,3 +31,22 @@ extension String {
} }
} }
extension String {
///url
func br_urlQuryToDictionary() -> [String : Any] {
let array = self.components(separatedBy: "&")
var tempDic: [String : Any] = [:]
array.forEach {
if let strRange = $0.range(of: "=") {
var key: String = String($0.prefix(upTo: strRange.upperBound))
key.removeLast()
var value: String = String($0.suffix(from: strRange.upperBound))
value = value.removingPercentEncoding ?? value
tempDic[key] = value
}
}
return tempDic
}
}

View File

@ -190,4 +190,20 @@ extension UIColor {
static func colorB5B5B5(alpha: CGFloat = 1) -> UIColor { static func colorB5B5B5(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xB5B5B5, alpha: alpha) return UIColor(rgb: 0xB5B5B5, alpha: alpha)
} }
static func colorF0F0F0(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xF0F0F0, alpha: alpha)
}
static func colorE8E8E8(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xE8E8E8, alpha: alpha)
}
static func colorFAFAFA(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xFAFAFA, alpha: alpha)
}
static func color7ECD5E(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x7ECD5E, alpha: alpha)
}
} }

View File

@ -0,0 +1,25 @@
//
// BROpenAppModel.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
import SmartCodable
class BROpenAppModel: BRModel, SmartCodable {
enum PathType: String, SmartCaseDefaultable {
case videoDetail = "detail"
///
case feedback = "feedback"
///
case promotion = "promotion"
}
var id: String?
var message_id: String?
var short_play_id: String?
var path: PathType?
}

View File

@ -0,0 +1,20 @@
//
// BRSettingAPI.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
class BRSettingAPI {
static func requestUploadApnsDeviceToken(token: String) {
var param = BRNetworkParameters(path: "/customer/firebaseToken")
param.parameters = ["fcm_token": token]
param.isToast = false
BRNetwork.request(parameters: param) { (response: BRNetworkResponse<String>) in
}
}
}

View File

@ -0,0 +1,94 @@
//
// BRStatAPI.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRStatAPI {
///APP
static func requestEnterApp() {
var param = BRNetworkParameters(path: "/customer/enterTheApp")
param.isToast = false
param.isLoding = false
BRNetwork.request(parameters: param) { (_: BRNetworkResponse<String>) in }
}
///APP
static func requestLeaveApp() {
var param = BRNetworkParameters(path: "/customer/leaveApp")
param.isToast = false
param.isLoding = false
BRNetwork.request(parameters: param) { (_: BRNetworkResponse<String>) in }
}
static func requestStatOnLine() {
var param = BRNetworkParameters(path: "/customer/onLine")
param.isToast = false
param.isLoding = false
BRNetwork.request(parameters: param) { (_: BRNetworkResponse<String>) in }
}
///w2a
static func requestStatW2a(data: String) {
var param = BRNetworkParameters(path: "/w2aSelfAttribution")
param.isToast = false
param.isLoding = false
param.parameters = [
"data" : data
]
BRNetwork.request(parameters: param) { (response: BRNetworkResponse<String>) in
}
}
///
static func requestStatApns(messageId: String, title: String) {
var param = BRNetworkParameters(path: "/message/sendReport")
param.isToast = false
param.isLoding = false
param.parameters = [
"message_id" : messageId,
"title" : title
]
BRNetwork.request(parameters: param) { (response: BRNetworkResponse<String>) in
}
}
///
static func requestUploadNoticeStatus(status: Bool) {
var param = BRNetworkParameters(path: "/customer/uploadNoticeStatus")
param.isLoding = false
param.isToast = false
param.parameters = [
"is_open_notice" : status ? 1 : 0
]
BRNetwork.request(parameters: param) { (response: BRNetworkResponse<String>) in
}
}
}
extension BRStatAPI {
///
static func uploadNoticeStatus() {
UNUserNotificationCenter.current().getNotificationSettings { settings in
if settings.authorizationStatus == .authorized {
BRStatAPI.requestUploadNoticeStatus(status: true)
} else if settings.authorizationStatus == .denied {
BRStatAPI.requestUploadNoticeStatus(status: false)
}
}
}
}

View File

@ -17,4 +17,15 @@ class BRUserAPI {
completer?(response.data) completer?(response.data)
} }
} }
///
static func requestThirdLogin(model: BRThirdSignModel, completer: ((_ token: BRLoginToken?) -> Void)?) {
var param = BRNetworkParameters(path: "/customer/login")
param.parameters = model.toDictionary()
BRNetwork.request(parameters: param) { (response: BRNetworkResponse<BRLoginToken>) in
completer?(response.data)
}
}
} }

View File

@ -69,7 +69,7 @@ extension BRNetworkTarget: TargetType {
let dic: [String : String] = [ let dic: [String : String] = [
"system-version" : kBROsVersion, "system-version" : kBROsVersion,
"lang-key" : BRLocalizedManager.manager.currentLocalizedKey,// "lang-key" : BRLocalizedManager.manager.currentLocalizedKey,//
"time-zone" : self.timeZone(), // "time-zone" : BRNetworkTarget.timeZone(), //
"app-version" : kBRAPPVersion, "app-version" : kBRAPPVersion,
"device-id" : JXUUID.uuid(), //id "device-id" : JXUUID.uuid(), //id
"brand" : "apple", // "brand" : "apple", //
@ -97,7 +97,7 @@ extension BRNetworkTarget {
} }
} }
func timeZone() -> String { static func timeZone() -> String {
let timeZone = NSTimeZone.local as NSTimeZone let timeZone = NSTimeZone.local as NSTimeZone
let timeZoneSecondsFromGMT = timeZone.secondsFromGMT / 3600 let timeZoneSecondsFromGMT = timeZone.secondsFromGMT / 3600
return String(format: "GMT+0%d:00", timeZoneSecondsFromGMT) return String(format: "GMT+0%d:00", timeZoneSecondsFromGMT)

View File

@ -30,13 +30,13 @@ let kSBCivizatioConventionWebUrl = BRWebBaseURL + "/civizatio_convention"
let kSBMemberShipAgreement = BRWebBaseURL + "/member_ship_agreement" let kSBMemberShipAgreement = BRWebBaseURL + "/member_ship_agreement"
/// ///
let kSBFeedBackHomeWebUrl = BRCampaignWebURL + "/pages/leave/index" let kBRFeedBackHomeWebUrl = BRCampaignWebURL + "/pages/leave/index"
/// ///
let kSBFeedBackListWebUrl = BRCampaignWebURL + "/pages/leave/list" let kBRFeedBackListWebUrl = BRCampaignWebURL + "/pages/leave/list"
/// ///
let kSBFeedBackDetailWebUrl = BRCampaignWebURL + "/pages/leave/detail" let kBRFeedBackDetailWebUrl = BRCampaignWebURL + "/pages/leave/detail"
/// ///
let kSBRewardsWebUrl = BRCampaignWebURL + "/pages/reward/theme4" let kBRRewardsWebUrl = BRCampaignWebURL + "/pages/reward/theme4"
/* /*

View File

@ -59,15 +59,15 @@ class BRPanModalContentView: HWPanModalContentView {
return config return config
} }
override func allowsDragToDismiss() -> Bool {
return false
}
/// ///
override func allowsTapBackgroundToDismiss() -> Bool { override func allowsTapBackgroundToDismiss() -> Bool {
return true return true
} }
override func allowsDragToDismiss() -> Bool {
return false
}
override func allowsPullDownWhenShortState() -> Bool { override func allowsPullDownWhenShortState() -> Bool {
return false return false
} }

View File

@ -0,0 +1,88 @@
//
// BRAppWebViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRAppWebViewController: BRWebViewController {
var id: String?
private var receiveDataCount = 0
var theme: String? = "theme_2"
override func viewDidLoad() {
super.viewDidLoad()
autoTitle = false
if webUrl == kBRFeedBackListWebUrl {
self.title = "Feedback History".localized
} else if webUrl == kBRFeedBackHomeWebUrl {
self.title = "Feedback".localized
} else if webUrl == kBRFeedBackDetailWebUrl {
self.title = "Feedback Details".localized
} else if webUrl == kBRRewardsWebUrl {
self.title = "Rewards".localized
}
self.webView.scrollView.br_addRefreshHeader { [weak self] in
self?.handleHeaderRefresh(nil)
}
}
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
self.reload()
self.webView.scrollView.br_endHeaderRefreshing()
}
override func br_webViewDidFinishLoad(_ webView: BRWebView) {
super.br_webViewDidFinishLoad(webView)
receiveDataCount = 0
receiveDataFromNative()
}
}
extension BRAppWebViewController {
///
func receiveDataFromNative() {
receiveDataCount += 1
if receiveDataCount > 10 { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
guard let self = self else { return }
var dic = [
"token" : BRLoginManager.manager.token?.token ?? "",
"time_zone" : BRNetworkTarget.timeZone(),
"lang" : BRLocalizedManager.manager.currentLocalizedKey,
"type" : "ios",
]
if let theme = theme {
dic["theme"] = theme
}
if let id = id {
dic["id"] = id
}
if let json = dic.toJsonString() {
let js = "receiveDataFromNative(\(json))"
self.webView.evaluateJavaScript(js) { [weak self] _, error in
guard let self = self else { return }
if error != nil {
self.receiveDataFromNative()
}
}
}
}
}
}

View File

@ -0,0 +1,25 @@
//
// BRWebScriptModel.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
import SmartCodable
class BRWebScriptModel: BRModel, SmartCodable {
var type: String?
var data: BRWebScriptData?
}
struct BRWebScriptData: SmartCodable {
var activity_id: String?
var short_play_id: String?
var link: String?
}

View File

@ -33,7 +33,12 @@ class BRWebView: WKWebView {
weak var delegate: BRWebViewDelegate? weak var delegate: BRWebViewDelegate?
private(set) var scriptMessageHandlerArray: [String] = [] private(set) var scriptMessageHandlerArray: [String] = [
kBRWebMessageAPP,
kBRWebMessageOpenFeedbackList,
kBRWebMessageOpenFeedbackDetail,
kBRWebMessageOpenPhotoPicker,
]
deinit { deinit {

View File

@ -0,0 +1,108 @@
//
// BRWebViewController+Script.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
import WebKit
import ZLPhotoBrowser
///APP
let kBRWebMessageAPP = "js2app"
///
let kBRWebMessageOpenFeedbackList = "openFeedbackList"
///
let kBRWebMessageOpenFeedbackDetail = "openFeedbackDetail"
///
let kBRWebMessageOpenPhotoPicker = "openPhotoPicker"
extension BRWebViewController {
func br_webViewUserContentController(didReceive message: WKScriptMessage) {
let name = message.name
let body = message.body
switch name {
case kBRWebMessageOpenFeedbackList:
let vc = BRAppWebViewController()
vc.webUrl = kBRFeedBackListWebUrl
self.navigationController?.pushViewController(vc, animated: true)
case kBRWebMessageOpenFeedbackDetail:
guard let body = body as? [String : Any] else { return }
guard let id = body["id"] as? Int else { return }
let vc = BRAppWebViewController()
vc.id = "\(id)"
vc.webUrl = kBRFeedBackDetailWebUrl
self.navigationController?.pushViewController(vc, animated: true)
case kBRWebMessageOpenPhotoPicker:
openPhotoPicker()
case kBRWebMessageAPP:
guard let body = message.body as? [String : Any] else { return }
guard let model = BRWebScriptModel.deserialize(from: body) else { return }
let type = model.type
let data = model.data
if type == "login" {
// VPLoginManager.manager.openLogin()
} else if type == "open_notify" {
// openNotify()
} else if type == "watch_video" {
let vc = BRVideoDetailViewController()
vc.shortPlayId = data?.short_play_id
vc.activityId = data?.activity_id
self.navigationController?.pushViewController(vc, animated: true)
} else {
guard let urlStr = data?.link else { return }
guard let url = URL(string: urlStr) else { return }
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
default:
break
}
}
}
extension BRWebViewController {
///
private func openPhotoPicker() {
ZLPhotoConfiguration.default().allowSelectOriginal = false
ZLPhotoConfiguration.default().maxSelectCount = 1
ZLPhotoConfiguration.default().allowEditImage = false
ZLPhotoConfiguration.default().allowSelectVideo = false
ZLPhotoConfiguration.default().allowSelectGif = false
ZLPhotoConfiguration.default().allowTakePhotoInLibrary = false
let picker = ZLPhotoPicker()
picker.selectImageBlock = { [weak self] (results, _) in
guard let self = self else { return }
guard let image = results.first?.image else { return }
guard let imageData = image.jpegData(compressionQuality: 0.8) else { return }
let imageDataStr = imageData.base64EncodedString(options: .endLineWithCarriageReturn)
let js = "uploadConvertImage('\(imageDataStr)')"
self.webView.evaluateJavaScript(js)
}
picker.showPhotoLibrary(sender: self)
}
}

View File

@ -109,6 +109,6 @@ extension BRWebViewController: BRWebViewDelegate {
} }
func br_userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { func br_userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
// vp_webViewUserContentController(didReceive: message) br_webViewUserContentController(didReceive: message)
} }
} }

View File

@ -0,0 +1,59 @@
//
// BRGuideViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRGuideViewController: BRViewController {
var clickStartButton: (() -> Void)?
private(set) lazy var lanuchVC: UIViewController? = {
let vc = BRAppTool.lanuchViewController
return vc
}()
private lazy var startButton: UIButton = {
let button = UIButton(type: .custom)
button.layer.cornerRadius = 24
button.layer.masksToBounds = true
button.layer.borderColor = UIColor.color1C1C1C().cgColor
button.layer.borderWidth = 1
button.setTitle("Get Started".localized, for: .normal)
button.setTitleColor(.color1C1C1C(), for: .normal)
button.titleLabel?.font = .fontMedium(ofSize: 15)
button.addTarget(self, action: #selector(handleStartButton), for: .touchUpInside)
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
if let vc = lanuchVC {
addChild(vc)
view.addSubview(vc.view)
}
view.addSubview(startButton)
startButton.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 100))
make.width.equalTo(180)
make.height.equalTo(48)
}
}
@objc private func handleStartButton() {
UserDefaults.standard.set(true, forKey: kBRHasBeenOpenedAPPDefaultsKey)
self.clickStartButton?()
}
}

View File

@ -22,8 +22,9 @@ class BRMineViewController: BRViewController {
BRMineItem(type: .store), BRMineItem(type: .store),
], ],
[ [
BRMineItem(type: .order, icon: UIImage(named: "Order Record"), title: "Order Record".localized, url: kSBPrivacyPolicyWebUrl),
BRMineItem(type: .web, icon: UIImage(named: "mine_item_icon_01"), title: "Privacy Policy".localized, url: kSBPrivacyPolicyWebUrl), BRMineItem(type: .web, icon: UIImage(named: "mine_item_icon_01"), title: "Privacy Policy".localized, url: kSBPrivacyPolicyWebUrl),
// BRMineItem(type: .helpCenter, icon: UIImage(named: "mine_item_icon_02"), title: "Help Center".localized, url: ""), BRMineItem(type: .helpCenter, icon: UIImage(named: "mine_item_icon_02"), title: "Help Center".localized, url: ""),
BRMineItem(type: .web, icon: UIImage(named: "mine_item_icon_03"), title: "User Agreement".localized, url: kSBUserAgreementWebUrl), BRMineItem(type: .web, icon: UIImage(named: "mine_item_icon_03"), title: "User Agreement".localized, url: kSBUserAgreementWebUrl),
BRMineItem(type: .aboutUs, icon: UIImage(named: "mine_item_icon_04"), title: "About Us".localized, url: ""), BRMineItem(type: .aboutUs, icon: UIImage(named: "mine_item_icon_04"), title: "About Us".localized, url: ""),
] ]
@ -149,6 +150,20 @@ extension BRMineViewController: UITableViewDelegate, UITableViewDataSource {
let vc = BRAboutUsViewController() let vc = BRAboutUsViewController()
self.navigationController?.pushViewController(vc, animated: true) self.navigationController?.pushViewController(vc, animated: true)
case .vip:
let vc = BRStoreViewController()
self.navigationController?.pushViewController(vc, animated: true)
case .order:
let vc = BRWalletViewController()
self.navigationController?.pushViewController(vc, animated: true)
case .helpCenter:
let vc = BRAppWebViewController()
vc.webUrl = kBRFeedBackHomeWebUrl
self.navigationController?.pushViewController(vc, animated: true)
default: default:
break break
} }

View File

@ -16,6 +16,7 @@ class BRMineItem: BRModel {
case aboutUs case aboutUs
case vip case vip
case store case store
case order
} }
var type: ItemType? var type: ItemType?

View File

@ -7,7 +7,7 @@
import UIKit import UIKit
class BRMineCoinItemView: UIView { class BRMineCoinItemView: UIControl {
var title: String? { var title: String? {
didSet { didSet {

View File

@ -58,8 +58,8 @@ class BRMineStoreCell: BRTableViewCell {
} }
@objc private func handleRewardsView() { @objc private func handleRewardsView() {
let vc = BRWalletViewController()
self.viewController?.navigationController?.pushViewController(vc, animated: true)
} }

View File

@ -19,6 +19,8 @@ class BRMineUserInfoCell: BRTableViewCell {
coinView.coinCount = userInfo?.coin_left_total ?? 0 coinView.coinCount = userInfo?.coin_left_total ?? 0
donateView.coinCount = userInfo?.send_coin_left_total ?? 0 donateView.coinCount = userInfo?.send_coin_left_total ?? 0
// loginButton.isSelected = !(userInfo?.is_tourist ?? true)
} }
} }
@ -60,6 +62,7 @@ class BRMineUserInfoCell: BRTableViewCell {
let view = BRMineCoinItemView() let view = BRMineCoinItemView()
view.title = "Coins".localized view.title = "Coins".localized
view.coinCount = 0 view.coinCount = 0
view.addTarget(self, action: #selector(handleCoinView), for: .touchUpInside)
return view return view
}() }()
@ -67,9 +70,37 @@ class BRMineUserInfoCell: BRTableViewCell {
let view = BRMineCoinItemView() let view = BRMineCoinItemView()
view.title = "Donate".localized view.title = "Donate".localized
view.coinCount = 0 view.coinCount = 0
view.addTarget(self, action: #selector(handleCoinView), for: .touchUpInside)
return view return view
}() }()
private lazy var loginButton: UIButton = {
let config = UIButton.Configuration.plain()
let button = UIButton(configuration: config)
button.layer.cornerRadius = 17
button.layer.masksToBounds = true
button.layer.borderWidth = 1
button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return }
if button.isSelected {
button.layer.borderColor = UIColor.colorD3D3D3().cgColor
button.configuration?.attributedTitle = AttributedString.br_createAttributedString(string: "Log out".localized, color: .colorD3D3D3(), font: .fontRegular(ofSize: 12))
} else {
button.layer.borderColor = UIColor.color1C1C1C().cgColor
button.configuration?.attributedTitle = AttributedString.br_createAttributedString(string: "Log in".localized, color: .color1C1C1C(), font: .fontRegular(ofSize: 12))
}
}
button.addTarget(self, action: #selector(handleLoginButton), for: .touchUpInside)
return button
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier) super.init(style: style, reuseIdentifier: reuseIdentifier)
@ -80,6 +111,20 @@ class BRMineUserInfoCell: BRTableViewCell {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
@objc private func handleCoinView() {
let vc = BRWalletViewController()
self.viewController?.navigationController?.pushViewController(vc, animated: true)
}
@objc private func handleLoginButton() {
if self.userInfo?.is_tourist == true {
let view = BRLoginView()
view.present(in: nil)
} else {
}
}
} }
extension BRMineUserInfoCell { extension BRMineUserInfoCell {
@ -92,6 +137,7 @@ extension BRMineUserInfoCell {
contentView.addSubview(idLabel) contentView.addSubview(idLabel)
contentView.addSubview(coinView) contentView.addSubview(coinView)
contentView.addSubview(donateView) contentView.addSubview(donateView)
// contentView.addSubview(loginButton)
avatarBgView.snp.makeConstraints { make in avatarBgView.snp.makeConstraints { make in
make.left.equalToSuperview() make.left.equalToSuperview()
@ -131,6 +177,13 @@ extension BRMineUserInfoCell {
make.top.equalTo(coinView) make.top.equalTo(coinView)
make.left.equalTo(coinView.snp.right).offset(35) make.left.equalTo(coinView.snp.right).offset(35)
} }
// loginButton.snp.makeConstraints { make in
// make.centerY.equalTo(avatarBgView)
// make.right.equalToSuperview().offset(-15)
// make.width.equalTo(88)
// make.height.equalTo(34)
// }
} }
} }

View File

@ -86,6 +86,10 @@ class BRVideoDetailViewController: BRPlayerListViewController {
} }
} }
override func handleNavBack() {
super.handleNavBack()
}
} }
extension BRVideoDetailViewController { extension BRVideoDetailViewController {

View File

@ -52,7 +52,7 @@ class BRPlayerViewModel: NSObject {
} }
} }
private lazy var payDataRequest = VPPayDataRequest() private lazy var payDataRequest = BRPayDataRequest()
} }

View File

@ -0,0 +1,80 @@
//
// BRCoinOrderRecordViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/26.
//
import UIKit
class BRCoinOrderRecordViewController: BRViewController, WMZPageProtocol {
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: UIScreen.width - 30, height: 80)
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
return layout
}()
private lazy var collectionView: BRCollectionView = {
let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin + 10, right: 0)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.br_addRefreshBackFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in
self?.handleFooterRefresh(nil)
}
collectionView.register(BRCoinOrderRecordCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .colorFFFFFF()
br_setupUI()
}
func getMyScrollView() -> UIScrollView {
return self.collectionView
}
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
completer?()
}
override func handleFooterRefresh(_ completer: (() -> Void)?) {
self.collectionView.br_endFooterRefreshing()
}
}
extension BRCoinOrderRecordViewController {
private func br_setupUI() {
view.addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalToSuperview().offset(10)
}
}
}
//MARK: UICollectionViewDelegate UICollectionViewDataSource
extension BRCoinOrderRecordViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRCoinOrderRecordCell
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
}

View File

@ -0,0 +1,74 @@
//
// BRConsumptionRecordViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRConsumptionRecordViewController: BRViewController, WMZPageProtocol {
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: UIScreen.width - 30, height: 80)
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
return layout
}()
private lazy var collectionView: BRCollectionView = {
let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin + 10, right: 0)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.br_addRefreshBackFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in
self?.handleFooterRefresh(nil)
}
collectionView.register(BRConsumptionRecordCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .colorFFFFFF()
br_setupUI()
}
func getMyScrollView() -> UIScrollView {
return self.collectionView
}
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
completer?()
}
override func handleFooterRefresh(_ completer: (() -> Void)?) {
self.collectionView.br_endFooterRefreshing()
}
}
extension BRConsumptionRecordViewController {
private func br_setupUI() {
view.addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalToSuperview().offset(20)
}
}
}
extension BRConsumptionRecordViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRConsumptionRecordCell
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
}

View File

@ -0,0 +1,122 @@
//
// BROrderRecordViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/26.
//
import UIKit
import WMZPageController
class BROrderRecordViewController: WMZPageController {
private lazy var vcArr: [BRViewController] = {
return [
BRCoinOrderRecordViewController(),
BRVipOrderRecordViewController()
]
}()
private lazy var pageParam: WMZPageParam = {
let param = WMZPageParam()
param.wTitleArr = [
"Coin Record".localized,
"VIP Record".localized
]
param.wViewController = { [weak self] index in
return self?.vcArr[index]
}
param.wMenuAnimal = PageTitleMenuLine
//
param.wBounces = false
param.wMenuTitleColor = .colorC2C2C2()
param.wMenuTitleSelectColor = .color1C1C1C()
param.wMenuTitleUIFont = .fontRegular(ofSize: 15)
param.wMenuTitleSelectUIFont = .fontMedium(ofSize: 15)
param.wMenuHeight = 35
// param.wMenuTitleWidth = (UIScreen.width - 50) / 2
param.wMenuTitleOffset = 60
param.wMenuPosition = PageMenuPositionCenter
param.wMenuInsets = UIEdgeInsets(top: 10, left: 15, bottom: 0, right: 15)
param.wMenuBgColor = .clear
param.wBgColor = .clear
param.wMenuIndicatorColor = .color1C1C1C()
param.wMenuIndicatorHeight = 2
param.wMenuIndicatorRadio = 1
param.wMenuIndicatorTitleRelativeWidth = 0
param.wMenuIndicatorY = 1
// param.wMenuFollowSliding = true
// param.wLazyLoading = false
param.wTopSuspension = true
param.wInsertHeadAndMenuBg = { [weak self] bgView in
guard let self = self else { return }
bgView?.addSubview(lineView)
lineView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.bottom.centerX.equalToSuperview()
make.height.equalTo(1)
}
}
// param.wCustomMenuTitle = { [weak self] buttons in
// buttons?.forEach({ button in
// self?.setMenuTitle(button: button)
// })
// }
param.wCustomNaviBarY = { _ in
return 0
}
param.wCustomTabbarY = { _ in
return 0
}
return param
}()
private lazy var lineView: UIView = {
let view = UIView()
view.backgroundColor = .colorE8E8E8()
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
br_setupUI()
}
func handleHeaderRefresh(_ completer: (() -> Void)?) {
if let vc = self.upSc.currentVC as? BRViewController {
vc.handleHeaderRefresh {
completer?()
}
} else {
completer?()
}
}
}
extension BROrderRecordViewController {
private func br_setupUI() {
self.param = self.pageParam
self.pageView.backgroundColor = .clear
self.downSc?.backgroundColor = .clear
}
}

View File

@ -0,0 +1,75 @@
//
// BRRewardCoinsRecordViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRRewardCoinsRecordViewController: BRViewController, WMZPageProtocol {
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: UIScreen.width - 30, height: 80)
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
return layout
}()
private lazy var collectionView: BRCollectionView = {
let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin + 10, right: 0)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.br_addRefreshBackFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in
self?.handleFooterRefresh(nil)
}
collectionView.register(BRRewardCoinsRecordCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .colorFFFFFF()
br_setupUI()
}
func getMyScrollView() -> UIScrollView {
return self.collectionView
}
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
completer?()
}
override func handleFooterRefresh(_ completer: (() -> Void)?) {
self.collectionView.br_endFooterRefreshing()
}
}
extension BRRewardCoinsRecordViewController {
private func br_setupUI() {
view.addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalToSuperview().offset(20)
}
}
}
extension BRRewardCoinsRecordViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRRewardCoinsRecordCell
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
}

View File

@ -11,7 +11,7 @@ class BRStoreViewController: BRViewController {
private var payData: BRPayDateModel? private var payData: BRPayDateModel?
private lazy var dataRequest = VPPayDataRequest() private lazy var dataRequest = BRPayDataRequest()
private lazy var scrollView: BRScrollView = { private lazy var scrollView: BRScrollView = {
let scrollView = BRScrollView() let scrollView = BRScrollView()

View File

@ -0,0 +1,80 @@
//
// BRVipOrderRecordViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRVipOrderRecordViewController: BRViewController, WMZPageProtocol {
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: UIScreen.width - 30, height: 80)
layout.minimumInteritemSpacing = 10
layout.minimumLineSpacing = 10
return layout
}()
private lazy var collectionView: BRCollectionView = {
let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin + 10, right: 0)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.br_addRefreshBackFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in
self?.handleFooterRefresh(nil)
}
collectionView.register(BRVipOrderRecordCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .colorFFFFFF()
br_setupUI()
}
func getMyScrollView() -> UIScrollView {
return self.collectionView
}
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
completer?()
}
override func handleFooterRefresh(_ completer: (() -> Void)?) {
self.collectionView.br_endFooterRefreshing()
}
}
extension BRVipOrderRecordViewController {
private func br_setupUI() {
view.addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalToSuperview().offset(10)
}
}
}
//MARK: UICollectionViewDelegate UICollectionViewDataSource
extension BRVipOrderRecordViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRVipOrderRecordCell
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 10
}
}

View File

@ -0,0 +1,164 @@
//
// BRWalletViewController.swift
// BeeReel
//
// Created by 鸿 on 2025/7/26.
//
import UIKit
import WMZPageController
class BRWalletViewController: WMZPageController {
private lazy var vcArr: [UIViewController] = {
return [
BROrderRecordViewController(),
BRConsumptionRecordViewController(),
BRRewardCoinsRecordViewController()
]
}()
private lazy var pageParam: WMZPageParam = {
let param = WMZPageParam()
param.wTitleArr = [
[
WMZPageBTNKey.keyName: "Order Records".localized,
WMZPageBTNKey.keyImage: UIImage(named: "Order Record 1")!,
WMZPageBTNKey.keySelectImage: UIImage(named: "Order Record 2")!,
],
[
WMZPageBTNKey.keyName: "Consumption Records".localized,
WMZPageBTNKey.keyImage: UIImage(named: "Order Record 1")!,
WMZPageBTNKey.keySelectImage: UIImage(named: "Order Record 2")!,
],
[
WMZPageBTNKey.keyName: "Reward Coins".localized,
WMZPageBTNKey.keyImage: UIImage(named: "Order Record 1")!,
WMZPageBTNKey.keySelectImage: UIImage(named: "Order Record 2")!,
],
]
param.wViewController = { [weak self] index in
return self?.vcArr[index]
}
param.wMenuHeadView = { [weak self] in
return self?.headerView
}
param.wInsertHeadAndMenuBg = { [weak self] bgView in
let view = UIImageView(image: UIImage(named: "bg 2"))
bgView?.addSubview(view)
view.snp.makeConstraints { make in
make.bottom.left.right.equalToSuperview()
make.height.equalTo(62)
}
}
//
param.wBounces = true
param.wMenuTitleColor = .color777777()
param.wMenuTitleSelectColor = .colorFFFFFF()
param.wMenuTitleUIFont = .fontRegular(ofSize: 14)
param.wMenuTitleSelectUIFont = .fontRegular(ofSize: 14)
param.wMenuTitleRadios = 21
param.wMenuHeight = 42
param.wMenuTitleOffset = 14
param.wMenuCellMargin = 22
param.wMenuImageMargin = 4
param.wMenuInsets = UIEdgeInsets(top: 20, left: 15, bottom: 0, right: 15)
param.wMenuBgColor = .clear
param.wBgColor = .clear
param.wMenuImagePosition = PageBtnPositionLeft
param.wTopSuspension = true
param.wCustomMenuTitle = { [weak self] buttons in
buttons?.forEach {
self?.updateMenuButton(button: $0)
}
}
param.wCustomMenuSelectTitle = { [weak self] buttons in
buttons?.forEach {
self?.updateMenuButton(button: $0)
}
}
return param
}()
private lazy var headerView: BRWalletHeaderView = {
let view = BRWalletHeaderView(frame: .init(x: 0, y: 0, width: UIScreen.width, height: 180))
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .color1C1C1C()
configNavigationBack("nav_back_icon_03")
self.title = "My Wallet".localized
br_setupUI()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(false, animated: true)
br_setNavigation(style: .dark)
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
private func updateMenuButton(button: WMZPageNaviBtn) {
if button.isSelected {
button.backgroundColor = .color1C1C1C()
} else {
button.backgroundColor = .colorF0F0F0()
}
}
func handleHeaderRefresh(_ completer: (() -> Void)?) {
if let vc = self.upSc.currentVC as? BRViewController {
vc.handleHeaderRefresh {
completer?()
}
} else if let vc = self.upSc.currentVC as? BROrderRecordViewController {
vc.handleHeaderRefresh {
completer?()
}
} else {
completer?()
}
}
}
extension BRWalletViewController {
private func br_setupUI() {
self.param = pageParam
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 0.1) {
self.pageView.backgroundColor = .clear
self.downSc?.backgroundColor = .clear
}
self.downSc?.br_addRefreshHeader { [weak self] in
self?.handleHeaderRefresh {
self?.downSc?.br_endHeaderRefreshing()
}
}
}
}

View File

@ -1,5 +1,5 @@
// //
// VPPayDataRequest.swift // BRPayDataRequest.swift
// BeeReel // BeeReel
// //
// Created by 鸿 on 2025/7/26. // Created by 鸿 on 2025/7/26.
@ -8,7 +8,7 @@
import UIKit import UIKit
import StoreKit import StoreKit
class VPPayDataRequest: NSObject { class BRPayDataRequest: NSObject {
private var oldTemplateModel: BRPayDateModel? private var oldTemplateModel: BRPayDateModel?
@ -67,7 +67,7 @@ class VPPayDataRequest: NSObject {
/* /*
//MARK: -------------- SKProductsRequestDelegate -------------- //MARK: -------------- SKProductsRequestDelegate --------------
extension VPPayTemplateRequest: SKProductsRequestDelegate { extension BRPayDataRequest: SKProductsRequestDelegate {
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
if isLoding { if isLoding {

View File

@ -0,0 +1,84 @@
//
// BRCoinOrderRecordCell.swift
// BeeReel
//
// Created by 鸿 on 2025/7/26.
//
import UIKit
class BRCoinOrderRecordCell: BRCollectionViewCell {
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 14)
label.textColor = .color1C1C1C()
label.text = "Recharge Coins"
return label
}()
private lazy var coinView: UIButton = {
var config = UIButton.Configuration.plain()
config.imagePadding = 2
config.image = UIImage(named: "Frame 6")
config.imagePlacement = .trailing
config.contentInsets = .zero
let button = UIButton(configuration: config)
button.isUserInteractionEnabled = false
button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return }
button.configuration?.attributedTitle = AttributedString.br_createAttributedString(string: "+60", color: .color7ECD5E(), font: .fontMedium(ofSize: 15))
}
return button
}()
private lazy var timeLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 11)
label.textColor = .colorC2C2C2()
label.text = "2025-04-17 06:19:13"
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.contentView.backgroundColor = .colorFAFAFA()
self.contentView.layer.cornerRadius = 10
self.contentView.layer.masksToBounds = true
br_setupUI()
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension BRCoinOrderRecordCell {
private func br_setupUI() {
contentView.addSubview(titleLabel)
contentView.addSubview(coinView)
contentView.addSubview(timeLabel)
titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalToSuperview().offset(11)
}
coinView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.bottom.equalToSuperview().offset(-16)
}
timeLabel.snp.makeConstraints { make in
make.centerY.equalTo(coinView)
make.right.equalToSuperview().offset(-10)
}
}
}

View File

@ -0,0 +1,101 @@
//
// BRConsumptionRecordCell.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRConsumptionRecordCell: BRCollectionViewCell {
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 14)
label.textColor = .color1C1C1C()
label.text = "Purchase Single Episode"
return label
}()
private lazy var contentLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 12)
label.textColor = .colorC2C2C2()
label.text = "Ep.8 Romantic Flash Marriage In Progress"
return label
}()
private lazy var timeLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 11)
label.textColor = .colorC2C2C2()
label.text = "2025-04-17 06:19:13"
label.setContentHuggingPriority(.required, for: .horizontal)
label.setContentCompressionResistancePriority(.required, for: .horizontal)
return label
}()
private lazy var coinView: UIButton = {
var config = UIButton.Configuration.plain()
config.imagePadding = 2
config.image = UIImage(named: "Frame 6")
config.imagePlacement = .trailing
config.contentInsets = .zero
let button = UIButton(configuration: config)
button.isUserInteractionEnabled = false
button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return }
button.configuration?.attributedTitle = AttributedString.br_createAttributedString(string: "-60", color: .color7ECD5E(), font: .fontMedium(ofSize: 15))
}
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.contentView.backgroundColor = .colorFAFAFA()
self.contentView.layer.cornerRadius = 10
self.contentView.layer.masksToBounds = true
br_setupUI()
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension BRConsumptionRecordCell {
private func br_setupUI() {
contentView.addSubview(titleLabel)
contentView.addSubview(contentLabel)
contentView.addSubview(timeLabel)
contentView.addSubview(coinView)
titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalToSuperview().offset(11)
}
contentLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.bottom.equalToSuperview().offset(-15)
make.right.equalTo(timeLabel.snp.left).offset(-25)
}
timeLabel.snp.makeConstraints { make in
make.centerY.equalTo(contentLabel)
make.right.equalToSuperview().offset(-10)
}
coinView.snp.makeConstraints { make in
make.centerY.equalTo(titleLabel)
make.right.equalToSuperview().offset(-11)
}
}
}

View File

@ -0,0 +1,100 @@
//
// BRRewardCoinsRecordCell.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRRewardCoinsRecordCell: BRCollectionViewCell {
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 14)
label.textColor = .color1C1C1C()
label.text = "Check in"
return label
}()
private lazy var contentLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 12)
label.textColor = .colorC2C2C2()
label.text = "Expires in 30 days"
return label
}()
private lazy var timeLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 11)
label.textColor = .colorC2C2C2()
label.text = "2025-04-17 06:19:13"
label.setContentHuggingPriority(.required, for: .horizontal)
label.setContentCompressionResistancePriority(.required, for: .horizontal)
return label
}()
private lazy var coinView: UIButton = {
var config = UIButton.Configuration.plain()
config.imagePadding = 2
config.image = UIImage(named: "Frame 6")
config.imagePlacement = .trailing
config.contentInsets = .zero
let button = UIButton(configuration: config)
button.isUserInteractionEnabled = false
button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return }
button.configuration?.attributedTitle = AttributedString.br_createAttributedString(string: "+60", color: .color7ECD5E(), font: .fontMedium(ofSize: 15))
}
return button
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.contentView.backgroundColor = .colorFAFAFA()
self.contentView.layer.cornerRadius = 10
self.contentView.layer.masksToBounds = true
br_setupUI()
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension BRRewardCoinsRecordCell {
private func br_setupUI() {
contentView.addSubview(titleLabel)
contentView.addSubview(contentLabel)
contentView.addSubview(timeLabel)
contentView.addSubview(coinView)
titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalToSuperview().offset(11)
}
contentLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.bottom.equalToSuperview().offset(-15)
make.right.equalTo(timeLabel.snp.left).offset(-25)
}
timeLabel.snp.makeConstraints { make in
make.centerY.equalTo(contentLabel)
make.right.equalToSuperview().offset(-10)
}
coinView.snp.makeConstraints { make in
make.centerY.equalTo(titleLabel)
make.right.equalToSuperview().offset(-11)
}
}
}

View File

@ -0,0 +1,74 @@
//
// BRVipOrderRecordCell.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRVipOrderRecordCell: BRCollectionViewCell {
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 14)
label.textColor = .color1C1C1C()
label.text = "Purchase VIP"
return label
}()
private lazy var durationLabel: UILabel = {
let label = UILabel()
label.font = .fontMedium(ofSize: 15)
label.textColor = .color7ECD5E()
label.text = "+30 days"
return label
}()
private lazy var timeLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 11)
label.textColor = .colorC2C2C2()
label.text = "2025-04-17 06:19:13"
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.contentView.backgroundColor = .colorFAFAFA()
self.contentView.layer.cornerRadius = 10
self.contentView.layer.masksToBounds = true
br_setupUI()
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension BRVipOrderRecordCell {
private func br_setupUI() {
contentView.addSubview(titleLabel)
contentView.addSubview(durationLabel)
contentView.addSubview(timeLabel)
titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.top.equalToSuperview().offset(11)
}
durationLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(12)
make.bottom.equalToSuperview().offset(-16)
}
timeLabel.snp.makeConstraints { make in
make.centerY.equalTo(durationLabel)
make.right.equalToSuperview().offset(-10)
}
}
}

View File

@ -0,0 +1,75 @@
//
// BRWalletHeaderItemView.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRWalletHeaderItemView: UIView {
var title: String? {
didSet {
titleLabel.text = title
}
}
var coin: Int? {
didSet {
coinLabel.text = "\(coin ?? 0)"
}
}
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 12)
label.textColor = .colorD3D3D3()
return label
}()
private lazy var coinLabel: UILabel = {
let label = UILabel()
label.font = .aaHouDiHei(ofSize: 18)
label.textColor = .colorFFFFFF()
return label
}()
private lazy var iconView: UIView = {
let view = UIImageView(image: UIImage(named: "Frame 6"))
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(titleLabel)
addSubview(coinLabel)
addSubview(iconView)
titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview()
make.right.lessThanOrEqualToSuperview()
make.top.equalToSuperview()
}
coinLabel.snp.makeConstraints { make in
make.left.equalToSuperview()
make.centerY.equalTo(iconView).offset(2)
}
iconView.snp.makeConstraints { make in
make.left.equalTo(coinLabel.snp.right).offset(3)
make.right.lessThanOrEqualToSuperview()
make.top.equalToSuperview().offset(21)
make.bottom.equalToSuperview()
}
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -0,0 +1,134 @@
//
// BRWalletHeaderView.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRWalletHeaderView: UIView {
private lazy var bgView: UIView = {
let view = UIImageView(image: UIImage(named: "bg 3"))
return view
}()
private lazy var totalTitleLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 12)
label.textColor = .colorD3D3D3()
label.text = "Total Coins".localized
return label
}()
private lazy var totalCoinIconView: UIImageView = {
let view = UIImageView(image: UIImage(named: "coins 2"))
return view
}()
private lazy var totalCoinLabel: UILabel = {
let label = UILabel()
label.font = .aaHouDiHei(ofSize: 24)
label.textColor = .colorFFFFFF()
return label
}()
private lazy var coinItemView: BRWalletHeaderItemView = {
let view = BRWalletHeaderItemView()
view.title = "Recharge".localized
return view
}()
private lazy var sendCoinItemView: BRWalletHeaderItemView = {
let view = BRWalletHeaderItemView()
view.title = "Donate".localized
return view
}()
private lazy var lineView: UIView = {
let view = UIView()
view.backgroundColor = .colorFFFFFF(alpha: 0.3)
return view
}()
deinit {
NotificationCenter.default.removeObserver(self)
}
override init(frame: CGRect) {
super.init(frame: frame)
NotificationCenter.default.addObserver(self, selector: #selector(userInfoUpdateNotification), name: BRLoginManager.userInfoUpdateNotification, object: nil)
userInfoUpdateNotification()
br_setupUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc private func userInfoUpdateNotification() {
let userInfo = BRLoginManager.manager.userInfo
totalCoinLabel.text = "\(userInfo?.totalCoin ?? 0)"
coinItemView.coin = userInfo?.coin_left_total
sendCoinItemView.coin = userInfo?.send_coin_left_total
}
}
extension BRWalletHeaderView {
private func br_setupUI() {
addSubview(bgView)
bgView.addSubview(totalTitleLabel)
bgView.addSubview(totalCoinIconView)
bgView.addSubview(totalCoinLabel)
bgView.addSubview(lineView)
bgView.addSubview(coinItemView)
bgView.addSubview(sendCoinItemView)
bgView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(10)
make.bottom.equalToSuperview().offset(-20)
}
totalTitleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(15)
}
totalCoinIconView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(20)
make.top.equalToSuperview().offset(40)
}
totalCoinLabel.snp.makeConstraints { make in
make.centerY.equalTo(totalCoinIconView).offset(2)
make.left.equalTo(totalCoinIconView.snp.right).offset(3)
}
lineView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.width.equalTo(1)
make.height.equalTo(28)
make.bottom.equalToSuperview().offset(-20)
}
coinItemView.snp.makeConstraints { make in
make.centerY.equalTo(lineView)
make.left.equalToSuperview().offset(20)
}
sendCoinItemView.snp.makeConstraints { make in
make.centerY.equalTo(lineView)
make.left.equalTo(lineView.snp.right).offset(30)
}
}
}

View File

@ -0,0 +1,111 @@
//
// AppDelegate+APNS.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
extension AppDelegate {
///
static var haveBeenShownAPNS = false
func requestAPNS() {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.badge, .sound, .alert]) { grant, error in
if !grant {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.showApnsAlert()
}
}
Self.haveBeenShownAPNS = true
BRAppTool.sceneDelegate?.br_retryHandleOpenAppMessage()
BRStatAPI.uploadNoticeStatus()
}
UIApplication.shared.registerForRemoteNotifications()
}
private func showApnsAlert() {
guard let date = UserDefaults.standard.object(forKey: kBRApnsAlertDefaultsKey) as? Date else {
UserDefaults.standard.set(Date(), forKey: kBRApnsAlertDefaultsKey)
return
}
if date.br_isToday { return }
UserDefaults.standard.set(Date(), forKey: kBRApnsAlertDefaultsKey)
let alert = BRAlert(title: "kApnsAlertTitle".localized, detail: "kApnsAlertContent".localized, image: UIImage(named: "通知"), normalButtonText: "Later".localized, highlightButtonText: "Allow".localized).show()
alert.clickNormalButton = {
}
alert.clickHighlightButton = {
BRAppTool.openApnsSetting()
}
}
}
//MARK: -------------- UNUserNotificationCenterDelegate --------------
extension AppDelegate: UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Messaging.messaging().apnsToken = deviceToken
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: any Error) {
}
///APP
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.badge, .banner])
}
///app
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if #available(iOS 16.0, *) {
UNUserNotificationCenter.current().setBadgeCount(0)
} else {
UIApplication.shared.applicationIconBadgeNumber = 0
}
guard let userInfo: [String : Any] = response.notification.request.content.userInfo as? [String : Any] else {
completionHandler()
return
}
guard let model = BROpenAppModel.deserialize(from: userInfo) else {
completionHandler()
return
}
// VPStatAPI.requestStatApns(messageId: model.message_id ?? "", title: response.notification.request.content.title)
//
//
// if model.path == .videoDetail, let shortPlayId = model.short_play_id {
// let vc = VPDetailPlayerViewController()
// vc.shortPlayId = shortPlayId
// VPAppTool.topViewController?.navigationController?.pushViewController(vc, animated: true)
//
// } else if model.path == .promotion {
// let vc = VPRewardsViewController()
// VPAppTool.topViewController?.navigationController?.pushViewController(vc, animated: true)
//
// } else if model.path == .feedback {
// let vc = VPCampaignWebViewController()
// vc.urlStr = kVPFeedBackListWebUrl
// VPAppTool.topViewController?.navigationController?.pushViewController(vc, animated: true)
// }
completionHandler()
}
}

View File

@ -0,0 +1,47 @@
//
// AppDelegate+Thirdparty.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import AdjustSdk
import FirebaseMessaging
import FirebaseCore
extension AppDelegate {
func registThirdparty(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
//Adjust
#if DEBUG
let config = ADJConfig(appToken: "tyo96hvbjabk", environment: ADJEnvironmentSandbox)
config?.logLevel = .verbose
#else
let config = ADJConfig(appToken: "tyo96hvbjabk", environment: ADJEnvironmentProduction)
#endif
config?.delegate = self
Adjust.initSdk(config)
// FirebaseApp.configure()
// Messaging.messaging().delegate = self
}
}
extension AppDelegate: AdjustDelegate {
func adjustDeferredDeeplinkReceived(_ deeplink: URL?) -> Bool {
return true
}
}
//MARK: MessagingDelegate
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
if let token = fcmToken {
BRSettingAPI.requestUploadApnsDeviceToken(token: token)
}
}
}

View File

@ -13,14 +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 {
registThirdparty(application, didFinishLaunchingWithOptions: launchOptions)
BRAppTool.appDelegate = self BRAppTool.appDelegate = self
BRNetworkStatusManager.manager.startMonitoring() BRNetworkStatusManager.manager.startMonitoring()
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: BRNetworkStatusManager.networkStatusDidChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: BRNetworkStatusManager.networkStatusDidChangeNotification, object: nil)
BRLoginManager.manager.updateUserInfo(completer: nil) BRLoginManager.manager.updateUserInfo(completer: nil)
addConfig() addConfig()
requestAPNS()
return true return true
} }

View File

@ -0,0 +1,102 @@
//
// SceneDelegate+Open.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import AdjustSdk
extension SceneDelegate {
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else {
return
}
br_handleOpenAppMessage(webpageURL: url)
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
guard let webpageURL = userActivity.webpageURL else { return }
br_handleOpenAppMessage(webpageURL: webpageURL)
}
}
extension SceneDelegate {
///(APP)
static var allowOpenMessage = true
///
static var isNeedRetry = false
private static var webpageURL: URL?
func br_handleOpenAppMessage(webpageURL: URL?) {
guard BRNetworkStatusManager.manager.isReachable == true, //
AppDelegate.haveBeenShownAPNS, //
self.isOpenApp, //APP
BRAppTool.idfaAuthorizationFinish
else {
if let webpageURL = webpageURL {
SceneDelegate.webpageURL = webpageURL
}
Self.isNeedRetry = true
return
}
Self.isNeedRetry = false
SceneDelegate.webpageURL = nil
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self._handleOpenAppMessage(webpageURL: webpageURL)
}
}
private func _handleOpenAppMessage(webpageURL: URL?) {
guard SceneDelegate.allowOpenMessage else { return }
SceneDelegate.allowOpenMessage = false
//URL
var statUrlStr: String? = webpageURL?.absoluteString
var data: [String : Any]? = webpageURL?.query?.br_urlQuryToDictionary()
if statUrlStr == nil, let pasteStr = UIPasteboard.general.string, pasteStr.contains("veloriaapp") {
let tempArr = pasteStr.components(separatedBy: "?")
let query = tempArr.last
let tempData = query?.br_urlQuryToDictionary()
if tempData?["short_play_id"] != nil {
data = tempData
statUrlStr = pasteStr
}
}
UIPasteboard.general.string = nil
if let urlStr = statUrlStr {//
BRStatAPI.requestStatW2a(data: urlStr)
}
guard let data = data else { return }
guard let model = BROpenAppModel.deserialize(from: data) else { return }
guard let shortPlayId = model.short_play_id, shortPlayId.count > 0 else { return }
let vc = BRVideoDetailViewController()
vc.shortPlayId = shortPlayId
BRAppTool.topViewController?.navigationController?.pushViewController(vc, animated: true)
}
///
func br_retryHandleOpenAppMessage() {
guard Self.isNeedRetry else { return }
br_handleOpenAppMessage(webpageURL: SceneDelegate.webpageURL)
}
}

View File

@ -11,18 +11,29 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow? var window: UIWindow?
private var onLineTimer: Timer?
private(set) var isOpenApp = false
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return } guard let windowScene = (scene as? UIWindowScene) else { return }
BRAppTool.sceneDelegate = self BRAppTool.sceneDelegate = self
BRAppTool.windowScene = windowScene BRAppTool.windowScene = windowScene
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: BRNetworkStatusManager.networkStatusDidChangeNotification, object: nil)
onLineTimer = Timer.scheduledTimer(timeInterval: 60 * 10, target: YYTextWeakProxy(target: self), selector: #selector(handleOnLine), userInfo: nil, repeats: true)
if let webpageURL = connectionOptions.userActivities.first?.webpageURL {
self.br_handleOpenAppMessage(webpageURL: webpageURL)
} else if let url = connectionOptions.urlContexts.first?.url {
self.br_handleOpenAppMessage(webpageURL: url)
}
window = UIWindow(windowScene: windowScene) window = UIWindow(windowScene: windowScene)
BRAppTool.tabBarController = BRTabBarController() startApp()
window?.rootViewController = BRAppTool.tabBarController
window?.makeKeyAndVisible()
} }
func sceneDidDisconnect(_ scene: UIScene) { func sceneDidDisconnect(_ scene: UIScene) {
@ -33,26 +44,68 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
} }
func sceneDidBecomeActive(_ scene: UIScene) { func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state. BRStatAPI.requestStatOnLine()
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. BRStatAPI.requestEnterApp()
} }
func sceneWillResignActive(_ scene: UIScene) { func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state. BRStatAPI.requestLeaveApp()
// This may occur due to temporary interruptions (ex. an incoming phone call).
} }
func sceneWillEnterForeground(_ scene: UIScene) { func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground. BRStatAPI.uploadNoticeStatus()
// Use this method to undo the changes made on entering the background.
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.br_handleOpenAppMessage(webpageURL: nil)
}
} }
func sceneDidEnterBackground(_ scene: UIScene) { func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background. SceneDelegate.allowOpenMessage = true
// 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.
} }
} }
extension SceneDelegate {
private func startApp() {
// let hasOpenApp = UserDefaults.standard.object(forKey: kBRHasBeenOpenedAPPDefaultsKey) as? Bool
//
// if hasOpenApp != true {
let guideVc = BRGuideViewController()
guideVc.clickStartButton = { [weak self] in
guard let self = self else { return }
self.openApp()
self.br_retryHandleOpenAppMessage()
}
window?.rootViewController = guideVc
window?.makeKeyAndVisible()
// } else {
// openApp()
// }
}
private func openApp() {
self.isOpenApp = true
BRAppTool.tabBarController = BRTabBarController()
window?.rootViewController = BRAppTool.tabBarController
window?.makeKeyAndVisible()
}
}
extension SceneDelegate {
@objc private func handleOnLine() {
BRStatAPI.requestStatOnLine()
}
@objc private func networkStatusDidChangeNotification() {
br_retryHandleOpenAppMessage()
}
}

View File

@ -87,6 +87,8 @@ class BRAlert: BRBaseAlert {
let stackView = UIStackView() let stackView = UIStackView()
stackView.axis = .vertical stackView.axis = .vertical
stackView.alignment = .center
stackView.spacing = 6
if let image = image { if let image = image {
let imageView = UIImageView(image: image) let imageView = UIImageView(image: image)

View File

@ -6,6 +6,8 @@
// //
import UIKit import UIKit
import AppTrackingTransparency
import AdSupport
class BRAppTool { class BRAppTool {
@ -54,3 +56,33 @@ class BRAppTool {
} }
} }
} }
extension BRAppTool {
///idfa
static var idfaAuthorizationFinish = false
static func requestIDFAAuthorization(completion: @escaping (String?) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
ATTrackingManager.requestTrackingAuthorization { status in
idfaAuthorizationFinish = true
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
BRAppTool.sceneDelegate?.br_retryHandleOpenAppMessage()
completion(idfa)
}
}
}
///
static func openApnsSetting() {
if #available(iOS 16.0, *) {
if let url = URL(string: UIApplication.openNotificationSettingsURLString) {
UIApplication.shared.open(url)
}
} else {
if let url = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(url)
}
}
}
}

View File

@ -0,0 +1,63 @@
//
// BRLoginButton.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
class BRLoginButton: UIControl {
override var intrinsicContentSize: CGSize {
return .init(width: UIScreen.width - 30, height: 48)
}
lazy var iconImageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 14)
return label
}()
lazy var arrowImageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
override init(frame: CGRect) {
super.init(frame: frame)
layer.cornerRadius = 24
layer.masksToBounds = true
addSubview(iconImageView)
addSubview(titleLabel)
addSubview(arrowImageView)
iconImageView.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(35)
}
titleLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview()
}
arrowImageView.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-24)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

View File

@ -0,0 +1,112 @@
//
// BRLoginManager+Apple.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
import AuthenticationServices
extension BRLoginManager {
private struct AssociatedKeys {
static var signAppleHandle: Int?
}
private var signAppleHandle: ((_ model: BRThirdSignModel?) -> Void)? {
set {
objc_setAssociatedObject(self, &AssociatedKeys.signAppleHandle, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
}
get {
return objc_getAssociatedObject(self, &AssociatedKeys.signAppleHandle) as? ((_ model: BRThirdSignModel?) -> Void)
}
}
///
func appleSignLogin(completer: ((_ model: BRThirdSignModel?) -> Void)?) {
self.signAppleHandle = completer
let appleIDProvider = ASAuthorizationAppleIDProvider()
let request = appleIDProvider.createRequest()
request.requestedScopes = [.fullName, .email]
let authorizationController = ASAuthorizationController(authorizationRequests: [request])
authorizationController.delegate = self
authorizationController.presentationContextProvider = self
authorizationController.performRequests()
}
}
//MARK:-------------- ASAuthorizationControllerDelegate --------------
extension BRLoginManager: ASAuthorizationControllerDelegate {
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
let userIdentifier = appleIDCredential.user
let fullName = appleIDCredential.fullName
let email = appleIDCredential.email
let identityToken = appleIDCredential.identityToken.flatMap { String(data: $0, encoding: .utf8) }
let identityTokenParams = self.jwtDecode(jwtStr: identityToken ?? "")
let model = BRThirdSignModel()
model.platform = .apple
model.third_id = userIdentifier
model.giving_name = fullName?.givenName
model.family_name = fullName?.familyName
model.avator = identityTokenParams?["picture"] as? String
model.email = identityTokenParams?["email"] as? String
signAppleHandle?(model)
}
}
func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
signAppleHandle?(nil)
}
}
extension BRLoginManager: ASAuthorizationControllerPresentationContextProviding {
func presentationAnchor(for controller: ASAuthorizationController) -> ASPresentationAnchor {
return BRAppTool.keyWindow!
}
}
extension BRLoginManager {
private func jwtDecode(jwtStr: String) -> [String: Any]? {
let segments = jwtStr.components(separatedBy: ".")
guard segments.count > 1 else { return nil }
var base64String = segments[1]
// Base64
let requiredLength = 4 * Int(ceil(Double(base64String.count) / 4.0))
let paddingLength = requiredLength - base64String.count
if paddingLength > 0 {
base64String += String(repeating: "=", count: paddingLength)
}
// URL
base64String = base64String.replacingOccurrences(of: "-", with: "+")
base64String = base64String.replacingOccurrences(of: "_", with: "/")
// Base64
guard let data = Data(base64Encoded: base64String),
let jsonObject = try? JSONSerialization.jsonObject(with: data, options: []),
let payload = jsonObject as? [String: Any] else {
return nil
}
return payload
}
}

View File

@ -8,7 +8,7 @@
import UIKit import UIKit
import SmartCodable import SmartCodable
class BRLoginManager { class BRLoginManager: NSObject {
enum LoginType: String, SmartCaseDefaultable { enum LoginType: String, SmartCaseDefaultable {
case apple = "Apple" case apple = "Apple"
@ -33,6 +33,24 @@ class BRLoginManager {
UserDefaults.br_setObject(token, forKey: kBRLoginTokenDefaultsKey) UserDefaults.br_setObject(token, forKey: kBRLoginTokenDefaultsKey)
} }
func login(type: LoginType, presentingViewController: UIViewController?, completer: ((_ isFinish: Bool) -> Void)?) {
// switch type {
// case .apple:
// appleSignLogin { [weak self] model in
// self?.requestThirdLogin(thirdSignModel: model, completer: completer)
// }
//
// case .faceBook:
// facebookLogin(presentingViewController: presentingViewController) { [weak self] model in
// self?.requestThirdLogin(thirdSignModel: model, completer: completer)
// }
// default:
// completer?(false)
// }
}
/// ///
func updateUserInfo(completer: (() -> Void)?) { func updateUserInfo(completer: (() -> Void)?) {
@ -51,11 +69,43 @@ class BRLoginManager {
}
extension BRLoginManager {
///
private func requestThirdLogin(thirdSignModel: BRThirdSignModel?, completer: ((_ isFinish: Bool) -> Void)?) {
guard let thirdSignModel = thirdSignModel else {
completer?(false)
return
}
// BRStatAPI.requestLeaveApp()
BRUserAPI.requestThirdLogin(model: thirdSignModel) { [weak self] token in
guard let self = self else { return }
guard let token = token else {
completer?(false)
return
}
self.setLoginToken(token: token)
self.userInfo?.is_tourist = false
self.updateUserInfo(completer: nil)
// VPStatAPI.requestStatOnLine()
// VPStatAPI.requestEnterApp()
completer?(true)
NotificationCenter.default.post(name: BRLoginManager.userInfoUpdateNotification, object: nil)
NotificationCenter.default.post(name: BRLoginManager.loginStateDidChangeNotification, object: nil)
}
}
} }
extension BRLoginManager { extension BRLoginManager {
/// ///
@objc static let userInfoUpdateNotification = NSNotification.Name(rawValue: "BRLoginManager.userInfoUpdateNotification") @objc static let userInfoUpdateNotification = NSNotification.Name(rawValue: "BRLoginManager.userInfoUpdateNotification")
///
@objc static let loginStateDidChangeNotification = NSNotification.Name(rawValue: "BRLoginManager.loginStateDidChangeNotification")
} }

View File

@ -0,0 +1,180 @@
//
// BRLoginView.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
import HWPanModal
class BRLoginView: BRPanModalContentView {
var bgViewHeight: CGFloat {
let imageSize = bgView.image?.size ?? .zero
return imageSize.height / imageSize.width * UIScreen.width
}
private lazy var bgView: UIImageView = {
let view = UIImageView(image: UIImage(named: "顶部bg"))
return view
}()
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.font = .fontBold(ofSize: 20)
label.textColor = .color1C1C1C()
label.text = "Welcome to BeeReel".localized
return label
}()
private lazy var facebookButton: BRLoginButton = {
let button = BRLoginButton()
button.iconImageView.image = UIImage(named: "Facebook")
button.titleLabel.text = "Login with Facebook".localized
button.titleLabel.textColor = .color1C1C1C()
button.arrowImageView.image = UIImage(named: "Frame 7")
button.backgroundColor = .colorF0F0F0()
button.addTarget(self, action: #selector(handleFacebookButton), for: .touchUpInside)
return button
}()
private lazy var appleButton: BRLoginButton = {
let button = BRLoginButton()
button.iconImageView.image = UIImage(named: "Apple")
button.titleLabel.text = "Login with Apple".localized
button.titleLabel.textColor = .colorFFFFFF()
button.arrowImageView.image = UIImage(named: "Frame 8")
button.backgroundColor = .color1C1C1C()
button.addTarget(self, action: #selector(handleAppleButton), for: .touchUpInside)
return button
}()
private lazy var agreementLabel: YYLabel = {
let userAgreement = "User Agreement".localized
let privacyPolicy = "Privacy Policy".localized
let text = "kLoginAgreementTipText".localizedReplace(text1: userAgreement, text2: privacyPolicy)
let range1 = (text as NSString).range(of: userAgreement)
let range2 = (text as NSString).range(of: privacyPolicy)
let textColor = UIColor.color777777()
let string = NSMutableAttributedString(string: text)
string.yy_font = .fontRegular(ofSize: 12)
string.yy_color = textColor
string.yy_setTextUnderline(YYTextDecoration(style: .single), range: range1)
string.yy_setTextUnderline(YYTextDecoration(style: .single), range: range2)
string.yy_setTextHighlight(range1, color: nil, backgroundColor: nil) { [weak self] _, _, _, _ in
self?.dismiss(animated: true) {
let vc = BRWebViewController()
vc.webUrl = kSBUserAgreementWebUrl
BRAppTool.topViewController?.navigationController?.pushViewController(vc, animated: true)
}
}
string.yy_setTextHighlight(range2, color: nil, backgroundColor: nil) { [weak self] _, _, _, _ in
self?.dismiss(animated: true) {
let vc = BRWebViewController()
vc.webUrl = kSBPrivacyPolicyWebUrl
BRAppTool.topViewController?.navigationController?.pushViewController(vc, animated: true)
}
}
let textContainer = YYTextContainer(size: .init(width: UIScreen.width - 30, height: 100))
let textLayout = YYTextLayout(container: textContainer, text: string)
let label = YYLabel()
label.textLayout = textLayout
// label.attributedText = string
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
contentHeight = bgViewHeight + 222 + (agreementLabel.textLayout?.textBoundingSize.height ?? 0) + UIScreen.tabbarSafeBottomMargin
// contentHeight = bgViewHeight + 232 + UIScreen.tabbarSafeBottomMargin
br_setupUI()
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func backgroundConfig() -> HWBackgroundConfig {
let config = HWBackgroundConfig()
config.backgroundAlpha = 0.4
return config
}
override func cornerRadius() -> CGFloat {
return 25
}
override func allowsDragToDismiss() -> Bool {
return true
}
override func allowsPullDownWhenShortState() -> Bool {
return true
}
}
extension BRLoginView {
private func br_setupUI() {
self.backgroundColor = .colorFFFFFF()
addSubview(bgView)
addSubview(titleLabel)
addSubview(facebookButton)
addSubview(appleButton)
addSubview(agreementLabel)
bgView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
make.height.equalTo(bgViewHeight)
}
titleLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(bgView.snp.bottom).offset(18)
}
facebookButton.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(bgView.snp.bottom).offset(64)
}
appleButton.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(facebookButton.snp.bottom).offset(20)
}
agreementLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(appleButton.snp.bottom).offset(22)
make.width.equalTo(self.agreementLabel.textLayout?.textBoundingSize.width ?? 0)
make.height.equalTo(self.agreementLabel.textLayout?.textBoundingSize.height ?? 0)
}
}
}
extension BRLoginView {
@objc private func handleFacebookButton() {
}
@objc private func handleAppleButton() {
}
private func login(type: BRLoginManager.LoginType) {
}
}

View File

@ -0,0 +1,24 @@
//
// BRThirdSignModel.swift
// BeeReel
//
// Created by 鸿 on 2025/7/28.
//
import UIKit
import SmartCodable
class BRThirdSignModel: BRModel, SmartCodable {
var third_id: String?
var email: String?
//
var family_name: String?
//
var giving_name: String?
var avator: String?
var platform: BRLoginManager.LoginType?
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 869 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 716 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

View File

@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>UIAppFonts</key> <key>UIAppFonts</key>
<array> <array>
<string>AaHouDiHei-Regular.ttf</string> <string>AaHouDiHei-Regular.ttf</string>

View File

@ -34,6 +34,17 @@
} }
} }
}, },
"Allow" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Allow"
}
}
}
},
"Balance: ## Coins" : { "Balance: ## Coins" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -135,6 +146,17 @@
} }
} }
}, },
"Consumption Records" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Consumption Records"
}
}
}
},
"Daily Check-In" : { "Daily Check-In" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -146,6 +168,17 @@
} }
} }
}, },
"Donate" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Donate"
}
}
}
},
"EP.##" : { "EP.##" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -190,6 +223,39 @@
} }
} }
}, },
"Feedback" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Feedback"
}
}
}
},
"Feedback Details" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Feedback Details"
}
}
}
},
"Feedback History" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Feedback History"
}
}
}
},
"Fresh Stories" : { "Fresh Stories" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -201,6 +267,17 @@
} }
} }
}, },
"Get Started" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Get Started"
}
}
}
},
"Help Center" : { "Help Center" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -223,6 +300,28 @@
} }
} }
}, },
"kApnsAlertContent" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Get alerts for new episodes and exclusive offers."
}
}
}
},
"kApnsAlertTitle" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Turn on Notifications"
}
}
}
},
"kCoinTipText" : { "kCoinTipText" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -234,6 +333,17 @@
} }
} }
}, },
"kLoginAgreementTipText" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "By logging in you agree to: #1# & #2#"
}
}
}
},
"kNormalRmptyDetail" : { "kNormalRmptyDetail" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -333,6 +443,50 @@
} }
} }
}, },
"Later" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Later"
}
}
}
},
"Log in" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Log in"
}
}
}
},
"Log out" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Log out"
}
}
}
},
"Login with Facebook" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Login with Facebook"
}
}
}
},
"month" : { "month" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -366,6 +520,17 @@
} }
} }
}, },
"My Wallet" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "My Wallet"
}
}
}
},
"New Releases" : { "New Releases" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -377,6 +542,28 @@
} }
} }
}, },
"Order Record" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Order Record"
}
}
}
},
"Order Records" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Order Records"
}
}
}
},
"Popular Picks" : { "Popular Picks" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -410,6 +597,17 @@
} }
} }
}, },
"Recharge" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Recharge"
}
}
}
},
"Remove" : { "Remove" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -421,6 +619,17 @@
} }
} }
}, },
"Reward Coins" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Reward Coins"
}
}
}
},
"Rewards" : { "Rewards" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -509,6 +718,17 @@
} }
} }
}, },
"Total Coins" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Total Coins"
}
}
}
},
"Unlock More" : { "Unlock More" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -597,6 +817,17 @@
} }
} }
}, },
"Welcome to BeeReel" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Welcome to BeeReel"
}
}
}
},
"year" : { "year" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {

View File

@ -31,5 +31,7 @@ target 'BeeReel' do
pod 'HWPanModal' #底部弹出控制器 pod 'HWPanModal' #底部弹出控制器
pod 'FDFullscreenPopGesture' #全屏手势返回 pod 'FDFullscreenPopGesture' #全屏手势返回
pod 'LYEmptyView' pod 'LYEmptyView'
pod 'ZLPhotoBrowser' #相册
pod 'Adjust' # Adjust
end end