From 17669d141208ab54d3e3a45f61260d9e78985f56 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=BE=9C=E5=A3=B0=E4=B8=96=E7=BA=AA?= <>
Date: Sat, 27 Dec 2025 13:10:21 +0800
Subject: [PATCH] =?UTF-8?q?bug=E4=BF=AE=E5=A4=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Base/Networking/API/NRHomeAPI.swift | 4 +-
.../Base/Networking/API/NRStatAPI.swift | 7 ++
ReaderHive/Base/VC/NRTabBarController.swift | 2 +
...xploreNovelContentListViewController.swift | 43 ++++++++---
.../NRExploreNovelGenresViewController.swift | 1 +
.../Explore/VC/NRExploreViewController.swift | 28 ++++++-
.../VC/NRNovelGenresViewController.swift | 2 +-
.../Class/Home/V/NRSearchResultView.swift | 1 +
ReaderHive/Class/Me/V/NRMeHeaderView.swift | 2 +-
.../Class/Me/V/NRSettingFooterView.swift | 2 +
.../Class/Me/VC/NRMeViewController.swift | 10 +++
.../VC/NRMyListNovelViewController.swift | 22 +++++-
.../MyList/VC/NRMyListViewController.swift | 26 +++++++
.../V/NRNovelDetailHeaderView+Data.swift | 11 ++-
.../Novel/V/NRNovelDetailHeaderView.swift | 1 +
.../V/Reader/NRNovelReadStarGradeView.swift | 6 +-
.../V/Reader/NRNovelReaderCatalogView.swift | 3 +-
.../Reader/NRReadSettingBrightnessView.swift | 10 +--
.../NRNovelDetailCatalogViewController.swift | 30 +++++++-
...NRNovelDetailRecommandViewController.swift | 2 +-
.../VC/NRNovelDetailViewController.swift | 32 +++++++-
.../NRNovelReaderViewController+Page.swift | 24 +++++-
.../VC/Read/NRNovelReaderViewController.swift | 73 +++++++++++++++++--
.../Class/Novel/VM/NRNovelReadViewModel.swift | 7 +-
ReaderHive/Class/Store/V/NRStoreVipCell.swift | 9 ++-
ReaderHive/Delegate/AppDelegate+APNS.swift | 6 +-
ReaderHive/Libs/Login/NRLoginManager.swift | 6 +-
.../Libs/NovelTool/NRNovelReadSet.swift | 7 ++
.../NovelTool/NRNovelReadSetManager.swift | 18 ++++-
ReaderHive/ReaderHive.entitlements | 2 +
30 files changed, 343 insertions(+), 54 deletions(-)
diff --git a/ReaderHive/Base/Networking/API/NRHomeAPI.swift b/ReaderHive/Base/Networking/API/NRHomeAPI.swift
index 894d1fb..def1011 100644
--- a/ReaderHive/Base/Networking/API/NRHomeAPI.swift
+++ b/ReaderHive/Base/Networking/API/NRHomeAPI.swift
@@ -29,7 +29,7 @@ struct NRHomeAPI {
}
///Explore接口
- static func requestRankingCollection(type: String, days: Int) async -> [NRNovelModel]? {
+ static func requestRankingCollection(page: Int, type: String, days: Int) async -> [NRNovelModel]? {
await withCheckedContinuation { continuation in
var param = NRNetwork.Parameters(path: "/rankingCollection")
@@ -37,7 +37,7 @@ struct NRHomeAPI {
param.parameters = [
"days" : days,
"type" : type,
- "current_page" : 1,
+ "current_page" : page,
"page_size" : 20,
]
diff --git a/ReaderHive/Base/Networking/API/NRStatAPI.swift b/ReaderHive/Base/Networking/API/NRStatAPI.swift
index 90962e4..43230fc 100644
--- a/ReaderHive/Base/Networking/API/NRStatAPI.swift
+++ b/ReaderHive/Base/Networking/API/NRStatAPI.swift
@@ -86,7 +86,14 @@ struct NRStatAPI {
}
///进入APP
+ private static var nr_needRequestEnterApp = true
static func nr_requestEnterApp() {
+ guard nr_needRequestEnterApp else { return }
+ nr_needRequestEnterApp = false
+ DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
+ nr_needRequestEnterApp = true
+ }
+
var param = NRNetwork.Parameters(path: "/customer/enterTheApp")
param.method = .post
param.isLoding = false
diff --git a/ReaderHive/Base/VC/NRTabBarController.swift b/ReaderHive/Base/VC/NRTabBarController.swift
index 79d8daf..10bc847 100644
--- a/ReaderHive/Base/VC/NRTabBarController.swift
+++ b/ReaderHive/Base/VC/NRTabBarController.swift
@@ -42,6 +42,8 @@ class NRTabBarController: UITabBarController {
NRTool.checkUpdates()
NROpenAppManager.manager.requestIDFAAuthorization()
+
+ NRIapManager.manager.restore(isLoding: false, completer: nil)
}
diff --git a/ReaderHive/Class/Explore/VC/NRExploreNovelContentListViewController.swift b/ReaderHive/Class/Explore/VC/NRExploreNovelContentListViewController.swift
index 3c323de..0cb896a 100644
--- a/ReaderHive/Class/Explore/VC/NRExploreNovelContentListViewController.swift
+++ b/ReaderHive/Class/Explore/VC/NRExploreNovelContentListViewController.swift
@@ -15,6 +15,7 @@ class NRExploreNovelContentListViewController: NRViewController {
var contentType: NRExploreNovelContentViewController.ContentType = .today
lazy var dataArr: [NRNovelModel] = []
+ lazy var page = 1
lazy var collectionViewLayout: UICollectionViewCompositionalLayout = {
let item = NSCollectionLayoutItem(
@@ -42,7 +43,14 @@ class NRExploreNovelContentListViewController: NRViewController {
frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
+ collectionView.showsVerticalScrollIndicator = false
collectionView.contentInset = .init(top: 0, left: 0, bottom: 10, right: 0)
+// collectionView.nr_addRefreshHeader { [weak self] in
+// self?.handleHeaderRefresh(nil)
+// }
+ collectionView.nr_addRefreshFooter(insetBottom: collectionView.contentInset.bottom) { [weak self] in
+ self?.handleFooterRefresh(nil)
+ }
collectionView.register(
NRExploreNovelContentListCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
@@ -64,19 +72,30 @@ class NRExploreNovelContentListViewController: NRViewController {
nr_setupUI()
Task {
- await requestDataArr()
+ await requestDataArr(page: 1)
}
}
@objc private func networkStatusDidChangeNotification() {
- guard NRNetworkReachableManager.manager.isReachable == true, self.dataArr.isEmpty else {
- return
- }
+ guard NRNetworkReachableManager.manager.isReachable == true, self.dataArr.isEmpty else { return }
Task {
- await requestDataArr()
+ await requestDataArr(page: 1)
+ }
+ }
+
+ override func handleHeaderRefresh(_ completer: (() -> Void)?) {
+ Task {
+ await requestDataArr(page: 1)
+ self.collectionView.nr_endHeaderRefreshing()
+ }
+ }
+
+ override func handleFooterRefresh(_ completer: (() -> Void)?) {
+ Task {
+ await requestDataArr(page: self.page + 1)
+ self.collectionView.nr_endFooterRefreshing()
}
}
-
}
extension NRExploreNovelContentListViewController {
@@ -126,14 +145,16 @@ extension NRExploreNovelContentListViewController: UICollectionViewDelegate,
extension NRExploreNovelContentListViewController {
- private func requestDataArr() async {
+ private func requestDataArr(page: Int) async {
guard let type = self.menuItem?.type else { return }
guard
- let list = await NRHomeAPI.requestRankingCollection(
- type: type.rawValue, days: self.contentType.rawValue)
+ let list = await NRHomeAPI.requestRankingCollection(page: page, type: type.rawValue, days: self.contentType.rawValue)
else { return }
-
- self.dataArr = list
+ if page == 1 {
+ self.dataArr.removeAll()
+ }
+ self.page = page
+ self.dataArr += list
self.collectionView.reloadData()
}
diff --git a/ReaderHive/Class/Explore/VC/NRExploreNovelGenresViewController.swift b/ReaderHive/Class/Explore/VC/NRExploreNovelGenresViewController.swift
index cfe840d..ef7e396 100644
--- a/ReaderHive/Class/Explore/VC/NRExploreNovelGenresViewController.swift
+++ b/ReaderHive/Class/Explore/VC/NRExploreNovelGenresViewController.swift
@@ -38,6 +38,7 @@ class NRExploreNovelGenresViewController: NRViewController {
collectionView.delegate = self
collectionView.dataSource = self
collectionView.contentInset = .init(top: 0, left: 0, bottom: 10, right: 0)
+ collectionView.showsVerticalScrollIndicator = false
collectionView.register(NRExploreNovelGenresCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
diff --git a/ReaderHive/Class/Explore/VC/NRExploreViewController.swift b/ReaderHive/Class/Explore/VC/NRExploreViewController.swift
index 978ad6d..e31ac6e 100644
--- a/ReaderHive/Class/Explore/VC/NRExploreViewController.swift
+++ b/ReaderHive/Class/Explore/VC/NRExploreViewController.swift
@@ -7,6 +7,7 @@
import UIKit
import SnapKit
+import LYEmptyView
class NRExploreViewController: NRViewController {
@@ -26,9 +27,13 @@ class NRExploreViewController: NRViewController {
lazy var novelVC = NRExploreNovelViewController()
+ @MainActor deinit {
+ NotificationCenter.default.removeObserver(self)
+ }
+
override func viewDidLoad() {
super.viewDidLoad()
-
+ NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
nr_setupUI()
}
@@ -38,12 +43,33 @@ class NRExploreViewController: NRViewController {
}
+
+ override func handleNotNetworkingEmptyBtn() {
+ self.nr_setupUI()
+ }
+
+ @objc private func networkStatusDidChangeNotification() {
+ guard NRNetworkReachableManager.manager.isReachable == true else { return }
+ nr_setupUI()
+ }
}
extension NRExploreViewController {
private func nr_setupUI() {
+ guard novelVC.view.superview == nil else { return }
+
+ if NRNetworkReachableManager.manager.isReachable != true {
+ if self.view.ly_emptyView == nil {
+ self.view.ly_emptyView = self.notNetworkingEmptyView
+ }
+ self.view.ly_showEmpty()
+ return;
+ }
+ self.view.ly_hideEmpty()
+
+
view.addSubview(searchButton)
view.addSubview(titleView)
addChild(novelVC)
diff --git a/ReaderHive/Class/Explore/VC/NRNovelGenresViewController.swift b/ReaderHive/Class/Explore/VC/NRNovelGenresViewController.swift
index adcf487..16f06be 100644
--- a/ReaderHive/Class/Explore/VC/NRNovelGenresViewController.swift
+++ b/ReaderHive/Class/Explore/VC/NRNovelGenresViewController.swift
@@ -20,7 +20,7 @@ class NRNovelGenresViewController: NRViewController {
let itemWidth = (UIScreen.width - 32 - 40) / 3
let itemHeight = 150 / 100 * itemWidth + 68
- let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1 / 3), heightDimension: .fractionalHeight(1)))
+ let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .absolute(floor(itemWidth)), heightDimension: .fractionalHeight(1)))
let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(itemHeight)), subitems: [item])
group.interItemSpacing = .fixed(20)
diff --git a/ReaderHive/Class/Home/V/NRSearchResultView.swift b/ReaderHive/Class/Home/V/NRSearchResultView.swift
index 5485000..63a1645 100644
--- a/ReaderHive/Class/Home/V/NRSearchResultView.swift
+++ b/ReaderHive/Class/Home/V/NRSearchResultView.swift
@@ -30,6 +30,7 @@ class NRSearchResultView: UIView {
let collectionView = NRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self
collectionView.dataSource = self
+ collectionView.keyboardDismissMode = .onDrag
collectionView.contentInset = .init(top: 10, left: 0, bottom: UIScreen.safeBottom + 10, right: 0)
collectionView.ly_emptyView = NREmpty.nr_emptyView()
collectionView.register(NRSearchResultCell.self, forCellWithReuseIdentifier: "cell")
diff --git a/ReaderHive/Class/Me/V/NRMeHeaderView.swift b/ReaderHive/Class/Me/V/NRMeHeaderView.swift
index 439f051..bab36be 100644
--- a/ReaderHive/Class/Me/V/NRMeHeaderView.swift
+++ b/ReaderHive/Class/Me/V/NRMeHeaderView.swift
@@ -15,7 +15,7 @@ class NRMeHeaderView: UITableViewHeaderFooterView {
var userInfo: NRUserInfo? {
didSet {
- avatarImageView.nr_setImage(userInfo?.avator)
+ avatarImageView.nr_setImage(userInfo?.avator, placeholder: UIImage(named: "logo_icon_01"))
nickLabel.text = userInfo?.getNickName()
idLabel.text = "ID:\(userInfo?.customer_id ?? "")"
diff --git a/ReaderHive/Class/Me/V/NRSettingFooterView.swift b/ReaderHive/Class/Me/V/NRSettingFooterView.swift
index 1e80bc1..793e6c5 100644
--- a/ReaderHive/Class/Me/V/NRSettingFooterView.swift
+++ b/ReaderHive/Class/Me/V/NRSettingFooterView.swift
@@ -8,6 +8,7 @@
import UIKit
import SnapKit
import HWPanModal
+import YYCategories
class NRSettingFooterView: UICollectionReusableView {
@@ -64,6 +65,7 @@ class NRSettingFooterView: UICollectionReusableView {
let alert = NRAlert(title: "Log Out".localized, detail: "logout_alert_text".localized, topIconImage: UIImage(named: "alert_top_icon_02"), highlightButtonText: "Confirm".localized)
alert.highlightHandle = {
NRLoginManager.manager.logout(completer: nil)
+ self.viewController?.navigationController?.popViewController(animated: true)
}
alert.show()
diff --git a/ReaderHive/Class/Me/VC/NRMeViewController.swift b/ReaderHive/Class/Me/VC/NRMeViewController.swift
index 7230e37..a8a5d72 100644
--- a/ReaderHive/Class/Me/VC/NRMeViewController.swift
+++ b/ReaderHive/Class/Me/VC/NRMeViewController.swift
@@ -21,6 +21,9 @@ class NRMeViewController: NRViewController {
tableView.rowHeight = 60
tableView.register(NRMeCell.self, forCellReuseIdentifier: "cell")
tableView.register(NRMeHeaderView.self, forHeaderFooterViewReuseIdentifier: "header")
+ tableView.nr_addRefreshHeader(insetTop: 0) { [weak self] in
+ self?.handleHeaderRefresh(nil)
+ }
return tableView
}()
@@ -54,6 +57,13 @@ class NRMeViewController: NRViewController {
reloadDataArr()
}
+ override func handleHeaderRefresh(_ completer: (() -> Void)?) {
+ Task {
+ await NRLoginManager.manager.updateUserInfo()
+ self.tableView.nr_endHeaderRefreshing()
+ }
+ }
+
}
extension NRMeViewController {
diff --git a/ReaderHive/Class/MyList/VC/NRMyListNovelViewController.swift b/ReaderHive/Class/MyList/VC/NRMyListNovelViewController.swift
index 98b5e03..9186522 100644
--- a/ReaderHive/Class/MyList/VC/NRMyListNovelViewController.swift
+++ b/ReaderHive/Class/MyList/VC/NRMyListNovelViewController.swift
@@ -55,15 +55,16 @@ class NRMyListNovelViewController: NRViewController {
NotificationCenter.default.removeObserver(self)
}
-
override func viewDidLoad() {
super.viewDidLoad()
self.backgroundImageView.isHidden = true
self.view.backgroundColor = .clear
-
+
+ NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateCollectStateNotification), name: NRNovelAPI.updateCollectStateNotification, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(loginStateDidChangeNotification), name: NRLoginManager.loginStateDidChangeNotification, object: nil)
-
+
nr_setupUI()
Task {
await requestDataArr(page: 1)
@@ -98,6 +99,19 @@ class NRMyListNovelViewController: NRViewController {
isNeedUpdate = true
}
}
+
+ @objc private func loginStateDidChangeNotification() {
+ isNeedUpdate = true
+ }
+
+ @objc private func networkStatusDidChangeNotification() {
+ guard NRNetworkReachableManager.manager.isReachable == true else { return }
+ guard self.dataArr.isEmpty else { return }
+
+ Task {
+ await requestDataArr(page: self.page + 1)
+ }
+ }
}
@@ -173,6 +187,8 @@ extension NRMyListNovelViewController {
guard let id = model.short_play_id else { return }
await NRNovelAPI.requestCollect(isCollect: false, id: id, chapterId: model.short_play_video_id)
+ self.dataArr.remove(at: indexPath.row)
+ self.collectionView.deleteItems(at: [indexPath])
// await self.requestDataArr(page: 1)
}
diff --git a/ReaderHive/Class/MyList/VC/NRMyListViewController.swift b/ReaderHive/Class/MyList/VC/NRMyListViewController.swift
index 4264a88..3f7c50c 100644
--- a/ReaderHive/Class/MyList/VC/NRMyListViewController.swift
+++ b/ReaderHive/Class/MyList/VC/NRMyListViewController.swift
@@ -7,6 +7,7 @@
import UIKit
import SnapKit
+import LYEmptyView
class NRMyListViewController: NRViewController {
@@ -39,8 +40,13 @@ class NRMyListViewController: NRViewController {
return button
}()
+ @MainActor deinit {
+ NotificationCenter.default.removeObserver(self)
+ }
+
override func viewDidLoad() {
super.viewDidLoad()
+ NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
nr_setupUI()
}
@@ -55,12 +61,32 @@ class NRMyListViewController: NRViewController {
self.nr_isEditing = false
}
+ override func handleNotNetworkingEmptyBtn() {
+ super.handleNotNetworkingEmptyBtn()
+ self.nr_setupUI()
+ }
+
+ @objc private func networkStatusDidChangeNotification() {
+ guard NRNetworkReachableManager.manager.isReachable == true else { return }
+ nr_setupUI()
+ }
}
extension NRMyListViewController {
private func nr_setupUI() {
+ guard novelVC.view.superview == nil else { return }
+
+ if NRNetworkReachableManager.manager.isReachable != true {
+ if self.view.ly_emptyView == nil {
+ self.view.ly_emptyView = self.notNetworkingEmptyView
+ }
+ self.view.ly_showEmpty()
+ return;
+ }
+ self.view.ly_hideEmpty()
+
view.addSubview(titleLabel)
view.addSubview(editButton)
addChild(novelVC)
diff --git a/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView+Data.swift b/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView+Data.swift
index 336e9d0..7d918aa 100644
--- a/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView+Data.swift
+++ b/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView+Data.swift
@@ -15,7 +15,13 @@ extension NRNovelDetailHeaderView {
var num: CGFloat = 0 {
didSet {
- numLabel.text = NSNumber(value: num).formattedNumber()
+ updateNumLabel()
+ }
+ }
+
+ var minimumFractionDigits: Int? {
+ didSet {
+ updateNumLabel()
}
}
@@ -108,6 +114,9 @@ extension NRNovelDetailHeaderView {
fatalError("init(coder:) has not been implemented")
}
+ private func updateNumLabel() {
+ numLabel.text = NSNumber(value: num).toString(minimumFractionDigits: minimumFractionDigits)
+ }
}
}
diff --git a/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView.swift b/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView.swift
index 087142e..b5781ba 100644
--- a/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView.swift
+++ b/ReaderHive/Class/Novel/V/NRNovelDetailHeaderView.swift
@@ -98,6 +98,7 @@ class NRNovelDetailHeaderView: UIView {
private lazy var rateDataView: DataView = {
let view = DataView()
view.num = 0
+ view.minimumFractionDigits = 1
view.icon = UIImage(named: "rate_icon_01")
view.title = "Rate".localized
return view
diff --git a/ReaderHive/Class/Novel/V/Reader/NRNovelReadStarGradeView.swift b/ReaderHive/Class/Novel/V/Reader/NRNovelReadStarGradeView.swift
index ffca79b..5776f2e 100644
--- a/ReaderHive/Class/Novel/V/Reader/NRNovelReadStarGradeView.swift
+++ b/ReaderHive/Class/Novel/V/Reader/NRNovelReadStarGradeView.swift
@@ -25,8 +25,8 @@ class NRNovelReadStarGradeView: UIView {
// gradeView.updateOnTouch = true
// gradeView.fillMode = .full
} else {
- label.text = "My Rate:##".localizedReplace(text: NSNumber(value: self_rate).toString(maximumFractionDigits: 1, minimumFractionDigits: 1))
- gradeView.grade = self_rate / 2
+ label.text = "My Rate:##".localizedReplace(text: NSNumber(value: self_rate * 2).toString(maximumFractionDigits: 1, minimumFractionDigits: 1))
+ gradeView.grade = self_rate
// gradeView.updateOnTouch = false
// gradeView.fillMode = .precise
}
@@ -84,7 +84,7 @@ class NRNovelReadStarGradeView: UIView {
guard let id = self.model?.id else { return }
Task {
guard await NRNovelAPI.requestRateScore(id, stars: CGFloat(grade)) else { return}
- self.model?.self_rate = grade * 2
+ self.model?.self_rate = grade
gradeView.isHidden = true
label.isHidden = true
finishView.isHidden = false
diff --git a/ReaderHive/Class/Novel/V/Reader/NRNovelReaderCatalogView.swift b/ReaderHive/Class/Novel/V/Reader/NRNovelReaderCatalogView.swift
index bfe8f79..0addc3f 100644
--- a/ReaderHive/Class/Novel/V/Reader/NRNovelReaderCatalogView.swift
+++ b/ReaderHive/Class/Novel/V/Reader/NRNovelReaderCatalogView.swift
@@ -56,7 +56,7 @@ class NRNovelReaderCatalogView: UIView {
let label = UILabel()
label.font = .font(ofSize: 14, weight: .medium)
label.textColor = .black
- label.numberOfLines = 0
+ label.numberOfLines = 3
return label
}()
@@ -85,6 +85,7 @@ class NRNovelReaderCatalogView: UIView {
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
+ tableView.showsVerticalScrollIndicator = false
// tableView.rowHeight = 44
tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.safeBottom, right: 0)
tableView.register(NRNovelCatalogCell.self, forCellReuseIdentifier: "cell")
diff --git a/ReaderHive/Class/Novel/V/Reader/NRReadSettingBrightnessView.swift b/ReaderHive/Class/Novel/V/Reader/NRReadSettingBrightnessView.swift
index 722110e..e63a27f 100644
--- a/ReaderHive/Class/Novel/V/Reader/NRReadSettingBrightnessView.swift
+++ b/ReaderHive/Class/Novel/V/Reader/NRReadSettingBrightnessView.swift
@@ -13,14 +13,15 @@ class NRReadSettingBrightnessView: NRNovelReadSettingItemView {
lazy var progressView: NRProgressView = {
let view = NRProgressView()
+ view.progress = UIScreen.main.brightness
view.thumbImage = UIImage(named: "Progress-handle")
view.insets = .init(top: 6, left: 0, bottom: 6, right: 0)
view.panChange = { progress in
- UIScreen.main.brightness = progress
+ NRNovelReadSetManager.manager.updateBrightness(value: progress)
}
view.panFinish = { [weak self] progress in
self?.progressView.progress = progress
- UIScreen.main.brightness = progress
+ NRNovelReadSetManager.manager.updateBrightness(value: progress)
}
return view
}()
@@ -30,8 +31,7 @@ class NRReadSettingBrightnessView: NRNovelReadSettingItemView {
self.titleLabel.text = "Brightness".localized
let imageSize = progressView.thumbImage?.size ?? .zero
-
- contentView.addSubview(progressView)
+ contentView.addSubview(progressView)
progressView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(-imageSize.width / 2)
@@ -39,7 +39,7 @@ class NRReadSettingBrightnessView: NRNovelReadSettingItemView {
make.top.bottom.equalToSuperview()
}
- progressView.progress = UIScreen.main.brightness
+
}
@MainActor required init?(coder: NSCoder) {
diff --git a/ReaderHive/Class/Novel/VC/NRNovelDetailCatalogViewController.swift b/ReaderHive/Class/Novel/VC/NRNovelDetailCatalogViewController.swift
index 18e7daf..ab9da76 100644
--- a/ReaderHive/Class/Novel/VC/NRNovelDetailCatalogViewController.swift
+++ b/ReaderHive/Class/Novel/VC/NRNovelDetailCatalogViewController.swift
@@ -40,7 +40,7 @@ class NRNovelDetailCatalogViewController: NRViewController {
let label = UILabel()
label.font = .font(ofSize: 14, weight: .medium)
label.textColor = .black
- label.numberOfLines = 0
+ label.numberOfLines = 3
return label
}()
@@ -56,6 +56,7 @@ class NRNovelDetailCatalogViewController: NRViewController {
tableView.delegate = self
tableView.dataSource = self
tableView.separatorStyle = .none
+ tableView.showsVerticalScrollIndicator = false
// tableView.rowHeight = 44
tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.safeBottom, right: 0)
tableView.register(NRNovelCatalogCell.self, forCellReuseIdentifier: "cell")
@@ -201,7 +202,32 @@ extension NRNovelDetailCatalogViewController {
guard let list = await NRNovelAPI.requestChapterCatalogList(id: id) else { return }
self.dataArr = list
- self.tableView.reloadData()
+
+ UIView.performWithoutAnimation {
+ self.tableView.reloadData()
+ }
+
+ self.tableView.performBatchUpdates(nil) { [weak self] _ in
+ guard let self = self else { return }
+
+// if self.isScrollToCurrent {
+//
+// }
+ let row = self.getCurrentIndex()
+
+ self.tableView.scrollToRow(at: IndexPath(row: row, section: 0), at: .top, animated: false)
+ }
+ }
+
+ private func getCurrentIndex() -> Int {
+ var currentIndex = 0
+ for (i, catalogModel) in self.dataArr.enumerated() {
+ if catalogModel.id == self.novelModel?.progress?.short_play_video_id {
+ currentIndex = i
+ break
+ }
+ }
+ return currentIndex
}
}
diff --git a/ReaderHive/Class/Novel/VC/NRNovelDetailRecommandViewController.swift b/ReaderHive/Class/Novel/VC/NRNovelDetailRecommandViewController.swift
index 6abcca6..6a77a03 100644
--- a/ReaderHive/Class/Novel/VC/NRNovelDetailRecommandViewController.swift
+++ b/ReaderHive/Class/Novel/VC/NRNovelDetailRecommandViewController.swift
@@ -33,7 +33,7 @@ class NRNovelDetailRecommandViewController: NRViewController {
let itemHeight = 150 / 100 * itemWidth + 68
let layout = UICollectionViewFlowLayout()
- layout.itemSize = .init(width: itemWidth, height: itemHeight)
+ layout.itemSize = .init(width: floor(itemWidth), height: itemHeight)
layout.minimumLineSpacing = 18
layout.minimumInteritemSpacing = 20
layout.sectionInset = .init(top: 0, left: 16, bottom: 0, right: 16)
diff --git a/ReaderHive/Class/Novel/VC/NRNovelDetailViewController.swift b/ReaderHive/Class/Novel/VC/NRNovelDetailViewController.swift
index 1938f6e..fb5bd70 100644
--- a/ReaderHive/Class/Novel/VC/NRNovelDetailViewController.swift
+++ b/ReaderHive/Class/Novel/VC/NRNovelDetailViewController.swift
@@ -7,6 +7,7 @@
import UIKit
import SnapKit
+import LYEmptyView
class NRNovelDetailViewController: NRViewController {
@@ -77,6 +78,7 @@ class NRNovelDetailViewController: NRViewController {
self.edgesForExtendedLayout = [.top]
self.view.backgroundColor = .white
+ NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(updateCollectStateNotification), name: NRNovelAPI.updateCollectStateNotification, object: nil)
recommandListView.addObserver(self, forKeyPath: "contentSize", context: nil)
@@ -143,14 +145,42 @@ class NRNovelDetailViewController: NRViewController {
}
}
+ override func handleNotNetworkingEmptyBtn() {
+ Task {
+ await updateData()
+ }
+ self.nr_setupUI()
+ }
+
+ @objc private func networkStatusDidChangeNotification() {
+ guard NRNetworkReachableManager.manager.isReachable == true else { return }
+ if self.viewModel.novelModel == nil {
+ Task {
+ await updateData()
+ }
+ }
+ nr_setupUI()
+ }
+
}
extension NRNovelDetailViewController {
private func nr_setupUI() {
- addChild(recommandVC)
+ guard tableView.superview == nil else { return }
+ if NRNetworkReachableManager.manager.isReachable != true {
+ if self.view.ly_emptyView == nil {
+ self.view.ly_emptyView = self.notNetworkingEmptyView
+ }
+ self.view.ly_showEmpty()
+ return;
+ }
+ self.view.ly_hideEmpty()
+
+
+ addChild(recommandVC)
view.addSubview(coverBgImageView)
view.addSubview(bottomView)
view.addSubview(tableView)
diff --git a/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController+Page.swift b/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController+Page.swift
index afe7989..3b3fe59 100644
--- a/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController+Page.swift
+++ b/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController+Page.swift
@@ -50,6 +50,8 @@ extension NRNovelReaderViewController {
let lockCoins = model?.coins ?? 0
let myCoins = NRLoginManager.manager.userInfo?.totalCoins ?? 0
if model?.is_lock == true {
+ //隐藏底部跟顶部的菜单
+ self.viewModel.showAllMenuView(isShow: false)
if lockCoins > myCoins { //弹出支付页面
self.viewModel.openRechargeView()
}
@@ -59,6 +61,7 @@ extension NRNovelReaderViewController {
}
+//MARK: NRNovelReadPageViewControllerDelegate
extension NRNovelReaderViewController: NRNovelReadPageViewControllerDelegate {
func pageViewController(_ pageViewController: NRNovelReadPageViewController, getViewControllerBefore viewController: UIViewController?) {
@@ -68,20 +71,36 @@ extension NRNovelReaderViewController: NRNovelReadPageViewControllerDelegate {
}
///点击进入下一页
func pageViewController(_ pageViewController: NRNovelReadPageViewController, getViewControllerAfter viewController: UIViewController?) {
+ let (currentCatalogModel, _) = self.viewModel.getCurrentPageData()
+ if currentCatalogModel?.is_lock == true {
+ self.viewModel.openRechargeView()
+ return
+ }
+
if let vc = getBelowReadController() {
setViewController(displayController: vc, isAbove: false, animated: true)
}
}
}
-
+//MARK: UIPageViewControllerDelegate
extension NRNovelReaderViewController: UIPageViewControllerDelegate {
///翻页完成
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) {
- if completed {
+ guard completed else { return }
+ guard let vc = pageViewController.viewControllers?.first as? NRNovelReadBaseViewController, let vcPageModel = vc.pageModel else { return }
+
+ let (_, pageModel) = self.viewModel.getPageData(vcPageModel.indexPath)
+ if pageModel != vc.pageModel {//当前页面数据与实际数据不相符的情况下,需要重载数据
+ self.viewModel.currentPageIndexPath = vcPageModel.indexPath
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
+ self.reloadData()
+ }
+ } else {
pageFinish(pageViewController.viewControllers?.first)
}
+
}
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
@@ -159,7 +178,6 @@ extension NRNovelReaderViewController {
let (currentCatalogModel, _) = self.viewModel.getCurrentPageData()
if currentCatalogModel?.is_lock == true {
- self.viewModel.openRechargeView()
return nil
} else {
let (catalogModel, pageModel) = self.viewModel.getBelowPageData()
diff --git a/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController.swift b/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController.swift
index d6b0c6c..eed7c2a 100644
--- a/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController.swift
+++ b/ReaderHive/Class/Novel/VC/Read/NRNovelReaderViewController.swift
@@ -8,6 +8,7 @@
import UIKit
import SnapKit
import FDFullscreenPopGesture
+import LYEmptyView
class NRNovelReaderViewController: NRViewController {
@@ -38,6 +39,8 @@ class NRNovelReaderViewController: NRViewController {
}
}
+ let oldBrightness: CGFloat = UIScreen.main.brightness
+
private(set) lazy var viewModel: NRNovelReadViewModel = {
let vm = NRNovelReadViewModel()
return vm
@@ -83,7 +86,11 @@ class NRNovelReaderViewController: NRViewController {
NotificationCenter.default.addObserver(self, selector: #selector(didChangedThemeNotification), name: NRNovelReadSetManager.didChangedThemeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(didChangedTextLayoutNotification), name: NRNovelReadSetManager.didChangedTextLayoutNotification, object: nil)
- self.view.backgroundColor = NRNovelReadSetManager.manager.currentTheme.backgroundColor
+ NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(willResignActiveNotification), name: UIApplication.willResignActiveNotification, object: nil)
+ NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActiveNotification), name: UIApplication.didBecomeActiveNotification, object: nil)
+
+ self.didChangedThemeNotification()
viewModel.vc = self
viewModel.topView = topView
@@ -105,6 +112,8 @@ class NRNovelReaderViewController: NRViewController {
super.viewDidAppear(animated)
//防止自动锁屏
UIApplication.shared.isIdleTimerDisabled = true
+
+ UIScreen.main.brightness = NRNovelReadSetManager.manager.brightness
}
override func viewWillDisappear(_ animated: Bool) {
@@ -112,6 +121,11 @@ class NRNovelReaderViewController: NRViewController {
UIApplication.shared.isIdleTimerDisabled = false
}
+ override func viewDidDisappear(_ animated: Bool) {
+ super.viewDidDisappear(animated)
+ UIScreen.main.brightness = oldBrightness
+ }
+
override var prefersStatusBarHidden: Bool {
return !self.viewModel.showTop
}
@@ -140,25 +154,37 @@ class NRNovelReaderViewController: NRViewController {
}
}
- @objc private func didChangedThemeNotification() {
- self.view.backgroundColor = NRNovelReadSetManager.manager.currentTheme.backgroundColor
- self.setNeedsStatusBarAppearanceUpdate()
- }
- @objc private func didChangedTextLayoutNotification() {
- self.viewModel.parserAllDataAndReloadPage(dismissMenu: false)
- }
func reloadData() {
if let vc = self.getCurrentReadController() {
setViewController(displayController: vc, isAbove: false, animated: false)
}
}
+
+ override func handleNotNetworkingEmptyBtn() {
+ self.loadData()
+ self.nr_setupUI()
+ }
+
+
}
+
extension NRNovelReaderViewController {
private func nr_setupUI() {
+ guard readContentView.superview == nil else { return }
+
+ if NRNetworkReachableManager.manager.isReachable != true {
+ if self.view.ly_emptyView == nil {
+ self.view.ly_emptyView = self.notNetworkingEmptyView
+ }
+ self.view.ly_showEmpty()
+ return;
+ }
+ self.view.ly_hideEmpty()
+
view.addSubview(readContentView)
view.addSubview(topView)
view.addSubview(bottomView)
@@ -276,3 +302,34 @@ extension NRNovelReaderViewController {
}
}
+
+extension NRNovelReaderViewController {
+ @objc private func didChangedThemeNotification() {
+ self.view.backgroundColor = NRNovelReadSetManager.manager.currentTheme.backgroundColor
+ self.setNeedsStatusBarAppearanceUpdate()
+ }
+
+ @objc private func didChangedTextLayoutNotification() {
+ self.viewModel.parserAllDataAndReloadPage(dismissMenu: false)
+ }
+
+ @objc private func networkStatusDidChangeNotification() {
+ guard NRNetworkReachableManager.manager.isReachable == true else { return }
+ if self.viewModel.novelModel == nil {
+ self.loadData()
+ }
+ nr_setupUI()
+ }
+
+ @objc private func willResignActiveNotification() {
+ guard self.isViewDidAppear else { return }
+ UIScreen.main.brightness = oldBrightness
+ }
+
+ @objc private func didBecomeActiveNotification() {
+ guard self.isViewDidAppear else { return }
+ UIScreen.main.brightness = NRNovelReadSetManager.manager.brightness
+ }
+
+}
+
diff --git a/ReaderHive/Class/Novel/VM/NRNovelReadViewModel.swift b/ReaderHive/Class/Novel/VM/NRNovelReadViewModel.swift
index dd79f40..f2d4a48 100644
--- a/ReaderHive/Class/Novel/VM/NRNovelReadViewModel.swift
+++ b/ReaderHive/Class/Novel/VM/NRNovelReadViewModel.swift
@@ -237,7 +237,12 @@ extension NRNovelReadViewModel {
extension NRNovelReadViewModel: UIGestureRecognizerDelegate {
@objc private func touchSingleTap() {
- showAllMenuView(isShow: !showTop)
+ let (catalogModel, _) = self.getCurrentPageData()
+ if catalogModel?.is_lock == true {
+ openRechargeView()
+ } else {
+ showAllMenuView(isShow: !showTop)
+ }
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
diff --git a/ReaderHive/Class/Store/V/NRStoreVipCell.swift b/ReaderHive/Class/Store/V/NRStoreVipCell.swift
index e1796d6..3b3e0d7 100644
--- a/ReaderHive/Class/Store/V/NRStoreVipCell.swift
+++ b/ReaderHive/Class/Store/V/NRStoreVipCell.swift
@@ -132,6 +132,7 @@ class NRStoreVipCell: UICollectionViewCell {
let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular)
label.textColor = .black.withAlphaComponent(0.5)
+ label.numberOfLines = 2
return label
}()
@@ -146,11 +147,15 @@ class NRStoreVipCell: UICollectionViewCell {
let label = UILabel()
label.font = .font(ofSize: 14, weight: .bold).withBoldItalic()
label.textColor = ._9_C_6_A_45
+ label.setContentHuggingPriority(.required, for: .horizontal)
+ label.setContentCompressionResistancePriority(.required, for: .horizontal)
return label
}()
private lazy var extraIconView: UIView = {
let view = UIImageView(image: UIImage(named: "coins_icon_04"))
+ view.setContentHuggingPriority(.required, for: .horizontal)
+ view.setContentCompressionResistancePriority(.required, for: .horizontal)
return view
}()
@@ -210,8 +215,8 @@ extension NRStoreVipCell {
desLabel.snp.makeConstraints { make in
make.left.equalTo(priceLabel)
- make.right.lessThanOrEqualToSuperview().offset(-12)
- make.bottom.equalToSuperview().offset(-12)
+ make.right.lessThanOrEqualTo(extraBgView.snp.left).offset(-5)
+ make.centerY.equalTo(self.bgView.snp.bottom).offset(-18)
}
extraBgView.snp.makeConstraints { make in
diff --git a/ReaderHive/Delegate/AppDelegate+APNS.swift b/ReaderHive/Delegate/AppDelegate+APNS.swift
index 182b7d0..adc9127 100644
--- a/ReaderHive/Delegate/AppDelegate+APNS.swift
+++ b/ReaderHive/Delegate/AppDelegate+APNS.swift
@@ -37,10 +37,14 @@ extension AppDelegate {
private func showApnsAlert() {
guard let date = UserDefaults.standard.object(forKey: kNRApnsAlertDefaultsKey) as? Date else {
UserDefaults.standard.set(Date(), forKey: kNRApnsAlertDefaultsKey)
+ NROpenAppManager.manager.apnsAuthorizationFinish()
return
}
#if !DEBUG
- if date.nr_isToday { return }
+ if date.nr_isToday {
+ NROpenAppManager.manager.apnsAuthorizationFinish()
+ return
+ }
UserDefaults.standard.set(Date(), forKey: kNRApnsAlertDefaultsKey)
#endif
diff --git a/ReaderHive/Libs/Login/NRLoginManager.swift b/ReaderHive/Libs/Login/NRLoginManager.swift
index 1e13bbb..f3259ba 100644
--- a/ReaderHive/Libs/Login/NRLoginManager.swift
+++ b/ReaderHive/Libs/Login/NRLoginManager.swift
@@ -25,6 +25,8 @@ class NRLoginManager: NSObject {
func setAccountToken(_ token: NRLoginToken?) {
self.token = token
UserDefaults.nr_setObject(token, forKey: kNRLoginTokenDefaultsKey)
+ NRStatAPI.nr_requestEnterApp()
+ NRStatAPI.nr_requestStatOnLine()
}
@@ -74,8 +76,6 @@ class NRLoginManager: NSObject {
Task {
await self.updateUserInfo()
}
- NRStatAPI.nr_requestEnterApp()
- NRStatAPI.nr_requestStatOnLine()
completer?(true)
NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil)
NotificationCenter.default.post(name: NRLoginManager.loginStateDidChangeNotification, object: nil)
@@ -93,8 +93,6 @@ class NRLoginManager: NSObject {
Task {
await self.updateUserInfo()
}
- NRStatAPI.nr_requestEnterApp()
- NRStatAPI.nr_requestStatOnLine()
completer?(true)
NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil)
NotificationCenter.default.post(name: NRLoginManager.loginStateDidChangeNotification, object: nil)
diff --git a/ReaderHive/Libs/NovelTool/NRNovelReadSet.swift b/ReaderHive/Libs/NovelTool/NRNovelReadSet.swift
index e0706ef..a9d6d93 100644
--- a/ReaderHive/Libs/NovelTool/NRNovelReadSet.swift
+++ b/ReaderHive/Libs/NovelTool/NRNovelReadSet.swift
@@ -33,6 +33,8 @@ class NRNovelReadSet: NSObject, NSSecureCoding {
var paragraphSpacingType: SpacingType = .standard
var fontSize: CGFloat = 16
var isNight: Bool = false
+// var brightness: CGFloat = UIScreen.main.brightness
+ var brightness: CGFloat?
static var supportsSecureCoding: Bool {
return true
@@ -44,6 +46,7 @@ class NRNovelReadSet: NSObject, NSSecureCoding {
coder.encode(paragraphSpacingType.rawValue, forKey: "paragraphSpacingType")
coder.encode(fontSize, forKey: "fontSize")
coder.encode(isNight, forKey: "isNight")
+ coder.encode(brightness, forKey: "brightness")
}
required init?(coder: NSCoder) {
@@ -64,5 +67,9 @@ class NRNovelReadSet: NSObject, NSSecureCoding {
fontSize = CGFloat(coder.decodeObject(of: NSNumber.self, forKey: "fontSize")?.floatValue ?? 16)
isNight = coder.decodeBool(forKey: "isNight")
+
+ if let value = coder.decodeObject(of: NSNumber.self, forKey: "brightness")?.floatValue {
+ brightness = CGFloat(value)
+ }
}
}
diff --git a/ReaderHive/Libs/NovelTool/NRNovelReadSetManager.swift b/ReaderHive/Libs/NovelTool/NRNovelReadSetManager.swift
index ff2d127..4fe414e 100644
--- a/ReaderHive/Libs/NovelTool/NRNovelReadSetManager.swift
+++ b/ReaderHive/Libs/NovelTool/NRNovelReadSetManager.swift
@@ -82,6 +82,14 @@ class NRNovelReadSetManager: NSObject {
return readSet.isNight
}
+ var brightness: CGFloat {
+ if let brightness = self.readSet.brightness {
+ return brightness
+ } else {
+ return UIScreen.main.brightness
+ }
+ }
+
func updateTheme(type: NRReadThemeType) {
readSet.theme = type
readSet.isNight = false
@@ -113,6 +121,12 @@ class NRNovelReadSetManager: NSObject {
NotificationCenter.default.post(name: NRNovelReadSetManager.didChangedTextLayoutNotification, object: nil)
}
+ func updateBrightness(value: CGFloat) {
+ readSet.brightness = value
+ UIScreen.main.brightness = value
+ UserDefaults.nr_setObject(readSet, forKey: kNRNovelReadSetDefaultsKey)
+ }
+
/// 字体属性
/// isPaging: 为YES的时候只需要返回跟分页相关的属性即可 (原因:包含UIColor,小数点相关的...不可返回,因为无法进行比较)
func attributes(isTitle:Bool, isPageing:Bool = false) ->[NSAttributedString.Key:Any] {
@@ -140,8 +154,8 @@ class NRNovelReadSetManager: NSObject {
paragraphStyle.lineSpacing = lineSpacing
// 换行模式(避免每页尾部留空白)
- paragraphStyle.lineBreakMode = .byCharWrapping
-// paragraphStyle.lineBreakMode = .byWordWrapping
+// paragraphStyle.lineBreakMode = .byCharWrapping
+ paragraphStyle.lineBreakMode = .byWordWrapping
// 段间距
paragraphStyle.paragraphSpacing = paragraphSpacing
diff --git a/ReaderHive/ReaderHive.entitlements b/ReaderHive/ReaderHive.entitlements
index 79134f5..d7d40df 100644
--- a/ReaderHive/ReaderHive.entitlements
+++ b/ReaderHive/ReaderHive.entitlements
@@ -11,6 +11,8 @@
com.apple.developer.associated-domains
applinks:readerhive.net
+ applinks:rskb.adj.st
+ applinks:readerhive.go.link
keychain-access-groups