This commit is contained in:
Horis 2023-12-27 09:58:07 +08:00
parent e895223638
commit cf40a32e3a
11 changed files with 102 additions and 25 deletions

View File

@ -1,5 +1,6 @@
package io.legado.app.constant
@Suppress("ConstPropertyName")
object IntentAction {
const val start = "start"
const val play = "play"

View File

@ -3,6 +3,7 @@ package io.legado.app.constant
/**
* 通知ID不能重复,统一规划通知ID
*/
@Suppress("ConstPropertyName")
object NotificationId {
const val ReadAloudService = 101

View File

@ -1,12 +1,22 @@
package io.legado.app.data.entities
import android.os.Parcelable
import androidx.room.*
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.Ignore
import androidx.room.Index
import androidx.room.PrimaryKey
import androidx.room.TypeConverter
import androidx.room.TypeConverters
import io.legado.app.constant.AppPattern
import io.legado.app.constant.BookType
import io.legado.app.constant.PageAnim
import io.legado.app.data.appDb
import io.legado.app.help.book.*
import io.legado.app.help.book.BookHelp
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.config.AppConfig
import io.legado.app.help.config.ReadBookConfig
import io.legado.app.model.ReadBook
@ -144,6 +154,10 @@ data class Book(
@IgnoredOnParcel
private var folderName: String? = null
@get:Ignore
@IgnoredOnParcel
val lastChapterIndex get() = totalChapterNum - 1
fun getRealAuthor() = author.replace(AppPattern.authorRegex, "")
fun getUnreadChapterNum() = max(totalChapterNum - durChapterIndex - 1, 0)

View File

@ -103,30 +103,34 @@ class CacheBookService : BaseService() {
execute {
val cacheBook = CacheBook.getOrCreate(bookUrl) ?: return@execute
val chapterCount = appDb.bookChapterDao.getChapterCount(bookUrl)
val book = cacheBook.book
if (chapterCount == 0) {
val name = cacheBook.book.name
if (cacheBook.book.tocUrl.isEmpty()) {
val name = book.name
if (book.tocUrl.isEmpty()) {
kotlin.runCatching {
WebBook.getBookInfoAwait(cacheBook.bookSource, cacheBook.book)
WebBook.getBookInfoAwait(cacheBook.bookSource, book)
}.onFailure {
val msg = "$name》目录为空且加载详情页失败\n${it.localizedMessage}"
AppLog.put(msg, it, true)
return@execute
}
}
WebBook.getChapterListAwait(cacheBook.bookSource, cacheBook.book).onFailure {
cacheBook.book.totalChapterNum = 0
WebBook.getChapterListAwait(cacheBook.bookSource, book).onFailure {
if (book.totalChapterNum > 0) {
book.totalChapterNum = 0
book.save()
}
AppLog.put("$name》目录为空且加载目录失败\n${it.localizedMessage}", it, true)
return@execute
}.getOrNull()?.let { toc ->
appDb.bookChapterDao.insert(*toc.toTypedArray())
}
cacheBook.book.save()
book.save()
}
val end2 = if (end == 0) {
appDb.bookChapterDao.getChapterCount(bookUrl)
val end2 = if (end < 0) {
book.lastChapterIndex
} else {
end
min(end, book.lastChapterIndex)
}
cacheBook.addDownload(start, end2)
notificationContent = CacheBook.downloadSummary

View File

@ -29,8 +29,10 @@ 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.getExportFileName
import io.legado.app.help.book.isLocal
import io.legado.app.help.config.AppConfig
import io.legado.app.help.coroutine.OrderCoroutine
import io.legado.app.model.localBook.LocalBook
import io.legado.app.ui.book.cache.CacheActivity
import io.legado.app.utils.DocumentUtils
import io.legado.app.utils.FileUtils
@ -177,6 +179,7 @@ class ExportBookService : BaseService() {
val book = appDb.bookDao.getBook(bookUrl)
try {
book ?: throw NoStackTraceException("获取${bookUrl}书籍出错")
refreshChapterList(book)
notificationContentText = getString(
R.string.export_book_notification_content,
book.name,
@ -207,6 +210,22 @@ class ExportBookService : BaseService() {
}
}
private fun refreshChapterList(book: Book) {
if (!book.isLocal) {
return
}
if (LocalBook.getLastModified(book).getOrDefault(0L) < book.latestChapterTime) {
return
}
kotlin.runCatching {
LocalBook.getChapterList(book)
}.onSuccess {
book.latestChapterTime = System.currentTimeMillis()
appDb.bookChapterDao.delByBook(book.bookUrl)
appDb.bookChapterDao.insert(*it.toTypedArray())
}
}
private data class SrcData(
val chapterTitle: String,
val index: Int,

View File

@ -34,13 +34,27 @@ import io.legado.app.model.CacheBook
import io.legado.app.service.ExportBookService
import io.legado.app.ui.about.AppLogDialog
import io.legado.app.ui.file.HandleFileContract
import io.legado.app.utils.*
import io.legado.app.utils.ACache
import io.legado.app.utils.FileDoc
import io.legado.app.utils.applyTint
import io.legado.app.utils.checkWrite
import io.legado.app.utils.cnCompare
import io.legado.app.utils.enableCustomExport
import io.legado.app.utils.isContentScheme
import io.legado.app.utils.observeEvent
import io.legado.app.utils.parseToUri
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.startService
import io.legado.app.utils.toastOnUi
import io.legado.app.utils.verificationField
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.conflate
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.math.max
/**
* cache/download 缓存界面
@ -146,7 +160,7 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
this@CacheActivity,
book,
book.durChapterIndex,
book.totalChapterNum
book.lastChapterIndex
)
}
} else {
@ -198,6 +212,10 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
}
3 -> booksDownload.sortedBy { it.order }
4 -> booksDownload.sortedByDescending {
max(it.latestChapterTime, it.durChapterTime)
}
else -> booksDownload.sortedByDescending { it.durChapterTime }
}
}.conflate().collect { books ->

View File

@ -71,10 +71,10 @@ class CacheAdapter(context: Context, private val callBack: CallBack) :
if (!it.isStop()) {
CacheBook.remove(context, book.bookUrl)
} else {
CacheBook.start(context, book, 0, book.totalChapterNum)
CacheBook.start(context, book, 0, book.lastChapterIndex)
}
} ?: let {
CacheBook.start(context, book, 0, book.totalChapterNum)
CacheBook.start(context, book, 0, book.lastChapterIndex)
}
}
}

View File

@ -10,13 +10,6 @@ import io.legado.app.help.book.isLocal
import io.legado.app.help.coroutine.Coroutine
import io.legado.app.utils.sendValue
import kotlinx.coroutines.ensureActive
import kotlin.collections.HashSet
import kotlin.collections.List
import kotlin.collections.contains
import kotlin.collections.forEach
import kotlin.collections.hashMapOf
import kotlin.collections.hashSetOf
import kotlin.collections.isNotEmpty
import kotlin.collections.set
@ -34,7 +27,9 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
val chapterCaches = hashSetOf<String>()
val cacheNames = BookHelp.getChapterFiles(book)
if (cacheNames.isNotEmpty()) {
appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter ->
appDb.bookChapterDao.getChapterList(book.bookUrl).also {
book.totalChapterNum = it.size
}.forEach { chapter ->
if (cacheNames.contains(chapter.getFileName()) || chapter.isVolume) {
chapterCaches.add(chapter.url)
}

View File

@ -39,7 +39,15 @@ import io.legado.app.ui.widget.dialog.WaitDialog
import io.legado.app.ui.widget.recycler.DragSelectTouchHelper
import io.legado.app.ui.widget.recycler.ItemTouchCallback
import io.legado.app.ui.widget.recycler.VerticalDivider
import io.legado.app.utils.*
import io.legado.app.utils.applyTint
import io.legado.app.utils.cnCompare
import io.legado.app.utils.dpToPx
import io.legado.app.utils.hideSoftInput
import io.legado.app.utils.isAbsUrl
import io.legado.app.utils.sendToClip
import io.legado.app.utils.setEdgeEffectColor
import io.legado.app.utils.showDialogFragment
import io.legado.app.utils.startActivity
import io.legado.app.utils.viewbindingdelegate.viewBinding
import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Job
@ -308,6 +316,7 @@ class BookshelfManageActivity :
R.id.menu_add_to_group -> selectGroup(addToGroupRequestCode, 0)
R.id.menu_change_source -> showDialogFragment<SourcePickerDialog>()
R.id.menu_clear_cache -> viewModel.clearCache(adapter.selection)
R.id.menu_check_selected_interval -> adapter.checkSelectedInterval()
}
return false

View File

@ -2,12 +2,14 @@ package io.legado.app.ui.book.manage
import android.app.Application
import androidx.lifecycle.MutableLiveData
import io.legado.app.R
import io.legado.app.base.BaseViewModel
import io.legado.app.constant.AppLog
import io.legado.app.constant.BookType
import io.legado.app.data.appDb
import io.legado.app.data.entities.Book
import io.legado.app.data.entities.BookSource
import io.legado.app.help.book.BookHelp
import io.legado.app.help.book.isLocal
import io.legado.app.help.book.removeType
import io.legado.app.help.config.AppConfig
@ -108,4 +110,14 @@ class BookshelfManageViewModel(application: Application) : BaseViewModel(applica
}
}
fun clearCache(books: List<Book>) {
execute {
books.forEach {
BookHelp.clearCache(it)
}
}.onSuccess {
context.toastOnUi(R.string.clear_cache_success)
}
}
}

View File

@ -21,6 +21,10 @@
android:id="@+id/menu_change_source"
android:title="@string/change_source_batch" />
<item
android:id="@+id/menu_clear_cache"
android:title="@string/clear_cache" />
<item
android:id="@+id/menu_check_selected_interval"
android:title="@string/check_selected_interval" />