一期
This commit is contained in:
parent
5b2b59ba12
commit
5ee82e3ab0
@ -88,14 +88,17 @@ struct NRNovelAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///查询章节数据 10011 金币不足 10005 提示
|
///查询章节数据 10011 金币不足 10005 提示
|
||||||
static func requestChapterData(novelId: String, chapterId: String) async -> (NRReadChapterModel?, Int?) {
|
static func requestChapterData(novelId: String, chapterId: String, isToast: Bool = false, isLoding: Bool = false) async -> (NRReadChapterModel?, Int?) {
|
||||||
await withCheckedContinuation { continuation in
|
await withCheckedContinuation { continuation in
|
||||||
var param = NRNetwork.Parameters(path: "/novel/getChapterInfo")
|
var param = NRNetwork.Parameters(path: "/novel/getChapterInfo")
|
||||||
param.method = .get
|
param.method = .get
|
||||||
|
param.isToast = isToast
|
||||||
|
param.isLoding = isLoding
|
||||||
param.parameters = [
|
param.parameters = [
|
||||||
"short_play_id" : novelId,
|
"short_play_id" : novelId,
|
||||||
"short_play_video_id" : chapterId,
|
"short_play_video_id" : chapterId,
|
||||||
]
|
]
|
||||||
|
|
||||||
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRReadChapterModel>) in
|
NRNetwork.request(parameters: param) { (response: NRNetwork.Response<NRReadChapterModel>) in
|
||||||
if response.isSuccess {
|
if response.isSuccess {
|
||||||
continuation.resume(returning: (response.data, response.code))
|
continuation.resume(returning: (response.data, response.code))
|
||||||
|
|||||||
@ -76,7 +76,7 @@ class NRImageView: UIImageView {
|
|||||||
override func layoutSubviews() {
|
override func layoutSubviews() {
|
||||||
super.layoutSubviews()
|
super.layoutSubviews()
|
||||||
|
|
||||||
placeholderImageView.frame = .init(x: 0, y: 0, width: self.bounds.width * (2 / 3), height: self.bounds.height * (2 / 3))
|
placeholderImageView.frame = .init(x: 0, y: 0, width: self.bounds.width * (1 / 3), height: self.bounds.height * (1 / 3))
|
||||||
placeholderImageView.center = .init(x: self.bounds.width / 2, y: self.bounds.height / 2)
|
placeholderImageView.center = .init(x: self.bounds.width / 2, y: self.bounds.height / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -90,7 +90,7 @@ extension NRExploreNovelContentViewController {
|
|||||||
|
|
||||||
private func nr_setupUI() {
|
private func nr_setupUI() {
|
||||||
view.addSubview(titleLabel)
|
view.addSubview(titleLabel)
|
||||||
view.addSubview(moreButton)
|
// view.addSubview(moreButton)
|
||||||
view.addSubview(pageMenuView)
|
view.addSubview(pageMenuView)
|
||||||
view.addSubview(pageView)
|
view.addSubview(pageView)
|
||||||
view.addSubview(lineView)
|
view.addSubview(lineView)
|
||||||
@ -98,17 +98,18 @@ extension NRExploreNovelContentViewController {
|
|||||||
|
|
||||||
titleLabel.snp.makeConstraints { make in
|
titleLabel.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(12)
|
make.left.equalToSuperview().offset(12)
|
||||||
make.centerY.equalTo(moreButton)
|
make.top.equalToSuperview().offset(16)
|
||||||
|
make.height.equalTo(24)
|
||||||
}
|
}
|
||||||
|
|
||||||
moreButton.snp.makeConstraints { make in
|
// moreButton.snp.makeConstraints { make in
|
||||||
make.right.equalToSuperview().offset(-12)
|
// make.right.equalToSuperview().offset(-12)
|
||||||
make.top.equalToSuperview().offset(16)
|
// make.top.equalToSuperview().offset(16)
|
||||||
}
|
// }
|
||||||
|
|
||||||
pageMenuView.snp.makeConstraints { make in
|
pageMenuView.snp.makeConstraints { make in
|
||||||
make.left.right.equalToSuperview()
|
make.left.right.equalToSuperview()
|
||||||
make.top.equalTo(moreButton.snp.bottom).offset(12)
|
make.top.equalTo(titleLabel.snp.bottom).offset(12)
|
||||||
make.height.equalTo(24)
|
make.height.equalTo(24)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import SnapKit
|
import SnapKit
|
||||||
//import JXPagingView
|
|
||||||
import JXSegmentedView
|
import JXSegmentedView
|
||||||
|
|
||||||
class NRExploreNovelViewController: NRViewController {
|
class NRExploreNovelViewController: NRViewController {
|
||||||
|
|||||||
@ -29,8 +29,25 @@ class NRReadChapterCatalogModel: NSObject, SmartCodable {
|
|||||||
@IgnoredKey
|
@IgnoredKey
|
||||||
var chapterModel: NRReadChapterModel?
|
var chapterModel: NRReadChapterModel?
|
||||||
|
|
||||||
|
///解析一个空白页面
|
||||||
|
func parserEmpty() {
|
||||||
|
let chapterModel = NRReadChapterModel()
|
||||||
|
if self.is_lock == true {
|
||||||
|
chapterModel.parserEmpty("Not unlocked yet".localized)
|
||||||
|
} else {
|
||||||
|
chapterModel.parserEmpty("Loading".localized)
|
||||||
|
}
|
||||||
|
self.chapterModel = chapterModel
|
||||||
|
}
|
||||||
|
|
||||||
|
///重新解析全部数据数据
|
||||||
|
func parserAllData() {
|
||||||
|
if self.chapterModel?.novel_txt == nil {
|
||||||
|
parserEmpty()
|
||||||
|
} else {
|
||||||
|
self.chapterModel?.parser()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -52,11 +52,6 @@ class NRReadChapterModel: NSObject, SmartCodable {
|
|||||||
|
|
||||||
///解析数据
|
///解析数据
|
||||||
func parser() {
|
func parser() {
|
||||||
guard novel_txt != nil else {
|
|
||||||
self.parserEmpty()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let tempAttributes = NRNovelReadSetManager.manager.attributes(isTitle: false, isPageing: true)
|
let tempAttributes = NRNovelReadSetManager.manager.attributes(isTitle: false, isPageing: true)
|
||||||
|
|
||||||
guard !NSDictionary(dictionary: attributes).isEqual(to: tempAttributes) else { return }
|
guard !NSDictionary(dictionary: attributes).isEqual(to: tempAttributes) else { return }
|
||||||
@ -77,8 +72,8 @@ class NRReadChapterModel: NSObject, SmartCodable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
///解析一个空白页面
|
///解析一个空白页面
|
||||||
func parserEmpty() {
|
func parserEmpty(_ text: String) {
|
||||||
fullContent = NSMutableAttributedString(string: "\n\n\n\n\n" + "Not unlocked yet".localized, attributes: NRNovelReadSetManager.manager.attributes(isTitle: true))
|
fullContent = NSMutableAttributedString(string: "\n\n\n\n\n" + text, attributes: NRNovelReadSetManager.manager.attributes(isTitle: true))
|
||||||
|
|
||||||
let pageModel = NRReadPageModel()
|
let pageModel = NRReadPageModel()
|
||||||
pageModel.content = fullContent
|
pageModel.content = fullContent
|
||||||
|
|||||||
@ -33,6 +33,8 @@ class NRNovelReadContentTopView: UIView {
|
|||||||
var configuration = UIButton.Configuration.plain()
|
var configuration = UIButton.Configuration.plain()
|
||||||
configuration.contentInsets = .zero
|
configuration.contentInsets = .zero
|
||||||
configuration.imagePadding = 12
|
configuration.imagePadding = 12
|
||||||
|
configuration.titleAlignment = .center
|
||||||
|
configuration.titleLineBreakMode = .byTruncatingTail
|
||||||
|
|
||||||
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
|
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
@ -99,6 +101,7 @@ extension NRNovelReadContentTopView {
|
|||||||
backButton.snp.makeConstraints { make in
|
backButton.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(16)
|
make.left.equalToSuperview().offset(16)
|
||||||
make.top.bottom.equalToSuperview()
|
make.top.bottom.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-16)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -145,6 +145,7 @@ extension NRNovelReadGradeView {
|
|||||||
nameLabel.snp.makeConstraints { make in
|
nameLabel.snp.makeConstraints { make in
|
||||||
make.top.equalTo(coverImageView).offset(8)
|
make.top.equalTo(coverImageView).offset(8)
|
||||||
make.left.equalTo(coverImageView.snp.right).offset(12)
|
make.left.equalTo(coverImageView.snp.right).offset(12)
|
||||||
|
make.right.lessThanOrEqualToSuperview().offset(-16)
|
||||||
}
|
}
|
||||||
|
|
||||||
starView.snp.makeConstraints { make in
|
starView.snp.makeConstraints { make in
|
||||||
|
|||||||
@ -32,6 +32,7 @@ class NRNovelReadTopView: UIView {
|
|||||||
configuration.contentInsets = .zero
|
configuration.contentInsets = .zero
|
||||||
configuration.image = UIImage(named: "arrow_left_icon_03")
|
configuration.image = UIImage(named: "arrow_left_icon_03")
|
||||||
configuration.imagePadding = 12
|
configuration.imagePadding = 12
|
||||||
|
configuration.titleLineBreakMode = .byTruncatingTail
|
||||||
|
|
||||||
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
|
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
@ -62,6 +63,8 @@ class NRNovelReadTopView: UIView {
|
|||||||
self.viewModel?.showMoreView()
|
self.viewModel?.showMoreView()
|
||||||
}))
|
}))
|
||||||
button.setImage(UIImage(named: "more_icon_01"), for: .normal)
|
button.setImage(UIImage(named: "more_icon_01"), for: .normal)
|
||||||
|
button.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
button.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||||
return button
|
return button
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@ -148,6 +151,7 @@ extension NRNovelReadTopView {
|
|||||||
backButton.snp.makeConstraints { make in
|
backButton.snp.makeConstraints { make in
|
||||||
make.left.equalToSuperview().offset(16)
|
make.left.equalToSuperview().offset(16)
|
||||||
make.top.bottom.equalToSuperview()
|
make.top.bottom.equalToSuperview()
|
||||||
|
make.right.lessThanOrEqualTo(moreButton.snp.left).offset(-10)
|
||||||
}
|
}
|
||||||
|
|
||||||
moreButton.snp.makeConstraints { make in
|
moreButton.snp.makeConstraints { make in
|
||||||
|
|||||||
@ -257,13 +257,25 @@ extension NRNovelReaderCatalogView: UITableViewDelegate, UITableViewDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
guard let novelId = self.novelModel?.id else { return }
|
||||||
|
let currentModel = self.catalogDataArr[indexPath.row]
|
||||||
|
|
||||||
let lastIndex = indexPath.row - 1
|
let lastIndex = indexPath.row - 1
|
||||||
var lastModel: NRReadChapterCatalogModel?
|
var lastModel: NRReadChapterCatalogModel?
|
||||||
if lastIndex >= 0 {
|
if lastIndex >= 0 {
|
||||||
lastModel = self.catalogDataArr[lastIndex]
|
lastModel = self.catalogDataArr[lastIndex]
|
||||||
}
|
}
|
||||||
///上一集加锁状态禁止点击
|
///上一集加锁状态禁止点击
|
||||||
if lastModel?.is_lock == true { return }
|
if lastModel?.is_lock == true {
|
||||||
|
Task {
|
||||||
|
let (_, code) = await NRNovelAPI.requestChapterData(novelId: novelId, chapterId: currentModel.id ?? "", isToast: true, isLoding: true)
|
||||||
|
if code == 200 {
|
||||||
|
self.didSelected?(indexPath.row)
|
||||||
|
self.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
self.didSelected?(indexPath.row)
|
self.didSelected?(indexPath.row)
|
||||||
self.dismiss()
|
self.dismiss()
|
||||||
|
|||||||
@ -142,8 +142,8 @@ extension NRNovelDetailCatalogViewController: UITableViewDelegate, UITableViewDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
guard let id = self.novelModel?.id else { return }
|
guard let novelId = self.novelModel?.id else { return }
|
||||||
let model = dataArr[indexPath.row]
|
let currentModel = dataArr[indexPath.row]
|
||||||
|
|
||||||
let lastIndex = indexPath.row - 1
|
let lastIndex = indexPath.row - 1
|
||||||
var lastModel: NRReadChapterCatalogModel?
|
var lastModel: NRReadChapterCatalogModel?
|
||||||
@ -152,17 +152,27 @@ extension NRNovelDetailCatalogViewController: UITableViewDelegate, UITableViewDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if lastModel?.is_lock == true {
|
if lastModel?.is_lock == true {
|
||||||
|
Task {
|
||||||
|
let (_, code) = await NRNovelAPI.requestChapterData(novelId: novelId, chapterId: currentModel.id ?? "", isToast: true, isLoding: true)
|
||||||
|
if code == 200 {
|
||||||
|
self.pushReadVC(currentModel)
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let vc = NRNovelReaderViewController()
|
self.pushReadVC(currentModel)
|
||||||
vc.novelId = id
|
|
||||||
vc.targetCatalogModel = model
|
|
||||||
self.navigationController?.pushViewController(vc, animated: true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func pushReadVC(_ model: NRReadChapterCatalogModel) {
|
||||||
|
guard let novelId = self.novelModel?.id else { return }
|
||||||
|
|
||||||
|
let vc = NRNovelReaderViewController()
|
||||||
|
vc.novelId = novelId
|
||||||
|
vc.targetCatalogModel = model
|
||||||
|
self.navigationController?.pushViewController(vc, animated: true)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NRNovelDetailCatalogViewController {
|
extension NRNovelDetailCatalogViewController {
|
||||||
|
|||||||
@ -156,9 +156,15 @@ extension NRNovelReaderViewController {
|
|||||||
|
|
||||||
///获取下一页控制器
|
///获取下一页控制器
|
||||||
func getBelowReadController() -> UIViewController? {
|
func getBelowReadController() -> UIViewController? {
|
||||||
|
let (currentCatalogModel, _) = self.viewModel.getCurrentPageData()
|
||||||
|
|
||||||
|
if currentCatalogModel?.is_lock == true {
|
||||||
|
return nil
|
||||||
|
} else {
|
||||||
let (catalogModel, pageModel) = self.viewModel.getBelowPageData()
|
let (catalogModel, pageModel) = self.viewModel.getBelowPageData()
|
||||||
return getReadController(catalogModel: catalogModel, pageModel: pageModel)
|
return getReadController(catalogModel: catalogModel, pageModel: pageModel)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///获取上一页控制器
|
///获取上一页控制器
|
||||||
func getAboveReadController() -> UIViewController? {
|
func getAboveReadController() -> UIViewController? {
|
||||||
|
|||||||
@ -141,6 +141,11 @@ class NRNovelReaderViewController: NRViewController {
|
|||||||
self.viewModel.parserAllDataAndReloadPage(dismissMenu: false)
|
self.viewModel.parserAllDataAndReloadPage(dismissMenu: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reloadData() {
|
||||||
|
if let vc = self.getCurrentReadController() {
|
||||||
|
setViewController(displayController: vc, isAbove: false, animated: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension NRNovelReaderViewController {
|
extension NRNovelReaderViewController {
|
||||||
@ -227,9 +232,7 @@ extension NRNovelReaderViewController {
|
|||||||
//校验索引,避免越界
|
//校验索引,避免越界
|
||||||
self.viewModel.checkCurrentIndexPath()
|
self.viewModel.checkCurrentIndexPath()
|
||||||
|
|
||||||
if let vc = self.getCurrentReadController() {
|
self.reloadData()
|
||||||
setViewController(displayController: vc, isAbove: false, animated: false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -78,7 +78,7 @@ extension NRNovelReadViewModel {
|
|||||||
func parserAllDataAndReloadPage(dismissMenu: Bool = true) {
|
func parserAllDataAndReloadPage(dismissMenu: Bool = true) {
|
||||||
///重新解析全部数据
|
///重新解析全部数据
|
||||||
self.chapterCatalogList.forEach {
|
self.chapterCatalogList.forEach {
|
||||||
$0.chapterModel?.parser()
|
$0.parserAllData()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.checkCurrentIndexPath()
|
self.checkCurrentIndexPath()
|
||||||
@ -101,7 +101,7 @@ extension NRNovelReadViewModel {
|
|||||||
let catalogModel = chapterCatalogList[currentSection]
|
let catalogModel = chapterCatalogList[currentSection]
|
||||||
let listCount = catalogModel.chapterModel?.pageList?.count ?? 0
|
let listCount = catalogModel.chapterModel?.pageList?.count ?? 0
|
||||||
|
|
||||||
if listCount <= currentRow {
|
if listCount <= currentRow, listCount > 0 {
|
||||||
currentRow = listCount - 1
|
currentRow = listCount - 1
|
||||||
}
|
}
|
||||||
self.currentPageIndexPath = IndexPath(row: currentRow, section: currentSection)
|
self.currentPageIndexPath = IndexPath(row: currentRow, section: currentSection)
|
||||||
@ -118,7 +118,15 @@ extension NRNovelReadViewModel {
|
|||||||
|
|
||||||
guard let displayController = vc?.getReadController(catalogModel: catalogModel, pageModel: chapterModel.pageList?.first) else { return }
|
guard let displayController = vc?.getReadController(catalogModel: catalogModel, pageModel: chapterModel.pageList?.first) else { return }
|
||||||
self.vc?.setViewController(displayController: displayController, isAbove: false, animated: false, dismissMenu: dismissMenu)
|
self.vc?.setViewController(displayController: displayController, isAbove: false, animated: false, dismissMenu: dismissMenu)
|
||||||
|
//缺少内容数据时,需要加载下真实数据
|
||||||
|
if chapterModel.novel_txt == nil {
|
||||||
|
Task {
|
||||||
|
guard let _ = await self.requestChapterData(catalogModel) else { return }
|
||||||
|
await MainActor.run {
|
||||||
|
self.vc?.reloadData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else { //没有章节数据,先获取章节数据
|
} else { //没有章节数据,先获取章节数据
|
||||||
Task {
|
Task {
|
||||||
guard let _ = await self.requestChapterData(catalogModel) else { return }
|
guard let _ = await self.requestChapterData(catalogModel) else { return }
|
||||||
@ -155,19 +163,35 @@ extension NRNovelReadViewModel {
|
|||||||
model.episode = catalogModel.episode
|
model.episode = catalogModel.episode
|
||||||
model.page = pageModel.page?.intValue
|
model.page = pageModel.page?.intValue
|
||||||
NRKeyedArchiver.archiver(folderName: kNRReadRecordFolderName, fileName: novelId, object: model)
|
NRKeyedArchiver.archiver(folderName: kNRReadRecordFolderName, fileName: novelId, object: model)
|
||||||
|
|
||||||
|
let lastTime = uploadRecordDate?.timeIntervalSince1970 ?? 0
|
||||||
|
let nowTime = Date().timeIntervalSince1970
|
||||||
|
|
||||||
|
if lastTime == 0 || nowTime - lastTime > 5 {//间隔5秒才能上传一次记录
|
||||||
|
uploadRecordDate = Date()
|
||||||
NRNovelAPI.requestUploadRecord(novelId, chapterId: catalogModel.id ?? "")
|
NRNovelAPI.requestUploadRecord(novelId, chapterId: catalogModel.id ?? "")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///获取阅读记录
|
///获取阅读记录
|
||||||
func getReadRecord() -> NRNovelReadRecordModel? {
|
func getReadRecord() -> NRNovelReadRecordModel? {
|
||||||
guard novelId.count > 0 else { return nil }
|
guard novelId.count > 0 else { return nil }
|
||||||
var recordModel = NRKeyedArchiver.unarchiver(folderName: kNRReadRecordFolderName, fileName: novelId) as? NRNovelReadRecordModel
|
var recordModel = NRKeyedArchiver.unarchiver(folderName: kNRReadRecordFolderName, fileName: novelId, as: NRNovelReadRecordModel.self)
|
||||||
//匹配本地记录与网络记录
|
//匹配本地记录与网络记录
|
||||||
if self.novelModel?.progress?.short_play_video_id != "0", self.novelModel?.progress?.short_play_video_id != recordModel?.short_play_video_id {
|
if self.novelModel?.progress?.short_play_video_id != "0", self.novelModel?.progress?.short_play_video_id != recordModel?.short_play_video_id {
|
||||||
recordModel = self.novelModel?.progress
|
recordModel = self.novelModel?.progress
|
||||||
}
|
}
|
||||||
return recordModel
|
return recordModel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///设置空白页数据
|
||||||
|
func setEmptyData() {
|
||||||
|
for model in self.chapterCatalogList {
|
||||||
|
if model.chapterModel == nil {
|
||||||
|
model.parserEmpty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: 网络请求
|
//MARK: 网络请求
|
||||||
@ -186,7 +210,7 @@ extension NRNovelReadViewModel {
|
|||||||
guard let list = await NRNovelAPI.requestChapterCatalogList(id: self.novelId) else { return }
|
guard let list = await NRNovelAPI.requestChapterCatalogList(id: self.novelId) else { return }
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
self.chapterCatalogList = list
|
self.chapterCatalogList = list
|
||||||
self.addUnlockPageData()
|
self.setEmptyData()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
///获取章节数据
|
///获取章节数据
|
||||||
@ -194,15 +218,12 @@ extension NRNovelReadViewModel {
|
|||||||
func requestChapterData(_ catalogModel: NRReadChapterCatalogModel) async -> NRReadChapterModel? {
|
func requestChapterData(_ catalogModel: NRReadChapterCatalogModel) async -> NRReadChapterModel? {
|
||||||
guard let chapterId = catalogModel.id else { return nil }
|
guard let chapterId = catalogModel.id else { return nil }
|
||||||
|
|
||||||
let myCoins = NRLoginManager.manager.userInfo?.totalCoins ?? 0
|
let (model, code) = await NRNovelAPI.requestChapterData(novelId: self.novelId, chapterId: chapterId)
|
||||||
let lockCoins = catalogModel.coins ?? 0
|
Task {//开个新的线程更新下用户信息
|
||||||
|
await NRLoginManager.manager.updateUserInfo()
|
||||||
//金币不够解锁
|
|
||||||
if catalogModel.is_lock == true, myCoins < lockCoins {
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (model, code) = await NRNovelAPI.requestChapterData(novelId: self.novelId, chapterId: chapterId)
|
if code == 200 {
|
||||||
guard let model = model else { return nil }
|
guard let model = model else { return nil }
|
||||||
|
|
||||||
model.parser()
|
model.parser()
|
||||||
@ -215,11 +236,13 @@ extension NRNovelReadViewModel {
|
|||||||
|
|
||||||
if catalogModel.is_lock == true {
|
if catalogModel.is_lock == true {
|
||||||
catalogModel.is_lock = false
|
catalogModel.is_lock = false
|
||||||
self.addUnlockPageData()
|
|
||||||
}
|
}
|
||||||
return model
|
return model
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
///预加载上下两页数据
|
///预加载上下两页数据
|
||||||
func preloadChapterData() {
|
func preloadChapterData() {
|
||||||
Task {
|
Task {
|
||||||
@ -249,16 +272,6 @@ extension NRNovelReadViewModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///给目录列表中增加未解锁页面数据
|
|
||||||
func addUnlockPageData() {
|
|
||||||
for model in self.chapterCatalogList {
|
|
||||||
if model.is_lock == true {
|
|
||||||
let chapterModel = NRReadChapterModel()
|
|
||||||
chapterModel.parserEmpty()
|
|
||||||
model.chapterModel = chapterModel
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -44,6 +44,9 @@ class NRNovelReadViewModel: NSObject {
|
|||||||
return tap
|
return tap
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
///用来记录上报历史记录的时间
|
||||||
|
var uploadRecordDate: Date?
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
import IQKeyboardManagerSwift
|
import IQKeyboardManagerSwift
|
||||||
import IQKeyboardToolbarManager
|
import IQKeyboardToolbarManager
|
||||||
|
import MJRefresh
|
||||||
|
|
||||||
|
|
||||||
extension AppDelegate {
|
extension AppDelegate {
|
||||||
@ -19,6 +20,8 @@ extension AppDelegate {
|
|||||||
IQKeyboardManager.shared.resignOnTouchOutside = true
|
IQKeyboardManager.shared.resignOnTouchOutside = true
|
||||||
IQKeyboardToolbarManager.shared.isEnabled = false
|
IQKeyboardToolbarManager.shared.isEnabled = false
|
||||||
|
|
||||||
|
MJRefreshConfig.default.languageCode = NRLocalizedManager.shared.mjLocalizedKey
|
||||||
|
|
||||||
let appearance = UINavigationBar.defaultAppearance()
|
let appearance = UINavigationBar.defaultAppearance()
|
||||||
UINavigationBar.appearance().scrollEdgeAppearance = appearance
|
UINavigationBar.appearance().scrollEdgeAppearance = appearance
|
||||||
UINavigationBar.appearance().standardAppearance = appearance
|
UINavigationBar.appearance().standardAppearance = appearance
|
||||||
|
|||||||
@ -17,21 +17,34 @@ class NRKeyedArchiver: NSObject {
|
|||||||
class func archiver(folderName:String, fileName:String, object:AnyObject) {
|
class func archiver(folderName:String, fileName:String, object:AnyObject) {
|
||||||
|
|
||||||
var path = documentDirectoryPath + "/\(mineFolderName)/\(folderName)"
|
var path = documentDirectoryPath + "/\(mineFolderName)/\(folderName)"
|
||||||
|
guard creat_file(path: path) else { return } // 创建文件夹成功或者文件夹存在
|
||||||
if creat_file(path: path) { // 创建文件夹成功或者文件夹存在
|
|
||||||
|
|
||||||
path += "/\(fileName)"
|
path += "/\(fileName)"
|
||||||
|
let url = URL(fileURLWithPath: path)
|
||||||
NSKeyedArchiver.archiveRootObject(object, toFile: path)
|
do {
|
||||||
|
let data = try NSKeyedArchiver.archivedData(withRootObject: object, requiringSecureCoding: true)
|
||||||
|
try data.write(to: url, options: .atomic)
|
||||||
|
} catch let error {
|
||||||
|
nrPrint(message: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 解档文件
|
/// 解档文件
|
||||||
class func unarchiver(folderName:String, fileName:String) ->AnyObject? {
|
class func unarchiver<T: NSObject & NSSecureCoding>(folderName:String, fileName:String, as type: T.Type) -> T? {
|
||||||
|
|
||||||
let path = documentDirectoryPath + "/\(mineFolderName)/\(folderName)/\(fileName)"
|
let path = documentDirectoryPath + "/\(mineFolderName)/\(folderName)/\(fileName)"
|
||||||
|
|
||||||
return NSKeyedUnarchiver.unarchiveObject(withFile: path) as AnyObject?
|
let url = URL(fileURLWithPath: path)
|
||||||
|
|
||||||
|
do {
|
||||||
|
let data = try Data(contentsOf: url)
|
||||||
|
let result = try NSKeyedUnarchiver.unarchivedObject(ofClass: type, from: data)
|
||||||
|
return result
|
||||||
|
|
||||||
|
} catch let error {
|
||||||
|
nrPrint(message: error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 删除归档文件
|
/// 删除归档文件
|
||||||
|
|||||||
@ -23,7 +23,7 @@ class NRLoginManager: NSObject {
|
|||||||
func updateUserInfo() async {
|
func updateUserInfo() async {
|
||||||
guard let userInfo = await NRUserAPI.requestUserInfo() else { return }
|
guard let userInfo = await NRUserAPI.requestUserInfo() else { return }
|
||||||
self.userInfo = userInfo
|
self.userInfo = userInfo
|
||||||
UserDefaults.nr_setObject(token, forKey: kNRUserInfoDefaultsKey)
|
UserDefaults.nr_setObject(userInfo, forKey: kNRUserInfoDefaultsKey)
|
||||||
|
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil)
|
NotificationCenter.default.post(name: NRLoginManager.userInfoUpdateNotification, object: nil)
|
||||||
|
|||||||
@ -82,7 +82,7 @@
|
|||||||
"Bonus" = "Bonus";
|
"Bonus" = "Bonus";
|
||||||
"Top Up" = "Top Up";
|
"Top Up" = "Top Up";
|
||||||
"Language" = "Language";
|
"Language" = "Language";
|
||||||
|
"Loading" = "Loading";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user