diff --git a/BeeReel.xcodeproj/project.pbxproj b/BeeReel.xcodeproj/project.pbxproj index d4fed8e..cf09808 100644 --- a/BeeReel.xcodeproj/project.pbxproj +++ b/BeeReel.xcodeproj/project.pbxproj @@ -175,7 +175,36 @@ F398554E2E34699F00E2D28D /* BRVideoLockView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398554D2E34699F00E2D28D /* BRVideoLockView.swift */; }; F39855502E34782200E2D28D /* BRVideoUnlockModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398554F2E34782200E2D28D /* BRVideoUnlockModel.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 */ /* Begin PBXFileReference section */ @@ -362,7 +391,35 @@ F398554D2E34699F00E2D28D /* BRVideoLockView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoLockView.swift; sourceTree = ""; }; F398554F2E34782200E2D28D /* BRVideoUnlockModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoUnlockModel.swift; sourceTree = ""; }; F39855512E347BDE00E2D28D /* BRVideoRechargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVideoRechargeView.swift; sourceTree = ""; }; - F39855532E34A49500E2D28D /* VPPayDataRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPPayDataRequest.swift; sourceTree = ""; }; + F39855532E34A49500E2D28D /* BRPayDataRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPayDataRequest.swift; sourceTree = ""; }; + F39855552E34BD6000E2D28D /* BRWalletViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWalletViewController.swift; sourceTree = ""; }; + F39855572E34CA2C00E2D28D /* BROrderRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BROrderRecordViewController.swift; sourceTree = ""; }; + F39855592E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRCoinOrderRecordViewController.swift; sourceTree = ""; }; + F398555B2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRCoinOrderRecordCell.swift; sourceTree = ""; }; + F398555D2E37040D00E2D28D /* BRVipOrderRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVipOrderRecordViewController.swift; sourceTree = ""; }; + F398555F2E37046100E2D28D /* BRVipOrderRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVipOrderRecordCell.swift; sourceTree = ""; }; + F39855612E3705E700E2D28D /* BRConsumptionRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRConsumptionRecordViewController.swift; sourceTree = ""; }; + F39855632E37065200E2D28D /* BRConsumptionRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRConsumptionRecordCell.swift; sourceTree = ""; }; + F39855652E37083100E2D28D /* BRRewardCoinsRecordViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRRewardCoinsRecordViewController.swift; sourceTree = ""; }; + F39855672E37087500E2D28D /* BRRewardCoinsRecordCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRRewardCoinsRecordCell.swift; sourceTree = ""; }; + F39855692E3709C500E2D28D /* BRWalletHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWalletHeaderView.swift; sourceTree = ""; }; + F398556B2E3717A500E2D28D /* BRWalletHeaderItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWalletHeaderItemView.swift; sourceTree = ""; }; + F398556D2E3743FC00E2D28D /* BRLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRLoginView.swift; sourceTree = ""; }; + F398556F2E374BD800E2D28D /* BRLoginButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRLoginButton.swift; sourceTree = ""; }; + F39855712E3758F800E2D28D /* BRLoginManager+Apple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BRLoginManager+Apple.swift"; sourceTree = ""; }; + F39855732E3759C600E2D28D /* BRThirdSignModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRThirdSignModel.swift; sourceTree = ""; }; + F39855752E375DA600E2D28D /* BRAppWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAppWebViewController.swift; sourceTree = ""; }; + F39855772E375E6B00E2D28D /* Dictionary+BRAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+BRAdd.swift"; sourceTree = ""; }; + F39855792E3761D300E2D28D /* BRWebViewController+Script.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BRWebViewController+Script.swift"; sourceTree = ""; }; + F398557B2E37635400E2D28D /* BRWebScriptModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWebScriptModel.swift; sourceTree = ""; }; + F398557D2E37669F00E2D28D /* BRStatAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRStatAPI.swift; sourceTree = ""; }; + F398557F2E376B4500E2D28D /* SceneDelegate+Open.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SceneDelegate+Open.swift"; sourceTree = ""; }; + F39855812E376CB000E2D28D /* BROpenAppModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BROpenAppModel.swift; sourceTree = ""; }; + F39855832E37704600E2D28D /* AppDelegate+Thirdparty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Thirdparty.swift"; sourceTree = ""; }; + F39855852E37724000E2D28D /* AppDelegate+APNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+APNS.swift"; sourceTree = ""; }; + F39855882E37732600E2D28D /* BRGuideViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRGuideViewController.swift; sourceTree = ""; }; + F398558A2E37792200E2D28D /* Date+BRAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Date+BRAdd.swift"; sourceTree = ""; }; + F398558F2E37861D00E2D28D /* BRSettingAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRSettingAPI.swift; sourceTree = ""; }; 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 = ""; }; /* End PBXFileReference section */ @@ -371,6 +428,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + F398558E2E37857D00E2D28D /* FirebaseMessaging in Frameworks */, 440A41A6E6A22A02807AE759 /* Pods_BeeReel.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -475,6 +533,9 @@ children = ( BF02B81D2E2F99D900172177 /* BRWebView.swift */, BF02B81F2E2F9B1000172177 /* BRWebViewController.swift */, + F39855752E375DA600E2D28D /* BRAppWebViewController.swift */, + F39855792E3761D300E2D28D /* BRWebViewController+Script.swift */, + F398557B2E37635400E2D28D /* BRWebScriptModel.swift */, ); path = WebView; sourceTree = ""; @@ -611,6 +672,9 @@ children = ( BF692AE12E0A475D00A5C2DA /* AppDelegate.swift */, BF692AE82E0A475D00A5C2DA /* SceneDelegate.swift */, + F39855832E37704600E2D28D /* AppDelegate+Thirdparty.swift */, + F39855852E37724000E2D28D /* AppDelegate+APNS.swift */, + F398557F2E376B4500E2D28D /* SceneDelegate+Open.swift */, BF692B662E0BC6BC00A5C2DA /* AppDelegate+BRConfig.swift */, ); path = Delegate; @@ -640,6 +704,7 @@ BF3338ED2E15566C00B10F76 /* Explore */, BF692B682E0BC78C00A5C2DA /* Home */, BF692B4A2E0AA84C00A5C2DA /* Player */, + F39855872E3772F600E2D28D /* Guide */, ); path = Class; sourceTree = ""; @@ -691,8 +756,12 @@ BF692B022E0A769C00A5C2DA /* Login */ = { isa = PBXGroup; children = ( + F398556D2E3743FC00E2D28D /* BRLoginView.swift */, + F398556F2E374BD800E2D28D /* BRLoginButton.swift */, BF692B032E0A76D200A5C2DA /* BRLoginManager.swift */, + F39855712E3758F800E2D28D /* BRLoginManager+Apple.swift */, BF692B082E0A775500A5C2DA /* BRLoginToken.swift */, + F39855732E3759C600E2D28D /* BRThirdSignModel.swift */, ); path = Login; sourceTree = ""; @@ -702,6 +771,7 @@ children = ( BF692B062E0A771C00A5C2DA /* BRModel.swift */, BF692B742E0D39D000A5C2DA /* BRListModel.swift */, + F39855812E376CB000E2D28D /* BROpenAppModel.swift */, ); path = Model; sourceTree = ""; @@ -709,6 +779,8 @@ BF692B0C2E0A7A9A00A5C2DA /* Extension */ = { isa = PBXGroup; children = ( + F398558A2E37792200E2D28D /* Date+BRAdd.swift */, + F39855772E375E6B00E2D28D /* Dictionary+BRAdd.swift */, BF3338FA2E161CF000B10F76 /* NSNumber+BRAdd.swift */, BF3338E72E15218F00B10F76 /* UINavigationBar+BRAdd.swift */, BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */, @@ -934,6 +1006,8 @@ BF692B712E0D395300A5C2DA /* API */ = { isa = PBXGroup; children = ( + F398558F2E37861D00E2D28D /* BRSettingAPI.swift */, + F398557D2E37669F00E2D28D /* BRStatAPI.swift */, F398553A2E336C4F00E2D28D /* BRStoreAPI.swift */, BFC676882E122FDB006659E5 /* BRVideoAPI.swift */, BFC676682E0E34D9006659E5 /* BRUserAPI.swift */, @@ -1063,6 +1137,12 @@ isa = PBXGroup; children = ( F39855362E33699900E2D28D /* BRStoreViewController.swift */, + F39855552E34BD6000E2D28D /* BRWalletViewController.swift */, + F39855572E34CA2C00E2D28D /* BROrderRecordViewController.swift */, + F39855592E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift */, + F398555D2E37040D00E2D28D /* BRVipOrderRecordViewController.swift */, + F39855612E3705E700E2D28D /* BRConsumptionRecordViewController.swift */, + F39855652E37083100E2D28D /* BRRewardCoinsRecordViewController.swift */, ); path = Controller; sourceTree = ""; @@ -1076,6 +1156,12 @@ F39855492E33929C00E2D28D /* BRStoreCoinCell.swift */, F39855472E33928400E2D28D /* BRStoreCoinBigCell.swift */, F398554B2E3392C200E2D28D /* BRStoreCoinSmallCell.swift */, + F398555B2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift */, + F398555F2E37046100E2D28D /* BRVipOrderRecordCell.swift */, + F39855632E37065200E2D28D /* BRConsumptionRecordCell.swift */, + F39855672E37087500E2D28D /* BRRewardCoinsRecordCell.swift */, + F39855692E3709C500E2D28D /* BRWalletHeaderView.swift */, + F398556B2E3717A500E2D28D /* BRWalletHeaderItemView.swift */, ); path = View; sourceTree = ""; @@ -1084,11 +1170,19 @@ isa = PBXGroup; children = ( F398553D2E336D3000E2D28D /* BRPayDateModel.swift */, - F39855532E34A49500E2D28D /* VPPayDataRequest.swift */, + F39855532E34A49500E2D28D /* BRPayDataRequest.swift */, ); path = Model; sourceTree = ""; }; + F39855872E3772F600E2D28D /* Guide */ = { + isa = PBXGroup; + children = ( + F39855882E37732600E2D28D /* BRGuideViewController.swift */, + ); + path = Guide; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -1135,6 +1229,9 @@ ); mainGroup = BF692AC02E0A475500A5C2DA; minimizedProjectReferenceProxies = 1; + packageReferences = ( + F398558C2E37857D00E2D28D /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */, + ); preferredProjectObjectVersion = 77; productRefGroup = BF692ACA2E0A475500A5C2DA /* Products */; projectDirPath = ""; @@ -1218,23 +1315,27 @@ F39855332E33629000E2D28D /* BRMineStoreItemView.swift in Sources */, BFC676B12E137D2F006659E5 /* BRPopularPicksViewController.swift in Sources */, BF02B7FC2E2F262F00172177 /* BRGradientView.swift in Sources */, + F398557A2E3761DB00E2D28D /* BRWebViewController+Script.swift in Sources */, BFC676692E0E34DA006659E5 /* BRUserAPI.swift in Sources */, F398554E2E34699F00E2D28D /* BRVideoLockView.swift in Sources */, + F39855642E37065200E2D28D /* BRConsumptionRecordCell.swift in Sources */, BFC676782E0E9553006659E5 /* BRSpotlightMainBaseCell.swift in Sources */, BFC676732E0E938B006659E5 /* BRTableView.swift in Sources */, BFC676932E126A62006659E5 /* BRSpotlightNewMainCell.swift in Sources */, BFC6768D2E123D6E006659E5 /* AttributedString+BRAdd.swift in Sources */, BF02B8392E30B30400172177 /* AlignedCollectionViewFlowLayout.swift in Sources */, BF3A56882E30E0DD009E5CF9 /* BREmpty.swift in Sources */, - F39855542E34A49500E2D28D /* VPPayDataRequest.swift in Sources */, + F39855542E34A49500E2D28D /* BRPayDataRequest.swift in Sources */, BF3338F52E1616B200B10F76 /* BRExploreControlView.swift in Sources */, F398552D2E33126D00E2D28D /* BRMineCoinItemView.swift in Sources */, BF692B132E0A7B9000A5C2DA /* BRUserInfo.swift in Sources */, BF692B042E0A76D200A5C2DA /* BRLoginManager.swift in Sources */, BFC6769D2E129794006659E5 /* BRHomeTop10ViewController.swift in Sources */, + F398556C2E3717A500E2D28D /* BRWalletHeaderItemView.swift in Sources */, BF02B80D2E2F63ED00172177 /* BRFavoritesCell.swift in Sources */, BF692AEB2E0A475D00A5C2DA /* AppDelegate.swift in Sources */, F39855372E33699900E2D28D /* BRStoreViewController.swift in Sources */, + F39855622E3705E700E2D28D /* BRConsumptionRecordViewController.swift in Sources */, BF02B81B2E2F8FDF00172177 /* BRMineUserInfoCell.swift in Sources */, F398554C2E3392C200E2D28D /* BRStoreCoinSmallCell.swift in Sources */, BF02B8202E2F9B1000172177 /* BRWebViewController.swift in Sources */, @@ -1249,23 +1350,29 @@ F39855292E322B1800E2D28D /* BRAlertWindowManager.swift in Sources */, BF02B82D2E30855300172177 /* BRSearchTextView.swift in Sources */, F398552B2E322C7C00E2D28D /* BRAlert.swift in Sources */, + F39855742E3759C600E2D28D /* BRThirdSignModel.swift in Sources */, BF692B472E0A9B7900A5C2DA /* BRPlayer.swift in Sources */, BF692B6E2E0BD4CB00A5C2DA /* BRHomeHeaderView.swift in Sources */, BF692AFA2E0A6F0900A5C2DA /* BRNetwork.swift in Sources */, BF02B7E52E2E1E6100172177 /* BREpisodeSelectorView.swift in Sources */, + F39855662E37083100E2D28D /* BRRewardCoinsRecordViewController.swift in Sources */, BF692B6B2E0BC85300A5C2DA /* BRHomeViewController.swift in Sources */, BF692B7C2E0D3C1300A5C2DA /* BRVideoInfoModel.swift in Sources */, + F39855702E374BD800E2D28D /* BRLoginButton.swift in Sources */, BFC6766D2E0E3A8D006659E5 /* BRImageView.swift in Sources */, BF02B7ED2E2E390500172177 /* BRScrollView.swift in Sources */, + F39855562E34BD6000E2D28D /* BRWalletViewController.swift in Sources */, BF3A56812E30C08F009E5CF9 /* BRHotSearchTagCell.swift in Sources */, BF02B8132E2F83C200172177 /* BRMineViewController.swift in Sources */, BF02B8222E2FAB1600172177 /* BRAboutUsViewController.swift in Sources */, BFC6766F2E0E3B5C006659E5 /* UIImageView+BRAdd.swift in Sources */, BF692B782E0D3A1200A5C2DA /* BRHomeModuleItem.swift in Sources */, BF692B5A2E0AAADD00A5C2DA /* BRPlayerListCell.swift in Sources */, + F398555C2E34DCB000E2D28D /* BRCoinOrderRecordCell.swift in Sources */, BF02B8312E30897700172177 /* BRSearchHomeView.swift in Sources */, F39855502E34782200E2D28D /* BRVideoUnlockModel.swift in Sources */, F398554A2E33929C00E2D28D /* BRStoreCoinCell.swift in Sources */, + F39855842E37705700E2D28D /* AppDelegate+Thirdparty.swift in Sources */, BF3A568C2E30EBA2009E5CF9 /* BRHomePlayRecordButton.swift in Sources */, BF692B162E0A7CD600A5C2DA /* BRHUD.swift in Sources */, BF3338F72E16176900B10F76 /* BRDetailPlayerCell.swift in Sources */, @@ -1279,14 +1386,17 @@ BFC676852E122D9E006659E5 /* BRVideoDetailViewController.swift in Sources */, BFC676912E126248006659E5 /* BRSpotlightTopCell.swift in Sources */, BFC676B72E137DFC006659E5 /* BRPopularPicksCell.swift in Sources */, + F398556A2E3709C500E2D28D /* BRWalletHeaderView.swift in Sources */, BF692B422E0A8FB500A5C2DA /* UIFont+BRAdd.swift in Sources */, BF02B8362E30ACEE00172177 /* BRSearchViewModel.swift in Sources */, + F39855762E375DA600E2D28D /* BRAppWebViewController.swift in Sources */, BF692AEC2E0A475D00A5C2DA /* SceneDelegate.swift in Sources */, BF692B492E0A9D0E00A5C2DA /* UIView+BRAdd.swift in Sources */, BF02B7F82E2F211A00172177 /* BRHomeCategoriesMainCell.swift in Sources */, BF02B8192E2F8B1100172177 /* BRMineCell.swift in Sources */, BFC676812E122733006659E5 /* BRPlayerProtocol.swift in Sources */, BFC676BC2E138ABB006659E5 /* BRNewReleasesViewController.swift in Sources */, + F39855602E37046100E2D28D /* BRVipOrderRecordCell.swift in Sources */, BF692B5F2E0B812800A5C2DA /* BRTabBarItemContainer.swift in Sources */, BF3338EC2E154BFE00B10F76 /* BRPlayerControlView.swift in Sources */, BF692B652E0BC53900A5C2DA /* CGMutablePath+BRRoundedCorner.swift in Sources */, @@ -1302,12 +1412,17 @@ F39855312E33620200E2D28D /* BRMineStoreCell.swift in Sources */, BF692B182E0A7D8900A5C2DA /* BRToast.swift in Sources */, BF692B0E2E0A7AF300A5C2DA /* UserDefaults+BRAdd.swift in Sources */, + F39855682E37087500E2D28D /* BRRewardCoinsRecordCell.swift in Sources */, + F398555A2E34DA0A00E2D28D /* BRCoinOrderRecordViewController.swift in Sources */, F39855522E347BDE00E2D28D /* BRVideoRechargeView.swift in Sources */, BF02B8082E2F616E00172177 /* BRFavoritesViewController.swift in Sources */, BF3338FD2E1626B000B10F76 /* BRPlayerControlProtocol.swift in Sources */, BF692B582E0AAA6F00A5C2DA /* UIScreen+BRAdd.swift in Sources */, + F398555E2E37040D00E2D28D /* BRVipOrderRecordViewController.swift in Sources */, BF692B1F2E0A804600A5C2DA /* BRLocalizedManager.swift in Sources */, + F39855862E37724800E2D28D /* AppDelegate+APNS.swift in Sources */, F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */, + F398557C2E37635400E2D28D /* BRWebScriptModel.swift in Sources */, BF02B7E92E2E29E900172177 /* BREpisodeSelectorCell.swift in Sources */, F39855462E338FDA00E2D28D /* BRStoreCoinView.swift in Sources */, F398553B2E336C5700E2D28D /* BRStoreAPI.swift in Sources */, @@ -1318,10 +1433,14 @@ BF692B012E0A74A200A5C2DA /* BRDefine.swift in Sources */, BFC6767B2E0E973B006659E5 /* UIStackView+BRAdd.swift in Sources */, BF3338F32E16169A00B10F76 /* BRExplorePlayerCell.swift in Sources */, + F398556E2E3743FC00E2D28D /* BRLoginView.swift in Sources */, + F398558B2E37792700E2D28D /* Date+BRAdd.swift in Sources */, BF3338F92E16178700B10F76 /* BRDetailControlView.swift in Sources */, BFC676AB2E1372BD006659E5 /* BRHomeTop3Cell.swift in Sources */, BFC676892E122FDD006659E5 /* BRVideoAPI.swift in Sources */, BFC6769B2E1285C5006659E5 /* BRPagerViewTransformer.swift in Sources */, + F39855892E37732600E2D28D /* BRGuideViewController.swift in Sources */, + F39855782E375E7000E2D28D /* Dictionary+BRAdd.swift in Sources */, BFC676832E122CC5006659E5 /* BRPlayerViewModel.swift in Sources */, BF02B7EF2E2E4BFD00172177 /* BRRateModel.swift in Sources */, BF692B672E0BC6C700A5C2DA /* AppDelegate+BRConfig.swift in Sources */, @@ -1341,9 +1460,11 @@ BFC676642E0E2C8E006659E5 /* WMZBannerFlowLayout.m in Sources */, BF02B81E2E2F99D900172177 /* BRWebView.swift in Sources */, BFC676652E0E2C8E006659E5 /* WMZBannerControl.m in Sources */, + F39855722E3758F800E2D28D /* BRLoginManager+Apple.swift in Sources */, BFC676972E127D3C006659E5 /* BRSpotlightRecommandMainCell.swift in Sources */, BFC6767F2E121A72006659E5 /* BRSpotlightHotCell.swift in Sources */, BFC6767D2E0E9809006659E5 /* BRSpotlightHotMainCell.swift in Sources */, + F39855802E376B4900E2D28D /* SceneDelegate+Open.swift in Sources */, BF02B7EB2E2E388800172177 /* BREpisodeMenuView.swift in Sources */, BF02B8042E2F5B4B00172177 /* BRCategorieShortCell.swift in Sources */, BFC676662E0E2C8E006659E5 /* WMZBannerFadeLayout.m in Sources */, @@ -1352,6 +1473,7 @@ BFC676672E0E2C8E006659E5 /* WMZBannerParam.m in Sources */, BF692B732E0D397700A5C2DA /* BRHomeAPI.swift in Sources */, BF692B7A2E0D3BD300A5C2DA /* BRShortModel.swift in Sources */, + F39855822E376CB000E2D28D /* BROpenAppModel.swift in Sources */, BFC676712E0E9234006659E5 /* BRSpotlightViewViewController.swift in Sources */, BF3338F02E15569600B10F76 /* BRExploreViewController.swift in Sources */, BF0DBDD12E0D4E150035F6B4 /* BRTabBar.swift in Sources */, @@ -1363,17 +1485,20 @@ BF692B752E0D39D000A5C2DA /* BRListModel.swift in Sources */, BF02B8172E2F881200172177 /* BRMineItem.swift in Sources */, BFC676B92E1385FC006659E5 /* BRPopularPicksSmallCell.swift in Sources */, + F39855582E34CA2C00E2D28D /* BROrderRecordViewController.swift in Sources */, BF692B512E0AA8C600A5C2DA /* BRPlayerListViewController.swift in Sources */, BF02B8282E30821B00172177 /* BRSearchViewController.swift in Sources */, F39855422E3374B500E2D28D /* BRStoreVipCell.swift in Sources */, BFC676522E0D4EFD006659E5 /* BRHomeViewModel.swift in Sources */, BFC676A72E12AF04006659E5 /* WaterfallMutiSectionFlowLayout.swift in Sources */, F398552F2E33179800E2D28D /* BRMineVipCell.swift in Sources */, + F39855902E37862200E2D28D /* BRSettingAPI.swift in Sources */, BF692B2A2E0A84F700A5C2DA /* JXUUID.m in Sources */, BF692B2B2E0A84F700A5C2DA /* PDKeyChain.m in Sources */, BF3A56852E30CA78009E5CF9 /* BRSearchResultCell.swift in Sources */, BF02B7FA2E2F225D00172177 /* BRHomeCategoryModel.swift in Sources */, BFC6766B2E0E395F006659E5 /* BRHomeHeaderBannerCell.swift in Sources */, + F398557E2E3766A300E2D28D /* BRStatAPI.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1405,6 +1530,9 @@ INFOPLIST_FILE = BeeReel/Sources/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = BeeReel; 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_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = ""; @@ -1441,6 +1569,9 @@ INFOPLIST_FILE = BeeReel/Sources/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = BeeReel; 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_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = ""; @@ -1608,6 +1739,25 @@ defaultConfigurationName = Release; }; /* 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 */; } diff --git a/BeeReel/Base/Controller/BRTabBarController.swift b/BeeReel/Base/Controller/BRTabBarController.swift index 15fa39c..abcecdf 100644 --- a/BeeReel/Base/Controller/BRTabBarController.swift +++ b/BeeReel/Base/Controller/BRTabBarController.swift @@ -53,6 +53,11 @@ class BRTabBarController: UITabBarController { br_setup() + + ///授权idfa + BRAppTool.requestIDFAAuthorization { idfa in + + } } diff --git a/BeeReel/Base/Define/BRUserDefaultsKey.swift b/BeeReel/Base/Define/BRUserDefaultsKey.swift index fdfc5f7..6d3a5fe 100644 --- a/BeeReel/Base/Define/BRUserDefaultsKey.swift +++ b/BeeReel/Base/Define/BRUserDefaultsKey.swift @@ -15,3 +15,7 @@ let kBRLoginUserInfoDefaultsKey = "kBRLoginUserInfoDefaultsKey" ///分辨率 let kBRVideoRevolutionDefaultsKey = "kBRVideoRevolutionDefaultsKey" +///是否开启过APP +let kBRHasBeenOpenedAPPDefaultsKey = "kBRHasBeenOpenedAPPDefaultsKey" + +let kBRApnsAlertDefaultsKey = "kBRApnsAlertDefaultsKey" diff --git a/BeeReel/Base/Extension/Date+BRAdd.swift b/BeeReel/Base/Extension/Date+BRAdd.swift new file mode 100644 index 0000000..01fa881 --- /dev/null +++ b/BeeReel/Base/Extension/Date+BRAdd.swift @@ -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) + } + } + +} diff --git a/BeeReel/Base/Extension/Dictionary+BRAdd.swift b/BeeReel/Base/Extension/Dictionary+BRAdd.swift new file mode 100644 index 0000000..5073e84 --- /dev/null +++ b/BeeReel/Base/Extension/Dictionary+BRAdd.swift @@ -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 + } + +} diff --git a/BeeReel/Base/Extension/String+BRAdd.swift b/BeeReel/Base/Extension/String+BRAdd.swift index 68e8b1d..967be53 100644 --- a/BeeReel/Base/Extension/String+BRAdd.swift +++ b/BeeReel/Base/Extension/String+BRAdd.swift @@ -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 + } +} diff --git a/BeeReel/Base/Extension/UIColor+BRAdd.swift b/BeeReel/Base/Extension/UIColor+BRAdd.swift index 439b2cb..112bd4e 100644 --- a/BeeReel/Base/Extension/UIColor+BRAdd.swift +++ b/BeeReel/Base/Extension/UIColor+BRAdd.swift @@ -190,4 +190,20 @@ extension UIColor { static func colorB5B5B5(alpha: CGFloat = 1) -> UIColor { 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) + } } diff --git a/BeeReel/Base/Model/BROpenAppModel.swift b/BeeReel/Base/Model/BROpenAppModel.swift new file mode 100644 index 0000000..d9598e9 --- /dev/null +++ b/BeeReel/Base/Model/BROpenAppModel.swift @@ -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? +} diff --git a/BeeReel/Base/Network/API/BRSettingAPI.swift b/BeeReel/Base/Network/API/BRSettingAPI.swift new file mode 100644 index 0000000..1d7414e --- /dev/null +++ b/BeeReel/Base/Network/API/BRSettingAPI.swift @@ -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) in + + } + } +} diff --git a/BeeReel/Base/Network/API/BRStatAPI.swift b/BeeReel/Base/Network/API/BRStatAPI.swift new file mode 100644 index 0000000..91ad0e6 --- /dev/null +++ b/BeeReel/Base/Network/API/BRStatAPI.swift @@ -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) in } + } + + ///离开APP + static func requestLeaveApp() { + var param = BRNetworkParameters(path: "/customer/leaveApp") + param.isToast = false + param.isLoding = false + + BRNetwork.request(parameters: param) { (_: BRNetworkResponse) in } + } + + static func requestStatOnLine() { + var param = BRNetworkParameters(path: "/customer/onLine") + param.isToast = false + param.isLoding = false + + BRNetwork.request(parameters: param) { (_: BRNetworkResponse) 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) 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) 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) 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) + } + } + } +} diff --git a/BeeReel/Base/Network/API/BRUserAPI.swift b/BeeReel/Base/Network/API/BRUserAPI.swift index d70dcd4..7a0b95c 100644 --- a/BeeReel/Base/Network/API/BRUserAPI.swift +++ b/BeeReel/Base/Network/API/BRUserAPI.swift @@ -17,4 +17,15 @@ class BRUserAPI { 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) in + completer?(response.data) + } + } } diff --git a/BeeReel/Base/Network/Base/BRNetworkTarget.swift b/BeeReel/Base/Network/Base/BRNetworkTarget.swift index 3c6607c..8c03495 100644 --- a/BeeReel/Base/Network/Base/BRNetworkTarget.swift +++ b/BeeReel/Base/Network/Base/BRNetworkTarget.swift @@ -69,7 +69,7 @@ extension BRNetworkTarget: TargetType { let dic: [String : String] = [ "system-version" : kBROsVersion, "lang-key" : BRLocalizedManager.manager.currentLocalizedKey,//当前语言 - "time-zone" : self.timeZone(), //时区 + "time-zone" : BRNetworkTarget.timeZone(), //时区 "app-version" : kBRAPPVersion, "device-id" : JXUUID.uuid(), //设备id "brand" : "apple", //品牌 @@ -97,7 +97,7 @@ extension BRNetworkTarget { } } - func timeZone() -> String { + static func timeZone() -> String { let timeZone = NSTimeZone.local as NSTimeZone let timeZoneSecondsFromGMT = timeZone.secondsFromGMT / 3600 return String(format: "GMT+0%d:00", timeZoneSecondsFromGMT) diff --git a/BeeReel/Base/Network/Base/BRURLPath.swift b/BeeReel/Base/Network/Base/BRURLPath.swift index b78067a..4b43173 100644 --- a/BeeReel/Base/Network/Base/BRURLPath.swift +++ b/BeeReel/Base/Network/Base/BRURLPath.swift @@ -30,13 +30,13 @@ let kSBCivizatioConventionWebUrl = BRWebBaseURL + "/civizatio_convention" 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" /* diff --git a/BeeReel/Base/View/BRPanModalContentView.swift b/BeeReel/Base/View/BRPanModalContentView.swift index 3fdbc00..faaa3a3 100644 --- a/BeeReel/Base/View/BRPanModalContentView.swift +++ b/BeeReel/Base/View/BRPanModalContentView.swift @@ -59,15 +59,15 @@ class BRPanModalContentView: HWPanModalContentView { return config } - override func allowsDragToDismiss() -> Bool { - return false - } - ///点击空白处关闭 override func allowsTapBackgroundToDismiss() -> Bool { return true } + override func allowsDragToDismiss() -> Bool { + return false + } + override func allowsPullDownWhenShortState() -> Bool { return false } diff --git a/BeeReel/Base/WebView/BRAppWebViewController.swift b/BeeReel/Base/WebView/BRAppWebViewController.swift new file mode 100644 index 0000000..dad4e58 --- /dev/null +++ b/BeeReel/Base/WebView/BRAppWebViewController.swift @@ -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() + } + } + } + } + + } + +} diff --git a/BeeReel/Base/WebView/BRWebScriptModel.swift b/BeeReel/Base/WebView/BRWebScriptModel.swift new file mode 100644 index 0000000..1f80245 --- /dev/null +++ b/BeeReel/Base/WebView/BRWebScriptModel.swift @@ -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? + +} + diff --git a/BeeReel/Base/WebView/BRWebView.swift b/BeeReel/Base/WebView/BRWebView.swift index 23dfda3..78f0fff 100644 --- a/BeeReel/Base/WebView/BRWebView.swift +++ b/BeeReel/Base/WebView/BRWebView.swift @@ -33,7 +33,12 @@ class BRWebView: WKWebView { weak var delegate: BRWebViewDelegate? - private(set) var scriptMessageHandlerArray: [String] = [] + private(set) var scriptMessageHandlerArray: [String] = [ + kBRWebMessageAPP, + kBRWebMessageOpenFeedbackList, + kBRWebMessageOpenFeedbackDetail, + kBRWebMessageOpenPhotoPicker, + ] deinit { diff --git a/BeeReel/Base/WebView/BRWebViewController+Script.swift b/BeeReel/Base/WebView/BRWebViewController+Script.swift new file mode 100644 index 0000000..60f7b42 --- /dev/null +++ b/BeeReel/Base/WebView/BRWebViewController+Script.swift @@ -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) + } + +} diff --git a/BeeReel/Base/WebView/BRWebViewController.swift b/BeeReel/Base/WebView/BRWebViewController.swift index 1b74c76..c04110e 100644 --- a/BeeReel/Base/WebView/BRWebViewController.swift +++ b/BeeReel/Base/WebView/BRWebViewController.swift @@ -109,6 +109,6 @@ extension BRWebViewController: BRWebViewDelegate { } func br_userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { -// vp_webViewUserContentController(didReceive: message) + br_webViewUserContentController(didReceive: message) } } diff --git a/BeeReel/Class/Guide/BRGuideViewController.swift b/BeeReel/Class/Guide/BRGuideViewController.swift new file mode 100644 index 0000000..94c7927 --- /dev/null +++ b/BeeReel/Class/Guide/BRGuideViewController.swift @@ -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?() + } + + + + +} diff --git a/BeeReel/Class/Mine/Controller/BRMineViewController.swift b/BeeReel/Class/Mine/Controller/BRMineViewController.swift index 5622365..514f0b2 100644 --- a/BeeReel/Class/Mine/Controller/BRMineViewController.swift +++ b/BeeReel/Class/Mine/Controller/BRMineViewController.swift @@ -22,8 +22,9 @@ class BRMineViewController: BRViewController { 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: .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: .aboutUs, icon: UIImage(named: "mine_item_icon_04"), title: "About Us".localized, url: ""), ] @@ -149,6 +150,20 @@ extension BRMineViewController: UITableViewDelegate, UITableViewDataSource { let vc = BRAboutUsViewController() 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: break } diff --git a/BeeReel/Class/Mine/Model/BRMineItem.swift b/BeeReel/Class/Mine/Model/BRMineItem.swift index 716a928..d8e8b5a 100644 --- a/BeeReel/Class/Mine/Model/BRMineItem.swift +++ b/BeeReel/Class/Mine/Model/BRMineItem.swift @@ -16,6 +16,7 @@ class BRMineItem: BRModel { case aboutUs case vip case store + case order } var type: ItemType? diff --git a/BeeReel/Class/Mine/View/BRMineCoinItemView.swift b/BeeReel/Class/Mine/View/BRMineCoinItemView.swift index 7a9e2d1..499c007 100644 --- a/BeeReel/Class/Mine/View/BRMineCoinItemView.swift +++ b/BeeReel/Class/Mine/View/BRMineCoinItemView.swift @@ -7,7 +7,7 @@ import UIKit -class BRMineCoinItemView: UIView { +class BRMineCoinItemView: UIControl { var title: String? { didSet { diff --git a/BeeReel/Class/Mine/View/BRMineStoreCell.swift b/BeeReel/Class/Mine/View/BRMineStoreCell.swift index ceaef80..002341c 100644 --- a/BeeReel/Class/Mine/View/BRMineStoreCell.swift +++ b/BeeReel/Class/Mine/View/BRMineStoreCell.swift @@ -58,8 +58,8 @@ class BRMineStoreCell: BRTableViewCell { } @objc private func handleRewardsView() { - - + let vc = BRWalletViewController() + self.viewController?.navigationController?.pushViewController(vc, animated: true) } diff --git a/BeeReel/Class/Mine/View/BRMineUserInfoCell.swift b/BeeReel/Class/Mine/View/BRMineUserInfoCell.swift index ef510a0..ae570f5 100644 --- a/BeeReel/Class/Mine/View/BRMineUserInfoCell.swift +++ b/BeeReel/Class/Mine/View/BRMineUserInfoCell.swift @@ -19,6 +19,8 @@ class BRMineUserInfoCell: BRTableViewCell { coinView.coinCount = userInfo?.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() view.title = "Coins".localized view.coinCount = 0 + view.addTarget(self, action: #selector(handleCoinView), for: .touchUpInside) return view }() @@ -67,9 +70,37 @@ class BRMineUserInfoCell: BRTableViewCell { let view = BRMineCoinItemView() view.title = "Donate".localized view.coinCount = 0 + view.addTarget(self, action: #selector(handleCoinView), for: .touchUpInside) 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?) { super.init(style: style, reuseIdentifier: reuseIdentifier) @@ -80,6 +111,20 @@ class BRMineUserInfoCell: BRTableViewCell { 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 { @@ -92,6 +137,7 @@ extension BRMineUserInfoCell { contentView.addSubview(idLabel) contentView.addSubview(coinView) contentView.addSubview(donateView) +// contentView.addSubview(loginButton) avatarBgView.snp.makeConstraints { make in make.left.equalToSuperview() @@ -131,6 +177,13 @@ extension BRMineUserInfoCell { make.top.equalTo(coinView) 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) +// } } } diff --git a/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift b/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift index c7ba1d4..d6633f8 100644 --- a/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift +++ b/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift @@ -85,7 +85,11 @@ class BRVideoDetailViewController: BRPlayerListViewController { self.viewModel.openRechargeView() } } - + + override func handleNavBack() { + super.handleNavBack() + + } } extension BRVideoDetailViewController { diff --git a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift index 11f1630..908a31e 100644 --- a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift +++ b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift @@ -52,7 +52,7 @@ class BRPlayerViewModel: NSObject { } } - private lazy var payDataRequest = VPPayDataRequest() + private lazy var payDataRequest = BRPayDataRequest() } diff --git a/BeeReel/Class/Store/Controller/BRCoinOrderRecordViewController.swift b/BeeReel/Class/Store/Controller/BRCoinOrderRecordViewController.swift new file mode 100644 index 0000000..ff628c6 --- /dev/null +++ b/BeeReel/Class/Store/Controller/BRCoinOrderRecordViewController.swift @@ -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 + } + +} diff --git a/BeeReel/Class/Store/Controller/BRConsumptionRecordViewController.swift b/BeeReel/Class/Store/Controller/BRConsumptionRecordViewController.swift new file mode 100644 index 0000000..6e7f991 --- /dev/null +++ b/BeeReel/Class/Store/Controller/BRConsumptionRecordViewController.swift @@ -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 + } +} diff --git a/BeeReel/Class/Store/Controller/BROrderRecordViewController.swift b/BeeReel/Class/Store/Controller/BROrderRecordViewController.swift new file mode 100644 index 0000000..1a85102 --- /dev/null +++ b/BeeReel/Class/Store/Controller/BROrderRecordViewController.swift @@ -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 + + } + +} + + diff --git a/BeeReel/Class/Store/Controller/BRRewardCoinsRecordViewController.swift b/BeeReel/Class/Store/Controller/BRRewardCoinsRecordViewController.swift new file mode 100644 index 0000000..2d99046 --- /dev/null +++ b/BeeReel/Class/Store/Controller/BRRewardCoinsRecordViewController.swift @@ -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 + } +} diff --git a/BeeReel/Class/Store/Controller/BRStoreViewController.swift b/BeeReel/Class/Store/Controller/BRStoreViewController.swift index 99a9e11..69ecace 100644 --- a/BeeReel/Class/Store/Controller/BRStoreViewController.swift +++ b/BeeReel/Class/Store/Controller/BRStoreViewController.swift @@ -11,7 +11,7 @@ class BRStoreViewController: BRViewController { private var payData: BRPayDateModel? - private lazy var dataRequest = VPPayDataRequest() + private lazy var dataRequest = BRPayDataRequest() private lazy var scrollView: BRScrollView = { let scrollView = BRScrollView() diff --git a/BeeReel/Class/Store/Controller/BRVipOrderRecordViewController.swift b/BeeReel/Class/Store/Controller/BRVipOrderRecordViewController.swift new file mode 100644 index 0000000..da35c43 --- /dev/null +++ b/BeeReel/Class/Store/Controller/BRVipOrderRecordViewController.swift @@ -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 + } + +} + diff --git a/BeeReel/Class/Store/Controller/BRWalletViewController.swift b/BeeReel/Class/Store/Controller/BRWalletViewController.swift new file mode 100644 index 0000000..24c87f2 --- /dev/null +++ b/BeeReel/Class/Store/Controller/BRWalletViewController.swift @@ -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() + } + } + + } + +} diff --git a/BeeReel/Class/Store/Model/VPPayDataRequest.swift b/BeeReel/Class/Store/Model/BRPayDataRequest.swift similarity index 96% rename from BeeReel/Class/Store/Model/VPPayDataRequest.swift rename to BeeReel/Class/Store/Model/BRPayDataRequest.swift index 6dfa4ce..700922d 100644 --- a/BeeReel/Class/Store/Model/VPPayDataRequest.swift +++ b/BeeReel/Class/Store/Model/BRPayDataRequest.swift @@ -1,5 +1,5 @@ // -// VPPayDataRequest.swift +// BRPayDataRequest.swift // BeeReel // // Created by 长沙鸿瑶 on 2025/7/26. @@ -8,7 +8,7 @@ import UIKit import StoreKit -class VPPayDataRequest: NSObject { +class BRPayDataRequest: NSObject { private var oldTemplateModel: BRPayDateModel? @@ -67,7 +67,7 @@ class VPPayDataRequest: NSObject { /* //MARK: -------------- SKProductsRequestDelegate -------------- - extension VPPayTemplateRequest: SKProductsRequestDelegate { + extension BRPayDataRequest: SKProductsRequestDelegate { func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) { if isLoding { diff --git a/BeeReel/Class/Store/View/BRCoinOrderRecordCell.swift b/BeeReel/Class/Store/View/BRCoinOrderRecordCell.swift new file mode 100644 index 0000000..3ce4ea1 --- /dev/null +++ b/BeeReel/Class/Store/View/BRCoinOrderRecordCell.swift @@ -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) + } + + } + +} diff --git a/BeeReel/Class/Store/View/BRConsumptionRecordCell.swift b/BeeReel/Class/Store/View/BRConsumptionRecordCell.swift new file mode 100644 index 0000000..5ea4279 --- /dev/null +++ b/BeeReel/Class/Store/View/BRConsumptionRecordCell.swift @@ -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) + } + + } + +} diff --git a/BeeReel/Class/Store/View/BRRewardCoinsRecordCell.swift b/BeeReel/Class/Store/View/BRRewardCoinsRecordCell.swift new file mode 100644 index 0000000..2fc9e12 --- /dev/null +++ b/BeeReel/Class/Store/View/BRRewardCoinsRecordCell.swift @@ -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) + } + + } + +} diff --git a/BeeReel/Class/Store/View/BRVipOrderRecordCell.swift b/BeeReel/Class/Store/View/BRVipOrderRecordCell.swift new file mode 100644 index 0000000..660f268 --- /dev/null +++ b/BeeReel/Class/Store/View/BRVipOrderRecordCell.swift @@ -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) + } + + } + +} + diff --git a/BeeReel/Class/Store/View/BRWalletHeaderItemView.swift b/BeeReel/Class/Store/View/BRWalletHeaderItemView.swift new file mode 100644 index 0000000..8fd57d9 --- /dev/null +++ b/BeeReel/Class/Store/View/BRWalletHeaderItemView.swift @@ -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") + } + +} diff --git a/BeeReel/Class/Store/View/BRWalletHeaderView.swift b/BeeReel/Class/Store/View/BRWalletHeaderView.swift new file mode 100644 index 0000000..c06c898 --- /dev/null +++ b/BeeReel/Class/Store/View/BRWalletHeaderView.swift @@ -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) + } + + } + +} diff --git a/BeeReel/Delegate/AppDelegate+APNS.swift b/BeeReel/Delegate/AppDelegate+APNS.swift new file mode 100644 index 0000000..51daa40 --- /dev/null +++ b/BeeReel/Delegate/AppDelegate+APNS.swift @@ -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() + } + + +} + diff --git a/BeeReel/Delegate/AppDelegate+Thirdparty.swift b/BeeReel/Delegate/AppDelegate+Thirdparty.swift new file mode 100644 index 0000000..ecf3d24 --- /dev/null +++ b/BeeReel/Delegate/AppDelegate+Thirdparty.swift @@ -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) + } + } +} diff --git a/BeeReel/Delegate/AppDelegate.swift b/BeeReel/Delegate/AppDelegate.swift index 0c78747..5e1bd03 100644 --- a/BeeReel/Delegate/AppDelegate.swift +++ b/BeeReel/Delegate/AppDelegate.swift @@ -13,14 +13,18 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + registThirdparty(application, didFinishLaunchingWithOptions: launchOptions) BRAppTool.appDelegate = self BRNetworkStatusManager.manager.startMonitoring() + NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: BRNetworkStatusManager.networkStatusDidChangeNotification, object: nil) BRLoginManager.manager.updateUserInfo(completer: nil) addConfig() + requestAPNS() + return true } diff --git a/BeeReel/Delegate/SceneDelegate+Open.swift b/BeeReel/Delegate/SceneDelegate+Open.swift new file mode 100644 index 0000000..03a292b --- /dev/null +++ b/BeeReel/Delegate/SceneDelegate+Open.swift @@ -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) { + 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) + } +} diff --git a/BeeReel/Delegate/SceneDelegate.swift b/BeeReel/Delegate/SceneDelegate.swift index 5e5dae0..384744a 100644 --- a/BeeReel/Delegate/SceneDelegate.swift +++ b/BeeReel/Delegate/SceneDelegate.swift @@ -10,19 +10,30 @@ import UIKit class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? - + + private var onLineTimer: Timer? + + private(set) var isOpenApp = false func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } BRAppTool.sceneDelegate = self 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) - BRAppTool.tabBarController = BRTabBarController() - window?.rootViewController = BRAppTool.tabBarController + startApp() - window?.makeKeyAndVisible() } func sceneDidDisconnect(_ scene: UIScene) { @@ -33,26 +44,68 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { } func sceneDidBecomeActive(_ scene: UIScene) { - // Called when the scene has moved from an inactive state to an active state. - // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + BRStatAPI.requestStatOnLine() + BRStatAPI.requestEnterApp() } func sceneWillResignActive(_ scene: UIScene) { - // Called when the scene will move from an active state to an inactive state. - // This may occur due to temporary interruptions (ex. an incoming phone call). + BRStatAPI.requestLeaveApp() } func sceneWillEnterForeground(_ scene: UIScene) { - // Called as the scene transitions from the background to the foreground. - // Use this method to undo the changes made on entering the background. + BRStatAPI.uploadNoticeStatus() + + DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { + self.br_handleOpenAppMessage(webpageURL: nil) + } } func sceneDidEnterBackground(_ scene: UIScene) { - // Called as the scene transitions from the foreground to the background. - // Use this method to save data, release shared resources, and store enough scene-specific state information - // to restore the scene back to its current state. + SceneDelegate.allowOpenMessage = true } } +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() + + } + +} + diff --git a/BeeReel/Lib/Alert/BRAlert.swift b/BeeReel/Lib/Alert/BRAlert.swift index 9415ccb..f43c694 100644 --- a/BeeReel/Lib/Alert/BRAlert.swift +++ b/BeeReel/Lib/Alert/BRAlert.swift @@ -87,6 +87,8 @@ class BRAlert: BRBaseAlert { let stackView = UIStackView() stackView.axis = .vertical + stackView.alignment = .center + stackView.spacing = 6 if let image = image { let imageView = UIImageView(image: image) diff --git a/BeeReel/Lib/AppTool/BRAppTool.swift b/BeeReel/Lib/AppTool/BRAppTool.swift index 97127a8..bc67886 100644 --- a/BeeReel/Lib/AppTool/BRAppTool.swift +++ b/BeeReel/Lib/AppTool/BRAppTool.swift @@ -6,6 +6,8 @@ // import UIKit +import AppTrackingTransparency +import AdSupport 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) + } + } + } +} + diff --git a/BeeReel/Lib/Login/BRLoginButton.swift b/BeeReel/Lib/Login/BRLoginButton.swift new file mode 100644 index 0000000..86f52b5 --- /dev/null +++ b/BeeReel/Lib/Login/BRLoginButton.swift @@ -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") + } + +} diff --git a/BeeReel/Lib/Login/BRLoginManager+Apple.swift b/BeeReel/Lib/Login/BRLoginManager+Apple.swift new file mode 100644 index 0000000..0a37a8a --- /dev/null +++ b/BeeReel/Lib/Login/BRLoginManager+Apple.swift @@ -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 + } + +} diff --git a/BeeReel/Lib/Login/BRLoginManager.swift b/BeeReel/Lib/Login/BRLoginManager.swift index 58d0920..907d264 100644 --- a/BeeReel/Lib/Login/BRLoginManager.swift +++ b/BeeReel/Lib/Login/BRLoginManager.swift @@ -8,7 +8,7 @@ import UIKit import SmartCodable -class BRLoginManager { +class BRLoginManager: NSObject { enum LoginType: String, SmartCaseDefaultable { case apple = "Apple" @@ -33,6 +33,24 @@ class BRLoginManager { 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)?) { @@ -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 { ///用户信息更新 @objc static let userInfoUpdateNotification = NSNotification.Name(rawValue: "BRLoginManager.userInfoUpdateNotification") + ///登录状态发生变化 + @objc static let loginStateDidChangeNotification = NSNotification.Name(rawValue: "BRLoginManager.loginStateDidChangeNotification") } diff --git a/BeeReel/Lib/Login/BRLoginView.swift b/BeeReel/Lib/Login/BRLoginView.swift new file mode 100644 index 0000000..0dcbe3d --- /dev/null +++ b/BeeReel/Lib/Login/BRLoginView.swift @@ -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) { + + } +} diff --git a/BeeReel/Lib/Login/BRThirdSignModel.swift b/BeeReel/Lib/Login/BRThirdSignModel.swift new file mode 100644 index 0000000..1545c2e --- /dev/null +++ b/BeeReel/Lib/Login/BRThirdSignModel.swift @@ -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? +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Apple@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Apple@2x.png new file mode 100644 index 0000000..b69e7ca Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Apple@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Apple@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Apple@3x.png new file mode 100644 index 0000000..9604d3a Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Apple@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Contents.json new file mode 100644 index 0000000..e1641ae --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Apple.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Contents.json new file mode 100644 index 0000000..215149c --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Facebook@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Facebook@2x.png new file mode 100644 index 0000000..ac933e4 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Facebook@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Facebook@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Facebook@3x.png new file mode 100644 index 0000000..f073917 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Facebook.imageset/Facebook@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Frame@2x.png new file mode 100644 index 0000000..3925770 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Frame@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Frame@3x.png new file mode 100644 index 0000000..98f2d79 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Frame 7.imageset/Frame@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Frame@2x.png new file mode 100644 index 0000000..2bf3c93 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Frame@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Frame@3x.png new file mode 100644 index 0000000..7ea58ca Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Frame 8.imageset/Frame@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Contents.json new file mode 100644 index 0000000..3760e29 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Order Record@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Order Record@2x.png new file mode 100644 index 0000000..c94d666 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Order Record@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Order Record@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Order Record@3x.png new file mode 100644 index 0000000..9c81325 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Order Record 1.imageset/Order Record@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Contents.json new file mode 100644 index 0000000..3760e29 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Order Record@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Order Record@2x.png new file mode 100644 index 0000000..1607115 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Order Record@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Order Record@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Order Record@3x.png new file mode 100644 index 0000000..60581e7 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Order Record 2.imageset/Order Record@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Contents.json new file mode 100644 index 0000000..3760e29 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Order Record@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Order Record@2x.png new file mode 100644 index 0000000..5ed9689 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Order Record@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Order Record@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Order Record@3x.png new file mode 100644 index 0000000..6a2eedb Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Order Record.imageset/Order Record@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/Contents.json new file mode 100644 index 0000000..36577cc --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/bg@2x.png b/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/bg@2x.png new file mode 100644 index 0000000..b63b8ce Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/bg@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/bg@3x.png b/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/bg@3x.png new file mode 100644 index 0000000..ec19873 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/bg 2.imageset/bg@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/Contents.json new file mode 100644 index 0000000..36577cc --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/bg@2x.png b/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/bg@2x.png new file mode 100644 index 0000000..6c58fbf Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/bg@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/bg@3x.png b/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/bg@3x.png new file mode 100644 index 0000000..4210b41 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/bg 3.imageset/bg@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/Contents.json new file mode 100644 index 0000000..ef6097c --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/coins@2x.png b/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/coins@2x.png new file mode 100644 index 0000000..db8e268 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/coins@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/coins@3x.png b/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/coins@3x.png new file mode 100644 index 0000000..ffca864 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/coins 2.imageset/coins@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/Contents.json new file mode 100644 index 0000000..8cc1ccd --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/通知@2x.png b/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/通知@2x.png new file mode 100644 index 0000000..c3853d1 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/通知@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/通知@3x.png b/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/通知@3x.png new file mode 100644 index 0000000..b45da31 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/通知.imageset/通知@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/Contents.json new file mode 100644 index 0000000..b3858aa --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/Contents.json @@ -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 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/顶部bg@2x.png b/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/顶部bg@2x.png new file mode 100644 index 0000000..6aee0c2 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/顶部bg@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/顶部bg@3x.png b/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/顶部bg@3x.png new file mode 100644 index 0000000..661edeb Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/顶部bg.imageset/顶部bg@3x.png differ diff --git a/BeeReel/Sources/Info.plist b/BeeReel/Sources/Info.plist index a65a270..fd05924 100644 --- a/BeeReel/Sources/Info.plist +++ b/BeeReel/Sources/Info.plist @@ -2,6 +2,8 @@ + FirebaseAppDelegateProxyEnabled + UIAppFonts AaHouDiHei-Regular.ttf diff --git a/BeeReel/Sources/Localizable.xcstrings b/BeeReel/Sources/Localizable.xcstrings index 41e3dfe..35a2d59 100644 --- a/BeeReel/Sources/Localizable.xcstrings +++ b/BeeReel/Sources/Localizable.xcstrings @@ -34,6 +34,17 @@ } } }, + "Allow" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Allow" + } + } + } + }, "Balance: ## Coins" : { "extractionState" : "manual", "localizations" : { @@ -135,6 +146,17 @@ } } }, + "Consumption Records" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Consumption Records" + } + } + } + }, "Daily Check-In" : { "extractionState" : "manual", "localizations" : { @@ -146,6 +168,17 @@ } } }, + "Donate" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Donate" + } + } + } + }, "EP.##" : { "extractionState" : "manual", "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" : { "extractionState" : "manual", "localizations" : { @@ -201,6 +267,17 @@ } } }, + "Get Started" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Get Started" + } + } + } + }, "Help Center" : { "extractionState" : "manual", "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" : { "extractionState" : "manual", "localizations" : { @@ -234,6 +333,17 @@ } } }, + "kLoginAgreementTipText" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "By logging in you agree to: #1# & #2#" + } + } + } + }, "kNormalRmptyDetail" : { "extractionState" : "manual", "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" : { "extractionState" : "manual", "localizations" : { @@ -366,6 +520,17 @@ } } }, + "My Wallet" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "My Wallet" + } + } + } + }, "New Releases" : { "extractionState" : "manual", "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" : { "extractionState" : "manual", "localizations" : { @@ -410,6 +597,17 @@ } } }, + "Recharge" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Recharge" + } + } + } + }, "Remove" : { "extractionState" : "manual", "localizations" : { @@ -421,6 +619,17 @@ } } }, + "Reward Coins" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Reward Coins" + } + } + } + }, "Rewards" : { "extractionState" : "manual", "localizations" : { @@ -509,6 +718,17 @@ } } }, + "Total Coins" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Total Coins" + } + } + } + }, "Unlock More" : { "extractionState" : "manual", "localizations" : { @@ -597,6 +817,17 @@ } } }, + "Welcome to BeeReel" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Welcome to BeeReel" + } + } + } + }, "year" : { "extractionState" : "manual", "localizations" : { diff --git a/Podfile b/Podfile index da019dc..ad0104c 100644 --- a/Podfile +++ b/Podfile @@ -31,5 +31,7 @@ target 'BeeReel' do pod 'HWPanModal' #底部弹出控制器 pod 'FDFullscreenPopGesture' #全屏手势返回 pod 'LYEmptyView' + pod 'ZLPhotoBrowser' #相册 + pod 'Adjust' # Adjust end