kunfei 4 лет назад
Родитель
Сommit
d6d67121ca

+ 4 - 4
app/src/main/java/io/legado/app/help/book/BookHelp.kt

@@ -87,7 +87,7 @@ object BookHelp {
     ) {
         saveText(book, bookChapter, content)
         saveImages(bookSource, book, bookChapter, content)
-        postEvent(EventBus.SAVE_CONTENT, bookChapter)
+        postEvent(EventBus.SAVE_CONTENT, Pair(book, bookChapter))
     }
 
     fun saveText(
@@ -198,11 +198,11 @@ object BookHelp {
         return ZipFile(uri.path)
     }
 
-    fun getChapterFiles(book: Book): Set<String> {
+    fun getChapterFiles(book: Book): HashSet<String> {
+        val fileNames = hashSetOf<String>()
         if (book.isLocalTxt) {
-            return emptySet()
+            return fileNames
         }
-        val fileNames = hashSetOf<String>()
         FileUtils.createFolderIfNotExist(
             downloadDir,
             subDirs = arrayOf(cacheFolderName, book.getFolderName())

+ 29 - 8
app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt

@@ -12,6 +12,7 @@ import io.legado.app.constant.AppConst
 import io.legado.app.constant.AppConst.charsets
 import io.legado.app.constant.EventBus
 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
@@ -26,6 +27,7 @@ import io.legado.app.ui.about.AppLogDialog
 import io.legado.app.ui.document.HandleFileContract
 import io.legado.app.utils.*
 import io.legado.app.utils.viewbindingdelegate.viewBinding
+import kotlinx.coroutines.Dispatchers.Default
 import kotlinx.coroutines.Dispatchers.IO
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.flow.*
@@ -191,9 +193,24 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
 
     override fun observeLiveBus() {
         viewModel.upAdapterLiveData.observe(this) {
-            adapter.getItems().forEachIndexed { index, book ->
-                if (book.bookUrl == it) {
-                    adapter.notifyItemChanged(index, true)
+            launch(Default) {
+                adapter.getItems().forEachIndexed { index, book ->
+                    if (book.bookUrl == it) {
+                        binding.recyclerView.post {
+                            adapter.notifyItemChanged(index, true)
+                        }
+                    }
+                }
+            }
+        }
+        viewModel.cacheLiveData.observe(this) {
+            launch(Default) {
+                adapter.getItems().forEachIndexed { index, book ->
+                    if (book.getFolderName() == it) {
+                        binding.recyclerView.post {
+                            adapter.notifyItemChanged(index, true)
+                        }
+                    }
                 }
             }
         }
@@ -217,11 +234,15 @@ class CacheActivity : VMBaseActivity<ActivityCacheBookBinding, CacheViewModel>()
                 }
             }
         }
-        observeEvent<BookChapter>(EventBus.SAVE_CONTENT) {
-            viewModel.cacheChapters[it.bookUrl]?.add(it.url)
-            adapter.getItems().forEachIndexed { index, book ->
-                if (book.bookUrl == it.bookUrl) {
-                    adapter.notifyItemChanged(index, true)
+        observeEvent<Pair<Book, BookChapter>>(EventBus.SAVE_CONTENT) { (book, chapter) ->
+            viewModel.cacheChapters[book.bookUrl]?.add(chapter.url)
+            launch(Default) {
+                adapter.getItems().forEachIndexed { index, item ->
+                    if (book.bookUrl == item.bookUrl) {
+                        binding.recyclerView.post {
+                            adapter.notifyItemChanged(index, true)
+                        }
+                    }
                 }
             }
         }

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt

@@ -37,7 +37,7 @@ class CacheAdapter(context: Context, private val callBack: CallBack) :
                 if (item.isLocal) {
                     tvDownload.setText(R.string.local_book)
                 } else {
-                    val cs = callBack.cacheChapters[item.bookUrl]
+                    val cs = callBack.cacheChapters[item.getFolderName()]
                     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 = callBack.cacheChapters[item.bookUrl]?.size ?: 0
+                    val cacheSize = callBack.cacheChapters[item.getFolderName()]?.size ?: 0
                     tvDownload.text =
                         context.getString(R.string.download_count, cacheSize, item.totalChapterNum)
                 }

+ 44 - 45
app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt

@@ -4,6 +4,7 @@ import android.app.Application
 import android.graphics.Bitmap
 import android.graphics.drawable.Drawable
 import android.net.Uri
+import android.os.Build
 import androidx.documentfile.provider.DocumentFile
 import androidx.lifecycle.MutableLiveData
 import com.bumptech.glide.Glide
@@ -25,8 +26,7 @@ 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.delay
-import kotlinx.coroutines.ensureActive
+import kotlinx.coroutines.*
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 import me.ag2s.epublib.domain.*
@@ -37,15 +37,19 @@ import splitties.init.appCtx
 import java.io.ByteArrayOutputStream
 import java.io.File
 import java.io.FileOutputStream
+import java.io.IOException
 import java.nio.charset.Charset
 import java.nio.file.*
+import java.nio.file.attribute.BasicFileAttributes
 import java.util.*
 import java.util.concurrent.ConcurrentHashMap
 import kotlin.coroutines.coroutineContext
+import kotlin.io.path.name
 
 
 class CacheViewModel(application: Application) : BaseViewModel(application) {
     val upAdapterLiveData = MutableLiveData<String>()
+    val cacheLiveData = MutableLiveData<String>()
     val exportProgress = ConcurrentHashMap<String, Int>()
     val exportMsg = ConcurrentHashMap<String, String>()
     private val mutex = Mutex()
@@ -61,52 +65,47 @@ class CacheViewModel(application: Application) : BaseViewModel(application) {
     private fun loadCacheFiles() {
         execute {
             //直接获取全部缓存信息,避免切换分组重新获取
-//            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-//                val visitor = object : SimpleFileVisitor<Path>() {
-//
-//                    var names: HashSet<String>? = null
-//
-//                    override fun preVisitDirectory(
-//                        dir: Path,
-//                        attrs: BasicFileAttributes?
-//                    ): FileVisitResult {
-//                        if (dir.name != "book_cache") {
-//                            names = hashSetOf()
-//                        }
-//                        return FileVisitResult.CONTINUE
-//                    }
-//
-//                    override fun visitFile(
-//                        file: Path,
-//                        attrs: BasicFileAttributes?
-//                    ): FileVisitResult {
-//                        names!!.add(file.name)
-//                        return FileVisitResult.CONTINUE
-//                    }
-//
-//                    override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult {
-//                        if (dir.name != "book_cache") {
-//                            cacheChapters[dir.name] = names!!
-//                        }
-//                        return FileVisitResult.CONTINUE
-//                    }
-//                }
-//                withContext(Dispatchers.IO) {
-//                    Files.walkFileTree(Paths.get(BookHelp.cachePath), emptySet(), 2, visitor)
-//                }
-//                return@execute
-//            }
             val books = appDb.bookDao.getByTypeOnLine(BookType.text or BookType.image)
-            books.forEach { book ->
-                val chapterCaches = hashSetOf<String>()
-                val cacheNames = BookHelp.getChapterFiles(book)
-                appDb.bookChapterDao.getChapterList(book.bookUrl).forEach { chapter ->
-                    if (cacheNames.contains(chapter.getFileName())) {
-                        chapterCaches.add(chapter.url)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+                val visitor = object : SimpleFileVisitor<Path>() {
+
+                    var names: HashSet<String>? = null
+
+                    override fun preVisitDirectory(
+                        dir: Path,
+                        attrs: BasicFileAttributes?
+                    ): FileVisitResult {
+                        if (dir.name != "book_cache") {
+                            names = hashSetOf()
+                        }
+                        return FileVisitResult.CONTINUE
+                    }
+
+                    override fun visitFile(
+                        file: Path,
+                        attrs: BasicFileAttributes?
+                    ): FileVisitResult {
+                        names!!.add(file.name)
+                        return FileVisitResult.CONTINUE
+                    }
+
+                    override fun postVisitDirectory(dir: Path, exc: IOException?): FileVisitResult {
+                        if (dir.name != "book_cache") {
+                            cacheChapters[dir.name] = names!!
+                            cacheLiveData.postValue(dir.name)
+                        }
+                        return FileVisitResult.CONTINUE
                     }
                 }
-                cacheChapters[book.bookUrl] = chapterCaches
-                upAdapterLiveData.postValue(book.bookUrl)
+                withContext(Dispatchers.IO) {
+                    Files.walkFileTree(Paths.get(BookHelp.cachePath), emptySet(), 2, visitor)
+                }
+                return@execute
+            }
+            books.forEach { book ->
+                val cacheNames = BookHelp.getChapterFiles(book)
+                cacheChapters[book.getFolderName()] = cacheNames
+                cacheLiveData.postValue(book.getFolderName())
             }
         }
     }

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt

@@ -132,9 +132,9 @@ class SearchContentActivity :
     }
 
     override fun observeLiveBus() {
-        observeEvent<BookChapter>(EventBus.SAVE_CONTENT) { chapter ->
+        observeEvent<Pair<Book, BookChapter>>(EventBus.SAVE_CONTENT) { (book, chapter) ->
             viewModel.book?.bookUrl?.let { bookUrl ->
-                if (chapter.bookUrl == bookUrl) {
+                if (book.bookUrl == bookUrl) {
                     viewModel.cacheChapterNames.add(chapter.getFileName())
                     adapter.notifyItemChanged(chapter.index, true)
                 }

+ 2 - 2
app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.kt

@@ -95,9 +95,9 @@ class ChapterListFragment : VMBaseFragment<TocViewModel>(R.layout.fragment_chapt
     }
 
     override fun observeLiveBus() {
-        observeEvent<BookChapter>(EventBus.SAVE_CONTENT) { chapter ->
+        observeEvent<Pair<Book, BookChapter>>(EventBus.SAVE_CONTENT) { (book, chapter) ->
             viewModel.bookData.value?.bookUrl?.let { bookUrl ->
-                if (chapter.bookUrl == bookUrl) {
+                if (book.bookUrl == bookUrl) {
                     adapter.cacheFileNames.add(chapter.getFileName())
                     if (viewModel.searchKey.isNullOrEmpty()) {
                         adapter.notifyItemChanged(chapter.index, true)