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