diff --git a/Podfile b/Podfile
index 6ce4cda..07ca518 100644
--- a/Podfile
+++ b/Podfile
@@ -31,6 +31,8 @@ target 'ShortPlay' do
pod 'KTVHTTPCache' #视频缓存
pod 'HWPanModal' #底部弹出控制器
pod 'Kingfisher' #图片加载
+ pod 'EmptyStateKit' #空数据页面
+ pod 'ReachabilitySwift' #网络状态监控
target 'ShortPlayTests' do
diff --git a/Podfile.lock b/Podfile.lock
index 3cac271..6f7b1c6 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -1,6 +1,7 @@
PODS:
- Alamofire (5.10.2)
- CocoaAsyncSocket (7.6.5)
+ - EmptyStateKit (1.1.0)
- HWPanModal (0.9.9)
- Kingfisher (8.3.1)
- KTVHTTPCache (3.0.2):
@@ -10,6 +11,7 @@ PODS:
- Moya/Core (= 15.0.0)
- Moya/Core (15.0.0):
- Alamofire (~> 5.0)
+ - ReachabilitySwift (5.2.4)
- SmartCodable (4.3.2)
- SnapKit (5.7.1)
- Toast (4.1.1)
@@ -21,11 +23,13 @@ PODS:
- ZFPlayer/Core (4.1.4)
DEPENDENCIES:
+ - EmptyStateKit
- HWPanModal
- Kingfisher
- KTVHTTPCache
- MJRefresh
- Moya
+ - ReachabilitySwift
- SmartCodable
- SnapKit
- Toast
@@ -36,11 +40,13 @@ SPEC REPOS:
trunk:
- Alamofire
- CocoaAsyncSocket
+ - EmptyStateKit
- HWPanModal
- Kingfisher
- KTVHTTPCache
- MJRefresh
- Moya
+ - ReachabilitySwift
- SmartCodable
- SnapKit
- Toast
@@ -50,17 +56,19 @@ SPEC REPOS:
SPEC CHECKSUMS:
Alamofire: 7193b3b92c74a07f85569e1a6c4f4237291e7496
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
+ EmptyStateKit: dc41e9ce5c6089f67a49d063bce73ade9f2ba73f
HWPanModal: b57a6717d3cdcd666bff44f9dd2a5be9f4d6f5d2
Kingfisher: 3204d23de16b5ea53541c44ca5a8efb55741dec3
KTVHTTPCache: 5711692cdf9a5ecfe829b1e16577deb3ffe3dc86
MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
Moya: 138f0573e53411fb3dc17016add0b748dfbd78ee
+ ReachabilitySwift: 32793e867593cfc1177f5d16491e3a197d2fccda
SmartCodable: 88fbf3d65207c2376fdbce4b080a3d578cb51be8
SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
YYKit: 7cda43304a8dc3696c449041e2cb3107b4e236e7
ZFPlayer: 5cf39e8d9f0c2394a014b0db4767b5b5a6bffe13
-PODFILE CHECKSUM: 13500f038833f93358c53b1941ce4a7f311776dd
+PODFILE CHECKSUM: 3842e01f3a774298d51e08a9caf0e72ea42cd7bc
COCOAPODS: 1.16.2
diff --git a/ShortPlay.xcodeproj/project.pbxproj b/ShortPlay.xcodeproj/project.pbxproj
index 97b1e68..9003f93 100644
--- a/ShortPlay.xcodeproj/project.pbxproj
+++ b/ShortPlay.xcodeproj/project.pbxproj
@@ -448,7 +448,7 @@
INFOPLIST_KEY_UIMainStoryboardFile = "";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
- IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
@@ -485,7 +485,7 @@
INFOPLIST_KEY_UIMainStoryboardFile = "";
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
- IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ IPHONEOS_DEPLOYMENT_TARGET = 14.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
diff --git a/ShortPlay.xcodeproj/xcshareddata/xcschemes/ShortPlay.xcscheme b/ShortPlay.xcodeproj/xcshareddata/xcschemes/ShortPlay.xcscheme
new file mode 100644
index 0000000..770ccaf
--- /dev/null
+++ b/ShortPlay.xcodeproj/xcshareddata/xcschemes/ShortPlay.xcscheme
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ShortPlay/AppDelegate/AppDelegate+Config.swift b/ShortPlay/AppDelegate/AppDelegate+Config.swift
index 25c7553..0b3456c 100644
--- a/ShortPlay/AppDelegate/AppDelegate+Config.swift
+++ b/ShortPlay/AppDelegate/AppDelegate+Config.swift
@@ -33,7 +33,7 @@ extension AppDelegate {
let backgroundImage = UIImage(color: .clear)
- let backgroundColor = UIColor.clear
+ let backgroundColor = UIColor.black
let shadowImage = UIImage()
let shadowColor = UIColor.clear
diff --git a/ShortPlay/AppDelegate/AppDelegate.swift b/ShortPlay/AppDelegate/AppDelegate.swift
index fcb5809..15a5fba 100644
--- a/ShortPlay/AppDelegate/AppDelegate.swift
+++ b/ShortPlay/AppDelegate/AppDelegate.swift
@@ -17,8 +17,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
self.appConfig()
SPLoginManager.manager.requestVisitorLogin(completer: nil)
+ ///开启网络监控
+// SPNetworkReachabilityManager.manager.startMonitoring()
+
+ NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
+ NetworkObserver.share.startMonitoring()
return true
@@ -38,6 +43,12 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
+
+ @objc private func reachabilityDidChangeNotification() {
+// if SPNetworkReachabilityManager.manager.isReachable {
+// SPLoginManager.manager.requestVisitorLogin(completer: nil)
+// }
+ }
}
diff --git a/ShortPlay/Base/Networking/API/SPVideoAPI.swift b/ShortPlay/Base/Networking/API/SPVideoAPI.swift
index e429e95..299aacd 100644
--- a/ShortPlay/Base/Networking/API/SPVideoAPI.swift
+++ b/ShortPlay/Base/Networking/API/SPVideoAPI.swift
@@ -43,7 +43,7 @@ class SPVideoAPI: NSObject {
}
///收藏短剧
- static func requestCollectShort(isCollect: Bool, shortPlayId: String, videoId: String, success: (() -> Void)?) {
+ static func requestCollectShort(isCollect: Bool, shortPlayId: String, videoId: String?, success: (() -> Void)?, failure: (() -> Void)? = nil) {
let path: String
if isCollect {
path = "/collect"
@@ -51,12 +51,17 @@ class SPVideoAPI: NSObject {
path = "/cancelCollect"
}
+ var parameters: [String : Any] = [
+ "short_play_id" : shortPlayId,
+ ]
+
+ if let videoId = videoId {
+ parameters["video_id"] = videoId
+ }
+
var param = SPNetworkParameters(path: path)
param.isLoding = true
- param.parameters = [
- "short_play_id" : shortPlayId,
- "video_id" : videoId
- ]
+ param.parameters = parameters
SPNetwork.request(parameters: param) { (response: SPNetworkResponse) in
if response.code == SPNetworkCodeSucceed {
@@ -65,6 +70,8 @@ class SPVideoAPI: NSObject {
"state" : isCollect,
"id" : shortPlayId,
])
+ } else {
+ failure?()
}
}
}
@@ -83,6 +90,20 @@ class SPVideoAPI: NSObject {
}
}
+ ///历史记录列表
+ static func requestPlayHistoryList(page: Int, completer: ((_ listModel: SPListModel?) -> Void)?) {
+ var param = SPNetworkParameters(path: "/myHistorys")
+ param.method = .get
+ param.parameters = [
+ "current_page" : page,
+ "page_size" : 20
+ ]
+
+ SPNetwork.request(parameters: param) { (response: SPNetworkResponse>) in
+ completer?(response.data)
+ }
+ }
+
}
extension SPVideoAPI {
diff --git a/ShortPlay/Base/Networking/Base/SPNetworkReachabilityManager.swift b/ShortPlay/Base/Networking/Base/SPNetworkReachabilityManager.swift
new file mode 100644
index 0000000..a9869b1
--- /dev/null
+++ b/ShortPlay/Base/Networking/Base/SPNetworkReachabilityManager.swift
@@ -0,0 +1,60 @@
+//
+// SPNetworkReachabilityManager.swift
+// ShortPlay
+//
+// Created by Overseas on 2025/4/19.
+//
+
+import UIKit
+import Network
+import Combine
+import Alamofire
+
+class SPNetworkReachabilityManager {
+// enum Status {
+// case notReachable
+// case reachableViaWiFi
+// case reachableViaWWAN
+// case ethernet
+// }
+
+ static let manager: SPNetworkReachabilityManager = SPNetworkReachabilityManager()
+
+ private let reachabilityManager = NetworkReachabilityManager()
+
+ ///是否有网
+// @objc var isReachable: Bool {
+// switch currentReachabilityStatus {
+// case .notReachable:
+// return false
+// case .reachableViaWiFi, .reachableViaWWAN:
+// return true
+//
+// default:
+// return false
+// }
+// }
+
+ func startMonitoring() {
+
+ reachabilityManager?.startListening(onUpdatePerforming: { status in
+ switch status {
+ case .notReachable:
+ print("网络不可用")
+ case .unknown:
+ print("网络状态未知")
+ case .reachable(.cellular):
+ print("蜂窝网络连接")
+ case .reachable(.ethernetOrWiFi):
+ print("WiFi 或有线网络连接")
+ }
+ })
+
+ }
+
+}
+
+extension SPNetworkReachabilityManager {
+ ///网络发生变化
+ @objc static let reachabilityDidChangeNotification = NSNotification.Name(rawValue: "reachabilityDidChangeNotification")
+}
diff --git a/ShortPlay/Class/Home/Controller/SPHomePageController.swift b/ShortPlay/Class/Home/Controller/SPHomePageController.swift
index 612aa20..3b0e8d8 100644
--- a/ShortPlay/Class/Home/Controller/SPHomePageController.swift
+++ b/ShortPlay/Class/Home/Controller/SPHomePageController.swift
@@ -11,6 +11,9 @@ class SPHomePageController: SPViewController {
private var topModel: SPHomeTopModel?
+ ///是否在请求中
+ private var isRequesting = false
+
private lazy var categoryArr: [SPHomeCategoryModel] = {
let arr = [
SPHomeCategoryModel(category_name: "Hot Picks".localized, category_id: nil, viewController: SPHomeViewController()),
@@ -55,7 +58,8 @@ class SPHomePageController: SPViewController {
override func viewDidLoad() {
super.viewDidLoad()
-
+ NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
+
sp_setupUI()
requestData()
@@ -97,6 +101,9 @@ extension SPHomePageController {
self.navigationController?.pushViewController(vc, animated: true)
}
+ @objc private func reachabilityDidChangeNotification() {
+ requestData()
+ }
}
@@ -130,9 +137,9 @@ extension SPHomePageController: JYPageControllerDelegate, JYPageControllerDataSo
extension SPHomePageController {
private func requestData() {
- if self.topModel != nil { return }
-
+ if self.topModel != nil || isRequesting { return }
+ isRequesting = true
SPHomeAPI.requestHomeTopData { [weak self] model in
guard let self = self else { return }
if let model = model {
@@ -142,6 +149,7 @@ extension SPHomePageController {
}
self.pageView.reload()
}
+ self.isRequesting = false
}
}
diff --git a/ShortPlay/Class/Home/Controller/SPHomeViewController.swift b/ShortPlay/Class/Home/Controller/SPHomeViewController.swift
index 12c42de..01db166 100644
--- a/ShortPlay/Class/Home/Controller/SPHomeViewController.swift
+++ b/ShortPlay/Class/Home/Controller/SPHomeViewController.swift
@@ -29,6 +29,8 @@ class SPHomeViewController: SPHomeChildController {
override func viewDidLoad() {
super.viewDidLoad()
+ NotificationCenter.default.addObserver(self, selector: #selector(reachabilityDidChangeNotification), name: SPNetworkReachabilityManager.reachabilityDidChangeNotification, object: nil)
+
// view.backgroundColor = .clear
requestModuleData()
_setupUI()
@@ -53,6 +55,12 @@ extension SPHomeViewController {
}
}
+extension SPHomeViewController {
+ @objc private func reachabilityDidChangeNotification() {
+
+ }
+}
+
//MARK: -------------- UICollectionViewDelegate & UICollectionViewDataSource --------------
extension SPHomeViewController: UICollectionViewDelegate, UICollectionViewDataSource {
diff --git a/ShortPlay/Class/Mine/Controller/SPAboutUsViewController.swift b/ShortPlay/Class/Mine/Controller/SPAboutUsViewController.swift
new file mode 100644
index 0000000..3b75103
--- /dev/null
+++ b/ShortPlay/Class/Mine/Controller/SPAboutUsViewController.swift
@@ -0,0 +1,18 @@
+//
+// SPAboutUsViewController.swift
+// ShortPlay
+//
+// Created by Overseas on 2025/4/19.
+//
+
+import UIKit
+
+class SPAboutUsViewController: SPViewController {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ }
+
+
+}
diff --git a/ShortPlay/Class/Mine/Controller/SPMineViewController.swift b/ShortPlay/Class/Mine/Controller/SPMineViewController.swift
index 8faf1f5..42a8eaf 100644
--- a/ShortPlay/Class/Mine/Controller/SPMineViewController.swift
+++ b/ShortPlay/Class/Mine/Controller/SPMineViewController.swift
@@ -21,6 +21,11 @@ class SPMineViewController: SPViewController {
return arr
}()
+ private lazy var headerView: SPMineHeaderView = {
+ let view = SPMineHeaderView(frame: CGRect(x: 0, y: 0, width: kSPScreenWidth, height: 200))
+ return view
+ }()
+
private lazy var tableView: SPTableView = {
let tableView = SPTableView(frame: .zero, style: .insetGrouped)
tableView.delegate = self
@@ -49,6 +54,8 @@ class SPMineViewController: SPViewController {
extension SPMineViewController {
private func _setupUI() {
+ tableView.tableHeaderView = self.headerView
+
view.addSubview(tableView)
tableView.snp.makeConstraints { make in
@@ -84,6 +91,10 @@ extension SPMineViewController: UITableViewDelegate, UITableViewDataSource {
vc.urlStr = SPUserAgreementWebUrl
self.navigationController?.pushViewController(vc, animated: true)
+ case .aboutUs:
+ let vc = SPAboutUsViewController()
+ self.navigationController?.pushViewController(vc, animated: true)
+
default:
break
}
diff --git a/ShortPlay/Class/Mine/View/SPMineHeaderView.swift b/ShortPlay/Class/Mine/View/SPMineHeaderView.swift
new file mode 100644
index 0000000..8f83277
--- /dev/null
+++ b/ShortPlay/Class/Mine/View/SPMineHeaderView.swift
@@ -0,0 +1,14 @@
+//
+// SPMineHeaderView.swift
+// ShortPlay
+//
+// Created by Overseas on 2025/4/19.
+//
+
+import UIKit
+
+class SPMineHeaderView: UIView {
+
+
+
+}
diff --git a/ShortPlay/Class/MyList/Controller/SPCollectListViewController.swift b/ShortPlay/Class/MyList/Controller/SPCollectListViewController.swift
index 930778d..e5c174a 100644
--- a/ShortPlay/Class/MyList/Controller/SPCollectListViewController.swift
+++ b/ShortPlay/Class/MyList/Controller/SPCollectListViewController.swift
@@ -7,12 +7,14 @@
import UIKit
-class SPCollectListViewController: SPViewController {
+class SPCollectListViewController: SPMyListChildViewController {
private lazy var dataArr: [SPShortModel] = []
private var page: Int?
+ private lazy var deleteGorup = DispatchGroup()
+
//MARK: UI属性
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let itemWidth = floor((kSPScreenWidth - 30 - 9 * 2) / 3)
@@ -67,6 +69,47 @@ class SPCollectListViewController: SPViewController {
self?.collectionView.sp_endFooterRefreshing()
}
}
+
+ override var sp_isEditing: Bool {
+ didSet {
+ self.collectionView.reloadData()
+ }
+ }
+
+ override var isAllSelected: Bool {
+ var result = true
+ for model in dataArr {
+ if model.sp_isSelected != true {
+ result = false
+ break
+ }
+ }
+ return result
+ }
+
+ override var selectedCount: Int {
+ var result = 0
+ dataArr.forEach {
+ if $0.sp_isSelected ?? false {
+ result += 1
+ }
+ }
+ return result
+ }
+
+
+ override func setAllSelectedState(isSelected: Bool) {
+ dataArr.forEach {
+ $0.sp_isSelected = isSelected
+ }
+ self.collectionView.reloadData()
+ allSelectedStateDidChange?(isSelected)
+ self.updateDeleteButtonState()
+ }
+
+ override func handelDeleteButton() {
+ requestDelete()
+ }
}
extension SPCollectListViewController {
@@ -87,16 +130,38 @@ extension SPCollectListViewController: UICollectionViewDelegate, UICollectionVie
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = SPCollectListCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
+ cell.sp_isEditing = self.sp_isEditing
cell.model = dataArr[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
- return self.dataArr.count
+ let count = self.dataArr.count
+ if count == 0 {
+ let parameters = SPEmptyParameters(image: UIImage(named: "empty_image_01"))
+ let emptyState = SPEmptyState.normail(parameters: parameters)
+ self.collectionView.emptyState.format = emptyState.format
+ self.collectionView.emptyState.show(emptyState)
+ } else {
+ self.collectionView.emptyState.hide()
+ }
+
+ return count
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
-
+ let model = dataArr[indexPath.row]
+ if sp_isEditing {
+ model.sp_isSelected = !(model.sp_isSelected ?? false)
+ self.collectionView.reloadData()
+
+ allSelectedStateDidChange?(isAllSelected)
+ self.updateDeleteButtonState()
+ } else {
+ let vc = SPPlayerDetailViewController()
+ vc.shortPlayId = model.short_play_id
+ self.navigationController?.pushViewController(vc, animated: true)
+ }
}
}
@@ -117,13 +182,33 @@ extension SPCollectListViewController {
self.page = page
self.collectionView.reloadData()
-
+ if self.sp_isEditing {
+ self.allSelectedStateDidChange?(self.isAllSelected)
+ }
}
completer?()
}
-
}
+ private func requestDelete() {
+
+ dataArr.forEach {
+ if $0.sp_isSelected == true, let shortPlayId = $0.short_play_id {
+ self.deleteGorup.enter()
+ SPVideoAPI.requestCollectShort(isCollect: false, shortPlayId: shortPlayId, videoId: nil) { [weak self] in
+ self?.deleteGorup.leave()
+ } failure: { [weak self] in
+ self?.deleteGorup.leave()
+ }
+ }
+ }
+
+ self.deleteGorup.notify(queue: DispatchQueue.main) { [weak self] in
+ self?.requestDataList(page: 1, completer: nil)
+ }
+ }
+
+
}
diff --git a/ShortPlay/Class/MyList/Controller/SPMyListChildViewController.swift b/ShortPlay/Class/MyList/Controller/SPMyListChildViewController.swift
new file mode 100644
index 0000000..c562535
--- /dev/null
+++ b/ShortPlay/Class/MyList/Controller/SPMyListChildViewController.swift
@@ -0,0 +1,87 @@
+//
+// SPMyListChildViewController.swift
+// ShortPlay
+//
+// Created by Overseas on 2025/4/19.
+//
+
+import UIKit
+
+class SPMyListChildViewController: SPViewController {
+
+ var sp_isEditing = false {
+ didSet {
+ deleteButton.isHidden = !sp_isEditing
+ if sp_isEditing {
+ self.view.bringSubviewToFront(deleteButton)
+ }
+ }
+ }
+
+ ///是否被全选
+ var isAllSelected: Bool {
+ return false
+ }
+
+ ///当前被选中的数量
+ var selectedCount: Int {
+ return 0
+ }
+
+ ///全选状态发生变化
+ var allSelectedStateDidChange: ((_ isAllSelected: Bool) -> Void)?
+
+
+ private(set) lazy var deleteButton: UIButton = {
+ let button = JXButton(type: .custom)
+ button.setTitle("0", for: .normal)
+ button.setTitleColor(.color9D9D9D(), for: .disabled)
+ button.setTitleColor(.colorF564B6(), for: .normal)
+ button.setImage(UIImage(named: "delete_icon_01"), for: .disabled)
+ button.setImage(UIImage(named: "delete_icon_02"), for: .normal)
+ button.jx_font = .fontRegular(ofSize: 14)
+ button.jx_setBorderColor(.color9D9D9D(), for: .disabled)
+ button.jx_setBorderColor(.colorF564B6(), for: .normal)
+ button.space = 7
+ button.layer.cornerRadius = 24
+ button.layer.masksToBounds = true
+ button.layer.borderWidth = 0.7
+ button.isHidden = true
+ button.addTarget(self, action: #selector(handelDeleteButton), for: .touchUpInside)
+ return button
+ }()
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ updateDeleteButtonState()
+
+ view.addSubview(deleteButton)
+
+ deleteButton.snp.makeConstraints { make in
+ make.left.equalToSuperview().offset(20)
+ make.centerX.equalToSuperview()
+ make.bottom.equalToSuperview().offset(-20)
+ make.height.equalTo(48)
+ }
+ }
+
+
+ ///设置全选状态
+ func setAllSelectedState(isSelected: Bool) { }
+
+
+ ///更新删除按钮状态
+ func updateDeleteButtonState() {
+ let count = self.selectedCount
+
+ deleteButton.isEnabled = count > 0
+ let text = String(format: "Delet (%@)".localized, "\(selectedCount)")
+ deleteButton.setTitle(text, for: .normal)
+ }
+
+ @objc func handelDeleteButton() {
+
+ }
+
+
+}
diff --git a/ShortPlay/Class/MyList/Controller/SPMyListViewController.swift b/ShortPlay/Class/MyList/Controller/SPMyListViewController.swift
index 2fb20ed..cd1912d 100644
--- a/ShortPlay/Class/MyList/Controller/SPMyListViewController.swift
+++ b/ShortPlay/Class/MyList/Controller/SPMyListViewController.swift
@@ -12,12 +12,40 @@ class SPMyListViewController: SPViewController {
private lazy var titles = ["Follow List".localized, "Play List".localized]
- private lazy var viewControllers: [SPViewController] = {
+ private lazy var viewControllers: [SPMyListChildViewController] = {
let vc1 = SPCollectListViewController()
+ vc1.allSelectedStateDidChange = { [weak self] isAllSelected in
+ self?.allSelectedButton.isSelected = isAllSelected
+ }
let vc2 = SPPlayHistoryViewController()
+ vc2.allSelectedStateDidChange = { [weak self] isAllSelected in
+ self?.allSelectedButton.isSelected = isAllSelected
+ }
+
return [vc1, vc2]
}()
+ private lazy var sp_isEditing = false {
+ didSet {
+ editButton.isHidden = sp_isEditing
+ pageView.segmentedView.isHidden = sp_isEditing
+
+ cancelButton.isHidden = !sp_isEditing
+ allSelectedButton.isHidden = !sp_isEditing
+ pageView.pageContentScrollView.isScrollEnabled = !sp_isEditing
+
+ let vc = viewControllers[pageView.selectedIndex]
+ vc.sp_isEditing = sp_isEditing
+
+ if !sp_isEditing {
+ vc.setAllSelectedState(isSelected: false)
+ allSelectedButton.isSelected = false
+ }
+
+ }
+ }
+
+ //MARK: UI属性
private lazy var pageView: JYPageController = {
let pageView = JYPageController()
pageView.delegate = self
@@ -37,6 +65,39 @@ class SPMyListViewController: SPViewController {
return pageView
}()
+ private lazy var editButton: UIButton = {
+ let button = UIButton(type: .custom)
+ button.setImage(UIImage(named: "delete_icon_01"), for: .normal)
+ button.addTarget(self, action: #selector(handleEditButton), for: .touchUpInside)
+ return button
+ }()
+
+ private lazy var cancelButton: UIButton = {
+ let button = UIButton(type: .custom)
+ button.setTitle("Cancel".localized, for: .normal)
+ button.setTitleColor(.colorFFFFFF(alpha: 0.9), for: .normal)
+ button.titleLabel?.font = .fontRegular(ofSize: 15)
+ button.addTarget(self, action: #selector(handleCancelButton), for: .touchUpInside)
+ button.isHidden = true
+ return button
+ }()
+
+ ///全选按钮
+ private lazy var allSelectedButton: UIButton = {
+ let button = JXButton(type: .custom)
+ button.setTitle("Select All".localized, for: .normal)
+ button.setTitleColor(.colorFFFFFF(alpha: 0.9), for: .normal)
+ button.setImage(UIImage(named: "check_icon_01"), for: .normal)
+ button.setImage(UIImage(named: "check_icon_01_selected"), for: .selected)
+ button.setImage(UIImage(named: "check_icon_01_selected"), for: [.selected, .highlighted])
+ button.jx_font = .fontRegular(ofSize: 15)
+ button.titleDirection = .right
+ button.space = 6
+ button.isHidden = true
+ button.addTarget(self, action: #selector(handleAllSelectedButton), for: .touchUpInside)
+ return button
+ }()
+
override func viewDidLoad() {
super.viewDidLoad()
@@ -48,19 +109,58 @@ class SPMyListViewController: SPViewController {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
-
-
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ self.sp_isEditing = false
+ }
+
+ @objc private func handleEditButton() {
+ self.sp_isEditing = true
+ }
+
+ @objc private func handleCancelButton() {
+ self.sp_isEditing = false
+ }
+
+ @objc private func handleAllSelectedButton() {
+ let vc = viewControllers[pageView.selectedIndex]
+ if self.allSelectedButton.isSelected {
+ vc.setAllSelectedState(isSelected: false)
+ } else {
+ vc.setAllSelectedState(isSelected: true)
+ }
+ }
}
extension SPMyListViewController {
private func _setupUI() {
addChild(pageView)
view.addSubview(pageView.view)
+ view.addSubview(editButton)
+ view.addSubview(cancelButton)
+ view.addSubview(allSelectedButton)
pageView.view.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
+
+ editButton.snp.makeConstraints { make in
+ make.right.equalToSuperview().offset(-5)
+ make.top.equalToSuperview().offset(kSPStatusbarHeight + 10)
+ make.height.equalTo(35)
+ make.width.equalTo(40)
+ }
+
+ cancelButton.snp.makeConstraints { make in
+ make.top.bottom.equalTo(editButton)
+ make.right.equalTo(editButton)
+ }
+
+ allSelectedButton.snp.makeConstraints { make in
+ make.left.equalToSuperview().offset(15)
+ make.top.bottom.equalTo(editButton)
+ }
}
}
@@ -88,4 +188,12 @@ extension SPMyListViewController: JYPageControllerDelegate, JYPageControllerData
return self.viewControllers[index]
}
+ func pageController(_ pageController: JYPageController, didEnterControllerAt index: Int) {
+ if index == 0 {
+ self.editButton.isHidden = false
+ } else {
+ self.editButton.isHidden = true
+ }
+ }
+
}
diff --git a/ShortPlay/Class/MyList/Controller/SPPlayHistoryViewController.swift b/ShortPlay/Class/MyList/Controller/SPPlayHistoryViewController.swift
index 91047f2..a4966b7 100644
--- a/ShortPlay/Class/MyList/Controller/SPPlayHistoryViewController.swift
+++ b/ShortPlay/Class/MyList/Controller/SPPlayHistoryViewController.swift
@@ -7,11 +7,13 @@
import UIKit
-class SPPlayHistoryViewController: SPViewController {
+class SPPlayHistoryViewController: SPMyListChildViewController {
private lazy var dataArr: [SPShortModel] = []
private var page: Int?
+ private lazy var deleteGorup = DispatchGroup()
+
//MARK: UI属性
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let itemWidth = floor((kSPScreenWidth - 30 - 9 * 2) / 3)
@@ -21,7 +23,7 @@ class SPPlayHistoryViewController: SPViewController {
layout.itemSize = .init(width: itemWidth, height: itemHeight)
layout.minimumLineSpacing = 10
layout.minimumInteritemSpacing = 9
- layout.sectionInset = .init(top: 10, left: 15, bottom: 0, right: 15)
+ layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15)
return layout
}()
@@ -30,6 +32,13 @@ class SPPlayHistoryViewController: SPViewController {
let collectionView = SPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
+ collectionView.contentInset = .init(top: 10, left: 0, bottom: 0, right: 0)
+ collectionView.sp_addRefreshHeader(insetTop: collectionView.contentInset.top) { [weak self] in
+ self?.handleHeaderRefresh(nil)
+ }
+ collectionView.sp_addRefreshBackFooter { [weak self] in
+ self?.handleFooterRefresh(nil)
+ }
SPCollectListCell.registerCell(collectionView: collectionView)
return collectionView
}()
@@ -45,7 +54,61 @@ class SPPlayHistoryViewController: SPViewController {
override func setBgImageView() { }
-
+
+ override func handleHeaderRefresh(_ completer: (() -> Void)?) {
+ requestDataList(page: 1) { [weak self] in
+ self?.collectionView.sp_endHeaderRefreshing()
+ }
+ }
+
+ override func handleFooterRefresh(_ completer: (() -> Void)?) {
+ guard let page = self.page else { return }
+
+ requestDataList(page: page + 1) { [weak self] in
+ self?.collectionView.sp_endFooterRefreshing()
+ }
+ }
+
+ override var sp_isEditing: Bool {
+ didSet {
+ self.collectionView.reloadData()
+ }
+ }
+
+ override var isAllSelected: Bool {
+ var result = true
+ for model in dataArr {
+ if model.sp_isSelected != true {
+ result = false
+ break
+ }
+ }
+ return result
+ }
+
+ override var selectedCount: Int {
+ var result = 0
+ dataArr.forEach {
+ if $0.sp_isSelected ?? false {
+ result += 1
+ }
+ }
+ return result
+ }
+
+
+ override func setAllSelectedState(isSelected: Bool) {
+ dataArr.forEach {
+ $0.sp_isSelected = isSelected
+ }
+ self.collectionView.reloadData()
+ allSelectedStateDidChange?(isSelected)
+ self.updateDeleteButtonState()
+ }
+
+ override func handelDeleteButton() {
+ requestDelete()
+ }
}
@@ -68,12 +131,38 @@ extension SPPlayHistoryViewController: UICollectionViewDelegate, UICollectionVie
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = SPCollectListCell.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
+ cell.sp_isEditing = self.sp_isEditing
cell.model = dataArr[indexPath.row]
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
- return self.dataArr.count
+ let count = self.dataArr.count
+ if count == 0 {
+ let parameters = SPEmptyParameters(image: UIImage(named: "empty_image_01"))
+ let emptyState = SPEmptyState.normail(parameters: parameters)
+ self.collectionView.emptyState.format = emptyState.format
+ self.collectionView.emptyState.show(emptyState)
+ } else {
+ self.collectionView.emptyState.hide()
+ }
+
+ return count
+ }
+
+ func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+ let model = dataArr[indexPath.row]
+ if sp_isEditing {
+ model.sp_isSelected = !(model.sp_isSelected ?? false)
+ self.collectionView.reloadData()
+
+ allSelectedStateDidChange?(isAllSelected)
+ self.updateDeleteButtonState()
+ } else {
+ let vc = SPPlayerDetailViewController()
+ vc.shortPlayId = model.short_play_id
+ self.navigationController?.pushViewController(vc, animated: true)
+ }
}
}
@@ -82,7 +171,7 @@ extension SPPlayHistoryViewController {
private func requestDataList(page: Int, completer: (() -> Void)?) {
- SPVideoAPI.requestCollectList(page: page) { [weak self] listModel in
+ SPVideoAPI.requestPlayHistoryList(page: page) { [weak self] listModel in
guard let self = self else { return }
if let listModel = listModel, let list = listModel.list {
@@ -94,12 +183,31 @@ extension SPPlayHistoryViewController {
self.page = page
self.collectionView.reloadData()
-
+ if self.sp_isEditing {
+ self.allSelectedStateDidChange?(self.isAllSelected)
+ }
}
completer?()
}
-
}
+ private func requestDelete() {
+
+ dataArr.forEach {
+ if $0.sp_isSelected == true, let shortPlayId = $0.short_play_id {
+ self.deleteGorup.enter()
+ SPVideoAPI.requestCollectShort(isCollect: false, shortPlayId: shortPlayId, videoId: nil) { [weak self] in
+ self?.deleteGorup.leave()
+ } failure: { [weak self] in
+ self?.deleteGorup.leave()
+ }
+ }
+ }
+
+ self.deleteGorup.notify(queue: DispatchQueue.main) { [weak self] in
+ self?.requestDataList(page: 1, completer: nil)
+ }
+ }
+
+
}
-
diff --git a/ShortPlay/Class/MyList/View/SPCollectListCell.swift b/ShortPlay/Class/MyList/View/SPCollectListCell.swift
index 10e3160..fd52a23 100644
--- a/ShortPlay/Class/MyList/View/SPCollectListCell.swift
+++ b/ShortPlay/Class/MyList/View/SPCollectListCell.swift
@@ -13,6 +13,14 @@ class SPCollectListCell: SPCollectionViewCell {
didSet {
coverImageView.sp_setImage(url: model?.image_url)
titleLabel.text = model?.name
+
+ selectedButton.isSelected = model?.sp_isSelected ?? false
+ }
+ }
+
+ var sp_isEditing: Bool = false {
+ didSet {
+ selectedButton.isHidden = !sp_isEditing
}
}
@@ -31,6 +39,15 @@ class SPCollectListCell: SPCollectionViewCell {
return label
}()
+ private lazy var selectedButton: UIButton = {
+ let button = UIButton(type: .custom)
+ button.isHidden = true
+ button.isUserInteractionEnabled = false
+ button.setImage(UIImage(named: "check_icon_01"), for: .normal)
+ button.setImage(UIImage(named: "check_icon_01_selected"), for: .selected)
+ return button
+ }()
+
override init(frame: CGRect) {
super.init(frame: frame)
@@ -49,6 +66,7 @@ extension SPCollectListCell {
private func _setupUI() {
contentView.addSubview(coverImageView)
contentView.addSubview(titleLabel)
+ coverImageView.addSubview(selectedButton)
coverImageView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
@@ -61,6 +79,11 @@ extension SPCollectListCell {
make.right.lessThanOrEqualToSuperview()
}
+ selectedButton.snp.makeConstraints { make in
+ make.right.equalToSuperview().offset(-5)
+ make.top.equalToSuperview().offset(5)
+ }
+
}
}
diff --git a/ShortPlay/Class/Player/Controller/SPPlayerDetailViewController.swift b/ShortPlay/Class/Player/Controller/SPPlayerDetailViewController.swift
index 3c3ac09..4be29aa 100644
--- a/ShortPlay/Class/Player/Controller/SPPlayerDetailViewController.swift
+++ b/ShortPlay/Class/Player/Controller/SPPlayerDetailViewController.swift
@@ -63,7 +63,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController {
override func play() {
super.play()
- if let _ = self.viewModel.currentPlayer?.model as? SPVideoDetailModel,
+ if let _ = self.detailModel,
let videoInfo = self.viewModel.currentPlayer?.videoInfo
{
SPVideoAPI.requestRequestVideoPlayHistory(videoId: videoInfo.short_play_video_id ?? "", shortPlayId: videoInfo.short_play_id ?? "")
diff --git a/ShortPlay/Class/Player/Model/SPShortModel.swift b/ShortPlay/Class/Player/Model/SPShortModel.swift
index 2137277..af93082 100644
--- a/ShortPlay/Class/Player/Model/SPShortModel.swift
+++ b/ShortPlay/Class/Player/Model/SPShortModel.swift
@@ -30,6 +30,8 @@ class SPShortModel: SPModel, SmartCodable {
@IgnoredKey
var titleAttributedString: NSAttributedString?
+ @IgnoredKey
+ var sp_isSelected: Bool?
static func mappingForKey() -> [SmartKeyTransformer]? {
diff --git a/ShortPlay/Libs/Empty/SPEmptyState.swift b/ShortPlay/Libs/Empty/SPEmptyState.swift
new file mode 100644
index 0000000..3e1e6e1
--- /dev/null
+++ b/ShortPlay/Libs/Empty/SPEmptyState.swift
@@ -0,0 +1,91 @@
+//
+// SPEmptyState.swift
+// ShortPlay
+//
+// Created by Overseas on 2025/4/19.
+//
+
+import UIKit
+import EmptyStateKit
+
+struct SPEmptyParameters {
+// var title: String = "暂无内容"
+// var titleFont: UIFont = UIFont.text_md
+// var titleColor: UIColor = UIColor.system_text_secondary_300
+ var image: UIImage? = UIImage(named: "empty_image_01")
+// var buttonTitle: String?
+}
+
+enum SPEmptyState {
+ case normail(parameters: SPEmptyParameters)
+}
+
+extension SPEmptyState: CustomState {
+
+ var image: UIImage? {
+ switch self {
+ case .normail(let parameters):
+ return parameters.image
+
+
+ }
+ }
+
+ var title: String? {
+ switch self {
+ case .normail(let parameters):
+ return nil
+
+ }
+ }
+
+// var titleButton: String? {
+// switch self {
+// case .normail(let parameters):
+// return parameters.buttonTitle
+// }
+
+}
+
+extension SPEmptyState {
+ var format: EmptyStateFormat {
+
+ var format = EmptyStateFormat()
+ format.backgroundColor = .clear
+ format.imageSize = self.image?.size ?? .zero
+// format.verticalMargin = -10
+//
+// format.buttonWidth = 107
+// format.buttonTopMargin = 10
+// format.buttonColor = .system_fill_primary_100
+// format.buttonAttributes = [
+// .font: UIFont.text_md,
+// .foregroundColor: UIColor.system_text_secondary_500
+// ]
+//
+// switch self {
+// case .normail(let p):
+// format.titleAttributes = [
+// .font: p.titleFont,
+// .foregroundColor: p.titleColor
+// ]
+//
+//
+// case .login(let p):
+// format.titleAttributes = [
+// .font: p.titleFont,
+// .foregroundColor: p.titleColor
+// ]
+//
+//
+// }
+
+
+
+
+ return format
+ }
+}
+
+
+
diff --git a/ShortPlay/Libs/Reachability/NetworkObserver.swift b/ShortPlay/Libs/Reachability/NetworkObserver.swift
new file mode 100644
index 0000000..f109b4c
--- /dev/null
+++ b/ShortPlay/Libs/Reachability/NetworkObserver.swift
@@ -0,0 +1,72 @@
+//
+// NetworkObserver.swift
+// ShortPlay
+//
+// Created by Overseas on 2025/4/21.
+//
+
+import UIKit
+import Network
+import Reachability
+
+
+class NetworkObserver {
+ static let share = NetworkObserver()
+
+
+ private let monitor = NWPathMonitor()
+ private let queue = DispatchQueue(label: "NetworkMonitorQueue")
+
+ func startMonitoring() {
+ monitor.pathUpdateHandler = { path in
+ if path.status == .satisfied {
+ print("++++++Network is available")
+ } else {
+ print("++++++No network connection")
+ }
+
+ if path.usesInterfaceType(.wifi) {
+ print("++++++Using Wi-Fi")
+ }
+
+ if path.usesInterfaceType(.cellular) {
+ print("++++++Using Cellular")
+ }
+ }
+
+ monitor.start(queue: queue)
+ }
+
+ func stopMonitoring() {
+ monitor.cancel()
+ }
+
+ /*
+ private let reachability = try! Reachability()
+
+ func startMonitoring() {
+ reachability.whenReachable = { reachability in
+ if reachability.connection == .wifi {
+ print("++++++Network reachable via Wi-Fi")
+ } else if reachability.connection == .cellular {
+ print("++++++Network reachable via Cellular")
+ }
+ }
+
+ reachability.whenUnreachable = { _ in
+ print("++++++Network not reachable")
+ }
+
+ do {
+ try reachability.startNotifier()
+ } catch {
+ print("++++++Unable to start notifier")
+ }
+ }
+
+ func stopMonitoring() {
+ reachability.stopNotifier()
+ }
+ */
+
+}
diff --git a/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/Contents.json b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/Contents.json
new file mode 100644
index 0000000..328d961
--- /dev/null
+++ b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "组件 67 – 2@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "组件 67 – 2@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/组件 67 – 2@2x.png b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/组件 67 – 2@2x.png
new file mode 100644
index 0000000..669f9bb
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/组件 67 – 2@2x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/组件 67 – 2@3x.png b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/组件 67 – 2@3x.png
new file mode 100644
index 0000000..a17639a
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01.imageset/组件 67 – 2@3x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/Contents.json b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/Contents.json
new file mode 100644
index 0000000..813db8e
--- /dev/null
+++ b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "组件 67 – 9@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "组件 67 – 9@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/组件 67 – 9@2x.png b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/组件 67 – 9@2x.png
new file mode 100644
index 0000000..76bcc22
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/组件 67 – 9@2x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/组件 67 – 9@3x.png b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/组件 67 – 9@3x.png
new file mode 100644
index 0000000..35b6827
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/check_icon_01_selected.imageset/组件 67 – 9@3x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/Contents.json b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/Contents.json
new file mode 100644
index 0000000..42b0bd4
--- /dev/null
+++ b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "delet-选中@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "delet-选中@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/delet-选中@2x.png b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/delet-选中@2x.png
new file mode 100644
index 0000000..7c04e41
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/delet-选中@2x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/delet-选中@3x.png b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/delet-选中@3x.png
new file mode 100644
index 0000000..60e3e5c
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_01.imageset/delet-选中@3x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/Contents.json b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/Contents.json
new file mode 100644
index 0000000..6b57fb5
--- /dev/null
+++ b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/Contents.json
@@ -0,0 +1,22 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "scale" : "1x"
+ },
+ {
+ "filename" : "delete@2x.png",
+ "idiom" : "universal",
+ "scale" : "2x"
+ },
+ {
+ "filename" : "delete@3x.png",
+ "idiom" : "universal",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "author" : "xcode",
+ "version" : 1
+ }
+}
diff --git a/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/delete@2x.png b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/delete@2x.png
new file mode 100644
index 0000000..c7278c6
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/delete@2x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/delete@3x.png b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/delete@3x.png
new file mode 100644
index 0000000..419168f
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/icon/delete_icon_02.imageset/delete@3x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/Contents.json b/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/Contents.json
new file mode 100644
index 0000000..0caa45e
--- /dev/null
+++ b/ShortPlay/Source/Assets.xcassets/image/empty_image_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/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@2x.png b/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@2x.png
new file mode 100644
index 0000000..985fa2e
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@2x.png differ
diff --git a/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@3x.png b/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@3x.png
new file mode 100644
index 0000000..f3d5df1
Binary files /dev/null and b/ShortPlay/Source/Assets.xcassets/image/empty_image_01.imageset/空空如也@3x.png differ
diff --git a/ShortPlay/Source/en.lproj/Localizable.strings b/ShortPlay/Source/en.lproj/Localizable.strings
index 0a10dde..e260d2f 100644
--- a/ShortPlay/Source/en.lproj/Localizable.strings
+++ b/ShortPlay/Source/en.lproj/Localizable.strings
@@ -30,6 +30,9 @@
"My list" = "My list";
"Follow List" = "Follow List";
"Play List" = "Play List";
+"Cancel" = "Cancel";
+"Select All" = "Select All";
+"Delet (%@)" = "Delet (%@)";
///视频详情标题
"kPlayerDetailTitleString" = "Episode %@ / %@";
diff --git a/ShortPlay/Thirdparty/JXButton/JXButton.swift b/ShortPlay/Thirdparty/JXButton/JXButton.swift
index e1a8929..246bd18 100644
--- a/ShortPlay/Thirdparty/JXButton/JXButton.swift
+++ b/ShortPlay/Thirdparty/JXButton/JXButton.swift
@@ -211,6 +211,12 @@ class JXButton: UIButton {
updateStatus()
}
}
+
+ override var isEnabled: Bool {
+ didSet {
+ updateStatus()
+ }
+ }
}
diff --git a/ShortPlay/Thirdparty/JYPageController/Classes/JYPageController.swift b/ShortPlay/Thirdparty/JYPageController/Classes/JYPageController.swift
index e7130c8..a9ab625 100644
--- a/ShortPlay/Thirdparty/JYPageController/Classes/JYPageController.swift
+++ b/ShortPlay/Thirdparty/JYPageController/Classes/JYPageController.swift
@@ -343,7 +343,7 @@ open class JYPageController: UIViewController {
return segment
}()
- private lazy var pageContentScrollView : UIScrollView = {
+ private(set) lazy var pageContentScrollView : UIScrollView = {
let scrollView = UIScrollView()
// scrollView.backgroundColor = .white
scrollView.showsHorizontalScrollIndicator = false