pull/2459/head
kunfei 3 years ago
parent e43435aa21
commit e6fdcfa3e5
  1. 8
      app/src/main/java/io/legado/app/help/book/BookHelp.kt
  2. 37
      app/src/main/java/io/legado/app/ui/book/cache/CacheActivity.kt
  3. 4
      app/src/main/java/io/legado/app/ui/book/cache/CacheAdapter.kt
  4. 89
      app/src/main/java/io/legado/app/ui/book/cache/CacheViewModel.kt
  5. 4
      app/src/main/java/io/legado/app/ui/book/searchContent/SearchContentActivity.kt
  6. 4
      app/src/main/java/io/legado/app/ui/book/toc/ChapterListFragment.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())

@ -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)
}
}
}
}
}

@ -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)
}

@ -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())
}
}
}

@ -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)
}

@ -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)

Loading…
Cancel
Save