This commit is contained in:
Horis
2024-07-10 16:20:41 +08:00
parent 63e34595f2
commit 74fb80a174
14 changed files with 67 additions and 30 deletions
@@ -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<BookChapter>
@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<BookChapter>
@Query("select * from chapters where bookUrl = :bookUrl order by `index`")
fun getChapterList(bookUrl: String): List<BookChapter>
@@ -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)
@@ -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"
@@ -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
@@ -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 -> {
@@ -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
@@ -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
@@ -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)
@@ -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 {
@@ -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
}
}
@@ -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 {
@@ -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<TocViewModel>(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<TocViewModel>(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)
@@ -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<ActivityChapterListBinding, TocViewModel>(),
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)
}
@@ -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 {