diff --git a/app/src/main/java/io/legado/app/data/dao/BookChapterDao.kt b/app/src/main/java/io/legado/app/data/dao/BookChapterDao.kt index 43ad9bd78..e5a47eb3d 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookChapterDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookChapterDao.kt @@ -13,6 +13,9 @@ interface BookChapterDao { @Query("SELECT * FROM chapters where bookUrl = :bookUrl and title like '%'||:key||'%' order by `index`") fun search(bookUrl: String, key: String): List + @Query("SELECT * FROM chapters where bookUrl = :bookUrl and `index` >= :start and `index` <= :end and title like '%'||:key||'%' order by `index`") + fun search(bookUrl: String, key: String, start: Int, end: Int): List + @Query("select * from chapters where bookUrl = :bookUrl order by `index`") fun getChapterList(bookUrl: String): List diff --git a/app/src/main/java/io/legado/app/data/entities/Book.kt b/app/src/main/java/io/legado/app/data/entities/Book.kt index 0be86a106..d1ede0c91 100644 --- a/app/src/main/java/io/legado/app/data/entities/Book.kt +++ b/app/src/main/java/io/legado/app/data/entities/Book.kt @@ -17,6 +17,7 @@ import io.legado.app.help.book.ContentProcessor import io.legado.app.help.book.isEpub import io.legado.app.help.book.isImage import io.legado.app.help.book.isPdf +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.model.ReadBook @@ -27,7 +28,6 @@ import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize import java.nio.charset.Charset import java.time.LocalDate -import java.time.Period.between import kotlin.math.max import kotlin.math.min @@ -160,18 +160,6 @@ data class Book( @IgnoredOnParcel val lastChapterIndex get() = totalChapterNum - 1 - // 根据当前日期计算章节总数 - fun simulatedTotalChapterNum(): Int { - if (config.readSimulating) { - val currentDate = LocalDate.now() - val daysPassed = between(this.config.startDate, currentDate).days + 1 - // 计算当前应该解锁到哪一章 - val chaptersToUnlock = - max(0, (config.startChapter ?: 0) + (daysPassed * config.dailyChapters)) - return min(this.totalChapterNum, chaptersToUnlock) - } else return this.totalChapterNum - } - fun getRealAuthor() = author.replace(AppPattern.authorRegex, "") fun getUnreadChapterNum() = max(simulatedTotalChapterNum() - durChapterIndex - 1, 0) diff --git a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt index 3925c04d7..c6b4efd25 100644 --- a/app/src/main/java/io/legado/app/help/book/BookExtensions.kt +++ b/app/src/main/java/io/legado/app/help/book/BookExtensions.kt @@ -23,8 +23,12 @@ import io.legado.app.utils.isUri import io.legado.app.utils.toastOnUi import splitties.init.appCtx import java.io.File +import java.time.LocalDate +import java.time.Period.between import java.util.concurrent.ConcurrentHashMap import kotlin.collections.set +import kotlin.math.max +import kotlin.math.min val Book.isAudio: Boolean @@ -296,6 +300,20 @@ fun Book.getExportFileName( }.getOrDefault(default) } +// 根据当前日期计算章节总数 +fun Book.simulatedTotalChapterNum(): Int { + return if (config.readSimulating) { + val currentDate = LocalDate.now() + val daysPassed = between(this.config.startDate, currentDate).days + 1 + // 计算当前应该解锁到哪一章 + val chaptersToUnlock = + max(0, (config.startChapter ?: 0) + (daysPassed * config.dailyChapters)) + min(totalChapterNum, chaptersToUnlock) + } else { + totalChapterNum + } +} + fun tryParesExportFileName(jsStr: String): Boolean { val bindings = SimpleBindings() bindings["name"] = "name" diff --git a/app/src/main/java/io/legado/app/model/AudioPlay.kt b/app/src/main/java/io/legado/app/model/AudioPlay.kt index 34067650c..19c035299 100644 --- a/app/src/main/java/io/legado/app/model/AudioPlay.kt +++ b/app/src/main/java/io/legado/app/model/AudioPlay.kt @@ -12,6 +12,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookSource import io.legado.app.help.book.ContentProcessor import io.legado.app.help.book.getBookSource +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.coroutine.Coroutine import io.legado.app.service.AudioPlayService import io.legado.app.utils.postEvent diff --git a/app/src/main/java/io/legado/app/model/ReadBook.kt b/app/src/main/java/io/legado/app/model/ReadBook.kt index 61719ee67..96b001937 100644 --- a/app/src/main/java/io/legado/app/model/ReadBook.kt +++ b/app/src/main/java/io/legado/app/model/ReadBook.kt @@ -12,6 +12,7 @@ import io.legado.app.help.AppWebDav import io.legado.app.help.book.BookHelp import io.legado.app.help.book.ContentProcessor import io.legado.app.help.book.isLocal +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.config.AppConfig import io.legado.app.help.config.ReadBookConfig import io.legado.app.help.coroutine.Coroutine @@ -47,6 +48,7 @@ object ReadBook : CoroutineScope by MainScope() { var inBookshelf = false var tocChanged = false var chapterSize = 0 + var simulatedChapterSize = 0 var durChapterIndex = 0 var durChapterPos = 0 var isLocalBook = true @@ -92,6 +94,11 @@ object ReadBook : CoroutineScope by MainScope() { readRecord.bookName = book.name readRecord.readTime = appDb.readRecordDao.getReadTime(book.name) ?: 0 chapterSize = appDb.bookChapterDao.getChapterCount(book.bookUrl) + simulatedChapterSize = if (book.config.readSimulating) { + book.simulatedTotalChapterNum() + } else { + chapterSize + } contentProcessor = ContentProcessor.get(book) durChapterIndex = book.durChapterIndex durChapterPos = book.durChapterPos @@ -112,6 +119,11 @@ object ReadBook : CoroutineScope by MainScope() { fun upData(book: Book) { ReadBook.book = book chapterSize = appDb.bookChapterDao.getChapterCount(book.bookUrl) + simulatedChapterSize = if (book.config.readSimulating) { + book.simulatedTotalChapterNum() + } else { + chapterSize + } if (durChapterIndex != book.durChapterIndex || tocChanged) { durChapterIndex = book.durChapterIndex durChapterPos = book.durChapterPos @@ -229,7 +241,7 @@ object ReadBook : CoroutineScope by MainScope() { } fun moveToNextChapter(upContent: Boolean, upContentInPlace: Boolean = true): Boolean { - if (durChapterIndex < (book?.simulatedTotalChapterNum()?: chapterSize) - 1) { + if (durChapterIndex < simulatedChapterSize - 1) { durChapterPos = 0 durChapterIndex++ prevTextChapter?.cancelLayout() @@ -544,7 +556,7 @@ object ReadBook : CoroutineScope by MainScope() { val contents = contentProcessor .getContent(book, chapter, content, includeTitle = false) val textChapter = ChapterProvider.getTextChapterAsync( - this@ReadBook, book, chapter, displayTitle, contents, chapterSize + this@ReadBook, book, chapter, displayTitle, contents, simulatedChapterSize ) when (val offset = chapter.index - durChapterIndex) { 0 -> { diff --git a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt index 37876cd7f..c0b75896a 100644 --- a/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt +++ b/app/src/main/java/io/legado/app/model/webBook/BookChapterList.kt @@ -11,6 +11,7 @@ import io.legado.app.data.entities.rule.TocRule import io.legado.app.exception.NoStackTraceException import io.legado.app.exception.TocEmptyException import io.legado.app.help.book.ContentProcessor +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.config.AppConfig import io.legado.app.model.Debug import io.legado.app.model.analyzeRule.AnalyzeRule diff --git a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt index 9172f8e60..d324afcf7 100644 --- a/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/audio/AudioPlayActivity.kt @@ -24,6 +24,7 @@ import io.legado.app.data.entities.BookSource import io.legado.app.databinding.ActivityAudioPlayBinding import io.legado.app.help.book.isAudio import io.legado.app.help.book.removeType +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.config.AppConfig import io.legado.app.lib.dialogs.alert import io.legado.app.model.AudioPlay diff --git a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt index db6abd93d..151288d83 100644 --- a/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/info/BookInfoViewModel.kt @@ -25,6 +25,7 @@ import io.legado.app.help.book.isLocal import io.legado.app.help.book.isSameNameAuthor import io.legado.app.help.book.isWebFile import io.legado.app.help.book.removeType +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.coroutine.Coroutine import io.legado.app.lib.webdav.ObjectNotFoundException import io.legado.app.model.BookCover @@ -251,7 +252,8 @@ class BookInfoViewModel(application: Application) : BaseViewModel(application) { appDb.bookChapterDao.insert(*it.toTypedArray()) if (book.isSameNameAuthor(ReadBook.book)) { ReadBook.book = book - ReadBook.chapterSize = book.simulatedTotalChapterNum() + ReadBook.chapterSize = book.totalChapterNum + ReadBook.simulatedChapterSize = book.simulatedTotalChapterNum() } } bookData.postValue(book) diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt index 40c21d682..b387d2c64 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadBookViewModel.kt @@ -22,6 +22,7 @@ import io.legado.app.help.book.ContentProcessor import io.legado.app.help.book.isLocal import io.legado.app.help.book.isLocalModified import io.legado.app.help.book.removeType +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.config.AppConfig import io.legado.app.help.coroutine.Coroutine import io.legado.app.model.ImageProvider @@ -116,8 +117,8 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { ReadBook.loadOrUpContent() checkLocalBookFileExist(book) } else { - if (ReadBook.durChapterIndex > ReadBook.chapterSize - 1) { - ReadBook.durChapterIndex = ReadBook.chapterSize - 1 + if (ReadBook.durChapterIndex > ReadBook.simulatedChapterSize - 1) { + ReadBook.durChapterIndex = ReadBook.simulatedChapterSize - 1 } ReadBook.loadContent(resetPageOffset = false) checkLocalBookFileExist(book) @@ -176,6 +177,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { appDb.bookChapterDao.insert(*it.toTypedArray()) appDb.bookDao.update(book) ReadBook.chapterSize = it.size + ReadBook.simulatedChapterSize = book.simulatedTotalChapterNum() ReadBook.upMsg(null) ReadBook.loadContent(resetPageOffset = true) } @@ -205,6 +207,7 @@ class ReadBookViewModel(application: Application) : BaseViewModel(application) { appDb.bookChapterDao.delByBook(oldBook.bookUrl) appDb.bookChapterDao.insert(*cList.toTypedArray()) ReadBook.chapterSize = cList.size + ReadBook.simulatedChapterSize = book.simulatedTotalChapterNum() ReadBook.upMsg(null) ReadBook.loadContent(resetPageOffset = true) }.onError { diff --git a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt index 960b84aaa..12b169066 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/ReadMenu.kt @@ -509,7 +509,7 @@ class ReadMenu @JvmOverloads constructor( } upSeekBar() binding.tvPre.isEnabled = ReadBook.durChapterIndex != 0 - binding.tvNext.isEnabled = ReadBook.durChapterIndex != ReadBook.chapterSize - 1 + binding.tvNext.isEnabled = ReadBook.durChapterIndex != ReadBook.simulatedChapterSize - 1 } ?: let { binding.tvChapterName.gone() binding.tvChapterUrl.gone() @@ -527,7 +527,7 @@ class ReadMenu @JvmOverloads constructor( } "chapter" -> { - max = ReadBook.chapterSize - 1 + max = ReadBook.simulatedChapterSize - 1 progress = ReadBook.durChapterIndex } } diff --git a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt index 55ff73577..2a09cda97 100644 --- a/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt +++ b/app/src/main/java/io/legado/app/ui/book/read/page/ReadView.kt @@ -708,8 +708,7 @@ class ReadView(context: Context, attrs: AttributeSet) : } override fun hasNextChapter(): Boolean { - return ReadBook.durChapterIndex < ((ReadBook.book?.simulatedTotalChapterNum() - ?: ReadBook.chapterSize) - 1) + return ReadBook.durChapterIndex < ReadBook.simulatedChapterSize - 1 } override fun hasPrevChapter(): Boolean { diff --git a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt index 7c3150f1a..460ae7132 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt @@ -17,6 +17,7 @@ import io.legado.app.data.entities.BookChapter import io.legado.app.databinding.FragmentChapterListBinding import io.legado.app.help.book.BookHelp import io.legado.app.help.book.isLocal +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.lib.theme.bottomBackground import io.legado.app.lib.theme.getPrimaryTextColor import io.legado.app.ui.widget.recycler.UpLinearLayoutManager @@ -81,7 +82,7 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragment_chapt upChapterList(null) durChapterIndex = book.durChapterIndex binding.tvCurrentChapterInfo.text = - "${book.durChapterTitle}(${book.durChapterIndex + 1}/${book.totalChapterNum})" + "${book.durChapterTitle}(${book.durChapterIndex + 1}/${book.simulatedTotalChapterNum()})" initCacheFileNames(book) } } @@ -117,12 +118,12 @@ class ChapterListFragment : VMBaseFragment(R.layout.fragment_chapt override fun upChapterList(searchKey: String?) { lifecycleScope.launch { withContext(IO) { + val end = (book?.simulatedTotalChapterNum() ?: Int.MAX_VALUE) - 1 when { - searchKey.isNullOrBlank() -> appDb.bookChapterDao.getChapterList( - viewModel.bookUrl - ).take(book?.simulatedTotalChapterNum() ?: Int.MAX_VALUE) + searchKey.isNullOrBlank() -> + appDb.bookChapterDao.getChapterList(viewModel.bookUrl, 0, end) - else -> appDb.bookChapterDao.search(viewModel.bookUrl, searchKey) + else -> appDb.bookChapterDao.search(viewModel.bookUrl, searchKey, 0, end) } }.let { adapter.setItems(it) diff --git a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt index d86771516..8b764cdeb 100644 --- a/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/toc/TocActivity.kt @@ -18,6 +18,7 @@ import io.legado.app.base.VMBaseActivity import io.legado.app.data.entities.Book import io.legado.app.databinding.ActivityChapterListBinding import io.legado.app.help.book.isLocalTxt +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.config.AppConfig import io.legado.app.lib.theme.accentColor import io.legado.app.lib.theme.primaryTextColor @@ -26,8 +27,12 @@ import io.legado.app.ui.about.AppLogDialog import io.legado.app.ui.book.toc.rule.TxtTocRuleDialog import io.legado.app.ui.file.HandleFileContract import io.legado.app.ui.widget.dialog.WaitDialog -import io.legado.app.utils.* +import io.legado.app.utils.applyTint +import io.legado.app.utils.gone +import io.legado.app.utils.hideSoftInput +import io.legado.app.utils.showDialogFragment import io.legado.app.utils.viewbindingdelegate.viewBinding +import io.legado.app.utils.visible /** * 目录 @@ -192,7 +197,8 @@ class TocActivity : VMBaseActivity(), ReadBook.book?.let { readBook -> if (readBook == book) { ReadBook.book = book - ReadBook.chapterSize = book.simulatedTotalChapterNum() + ReadBook.chapterSize = book.totalChapterNum + ReadBook.simulatedChapterSize = book.simulatedTotalChapterNum() ReadBook.upMsg(null) ReadBook.loadContent(resetPageOffset = true) } diff --git a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt index 6f9080a62..33a93e85d 100644 --- a/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/main/MainViewModel.kt @@ -19,6 +19,7 @@ import io.legado.app.help.book.isLocal import io.legado.app.help.book.isSameNameAuthor import io.legado.app.help.book.isUpError import io.legado.app.help.book.removeType +import io.legado.app.help.book.simulatedTotalChapterNum import io.legado.app.help.book.sync import io.legado.app.help.config.AppConfig import io.legado.app.model.CacheBook @@ -163,7 +164,8 @@ class MainViewModel(application: Application) : BaseViewModel(application) { appDb.bookChapterDao.insert(*toc.toTypedArray()) if (book.isSameNameAuthor(ReadBook.book)) { ReadBook.book = book - ReadBook.chapterSize = book.simulatedTotalChapterNum() + ReadBook.chapterSize = book.totalChapterNum + ReadBook.simulatedChapterSize = book.simulatedTotalChapterNum() } addDownload(source, book) }.onFailure {