bug修复

This commit is contained in:
澜声世纪 2025-12-27 13:10:21 +08:00
parent 17d83f3b7a
commit 17669d1412
30 changed files with 343 additions and 54 deletions

View File

@ -29,7 +29,7 @@ struct NRHomeAPI {
} }
///Explore ///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 await withCheckedContinuation { continuation in
var param = NRNetwork.Parameters(path: "/rankingCollection") var param = NRNetwork.Parameters(path: "/rankingCollection")
@ -37,7 +37,7 @@ struct NRHomeAPI {
param.parameters = [ param.parameters = [
"days" : days, "days" : days,
"type" : type, "type" : type,
"current_page" : 1, "current_page" : page,
"page_size" : 20, "page_size" : 20,
] ]

View File

@ -86,7 +86,14 @@ struct NRStatAPI {
} }
///APP ///APP
private static var nr_needRequestEnterApp = true
static func nr_requestEnterApp() { 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") var param = NRNetwork.Parameters(path: "/customer/enterTheApp")
param.method = .post param.method = .post
param.isLoding = false param.isLoding = false

View File

@ -42,6 +42,8 @@ class NRTabBarController: UITabBarController {
NRTool.checkUpdates() NRTool.checkUpdates()
NROpenAppManager.manager.requestIDFAAuthorization() NROpenAppManager.manager.requestIDFAAuthorization()
NRIapManager.manager.restore(isLoding: false, completer: nil)
} }

View File

