diff --git a/app/build.gradle b/app/build.gradle index 42dfa44297..f133845804 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -30,7 +30,7 @@ ext { android { compileSdkVersion 25 - buildToolsVersion "25.0.1" + buildToolsVersion "25.0.2" publishNonDefault true defaultConfig { @@ -48,7 +48,7 @@ android { vectorDrawables.useSupportLibrary = true ndk { - abiFilters "armeabi", "armeabi-v7a", "x86" + abiFilters "armeabi-v7a", "arm64-v8a", "x86" } } @@ -98,7 +98,7 @@ android { dependencies { // Modified dependencies - compile 'com.github.inorichi:subsampling-scale-image-view:41e76b5' + compile 'com.github.inorichi:subsampling-scale-image-view:8a22092' compile 'com.github.inorichi:junrar-android:634c1f5' // Android support library @@ -117,13 +117,13 @@ dependencies { // ReactiveX compile 'io.reactivex:rxandroid:1.2.1' - compile 'io.reactivex:rxjava:1.2.5' + compile 'io.reactivex:rxjava:1.2.6' compile 'com.jakewharton.rxrelay:rxrelay:1.2.0' compile 'com.f2prateek.rx.preferences:rx-preferences:1.0.2' compile 'com.github.pwittchen:reactivenetwork:0.7.0' // Network client - compile "com.squareup.okhttp3:okhttp:3.5.0" + compile "com.squareup.okhttp3:okhttp:3.6.0" compile 'com.squareup.okio:okio:1.11.0' // REST @@ -150,14 +150,14 @@ dependencies { compile 'org.jsoup:jsoup:1.10.2' // Job scheduling - compile 'com.evernote:android-job:1.1.4' + compile 'com.evernote:android-job:1.1.6' compile 'com.google.android.gms:play-services-gcm:10.0.1' // Changelog compile 'com.github.gabrielemariotti.changeloglib:changelog:2.1.0' // Database - compile "com.pushtorefresh.storio:sqlite:1.12.1" + compile "com.pushtorefresh.storio:sqlite:1.12.2" // Model View Presenter final nucleus_version = '3.0.0' @@ -175,7 +175,7 @@ dependencies { compile 'jp.wasabeef:glide-transformations:2.0.1' // Logging - compile 'com.jakewharton.timber:timber:4.5.0' + compile 'com.jakewharton.timber:timber:4.5.1' // Crash reports compile 'ch.acra:acra:4.9.2' @@ -190,8 +190,8 @@ dependencies { compile 'com.github.inorichi:FlexibleAdapter:93985fe' // v4.2.0 to be removed compile 'com.nononsenseapps:filepicker:2.5.2' compile 'com.github.amulyakhare:TextDrawable:558677e' - compile 'com.afollestad.material-dialogs:core:0.9.2.3' - compile 'net.xpece.android:support-preference:1.2.2' + compile 'com.afollestad.material-dialogs:core:0.9.3.0' + compile 'net.xpece.android:support-preference:1.2.5' compile 'me.zhanghai.android.systemuihelper:library:1.0.0' compile 'de.hdodenhof:circleimageview:2.1.0' diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/glide/FileFetcher.kt b/app/src/main/java/eu/kanade/tachiyomi/data/glide/FileFetcher.kt new file mode 100644 index 0000000000..6e1e06ff4a --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/glide/FileFetcher.kt @@ -0,0 +1,35 @@ +package eu.kanade.tachiyomi.data.glide + +import com.bumptech.glide.Priority +import com.bumptech.glide.load.data.DataFetcher +import java.io.File +import java.io.IOException +import java.io.InputStream + +open class FileFetcher(private val file: File) : DataFetcher { + + private var data: InputStream? = null + + override fun loadData(priority: Priority): InputStream { + data = file.inputStream() + return data!! + } + + override fun cleanup() { + data?.let { data -> + try { + data.close() + } catch (e: IOException) { + // Ignore + } + } + } + + override fun cancel() { + // Do nothing. + } + + override fun getId(): String { + return file.toString() + } +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaFileFetcher.kt b/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaFileFetcher.kt index cc309ab953..5e594e4969 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaFileFetcher.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaFileFetcher.kt @@ -1,29 +1,18 @@ package eu.kanade.tachiyomi.data.glide -import com.bumptech.glide.Priority -import com.bumptech.glide.load.data.DataFetcher import eu.kanade.tachiyomi.data.database.models.Manga import java.io.File -import java.io.InputStream -class MangaFileFetcher(private val fetcher: DataFetcher, - private val file: File, - private val manga: Manga) : DataFetcher { - - - override fun loadData(priority: Priority?): InputStream? { - return fetcher.loadData(priority) - } +open class MangaFileFetcher(private val file: File, private val manga: Manga) : FileFetcher(file) { + /** + * Returns the id for this manga's cover. + * + * Appending the file's modified date to the url, we can force Glide to skip its memory and disk + * lookup step and fetch from our custom cache. This allows us to invalidate Glide's cache when + * the file has changed. If the file doesn't exist it will append a 0. + */ override fun getId(): String { return manga.thumbnail_url + file.lastModified() } - - override fun cancel() { - fetcher.cancel() - } - - override fun cleanup() { - fetcher.cleanup() - } } \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaModelLoader.kt b/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaModelLoader.kt index 216019099e..f5342c451e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaModelLoader.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaModelLoader.kt @@ -44,12 +44,6 @@ class MangaModelLoader(context: Context) : StreamModelLoader { private val baseUrlLoader = Glide.buildModelLoader(GlideUrl::class.java, InputStream::class.java, context) - /** - * Base file loader. - */ - private val baseFileLoader = Glide.buildModelLoader(File::class.java, - InputStream::class.java, context) - /** * LRU cache whose key is the thumbnail url of the manga, and the value contains the request url * and the file where it should be stored in case the manga is a favorite. @@ -109,11 +103,8 @@ class MangaModelLoader(context: Context) : StreamModelLoader { // Get the file from the url, removing the scheme if present. val file = File(url.substringAfter("file://")) - // Get the resource fetcher for the given file. - val fileFetcher = baseFileLoader.getResourceFetcher(file, width, height) - // Return an instance of the fetcher providing the needed elements. - return MangaFileFetcher(fileFetcher, file, manga) + return MangaFileFetcher(file, manga) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaUrlFetcher.kt b/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaUrlFetcher.kt index 9893377d22..1933095835 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaUrlFetcher.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/glide/MangaUrlFetcher.kt @@ -21,10 +21,9 @@ import java.io.InputStream class MangaUrlFetcher(private val networkFetcher: DataFetcher, private val file: File, private val manga: Manga) -: DataFetcher { +: MangaFileFetcher(file, manga) { - @Throws(Exception::class) - override fun loadData(priority: Priority): InputStream? { + override fun loadData(priority: Priority): InputStream { if (manga.favorite) { synchronized(file) { if (!file.exists()) { @@ -51,7 +50,7 @@ class MangaUrlFetcher(private val networkFetcher: DataFetcher, } } } - return file.inputStream() + return super.loadData(priority) } else { if (file.exists()) { file.delete() @@ -60,22 +59,12 @@ class MangaUrlFetcher(private val networkFetcher: DataFetcher, } } - /** - * Returns the id for this manga's cover. - * - * Appending the file's modified date to the url, we can force Glide to skip its memory and disk - * lookup step and fetch from our custom cache. This allows us to invalidate Glide's cache when - * the file has changed. If the file doesn't exist it will append a 0. - */ - override fun getId(): String { - return manga.thumbnail_url + file.lastModified() - } - override fun cancel() { networkFetcher.cancel() } override fun cleanup() { + super.cleanup() networkFetcher.cleanup() } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt index 176c1f6cd3..b1990ef80f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/library/LibraryPresenter.kt @@ -127,7 +127,7 @@ class LibraryPresenter : BasePresenter() { */ private fun applyFilters(map: Map>): Map> { // Cached list of downloaded manga directories given a source id. - val mangaDirectories = mutableMapOf>() + val mangaDirsForSource = mutableMapOf>() // Cached list of downloaded chapter directories for a manga. val chapterDirectories = mutableMapOf() @@ -147,15 +147,17 @@ class LibraryPresenter : BasePresenter() { // Filter when the download directory doesn't exist or is null. if (filterDownloaded) { - val mangaDirs = mangaDirectories.getOrPut(source.id) { - downloadManager.findSourceDir(source)?.listFiles() ?: emptyArray() + // 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(manga) - val mangaDir = mangaDirs.find { it.name == mangaDirName } ?: return@f false + val mangaDir = dirsForSource[mangaDirName] ?: return@f false val hasDirs = chapterDirectories.getOrPut(manga.id!!) { - (mangaDir.listFiles() ?: emptyArray()).isNotEmpty() + mangaDir.listFiles()?.isNotEmpty() ?: false } if (!hasDirs) { return@f false