mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-15 13:37:29 +01:00
Implement a download cache
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.library
|
||||
|
||||
import android.os.Bundle
|
||||
import com.hippo.unifile.UniFile
|
||||
import com.jakewharton.rxrelay.BehaviorRelay
|
||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
@@ -107,12 +106,6 @@ class LibraryPresenter(
|
||||
* @param map the map to filter.
|
||||
*/
|
||||
private fun applyFilters(map: LibraryMap): LibraryMap {
|
||||
// Cached list of downloaded manga directories given a source id.
|
||||
val mangaDirsForSource = mutableMapOf<Long, Map<String?, UniFile>>()
|
||||
|
||||
// Cached list of downloaded chapter directories for a manga.
|
||||
val chapterDirectories = mutableMapOf<Long, Boolean>()
|
||||
|
||||
val filterDownloaded = preferences.filterDownloaded().getOrDefault()
|
||||
|
||||
val filterUnread = preferences.filterUnread().getOrDefault()
|
||||
@@ -121,7 +114,7 @@ class LibraryPresenter(
|
||||
|
||||
val filterFn: (LibraryItem) -> Boolean = f@ { item ->
|
||||
// Filter out manga without source.
|
||||
val source = sourceManager.get(item.manga.source) ?: return@f false
|
||||
sourceManager.get(item.manga.source) ?: return@f false
|
||||
|
||||
// Filter when there isn't unread chapters.
|
||||
if (filterUnread && item.manga.unread == 0) {
|
||||
@@ -132,28 +125,14 @@ class LibraryPresenter(
|
||||
return@f false
|
||||
}
|
||||
|
||||
// Filter when the download directory doesn't exist or is null.
|
||||
// Filter when there are no downloads.
|
||||
if (filterDownloaded) {
|
||||
// Don't bother with directory checking if download count has been set.
|
||||
if (item.downloadCount != -1) {
|
||||
return@f item.downloadCount > 0
|
||||
}
|
||||
|
||||
// Get the directories for the source of the manga.
|
||||
val dirsForSource = mangaDirsForSource.getOrPut(source.id) {
|
||||
val sourceDir = downloadManager.findSourceDir(source)
|
||||
sourceDir?.listFiles()?.associateBy { it.name }.orEmpty()
|
||||
}
|
||||
|
||||
val mangaDirName = downloadManager.getMangaDirName(item.manga)
|
||||
val mangaDir = dirsForSource[mangaDirName] ?: return@f false
|
||||
|
||||
val hasDirs = chapterDirectories.getOrPut(item.manga.id!!) {
|
||||
mangaDir.listFiles()?.isNotEmpty() ?: false
|
||||
}
|
||||
if (!hasDirs) {
|
||||
return@f false
|
||||
}
|
||||
return@f downloadManager.getDownloadCount(item.manga) > 0
|
||||
}
|
||||
true
|
||||
}
|
||||
@@ -177,31 +156,9 @@ class LibraryPresenter(
|
||||
return
|
||||
}
|
||||
|
||||
// Cached list of downloaded manga directories given a source id.
|
||||
val mangaDirsForSource = mutableMapOf<Long, Map<String?, UniFile>>()
|
||||
|
||||
// Cached list of downloaded chapter directories for a manga.
|
||||
val chapterDirectories = mutableMapOf<Long, Int>()
|
||||
|
||||
val downloadCountFn: (LibraryItem) -> Int = f@ { item ->
|
||||
val source = sourceManager.get(item.manga.source) ?: return@f 0
|
||||
|
||||
// Get the directories for the source of the manga.
|
||||
val dirsForSource = mangaDirsForSource.getOrPut(source.id) {
|
||||
val sourceDir = downloadManager.findSourceDir(source)
|
||||
sourceDir?.listFiles()?.associateBy { it.name }.orEmpty()
|
||||
}
|
||||
val mangaDirName = downloadManager.getMangaDirName(item.manga)
|
||||
val mangaDir = dirsForSource[mangaDirName] ?: return@f 0
|
||||
|
||||
chapterDirectories.getOrPut(item.manga.id!!) {
|
||||
mangaDir.listFiles()?.size ?: 0
|
||||
}
|
||||
}
|
||||
|
||||
for ((_, itemList) in map) {
|
||||
for (item in itemList) {
|
||||
item.downloadCount = downloadCountFn(item)
|
||||
item.downloadCount = downloadManager.getDownloadCount(item.manga)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -360,7 +317,7 @@ class LibraryPresenter(
|
||||
if (deleteChapters) {
|
||||
val source = sourceManager.get(manga.source) as? HttpSource
|
||||
if (source != null) {
|
||||
downloadManager.findMangaDir(source, manga)?.delete()
|
||||
downloadManager.deleteManga(manga, source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,13 +128,11 @@ class ChaptersPresenter(
|
||||
* @param chapters the list of chapter from the database.
|
||||
*/
|
||||
private fun setDownloadedChapters(chapters: List<ChapterItem>) {
|
||||
val files = downloadManager.findMangaDir(source, manga)?.listFiles() ?: return
|
||||
val cached = mutableMapOf<Chapter, String>()
|
||||
files.mapNotNull { it.name }
|
||||
.mapNotNull { name -> chapters.find {
|
||||
name == cached.getOrPut(it) { downloadManager.getChapterDirName(it) }
|
||||
} }
|
||||
.forEach { it.status = Download.DOWNLOADED }
|
||||
for (chapter in chapters) {
|
||||
if (downloadManager.isChapterDownloaded(chapter, manga)) {
|
||||
chapter.status = Download.DOWNLOADED
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -283,7 +281,7 @@ class ChaptersPresenter(
|
||||
*/
|
||||
private fun deleteChapter(chapter: ChapterItem) {
|
||||
downloadManager.queue.remove(chapter)
|
||||
downloadManager.deleteChapter(source, manga, chapter)
|
||||
downloadManager.deleteChapter(chapter, manga, source)
|
||||
chapter.status = Download.NOT_DOWNLOADED
|
||||
chapter.download = null
|
||||
}
|
||||
|
||||
@@ -115,14 +115,14 @@ class MangaInfoPresenter(
|
||||
* Returns true if the manga has any downloads.
|
||||
*/
|
||||
fun hasDownloads(): Boolean {
|
||||
return downloadManager.findMangaDir(source, manga) != null
|
||||
return downloadManager.getDownloadCount(manga) > 0
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all the downloads for the manga.
|
||||
*/
|
||||
fun deleteDownloads() {
|
||||
downloadManager.findMangaDir(source, manga)?.delete()
|
||||
downloadManager.deleteManga(manga, source)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -79,7 +79,7 @@ class ChapterLoader(
|
||||
private fun retrievePageList(chapter: ReaderChapter) = Observable.just(chapter)
|
||||
.flatMap {
|
||||
// Check if the chapter is downloaded.
|
||||
chapter.isDownloaded = downloadManager.findChapterDir(source, manga, chapter) != null
|
||||
chapter.isDownloaded = downloadManager.isChapterDownloaded(chapter, manga, true)
|
||||
|
||||
if (chapter.isDownloaded) {
|
||||
// Fetch the page list from disk.
|
||||
|
||||
@@ -411,7 +411,7 @@ class ReaderPresenter(
|
||||
fun deleteChapter(chapter: ReaderChapter, manga: Manga) {
|
||||
chapter.isDownloaded = false
|
||||
chapter.pages?.forEach { it.status == Page.QUEUE }
|
||||
downloadManager.deleteChapter(source, manga, chapter)
|
||||
downloadManager.deleteChapter(chapter, manga, source)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package eu.kanade.tachiyomi.ui.recent_updates
|
||||
|
||||
import android.os.Bundle
|
||||
import com.hippo.unifile.UniFile
|
||||
import eu.kanade.tachiyomi.data.database.DatabaseHelper
|
||||
import eu.kanade.tachiyomi.data.database.models.MangaChapter
|
||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||
@@ -114,36 +113,11 @@ class RecentChaptersPresenter(
|
||||
* @param items the list of chapter from the database.
|
||||
*/
|
||||
private fun setDownloadedChapters(items: List<RecentChapterItem>) {
|
||||
// Cached list of downloaded manga directories. Directory name is also cached because
|
||||
// it's slow when using SAF.
|
||||
val mangaDirsForSource = mutableMapOf<Long, Map<String?, UniFile>>()
|
||||
|
||||
// Cached list of downloaded chapter directories for a manga.
|
||||
val chapterDirsForManga = mutableMapOf<Long, Map<String?, UniFile>>()
|
||||
|
||||
for (item in items) {
|
||||
val manga = item.manga
|
||||
val chapter = item.chapter
|
||||
val source = sourceManager.get(manga.source) ?: continue
|
||||
|
||||
// Get the directories for the source of the manga.
|
||||
val dirsForSource = mangaDirsForSource.getOrPut(source.id) {
|
||||
val sourceDir = downloadManager.findSourceDir(source)
|
||||
sourceDir?.listFiles()?.associateBy { it.name }.orEmpty()
|
||||
}
|
||||
|
||||
// Get the manga directory in the source or continue.
|
||||
val mangaDirName = downloadManager.getMangaDirName(manga)
|
||||
val mangaDir = dirsForSource[mangaDirName] ?: continue
|
||||
|
||||
// Get the directories for the manga.
|
||||
val chapterDirs = chapterDirsForManga.getOrPut(manga.id!!) {
|
||||
mangaDir.listFiles()?.associateBy { it.name }.orEmpty()
|
||||
}
|
||||
|
||||
// Assign the download if the directory exists.
|
||||
val chapterDirName = downloadManager.getChapterDirName(chapter)
|
||||
if (chapterDirName in chapterDirs) {
|
||||
if (downloadManager.isChapterDownloaded(chapter, manga)) {
|
||||
item.status = Download.DOWNLOADED
|
||||
}
|
||||
}
|
||||
@@ -216,7 +190,7 @@ class RecentChaptersPresenter(
|
||||
private fun deleteChapter(item: RecentChapterItem) {
|
||||
val source = sourceManager.get(item.manga.source) ?: return
|
||||
downloadManager.queue.remove(item.chapter)
|
||||
downloadManager.deleteChapter(source, item.manga, item.chapter)
|
||||
downloadManager.deleteChapter(item.chapter, item.manga, source)
|
||||
item.status = Download.NOT_DOWNLOADED
|
||||
item.download = null
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user