@ -15,6 +15,7 @@ class NRExploreNovelContentListViewController: NRViewController {
var contentType: NRExploreNovelContentViewController.ContentType = .today var contentType: NRExploreNovelContentViewController.ContentType = .today
lazy var dataArr: [NRNovelModel] = [] lazy var dataArr: [NRNovelModel] = []
lazy var page = 1
lazy var collectionViewLayout: UICollectionViewCompositionalLayout = { lazy var collectionViewLayout: UICollectionViewCompositionalLayout = {
let item = NSCollectionLayoutItem( let item = NSCollectionLayoutItem(
@ -42,7 +43,14 @@ class NRExploreNovelContentListViewController: NRViewController {
frame: .zero, collectionViewLayout: collectionViewLayout) frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self collectionView.delegate = self
collectionView.dataSource = self collectionView.dataSource = self
collectionView.showsVerticalScrollIndicator = false
collectionView.contentInset = .init(top: 0, left: 0, bottom: 10, right: 0) 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( collectionView.register(
NRExploreNovelContentListCell.self, forCellWithReuseIdentifier: "cell") NRExploreNovelContentListCell.self, forCellWithReuseIdentifier: "cell")
return collectionView return collectionView
@ -64,19 +72,30 @@ class NRExploreNovelContentListViewController: NRViewController {
nr_setupUI() nr_setupUI()
Task { Task {
await requestDataArr() await requestDataArr(page: 1)
} }
} }
@objc private func networkStatusDidChangeNotification() { @objc private func networkStatusDidChangeNotification() {
guard NRNetworkReachableManager.manager.isReachable == true, self.dataArr.isEmpty else { guard NRNetworkReachableManager.manager.isReachable == true, self.dataArr.isEmpty else { return }
return
}
Task { 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 { extension NRExploreNovelContentListViewController {
@ -126,14 +145,16 @@ extension NRExploreNovelContentListViewController: UICollectionViewDelegate,
extension NRExploreNovelContentListViewController { extension NRExploreNovelContentListViewController {
private func requestDataArr() async { private func requestDataArr(page: Int) async {
guard let type = self.menuItem?.type else { return } guard let type = self.menuItem?.type else { return }
guard guard
let list = await NRHomeAPI.requestRankingCollection( let list = await NRHomeAPI.requestRankingCollection(page: page, type: type.rawValue, days: self.contentType.rawValue)
type: type.rawValue, days: self.contentType.rawValue)
else { return } else { return }
if page == 1 {
self.dataArr = list self.dataArr.removeAll()
}
self.page = page
self.dataArr += list
self.collectionView.reloadData() self.collectionView.reloadData()
} }

View File

@ -38,6 +38,7 @@ class NRExploreNovelGenresViewController: NRViewController {
collectionView.delegate = self collectionView.delegate = self
collectionView.dataSource = self collectionView.dataSource = self
collectionView.contentInset = .init(top: 0, left: 0, bottom: 10, right: 0) collectionView.contentInset = .init(top: 0, left: 0, bottom: 10, right: 0)
collectionView.showsVerticalScrollIndicator = false
collectionView.register(NRExploreNovelGenresCell.self, forCellWithReuseIdentifier: "cell") collectionView.register(NRExploreNovelGenresCell.self, forCellWithReuseIdentifier: "cell")
return collectionView return collectionView
}() }()

View File

@ -7,6 +7,7 @@
import UIKit import UIKit
import SnapKit import SnapKit
import LYEmptyView
class NRExploreViewController: NRViewController { class NRExploreViewController: NRViewController {
@ -26,9 +27,13 @@ class NRExploreViewController: NRViewController {
lazy var novelVC = NRExploreNovelViewController() lazy var novelVC = NRExploreNovelViewController()
@MainActor deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
nr_setupUI() nr_setupUI()
} }
@ -39,11 +44,32 @@ class NRExploreViewController: NRViewController {
} }
override func handleNotNetworkingEmptyBtn() {
self.nr_setupUI()
}
@objc private func networkStatusDidChangeNotification() {
guard NRNetworkReachableManager.manager.isReachable == true else { return }
nr_setupUI()
}
} }
extension NRExploreViewController { extension NRExploreViewController {
private func nr_setupUI() { 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(searchButton)
view.addSubview(titleView) view.addSubview(titleView)
addChild(novelVC) addChild(novelVC)

View File

@ -20,7 +20,7 @@ class NRNovelGenresViewController: NRViewController {
let itemWidth = (UIScreen.width - 32 - 40) / 3 let itemWidth = (UIScreen.width - 32 - 40) / 3
let itemHeight = 150 / 100 * itemWidth + 68 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]) let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(itemHeight)), subitems: [item])
group.interItemSpacing = .fixed(20) group.interItemSpacing = .fixed(20)

View File

@ -30,6 +30,7 @@ class NRSearchResultView: UIView {
let collectionView = NRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout) let collectionView = NRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.delegate = self collectionView.delegate = self
collectionView.dataSource = self collectionView.dataSource = self
collectionView.keyboardDismissMode = .onDrag
collectionView.contentInset = .init(top: 10, left: 0, bottom: UIScreen.safeBottom + 10, right: 0) collectionView.contentInset = .init(top: 10, left: 0, bottom: UIScreen.safeBottom + 10, right: 0)
collectionView.ly_emptyView = NREmpty.nr_emptyView() collectionView.ly_emptyView = NREmpty.nr_emptyView()
collectionView.register(NRSearchResultCell.self, forCellWithReuseIdentifier: "cell") collectionView.register(NRSearchResultCell.self, forCellWithReuseIdentifier: "cell")

View File

@ -15,7 +15,7 @@ class NRMeHeaderView: UITableViewHeaderFooterView {
var userInfo: NRUserInfo? { var userInfo: NRUserInfo? {
didSet { didSet {
avatarImageView.nr_setImage(userInfo?.avator) avatarImageView.nr_setImage(userInfo?.avator, placeholder: UIImage(named: "logo_icon_01"))
nickLabel.text = userInfo?.getNickName() nickLabel.text = userInfo?.getNickName()
idLabel.text = "ID\(userInfo?.customer_id ?? "")" idLabel.text = "ID\(userInfo?.customer_id ?? "")"

View File

@ -8,6 +8,7 @@
import UIKit import UIKit
import SnapKit import SnapKit
import HWPanModal import HWPanModal
import YYCategories
class NRSettingFooterView: UICollectionReusableView { 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) let alert = NRAlert(title: "Log Out".localized, detail: "logout_alert_text".localized, topIconImage: UIImage(named: "alert_top_icon_02"), highlightButtonText: "Confirm".localized)
alert.highlightHandle = { alert.highlightHandle = {
NRLoginManager.manager.logout(completer: nil) NRLoginManager.manager.logout(completer: nil)
self.viewController?.navigationController?.popViewController(animated: true)
} }
alert.show() alert.show()

View File

@ -21,6 +21,9 @@ class NRMeViewController: NRViewController {
tableView.rowHeight = 60 tableView.rowHeight = 60
tableView.register(NRMeCell.self, forCellReuseIdentifier: "cell") tableView.register(NRMeCell.self, forCellReuseIdentifier: "cell")
tableView.register(NRMeHeaderView.self, forHeaderFooterViewReuseIdentifier: "header") tableView.register(NRMeHeaderView.self, forHeaderFooterViewReuseIdentifier: "header")
tableView.nr_addRefreshHeader(insetTop: 0) { [weak self] in
self?.handleHeaderRefresh(nil)
}
return tableView return tableView
}() }()
@ -54,6 +57,13 @@ class NRMeViewController: NRViewController {
reloadDataArr() reloadDataArr()
} }
override func handleHeaderRefresh(_ completer: (() -> Void)?) {
Task {
await NRLoginManager.manager.updateUserInfo()
self.tableView.nr_endHeaderRefreshing()
}
}
} }
extension NRMeViewController { extension NRMeViewController {

View File

@ -55,13 +55,14 @@ class NRMyListNovelViewController: NRViewController {
NotificationCenter.default.removeObserver(self) NotificationCenter.default.removeObserver(self)
} }
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
self.backgroundImageView.isHidden = true self.backgroundImageView.isHidden = true
self.view.backgroundColor = .clear 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(updateCollectStateNotification), name: NRNovelAPI.updateCollectStateNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(loginStateDidChangeNotification), name: NRLoginManager.loginStateDidChangeNotification, object: nil)
nr_setupUI() nr_setupUI()
@ -99,6 +100,19 @@ class NRMyListNovelViewController: NRViewController {
} }
} }
@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)
}
}
} }
extension NRMyListNovelViewController { extension NRMyListNovelViewController {
@ -173,6 +187,8 @@ extension NRMyListNovelViewController {
guard let id = model.short_play_id else { return } guard let id = model.short_play_id else { return }
await NRNovelAPI.requestCollect(isCollect: false, id: id, chapterId: model.short_play_video_id) 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) // await self.requestDataArr(page: 1)
} }

View File

@ -7,6 +7,7 @@
import UIKit import UIKit
import SnapKit import SnapKit
import LYEmptyView
class NRMyListViewController: NRViewController { class NRMyListViewController: NRViewController {
@ -39,8 +40,13 @@ class NRMyListViewController: NRViewController {
return button return button
}() }()
@MainActor deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(networkStatusDidChangeNotification), name: NRNetworkReachableManager.networkStatusDidChangeNotification, object: nil)
nr_setupUI() nr_setupUI()
} }
@ -55,12 +61,32 @@ class NRMyListViewController: NRViewController {
self.nr_isEditing = false 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 { extension NRMyListViewController {
private func nr_setupUI() { 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(titleLabel)
view.addSubview(editButton) view.addSubview(editButton)
addChild(novelVC) addChild(novelVC)

View File

@ -15,7 +15,13 @@ extension NRNovelDetailHeaderView {
var num: CGFloat = 0 { var num: CGFloat = 0 {
didSet { 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") fatalError("init(coder:) has not been implemented")
} }
private func updateNumLabel() {
numLabel.text = NSNumber(value: num).toString(minimumFractionDigits: minimumFractionDigits)
}
} }
} }

View File

@ -98,6 +98,7 @@ class NRNovelDetailHeaderView: UIView {
private lazy var rateDataView: DataView = { private lazy var rateDataView: DataView = {
let view = DataView() let view = DataView()
view.num = 0 view.num = 0
view.minimumFractionDigits = 1
view.icon = UIImage(named: "rate_icon_01") view.icon = UIImage(named: "rate_icon_01")
view.title = "Rate".localized view.title = "Rate".localized
return view return view

View File

@ -25,8 +25,8 @@ class NRNovelReadStarGradeView: UIView {
// gradeView.updateOnTouch = true // gradeView.updateOnTouch = true
// gradeView.fillMode = .full // gradeView.fillMode = .full
} else { } else {
label.text = "My Rate##".localizedReplace(text: NSNumber(value: self_rate).toString(maximumFractionDigits: 1, minimumFractionDigits: 1)) label.text = "My Rate##".localizedReplace(text: NSNumber(value: self_rate * 2).toString(maximumFractionDigits: 1, minimumFractionDigits: 1))
gradeView.grade = self_rate / 2 gradeView.grade = self_rate
// gradeView.updateOnTouch = false // gradeView.updateOnTouch = false
// gradeView.fillMode = .precise // gradeView.fillMode = .precise
} }
@ -84,7 +84,7 @@ class NRNovelReadStarGradeView: UIView {
guard let id = self.model?.id else { return } guard let id = self.model?.id else { return }
Task { Task {
guard await NRNovelAPI.requestRateScore(id, stars: CGFloat(grade)) else { return} guard await NRNovelAPI.requestRateScore(id, stars: CGFloat(grade)) else { return}
self.model?.self_rate = grade * 2 self.model?.self_rate = grade
gradeView.isHidden = true gradeView.isHidden = true
label.isHidden = true label.isHidden = true
finishView.isHidden = false finishView.isHidden = false

View File

@ -56,7 +56,7 @@ class NRNovelReaderCatalogView: UIView {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 14, weight: .medium) label.font = .font(ofSize: 14, weight: .medium)
label.textColor = .black label.textColor = .black
label.numberOfLines = 0 label.numberOfLines = 3
return label return label
}() }()
@ -85,6 +85,7 @@ class NRNovelReaderCatalogView: UIView {
tableView.delegate = self tableView.delegate = self
tableView.dataSource = self tableView.dataSource = self
tableView.separatorStyle = .none tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
// tableView.rowHeight = 44 // tableView.rowHeight = 44
tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.safeBottom, right: 0) tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.safeBottom, right: 0)
tableView.register(NRNovelCatalogCell.self, forCellReuseIdentifier: "cell") tableView.register(NRNovelCatalogCell.self, forCellReuseIdentifier: "cell")

View File

@ -13,14 +13,15 @@ class NRReadSettingBrightnessView: NRNovelReadSettingItemView {
lazy var progressView: NRProgressView = { lazy var progressView: NRProgressView = {
let view = NRProgressView() let view = NRProgressView()
view.progress = UIScreen.main.brightness
view.thumbImage = UIImage(named: "Progress-handle") view.thumbImage = UIImage(named: "Progress-handle")
view.insets = .init(top: 6, left: 0, bottom: 6, right: 0) view.insets = .init(top: 6, left: 0, bottom: 6, right: 0)
view.panChange = { progress in view.panChange = { progress in
UIScreen.main.brightness = progress NRNovelReadSetManager.manager.updateBrightness(value: progress)
} }
view.panFinish = { [weak self] progress in view.panFinish = { [weak self] progress in
self?.progressView.progress = progress self?.progressView.progress = progress
UIScreen.main.brightness = progress NRNovelReadSetManager.manager.updateBrightness(value: progress)
} }
return view return view
}() }()
@ -30,8 +31,7 @@ class NRReadSettingBrightnessView: NRNovelReadSettingItemView {
self.titleLabel.text = "Brightness".localized self.titleLabel.text = "Brightness".localized
let imageSize = progressView.thumbImage?.size ?? .zero let imageSize = progressView.thumbImage?.size ?? .zero
contentView.addSubview(progressView)
contentView.addSubview(progressView)
progressView.snp.makeConstraints { make in progressView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(-imageSize.width / 2) make.left.equalToSuperview().offset(-imageSize.width / 2)
@ -39,7 +39,7 @@ class NRReadSettingBrightnessView: NRNovelReadSettingItemView {
make.top.bottom.equalToSuperview() make.top.bottom.equalToSuperview()
} }
progressView.progress = UIScreen.main.brightness
} }
@MainActor required init?(coder: NSCoder) { @MainActor required init?(coder: NSCoder) {

View File

@ -40,7 +40,7 @@ class NRNovelDetailCatalogViewController: NRViewController {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 14, weight: .medium) label.font = .font(ofSize: 14, weight: .medium)
label.textColor = .black label.textColor = .black
label.numberOfLines = 0 label.numberOfLines = 3
return label return label
}() }()
@ -56,6 +56,7 @@ class NRNovelDetailCatalogViewController: NRViewController {
tableView.delegate = self tableView.delegate = self
tableView.dataSource = self tableView.dataSource = self
tableView.separatorStyle = .none tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
// tableView.rowHeight = 44 // tableView.rowHeight = 44
tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.safeBottom, right: 0) tableView.contentInset = .init(top: 0, left: 0, bottom: UIScreen.safeBottom, right: 0)
tableView.register(NRNovelCatalogCell.self, forCellReuseIdentifier: "cell") tableView.register(NRNovelCatalogCell.self, forCellReuseIdentifier: "cell")
@ -201,7 +202,32 @@ extension NRNovelDetailCatalogViewController {
guard let list = await NRNovelAPI.requestChapterCatalogList(id: id) else { return } guard let list = await NRNovelAPI.requestChapterCatalogList(id: id) else { return }
self.dataArr = list 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
} }
} }

View File

@ -33,7 +33,7 @@ class NRNovelDetailRecommandViewController: NRViewController {
let itemHeight = 150 / 100 * itemWidth + 68 let itemHeight = 150 / 100 * itemWidth + 68
let layout = UICollectionViewFlowLayout() let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: itemWidth, height: itemHeight) layout.itemSize = .init(width: floor(itemWidth), height: itemHeight)
layout.minimumLineSpacing = 18 layout.minimumLineSpacing = 18
layout.minimumInteritemSpacing = 20 layout.minimumInteritemSpacing = 20
layout.sectionInset = .init(top: 0, left: 16, bottom: 0, right: 16) layout.sectionInset = .init(top: 0, left: 16, bottom: 0, right: 16)

View File

@ -7,6 +7,7 @@
import UIKit import UIKit
import SnapKit import SnapKit
import LYEmptyView
class NRNovelDetailViewController: NRViewController { class NRNovelDetailViewController: NRViewController {
@ -77,6 +78,7 @@ class NRNovelDetailViewController: NRViewController {
self.edgesForExtendedLayout = [.top] self.edgesForExtendedLayout = [.top]
self.view.backgroundColor = .white 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) NotificationCenter.default.addObserver(self, selector: #selector(updateCollectStateNotification), name: NRNovelAPI.updateCollectStateNotification, object: nil)
recommandListView.addObserver(self, forKeyPath: "contentSize", context: 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 { extension NRNovelDetailViewController {
private func nr_setupUI() { 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(coverBgImageView)
view.addSubview(bottomView) view.addSubview(bottomView)
view.addSubview(tableView) view.addSubview(tableView)

View File

@ -50,6 +50,8 @@ extension NRNovelReaderViewController {
let lockCoins = model?.coins ?? 0 let lockCoins = model?.coins ?? 0
let myCoins = NRLoginManager.manager.userInfo?.totalCoins ?? 0 let myCoins = NRLoginManager.manager.userInfo?.totalCoins ?? 0
if model?.is_lock == true { if model?.is_lock == true {
//
self.viewModel.showAllMenuView(isShow: false)
if lockCoins > myCoins { // if lockCoins > myCoins { //
self.viewModel.openRechargeView() self.viewModel.openRechargeView()
} }
@ -59,6 +61,7 @@ extension NRNovelReaderViewController {
} }
//MARK: NRNovelReadPageViewControllerDelegate
extension NRNovelReaderViewController: NRNovelReadPageViewControllerDelegate { extension NRNovelReaderViewController: NRNovelReadPageViewControllerDelegate {
func pageViewController(_ pageViewController: NRNovelReadPageViewController, getViewControllerBefore viewController: UIViewController?) { func pageViewController(_ pageViewController: NRNovelReadPageViewController, getViewControllerBefore viewController: UIViewController?) {
@ -68,20 +71,36 @@ extension NRNovelReaderViewController: NRNovelReadPageViewControllerDelegate {
} }
/// ///
func pageViewController(_ pageViewController: NRNovelReadPageViewController, getViewControllerAfter viewController: UIViewController?) { 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() { if let vc = getBelowReadController() {
setViewController(displayController: vc, isAbove: false, animated: true) setViewController(displayController: vc, isAbove: false, animated: true)
} }
} }
} }
//MARK: UIPageViewControllerDelegate
extension NRNovelReaderViewController: UIPageViewControllerDelegate { extension NRNovelReaderViewController: UIPageViewControllerDelegate {
/// ///
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { 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) pageFinish(pageViewController.viewControllers?.first)
} }
} }
func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) { func pageViewController(_ pageViewController: UIPageViewController, willTransitionTo pendingViewControllers: [UIViewController]) {
@ -159,7 +178,6 @@ extension NRNovelReaderViewController {
let (currentCatalogModel, _) = self.viewModel.getCurrentPageData() let (currentCatalogModel, _) = self.viewModel.getCurrentPageData()
if currentCatalogModel?.is_lock == true { if currentCatalogModel?.is_lock == true {
self.viewModel.openRechargeView()
return nil return nil
} else { } else {
let (catalogModel, pageModel) = self.viewModel.getBelowPageData() let (catalogModel, pageModel) = self.viewModel.getBelowPageData()

View File

@ -8,6 +8,7 @@
import UIKit import UIKit
import SnapKit import SnapKit
import FDFullscreenPopGesture import FDFullscreenPopGesture
import LYEmptyView
class NRNovelReaderViewController: NRViewController { class NRNovelReaderViewController: NRViewController {
@ -38,6 +39,8 @@ class NRNovelReaderViewController: NRViewController {
} }
} }
let oldBrightness: CGFloat = UIScreen.main.brightness
private(set) lazy var viewModel: NRNovelReadViewModel = { private(set) lazy var viewModel: NRNovelReadViewModel = {
let vm = NRNovelReadViewModel() let vm = NRNovelReadViewModel()
return vm 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(didChangedThemeNotification), name: NRNovelReadSetManager.didChangedThemeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(didChangedTextLayoutNotification), name: NRNovelReadSetManager.didChangedTextLayoutNotification, 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.vc = self
viewModel.topView = topView viewModel.topView = topView
@ -105,6 +112,8 @@ class NRNovelReaderViewController: NRViewController {
super.viewDidAppear(animated) super.viewDidAppear(animated)
// //
UIApplication.shared.isIdleTimerDisabled = true UIApplication.shared.isIdleTimerDisabled = true
UIScreen.main.brightness = NRNovelReadSetManager.manager.brightness
} }
override func viewWillDisappear(_ animated: Bool) { override func viewWillDisappear(_ animated: Bool) {
@ -112,6 +121,11 @@ class NRNovelReaderViewController: NRViewController {
UIApplication.shared.isIdleTimerDisabled = false UIApplication.shared.isIdleTimerDisabled = false
} }
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
UIScreen.main.brightness = oldBrightness
}
override var prefersStatusBarHidden: Bool { override var prefersStatusBarHidden: Bool {
return !self.viewModel.showTop 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() { func reloadData() {
if let vc = self.getCurrentReadController() { if let vc = self.getCurrentReadController() {
setViewController(displayController: vc, isAbove: false, animated: false) setViewController(displayController: vc, isAbove: false, animated: false)
} }
} }
override func handleNotNetworkingEmptyBtn() {
self.loadData()
self.nr_setupUI()
}
} }
extension NRNovelReaderViewController { extension NRNovelReaderViewController {
private func nr_setupUI() { 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(readContentView)
view.addSubview(topView) view.addSubview(topView)
view.addSubview(bottomView) 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
}
}

View File

@ -237,7 +237,12 @@ extension NRNovelReadViewModel {
extension NRNovelReadViewModel: UIGestureRecognizerDelegate { extension NRNovelReadViewModel: UIGestureRecognizerDelegate {
@objc private func touchSingleTap() { @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 { func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {

View File

@ -132,6 +132,7 @@ class NRStoreVipCell: UICollectionViewCell {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 12, weight: .regular) label.font = .font(ofSize: 12, weight: .regular)
label.textColor = .black.withAlphaComponent(0.5) label.textColor = .black.withAlphaComponent(0.5)
label.numberOfLines = 2
return label return label
}() }()
@ -146,11 +147,15 @@ class NRStoreVipCell: UICollectionViewCell {
let label = UILabel() let label = UILabel()
label.font = .font(ofSize: 14, weight: .bold).withBoldItalic() label.font = .font(ofSize: 14, weight: .bold).withBoldItalic()
label.textColor = ._9_C_6_A_45 label.textColor = ._9_C_6_A_45
label.setContentHuggingPriority(.required, for: .horizontal)
label.setContentCompressionResistancePriority(.required, for: .horizontal)
return label return label
}() }()
private lazy var extraIconView: UIView = { private lazy var extraIconView: UIView = {
let view = UIImageView(image: UIImage(named: "coins_icon_04")) let view = UIImageView(image: UIImage(named: "coins_icon_04"))
view.setContentHuggingPriority(.required, for: .horizontal)
view.setContentCompressionResistancePriority(.required, for: .horizontal)
return view return view
}() }()
@ -210,8 +215,8 @@ extension NRStoreVipCell {
desLabel.snp.makeConstraints { make in desLabel.snp.makeConstraints { make in
make.left.equalTo(priceLabel) make.left.equalTo(priceLabel)
make.right.lessThanOrEqualToSuperview().offset(-12) make.right.lessThanOrEqualTo(extraBgView.snp.left).offset(-5)
make.bottom.equalToSuperview().offset(-12) make.centerY.equalTo(self.bgView.snp.bottom).offset(-18)
} }
extraBgView.snp.makeConstraints { make in extraBgView.snp.makeConstraints { make in

View File

@ -37,10 +37,14 @@ extension AppDelegate {
private func showApnsAlert() { private func showApnsAlert() {
guard let date = UserDefaults.standard.object(forKey: kNRApnsAlertDefaultsKey) as? Date else { guard let date = UserDefaults.standard.object(forKey: kNRApnsAlertDefaultsKey) as? Date else {
UserDefaults.standard.set(Date(), forKey: kNRApnsAlertDefaultsKey) UserDefaults.standard.set(Date(), forKey: kNRApnsAlertDefaultsKey)
NROpenAppManager.manager.apnsAuthorizationFinish()
return return
} }
#if !DEBUG #if !DEBUG
if date.nr_isToday { return } if date.nr_isToday {
NROpenAppManager.manager.apnsAuthorizationFinish()
return
}
UserDefaults.standard.set(Date(), forKey: kNRApnsAlertDefaultsKey) UserDefaults.standard.set(Date(), forKey: kNRApnsAlertDefaultsKey)
#endif #endif

View File

@ -25,6 +25,8 @@ class NRLoginManager: NSObject {
func setAccountToken(_ token: NRLoginToken?) { func setAccountToken(_ token: NRLoginToken?) {
self.token = token self.token = token
UserDefaults.nr_setObject(token, forKey: kNRLoginTokenDefaultsKey) UserDefaults.nr_setObject(token, forKey: kNRLoginTokenDefaultsKey)
NRStatAPI.nr_requestEnterApp()
NRStatAPI.nr_requestStatOnLine()
} }
@ -74,8 +76,6 @@ class NRLoginManager: NSObject {
Task { Task {
await self.updateUserInfo() await self.updateUserInfo()
} }
NRStatAPI.nr_requestEnterApp()
NRStatAPI.nr_requestStatOnLine()
completer?(true) completer?(true)
NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil) NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil)
NotificationCenter.default.post(name: NRLoginManager.loginStateDidChangeNotification, object: nil) NotificationCenter.default.post(name: NRLoginManager.loginStateDidChangeNotification, object: nil)
@ -93,8 +93,6 @@ class NRLoginManager: NSObject {
Task { Task {
await self.updateUserInfo() await self.updateUserInfo()
} }
NRStatAPI.nr_requestEnterApp()
NRStatAPI.nr_requestStatOnLine()
completer?(true) completer?(true)
NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil) NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil)
NotificationCenter.default.post(name: NRLoginManager.loginStateDidChangeNotification, object: nil) NotificationCenter.default.post(name: NRLoginManager.loginStateDidChangeNotification, object: nil)

View File

@ -33,6 +33,8 @@ class NRNovelReadSet: NSObject, NSSecureCoding {
var paragraphSpacingType: SpacingType = .standard var paragraphSpacingType: SpacingType = .standard
var fontSize: CGFloat = 16 var fontSize: CGFloat = 16
var isNight: Bool = false var isNight: Bool = false
// var brightness: CGFloat = UIScreen.main.brightness
var brightness: CGFloat?
static var supportsSecureCoding: Bool { static var supportsSecureCoding: Bool {
return true return true
@ -44,6 +46,7 @@ class NRNovelReadSet: NSObject, NSSecureCoding {
coder.encode(paragraphSpacingType.rawValue, forKey: "paragraphSpacingType") coder.encode(paragraphSpacingType.rawValue, forKey: "paragraphSpacingType")
coder.encode(fontSize, forKey: "fontSize") coder.encode(fontSize, forKey: "fontSize")
coder.encode(isNight, forKey: "isNight") coder.encode(isNight, forKey: "isNight")
coder.encode(brightness, forKey: "brightness")
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@ -64,5 +67,9 @@ class NRNovelReadSet: NSObject, NSSecureCoding {
fontSize = CGFloat(coder.decodeObject(of: NSNumber.self, forKey: "fontSize")?.floatValue ?? 16) fontSize = CGFloat(coder.decodeObject(of: NSNumber.self, forKey: "fontSize")?.floatValue ?? 16)
isNight = coder.decodeBool(forKey: "isNight") isNight = coder.decodeBool(forKey: "isNight")
if let value = coder.decodeObject(of: NSNumber.self, forKey: "brightness")?.floatValue {
brightness = CGFloat(value)
}
} }
} }

View File

@ -82,6 +82,14 @@ class NRNovelReadSetManager: NSObject {
return readSet.isNight return readSet.isNight
} }
var brightness: CGFloat {
if let brightness = self.readSet.brightness {
return brightness
} else {
return UIScreen.main.brightness
}
}
func updateTheme(type: NRReadThemeType) { func updateTheme(type: NRReadThemeType) {
readSet.theme = type readSet.theme = type
readSet.isNight = false readSet.isNight = false
@ -113,6 +121,12 @@ class NRNovelReadSetManager: NSObject {
NotificationCenter.default.post(name: NRNovelReadSetManager.didChangedTextLayoutNotification, object: nil) 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,...,) /// isPaging: YES (:UIColor,...,)
func attributes(isTitle:Bool, isPageing:Bool = false) ->[NSAttributedString.Key:Any] { func attributes(isTitle:Bool, isPageing:Bool = false) ->[NSAttributedString.Key:Any] {
@ -140,8 +154,8 @@ class NRNovelReadSetManager: NSObject {
paragraphStyle.lineSpacing = lineSpacing paragraphStyle.lineSpacing = lineSpacing
// //
paragraphStyle.lineBreakMode = .byCharWrapping // paragraphStyle.lineBreakMode = .byCharWrapping
// paragraphStyle.lineBreakMode = .byWordWrapping paragraphStyle.lineBreakMode = .byWordWrapping
// //
paragraphStyle.paragraphSpacing = paragraphSpacing paragraphStyle.paragraphSpacing = paragraphSpacing

View File

@ -11,6 +11,8 @@
<key>com.apple.developer.associated-domains</key> <key>com.apple.developer.associated-domains</key>
<array> <array>
<string>applinks:readerhive.net</string> <string>applinks:readerhive.net</string>
<string>applinks:rskb.adj.st</string>
<string>applinks:readerhive.go.link</string>
</array> </array>
<key>keychain-access-groups</key> <key>keychain-access-groups</key>
<array/> <array/>