diff --git a/app/build.gradle b/app/build.gradle index 528c0bccf..d69a4cef4 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -101,7 +101,7 @@ dependencies { implementation 'io.insert-koin:koin-android:3.1.2' implementation 'io.coil-kt:coil-base:1.3.2' implementation 'com.davemorrissey.labs:subsampling-scale-image-view-androidx:3.10.0' - implementation 'com.github.solkin:disk-lru-cache:1.2' + implementation 'com.github.solkin:disk-lru-cache:1.3' debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7' diff --git a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/AnimatedToolbar.kt b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/AnimatedToolbar.kt index 53aecf620..f17b31f84 100644 --- a/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/AnimatedToolbar.kt +++ b/app/src/main/java/org/koitharu/kotatsu/base/ui/widgets/AnimatedToolbar.kt @@ -6,17 +6,36 @@ import android.util.AttributeSet import android.view.View import androidx.appcompat.widget.Toolbar import androidx.core.view.isGone +import com.google.android.material.R import com.google.android.material.appbar.MaterialToolbar +import java.lang.reflect.Field -class AnimatedToolbar(context: Context, attrs: AttributeSet?) : MaterialToolbar(context, attrs) { - companion object { - private val navButtonViewField = Toolbar::class.java.getDeclaredField("mNavButtonView") - .also { it.isAccessible = true } - } +class AnimatedToolbar @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = R.attr.toolbarStyle, +) : MaterialToolbar(context, attrs, defStyleAttr) { + + private var navButtonView: View? = null + get() { + if (field == null) { + runCatching { + field = navButtonViewField?.get(this) as? View + } + } + return field + } override fun setNavigationIcon(icon: Drawable?) { super.setNavigationIcon(icon) + navButtonView?.isGone = (icon == null) + } + + private companion object { - (navButtonViewField.get(this) as? View)?.isGone = (icon == null) + val navButtonViewField: Field? = runCatching { + Toolbar::class.java.getDeclaredField("mNavButtonView") + .also { it.isAccessible = true } + }.getOrNull() } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt index 4033584d0..aaad60566 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/HenChanRepository.kt @@ -8,7 +8,7 @@ import org.koitharu.kotatsu.utils.ext.parseHtml class HenChanRepository(loaderContext: MangaLoaderContext) : ChanRepository(loaderContext) { - override val defaultDomain = "hentaichan.pro" + override val defaultDomain = "hentaichan.live" override val source = MangaSource.HENCHAN override suspend fun getList( diff --git a/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadManager.kt b/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadManager.kt index cc81f7895..75905aa51 100644 --- a/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadManager.kt +++ b/app/src/main/java/org/koitharu/kotatsu/download/domain/DownloadManager.kt @@ -8,7 +8,6 @@ import coil.ImageLoader import coil.request.ImageRequest import coil.size.Scale import kotlinx.coroutines.* -import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.flow import okhttp3.OkHttpClient @@ -48,7 +47,7 @@ class DownloadManager( androidx.core.R.dimen.compat_notification_large_icon_max_height ) - fun downloadManga(manga: Manga, chaptersIds: Set?, startId: Int): Flow = flow { + fun downloadManga(manga: Manga, chaptersIds: Set?, startId: Int) = flow { emit(State.Preparing(startId, manga, null)) var cover: Drawable? = null val destination = settings.getStorageDir(context) diff --git a/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFetcher.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFetcher.kt index f74c023e1..cd4f5ea83 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFetcher.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFetcher.kt @@ -20,19 +20,22 @@ class CbzFetcher : Fetcher { pool: BitmapPool, data: Uri, size: Size, - options: Options + options: Options, ): FetchResult { val zip = ZipFile(data.schemeSpecificPart) val entry = zip.getEntry(data.fragment) val ext = MimeTypeMap.getFileExtensionFromUrl(entry.name) return SourceResult( - source = zip.getInputStream(entry).source().buffer(), + source = ExtraCloseableBufferedSource( + zip.getInputStream(entry).source().buffer(), + zip, + ), mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext), dataSource = DataSource.DISK ) } - override fun key(data: Uri): String? = data.toString() + override fun key(data: Uri) = data.toString() override fun handles(data: Uri) = data.scheme == "cbz" } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFilter.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFilter.kt index 98f4e73fc..106cbaacd 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFilter.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/CbzFilter.kt @@ -7,7 +7,7 @@ import java.util.* class CbzFilter : FilenameFilter { override fun accept(dir: File, name: String): Boolean { - val ext = name.substringAfterLast('.', "").toLowerCase(Locale.ROOT) + val ext = name.substringAfterLast('.', "").lowercase(Locale.ROOT) return ext == "cbz" || ext == "zip" } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/local/data/ExtraCloseableBufferedSource.kt b/app/src/main/java/org/koitharu/kotatsu/local/data/ExtraCloseableBufferedSource.kt new file mode 100644 index 000000000..69ba2565a --- /dev/null +++ b/app/src/main/java/org/koitharu/kotatsu/local/data/ExtraCloseableBufferedSource.kt @@ -0,0 +1,18 @@ +package org.koitharu.kotatsu.local.data + +import okhttp3.internal.closeQuietly +import okio.BufferedSource +import okio.Closeable + +class ExtraCloseableBufferedSource( + private val delegate: BufferedSource, + vararg closeable: Closeable, +) : BufferedSource by delegate { + + private val extraCloseable = closeable + + override fun close() { + delegate.close() + extraCloseable.forEach { x -> x.closeQuietly() } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt index baaab7400..383c295bc 100644 --- a/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/local/domain/LocalMangaRepository.kt @@ -15,10 +15,7 @@ import org.koitharu.kotatsu.local.data.CbzFilter import org.koitharu.kotatsu.local.data.MangaIndex import org.koitharu.kotatsu.local.data.MangaZip import org.koitharu.kotatsu.utils.AlphanumComparator -import org.koitharu.kotatsu.utils.ext.longHashCode -import org.koitharu.kotatsu.utils.ext.readText -import org.koitharu.kotatsu.utils.ext.sub -import org.koitharu.kotatsu.utils.ext.toCamelCase +import org.koitharu.kotatsu.utils.ext.* import java.io.File import java.util.* import java.util.zip.ZipEntry @@ -78,9 +75,9 @@ class LocalMangaRepository(private val context: Context) : MangaRepository { } } - fun delete(manga: Manga): Boolean { + suspend fun delete(manga: Manga): Boolean { val file = Uri.parse(manga.url).toFile() - return file.delete() + return file.deleteAwait() } @SuppressLint("DefaultLocale") diff --git a/build.gradle b/build.gradle index de81afc1e..cd35015e3 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { classpath 'com.android.tools.build:gradle:4.2.2' - classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.21' + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.30' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files