diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bee5bb1fa..a4582af3a 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -237,8 +237,7 @@ dependencies { implementation(libs.reorderable) implementation(platform(libs.arrow.stack)) - implementation(libs.arrow.fx.coroutines) - implementation(libs.arrow.resilience) + implementation(libs.bundles.arrow) // https://coil-kt.github.io/coil/changelog/ implementation(platform(libs.coil.bom)) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/EhDB.kt b/app/src/main/kotlin/com/hippo/ehviewer/EhDB.kt index 782d6eea4..46c036f9e 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/EhDB.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/EhDB.kt @@ -17,8 +17,8 @@ package com.hippo.ehviewer import android.content.Context import android.net.Uri -import arrow.fx.coroutines.release import arrow.fx.coroutines.resource +import arrow.fx.coroutines.resourceScope import com.hippo.ehviewer.client.data.BaseGalleryInfo import com.hippo.ehviewer.dao.DownloadArtist import com.hippo.ehviewer.dao.DownloadDirname @@ -279,52 +279,51 @@ object EhDB { dbFile.toOkioPath() sendTo file } - suspend fun importDB(context: Context, uri: Uri) { + suspend fun importDB(context: Context, uri: Uri) = resourceScope { val tempDBName = "tmp.db" - resource { + val oldDB = resource { context.deleteDatabase(tempDBName) roomDb(tempDBName) { createFromInputStream { context.contentResolver.openInputStream(uri) } addMigrations(Schema17to18()) } - } release { - it.close() + } release { db -> + db.close() context.deleteDatabase(tempDBName) - } use { oldDB -> - db.galleryDao().insertOrIgnore(oldDB.galleryDao().list()) + } - db.progressDao().insertOrIgnore(oldDB.progressDao().list()) + db.galleryDao().insertOrIgnore(oldDB.galleryDao().list()) + db.progressDao().insertOrIgnore(oldDB.progressDao().list()) - val downloadLabelList = oldDB.downloadLabelDao().list() - DownloadManager.addDownloadLabel(downloadLabelList) + val downloadLabelList = oldDB.downloadLabelDao().list() + DownloadManager.addDownloadLabel(downloadLabelList) - oldDB.downloadDirnameDao().list().let { - importDownloadDirname(it) - } + oldDB.downloadDirnameDao().list().let { + importDownloadDirname(it) + } - val downloadInfoList = oldDB.downloadsDao().joinList().asReversed() - DownloadManager.addDownload(downloadInfoList) + val downloadInfoList = oldDB.downloadsDao().joinList().asReversed() + DownloadManager.addDownload(downloadInfoList) - val historyInfoList = oldDB.historyDao().list() - importHistoryInfo(historyInfoList) + val historyInfoList = oldDB.historyDao().list() + importHistoryInfo(historyInfoList) - val quickSearchList = oldDB.quickSearchDao().list() - val currentQuickSearchList = db.quickSearchDao().list() - val offset = currentQuickSearchList.size - val importList = quickSearchList.filter { newQS -> - currentQuickSearchList.none { it.name == newQS.name } - }.onEachIndexed { index, q -> q.position = index + offset } - importQuickSearch(importList) + val quickSearchList = oldDB.quickSearchDao().list() + val currentQuickSearchList = db.quickSearchDao().list() + val offset = currentQuickSearchList.size + val importList = quickSearchList.filter { newQS -> + currentQuickSearchList.none { it.name == newQS.name } + }.onEachIndexed { index, q -> q.position = index + offset } + importQuickSearch(importList) - oldDB.localFavoritesDao().list().let { - importLocalFavorites(it) - } + oldDB.localFavoritesDao().list().let { + importLocalFavorites(it) + } - val filterList = oldDB.filterDao().list() - val currentFilterList = db.filterDao().list() - filterList.forEach { - if (it !in currentFilterList) addFilter(it) - } + val filterList = oldDB.filterDao().list() + val currentFilterList = db.filterDao().list() + filterList.forEach { + if (it !in currentFilterList) addFilter(it) } } } diff --git a/app/src/main/kotlin/com/hippo/ehviewer/gallery/ArchivePageLoader.kt b/app/src/main/kotlin/com/hippo/ehviewer/gallery/ArchivePageLoader.kt index 4e3255a9a..5b6d5ef82 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/gallery/ArchivePageLoader.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/gallery/ArchivePageLoader.kt @@ -32,6 +32,7 @@ import com.hippo.ehviewer.util.displayName import com.hippo.files.openFileDescriptor import eu.kanade.tachiyomi.util.system.logcat import kotlinx.coroutines.coroutineScope +import moe.tarsin.kt.install import okio.Path typealias PasswdInvalidator = (String) -> Boolean @@ -48,7 +49,7 @@ suspend fun useArchivePageLoader( ) = autoCloseScope { coroutineScope { val pfd = install(file.openFileDescriptor("r")) - val size = autoClose( + val size = install( { openArchive(pfd.fd, pfd.statSize, gid == 0L || file.name.endsWith(".zip")) }, { _, _ -> closeArchive() }, ) diff --git a/app/src/main/kotlin/com/hippo/ehviewer/gallery/EhPageLoader.kt b/app/src/main/kotlin/com/hippo/ehviewer/gallery/EhPageLoader.kt index 5b6ff7bc4..651f688ab 100644 --- a/app/src/main/kotlin/com/hippo/ehviewer/gallery/EhPageLoader.kt +++ b/app/src/main/kotlin/com/hippo/ehviewer/gallery/EhPageLoader.kt @@ -9,6 +9,7 @@ import com.hippo.ehviewer.spider.SpiderQueen.Companion.releaseSpiderQueen import com.hippo.ehviewer.spider.SpiderQueen.OnSpiderListener import com.hippo.ehviewer.util.hasAds import kotlinx.coroutines.coroutineScope +import moe.tarsin.kt.install import okio.Path suspend fun useEhPageLoader( @@ -17,7 +18,7 @@ suspend fun useEhPageLoader( block: suspend (PageLoader) -> T, ) = autoCloseScope { coroutineScope { - val queen = autoClose( + val queen = install( { obtainSpiderQueen(info, SpiderQueen.MODE_READ) }, { queen, _ -> releaseSpiderQueen(queen, SpiderQueen.MODE_READ) }, ) @@ -48,7 +49,7 @@ suspend fun useEhPageLoader( override fun onPageFailure(index: Int, error: String?, finished: Int, downloaded: Int, total: Int) = notifyPageFailed(index, error) } - autoClose( + install( { queen.addOnSpiderListener(listener) }, { _, _ -> queen.removeOnSpiderListener(listener) }, ) diff --git a/app/src/main/kotlin/moe/tarsin/kt/AutoClose.kt b/app/src/main/kotlin/moe/tarsin/kt/AutoClose.kt new file mode 100644 index 000000000..19ece04b8 --- /dev/null +++ b/app/src/main/kotlin/moe/tarsin/kt/AutoClose.kt @@ -0,0 +1,8 @@ +package moe.tarsin.kt + +import arrow.AutoCloseScope + +inline fun AutoCloseScope.install( + acquire: () -> A, + crossinline release: (A, Throwable?) -> Unit, +): A = acquire().also { a -> onClose { release(a, it) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index efeb76b83..3be4d1834 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -15,7 +15,7 @@ androidx-lifecycle = "2.9.0-alpha07" androidx-paging = "3.3.4" androidx-room = "2.7.0-alpha11" androidx-work = "2.10.0" -arrow = "1.2.4" +arrow = "2.0.0-beta.2" coil = "3.0.3" compose-bom = "2024.11.00" compose-destinations = "2.1.0-beta14" @@ -60,6 +60,7 @@ androidx-room-paging = { module = "androidx.room:room-paging", version.ref = "an androidx-work-runtime = { module = "androidx.work:work-runtime", version.ref = "androidx-work" } arrow-fx-coroutines = { module = "io.arrow-kt:arrow-fx-coroutines" } +arrow-functions = { module = "io.arrow-kt:arrow-functions" } arrow-resilience = { module = "io.arrow-kt:arrow-resilience" } arrow-stack = { module = "io.arrow-kt:arrow-stack", version.ref = "arrow" } @@ -122,6 +123,7 @@ androidx-benchmark-macro-junit4 = { module = "androidx.benchmark:benchmark-macro androidx-profileinstaller = { module = "androidx.profileinstaller:profileinstaller", version.ref = "profileinstaller" } [bundles] +arrow = ["arrow-fx-coroutines", "arrow-functions", "arrow-resilience"] coil = ["coil-compose", "coil-gif", "coil-network"] compose = ["compose-foundation", "compose-material-icons-extended", "compose-material3", "compose-material3-adaptive", "compose-ui-util"] kotlinx-serialization = ["serialization-cbor", "serialization-json", "serialization-json-okio", "serialization-xml"]