From cb7fadea6bcc620d7e366bbb1edfc6e9200ef1fc Mon Sep 17 00:00:00 2001 From: zeng Date: Thu, 24 Jul 2025 16:40:34 +0800 Subject: [PATCH] 1.0 --- BeeReel.xcodeproj/project.pbxproj | 16 ++- .../Base/Controller/BRTabBarController.swift | 2 +- .../BRFavoritesPageViewController.swift | 81 +++++++++++ .../BRFavoritesViewController.swift | 68 +++------- .../BRPlayHistorysViewController.swift | 126 ++++++++++++++++++ .../Favorites/View/BRFavoritesCell.swift | 66 ++++----- .../View/BRFavoritesHeaderView.swift | 4 +- .../Favorites/View/BRPlayHistorysCell.swift | 126 ++++++++++++++++++ .../View/Spotlight/BRSpotlightHotCell.swift | 76 +++++------ .../Contents.json | 0 .../Favorites 1.imageset/Favorites@2x.png | Bin 0 -> 4558 bytes .../Favorites 1.imageset/Favorites@3x.png | Bin 0 -> 7102 bytes .../icon/Favorites.imageset/Contents.json | 22 +++ .../Favorites@2x.png | Bin .../Favorites@3x.png | Bin .../icon/history 1.imageset/Contents.json | 22 +++ .../icon/history 1.imageset/history@2x.png | Bin 0 -> 3681 bytes .../icon/history 1.imageset/history@3x.png | Bin 0 -> 5608 bytes .../icon/history.imageset/Contents.json | 22 +++ .../icon/history.imageset/history@2x.png | Bin 0 -> 4080 bytes .../icon/history.imageset/history@3x.png | Bin 0 -> 6257 bytes 21 files changed, 506 insertions(+), 125 deletions(-) create mode 100644 BeeReel/Class/Favorites/Controller/BRFavoritesPageViewController.swift create mode 100644 BeeReel/Class/Favorites/Controller/BRPlayHistorysViewController.swift create mode 100644 BeeReel/Class/Favorites/View/BRPlayHistorysCell.swift rename BeeReel/Sources/Assets.xcassets/icon/{title_icon_01.imageset => Favorites 1.imageset}/Contents.json (100%) create mode 100644 BeeReel/Sources/Assets.xcassets/icon/Favorites 1.imageset/Favorites@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/Favorites 1.imageset/Favorites@3x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/Favorites.imageset/Contents.json rename BeeReel/Sources/Assets.xcassets/icon/{title_icon_01.imageset => Favorites.imageset}/Favorites@2x.png (100%) rename BeeReel/Sources/Assets.xcassets/icon/{title_icon_01.imageset => Favorites.imageset}/Favorites@3x.png (100%) create mode 100644 BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/Contents.json create mode 100644 BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/history@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/history@3x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/history.imageset/Contents.json create mode 100644 BeeReel/Sources/Assets.xcassets/icon/history.imageset/history@2x.png create mode 100644 BeeReel/Sources/Assets.xcassets/icon/history.imageset/history@3x.png diff --git a/BeeReel.xcodeproj/project.pbxproj b/BeeReel.xcodeproj/project.pbxproj index 057bc9a..7fe2690 100644 --- a/BeeReel.xcodeproj/project.pbxproj +++ b/BeeReel.xcodeproj/project.pbxproj @@ -152,6 +152,9 @@ BFC676B92E1385FC006659E5 /* BRPopularPicksSmallCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676B82E1385FC006659E5 /* BRPopularPicksSmallCell.swift */; }; BFC676BC2E138ABB006659E5 /* BRNewReleasesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676BB2E138ABB006659E5 /* BRNewReleasesViewController.swift */; }; BFC676BE2E13A8EB006659E5 /* UIScrollView+BRRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */; }; + F39855202E32166300E2D28D /* BRFavoritesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */; }; + F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */; }; + F39855242E3222BE00E2D28D /* BRPlayHistorysCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -315,6 +318,9 @@ BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+BRRefresh.swift"; sourceTree = ""; }; C8F11086BA392585E9563BA7 /* Pods-ShortBox.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShortBox.release.xcconfig"; path = "Target Support Files/Pods-ShortBox/Pods-ShortBox.release.xcconfig"; sourceTree = ""; }; F06627B1DEE86552C2A87AEC /* Pods-BeeReel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BeeReel.debug.xcconfig"; path = "Target Support Files/Pods-BeeReel/Pods-BeeReel.debug.xcconfig"; sourceTree = ""; }; + F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRFavoritesPageViewController.swift; sourceTree = ""; }; + F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysViewController.swift; sourceTree = ""; }; + F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysCell.swift; sourceTree = ""; }; F70FA1F4169364C4C53534CE /* Pods-BeeReel.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BeeReel.release.xcconfig"; path = "Target Support Files/Pods-BeeReel/Pods-BeeReel.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -363,7 +369,9 @@ BF02B8062E2F613600172177 /* Controller */ = { isa = PBXGroup; children = ( + F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */, BF02B8072E2F616E00172177 /* BRFavoritesViewController.swift */, + F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */, ); path = Controller; sourceTree = ""; @@ -371,8 +379,9 @@ BF02B80B2E2F63C600172177 /* View */ = { isa = PBXGroup; children = ( - BF02B80C2E2F63ED00172177 /* BRFavoritesCell.swift */, BF02B80E2E2F6EEA00172177 /* BRFavoritesHeaderView.swift */, + BF02B80C2E2F63ED00172177 /* BRFavoritesCell.swift */, + F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */, ); path = View; sourceTree = ""; @@ -1147,6 +1156,7 @@ BF3338F72E16176900B10F76 /* BRDetailPlayerCell.swift in Sources */, BF3338EA2E152B8100B10F76 /* BRPlayerCache.swift in Sources */, BF3A56832E30C561009E5CF9 /* BRSearchResultView.swift in Sources */, + F39855242E3222BE00E2D28D /* BRPlayHistorysCell.swift in Sources */, BFC676952E126BBF006659E5 /* BRSpotlightNewCell.swift in Sources */, BF692B402E0A8FA100A5C2DA /* UIColor+BRAdd.swift in Sources */, BF692B102E0A7B4300A5C2DA /* BRUserDefaultsKey.swift in Sources */, @@ -1180,6 +1190,7 @@ BF3338FD2E1626B000B10F76 /* BRPlayerControlProtocol.swift in Sources */, BF692B582E0AAA6F00A5C2DA /* UIScreen+BRAdd.swift in Sources */, BF692B1F2E0A804600A5C2DA /* BRLocalizedManager.swift in Sources */, + F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */, BF02B7E92E2E29E900172177 /* BREpisodeSelectorCell.swift in Sources */, BF02B83B2E30BB4C00172177 /* BRHotSearchView.swift in Sources */, BF02B8332E308E4300172177 /* BRSearchRecordTagCell.swift in Sources */, @@ -1198,6 +1209,7 @@ BF02B8022E2F39FE00172177 /* BRCategorieShortViewController.swift in Sources */, BF3338FB2E161CF900B10F76 /* NSNumber+BRAdd.swift in Sources */, BF692B222E0A820D00A5C2DA /* String+BRAdd.swift in Sources */, + F39855202E32166300E2D28D /* BRFavoritesPageViewController.swift in Sources */, BF02B80F2E2F6EEA00172177 /* BRFavoritesHeaderView.swift in Sources */, BF692B632E0B9D4800A5C2DA /* BRTabBarItem.swift in Sources */, BFC6768B2E123690006659E5 /* BRVideoRevolutionManager.swift in Sources */, @@ -1268,6 +1280,7 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BeeReel/Sources/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = BeeReel; + INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = ""; @@ -1303,6 +1316,7 @@ GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = BeeReel/Sources/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = BeeReel; + INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; INFOPLIST_KEY_UIMainStoryboardFile = ""; diff --git a/BeeReel/Base/Controller/BRTabBarController.swift b/BeeReel/Base/Controller/BRTabBarController.swift index 77ae065..15fa39c 100644 --- a/BeeReel/Base/Controller/BRTabBarController.swift +++ b/BeeReel/Base/Controller/BRTabBarController.swift @@ -72,7 +72,7 @@ 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: BRFavoritesViewController(), title: "首页".localized, image: UIImage(named: "tabbar_icon_03"), selectedImage: UIImage(named: "tabbar_icon_03_selected")) + let nav3 = createNavigationController(viewController: BRFavoritesPageViewController(), 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] diff --git a/BeeReel/Class/Favorites/Controller/BRFavoritesPageViewController.swift b/BeeReel/Class/Favorites/Controller/BRFavoritesPageViewController.swift new file mode 100644 index 0000000..5f6c96a --- /dev/null +++ b/BeeReel/Class/Favorites/Controller/BRFavoritesPageViewController.swift @@ -0,0 +1,81 @@ +// +// BRFavoritesPageViewController.swift +// BeeReel +// +// Created by 长沙鸿瑶 on 2025/7/24. +// + +import UIKit +import WMZPageController + +class BRFavoritesPageViewController: BRViewController { + + private lazy var vcArr: [BRViewController] = { + let arr = [ + BRFavoritesViewController(), + BRPlayHistorysViewController(), + ] + return arr + }() + + private lazy var pageParam: WMZPageParam = { + let param = WMZPageParam() + param.wTitleArr = [ + [WMZPageBTNKey.keyImage : "Favorites 1", WMZPageBTNKey.keySelectImage : "Favorites", WMZPageBTNKey.keyTitleWidth : UIImage(named: "Favorites")?.size.width ?? 0], + [WMZPageBTNKey.keyImage : "history 1", WMZPageBTNKey.keySelectImage : "history", WMZPageBTNKey.keyTitleWidth : UIImage(named: "history")?.size.width ?? 0], + ] + param.wViewController = { [weak self] index in + return self?.vcArr[index] + } + + //顶部可下拉 + param.wBounces = false + + param.wMenuHeight = 25 + param.wMenuTitleOffset = 20 + param.wMenuInsets = UIEdgeInsets(top: 0, left: 15, bottom: 0, right: 15) + param.wMenuBgColor = .clear + param.wBgColor = .clear + + + param.wCustomNaviBarY = { _ in + return UIScreen.statusBarHeight + 18 + } + param.wCustomTabbarY = { _ in + return 0 + } + + return param + }() + + private lazy var pageView: WMZPageView = { + let view = WMZPageView(frame: self.view.bounds, autoFix: true, param: pageParam, parentReponder: self) + view.backgroundColor = .clear + view.downSc?.backgroundColor = .clear + return view + }() + + override func viewDidLoad() { + super.viewDidLoad() + self.navigationController?.isNavigationBarHidden = true + + br_setupUI() + } + + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + self.navigationController?.setNavigationBarHidden(true, animated: true) + } + +} + +extension BRFavoritesPageViewController { + + private func br_setupUI() { + view.addSubview(pageView) + + + } + +} diff --git a/BeeReel/Class/Favorites/Controller/BRFavoritesViewController.swift b/BeeReel/Class/Favorites/Controller/BRFavoritesViewController.swift index 569103d..1b8c49c 100644 --- a/BeeReel/Class/Favorites/Controller/BRFavoritesViewController.swift +++ b/BeeReel/Class/Favorites/Controller/BRFavoritesViewController.swift @@ -12,23 +12,6 @@ class BRFavoritesViewController: BRViewController { private lazy var listArr: [BRShortModel] = [] private lazy var page = 1 - ///播放历史 - private var playHistoryModel: BRShortModel? { - didSet { - if let _ = playHistoryModel { - self.collectionViewLayout.headerReferenceSize = .init(width: UIScreen.width, height: 180) - } else { - self.collectionViewLayout.headerReferenceSize = .zero - } - - 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) @@ -79,23 +62,10 @@ class BRFavoritesViewController: BRViewController { requestDataList(page: 1, completer: nil) - requestPlayHistorys() } - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - self.navigationController?.setNavigationBarHidden(true, animated: true) - } - - override func viewDidAppear(_ animated: Bool) { - if self.hasViewDidAppear { - requestPlayHistorys() - } - super.viewDidAppear(animated) - } override func handleHeaderRefresh(_ completer: (() -> Void)?) { - self.requestPlayHistorys() self.requestDataList(page: 1) { [weak self] in self?.collectionView.br_endHeaderRefreshing() } @@ -108,7 +78,7 @@ class BRFavoritesViewController: BRViewController { } private func updateEmptyStatus() { - if listArr.isEmpty, self.playHistoryModel == nil { + if listArr.isEmpty { self.collectionView.ly_showEmpty() } else { self.collectionView.ly_hideEmpty() @@ -120,18 +90,12 @@ class BRFavoritesViewController: BRViewController { 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.top.equalToSuperview().offset(18) make.bottom.equalTo(addFavoritesButton.snp.top).offset(-10) } @@ -157,18 +121,21 @@ extension BRFavoritesViewController { 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] + cell.model = self.listArr[indexPath.row + 1] return cell } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return self.listArr.count + if self.listArr.count == 0 { + return 0 + } + return self.listArr.count - 1 } 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 + view.model = self.listArr.first return view } else { return UICollectionReusableView() @@ -176,7 +143,7 @@ extension BRFavoritesViewController: UICollectionViewDelegate, UICollectionViewD } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - let model = self.listArr[indexPath.row] + let model = self.listArr[indexPath.row + 1] let vc = BRVideoDetailViewController() vc.shortPlayId = model.short_play_id self.navigationController?.pushViewController(vc, animated: true) @@ -198,23 +165,22 @@ extension BRFavoritesViewController { $0.is_collect = true } self.listArr += list + + if self.listArr.count > 0 { + self.collectionViewLayout.headerReferenceSize = .init(width: UIScreen.width, height: 180) + } else { + self.collectionViewLayout.headerReferenceSize = .zero + } + self.page = page self.collectionView.reloadData() } + self.updateEmptyStatus() 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 - self.updateEmptyStatus() - } - } - } diff --git a/BeeReel/Class/Favorites/Controller/BRPlayHistorysViewController.swift b/BeeReel/Class/Favorites/Controller/BRPlayHistorysViewController.swift new file mode 100644 index 0000000..c8c7898 --- /dev/null +++ b/BeeReel/Class/Favorites/Controller/BRPlayHistorysViewController.swift @@ -0,0 +1,126 @@ +// +// BRPlayHistorysViewController.swift +// BeeReel +// +// Created by 长沙鸿瑶 on 2025/7/24. +// + +import UIKit + +class BRPlayHistorysViewController: BRViewController { + + private lazy var listArr: [BRShortModel] = [] + private lazy var page = 1 + + 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.ly_emptyView = BREmpty.br_normalEmptyView() + collectionView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.customTabBarHeight + 10, right: 0) + collectionView.br_addRefreshHeader { [weak self] in + self?.handleHeaderRefresh(nil) + } + collectionView.br_addRefreshBackFooter(insetBottom: 0) { [weak self] in + self?.handleFooterRefresh(nil) + } + collectionView.register(BRPlayHistorysCell.self, forCellWithReuseIdentifier: "cell") + return collectionView + }() + + override func viewDidLoad() { + super.viewDidLoad() + requestDataList(page: 1, completer: nil) + + view.addSubview(collectionView) + + collectionView.snp.makeConstraints { make in + make.top.equalToSuperview().offset(18) + make.left.right.bottom.equalToSuperview() + } + + } + + override func viewDidAppear(_ animated: Bool) { + if self.hasViewDidAppear { + requestDataList(page: 1, completer: nil) + } + super.viewDidAppear(animated) + } + + 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() + } + } + + +} + + +// MARK: - UICollectionViewDelegate & UICollectionViewDataSource +extension BRPlayHistorysViewController: UICollectionViewDelegate, UICollectionViewDataSource { + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRPlayHistorysCell + cell.model = self.listArr[indexPath.row] + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.listArr.count + } + + 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 BRPlayHistorysViewController { + + private func requestDataList(page: Int, completer: (() -> Void)?) { + + BRVideoAPI.requestPlayHistorys(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?() + } + + } + + + +} + diff --git a/BeeReel/Class/Favorites/View/BRFavoritesCell.swift b/BeeReel/Class/Favorites/View/BRFavoritesCell.swift index a50338f..d02b734 100644 --- a/BeeReel/Class/Favorites/View/BRFavoritesCell.swift +++ b/BeeReel/Class/Favorites/View/BRFavoritesCell.swift @@ -13,17 +13,17 @@ class BRFavoritesCell: BRCollectionViewCell { 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 +// 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 } @@ -34,17 +34,17 @@ class BRFavoritesCell: BRCollectionViewCell { 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 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) @@ -99,23 +99,23 @@ extension BRFavoritesCell { private func br_setupUI() { contentView.addSubview(coverView) - contentView.addSubview(bottomView) - bottomView.addSubview(epLabel) +// 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() - } +// 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) diff --git a/BeeReel/Class/Favorites/View/BRFavoritesHeaderView.swift b/BeeReel/Class/Favorites/View/BRFavoritesHeaderView.swift index ef2b119..4cee43c 100644 --- a/BeeReel/Class/Favorites/View/BRFavoritesHeaderView.swift +++ b/BeeReel/Class/Favorites/View/BRFavoritesHeaderView.swift @@ -34,6 +34,8 @@ class BRFavoritesHeaderView: UICollectionReusableView { private lazy var bgView: UIImageView = { let view = UIImageView(image: UIImage(named: "history_bg_image")) view.isUserInteractionEnabled = true + let tap = UITapGestureRecognizer(target: self, action: #selector(handlePlayButton)) + view.addGestureRecognizer(tap) return view }() @@ -47,11 +49,11 @@ class BRFavoritesHeaderView: UICollectionReusableView { private lazy var playButton: UIButton = { let button = UIButton(type: .custom) + button.isUserInteractionEnabled = false 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 }() diff --git a/BeeReel/Class/Favorites/View/BRPlayHistorysCell.swift b/BeeReel/Class/Favorites/View/BRPlayHistorysCell.swift new file mode 100644 index 0000000..08f2d4a --- /dev/null +++ b/BeeReel/Class/Favorites/View/BRPlayHistorysCell.swift @@ -0,0 +1,126 @@ +// +// BRPlayHistorysCell.swift +// BeeReel +// +// Created by 长沙鸿瑶 on 2025/7/24. +// + +import UIKit + +class BRPlayHistorysCell: 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 BRPlayHistorysCell { + + 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/Home/View/Spotlight/BRSpotlightHotCell.swift b/BeeReel/Class/Home/View/Spotlight/BRSpotlightHotCell.swift index ebdfe18..b319990 100644 --- a/BeeReel/Class/Home/View/Spotlight/BRSpotlightHotCell.swift +++ b/BeeReel/Class/Home/View/Spotlight/BRSpotlightHotCell.swift @@ -15,7 +15,7 @@ class BRSpotlightHotCell: BRCollectionViewCell { titleLabel.text = model?.name categoryLabel.text = model?.category?.first - favoriteButton.isSelected = self.model?.is_collect ?? false +// favoriteButton.isSelected = self.model?.is_collect ?? false hotView.setNeedsUpdateConfiguration() } @@ -68,23 +68,23 @@ class BRSpotlightHotCell: BRCollectionViewCell { return button }() - private lazy var favoriteButton: UIButton = { - let button = UIButton(type: .custom) - button.setImage(UIImage(named: "favorite_icon_01"), for: .normal) - button.setImage(UIImage(named: "favorite_icon_01_selected"), for: .selected) - button.setImage(UIImage(named: "favorite_icon_01_selected"), for: [.selected, .highlighted]) - button.addTarget(self, action: #selector(handleFavoriteButton), for: .touchUpInside) - return button - }() +// private lazy var favoriteButton: UIButton = { +// let button = UIButton(type: .custom) +// button.setImage(UIImage(named: "favorite_icon_01"), for: .normal) +// button.setImage(UIImage(named: "favorite_icon_01_selected"), for: .selected) +// button.setImage(UIImage(named: "favorite_icon_01_selected"), for: [.selected, .highlighted]) +// button.addTarget(self, action: #selector(handleFavoriteButton), for: .touchUpInside) +// return button +// }() - deinit { - NotificationCenter.default.removeObserver(self) - } +// 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) +// NotificationCenter.default.addObserver(self, selector: #selector(updateShortFavoriteStateNotification), name: BRVideoAPI.updateShortFavoriteStateNotification, object: nil) contentView.backgroundColor = .colorFFFFFF() contentView.layer.cornerRadius = 10 @@ -98,27 +98,27 @@ class BRSpotlightHotCell: BRCollectionViewCell { } - @objc private func handleFavoriteButton() { - guard let shortPlayId = self.model?.short_play_id else { return } - - let isFavorite = !(self.model?.is_collect ?? false) - let videoId = self.model?.short_play_video_id - - BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: videoId) { - - } - } +// @objc private func handleFavoriteButton() { +// guard let shortPlayId = self.model?.short_play_id else { return } +// +// let isFavorite = !(self.model?.is_collect ?? false) +// let videoId = self.model?.short_play_video_id +// +// BRVideoAPI.requestFavorite(isFavorite: isFavorite, shortPlayId: shortPlayId, videoId: videoId) { +// +// } +// } - @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 - } +// @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 +// } } @@ -126,7 +126,7 @@ extension BRSpotlightHotCell { private func br_setupUI() { contentView.addSubview(coverImageView) - contentView.addSubview(favoriteButton) +// contentView.addSubview(favoriteButton) contentView.addSubview(titleLabel) contentView.addSubview(playIconImageView) contentView.addSubview(categoryLabel) @@ -137,10 +137,10 @@ extension BRSpotlightHotCell { make.height.equalTo(160) } - favoriteButton.snp.makeConstraints { make in - make.top.equalToSuperview().offset(4) - make.right.equalToSuperview().offset(-4) - } +// favoriteButton.snp.makeConstraints { make in +// make.top.equalToSuperview().offset(4) +// make.right.equalToSuperview().offset(-4) +// } titleLabel.snp.makeConstraints { make in make.left.equalToSuperview().offset(7) diff --git a/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Favorites 1.imageset/Contents.json similarity index 100% rename from BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Contents.json rename to BeeReel/Sources/Assets.xcassets/icon/Favorites 1.imageset/Contents.json diff --git a/BeeReel/Sources/Assets.xcassets/icon/Favorites 1.imageset/Favorites@2x.png b/BeeReel/Sources/Assets.xcassets/icon/Favorites 1.imageset/Favorites@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..6627104838f4bc5e32978fa35c93006e101bae33 GIT binary patch literal 4558 zcmV;<5i#zGP)YbqM1XUL(iX(rJPZV$m zP;z3s`aO>#ha^CJ+&2yo(HUo)amE>EJZG%e>#6@t=!};SKhYJP5KK6yuJer3!_U$6 zd7gUwk6th^$^6;S2>{J-#r4f*vy;^M9O1{I_FvnlItD!N7Z(@5I_Ez6Hnw!e%Vcyg zzsSy`PmcCdtc|4{)2$vocqt}2{ZYXpQk%NPqU}WI zsejL^pbWQ>=l&X+{5e<~-%MeAcSeU9$dh_YBM~&XA3!F?-~8Xd95aXQOn4>q z!MAbYKbPOy+PElr80PC+IugF4Of(zc@n1awUHHGRtui1~89n96{n39<@!3L)XK8_^ zX}%8X>*~a{3EKI^e_dNb0~2_qJkok=;5}u63D+~&yC7)rkzk>-3FBzg#eL!Ny_Nky zo2Q9lVNAQWvl&eNcypWn7a9Pp=3xR6rTgTeT{qwL2P*7JVbodPTj!SLr>tNh}n|n4ie|-lrJ;6=forax@;yjF-L>KZ0qe z+_0R27^oA#nh0oJ^vFge#_F*yqhPta>HLQQ4h;M4Cc4CO`E zbnpe=M~Il8)rcrC;4MtzMdCRYa(AqW$pBjegG&v@c>;Q9&iSC7VQw0fnbYxT zViwymmMd#m(E3}nv%+=N^}(F|5wTEm&?y{VQjFcqW^^hiz#Uiu^CUu2EvfHBlM{Sn z(~aVc6imun5JYL4{*GMxj0yUg`lzT1W>AF*LY+589d#gd8jnd3hCyh+OiaZpYNf8g zfZN=5@w+r;ADY2DCV?J;We3Y(Px!*R31ySv6H|sM>;42yo16>OpG%>=|6G3Bc-oofT0G<8gNO7 zF@Sj6)P2t!@1Vtxnq0zo2=lmh%JNcbyn=NE1}th9&+X8v5bp~naG(b^yVrsq+M(Yn z1iWOPuLI^e1)AXnk$+Kw4Fu!{f@n`szzvE5V{Iyy0xb9+1U7kZQf`1l*8@N2ir3j3^0h14XZI#F~f;Fucbm8D4tQ)J14ZbUi2wMcQ zt`W$(#)I9|7v_Q`m6SfyAM>*COJRd3MWl5a62jYplj;reC0HvC_#Y>Y{_z0z)` z+%LZ7-}^=Ih_p&OMKHALav5D~P?z%zt$&h~K6IcWEOSw>4Oq%+?cnFl$%Wt2_|H^m z$5| zNQ{}&exgRu225xv>tafIQhcK@NlyD}Qna~K{9~AE$+Dy@#qqenG;AZTi-hL0hSi44 zm~|B9QbA?h4+4Le=?GUrD;N4ZElet^jYr06^jf*s`cD(w3uFtfXgsvJ;_bDS5>WjK z8lT%UfdbgM$is3bqZ|G?59TO_NxchxTnKKw6H!)X{Ev~Oi-3yk`a74v4+>{@y+^{u zgbIK%DX0NB>c_E4-Aq{m&@v6iL$xL{aIIKJjaD$S7B0~WOGFaC<@R-DX65@FYVGE1 zz!0d54Ngl5qL2CL2BWG0 zIGCDM>b~pq>SN`m@LgrFr=m1c{{081uR$l7PDI>OXqCR#sX`g9f`jXe`4B zNQO3a5pd%%wtPO2jS4i-3fE{!1uz+X;GZ|>fEvhB5cR>ph^y2x7kqVwCjFCbNfEHG z_fOvs$^o=_mAY?fbFvd6n&AazPOrt^xWhD7&8pZ-L=wwYHR+fnHl5UDxJ53J%3KoI zDnW*S-iT+b0ux(~tF_W&!PL6&uWzj2Zmcaq%jYt@ni(hka~DZlq%yS1fKRX%9P{^= z179SCYJ?k+EjYBvaCU-N44Zx;Y5|T&kO`bl6UryVX`x_5{@99ue7z~3w`aC znS2Ya&slZ5%(9E}6y_vczxn4)Mr6BAT<C_e zdtq!l&Ok$j;I{HU0~R#U;@#$|%(l!e>&5cX8zpVg4CxQBGi5>wpHmV?D6J`5N_RYU zJ^2pn0r*8#;&y`|VbIu3f?!jOE(4ovs^4oG5JB_+p5SSR4P_x2dHJy2jGyGIc-6=+;t< z%RHE2h{TB?F-(wAb#OgZ0NO4jYUBiAwEL5c1ecoI=%4v*rk|1%YqJb&u3bjza8A%B zb}=Jqr35u)Y)GQS1{~`1BR*l7YRr*JQecHKB$4mGoMoQi5|EL{|EQ<_3gNX=6!>29 zXPvjtpw`|IW%P`t7)DXYMKa74^%BoybSn3`neqMtLFEV`H5eySag*hpa;irPF!yi8 z@j@n(hqO}Vk)^^kQ=>hvg}=<2?T^&65T=??3(raae7NDFb|a5s=Dc#WxrQ`~j9?4NEMUlL8HY2{V3_W%g>&kO?+A=Mih-Joi($F}K_njb{0t)6Z~F z`>`$>aDLlTarH7-mVu4Myy=-C8 z$ozUh^Xu;;*DS(T+Z$Yr)RJte)@2~=bLzzDH$zRFyRxwE&wl?E?c+R!k4BMGne9?z zGd;}2(Q1`d*vS4=+t@KWOok1ZktMAvZJ7{oM2%@$vq>to9*DN069Q4-Ku~vu+M+Fa z)>=}Efdh8jJ`mT=%nV?`ml{j#cGKQx9dKd!=bMOzUMbJ376PS7V2ysA0j(N8vv*fecqozQ5NrhVM_10lLtkMhWh#-Ws6B*MX!jhyS484Y^4bNb;a#c-MV z?y1bUVdsO1c&qsyDOlNMr0;%`=+<6IIoJC_IT}J<7dKF?XTs39MVKZKucTBX~@Vkh;6XRSjuZ@ z1dM>0>7Oeo*63m!W5;6e2^{<=18Z_Vm;N;$SP8*@%-(|_>=(HOVy649<1T)9V3Fix zlLh8V8@uoNtg@Usw*%9srPH9Lhq^*=Paa>j%@jnzZ(SPep{@UVv+jTLhqYp@RLk|O zT*hx}#UPkt?+gK$m~95rHKZ@4)pV%&HO3jM&BME*IKn>1dOo|#1_V#(M5+(`R=eQj(U@mwaGX8ZSJQGEBS{J0%Y#t^pXD%1dK}u&(_S=JGj0WGYtF(??4$1vx3L sFA4v({+>~W9RK}U;Y{#nobj^pFZ#ggZp`Y( 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 literal 0 HcmV?d00001 diff --git a/BeeReel/Sources/Assets.xcassets/icon/Favorites.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/Favorites.imageset/Contents.json new file mode 100644 index 0000000..dd0db90 --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/Favorites.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/Favorites.imageset/Favorites@2x.png similarity index 100% rename from BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@2x.png rename to BeeReel/Sources/Assets.xcassets/icon/Favorites.imageset/Favorites@2x.png diff --git a/BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@3x.png b/BeeReel/Sources/Assets.xcassets/icon/Favorites.imageset/Favorites@3x.png similarity index 100% rename from BeeReel/Sources/Assets.xcassets/icon/title_icon_01.imageset/Favorites@3x.png rename to BeeReel/Sources/Assets.xcassets/icon/Favorites.imageset/Favorites@3x.png diff --git a/BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/Contents.json b/BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/Contents.json new file mode 100644 index 0000000..a9c623f --- /dev/null +++ b/BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "history@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "history@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/history@2x.png b/BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/history@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..bdad5a18f3c234321302537225b828fb87a910cd GIT binary patch literal 3681 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 literal 0 HcmV?d00001 diff --git a/BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/history@3x.png b/BeeReel/Sources/Assets.xcassets/icon/history 1.imageset/history@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..fdab34c33281e28a37d8d74ba407c9480c3e9bc3 GIT binary patch literal 5608 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 b;_l*q0se67?>S@c00000NkvXXu0mjfFq0U( literal 0 HcmV?d00001