feat: allow canceling search for a migrating manga without remove it

so user can perform manual search without waiting
This commit is contained in:
Cuong-Tran 2024-08-08 18:34:03 +07:00 committed by Tran M. Cuong
parent 27ca4af744
commit 006d30ed36
5 changed files with 41 additions and 3 deletions

View file

@ -51,6 +51,9 @@ fun MigrationListScreen(
onMigrationItemClick: (Manga) -> Unit,
openMigrationDialog: (Boolean) -> Unit,
skipManga: (Long) -> Unit,
// KMK -->
cancelManga: (Long) -> Unit,
// KMK <--
searchManually: (MigratingManga) -> Unit,
migrateNow: (Long) -> Unit,
copyNow: (Long) -> Unit,
@ -138,6 +141,9 @@ fun MigrationListScreen(
.weight(0.2f),
result = result,
skipManga = { skipManga(migrationItem.manga.id) },
// KMK -->
cancelManga = { cancelManga(migrationItem.manga.id) },
// KMK <--
searchManually = { searchManually(migrationItem) },
migrateNow = {
migrateNow(migrationItem.manga.id)

View file

@ -27,6 +27,9 @@ fun MigrationActionIcon(
modifier: Modifier,
result: MigratingManga.SearchResult,
skipManga: () -> Unit,
// KMK -->
cancelManga: () -> Unit,
// KMK <--
searchManually: () -> Unit,
migrateNow: () -> Unit,
copyNow: () -> Unit,
@ -36,7 +39,9 @@ fun MigrationActionIcon(
Box(modifier) {
if (result is MigratingManga.SearchResult.Searching) {
IconButton(onClick = skipManga) {
// KMK -->
IconButton(onClick = cancelManga) {
// KMK <--
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = stringResource(SYMR.strings.action_stop),

View file

@ -2,6 +2,7 @@ package eu.kanade.tachiyomi.ui.browse.migration.advanced.process
import android.content.Context
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.flow.MutableStateFlow
@ -20,6 +21,10 @@ class MigratingManga(
) {
val migrationScope = CoroutineScope(parentContext + SupervisorJob() + Dispatchers.Default)
// KMK -->
lateinit var searchingJob: Deferred<Manga?>
// KMK <--
val searchResult = MutableStateFlow<SearchResult>(SearchResult.Searching)
// <MAX, PROGRESS>

View file

@ -106,6 +106,9 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
},
openMigrationDialog = screenModel::openMigrateDialog,
skipManga = { screenModel.removeManga(it) },
// KMK -->
cancelManga = { screenModel.cancelManga(it) },
// KMK <--
searchManually = { migrationItem ->
val sources = screenModel.getMigrationSources()
val validSources = if (sources.size == 1) {

View file

@ -180,7 +180,9 @@ class MigrationListScreenModel(
val mangaSource = sourceManager.getOrStub(mangaObj.source)
val result = try {
manga.migrationScope.async {
// KMK -->
manga.searchingJob = manga.migrationScope.async {
// KMK <--
val validSources = if (sources.size == 1) {
sources
} else {
@ -288,7 +290,10 @@ class MigrationListScreenModel(
null
}
}.await()
}
// KMK -->
manga.searchingJob.await()
// KMK <--
} catch (e: CancellationException) {
// Ignore canceled migrations
continue
@ -434,6 +439,7 @@ class MigrationListScreenModel(
updateManga.awaitAll(listOfNotNull(mangaUpdate, prevMangaUpdate))
}
/** Set a manga picked from manual search to be used as migration target */
fun useMangaForMigration(context: Context, newMangaId: Long, selectedMangaId: Long) {
val migratingManga = migratingItems.value.orEmpty().find { it.manga.id == selectedMangaId }
?: return
@ -545,6 +551,19 @@ class MigrationListScreenModel(
}
}
// KMK -->
/** Cancel searching without remove it from list so user can perform manual search */
fun cancelManga(mangaId: Long) {
screenModelScope.launchIO {
val item = migratingItems.value.orEmpty().find { it.manga.id == mangaId }
?: return@launchIO
item.searchingJob.cancel()
item.searchResult.value = SearchResult.NotFound
sourceFinished()
}
}
// KMK <--
fun removeManga(mangaId: Long) {
screenModelScope.launchIO {
val item = migratingItems.value.orEmpty().find { it.manga.id == mangaId }