历史记录
This commit is contained in:
parent
d1a1bde3aa
commit
f0628bd609
@ -9,6 +9,7 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
B8B1DA3824F2148CEEF9F162 /* Pods_Fableon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C4958FEE55B4555A94F11F00 /* Pods_Fableon.framework */; };
|
||||
F301F6472E974B6300E76A90 /* FARecommendPlayerControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F301F6462E974B6300E76A90 /* FARecommendPlayerControlView.swift */; };
|
||||
F34296922EA0C60200A58F99 /* FAHomePlayHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F34296912EA0C60200A58F99 /* FAHomePlayHistoryView.swift */; };
|
||||
F37103312E978F8C00E7F171 /* FACollectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F37103302E978F8C00E7F171 /* FACollectViewController.swift */; };
|
||||
F37103352E97929F00E7F171 /* FACollectCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = F37103342E97929F00E7F171 /* FACollectCell.xib */; };
|
||||
F37103362E97929F00E7F171 /* FACollectCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F37103332E97929F00E7F171 /* FACollectCell.swift */; };
|
||||
@ -127,6 +128,7 @@
|
||||
C4958FEE55B4555A94F11F00 /* Pods_Fableon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Fableon.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DC14083E24B746ED3DE2FE0C /* Pods-Fableon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Fableon.release.xcconfig"; path = "Target Support Files/Pods-Fableon/Pods-Fableon.release.xcconfig"; sourceTree = "<group>"; };
|
||||
F301F6462E974B6300E76A90 /* FARecommendPlayerControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FARecommendPlayerControlView.swift; sourceTree = "<group>"; };
|
||||
F34296912EA0C60200A58F99 /* FAHomePlayHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FAHomePlayHistoryView.swift; sourceTree = "<group>"; };
|
||||
F37103302E978F8C00E7F171 /* FACollectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACollectViewController.swift; sourceTree = "<group>"; };
|
||||
F37103332E97929F00E7F171 /* FACollectCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FACollectCell.swift; sourceTree = "<group>"; };
|
||||
F37103342E97929F00E7F171 /* FACollectCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FACollectCell.xib; sourceTree = "<group>"; };
|
||||
@ -556,6 +558,7 @@
|
||||
F371035D2E9E2E7400E7F171 /* FASearchRecommendCell.xib */,
|
||||
F37103642E9E3ABC00E7F171 /* FASearchResultCell.swift */,
|
||||
F37103652E9E3ABC00E7F171 /* FASearchResultCell.xib */,
|
||||
F34296912EA0C60200A58F99 /* FAHomePlayHistoryView.swift */,
|
||||
);
|
||||
path = V;
|
||||
sourceTree = "<group>";
|
||||
@ -852,10 +855,14 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Fableon/Pods-Fableon-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Fableon/Pods-Fableon-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Fableon/Pods-Fableon-frameworks.sh\"\n";
|
||||
@ -923,6 +930,7 @@
|
||||
F3DCC0572E8A8EE800D58007 /* FAMeViewController.swift in Sources */,
|
||||
F3A792E82E77F8590097E0BC /* FAHomeModuleItem.swift in Sources */,
|
||||
F3DCC0452E89530200D58007 /* CGMutablePath+FARoundedCorner.swift in Sources */,
|
||||
F34296922EA0C60200A58F99 /* FAHomePlayHistoryView.swift in Sources */,
|
||||
F37103882EA08B6F00E7F171 /* FANetworkMonitor.swift in Sources */,
|
||||
F37103672E9E3ABC00E7F171 /* FASearchResultCell.swift in Sources */,
|
||||
F371037B2EA0820C00E7F171 /* FASettingViewController.swift in Sources */,
|
||||
|
||||
@ -68,6 +68,19 @@ struct FAAPI {
|
||||
}
|
||||
}
|
||||
|
||||
///上报播放时长
|
||||
static func requestUploadPlayTime(shortPlayId: String, videoId: String, seconds: Int) {
|
||||
let parameters: [String : Any] = [
|
||||
"video_id" : videoId,
|
||||
"short_play_id" : shortPlayId,
|
||||
"play_seconds" : seconds
|
||||
]
|
||||
|
||||
FANetworkManager.manager.request(FABaseURL + "/uploadHistorySeconds", method: .post, parameters: parameters, isToast: false) { (response: FANetworkManager.Response<String>) in
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
///收藏
|
||||
static func requestShortCollect(isCollect: Bool, shortPlayId: String, videoId: String?, isLoding: Bool = true, success: (() -> Void)?, failure: (() -> Void)? = nil) {
|
||||
let path: String
|
||||
|
||||
@ -56,6 +56,12 @@ class FAHomeViewController: FAViewController {
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var playHistoryView: FAHomePlayHistoryView = {
|
||||
let view = FAHomePlayHistoryView()
|
||||
view.isHidden = true
|
||||
return view
|
||||
}()
|
||||
|
||||
deinit {
|
||||
NotificationCenter.default.removeObserver(self)
|
||||
}
|
||||
@ -65,9 +71,7 @@ class FAHomeViewController: FAViewController {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: FANetworkMonitor.networkStatusDidChangeNotification, object: nil)
|
||||
fa_setupLayout()
|
||||
|
||||
self.viewModel.requestHomeData { [weak self] in
|
||||
self?.collectionView.reloadData()
|
||||
}
|
||||
requestAllData(completer: nil)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
@ -75,18 +79,20 @@ class FAHomeViewController: FAViewController {
|
||||
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
requestPlayHistory()
|
||||
}
|
||||
|
||||
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
|
||||
self.viewModel.requestHomeData { [weak self] in
|
||||
self?.collectionView.reloadData()
|
||||
requestAllData { [weak self] in
|
||||
self?.collectionView.fa_endHeaderRefreshing()
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func networkStatusDidChangeNotification() {
|
||||
if self.viewModel.dataArr.isEmpty, FANetworkMonitor.manager.isReachable == true {
|
||||
self.viewModel.requestHomeData { [weak self] in
|
||||
self?.collectionView.reloadData()
|
||||
}
|
||||
requestAllData(completer: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -97,6 +103,7 @@ extension FAHomeViewController {
|
||||
view.addSubview(titleView)
|
||||
view.addSubview(searchButton)
|
||||
view.addSubview(collectionView)
|
||||
view.addSubview(playHistoryView)
|
||||
|
||||
titleView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
@ -112,6 +119,12 @@ extension FAHomeViewController {
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(UIScreen.navBarHeight)
|
||||
}
|
||||
|
||||
playHistoryView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
make.centerX.equalToSuperview()
|
||||
make.bottom.equalToSuperview().offset(-10)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -245,3 +258,26 @@ extension FAHomeViewController: FAWaterfallMutiSectionDelegate {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension FAHomeViewController {
|
||||
|
||||
private func requestAllData(completer: (() -> Void)?) {
|
||||
self.viewModel.requestHomeData { [weak self] in
|
||||
self?.collectionView.reloadData()
|
||||
completer?()
|
||||
}
|
||||
requestPlayHistory()
|
||||
}
|
||||
|
||||
private func requestPlayHistory() {
|
||||
self.viewModel.requestPlayHistory { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if let playHistory = self.viewModel.playHistory {
|
||||
self.playHistoryView.model = playHistory
|
||||
self.playHistoryView.isHidden = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
128
Fableon/Class/Home/V/FAHomePlayHistoryView.swift
Normal file
128
Fableon/Class/Home/V/FAHomePlayHistoryView.swift
Normal file
@ -0,0 +1,128 @@
|
||||
//
|
||||
// FAHomePlayHistoryView.swift
|
||||
// Fableon
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2025/10/16.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class FAHomePlayHistoryView: UIView {
|
||||
|
||||
var model: FAShortPlayModel? {
|
||||
didSet {
|
||||
coverImageView.fa_setImage(model?.image_url)
|
||||
titleLabel.text = model?.name
|
||||
epLabel.text = "Last Watch:Ep.##".localizedReplace(text: model?.current_episode ?? "")
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var coverImageView: FAImageView = {
|
||||
let imageView = FAImageView()
|
||||
imageView.layer.cornerRadius = 6
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var bgView: UIView = {
|
||||
let view = UIView()
|
||||
view.layer.cornerRadius = 12
|
||||
view.layer.masksToBounds = true
|
||||
view.layer.borderWidth = 1
|
||||
view.layer.borderColor = UIColor.BDCEFF.cgColor
|
||||
view.fa_addEffectView(style: .light)
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var bgColorView: UIView = {
|
||||
let view = UIView()
|
||||
view.backgroundColor = ._5_CA_8_FF_0_2
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var playView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "Group 2420"))
|
||||
imageView.setContentHuggingPriority(.required, for: .horizontal)
|
||||
imageView.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 12, weight: .medium)
|
||||
label.textColor = .FFFFFF
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var epLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 10, weight: .regular)
|
||||
label.textColor = .FFFFFF
|
||||
return label
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
fa_setupLayout()
|
||||
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(handleBg))
|
||||
addGestureRecognizer(tap)
|
||||
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc func handleBg() {
|
||||
let vc = FAPlayerDetailViewController()
|
||||
vc.shortPlayId = self.model?.short_play_id
|
||||
self.viewController?.navigationController?.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension FAHomePlayHistoryView {
|
||||
private func fa_setupLayout() {
|
||||
addSubview(bgView)
|
||||
bgView.addSubview(bgColorView)
|
||||
addSubview(coverImageView)
|
||||
bgView.addSubview(playView)
|
||||
bgView.addSubview(titleLabel)
|
||||
bgView.addSubview(epLabel)
|
||||
|
||||
bgView.snp.makeConstraints { make in
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(24)
|
||||
make.height.equalTo(57)
|
||||
}
|
||||
|
||||
bgColorView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
|
||||
coverImageView.snp.makeConstraints { make in
|
||||
make.top.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(25)
|
||||
make.width.equalTo(56)
|
||||
make.height.equalTo(74)
|
||||
}
|
||||
|
||||
playView.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.right.equalToSuperview().offset(-10)
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(96)
|
||||
make.top.equalToSuperview().offset(12)
|
||||
make.right.lessThanOrEqualTo(playView.snp.left).offset(-10)
|
||||
}
|
||||
|
||||
epLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(titleLabel)
|
||||
make.bottom.equalToSuperview().offset(-12)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -17,6 +17,9 @@ class FAHomeViewModel: ObservableObject {
|
||||
@Published var homeNewItem: FAHomeModuleItem?
|
||||
@Published var recommendedItem: FAHomeModuleItem?
|
||||
|
||||
///播放历史
|
||||
var playHistory: FAShortPlayModel?
|
||||
|
||||
func requestHomeData(completer: (() -> Void)?) {
|
||||
FAAPI.requestHomeModulesData { [weak self] list in
|
||||
guard let self = self else { return }
|
||||
@ -100,6 +103,16 @@ class FAHomeViewModel: ObservableObject {
|
||||
completer?()
|
||||
}
|
||||
}
|
||||
|
||||
func requestPlayHistory(completer: (() -> Void)?) {
|
||||
FAAPI.requestPlayHistorys(page: 1, pageSize: 1) { [weak self] listModel in
|
||||
guard let self = self else { return }
|
||||
if let model = listModel?.list?.first {
|
||||
self.playHistory = model
|
||||
}
|
||||
completer?()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension FAHomeViewModel {
|
||||
|
||||
@ -40,3 +40,17 @@ class FAPlayerDetailCell: JXPlayerListCell {
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension FAPlayerDetailCell {
|
||||
|
||||
override func jx_playerReadyToPlay(_ player: JXPlayer) {
|
||||
super.jx_playerReadyToPlay(player)
|
||||
guard let videoInfo = self.model as? FAVideoInfoModel else { return }
|
||||
|
||||
let time = TimeInterval(videoInfo.play_seconds ?? 0) / 1000
|
||||
let durationTime = self.durationTime
|
||||
if time > 1, durationTime > 0 {
|
||||
self.seekTo(progress: Float(time) / Float(durationTime))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -15,7 +15,8 @@ class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject {
|
||||
|
||||
var shortPlayId: String = ""
|
||||
|
||||
|
||||
///上一次上报播放时长的节点
|
||||
private var lastUploadTime: TimeInterval = 0
|
||||
|
||||
var previousEpisode: FAVideoInfoModel? {
|
||||
guard dataArr.count > 0 else { return nil }
|
||||
@ -43,14 +44,55 @@ class FAShortDetailViewModel: JXPlayerListViewModel, ObservableObject {
|
||||
if let model = model {
|
||||
self.dataArr.removeAll()
|
||||
self.dataArr.append(model)
|
||||
self.playerListVC?.reloadData {
|
||||
self.playerListVC?.play()
|
||||
self.playerListVC?.reloadData { [weak self] in
|
||||
guard let self = self else { return }
|
||||
var targetIndexPath = IndexPath(row: 0, section: 0)
|
||||
|
||||
if let videoInfo = model.video_info {
|
||||
var row: Int?
|
||||
model.episodeList?.enumerated().forEach {
|
||||
if $1.short_play_video_id == videoInfo.short_play_video_id {
|
||||
row = $0
|
||||
}
|
||||
}
|
||||
if let row = row {
|
||||
targetIndexPath = .init(row: row, section: 0)
|
||||
}
|
||||
}
|
||||
|
||||
self.playerListVC?.scrollToItem(indexPath: targetIndexPath, animated: false)
|
||||
}
|
||||
}
|
||||
completer?(code ?? -1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override func playProgressDidChange(player: any JXPlayerCell, time: TimeInterval) {
|
||||
if time > 1 {
|
||||
(player.model as? FAVideoInfoModel)?.play_seconds = Int(time) * 1000
|
||||
}
|
||||
|
||||
if (time >= lastUploadTime + 5 || time < lastUploadTime) && time >= 5 {
|
||||
lastUploadTime = time
|
||||
uploadPlayTime()
|
||||
}
|
||||
}
|
||||
|
||||
private func uploadPlayTime() {
|
||||
let videoInfo = self.currentCell?.model as? FAVideoInfoModel
|
||||
let currentTime = self.currentCell?.currentTime ?? 0
|
||||
let duration = self.currentCell?.durationTime ?? 0
|
||||
|
||||
var time = currentTime
|
||||
if currentTime >= duration {
|
||||
time = 0
|
||||
}
|
||||
|
||||
guard let shortPlayId = videoInfo?.short_play_id, let videoId = videoInfo?.short_play_video_id else { return }
|
||||
FAAPI.requestUploadPlayTime(shortPlayId: shortPlayId, videoId: videoId, seconds: Int(time) * 1000)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension FAShortDetailViewModel {
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xFF",
|
||||
"green" : "0xCE",
|
||||
"red" : "0xBD"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
22
Fableon/Source/Assets.xcassets/image/Group 2420.imageset/Contents.json
vendored
Normal file
22
Fableon/Source/Assets.xcassets/image/Group 2420.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 2420@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 2420@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
Fableon/Source/Assets.xcassets/image/Group 2420.imageset/Group 2420@2x.png
vendored
Normal file
BIN
Fableon/Source/Assets.xcassets/image/Group 2420.imageset/Group 2420@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.6 KiB |
BIN
Fableon/Source/Assets.xcassets/image/Group 2420.imageset/Group 2420@3x.png
vendored
Normal file
BIN
Fableon/Source/Assets.xcassets/image/Group 2420.imageset/Group 2420@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
@ -16,3 +16,4 @@
|
||||
"Visit Website" = "Visit Website";
|
||||
"Setting" = "Setting";
|
||||
"Settings" = "Settings";
|
||||
"Last Watch:Ep.##" = "Last Watch:Ep.##";
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user