diff --git a/BeeReel.xcodeproj/project.pbxproj b/BeeReel.xcodeproj/project.pbxproj index ad3a536..2ba7bd4 100644 --- a/BeeReel.xcodeproj/project.pbxproj +++ b/BeeReel.xcodeproj/project.pbxproj @@ -18,6 +18,25 @@ BF02B7EF2E2E4BFD00172177 /* BRRateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7EE2E2E4BFD00172177 /* BRRateModel.swift */; }; BF02B7F12E2E55E300172177 /* BRRateSelectorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7F02E2E55E300172177 /* BRRateSelectorView.swift */; }; BF02B7F32E2E571600172177 /* BRRateSelectorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7F22E2E571600172177 /* BRRateSelectorCell.swift */; }; + BF02B7F52E2F203D00172177 /* BRHomeCategoriesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7F42E2F203D00172177 /* BRHomeCategoriesViewController.swift */; }; + BF02B7F82E2F211A00172177 /* BRHomeCategoriesMainCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7F72E2F211A00172177 /* BRHomeCategoriesMainCell.swift */; }; + BF02B7FA2E2F225D00172177 /* BRHomeCategoryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7F92E2F225D00172177 /* BRHomeCategoryModel.swift */; }; + BF02B7FC2E2F262F00172177 /* BRGradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7FB2E2F262F00172177 /* BRGradientView.swift */; }; + BF02B7FF2E2F2F2900172177 /* BRHomeCategoriesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B7FD2E2F2F2900172177 /* BRHomeCategoriesCell.swift */; }; + BF02B8022E2F39FE00172177 /* BRCategorieShortViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8012E2F39FE00172177 /* BRCategorieShortViewController.swift */; }; + BF02B8042E2F5B4B00172177 /* BRCategorieShortCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8032E2F5B4B00172177 /* BRCategorieShortCell.swift */; }; + BF02B8082E2F616E00172177 /* BRFavoritesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8072E2F616E00172177 /* BRFavoritesViewController.swift */; }; + BF02B80D2E2F63ED00172177 /* BRFavoritesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B80C2E2F63ED00172177 /* BRFavoritesCell.swift */; }; + BF02B80F2E2F6EEA00172177 /* BRFavoritesHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B80E2E2F6EEA00172177 /* BRFavoritesHeaderView.swift */; }; + BF02B8132E2F83C200172177 /* BRMineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8122E2F83C200172177 /* BRMineViewController.swift */; }; + BF02B8172E2F881200172177 /* BRMineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8162E2F881200172177 /* BRMineItem.swift */; }; + BF02B8192E2F8B1100172177 /* BRMineCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8182E2F8B1100172177 /* BRMineCell.swift */; }; + BF02B81B2E2F8FDF00172177 /* BRMineUserInfoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B81A2E2F8FDF00172177 /* BRMineUserInfoCell.swift */; }; + BF02B81E2E2F99D900172177 /* BRWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B81D2E2F99D900172177 /* BRWebView.swift */; }; + BF02B8202E2F9B1000172177 /* BRWebViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B81F2E2F9B1000172177 /* BRWebViewController.swift */; }; + BF02B8222E2FAB1600172177 /* BRAboutUsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8212E2FAB1600172177 /* BRAboutUsViewController.swift */; }; + BF02B8242E2FAEB500172177 /* BRAboutUsCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8232E2FAEB500172177 /* BRAboutUsCell.swift */; }; + BF02B8262E2FB36A00172177 /* BRAboutUsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF02B8252E2FB36A00172177 /* BRAboutUsHeaderView.swift */; }; BF0DBDD12E0D4E150035F6B4 /* BRTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0DBDD02E0D4E150035F6B4 /* BRTabBar.swift */; }; BF3338E82E15219500B10F76 /* UINavigationBar+BRAdd.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3338E72E15218F00B10F76 /* UINavigationBar+BRAdd.swift */; }; BF3338EA2E152B8100B10F76 /* BRPlayerCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF3338E92E152B8100B10F76 /* BRPlayerCache.swift */; }; @@ -133,6 +152,25 @@ BF02B7EE2E2E4BFD00172177 /* BRRateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRRateModel.swift; sourceTree = ""; }; BF02B7F02E2E55E300172177 /* BRRateSelectorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRRateSelectorView.swift; sourceTree = ""; }; BF02B7F22E2E571600172177 /* BRRateSelectorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRRateSelectorCell.swift; sourceTree = ""; }; + BF02B7F42E2F203D00172177 /* BRHomeCategoriesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRHomeCategoriesViewController.swift; sourceTree = ""; }; + BF02B7F72E2F211A00172177 /* BRHomeCategoriesMainCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRHomeCategoriesMainCell.swift; sourceTree = ""; }; + BF02B7F92E2F225D00172177 /* BRHomeCategoryModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRHomeCategoryModel.swift; sourceTree = ""; }; + BF02B7FB2E2F262F00172177 /* BRGradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRGradientView.swift; sourceTree = ""; }; + BF02B7FD2E2F2F2900172177 /* BRHomeCategoriesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRHomeCategoriesCell.swift; sourceTree = ""; }; + BF02B8012E2F39FE00172177 /* BRCategorieShortViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRCategorieShortViewController.swift; sourceTree = ""; }; + BF02B8032E2F5B4B00172177 /* BRCategorieShortCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRCategorieShortCell.swift; sourceTree = ""; }; + BF02B8072E2F616E00172177 /* BRFavoritesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRFavoritesViewController.swift; sourceTree = ""; }; + BF02B80C2E2F63ED00172177 /* BRFavoritesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRFavoritesCell.swift; sourceTree = ""; }; + BF02B80E2E2F6EEA00172177 /* BRFavoritesHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRFavoritesHeaderView.swift; sourceTree = ""; }; + BF02B8122E2F83C200172177 /* BRMineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRMineViewController.swift; sourceTree = ""; }; + BF02B8162E2F881200172177 /* BRMineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRMineItem.swift; sourceTree = ""; }; + BF02B8182E2F8B1100172177 /* BRMineCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRMineCell.swift; sourceTree = ""; }; + BF02B81A2E2F8FDF00172177 /* BRMineUserInfoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRMineUserInfoCell.swift; sourceTree = ""; }; + BF02B81D2E2F99D900172177 /* BRWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWebView.swift; sourceTree = ""; }; + BF02B81F2E2F9B1000172177 /* BRWebViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRWebViewController.swift; sourceTree = ""; }; + BF02B8212E2FAB1600172177 /* BRAboutUsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAboutUsViewController.swift; sourceTree = ""; }; + BF02B8232E2FAEB500172177 /* BRAboutUsCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAboutUsCell.swift; sourceTree = ""; }; + BF02B8252E2FB36A00172177 /* BRAboutUsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRAboutUsHeaderView.swift; sourceTree = ""; }; BF0DBDD02E0D4E150035F6B4 /* BRTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRTabBar.swift; sourceTree = ""; }; BF3338E72E15218F00B10F76 /* UINavigationBar+BRAdd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationBar+BRAdd.swift"; sourceTree = ""; }; BF3338E92E152B8100B10F76 /* BRPlayerCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayerCache.swift; sourceTree = ""; }; @@ -273,6 +311,89 @@ path = Pods; sourceTree = ""; }; + BF02B7F62E2F20F900172177 /* Categories */ = { + isa = PBXGroup; + children = ( + BF02B8032E2F5B4B00172177 /* BRCategorieShortCell.swift */, + BF02B7F72E2F211A00172177 /* BRHomeCategoriesMainCell.swift */, + BF02B7FD2E2F2F2900172177 /* BRHomeCategoriesCell.swift */, + ); + path = Categories; + sourceTree = ""; + }; + BF02B8052E2F612200172177 /* Favorites */ = { + isa = PBXGroup; + children = ( + BF02B8062E2F613600172177 /* Controller */, + BF02B80B2E2F63C600172177 /* View */, + ); + path = Favorites; + sourceTree = ""; + }; + BF02B8062E2F613600172177 /* Controller */ = { + isa = PBXGroup; + children = ( + BF02B8072E2F616E00172177 /* BRFavoritesViewController.swift */, + ); + path = Controller; + sourceTree = ""; + }; + BF02B80B2E2F63C600172177 /* View */ = { + isa = PBXGroup; + children = ( + BF02B80C2E2F63ED00172177 /* BRFavoritesCell.swift */, + BF02B80E2E2F6EEA00172177 /* BRFavoritesHeaderView.swift */, + ); + path = View; + sourceTree = ""; + }; + BF02B8102E2F83A100172177 /* Mine */ = { + isa = PBXGroup; + children = ( + BF02B8112E2F83AA00172177 /* Controller */, + BF02B8142E2F87D800172177 /* View */, + BF02B8152E2F87E000172177 /* Model */, + ); + path = Mine; + sourceTree = ""; + }; + BF02B8112E2F83AA00172177 /* Controller */ = { + isa = PBXGroup; + children = ( + BF02B8122E2F83C200172177 /* BRMineViewController.swift */, + BF02B8212E2FAB1600172177 /* BRAboutUsViewController.swift */, + ); + path = Controller; + sourceTree = ""; + }; + BF02B8142E2F87D800172177 /* View */ = { + isa = PBXGroup; + children = ( + BF02B8182E2F8B1100172177 /* BRMineCell.swift */, + BF02B81A2E2F8FDF00172177 /* BRMineUserInfoCell.swift */, + BF02B8232E2FAEB500172177 /* BRAboutUsCell.swift */, + BF02B8252E2FB36A00172177 /* BRAboutUsHeaderView.swift */, + ); + path = View; + sourceTree = ""; + }; + BF02B8152E2F87E000172177 /* Model */ = { + isa = PBXGroup; + children = ( + BF02B8162E2F881200172177 /* BRMineItem.swift */, + ); + path = Model; + sourceTree = ""; + }; + BF02B81C2E2F996B00172177 /* WebView */ = { + isa = PBXGroup; + children = ( + BF02B81D2E2F99D900172177 /* BRWebView.swift */, + BF02B81F2E2F9B1000172177 /* BRWebViewController.swift */, + ); + path = WebView; + sourceTree = ""; + }; BF3338ED2E15566C00B10F76 /* Explore */ = { isa = PBXGroup; children = ( @@ -357,6 +478,7 @@ children = ( BF692B352E0A8AF200A5C2DA /* Controller */, BF692B522E0AA8D600A5C2DA /* View */, + BF02B81C2E2F996B00172177 /* WebView */, BF692B0C2E0A7A9A00A5C2DA /* Extension */, BF692B052E0A770F00A5C2DA /* Model */, BF692AFF2E0A748D00A5C2DA /* Define */, @@ -368,6 +490,8 @@ BF692AF52E0A47D400A5C2DA /* Class */ = { isa = PBXGroup; children = ( + BF02B8102E2F83A100172177 /* Mine */, + BF02B8052E2F612200172177 /* Favorites */, BF3338ED2E15566C00B10F76 /* Explore */, BF692B682E0BC78C00A5C2DA /* Home */, BF692B4A2E0AA84C00A5C2DA /* Player */, @@ -587,6 +711,7 @@ BFC676742E0E93B3006659E5 /* BRTableViewCell.swift */, BF02B7E62E2E1F0500172177 /* BRPanModalContentView.swift */, BF02B7EC2E2E390500172177 /* BRScrollView.swift */, + BF02B7FB2E2F262F00172177 /* BRGradientView.swift */, ); path = View; sourceTree = ""; @@ -621,6 +746,8 @@ BFC6769C2E129794006659E5 /* BRHomeTop10ViewController.swift */, BFC676B02E137D2F006659E5 /* BRPopularPicksViewController.swift */, BFC676BB2E138ABB006659E5 /* BRNewReleasesViewController.swift */, + BF02B7F42E2F203D00172177 /* BRHomeCategoriesViewController.swift */, + BF02B8012E2F39FE00172177 /* BRCategorieShortViewController.swift */, ); path = Controller; sourceTree = ""; @@ -628,6 +755,7 @@ BF692B6C2E0BD4B200A5C2DA /* View */ = { isa = PBXGroup; children = ( + BF02B7F62E2F20F900172177 /* Categories */, BFC676BA2E138A9A006659E5 /* NewReleases */, BFC676AC2E137687006659E5 /* PopularPicks */, BFC6769E2E129CE5006659E5 /* Top10 */, @@ -666,6 +794,7 @@ BF692B792E0D3BD300A5C2DA /* BRShortModel.swift */, BF692B7B2E0D3C1300A5C2DA /* BRVideoInfoModel.swift */, BFC6769A2E1285C5006659E5 /* BRPagerViewTransformer.swift */, + BF02B7F92E2F225D00172177 /* BRHomeCategoryModel.swift */, ); path = Model; sourceTree = ""; @@ -878,8 +1007,10 @@ BF02B7F32E2E571600172177 /* BRRateSelectorCell.swift in Sources */, BFC676992E1280E3006659E5 /* BRSpotlightRecommandCell.swift in Sources */, BFC676A42E129D60006659E5 /* BRHomeTop10Cell.swift in Sources */, + BF02B8262E2FB36A00172177 /* BRAboutUsHeaderView.swift in Sources */, BF692B3C2E0A8D0200A5C2DA /* BRNavigationController.swift in Sources */, BFC676B12E137D2F006659E5 /* BRPopularPicksViewController.swift in Sources */, + BF02B7FC2E2F262F00172177 /* BRGradientView.swift in Sources */, BFC676692E0E34DA006659E5 /* BRUserAPI.swift in Sources */, BFC676782E0E9553006659E5 /* BRSpotlightMainBaseCell.swift in Sources */, BFC676732E0E938B006659E5 /* BRTableView.swift in Sources */, @@ -889,8 +1020,12 @@ BF692B132E0A7B9000A5C2DA /* BRUserInfo.swift in Sources */, BF692B042E0A76D200A5C2DA /* BRLoginManager.swift in Sources */, BFC6769D2E129794006659E5 /* BRHomeTop10ViewController.swift in Sources */, + BF02B80D2E2F63ED00172177 /* BRFavoritesCell.swift in Sources */, BF692AEB2E0A475D00A5C2DA /* AppDelegate.swift in Sources */, + BF02B81B2E2F8FDF00172177 /* BRMineUserInfoCell.swift in Sources */, + BF02B8202E2F9B1000172177 /* BRWebViewController.swift in Sources */, BF692B242E0A825B00A5C2DA /* BRCryptorService.swift in Sources */, + BF02B8242E2FAEB500172177 /* BRAboutUsCell.swift in Sources */, BF692B342E0A87C800A5C2DA /* UIDevice+BRAdd.swift in Sources */, BF692B3E2E0A8D2300A5C2DA /* BRTabBarController.swift in Sources */, BF02B7E12E2DE64200172177 /* BRVideoProgressView.swift in Sources */, @@ -904,6 +1039,8 @@ BF692B7C2E0D3C1300A5C2DA /* BRVideoInfoModel.swift in Sources */, BFC6766D2E0E3A8D006659E5 /* BRImageView.swift in Sources */, BF02B7ED2E2E390500172177 /* BRScrollView.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 */, @@ -919,19 +1056,24 @@ BF692B422E0A8FB500A5C2DA /* UIFont+BRAdd.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 */, BF692B5F2E0B812800A5C2DA /* BRTabBarItemContainer.swift in Sources */, BF3338EC2E154BFE00B10F76 /* BRPlayerControlView.swift in Sources */, BF692B652E0BC53900A5C2DA /* CGMutablePath+BRRoundedCorner.swift in Sources */, + BF02B7F52E2F203D00172177 /* BRHomeCategoriesViewController.swift in Sources */, BFC676752E0E93B3006659E5 /* BRTableViewCell.swift in Sources */, BF78108B2E0D4EB3007DEEBC /* BRURLPath.swift in Sources */, BF692B092E0A775500A5C2DA /* BRLoginToken.swift in Sources */, BF692AFC2E0A6F8000A5C2DA /* BRNetworkTarget.swift in Sources */, + BF02B7FF2E2F2F2900172177 /* BRHomeCategoriesCell.swift in Sources */, BF692B3A2E0A8C6000A5C2DA /* BRViewController.swift in Sources */, BFC676BE2E13A8EB006659E5 /* UIScrollView+BRRefresh.swift in Sources */, BF692B182E0A7D8900A5C2DA /* BRToast.swift in Sources */, BF692B0E2E0A7AF300A5C2DA /* UserDefaults+BRAdd.swift in Sources */, + BF02B8082E2F616E00172177 /* BRFavoritesViewController.swift in Sources */, BF3338FD2E1626B000B10F76 /* BRPlayerControlProtocol.swift in Sources */, BF692B582E0AAA6F00A5C2DA /* UIScreen+BRAdd.swift in Sources */, BF692B1F2E0A804600A5C2DA /* BRLocalizedManager.swift in Sources */, @@ -948,8 +1090,10 @@ BFC676832E122CC5006659E5 /* BRPlayerViewModel.swift in Sources */, BF02B7EF2E2E4BFD00172177 /* BRRateModel.swift in Sources */, BF692B672E0BC6C700A5C2DA /* AppDelegate+BRConfig.swift in Sources */, + BF02B8022E2F39FE00172177 /* BRCategorieShortViewController.swift in Sources */, BF3338FB2E161CF900B10F76 /* NSNumber+BRAdd.swift in Sources */, BF692B222E0A820D00A5C2DA /* String+BRAdd.swift in Sources */, + BF02B80F2E2F6EEA00172177 /* BRFavoritesHeaderView.swift in Sources */, BF692B632E0B9D4800A5C2DA /* BRTabBarItem.swift in Sources */, BFC6768B2E123690006659E5 /* BRVideoRevolutionManager.swift in Sources */, BFC6768F2E125D5B006659E5 /* BRSpotlightTopMainCell.swift in Sources */, @@ -957,11 +1101,13 @@ BFC676622E0E2C8E006659E5 /* WMZBannerView.m in Sources */, BFC676632E0E2C8E006659E5 /* WMZBannerOverLayout.m in Sources */, BFC676642E0E2C8E006659E5 /* WMZBannerFlowLayout.m in Sources */, + BF02B81E2E2F99D900172177 /* BRWebView.swift in Sources */, BFC676652E0E2C8E006659E5 /* WMZBannerControl.m in Sources */, BFC676972E127D3C006659E5 /* BRSpotlightRecommandMainCell.swift in Sources */, BFC6767F2E121A72006659E5 /* BRSpotlightHotCell.swift in Sources */, BFC6767D2E0E9809006659E5 /* BRSpotlightHotMainCell.swift in Sources */, BF02B7EB2E2E388800172177 /* BREpisodeMenuView.swift in Sources */, + BF02B8042E2F5B4B00172177 /* BRCategorieShortCell.swift in Sources */, BFC676662E0E2C8E006659E5 /* WMZBannerFadeLayout.m in Sources */, BF02B7E72E2E1F0500172177 /* BRPanModalContentView.swift in Sources */, BFC676872E122E36006659E5 /* BRVideoDetailModel.swift in Sources */, @@ -975,12 +1121,14 @@ BF02B7E32E2E08BD00172177 /* BRDetailEpButton.swift in Sources */, BF692B072E0A771C00A5C2DA /* BRModel.swift in Sources */, BF692B752E0D39D000A5C2DA /* BRListModel.swift in Sources */, + BF02B8172E2F881200172177 /* BRMineItem.swift in Sources */, BFC676B92E1385FC006659E5 /* BRPopularPicksSmallCell.swift in Sources */, BF692B512E0AA8C600A5C2DA /* BRPlayerListViewController.swift in Sources */, BFC676522E0D4EFD006659E5 /* BRHomeViewModel.swift in Sources */, BFC676A72E12AF04006659E5 /* WaterfallMutiSectionFlowLayout.swift in Sources */, BF692B2A2E0A84F700A5C2DA /* JXUUID.m in Sources */, BF692B2B2E0A84F700A5C2DA /* PDKeyChain.m in Sources */, + BF02B7FA2E2F225D00172177 /* BRHomeCategoryModel.swift in Sources */, BFC6766B2E0E395F006659E5 /* BRHomeHeaderBannerCell.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/BeeReel/Base/Controller/BRTabBarController.swift b/BeeReel/Base/Controller/BRTabBarController.swift index 8922c36..8ec6eb4 100644 --- a/BeeReel/Base/Controller/BRTabBarController.swift +++ b/BeeReel/Base/Controller/BRTabBarController.swift @@ -72,8 +72,8 @@ extension BRTabBarController { private func br_setup() { let nav1 = createNavigationController(viewController: BRHomeViewController(), title: "首页".localized, image: UIImage(named: "tabbar_icon_01"), selectedImage: UIImage(named: "tabbar_icon_01_selected")) let nav2 = createNavigationController(viewController: BRExploreViewController(), title: "推荐".localized, image: UIImage(named: "tabbar_icon_02"), selectedImage: UIImage(named: "tabbar_icon_02_selected")) - let nav3 = createNavigationController(viewController: BRViewController(), title: "首页".localized, image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected")) - let nav4 = createNavigationController(viewController: BRViewController(), title: "首页".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected")) + let nav3 = createNavigationController(viewController: BRFavoritesViewController(), title: "首页".localized, image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected")) + let nav4 = createNavigationController(viewController: BRMineViewController(), title: "首页".localized, image: UIImage(named: "tabbar_icon_04"), selectedImage: UIImage(named: "tabbar_icon_04_selected")) viewControllers = [nav1, nav2, nav3, nav4] @@ -116,3 +116,11 @@ extension BRTabBarController { } } } + + +extension BRTabBarController { + + func onHomePage() { + self.selectedIndex = 0 + } +} diff --git a/BeeReel/Base/Controller/BRViewController.swift b/BeeReel/Base/Controller/BRViewController.swift index 5fa4396..c9650a8 100644 --- a/BeeReel/Base/Controller/BRViewController.swift +++ b/BeeReel/Base/Controller/BRViewController.swift @@ -7,6 +7,7 @@ import UIKit + class BRViewController: UIViewController { private(set) var isViewDidLoad = false @@ -67,7 +68,7 @@ class BRViewController: UIViewController { extension UIViewController { - func configNavigationBack(_ imageName: String = "nav_back_icon_01") { + func configNavigationBack(_ imageName: String = "nav_back_icon_02") { let image = UIImage(named: imageName) let leftBarButtonItem = UIBarButtonItem(image: image, style: .plain ,target: self,action: #selector(handleNavBack)) @@ -96,13 +97,15 @@ extension UIViewController { extension UIViewController { ///设置导航默认样式 - func br_setNavigationNormalStyle(backgroundColor: UIColor = .clear, - isTranslucent: Bool = true, - prefersLargeTitles: Bool = false) + func br_setNavigation(style: BRNavigationBarStyle) { - self.br_setNavigationBackgroundColor(color: backgroundColor, isTranslucent: isTranslucent) - self.br_setNavigationTitleStyle() - self.navigationController?.navigationBar.prefersLargeTitles = prefersLargeTitles + if style == .light { + self.br_setNavigationBackgroundColor(color: .colorFFFFFF()) + self.br_setNavigationTitleStyle(color: .color1C1C1C()) + } else { + self.br_setNavigationBackgroundColor(color: .color1C1C1C()) + self.br_setNavigationTitleStyle(color: .colorFFFFFF()) + } } ///设置导航背景色 diff --git a/BeeReel/Base/Define/BRDefine.swift b/BeeReel/Base/Define/BRDefine.swift index f1503ad..755d889 100644 --- a/BeeReel/Base/Define/BRDefine.swift +++ b/BeeReel/Base/Define/BRDefine.swift @@ -7,17 +7,22 @@ import UIKit + + + //MARK:-------------- 系统版本号 -------------- ///当前系统版本号 let kBROsVersion: String = UIDevice.current.systemVersion let kBRAPPBundleIdentifier: String = (Bundle.main.infoDictionary!["CFBundleIdentifier"] as? String) ?? "0" ///app版本号 -public let kBRAPPVersion: String = (Bundle.main.infoDictionary!["CFBundleShortVersionString"] as? String) ?? "0" -public let kSBAPPBundleVersion: String = (Bundle.main.infoDictionary!["CFBundleVersion"] as? String) ?? "0" +let kBRAPPVersion: String = (Bundle.main.infoDictionary!["CFBundleShortVersionString"] as? String) ?? "0" +let kSBAPPBundleVersion: String = (Bundle.main.infoDictionary!["CFBundleVersion"] as? String) ?? "0" + +let kBRAPPBundleName: String = (Bundle.main.infoDictionary!["CFBundleName"] as? String) ?? "" +let kBRAPPName: String = (Bundle.main.infoDictionary!["CFBundleDisplayName"] as? String) ?? "" + -public let kBRAPPBundleName: String = (Bundle.main.infoDictionary!["CFBundleName"] as? String) ?? "" -public let kBRAPPName: String = (Bundle.main.infoDictionary!["CFBundleDisplayName"] as? String) ?? "" //MARK: ------- 打印信息 ---------- diff --git a/BeeReel/Base/Extension/UIColor+BRAdd.swift b/BeeReel/Base/Extension/UIColor+BRAdd.swift index 7fb2629..65ff369 100644 --- a/BeeReel/Base/Extension/UIColor+BRAdd.swift +++ b/BeeReel/Base/Extension/UIColor+BRAdd.swift @@ -74,4 +74,24 @@ extension UIColor { static func color747474(alpha: CGFloat = 1) -> UIColor { return UIColor(rgb: 0x747474, alpha: alpha) } + + static func colorF2FEDC(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xF2FEDC, alpha: alpha) + } + + static func colorFFEFE2(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xFFEFE2, alpha: alpha) + } + + static func colorDFFDFF(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xDFFDFF, alpha: alpha) + } + + static func colorFFE9FA(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xFFE9FA, alpha: alpha) + } + + static func colorB7B7B7(alpha: CGFloat = 1) -> UIColor { + return UIColor(rgb: 0xB7B7B7, alpha: alpha) + } } diff --git a/BeeReel/Base/Extension/UINavigationBar+BRAdd.swift b/BeeReel/Base/Extension/UINavigationBar+BRAdd.swift index e48742d..bf9eb29 100644 --- a/BeeReel/Base/Extension/UINavigationBar+BRAdd.swift +++ b/BeeReel/Base/Extension/UINavigationBar+BRAdd.swift @@ -7,6 +7,12 @@ import UIKit +enum BRNavigationBarStyle: Int { + case light = 1 + case dark = 2 +} + + extension UINavigationBar { static let br_normalTitleFont = UIFont.fontBold(ofSize: 16) diff --git a/BeeReel/Base/Extension/UIScreen+BRAdd.swift b/BeeReel/Base/Extension/UIScreen+BRAdd.swift index 1b0c91c..9927ffd 100644 --- a/BeeReel/Base/Extension/UIScreen+BRAdd.swift +++ b/BeeReel/Base/Extension/UIScreen+BRAdd.swift @@ -46,4 +46,13 @@ extension UIScreen { static var customTabBarHeight: CGFloat { return tabbarSafeBottomMargin + 50 } + + ///屏幕宽比 + static var widthRatio: CGFloat { + return UIScreen.width / 375 + } + + static func getRatioWidth(size: CGFloat) -> CGFloat { + return self.widthRatio * size + } } diff --git a/BeeReel/Base/Network/API/BRHomeAPI.swift b/BeeReel/Base/Network/API/BRHomeAPI.swift index 2d97e19..6554da9 100644 --- a/BeeReel/Base/Network/API/BRHomeAPI.swift +++ b/BeeReel/Base/Network/API/BRHomeAPI.swift @@ -55,4 +55,30 @@ class BRHomeAPI { } } + static func requestHomeCategoryList(completer: ((_ list: [BRHomeCategoryModel]?) -> Void)?) { + var param = BRNetworkParameters(path: "/categoryListAppendShortPlay") + param.method = .get + param.parameters = [ + "short_play_num" : 4, + ] + + BRNetwork.request(parameters: param) { (response: BRNetworkResponse>) in + completer?(response.data?.list) + } + } + + static func requestCategoryVideoList(id: String, page: Int, completer: ((_ listModel: BRListModel?) -> Void)?) { + + var param = BRNetworkParameters(path: "/videoList") + param.method = .get + param.parameters = [ + "category_id" : id, + "current_page" : page, + "page_size" : 20 + ] + + BRNetwork.request(parameters: param) { (response: BRNetworkResponse>) in + completer?(response.data) + } + } } diff --git a/BeeReel/Base/Network/API/BRVideoAPI.swift b/BeeReel/Base/Network/API/BRVideoAPI.swift index 0eb1911..20cf490 100644 --- a/BeeReel/Base/Network/API/BRVideoAPI.swift +++ b/BeeReel/Base/Network/API/BRVideoAPI.swift @@ -67,6 +67,20 @@ class BRVideoAPI { } } + ///收藏列表 + static func requestFavoriteList(page: Int, completer: ((_ listModel: BRListModel?) -> Void)?) { + var param = BRNetworkParameters(path: "/myCollections") + param.method = .get + param.parameters = [ + "current_page" : page, + "page_size" : 20 + ] + + BRNetwork.request(parameters: param) { (response: BRNetworkResponse>) in + completer?(response.data) + } + } + ///推荐短剧 static func requestExploreVideo(page: Int, revolution: BRShortModel.VideoRevolution? = nil, completer: ((_ listModel: BRListModel?) -> Void)?) { @@ -88,6 +102,38 @@ class BRVideoAPI { completer?(response.data) } } + + + static func requestAddPlayHistory(videoId: String?, shortPlayId: String?) { + guard let shortPlayId = shortPlayId else { return } + + var param = BRNetworkParameters(path: "/createHistory") + param.isLoding = false + param.isToast = false + param.parameters = [ + "video_id" : videoId ?? "0", + "short_play_id" : shortPlayId + ] + + BRNetwork.request(parameters: param) { (response: BRNetworkResponse) in + + } + } + + ///历史记录列表 + static func requestPlayHistorys(page: Int, pageSize: Int = 20, completer: ((_ listModel: BRListModel?) -> Void)?) { + var param = BRNetworkParameters(path: "/myHistorys") + param.method = .get + param.parameters = [ + "current_page" : page, + "page_size" : pageSize + ] + + BRNetwork.request(parameters: param) { (response: BRNetworkResponse>) in + completer?(response.data) + } + } + } diff --git a/BeeReel/Base/View/BRGradientView.swift b/BeeReel/Base/View/BRGradientView.swift new file mode 100644 index 0000000..6f1b9e5 --- /dev/null +++ b/BeeReel/Base/View/BRGradientView.swift @@ -0,0 +1,45 @@ +// +// BRGradientView.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRGradientView: UIView { + + override class var layerClass: AnyClass { + return CAGradientLayer.self + } + + var br_gradientLayer: CAGradientLayer { + return self.layer as! CAGradientLayer + } + + var br_colors: [CGColor]? { + didSet { + br_gradientLayer.colors = br_colors + } + } + + var br_startPoint: CGPoint = .zero { + didSet { + br_gradientLayer.startPoint = br_startPoint + } + } + + var br_endPoint: CGPoint = .zero { + didSet { + br_gradientLayer.endPoint = br_endPoint + } + } + + var br_locations: [NSNumber] = [] { + didSet { + br_gradientLayer.locations = br_locations + } + } + + +} diff --git a/BeeReel/Base/View/BRImageView.swift b/BeeReel/Base/View/BRImageView.swift index b6fb3d4..8d96365 100644 --- a/BeeReel/Base/View/BRImageView.swift +++ b/BeeReel/Base/View/BRImageView.swift @@ -34,7 +34,8 @@ class BRImageView: UIImageView { } required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") +// fatalError("init(coder:) has not been implemented") + super.init(image: nil) } diff --git a/BeeReel/Base/View/BRTableView.swift b/BeeReel/Base/View/BRTableView.swift index 0172b95..b17025a 100644 --- a/BeeReel/Base/View/BRTableView.swift +++ b/BeeReel/Base/View/BRTableView.swift @@ -19,7 +19,7 @@ class BRTableView: UITableView { self.contentInsetAdjustmentBehavior = .never if style == .insetGrouped { - sectionFooterHeight = 12 + sectionFooterHeight = 14 sectionHeaderHeight = 0.1 } else if style == .plain { if #available(iOS 15.0, *) { @@ -32,7 +32,6 @@ class BRTableView: UITableView { fatalError("init(coder:) has not been implemented") } - ///修改 insetGrouped 的边距 参考https://github.com/QMUI/QMUIDemo_iOS/blob/master/QMUI/QMUIKit/UIKitExtensions/UITableView%2BQMUI.m override var layoutMargins: UIEdgeInsets { set { super.layoutMargins = newValue diff --git a/BeeReel/Base/WebView/BRWebView.swift b/BeeReel/Base/WebView/BRWebView.swift new file mode 100644 index 0000000..c78b122 --- /dev/null +++ b/BeeReel/Base/WebView/BRWebView.swift @@ -0,0 +1,149 @@ +// +// BRWebView.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit +@preconcurrency import WebKit + +//MARK:-------------- VPWebViewDelegate -------------- +@objc protocol BRWebViewDelegate: NSObjectProtocol { + + @objc optional func br_webView(_ webView: BRWebView, shouldStartLoadWith navigationAction: WKNavigationAction) -> Bool + + @objc optional func br_webViewDidStartLoad(_ webView: BRWebView) + + @objc optional func br_webViewDidFinishLoad(_ webView: BRWebView) + + @objc optional func br_webView(_ webView: BRWebView, didFailLoadWithError error: Error) + + ///进度 + @objc optional func br_webView(webView: BRWebView, didChangeProgress progress: CGFloat) + ///标题 + @objc optional func br_webView(webView: BRWebView, didChangeTitle title: String) + + ///web交互用 + @objc optional func br_userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) + +} + +class BRWebView: WKWebView { + + weak var delegate: BRWebViewDelegate? + + private(set) var scriptMessageHandlerArray: [String] = [] + + + deinit { + self.removeObserver(self, forKeyPath: "estimatedProgress") + self.removeObserver(self, forKeyPath: "title") + + } + + override init(frame: CGRect, configuration: WKWebViewConfiguration) { + super.init(frame: frame, configuration: configuration) + addScriptMessageHandler() + _setupInit() + } + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + private func _setupInit() { + + self.isOpaque = false + self.navigationDelegate = self + self.addObserver(self, forKeyPath: "estimatedProgress", options: .new, context: nil) + self.addObserver(self, forKeyPath: "title", options: .new, context: nil) + + } + + override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { + if object as? BRWebView == self { + if keyPath == "estimatedProgress", let progress = change?[NSKeyValueChangeKey.newKey] as? CGFloat { + self.delegate?.br_webView?(webView: self, didChangeProgress: progress) + } else if keyPath == "title", let title = change?[NSKeyValueChangeKey.newKey] as? String { + self.delegate?.br_webView?(webView: self, didChangeTitle: title) + } + } + } + + func load(urlStr: String) { + guard let url = URL(string: urlStr) else { return } + let request = URLRequest(url: url, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30) + self.load(request) + } + + func removeScriptMessageHandler() { + self.scriptMessageHandlerArray.forEach{ + configuration.userContentController.removeScriptMessageHandler(forName: $0) + } + } + func addScriptMessageHandler() { + self.scriptMessageHandlerArray.forEach{ + configuration.userContentController.add(YYTextWeakProxy(target: self) as! WKScriptMessageHandler, name: $0) + } + } + + +} + + +//MARK:-------------- WKNavigationDelegate -------------- +extension BRWebView: WKNavigationDelegate { + + func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { + + decisionHandler(.allow); + } + + func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { + + if let url = navigationAction.request.url, + url.scheme != "http", + url.scheme != "https" + { + UIApplication.shared.open(url) + decisionHandler(.cancel) + return + } + + if let result = self.delegate?.br_webView?(self, shouldStartLoadWith: navigationAction) { + if result { + decisionHandler(.allow) + } else { + decisionHandler(.cancel) + } + } else { + decisionHandler(.allow) + } + } + + func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { + self.delegate?.br_webViewDidStartLoad?(self) + } + + func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { + self.delegate?.br_webViewDidFinishLoad?(self) + } + + func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { + self.delegate?.br_webView?(self, didFailLoadWithError: error) + } + + func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { + self.delegate?.br_webView?(self, didFailLoadWithError: error) + } + + +} + +//MARK:-------------- WKScriptMessageHandler -------------- +extension BRWebView: WKScriptMessageHandler { + + func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { + self.delegate?.br_userContentController?(userContentController, didReceive: message) + } + +} diff --git a/BeeReel/Base/WebView/BRWebViewController.swift b/BeeReel/Base/WebView/BRWebViewController.swift new file mode 100644 index 0000000..794e986 --- /dev/null +++ b/BeeReel/Base/WebView/BRWebViewController.swift @@ -0,0 +1,114 @@ +// +// BRWebViewController.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit +import WebKit + + + +class BRWebViewController: BRViewController { + + var webUrl: String? + + ///自动设置标题 + var autoTitle = true + + var needAutoRefresh = true + + private(set) lazy var webView: BRWebView = { + let controller = WKUserContentController() + + let config = WKWebViewConfiguration() + config.userContentController = controller + config.preferences.javaScriptEnabled = true + /** 默认是不能通过JS自动打开窗口的,必须通过用户交互才能打开 */ + config.preferences.javaScriptCanOpenWindowsAutomatically = true + let webView = BRWebView(frame: self.view.bounds, configuration: config) + webView.delegate = self + return webView + }() + + override func viewDidLoad() { + super.viewDidLoad() + + + _setupUI() + + if let url = webUrl { + self.load(webUrl: url) + } + + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: true) + br_setNavigation(style: .light) + } + + func load(webUrl: String) { + let str: String = webUrl + + guard let url = URL(string: str) else { return } + let request = URLRequest(url: url, timeoutInterval: 30) + + self.webView.load(request) + } + + func reload() { + self.webView.reload() + } + +} + +extension BRWebViewController { + + private func _setupUI() { + self.view.addSubview(webView) + + self.webView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(0) + make.right.equalToSuperview().offset(0) + make.top.equalToSuperview().offset(0) + make.bottom.equalToSuperview().offset(0) + } + } + + +} + +//MARK: -------------- VPWebViewDelegate -------------- +extension BRWebViewController: BRWebViewDelegate { + + func br_webView(_ webView: BRWebView, shouldStartLoadWith navigationAction: WKNavigationAction) -> Bool { + self.webView.isHidden = false + return true + } + + func br_webViewDidStartLoad(_ webView: BRWebView) { + BRHUD.show(containerView: self.view) + } + + func br_webView(webView: BRWebView, didChangeTitle title: String) { + if autoTitle { + self.title = title + } + } + + func br_webViewDidFinishLoad(_ webView: BRWebView) { + self.webView.isHidden = false + BRHUD.dismiss() + } + + func br_webView(_ webView: BRWebView, didFailLoadWithError error: any Error) { + BRHUD.dismiss() + } + + func br_userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { +// vp_webViewUserContentController(didReceive: message) + } +} diff --git a/BeeReel/Class/Favorites/Controller/BRFavoritesViewController.swift b/BeeReel/Class/Favorites/Controller/BRFavoritesViewController.swift new file mode 100644 index 0000000..8be1045 --- /dev/null +++ b/BeeReel/Class/Favorites/Controller/BRFavoritesViewController.swift @@ -0,0 +1,178 @@ +// +// BRFavoritesViewController.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRFavoritesViewController: BRViewController { + + private lazy var listArr: [BRShortModel] = [] + private lazy var page = 1 + + ///播放历史 + private var playHistoryModel: BRShortModel? { + didSet { + collectionView.reloadData() + } + } + + private lazy var titleImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "title_icon_01")) + return imageView + }() + + private lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let width = floor((UIScreen.width - 30 - 22) / 3) + let height = 144 / 108 * width + + let layout = UICollectionViewFlowLayout() + layout.minimumLineSpacing = 11 + layout.minimumInteritemSpacing = 11 + layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15) + layout.itemSize = .init(width: width, height: height) + layout.headerReferenceSize = .init(width: UIScreen.width, height: 180) + return layout + }() + + private lazy var collectionView: BRCollectionView = { + let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) + collectionView.delegate = self + collectionView.dataSource = self + collectionView.register(BRFavoritesCell.self, forCellWithReuseIdentifier: "cell") + collectionView.register(BRFavoritesHeaderView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "headerView") + return collectionView + }() + + private lazy var addFavoritesButton: UIButton = { + var config = UIButton.Configuration.plain() + config.background.image = UIImage(named: "add_bg_image_01") + config.image = UIImage(named: "add_icon_01") + config.attributedTitle = AttributedString.br_createAttributedString(string: "Expand Your Favorites".localized, color: .colorB7B7B7(), font: .fontMedium(ofSize: 14)) + config.imagePadding = 8 + let button = UIButton(configuration: config) + button.addTarget(self, action: #selector(handleAddFavoritesButton), for: .touchUpInside) + return button + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.edgesForExtendedLayout = [.top, .bottom] + + br_setupUI() + + requestDataList(page: 1, completer: nil) + + requestPlayHistorys() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(true, animated: true) + + } + + +} + +extension BRFavoritesViewController { + + private func br_setupUI() { + view.addSubview(titleImageView) + view.addSubview(collectionView) + view.addSubview(addFavoritesButton) + + titleImageView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.top.equalToSuperview().offset(UIScreen.statusBarHeight + 20) + } + + collectionView.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.top.equalToSuperview().offset(UIScreen.statusBarHeight + 60) + make.bottom.equalTo(addFavoritesButton.snp.top).offset(-10) + } + + addFavoritesButton.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.centerX.equalToSuperview() + make.bottom.equalToSuperview().offset(-(UIScreen.customTabBarHeight + 10)) + make.height.equalTo(48) + } + + } + +} + + +extension BRFavoritesViewController { + @objc private func handleAddFavoritesButton() { + BRAppTool.tabBarController?.onHomePage() + } + +} + +extension BRFavoritesViewController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRFavoritesCell + cell.model = self.listArr[indexPath.row] + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.listArr.count + } + + func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { + if kind == UICollectionView.elementKindSectionHeader { + let view = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: "headerView", for: indexPath) as! BRFavoritesHeaderView + view.model = self.playHistoryModel + return view + } else { + return UICollectionReusableView() + } + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let model = self.listArr[indexPath.row] + let vc = BRVideoDetailViewController() + vc.shortPlayId = model.short_play_id + self.navigationController?.pushViewController(vc, animated: true) + } +} + + +extension BRFavoritesViewController { + + private func requestDataList(page: Int, completer: (() -> Void)?) { + + BRVideoAPI.requestFavoriteList(page: page) { [weak self] listModel in + guard let self = self else { return } + if let list = listModel?.list { + if page == 1 { + self.listArr.removeAll() + } + list.forEach { + $0.is_collect = true + } + self.listArr += list + self.page = page + self.collectionView.reloadData() + } + completer?() + } + + } + + private func requestPlayHistorys() { + BRVideoAPI.requestPlayHistorys(page: 1, pageSize: 1) { [weak self] listModel in + guard let self = self else { return } + guard let list = listModel?.list else { return } + self.playHistoryModel = list.first + } + } + + +} diff --git a/BeeReel/Class/Favorites/View/BRFavoritesCell.swift b/BeeReel/Class/Favorites/View/BRFavoritesCell.swift new file mode 100644 index 0000000..3b8d42b --- /dev/null +++ b/BeeReel/Class/Favorites/View/BRFavoritesCell.swift @@ -0,0 +1,126 @@ +// +// BRFavoritesCell.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRFavoritesCell: BRCollectionViewCell { + + var model: BRShortModel? { + didSet { + coverView.br_setImage(url: model?.image_url) + + let epString = NSMutableAttributedString() + + let epStr1 = NSMutableAttributedString(string: "EP.##".localizedReplace(text: model?.current_episode ?? "")) + epStr1.yy_color = .colorE3FC37() + epString.append(epStr1) + + let epStr2 = NSMutableAttributedString(string: "/" + "EP.##".localizedReplace(text: "\(model?.episode_total ?? 0)")) + epStr2.yy_color = .colorD3D3D3() + epString.append(epStr2) + + epLabel.attributedText = epString + + favoriteButton.isSelected = model?.is_collect ?? false + } + } + + private lazy var coverView: BRImageView = { + let imageView = BRImageView() + return imageView + }() + + private lazy var bottomView: UIView = { + let view = UIView() + view.br_addEffectView(style: .light) + return view + }() + + private lazy var epLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + return label + }() + + private lazy var favoriteButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "favorite_icon_04"), for: .normal) + button.setImage(UIImage(named: "favorite_icon_04_selected"), for: .selected) + button.setImage(UIImage(named: "favorite_icon_04_selected"), for: [.selected, .highlighted]) + button.addTarget(self, action: #selector(handleFavoriteButton), for: .touchUpInside) + return button + }() + + deinit { + NotificationCenter.default.removeObserver(self) + } + + override init(frame: CGRect) { + super.init(frame: frame) + NotificationCenter.default.addObserver(self, selector: #selector(updateShortFavoriteStateNotification), name: BRVideoAPI.updateShortFavoriteStateNotification, object: nil) + self.contentView.layer.cornerRadius = 8 + self.contentView.layer.masksToBounds = true + + br_setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc private func handleFavoriteButton() { + guard let shortPlayId = self.model?.short_play_id else { return } + let isFavorite = !(self.model?.is_collect ?? false) + + BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: model?.short_play_video_id) { + + } + + } + + @objc private func updateShortFavoriteStateNotification(sender: Notification) { + guard let userInfo = sender.userInfo else { return } + guard let shortPlayId = userInfo["id"] as? String else { return } + guard let state = userInfo["state"] as? Bool else { return } + guard shortPlayId == self.model?.short_play_id else { return } + + self.model?.is_collect = state; + + favoriteButton.isSelected = self.model?.is_collect ?? false + } + +} + +extension BRFavoritesCell { + + private func br_setupUI() { + contentView.addSubview(coverView) + contentView.addSubview(bottomView) + bottomView.addSubview(epLabel) + contentView.addSubview(favoriteButton) + + coverView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + bottomView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.height.equalTo(28) + } + + epLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(6) + make.centerY.equalToSuperview() + } + + favoriteButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(5) + make.right.equalToSuperview().offset(-5) + } + } + +} diff --git a/BeeReel/Class/Favorites/View/BRFavoritesHeaderView.swift b/BeeReel/Class/Favorites/View/BRFavoritesHeaderView.swift new file mode 100644 index 0000000..d7c52c7 --- /dev/null +++ b/BeeReel/Class/Favorites/View/BRFavoritesHeaderView.swift @@ -0,0 +1,188 @@ +// +// BRFavoritesHeaderView.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRFavoritesHeaderView: UICollectionReusableView { + + var model: BRShortModel? { + didSet { + coverView.br_setImage(url: model?.image_url) + nameLabel.text = model?.name + categoryLabel.text = model?.category?.first + + let epString = NSMutableAttributedString() + + let epStr1 = NSMutableAttributedString(string: "EP.##".localizedReplace(text: model?.current_episode ?? "")) + epStr1.yy_color = .colorE3FC37() + epString.append(epStr1) + + let epStr2 = NSMutableAttributedString(string: "/" + "EP.##".localizedReplace(text: "\(model?.episode_total ?? 0)")) + epStr2.yy_color = .colorFFFFFF() + epString.append(epStr2) + + epLabel.attributedText = epString + + favoriteButton.isSelected = self.model?.is_collect ?? false + } + } + + private lazy var bgView: UIImageView = { + let view = UIImageView(image: UIImage(named: "history_bg_image")) + view.isUserInteractionEnabled = true + return view + }() + + private lazy var coverView: BRImageView = { + let imageView = BRImageView() + imageView.layer.cornerRadius = 8 + imageView.layer.masksToBounds = true + imageView.isUserInteractionEnabled = true + return imageView + }() + + private lazy var playButton: UIButton = { + let button = UIButton(type: .custom) + button.layer.cornerRadius = 10 + button.layer.masksToBounds = true + button.backgroundColor = .colorE3FC37() + button.setImage(UIImage(named: "play_icon_06"), for: .normal) + button.addTarget(self, action: #selector(handlePlayButton), for: .touchUpInside) + return button + }() + + private lazy var nameLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 14) + label.textColor = .colorFFFFFF() + label.numberOfLines = 2 + return label + }() + + private lazy var categoryLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorF1FF94() + return label + }() + + private lazy var epLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + return label + }() + + private lazy var favoriteButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "favorite_icon_04"), for: .normal) + button.setImage(UIImage(named: "favorite_icon_04_selected"), for: .selected) + button.setImage(UIImage(named: "favorite_icon_04_selected"), for: [.selected, .highlighted]) + button.addTarget(self, action: #selector(handleFavoriteButton), for: .touchUpInside) + return button + }() + + deinit { + NotificationCenter.default.removeObserver(self) + } + + override init(frame: CGRect) { + super.init(frame: frame) + NotificationCenter.default.addObserver(self, selector: #selector(updateShortFavoriteStateNotification), name: BRVideoAPI.updateShortFavoriteStateNotification, object: nil) + + br_setupUI() + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc private func handlePlayButton() { + guard let shortPlayId = self.model?.short_play_id else { return } + + let vc = BRVideoDetailViewController() + vc.shortPlayId = shortPlayId + self.viewController?.navigationController?.pushViewController(vc, animated: true) + } + + @objc private func handleFavoriteButton() { + guard let shortPlayId = self.model?.short_play_id else { return } + let isFavorite = !(self.model?.is_collect ?? false) + + BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: model?.short_play_video_id) { + + } + + } + + @objc private func updateShortFavoriteStateNotification(sender: Notification) { + guard let userInfo = sender.userInfo else { return } + guard let shortPlayId = userInfo["id"] as? String else { return } + guard let state = userInfo["state"] as? Bool else { return } + guard shortPlayId == self.model?.short_play_id else { return } + + self.model?.is_collect = state + + favoriteButton.isSelected = self.model?.is_collect ?? false + } + +} + +extension BRFavoritesHeaderView { + + private func br_setupUI() { + addSubview(bgView) + bgView.addSubview(coverView) + coverView.addSubview(favoriteButton) + bgView.addSubview(playButton) + bgView.addSubview(nameLabel) + bgView.addSubview(categoryLabel) + bgView.addSubview(epLabel) + + bgView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.right.equalToSuperview().offset(-15) + make.top.equalToSuperview() + make.bottom.equalToSuperview().offset(-16) + } + + coverView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(10) + make.centerY.equalToSuperview() + make.width.equalTo(109) + make.height.equalTo(144) + } + + favoriteButton.snp.makeConstraints { make in + make.top.equalToSuperview().offset(5) + make.right.equalToSuperview().offset(-5) + } + + playButton.snp.makeConstraints { make in + make.right.equalToSuperview().offset(-10) + make.bottom.equalToSuperview().offset(-10) + make.height.equalTo(116) + make.width.equalTo(40) + } + + nameLabel.snp.makeConstraints { make in + make.left.equalTo(coverView.snp.right).offset(8) + make.top.equalToSuperview().offset(20) + make.right.lessThanOrEqualToSuperview().offset(-78) + } + + categoryLabel.snp.makeConstraints { make in + make.left.equalTo(nameLabel) + make.top.equalToSuperview().offset(75) + } + + epLabel.snp.makeConstraints { make in + make.left.equalTo(nameLabel) + make.bottom.equalToSuperview().offset(-20) + } + } + +} diff --git a/BeeReel/Class/Home/Controller/BRCategorieShortViewController.swift b/BeeReel/Class/Home/Controller/BRCategorieShortViewController.swift new file mode 100644 index 0000000..20dd9e3 --- /dev/null +++ b/BeeReel/Class/Home/Controller/BRCategorieShortViewController.swift @@ -0,0 +1,173 @@ +// +// BRCategorieShortViewController.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRCategorieShortViewController: BRViewController { + + var categorieId: String? + + var page: Int = 1 + var dataList: [BRShortModel] = [] + + private lazy var backButton: UIButton = { + let button = UIButton(type: .custom) + button.setImage(UIImage(named: "nav_back_icon_02"), for: .normal) + button.addTarget(self, action: #selector(handleNavBack), for: .touchUpInside) + return button + }() + + private lazy var lightBgImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "light_icon_02")) + return imageView + }() + + private lazy var titleImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "categorie_title_icon")) + return imageView + }() + + private lazy var starsIconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "stars_icon_01")) + return imageView + }() + + private lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let width = floor((UIScreen.width - 30 - 22) / 3) + let height = 144 / 108 * width + + let layout = UICollectionViewFlowLayout() + layout.minimumLineSpacing = 11 + layout.minimumInteritemSpacing = 11 + layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15) + layout.itemSize = .init(width: width, height: height) + return layout + }() + + private lazy var collectionView: BRCollectionView = { + let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) + collectionView.delegate = self + collectionView.dataSource = self + collectionView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin, right: 0) + collectionView.br_addRefreshHeader { [weak self] in + self?.handleHeaderRefresh(nil) + } + collectionView.br_addRefreshBackFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in + self?.handleFooterRefresh(nil) + } + collectionView.register(BRCategorieShortCell.self, forCellWithReuseIdentifier: "cell") + return collectionView + }() + + override func viewDidLoad() { + super.viewDidLoad() + + br_setupUI() + + requestDataList(page: 1, completer: nil) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(true, animated: true) + } + + override func handleHeaderRefresh(_ completer: (() -> Void)?) { + self.requestDataList(page: 1) { [weak self] in + self?.collectionView.br_endHeaderRefreshing() + } + } + + override func handleFooterRefresh(_ completer: (() -> Void)?) { + self.requestDataList(page: self.page + 1) { [weak self] in + self?.collectionView.br_endFooterRefreshing() + } + } + +} + + +extension BRCategorieShortViewController { + + private func br_setupUI() { + view.addSubview(lightBgImageView) + view.addSubview(backButton) + view.addSubview(titleImageView) + view.addSubview(starsIconImageView) + view.addSubview(collectionView) + + lightBgImageView.snp.makeConstraints { make in + make.top.left.right.equalToSuperview() + } + + backButton.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.top.equalToSuperview().offset(UIScreen.statusBarHeight + 10) + } + + titleImageView.snp.makeConstraints { make in + make.centerX.equalToSuperview() + make.centerY.equalTo(backButton) + } + + starsIconImageView.snp.makeConstraints { make in + make.bottom.equalTo(backButton).offset(-2) + make.left.equalTo(titleImageView.snp.right).offset(28) + } + + collectionView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview().offset(UIScreen.navBarHeight + 20) + } + + } + +} + + +extension BRCategorieShortViewController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRCategorieShortCell + cell.model = dataList[indexPath.row] + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.dataList.count + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let model = dataList[indexPath.row] + let vc = BRVideoDetailViewController() + vc.shortPlayId = model.short_play_id + self.navigationController?.pushViewController(vc, animated: true) + } +} + +extension BRCategorieShortViewController { + + private func requestDataList(page: Int, completer: (() -> Void)?) { + guard let id = categorieId else { return } + BRHomeAPI.requestCategoryVideoList(id: id, page: page) { [weak self] listModel in + guard let self = self else { return } + + if let list = listModel?.list { + if page == 1 { + self.dataList.removeAll() + } + self.dataList += list + + self.page = page + self.collectionView.reloadData() + } + + completer?() + } + } + + +} diff --git a/BeeReel/Class/Home/Controller/BRHomeCategoriesViewController.swift b/BeeReel/Class/Home/Controller/BRHomeCategoriesViewController.swift new file mode 100644 index 0000000..017670a --- /dev/null +++ b/BeeReel/Class/Home/Controller/BRHomeCategoriesViewController.swift @@ -0,0 +1,97 @@ +// +// BRHomeCategoriesViewController.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRHomeCategoriesViewController: BRViewController { + + private lazy var list: [BRHomeCategoryModel] = [] + + private lazy var tableView: BRTableView = { + let tableView = BRTableView(frame: .zero, style: .plain) + tableView.delegate = self + tableView.dataSource = self + tableView.separatorStyle = .none + tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.customTabBarHeight, right: 0) + tableView.register(BRHomeCategoriesMainCell.self, forCellReuseIdentifier: "cell") + return tableView + }() + + private lazy var cellColorArr: [[CGColor]] = [ + [UIColor.colorF2FEDC().cgColor, UIColor.colorF2FEDC(alpha: 0).cgColor], + [UIColor.colorFFEFE2().cgColor, UIColor.colorFFEFE2(alpha: 0).cgColor], + [UIColor.colorDFFDFF().cgColor, UIColor.colorDFFDFF(alpha: 0).cgColor], + [UIColor.colorFFE9FA().cgColor, UIColor.colorFFE9FA(alpha: 0).cgColor], + ] + + override func viewDidLoad() { + super.viewDidLoad() + + br_setupUI() + + requestListData(completer: nil) + } + + override func handleHeaderRefresh(_ completer: (() -> Void)?) { + requestListData { + completer?() + } + } + +} + +extension BRHomeCategoriesViewController { + + private func br_setupUI() { + view.addSubview(tableView) + + tableView.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.top.equalToSuperview().offset(20) + make.bottom.equalToSuperview() + } + } + +} + +//MARK: -------------- WMZPageProtocol -------------- +extension BRHomeCategoriesViewController: WMZPageProtocol { + func getMyScrollView() -> UIScrollView { + return self.tableView + } +} + +//MARK: -------------- UITableViewDelegate UITableViewDataSource -------------- +extension BRHomeCategoriesViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! BRHomeCategoriesMainCell + cell.model = list[indexPath.row] + cell.bgColors = cellColorArr[indexPath.row % 4] + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return list.count + } + +} + +extension BRHomeCategoriesViewController { + + private func requestListData(completer: (() -> Void)?) { + BRHomeAPI.requestHomeCategoryList { [weak self] list in + guard let self = self else { return } + if let list = list { + self.list = list + self.tableView.reloadData() + } + completer?() + } + } + +} diff --git a/BeeReel/Class/Home/Controller/BRHomeViewController.swift b/BeeReel/Class/Home/Controller/BRHomeViewController.swift index 9c8a9fa..30ea909 100644 --- a/BeeReel/Class/Home/Controller/BRHomeViewController.swift +++ b/BeeReel/Class/Home/Controller/BRHomeViewController.swift @@ -25,7 +25,7 @@ class BRHomeViewController: BRViewController { BRHomeTop10ViewController(), BRPopularPicksViewController(), BRNewReleasesViewController(), - BRViewController() + BRHomeCategoriesViewController() ] }() diff --git a/BeeReel/Class/Home/Model/BRHomeCategoryModel.swift b/BeeReel/Class/Home/Model/BRHomeCategoryModel.swift new file mode 100644 index 0000000..c8c19ff --- /dev/null +++ b/BeeReel/Class/Home/Model/BRHomeCategoryModel.swift @@ -0,0 +1,18 @@ +// +// BRHomeCategoryModel.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit +import SmartCodable + +class BRHomeCategoryModel: BRModel, SmartCodable { + + var id: String? + var category_name: String? + var short_play_list: [BRShortModel]? + + +} diff --git a/BeeReel/Class/Home/View/Categories/BRCategorieShortCell.swift b/BeeReel/Class/Home/View/Categories/BRCategorieShortCell.swift new file mode 100644 index 0000000..30a28b1 --- /dev/null +++ b/BeeReel/Class/Home/View/Categories/BRCategorieShortCell.swift @@ -0,0 +1,37 @@ +// +// BRCategorieShortCell.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRCategorieShortCell: BRCollectionViewCell { + + var model: BRShortModel? { + didSet { + coverView.br_setImage(url: model?.image_url) + } + } + + private lazy var coverView: BRImageView = { + let imageView = BRImageView() + imageView.layer.cornerRadius = 8 + imageView.layer.masksToBounds = true + return imageView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + contentView.addSubview(coverView) + + coverView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/BeeReel/Class/Home/View/Categories/BRHomeCategoriesCell.swift b/BeeReel/Class/Home/View/Categories/BRHomeCategoriesCell.swift new file mode 100644 index 0000000..8b35d1e --- /dev/null +++ b/BeeReel/Class/Home/View/Categories/BRHomeCategoriesCell.swift @@ -0,0 +1,39 @@ +// +// BRHomeCategoriesCell.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRHomeCategoriesCell: BRCollectionViewCell { + + + var model: BRShortModel? { + didSet { + imageView.br_setImage(url: model?.image_url) + } + } + + private lazy var imageView: BRImageView = { + let imageView = BRImageView() + imageView.layer.cornerRadius = 6 + imageView.layer.masksToBounds = true + return imageView + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + contentView.addSubview(imageView) + imageView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} diff --git a/BeeReel/Class/Home/View/Categories/BRHomeCategoriesMainCell.swift b/BeeReel/Class/Home/View/Categories/BRHomeCategoriesMainCell.swift new file mode 100644 index 0000000..c4467cb --- /dev/null +++ b/BeeReel/Class/Home/View/Categories/BRHomeCategoriesMainCell.swift @@ -0,0 +1,200 @@ +// +// BRHomeCategoriesMainCell.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRHomeCategoriesMainCell: BRTableViewCell { + + var model: BRHomeCategoryModel? { + didSet { + let firstModel = model?.short_play_list?.first + coverImageView.br_setImage(url: firstModel?.image_url) + + moreTitleLabel.text = model?.category_name + + self.collectionView.reloadData() + } + } + + var bgColors: [CGColor] = [] { + didSet { + bgView.br_colors = bgColors + } + } + + private let coverWidht = UIScreen.getRatioWidth(size: 100) + private let coverHeight = 48 + UIScreen.getRatioWidth(size: 84) + + private lazy var coverImageView: BRImageView = { + let imageView = BRImageView() + imageView.layer.cornerRadius = 10 + imageView.layer.masksToBounds = true + imageView.isUserInteractionEnabled = true + let tap = UITapGestureRecognizer(target: self, action: #selector(handleCoverImageView)) + imageView.addGestureRecognizer(tap) + return imageView + }() + + private lazy var bgView: BRGradientView = { + let view = BRGradientView() + view.br_startPoint = .init(x: 0, y: 0.5) + view.br_endPoint = .init(x: 1, y: 0.5) + view.br_locations = [0, 1] + view.layer.cornerRadius = 10 + view.layer.masksToBounds = true + return view + }() + + private lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let totalWidth = UIScreen.width - 30 - coverWidht - 12 - 10 - 22 + let width = floor(totalWidth / 3) + + let layout = UICollectionViewFlowLayout() + layout.scrollDirection = .horizontal + layout.minimumInteritemSpacing = 11 + layout.minimumLineSpacing = 11 + layout.itemSize = CGSize(width: width, height: coverHeight - 48) + return layout + }() + + private lazy var collectionView: BRCollectionView = { + let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) + collectionView.isScrollEnabled = false + collectionView.delegate = self + collectionView.dataSource = self + collectionView.contentInset = .init(top: 0, left: 12, bottom: 0, right: 0) + collectionView.register(BRHomeCategoriesCell.self, forCellWithReuseIdentifier: "cell") + return collectionView + }() + + private lazy var moreButton: UIButton = { + let button = UIButton(type: .custom) + button.addTarget(self, action: #selector(handleMoreButton), for: .touchUpInside) + return button + }() + + private lazy var moreTitleLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 14) + label.textColor = .color1C1C1C() + return label + }() + + private lazy var moreIconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "arrow_right_icon_01")) + return imageView + }() + + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + br_setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + @objc private func handleCoverImageView() { + guard let model = self.model?.short_play_list?.first else { return } + + let vc = BRVideoDetailViewController() + vc.shortPlayId = model.short_play_id + self.viewController?.navigationController?.pushViewController(vc, animated: true) + } + + @objc private func handleMoreButton() { + let vc = BRCategorieShortViewController() + vc.categorieId = self.model?.id + self.viewController?.navigationController?.pushViewController(vc, animated: true) + } + +} + +extension BRHomeCategoriesMainCell { + + private func br_setupUI() { + contentView.addSubview(coverImageView) + contentView.addSubview(bgView) + bgView.addSubview(collectionView) + bgView.addSubview(moreButton) + moreButton.addSubview(moreTitleLabel) + moreButton.addSubview(moreIconImageView) + + coverImageView.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.top.equalToSuperview() + make.bottom.equalToSuperview().offset(-14) + make.height.equalTo(coverHeight) + make.width.equalTo(coverWidht) + } + + bgView.snp.makeConstraints { make in + make.left.equalTo(coverImageView.snp.right) + make.top.bottom.equalTo(coverImageView) + make.right.equalToSuperview().offset(-15) + } + + collectionView.snp.makeConstraints { make in + make.left.equalToSuperview() + make.right.equalToSuperview() + make.top.equalToSuperview().offset(38) + make.height.equalTo(self.collectionViewLayout.itemSize.height) + } + + moreButton.snp.makeConstraints { make in + make.left.equalToSuperview().offset(14) + make.right.equalToSuperview().offset(-10) + make.top.equalToSuperview().offset(2) + make.bottom.equalTo(collectionView.snp.top) + } + + moreTitleLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.left.equalToSuperview() + } + + moreIconImageView.snp.makeConstraints { make in + make.right.equalToSuperview() + make.centerY.equalToSuperview() + } + + } + +} + +extension BRHomeCategoriesMainCell: UICollectionViewDelegate, UICollectionViewDataSource { + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRHomeCategoriesCell + cell.model = model?.short_play_list?[indexPath.row + 1] + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + var count = model?.short_play_list?.count ?? 0 + if count == 0 { + return 0 + } else { + count = count - 1 + if count > 3 { + return 3 + } + return count + } + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let model = model?.short_play_list?[indexPath.row + 1] + + let vc = BRVideoDetailViewController() + vc.shortPlayId = model?.short_play_id + self.viewController?.navigationController?.pushViewController(vc, animated: true) + + } +} diff --git a/BeeReel/Class/Home/View/Spotlight/BRSpotlightHotCell.swift b/BeeReel/Class/Home/View/Spotlight/BRSpotlightHotCell.swift index a01bf68..7cb1ee2 100644 --- a/BeeReel/Class/Home/View/Spotlight/BRSpotlightHotCell.swift +++ b/BeeReel/Class/Home/View/Spotlight/BRSpotlightHotCell.swift @@ -77,6 +77,11 @@ class BRSpotlightHotCell: BRCollectionViewCell { return button }() + + deinit { + NotificationCenter.default.removeObserver(self) + } + override init(frame: CGRect) { super.init(frame: frame) NotificationCenter.default.addObserver(self, selector: #selector(updateShortFavoriteStateNotification), name: BRVideoAPI.updateShortFavoriteStateNotification, object: nil) diff --git a/BeeReel/Class/Mine/Controller/BRAboutUsViewController.swift b/BeeReel/Class/Mine/Controller/BRAboutUsViewController.swift new file mode 100644 index 0000000..e050f99 --- /dev/null +++ b/BeeReel/Class/Mine/Controller/BRAboutUsViewController.swift @@ -0,0 +1,85 @@ +// +// BRAboutUsViewController.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRAboutUsViewController: BRViewController { + + + private lazy var listArr: [BRMineItem] = { + let arr = [ + BRMineItem(type: .web, title: "User Agreement".localized, url: kSBUserAgreementWebUrl), + BRMineItem(type: .web, title: "Privacy Policy".localized, url: kSBPrivacyPolicyWebUrl), + BRMineItem(type: .web, title: "Child Personal Information Protection Rules".localized, url: kSBInformationProtectionWebUrl), + BRMineItem(type: .web, title: "Youth Internet Civility Convention".localized, url: kSBCivizatioConventionWebUrl), + BRMineItem(type: .web, title: "Third-party information sharing list".localized, url: kSBInformationSharingWebUrl), + BRMineItem(type: .web, title: "Explicit List of Personal Information Collection".localized, url: kSBPersoInforDisclosureWebUrl), + ] + return arr + }() + + private lazy var tableView: BRTableView = { + let tableView = BRTableView(frame: .zero, style: .plain) + tableView.delegate = self + tableView.dataSource = self + tableView.rowHeight = 50 + tableView.separatorStyle = .none + tableView.register(BRAboutUsCell.self, forCellReuseIdentifier: "cell") + return tableView + }() + + private lazy var headerView: BRAboutUsHeaderView = { + let view = BRAboutUsHeaderView(frame: .init(x: 0, y: 0, width: UIScreen.width, height: 200)) + return view + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.title = "About Us".localized + + self.tableView.tableHeaderView = self.headerView + + view.addSubview(self.tableView) + + self.tableView.snp.makeConstraints { make in + make.edges.equalToSuperview() + } + + } + + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(false, animated: true) + br_setNavigation(style: .light) + } + +} + + +extension BRAboutUsViewController: UITableViewDelegate, UITableViewDataSource { + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return listArr.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! BRAboutUsCell + cell.item = listArr[indexPath.row] + return cell + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let item = listArr[indexPath.row] + guard let webUrl = item.url else { return } + + let vc = BRWebViewController() + vc.webUrl = webUrl + self.navigationController?.pushViewController(vc, animated: true) + } + + +} diff --git a/BeeReel/Class/Mine/Controller/BRMineViewController.swift b/BeeReel/Class/Mine/Controller/BRMineViewController.swift new file mode 100644 index 0000000..9bb974d --- /dev/null +++ b/BeeReel/Class/Mine/Controller/BRMineViewController.swift @@ -0,0 +1,126 @@ +// +// BRMineViewController.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRMineViewController: BRViewController { + + + private lazy var listArr: [[BRMineItem]] = { + let arr = [ + [ + BRMineItem(type: .userInfo), + ], + [ + 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: .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: ""), + ] + ] + + return arr + }() + + private lazy var lightImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "light_icon_03")) + return imageView + }() + + private lazy var tableView: BRTableView = { + let tableView = BRTableView(frame: .zero, style: .insetGrouped) + tableView.delegate = self + tableView.dataSource = self + tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.tabbarSafeBottomMargin + 10, right: 0) + tableView.register(BRMineCell.self, forCellReuseIdentifier: "cell") + tableView.register(BRMineUserInfoCell.self, forCellReuseIdentifier: "userInfo") + return tableView + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.edgesForExtendedLayout = [.top, .bottom] + + br_setupUI() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(true, animated: true) + } + + +} + +extension BRMineViewController { + + private func br_setupUI() { + view.addSubview(lightImageView) + view.addSubview(tableView) + + lightImageView.snp.makeConstraints { make in + make.left.top.equalToSuperview() + } + + tableView.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.bottom.equalToSuperview() + make.top.equalToSuperview().offset(UIScreen.statusBarHeight) + } + + + } + +} + +//MARK: -------------- UITableViewDelegate UITableViewDataSource -------------- +extension BRMineViewController: UITableViewDelegate, UITableViewDataSource { + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let item = listArr[indexPath.section][indexPath.row] + if item.type == .userInfo { + let cell = tableView.dequeueReusableCell(withIdentifier: "userInfo", for: indexPath) as! BRMineUserInfoCell + cell.userInfo = BRLoginManager.manager.userInfo + return cell + } + + let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! BRMineCell + cell.item = item + return cell + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return listArr[section].count + } + + func numberOfSections(in tableView: UITableView) -> Int { + return listArr.count + } + + func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { + return 0.1 + } + + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let item = listArr[indexPath.section][indexPath.row] + + switch item.type { + case .web: + let vc = BRWebViewController() + vc.webUrl = item.url + self.navigationController?.pushViewController(vc, animated: true) + + case .aboutUs: + let vc = BRAboutUsViewController() + self.navigationController?.pushViewController(vc, animated: true) + + default: + break + } + } + +} diff --git a/BeeReel/Class/Mine/Model/BRMineItem.swift b/BeeReel/Class/Mine/Model/BRMineItem.swift new file mode 100644 index 0000000..c2d23ef --- /dev/null +++ b/BeeReel/Class/Mine/Model/BRMineItem.swift @@ -0,0 +1,37 @@ +// +// BRMineItem.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRMineItem: BRModel { + + enum ItemType { + case userInfo + case web + case helpCenter + case aboutUs + } + + var type: ItemType? + var icon: UIImage? + var title: String? + var url: String? + + init(type: ItemType? = nil, icon: UIImage? = nil, title: String? = nil, url: String? = nil) { + self.type = type + self.icon = icon + self.title = title + self.url = url + } + + required init() { + fatalError("init() has not been implemented") + } + +} + + diff --git a/BeeReel/Class/Mine/View/BRAboutUsCell.swift b/BeeReel/Class/Mine/View/BRAboutUsCell.swift new file mode 100644 index 0000000..457a51e --- /dev/null +++ b/BeeReel/Class/Mine/View/BRAboutUsCell.swift @@ -0,0 +1,47 @@ +// +// BRAboutUsCell.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRAboutUsCell: BRTableViewCell { + + var item: BRMineItem? { + didSet { + titleLabel.text = item?.title + } + } + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 14) + label.textColor = .color1C1C1C() + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + contentView.addSubview(titleLabel) + contentView.addSubview(br_indicatorImageView) + + titleLabel.snp.makeConstraints { make in + make.left.equalToSuperview().offset(15) + make.centerY.equalToSuperview() + make.right.lessThanOrEqualToSuperview().offset(-70) + } + + br_indicatorImageView.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalToSuperview().offset(-15) + } + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} diff --git a/BeeReel/Class/Mine/View/BRAboutUsHeaderView.swift b/BeeReel/Class/Mine/View/BRAboutUsHeaderView.swift new file mode 100644 index 0000000..b433dc4 --- /dev/null +++ b/BeeReel/Class/Mine/View/BRAboutUsHeaderView.swift @@ -0,0 +1,20 @@ +// +// BRAboutUsHeaderView.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRAboutUsHeaderView: UIView { + + /* + // Only override draw() if you perform custom drawing. + // An empty implementation adversely affects performance during animation. + override func draw(_ rect: CGRect) { + // Drawing code + } + */ + +} diff --git a/BeeReel/Class/Mine/View/BRMineCell.swift b/BeeReel/Class/Mine/View/BRMineCell.swift new file mode 100644 index 0000000..4a789f8 --- /dev/null +++ b/BeeReel/Class/Mine/View/BRMineCell.swift @@ -0,0 +1,56 @@ +// +// BRMineCell.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRMineCell: BRTableViewCell { + + var item: BRMineItem? { + didSet { + imageView?.image = item?.icon + titleLabel.text = item?.title + } + } + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 14) + label.textColor = .color1C1C1C() + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + contentView.backgroundColor = .colorFFFFFF() + + + contentView.addSubview(titleLabel) + contentView.addSubview(br_indicatorImageView) + + imageView?.snp.makeConstraints { make in + make.top.equalToSuperview().offset(10) + make.centerY.equalToSuperview() + make.left.equalToSuperview().offset(10) + make.width.height.equalTo(34) + } + + titleLabel.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.left.equalToSuperview().offset(54) + } + + br_indicatorImageView.snp.makeConstraints { make in + make.centerY.equalToSuperview() + make.right.equalToSuperview().offset(-10) + } + + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} diff --git a/BeeReel/Class/Mine/View/BRMineUserInfoCell.swift b/BeeReel/Class/Mine/View/BRMineUserInfoCell.swift new file mode 100644 index 0000000..6d60bed --- /dev/null +++ b/BeeReel/Class/Mine/View/BRMineUserInfoCell.swift @@ -0,0 +1,106 @@ +// +// BRMineUserInfoCell.swift +// BeeReel +// +// Created by 湖南秦九 on 2025/7/22. +// + +import UIKit + +class BRMineUserInfoCell: BRTableViewCell { + + var userInfo: BRUserInfo? { + didSet { + avatarImageView.br_setImage(url: userInfo?.avator, placeholder: UIImage(named: "默认头像")) + + nickLabel.text = userInfo?.family_name?.isEmpty != false ? "Visitor".localized : userInfo?.family_name + + idLabel.text = "ID: \(userInfo?.customer_id ?? "")" + } + } + + private lazy var avatarBgView: UIView = { + let view = UIView() + view.layer.cornerRadius = 34 + view.layer.borderColor = UIColor.color1C1C1C().cgColor + view.layer.borderWidth = 2 + return view + }() + + private lazy var avatarIconImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "Polygon 6")) + return imageView + }() + + private lazy var avatarImageView: BRImageView = { + let imageView = BRImageView() + imageView.layer.cornerRadius = 28 + imageView.layer.masksToBounds = true + return imageView + }() + + private lazy var nickLabel: UILabel = { + let label = UILabel() + label.font = .fontMedium(ofSize: 18) + label.textColor = .color1C1C1C() + return label + }() + + private lazy var idLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .color777777() + return label + }() + + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + br_setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + +} + +extension BRMineUserInfoCell { + + private func br_setupUI() { + contentView.addSubview(avatarBgView) + contentView.addSubview(avatarIconImageView) + avatarBgView.addSubview(avatarImageView) + contentView.addSubview(nickLabel) + contentView.addSubview(idLabel) + + avatarBgView.snp.makeConstraints { make in + make.left.equalToSuperview() + make.top.equalToSuperview().offset(39) + make.width.height.equalTo(68) + make.bottom.equalToSuperview().offset(-6) + } + + avatarIconImageView.snp.makeConstraints { make in + make.centerX.equalTo(avatarBgView) + make.centerY.equalTo(avatarBgView.snp.top).offset(0) + } + + avatarImageView.snp.makeConstraints { make in + make.center.equalToSuperview() + make.width.height.equalTo(56) + } + + nickLabel.snp.makeConstraints { make in + make.left.equalTo(avatarBgView.snp.right).offset(10) + make.top.equalTo(avatarBgView).offset(13) + make.right.lessThanOrEqualToSuperview().offset(-100) + } + + idLabel.snp.makeConstraints { make in + make.left.equalTo(nickLabel) + make.bottom.equalTo(avatarBgView).offset(-13) + } + } + +} diff --git a/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift b/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift index a64ef70..ddb9887 100644 --- a/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift +++ b/BeeReel/Class/Player/Controller/BRPlayerListViewController.swift @@ -24,6 +24,9 @@ import SJMediaCacheServer ///当前展示的发生变化 @objc optional func br_playerListViewController(_ viewController: BRPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) + ///即将自动滑至下一级 + @objc optional func br_shouldAutoScrollNextEpisode(_ viewController: BRPlayerListViewController) -> Bool + } @objc protocol BRPlayerListViewControllerDataSource { @@ -295,7 +298,15 @@ extension BRPlayerListViewController: UICollectionViewDelegate, UICollectionView extension BRPlayerListViewController: BRPlayerViewModelDelegate { func br_currentVideoPlayFinish(viewModel: BRPlayerViewModel) { - scrollToNextEpisode() + var isScroll = true + if let result = self.delegate?.br_shouldAutoScrollNextEpisode?(self) { + isScroll = result + } + if isScroll { + scrollToNextEpisode() + } else { + viewModel.currentPlayer?.replay() + } } func br_switchPlayAndPause(viewModel: BRPlayerViewModel) { diff --git a/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift b/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift index 15f6548..ec82819 100644 --- a/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift +++ b/BeeReel/Class/Player/Controller/BRVideoDetailViewController.swift @@ -30,6 +30,9 @@ class BRVideoDetailViewController: BRPlayerListViewController { button.addTarget(self, action: #selector(handleNavBack), for: .touchUpInside) return button }() + + ///弹窗视图 + private weak var popUpView: UIView? override func viewDidLoad() { super.viewDidLoad() @@ -60,6 +63,11 @@ class BRVideoDetailViewController: BRPlayerListViewController { guard index < (model.episodeList?.count ?? 0) else { return nil } return model.episodeList?[index].video_url } + + override func play() { + super.play() + BRVideoAPI.requestAddPlayHistory(videoId: self.viewModel.currentPlayer?.videoInfo?.short_play_video_id, shortPlayId: self.viewModel.currentPlayer?.videoInfo?.short_play_id) + } } @@ -92,6 +100,8 @@ extension BRVideoDetailViewController { self?.scrollToItem(indexPath: IndexPath(row: index, section: indexPath.section), animated: false) } view.present(in: nil) + + self.popUpView = view } override func br_clickRateButton(viewModel: BRPlayerViewModel) { @@ -102,6 +112,8 @@ extension BRVideoDetailViewController { self.viewModel.rateModel = model } view.show() + + self.popUpView = view } } @@ -126,6 +138,14 @@ extension BRVideoDetailViewController: BRPlayerListViewControllerDataSource, BRP func br_numberOfSections(in viewController: BRPlayerListViewController) -> Int { return self.detailArr.count } + + func br_shouldAutoScrollNextEpisode(_ viewController: BRPlayerListViewController) -> Bool { + if self.popUpView == nil { + return true + } else { + return false + } + } } extension BRVideoDetailViewController { diff --git a/BeeReel/Class/Player/Model/BRPlayerProtocol.swift b/BeeReel/Class/Player/Model/BRPlayerProtocol.swift index ee22b82..e069f6c 100644 --- a/BeeReel/Class/Player/Model/BRPlayerProtocol.swift +++ b/BeeReel/Class/Player/Model/BRPlayerProtocol.swift @@ -18,10 +18,9 @@ import UIKit ///上一集是否加锁 @objc optional var hasLastEpisodeUnlocked: Bool { get set } - ///总进度 - var duration: Int { get } - ///当前进度 - var currentPosition: Int { get } + + var durationTime: TimeInterval { get } + var currentTime: TimeInterval { get } var rate: Float { get set } @@ -41,6 +40,6 @@ import UIKit func replay() ///设置进度 - func seekToTime(toTime: Int) + func seekTo(progress: Float) } diff --git a/BeeReel/Class/Player/View/BRDetailControlView.swift b/BeeReel/Class/Player/View/BRDetailControlView.swift index dcedcc1..133127b 100644 --- a/BeeReel/Class/Player/View/BRDetailControlView.swift +++ b/BeeReel/Class/Player/View/BRDetailControlView.swift @@ -61,6 +61,9 @@ class BRDetailControlView: BRPlayerControlView { private lazy var progressView: BRVideoProgressView = { let view = BRVideoProgressView() view.insets = .init(top: 18, left: 15, bottom: 0, right: 18) + view.panFinish = { [weak self] progress in + self?.viewModel?.seekTo(progress: Float(progress)) + } return view }() diff --git a/BeeReel/Class/Player/View/BRPlayerListCell.swift b/BeeReel/Class/Player/View/BRPlayerListCell.swift index 36eaaf2..4a5c4c4 100644 --- a/BeeReel/Class/Player/View/BRPlayerListCell.swift +++ b/BeeReel/Class/Player/View/BRPlayerListCell.swift @@ -36,9 +36,12 @@ class BRPlayerListCell: BRCollectionViewCell, BRPlayerProtocol { } } - var duration: Int = 0 - - var currentPosition: Int = 0 + var durationTime: TimeInterval { + return player.duration + } + var currentTime: TimeInterval { + return player.currentTime + } var rate: Float = 1 { didSet { @@ -63,11 +66,13 @@ class BRPlayerListCell: BRCollectionViewCell, BRPlayerProtocol { } func replay() { - + player.replay() } - func seekToTime(toTime: Int) { - + func seekTo(progress: Float) { + let duration = self.durationTime + let time = duration * TimeInterval(progress) + self.player.seek(toTime: time) } diff --git a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift index 70ff869..36dcb71 100644 --- a/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift +++ b/BeeReel/Class/Player/ViewModel/BRPlayerViewModel.swift @@ -70,4 +70,10 @@ extension BRPlayerViewModel { self.delegate?.br_clickRateButton(viewModel: self) } + ///设置进度 + func seekTo(progress: Float) { + self.currentPlayer?.seekTo(progress: progress) + + } + } diff --git a/BeeReel/Delegate/SceneDelegate.swift b/BeeReel/Delegate/SceneDelegate.swift index 90f9d94..ee5dac7 100644 --- a/BeeReel/Delegate/SceneDelegate.swift +++ b/BeeReel/Delegate/SceneDelegate.swift @@ -19,7 +19,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { window = UIWindow(windowScene: windowScene) - window?.rootViewController = BRTabBarController() + BRAppTool.tabBarController = BRTabBarController() + window?.rootViewController = BRAppTool.tabBarController + window?.makeKeyAndVisible() } diff --git a/BeeReel/Lib/AppTool/BRAppTool.swift b/BeeReel/Lib/AppTool/BRAppTool.swift index ea9025c..53116e6 100644 --- a/BeeReel/Lib/AppTool/BRAppTool.swift +++ b/BeeReel/Lib/AppTool/BRAppTool.swift @@ -11,6 +11,7 @@ class BRAppTool { static var appDelegate: AppDelegate? static var sceneDelegate: SceneDelegate? + static var tabBarController: BRTabBarController? static var windowScene: UIWindowScene? diff --git a/BeeReel/Lib/Player/BRPlayer.swift b/BeeReel/Lib/Player/BRPlayer.swift index 6d4b0b3..5ffc1db 100644 --- a/BeeReel/Lib/Player/BRPlayer.swift +++ b/BeeReel/Lib/Player/BRPlayer.swift @@ -123,8 +123,12 @@ class BRPlayer: NSObject { self.player.stop() } - func seek(toTime: Int) { - self.player.seek(toTime: TimeInterval(toTime)) + func replay() { + player.replay() + } + + func seek(toTime: TimeInterval) { + self.player.seek(toTime: toTime) } } diff --git a/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Contents.json new file mode 100644 index 0000000..6978e99 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Polygon 6@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Polygon 6@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Polygon 6@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Polygon 6@2x.png new file mode 100644 index 0000000..a6f4581 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Polygon 6@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Polygon 6@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Polygon 6@3x.png new file mode 100644 index 0000000..72f4203 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/Polygon 6.imageset/Polygon 6@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Contents.json new file mode 100644 index 0000000..9f525a5 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame 1503@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame 1503@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Frame 1503@2x.png b/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Frame 1503@2x.png new file mode 100644 index 0000000..688fb72 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Frame 1503@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Frame 1503@3x.png b/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Frame 1503@3x.png new file mode 100644 index 0000000..0acbdbf Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/add_icon_01.imageset/Frame 1503@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Contents.json new file mode 100644 index 0000000..526dcd5 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Frame 1492@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Frame 1492@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Frame 1492@2x.png b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Frame 1492@2x.png new file mode 100644 index 0000000..52f1102 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Frame 1492@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Frame 1492@3x.png b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Frame 1492@3x.png new file mode 100644 index 0000000..1a2438a Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_01.imageset/Frame 1492@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.imageset/Contents.json new file mode 100644 index 0000000..5c4d3b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.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/arrow_right_icon_02.imageset/Frame@2x.png b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@2x.png new file mode 100644 index 0000000..3925770 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@3x.png b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@3x.png new file mode 100644 index 0000000..98f2d79 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/arrow_right_icon_02.imageset/Frame@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Contents.json new file mode 100644 index 0000000..e41283c --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Period Drama@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Period Drama@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Period Drama@2x.png b/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Period Drama@2x.png new file mode 100644 index 0000000..bb2517a Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Period Drama@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Period Drama@3x.png b/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Period Drama@3x.png new file mode 100644 index 0000000..4d25318 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/categorie_title_icon.imageset/Period Drama@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Component 2@2x.png b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Component 2@2x.png new file mode 100644 index 0000000..b0a9979 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Component 2@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Component 2@3x.png b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Component 2@3x.png new file mode 100644 index 0000000..fd11f15 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Component 2@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Contents.json new file mode 100644 index 0000000..19b16b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Component 2@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Component 2@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Component 2@2x.png b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Component 2@2x.png new file mode 100644 index 0000000..55210c5 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Component 2@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Component 2@3x.png b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Component 2@3x.png new file mode 100644 index 0000000..49737ca Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Component 2@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Contents.json new file mode 100644 index 0000000..19b16b1 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/favorite_icon_04_selected.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Component 2@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Component 2@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Contents.json new file mode 100644 index 0000000..116345c --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Ellipse 114@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Ellipse 114@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Ellipse 114@2x.png b/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Ellipse 114@2x.png new file mode 100644 index 0000000..4430212 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Ellipse 114@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Ellipse 114@3x.png b/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Ellipse 114@3x.png new file mode 100644 index 0000000..e79cf3c Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/light_icon_02.imageset/Ellipse 114@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.imageset/Contents.json new file mode 100644 index 0000000..b3858aa --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.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/light_icon_03.imageset/顶部bg@2x.png b/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.imageset/顶部bg@2x.png new file mode 100644 index 0000000..638d206 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.imageset/顶部bg@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.imageset/顶部bg@3x.png b/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.imageset/顶部bg@3x.png new file mode 100644 index 0000000..037f169 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/light_icon_03.imageset/顶部bg@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Contents.json new file mode 100644 index 0000000..8a1e1bf --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Privacy Policy@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Privacy Policy@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Privacy Policy@2x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Privacy Policy@2x.png new file mode 100644 index 0000000..977c3da Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Privacy Policy@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Privacy Policy@3x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Privacy Policy@3x.png new file mode 100644 index 0000000..77b5590 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_01.imageset/Privacy Policy@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Contents.json new file mode 100644 index 0000000..f6a1eb0 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Help Center@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Help Center@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Help Center@2x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Help Center@2x.png new file mode 100644 index 0000000..beff69d Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Help Center@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Help Center@3x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Help Center@3x.png new file mode 100644 index 0000000..7b183ce Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_02.imageset/Help Center@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/Contents.json new file mode 100644 index 0000000..481be51 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "User Agreement@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "User Agreement@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/User Agreement@2x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/User Agreement@2x.png new file mode 100644 index 0000000..84a53f1 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/User Agreement@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/User Agreement@3x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/User Agreement@3x.png new file mode 100644 index 0000000..5709f8e Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_03.imageset/User Agreement@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/About Us@2x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/About Us@2x.png new file mode 100644 index 0000000..0359807 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/About Us@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/About Us@3x.png b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/About Us@3x.png new file mode 100644 index 0000000..cd0ff31 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/About Us@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/Contents.json new file mode 100644 index 0000000..58cc5d3 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/mine_item_icon_04.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "About Us@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "About Us@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_01.imageset/Contents.json index 725eae5..ca0c402 100644 --- a/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_01.imageset/Contents.json +++ b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_01.imageset/Contents.json @@ -18,5 +18,8 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" } } diff --git a/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Component 46@2x.png b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Component 46@2x.png new file mode 100644 index 0000000..634aa0f Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Component 46@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Component 46@3x.png b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Component 46@3x.png new file mode 100644 index 0000000..ffa596c Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Component 46@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Contents.json new file mode 100644 index 0000000..e2213ad --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/nav_back_icon_02.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Component 46@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Component 46@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "original" + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Contents.json new file mode 100644 index 0000000..b15ba9e --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Polygon 1@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Polygon 1@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Polygon 1@2x.png b/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Polygon 1@2x.png new file mode 100644 index 0000000..a07f3ff Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Polygon 1@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Polygon 1@3x.png b/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Polygon 1@3x.png new file mode 100644 index 0000000..efdceee Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/play_icon_06.imageset/Polygon 1@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.imageset/Contents.json new file mode 100644 index 0000000..d2f4b6c --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.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/stars_icon_01.imageset/星星@2x.png b/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.imageset/星星@2x.png new file mode 100644 index 0000000..1d0a65c Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.imageset/星星@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.imageset/星星@3x.png b/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.imageset/星星@3x.png new file mode 100644 index 0000000..93ac60f Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/stars_icon_01.imageset/星星@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Contents.json new file mode 100644 index 0000000..dd0db90 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Favorites@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "Favorites@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@2x.png b/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@2x.png new file mode 100644 index 0000000..6e97c9c Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@3x.png b/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@3x.png new file mode 100644 index 0000000..b3aeef5 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@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..389b8ad --- /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..f969223 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..7ae13d0 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/icon/默认头像.imageset/默认头像@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/Contents.json new file mode 100644 index 0000000..eb5c968 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/Contents.json @@ -0,0 +1,44 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "框@2x.png", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 339, + "right" : 12 + }, + "center" : { + "mode" : "tile", + "width" : 24 + }, + "mode" : "3-part-horizontal" + }, + "scale" : "2x" + }, + { + "filename" : "框@3x.png", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 473, + "right" : 18 + }, + "center" : { + "mode" : "tile", + "width" : 36 + }, + "mode" : "3-part-horizontal" + }, + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/框@2x.png b/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/框@2x.png new file mode 100644 index 0000000..d032511 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/框@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/框@3x.png b/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/框@3x.png new file mode 100644 index 0000000..a816ad4 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/image/add_bg_image_01.imageset/框@3x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Contents.json new file mode 100644 index 0000000..a11b6ec --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Contents.json @@ -0,0 +1,44 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "Rectangle 82@2x.png", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 38, + "right" : 255 + }, + "center" : { + "mode" : "tile", + "width" : 1 + }, + "mode" : "3-part-horizontal" + }, + "scale" : "2x" + }, + { + "filename" : "Rectangle 82@3x.png", + "idiom" : "universal", + "resizing" : { + "cap-insets" : { + "left" : 53, + "right" : 371 + }, + "center" : { + "mode" : "tile", + "width" : 1 + }, + "mode" : "3-part-horizontal" + }, + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Rectangle 82@2x.png b/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Rectangle 82@2x.png new file mode 100644 index 0000000..eb6d7e2 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Rectangle 82@2x.png differ diff --git a/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Rectangle 82@3x.png b/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Rectangle 82@3x.png new file mode 100644 index 0000000..98cd416 Binary files /dev/null and b/BeeReel/Sources/Assets.xcassets/image/history_bg_image.imageset/Rectangle 82@3x.png differ diff --git a/BeeReel/Sources/Localizable.xcstrings b/BeeReel/Sources/Localizable.xcstrings index 69e41c3..8cef08a 100644 --- a/BeeReel/Sources/Localizable.xcstrings +++ b/BeeReel/Sources/Localizable.xcstrings @@ -1,6 +1,17 @@ { "sourceLanguage" : "en", "strings" : { + "About Us" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "About Us" + } + } + } + }, "All ## Episodes" : { "extractionState" : "manual", "localizations" : { @@ -34,6 +45,17 @@ } } }, + "Child Personal Information Protection Rules" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Child Personal Information Protection Rules" + } + } + } + }, "EP.##" : { "extractionState" : "manual", "localizations" : { @@ -45,6 +67,28 @@ } } }, + "Expand Your Favorites" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Expand Your Favorites" + } + } + } + }, + "Explicit List of Personal Information Collection" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Explicit List of Personal Information Collection" + } + } + } + }, "Fresh Stories" : { "extractionState" : "manual", "localizations" : { @@ -56,6 +100,17 @@ } } }, + "Help Center" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Help Center" + } + } + } + }, "New Releases" : { "extractionState" : "manual", "localizations" : { @@ -78,6 +133,17 @@ } } }, + "Privacy Policy" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Privacy Policy" + } + } + } + }, "Speed" : { "extractionState" : "manual", "localizations" : { @@ -100,6 +166,9 @@ } } }, + "Third-party information sharing list" : { + "extractionState" : "manual" + }, "Top 10" : { "extractionState" : "manual", "localizations" : { @@ -121,6 +190,39 @@ } } } + }, + "User Agreement" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "User Agreement" + } + } + } + }, + "Visitor" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Visitor" + } + } + } + }, + "Youth Internet Civility Convention" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Youth Internet Civility Convention" + } + } + } } }, "version" : "1.0"