diff --git a/app/src/main/java/io/legado/app/data/dao/BookDao.kt b/app/src/main/java/io/legado/app/data/dao/BookDao.kt index 082bfba0a..ddf016ce5 100644 --- a/app/src/main/java/io/legado/app/data/dao/BookDao.kt +++ b/app/src/main/java/io/legado/app/data/dao/BookDao.kt @@ -80,6 +80,9 @@ interface BookDao { @get:Query("SELECT * FROM books") val all: List + @Query("SELECT * FROM books where type & :type > 0 and type & ${BookType.local} = 0") + fun getByTypeOnLine(type: Int): List + @get:Query("SELECT * FROM books where type & ${BookType.text} > 0 ORDER BY durChapterTime DESC limit 1") val lastReadBook: Book? diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt index e6e4fa925..22a900ed7 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt @@ -11,14 +11,11 @@ import io.legado.app.base.VMBaseActivity import io.legado.app.constant.AppConst import io.legado.app.constant.AppConst.charsets import io.legado.app.constant.EventBus -import io.legado.app.constant.PreferKey import io.legado.app.data.appDb -import io.legado.app.data.entities.Book import io.legado.app.data.entities.BookChapter import io.legado.app.data.entities.BookGroup import io.legado.app.databinding.ActivityCacheBookBinding import io.legado.app.databinding.DialogEditTextBinding -import io.legado.app.help.book.BookHelp import io.legado.app.help.book.isAudio import io.legado.app.help.config.AppConfig import io.legado.app.lib.dialogs.SelectItem @@ -32,8 +29,7 @@ import io.legado.app.utils.viewbindingdelegate.viewBinding import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.conflate -import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.* import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -76,6 +72,7 @@ class CacheActivity : VMBaseActivity() initRecyclerView() initGroupData() initBookData() + initCacheData() } override fun onCompatCreateOptionsMenu(menu: Menu): Boolean { @@ -178,7 +175,6 @@ class CacheActivity : VMBaseActivity() } }.conflate().collect { books -> adapter.setItems(books) - initCacheSize(books) } } } @@ -195,17 +191,10 @@ class CacheActivity : VMBaseActivity() } } - private fun initCacheSize(books: List) { - launch(IO) { - books.forEach { book -> - val chapterCaches = hashSetOf() - val cacheNames = BookHelp.getChapterFiles(book) - appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter -> - if (cacheNames.contains(chapter.getFileName())) { - chapterCaches.add(chapter.url) - } - } - adapter.cacheChapters[book.bookUrl] = chapterCaches + private fun initCacheData() { + launch { + viewModel.bookCacheFlow.conflate().collect { + viewModel.cacheChapters[it.first] = it.second withContext(Dispatchers.Main) { adapter.notifyItemRangeChanged(0, adapter.itemCount, true) } @@ -242,7 +231,7 @@ class CacheActivity : VMBaseActivity() } } observeEvent(EventBus.SAVE_CONTENT) { - adapter.cacheChapters[it.bookUrl]?.add(it.url) + viewModel.cacheChapters[it.bookUrl]?.add(it.url) } } @@ -341,6 +330,9 @@ class CacheActivity : VMBaseActivity() } } + override val cacheChapters: HashMap> + get() = viewModel.cacheChapters + override fun exportProgress(bookUrl: String): Int? { return viewModel.exportProgress[bookUrl] } diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt index 02bdf756e..320f1af2f 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt @@ -18,7 +18,7 @@ import io.legado.app.utils.visible class CacheAdapter(context: Context, private val callBack: CallBack) : RecyclerAdapter(context) { - val cacheChapters = hashMapOf>() + override fun getViewBinding(parent: ViewGroup): ItemDownloadBinding { return ItemDownloadBinding.inflate(inflater, parent, false) @@ -37,7 +37,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : if (item.isLocal) { tvDownload.setText(R.string.local_book) } else { - val cs = cacheChapters[item.bookUrl] + val cs = callBack.cacheChapters[item.bookUrl] if (cs == null) { tvDownload.setText(R.string.loading) } else { @@ -53,7 +53,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : if (item.isLocal) { tvDownload.setText(R.string.local_book) } else { - val cacheSize = cacheChapters[item.bookUrl]?.size ?: 0 + val cacheSize = callBack.cacheChapters[item.bookUrl]?.size ?: 0 tvDownload.text = context.getString(R.string.download_count, cacheSize, item.totalChapterNum) } @@ -121,6 +121,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) : } interface CallBack { + val cacheChapters: HashMap> fun export(position: Int) fun exportProgress(bookUrl: String): Int? fun exportMsg(bookUrl: String): String? diff --git a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt index be3e45da9..2a2390086 100644 --- a/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt +++ b/app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt @@ -14,6 +14,7 @@ import io.legado.app.R import io.legado.app.base.BaseViewModel import io.legado.app.constant.AppConst import io.legado.app.constant.AppPattern +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.BookChapter @@ -24,8 +25,11 @@ import io.legado.app.help.book.ContentProcessor import io.legado.app.help.config.AppConfig import io.legado.app.help.coroutine.OrderCoroutine import io.legado.app.utils.* +import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.ensureActive +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import me.ag2s.epublib.domain.* @@ -46,6 +50,23 @@ class CacheViewModel(application: Application) : BaseViewModel(application) { val exportMsg = ConcurrentHashMap() private val mutex = Mutex() + val cacheChapters = hashMapOf>() + + val bookCacheFlow = flow { + //直接获取全部缓存信息,避免切换分组重新获取 + val books = appDb.bookDao.getByTypeOnLine(BookType.text or BookType.image) + books.forEach { book -> + val chapterCaches = hashSetOf() + val cacheNames = BookHelp.getChapterFiles(book) + appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter -> + if (cacheNames.contains(chapter.getFileName())) { + chapterCaches.add(chapter.url) + } + } + emit(Pair(book.bookUrl, chapterCaches)) + } + }.flowOn(Dispatchers.IO) + @Volatile private var exportNumber = 0