|
@@ -149,11 +149,6 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
|
|
|
LocalPageEstimateMetrics.record(metric)
|
|
LocalPageEstimateMetrics.record(metric)
|
|
|
AppLog.putDebug("PageEstimate $metric")
|
|
AppLog.putDebug("PageEstimate $metric")
|
|
|
},
|
|
},
|
|
|
- onStateChanged = {
|
|
|
|
|
- launch {
|
|
|
|
|
- callBack?.upContent(resetPageOffset = false)
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
)
|
|
)
|
|
|
//占位
|
|
//占位
|
|
|
private var currentReadLength: Long = 10L
|
|
private var currentReadLength: Long = 10L
|
|
@@ -228,7 +223,13 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
|
|
|
|
|
|
|
|
fun requestWholeBookPageEstimate() {
|
|
fun requestWholeBookPageEstimate() {
|
|
|
val book = book ?: return
|
|
val book = book ?: return
|
|
|
|
|
+ if (!FullBookPaginator.isNeeded()) {
|
|
|
|
|
+ FullBookPaginator.stop()
|
|
|
|
|
+ wholeBookPageCoordinator.clear()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
if (book.isImage || book.isPdf) {
|
|
if (book.isImage || book.isPdf) {
|
|
|
|
|
+ FullBookPaginator.stop()
|
|
|
wholeBookPageCoordinator.clear()
|
|
wholeBookPageCoordinator.clear()
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
@@ -276,7 +277,7 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
|
|
|
val showChapterTitle = ReadBookConfig.titleMode != 2
|
|
val showChapterTitle = ReadBookConfig.titleMode != 2
|
|
|
val wholeBookAverageChapterLength = book.wordCount.toContentLength()
|
|
val wholeBookAverageChapterLength = book.wordCount.toContentLength()
|
|
|
?.div(chapterSize.coerceAtLeast(1))
|
|
?.div(chapterSize.coerceAtLeast(1))
|
|
|
- wholeBookPageCoordinator.requestEstimate(
|
|
|
|
|
|
|
+ val layoutGeneration = wholeBookPageCoordinator.requestEstimate(
|
|
|
config = config,
|
|
config = config,
|
|
|
bookId = bookUrl,
|
|
bookId = bookUrl,
|
|
|
fallbackContentLength = wholeBookAverageChapterLength,
|
|
fallbackContentLength = wholeBookAverageChapterLength,
|
|
@@ -311,22 +312,35 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- FullBookPaginator.startIfNeeded()
|
|
|
|
|
|
|
+ FullBookPaginator.startIfNeeded(layoutGeneration)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ fun updateWholeBookPageDemand() {
|
|
|
|
|
+ if (!FullBookPaginator.isNeeded()) {
|
|
|
|
|
+ FullBookPaginator.stop()
|
|
|
|
|
+ wholeBookPageCoordinator.clear()
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ if (wholeBookPageCoordinator.hasEstimate()) {
|
|
|
|
|
+ FullBookPaginator.startIfNeeded(wholeBookPageCoordinator.generation)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ requestWholeBookPageEstimate()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
fun getWholeBookPageState(chapterIndex: Int, localPageIndex: Int): WholeBookPageState? =
|
|
fun getWholeBookPageState(chapterIndex: Int, localPageIndex: Int): WholeBookPageState? =
|
|
|
wholeBookPageCoordinator.getState(chapterIndex, localPageIndex)
|
|
wholeBookPageCoordinator.getState(chapterIndex, localPageIndex)
|
|
|
|
|
|
|
|
- /** Performs local-book precision pagination and feeds the existing whole-book coordinator. */
|
|
|
|
|
- suspend fun paginateLocalBookPages(onProgress: (completed: Int, total: Int) -> Unit) {
|
|
|
|
|
|
|
+ /** Silently paginates uncached local-book chapters and feeds the whole-book coordinator. */
|
|
|
|
|
+ suspend fun paginateLocalBookPages(layoutGeneration: Long) {
|
|
|
val book = book?.takeIf { it.isLocal && !it.isImage && !it.isPdf } ?: return
|
|
val book = book?.takeIf { it.isLocal && !it.isImage && !it.isPdf } ?: return
|
|
|
- val generation = wholeBookPageCoordinator.generation
|
|
|
|
|
|
|
+ if (!wholeBookPageCoordinator.awaitInitialized(layoutGeneration)) return
|
|
|
val chapters = withContext(IO) { appDb.bookChapterDao.getChapterList(book.bookUrl) }
|
|
val chapters = withContext(IO) { appDb.bookChapterDao.getChapterList(book.bookUrl) }
|
|
|
val processor = ContentProcessor.get(book)
|
|
val processor = ContentProcessor.get(book)
|
|
|
val useReplaceRule = book.getUseReplaceRule(AppConfig.replaceEnableDefault)
|
|
val useReplaceRule = book.getUseReplaceRule(AppConfig.replaceEnableDefault)
|
|
|
- for ((completed, chapter) in chapters.withIndex()) {
|
|
|
|
|
|
|
+ for (chapter in chapters) {
|
|
|
ensureActive()
|
|
ensureActive()
|
|
|
- onProgress(completed, chapters.size)
|
|
|
|
|
|
|
+ if (wholeBookPageCoordinator.isChapterExact(chapter.index, layoutGeneration)) continue
|
|
|
val content = withContext(IO) { BookHelp.getContent(book, chapter) } ?: continue
|
|
val content = withContext(IO) { BookHelp.getContent(book, chapter) } ?: continue
|
|
|
val displayTitle = chapter.getDisplayTitle(
|
|
val displayTitle = chapter.getDisplayTitle(
|
|
|
processor.getTitleReplaceRules(),
|
|
processor.getTitleReplaceRules(),
|
|
@@ -334,6 +348,19 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
|
|
|
chineseConverterType = AppConfig.chineseConverterType,
|
|
chineseConverterType = AppConfig.chineseConverterType,
|
|
|
)
|
|
)
|
|
|
val processed = processor.getContent(book, chapter, content, includeTitle = false)
|
|
val processed = processor.getContent(book, chapter, content, includeTitle = false)
|
|
|
|
|
+ wholeBookPageCoordinator.updateChapterContent(
|
|
|
|
|
+ chapterIndex = chapter.index,
|
|
|
|
|
+ actualLength = processed.textList
|
|
|
|
|
+ .sumOf { it.length.toLong() }
|
|
|
|
|
+ .coerceAtMost(Int.MAX_VALUE.toLong())
|
|
|
|
|
+ .toInt(),
|
|
|
|
|
+ contentHash = if (book.isLocalTxt) {
|
|
|
|
|
+ ChapterContentHasher.fromLocalOffsets(chapter.start, chapter.end)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ChapterContentHasher.fromContent(content)
|
|
|
|
|
+ },
|
|
|
|
|
+ layoutGeneration = layoutGeneration,
|
|
|
|
|
+ )
|
|
|
val textChapter = ChapterProvider.getTextChapterAsync(
|
|
val textChapter = ChapterProvider.getTextChapterAsync(
|
|
|
this, book, chapter, displayTitle, processed, chapters.size,
|
|
this, book, chapter, displayTitle, processed, chapters.size,
|
|
|
)
|
|
)
|
|
@@ -348,13 +375,12 @@ object ReadBook : CoroutineScope by MainScope(), KoinComponent {
|
|
|
wholeBookPageCoordinator.correctChapter(
|
|
wholeBookPageCoordinator.correctChapter(
|
|
|
chapterIndex = chapter.index,
|
|
chapterIndex = chapter.index,
|
|
|
realPageCount = pageCount.coerceAtLeast(1),
|
|
realPageCount = pageCount.coerceAtLeast(1),
|
|
|
- layoutGeneration = generation,
|
|
|
|
|
|
|
+ layoutGeneration = layoutGeneration,
|
|
|
)
|
|
)
|
|
|
} finally {
|
|
} finally {
|
|
|
textChapter.cancelLayout()
|
|
textChapter.cancelLayout()
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
- onProgress(chapters.size, chapters.size)
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
private fun String?.toContentLength(): Int? {
|
|
private fun String?.toContentLength(): Int? {
|