diff --git a/Thimra/Base/Extension/UIColor+SPAdd.swift b/Thimra/Base/Extension/UIColor+SPAdd.swift index 17ec061..4cc8611 100644 --- a/Thimra/Base/Extension/UIColor+SPAdd.swift +++ b/Thimra/Base/Extension/UIColor+SPAdd.swift @@ -172,5 +172,9 @@ extension UIColor { static func colorEC3324(alpha: CGFloat = 1) -> UIColor { return color(hex: 0xEC3324, alpha: alpha) } + + static func colorCCCCCC(alpha: CGFloat = 1) -> UIColor { + return color(hex: 0xCCCCCC, alpha: alpha) + } } diff --git a/Thimra/Base/Networking/API/SPVideoAPI.swift b/Thimra/Base/Networking/API/SPVideoAPI.swift index 05143dc..f25306a 100644 --- a/Thimra/Base/Networking/API/SPVideoAPI.swift +++ b/Thimra/Base/Networking/API/SPVideoAPI.swift @@ -105,16 +105,29 @@ class SPVideoAPI: NSObject { } ///获取视频分类 - static func requestShortCategoryList() { + static func requestShortCategoryList(completer: ((_ list: [SPCategoryModel]?) -> Void)?) { var param = SPNetworkParameters(path: "/getCategories") param.method = .get - SPNetwork.request(parameters: param) { (response: SPNetworkResponse>) in -// completer?(response.data) + SPNetwork.request(parameters: param) { (response: SPNetworkResponse>) in + completer?(response.data?.list) } - } + ///获取分类短剧 + static func requestCategoryShortList(page: Int, id: String, completer: ((_ listModel: SPListModel?) -> Void)?) { + var param = SPNetworkParameters(path: "/videoList") + param.method = .get + param.parameters = [ + "category_id" : id, + "current_page" : page, + "page_size" : 20 + ] + + SPNetwork.request(parameters: param) { (response: SPNetworkResponse>) in + completer?(response.data) + } + } } extension SPVideoAPI { diff --git a/Thimra/Class/Explore/Controller/SPAllShortViewController.swift b/Thimra/Class/Explore/Controller/SPAllShortViewController.swift index 29d0653..a74b275 100644 --- a/Thimra/Class/Explore/Controller/SPAllShortViewController.swift +++ b/Thimra/Class/Explore/Controller/SPAllShortViewController.swift @@ -8,20 +8,203 @@ import UIKit class SPAllShortViewController: SPViewController { - + + + private lazy var allCategoryModel: SPCategoryModel = { + let model = SPCategoryModel() + model.id = "0" + model.name = "All".localized + return model + }() + private lazy var categoryArr: [SPCategoryModel] = [self.allCategoryModel] + private lazy var currentCategoryModel: SPCategoryModel = self.allCategoryModel + + private lazy var dataArr: [SPShortModel] = [] + private lazy var page = 1 + + //MARK: UI属性 + private lazy var tagView: JXTagView = { + let tagView = JXTagView() + tagView.delegate = self + tagView.dataSource = self + tagView.tagHeight = 24 + tagView.tagCornerRadius = 12 + tagView.tagBorderWidth = 1 + tagView.tagBorderColor = .clear + tagView.tagBorderSelectedColor = .colorFF4B5A() + tagView.textColor = .colorCCCCCC() + tagView.textSelectedColor = .colorFF4B5A() + tagView.tagBackgroundColor = .clear + tagView.tagSelectedBackgroundColor = .clear + tagView.textFont = .fontRegular(ofSize: 14) + tagView.textMargin = 14 + tagView.tagVerticalGap = 5 + tagView.tagHorizontalGap = 0 + tagView.leftAndRightMargin = 16 + return tagView + }() + + private lazy var collectionViewLayout: UICollectionViewFlowLayout = { + let width = floor((kSPScreenWidth - 32 - 14 * 2) / 3) + let height = 145 / 105 * width + 36 + + let layout = UICollectionViewFlowLayout() + layout.itemSize = CGSize(width: width, height: height) + layout.minimumLineSpacing = 14 + layout.minimumInteritemSpacing = 14 + layout.sectionInset = .init(top: 0, left: 16, bottom: 0, right: 16) + return layout + }() + + private lazy var bgView: UIView = { + let view = UIView() + view.addEffectView(style: .dark) + return view + }() + + private lazy var collectionView: SPCollectionView = { + let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) + collectionView.delegate = self + collectionView.dataSource = self + collectionView.contentInset = .init(top: 10, left: 0, bottom: 10, right: 0) + collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in + self?.handleHeaderRefresh(nil) + } + collectionView.sp_addRefreshBackFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in + self?.handleFooterRefresh(nil) + } + SPAllShortCell.registerCell(collectionView: collectionView) + return collectionView + }() + override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = .clear - SPVideoAPI.requestShortCategoryList() + requestCategoryList() + requestDataArr(page: 1, completer: nil) + + _setupUI() } override func setBgImageView() { } + + override func handleHeaderRefresh(_ completer: (() -> Void)?) { + requestDataArr(page: 1) { [weak self] in + self?.collectionView.sp_endHeaderRefreshing() + } + } + + override func handleFooterRefresh(_ completer: (() -> Void)?) { + requestDataArr(page: self.page + 1) { [weak self] in + self?.collectionView.sp_endFooterRefreshing() + } + } } extension SPAllShortViewController { + private func _setupUI() { + view.addSubview(tagView) + view.addSubview(bgView) + bgView.addSubview(collectionView) + + tagView.snp.makeConstraints { make in + make.left.right.equalToSuperview() + make.top.equalToSuperview().offset(kSPStatusbarHeight + 40 + 12) + } + + bgView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalTo(tagView.snp.bottom).offset(5) + } + + collectionView.snp.makeConstraints { make in + make.left.right.bottom.equalToSuperview() + make.top.equalToSuperview() + } + } + +} + +//MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource -------------- +extension SPAllShortViewController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = SPAllShortCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath) + cell.model = dataArr[indexPath.row] + return cell + } + + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return self.dataArr.count + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + let model = dataArr[indexPath.row] + + } +} + +//MARK: -------------- JXTagViewDelegate & JXTagViewDataSource -------------- +extension SPAllShortViewController: JXTagViewDelegate, JXTagViewDataSource { + func jx_number(in tagView: JXTagView) -> Int { + return self.categoryArr.count + } + + func jx_tagView(tagView: JXTagView, titleForIndex index: Int) -> String? { + return self.categoryArr[index].name + } + + func jx_tagView(tagView: JXTagView, selectedForIndex index: Int) -> Bool { + let model = self.categoryArr[index] + return model.id == self.currentCategoryModel.id + } + + func jx_tagView(tagView: JXTagView, didSelectedTagAt index: Int) { + let model = self.categoryArr[index] + if model.id == self.currentCategoryModel.id { return } + + self.currentCategoryModel = model + tagView.updateState() + + requestDataArr(page: 1, completer: nil) + } +} + +extension SPAllShortViewController { + private func requestCategoryList() { + SPVideoAPI.requestShortCategoryList { [weak self] list in + guard let self = self else { return } + if let list = list { + self.categoryArr = list + self.categoryArr.insert(self.allCategoryModel, at: 0) + self.tagView.reloadData() + } + } + } + + private func requestDataArr(page: Int, completer: (() -> Void)?) { + guard let id = self.currentCategoryModel.id else { return } + + SPVideoAPI.requestCategoryShortList(page: page, id: id) { [weak self] listModel in + guard let self = self else { return } + + if let list = listModel?.list { + if page == 1 { + self.dataArr.removeAll() + } + self.dataArr += list + + self.page = page + + self.collectionView.reloadData() + } + + completer?() + } + + } } diff --git a/Thimra/Class/Explore/Model/SPCategoryModel.swift b/Thimra/Class/Explore/Model/SPCategoryModel.swift new file mode 100644 index 0000000..06220ac --- /dev/null +++ b/Thimra/Class/Explore/Model/SPCategoryModel.swift @@ -0,0 +1,14 @@ +// +// SPCategoryModel.swift +// Thimra +// +// Created by Overseas on 2025/4/23. +// + +import UIKit +import SmartCodable + +class SPCategoryModel: SPModel, SmartCodable { + var id: String? + var name: String? +} diff --git a/Thimra/Class/Explore/View/SPAllShortCell.swift b/Thimra/Class/Explore/View/SPAllShortCell.swift new file mode 100644 index 0000000..a45379c --- /dev/null +++ b/Thimra/Class/Explore/View/SPAllShortCell.swift @@ -0,0 +1,64 @@ +// +// SPAllShortCell.swift +// Thimra +// +// Created by Overseas on 2025/4/23. +// + +import UIKit + +class SPAllShortCell: SPCollectionViewCell { + + + var model: SPShortModel? { + didSet { + coverImageView.sp_setImage(url: model?.image_url) + titleLabel.text = model?.name + } + } + + private lazy var coverImageView: SPImageView = { + let imageView = SPImageView() + imageView.layer.cornerRadius = 4 + imageView.layer.masksToBounds = true + return imageView + }() + + private lazy var titleLabel: UILabel = { + let label = UILabel() + label.font = .fontRegular(ofSize: 12) + label.textColor = .colorFFFFFF() + label.numberOfLines = 2 + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + _setupUI() + } + + @MainActor required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +extension SPAllShortCell { + + private func _setupUI() { + contentView.addSubview(coverImageView) + contentView.addSubview(titleLabel) + + coverImageView.snp.makeConstraints { make in + make.left.right.top.equalToSuperview() + make.bottom.equalToSuperview().offset(-36) + } + + titleLabel.snp.makeConstraints { make in + make.left.equalToSuperview() + make.right.lessThanOrEqualToSuperview() + make.top.equalTo(coverImageView.snp.bottom).offset(8) + } + } + +}