feat: 实现大书远距目录跳转与后台补全优化方案
Phase 1: 稳定性优先 - 新增 RDEPUBJumpSession 保护机制,防止远距跳转后翻页串章 - 升级页图接管条件,增加 JumpSession 保护区检查 - 窗口扩展改为基于当前权威窗口方向 Phase 2: 补全优先级重排 - 新增 RDEPUBBackgroundPriorityPolicy 策略配置 - 实现 hot/warm/cold zone 优先级排序 - 添加失败重试机制(指数退避,最多3次) Phase 3: 分段覆盖与最终收敛 - 新增 RDEPUBBackgroundCoverageStore 分段存储 - 新增 RDEPUBPageMapReconciliationCoordinator 页图接管仲裁 - 实现 LRU 淘汰和内存警告处理 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
e976ceebd5
commit
c64460988a
@@ -10,6 +10,9 @@ import Foundation
|
||||
final class RDEPUBReaderLocationCoordinator {
|
||||
private unowned let context: RDEPUBReaderContext
|
||||
|
||||
/// 上次翻页时的 spineIndex,用于检测跨章翻页
|
||||
private var lastPageChangeSpineIndex: Int?
|
||||
|
||||
init(context: RDEPUBReaderContext) {
|
||||
self.context = context
|
||||
}
|
||||
@@ -23,6 +26,9 @@ final class RDEPUBReaderLocationCoordinator {
|
||||
) -> Bool {
|
||||
guard let controller = context.controller,
|
||||
let readerView = context.readerView else { return false }
|
||||
if context.bookPageMap != nil {
|
||||
_ = context.runtime?.ensureOnDemandNavigationTargetAvailable(for: location)
|
||||
}
|
||||
guard let targetPageNumber = controller.pageNumber(for: location) else {
|
||||
readerView.transitionToPage(pageNum: 0)
|
||||
context.readingSession?.transition(to: .idle)
|
||||
@@ -50,6 +56,10 @@ final class RDEPUBReaderLocationCoordinator {
|
||||
context.readingSession?.transition(to: .jumping)
|
||||
}
|
||||
readerView.transitionToPage(pageNum: max(targetPageNumber - 1, 0), animated: animated)
|
||||
|
||||
// 记录翻页到 JumpSession
|
||||
recordPageChangeIfNeeded()
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -95,4 +105,40 @@ final class RDEPUBReaderLocationCoordinator {
|
||||
controller.delegate?.epubReader(controller, didUpdateCurrentTableOfContentsItem: controller.currentTableOfContentsItem)
|
||||
controller.updateReaderChrome()
|
||||
}
|
||||
|
||||
/// 记录翻页到 JumpSession
|
||||
func recordPageChangeIfNeeded() {
|
||||
guard let runtime = context.runtime,
|
||||
let bookPageMap = context.bookPageMap,
|
||||
let readerView = context.readerView else { return }
|
||||
|
||||
let currentPageNumber = readerView.currentPage + 1
|
||||
guard let currentSpineIndex = bookPageMap.spineIndex(forAbsolutePage: currentPageNumber - 1) else {
|
||||
return
|
||||
}
|
||||
|
||||
if let lastSpineIndex = lastPageChangeSpineIndex,
|
||||
lastSpineIndex != currentSpineIndex {
|
||||
runtime.jumpSessionManager.recordPageChange(
|
||||
fromSpineIndex: lastSpineIndex,
|
||||
toSpineIndex: currentSpineIndex
|
||||
)
|
||||
}
|
||||
|
||||
lastPageChangeSpineIndex = currentSpineIndex
|
||||
|
||||
// 检查是否应该结束 JumpSession
|
||||
let isIdle = context.secondsSinceLastUserNavigation() > 2.0
|
||||
if let endReason = runtime.jumpSessionManager.checkSessionEnd(
|
||||
currentSpineIndex: currentSpineIndex,
|
||||
isIdle: isIdle
|
||||
) {
|
||||
runtime.jumpSessionManager.endSession(endReason)
|
||||
}
|
||||
}
|
||||
|
||||
/// 重置翻页状态(用于重新加载等场景)
|
||||
func resetPageChangeState() {
|
||||
lastPageChangeSpineIndex = nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user