allow edit migration options while already being searching (#616)

This commit is contained in:
Cuong-Tran 2024-12-31 11:46:16 +07:00 committed by GitHub
parent 468529cd47
commit a6f3a2cdcf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 86 additions and 11 deletions

View file

@ -14,6 +14,7 @@ import androidx.compose.material.icons.outlined.ContentCopy
import androidx.compose.material.icons.outlined.CopyAll
import androidx.compose.material.icons.outlined.Done
import androidx.compose.material.icons.outlined.DoneAll
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
@ -54,6 +55,7 @@ fun MigrationListScreen(
// KMK -->
cancelManga: (Long) -> Unit,
navigateUp: () -> Unit,
openMigrationOptionsDialog: () -> Unit,
// KMK <--
searchManually: (MigratingManga) -> Unit,
migrateNow: (Long) -> Unit,
@ -75,6 +77,13 @@ fun MigrationListScreen(
actions = {
AppBarActions(
persistentListOf(
// KMK -->
AppBar.Action(
title = stringResource(MR.strings.action_settings),
icon = Icons.Outlined.Settings,
onClick = openMigrationOptionsDialog,
),
// KMK <--
AppBar.Action(
title = stringResource(MR.strings.copy),
icon = if (items.size == 1) Icons.Outlined.ContentCopy else Icons.Outlined.CopyAll,

View file

@ -22,9 +22,11 @@ import eu.kanade.presentation.components.AdaptiveSheet
import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
import eu.kanade.tachiyomi.util.system.toast
import tachiyomi.core.common.i18n.stringResource
import tachiyomi.core.common.preference.Preference
import tachiyomi.core.common.util.lang.toLong
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.i18n.MR
import tachiyomi.i18n.sy.SYMR
import uy.kohesive.injekt.injectLazy
@ -32,10 +34,18 @@ import uy.kohesive.injekt.injectLazy
fun MigrationBottomSheetDialog(
onDismissRequest: () -> Unit,
onStartMigration: (extraParam: String?) -> Unit,
// KMK -->
fullSettings: Boolean = true,
// KMK <--
) {
val startMigration = rememberUpdatedState(onStartMigration)
val state = remember {
MigrationBottomSheetDialogState(startMigration)
MigrationBottomSheetDialogState(
startMigration,
// KMK -->
fullSettings,
// KMK <--
)
}
// KMK -->
@ -132,7 +142,12 @@ fun MigrationBottomSheetDialog(
}
}
class MigrationBottomSheetDialogState(private val onStartMigration: State<(extraParam: String?) -> Unit>) {
class MigrationBottomSheetDialogState(
private val onStartMigration: State<(extraParam: String?) -> Unit>,
// KMK -->
private val fullSettings: Boolean = true,
// KMK <--
) {
private val preferences: UnsortedPreferences by injectLazy()
/**
@ -186,6 +201,17 @@ class MigrationBottomSheetDialogState(private val onStartMigration: State<(extra
},
)
}
// KMK -->
if (!fullSettings) {
binding.useSmartSearch.isVisible = false
binding.extraSearchParam.isVisible = false
binding.extraSearchParamText.isVisible = false
binding.sourceGroup.isVisible = false
binding.skipStep.isVisible = false
binding.migrateBtn.text = binding.root.context.stringResource(MR.strings.action_save)
}
// KMK <--
}
private fun setFlags(binding: MigrationBottomSheetBinding) {

View file

@ -99,6 +99,9 @@ sealed class MigrationType : Serializable {
data class MangaSingle(val fromMangaId: Long, val toManga: Long?) : MigrationType()
}
/**
* The screen showing a list of selectable sources used for migration, with migration setting dialog.
*/
class PreMigrationScreen(val migration: MigrationType) : Screen() {
@Composable
override fun Content() {

View file

@ -14,6 +14,7 @@ import eu.kanade.presentation.browse.components.MigrationExitDialog
import eu.kanade.presentation.browse.components.MigrationMangaDialog
import eu.kanade.presentation.browse.components.MigrationProgressDialog
import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.MigrationBottomSheetDialog
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationScreen
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen
@ -25,6 +26,9 @@ import tachiyomi.core.common.i18n.pluralStringResource
import tachiyomi.core.common.util.lang.withUIContext
import tachiyomi.i18n.sy.SYMR
/**
* Screen showing a list of pair of source-dest manga entries being migrated.
*/
class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen() {
var newSelectedItem: Pair<Long, Long>? = null
@ -106,6 +110,7 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
// KMK -->
cancelManga = { screenModel.cancelManga(it) },
navigateUp = { navigator.pop() },
openMigrationOptionsDialog = screenModel::openMigrationOptionsDialog,
// KMK <--
searchManually = { migrationItem ->
val sources = screenModel.getMigrationSources()
@ -143,6 +148,18 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
exitMigration = navigator::pop,
)
}
// KMK -->
MigrationListScreenModel.Dialog.MigrationOptionsDialog -> {
MigrationBottomSheetDialog(
onDismissRequest = onDismissRequest,
onStartMigration = { _ ->
onDismissRequest()
screenModel.updateOptions()
},
fullSettings = false,
)
}
// KMK <--
null -> Unit
}

View file

@ -58,6 +58,7 @@ import tachiyomi.domain.track.interactor.DeleteTrack
import tachiyomi.domain.track.interactor.GetTracks
import tachiyomi.domain.track.interactor.InsertTrack
import tachiyomi.i18n.sy.SYMR
import timber.log.Timber
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.util.concurrent.atomic.AtomicInteger
@ -93,8 +94,10 @@ class MigrationListScreenModel(
val manualMigrations = MutableStateFlow(0)
val hideNotFound = preferences.hideNotFoundMigration().get()
val showOnlyUpdates = preferences.showOnlyUpdatesMigration().get()
var hideNotFound = preferences.hideNotFoundMigration().get()
private var showOnlyUpdates = preferences.showOnlyUpdatesMigration().get()
private var useSourceWithMost = preferences.useSourceWithMost().get()
private var useSmartSearch = preferences.smartMigration().get()
val navigateOut = MutableSharedFlow<Unit>()
@ -144,7 +147,7 @@ class MigrationListScreenModel(
suspend fun getManga(result: SearchResult.Result) = getManga(result.id)
suspend fun getManga(id: Long) = getManga.await(id)
suspend fun getChapterInfo(result: SearchResult.Result) = getChapterInfo(result.id)
suspend fun getChapterInfo(id: Long) = getChaptersByMangaId.await(id).let { chapters ->
private suspend fun getChapterInfo(id: Long) = getChaptersByMangaId.await(id).let { chapters ->
MigratingManga.ChapterInfo(
latestChapter = chapters.maxOfOrNull { it.chapterNumber },
chapterCount = chapters.size,
@ -160,8 +163,6 @@ class MigrationListScreenModel(
private suspend fun runMigrations(mangas: List<MigratingManga>) {
throttleManager.resetThrottle()
// KMK: finishedCount.value = mangas.size
val useSourceWithMost = preferences.useSourceWithMost().get()
val useSmartSearch = preferences.smartMigration().get()
val sources = getMigrationSources()
for (manga in mangas) {
@ -311,6 +312,7 @@ class MigrationListScreenModel(
// Ignore cancellations
throw e
} catch (e: Exception) {
Timber.tag("MigrationListScreenModel").e(e, "Error updating manga from source")
}
}
@ -346,10 +348,10 @@ class MigrationListScreenModel(
}
}
fun allMangasDone() = migratingItems.value.orEmpty().all { it.searchResult.value != SearchResult.Searching } &&
private fun allMangasDone() = migratingItems.value.orEmpty().all { it.searchResult.value != SearchResult.Searching } &&
migratingItems.value.orEmpty().any { it.searchResult.value is SearchResult.Result }
fun mangasSkipped() = migratingItems.value.orEmpty().count { it.searchResult.value == SearchResult.NotFound }
private fun mangasSkipped() = migratingItems.value.orEmpty().count { it.searchResult.value == SearchResult.NotFound }
private suspend fun migrateMangaInternal(
prevManga: Manga,
@ -480,6 +482,7 @@ class MigrationListScreenModel(
// Ignore cancellations
throw e
} catch (e: Exception) {
Timber.tag("MigrationListScreenModel").e(e, "Error updating manga from source")
}
migratingManga.searchResult.value = SearchResult.Result(result.id)
@ -593,7 +596,7 @@ class MigrationListScreenModel(
}
}
fun removeManga(item: MigratingManga) {
private fun removeManga(item: MigratingManga) {
when (val migration = config.migration) {
is MigrationType.MangaList -> {
val ids = migration.mangaIds.toMutableList()
@ -626,8 +629,25 @@ class MigrationListScreenModel(
)
}
// KMK -->
fun openMigrationOptionsDialog() {
dialog.value = Dialog.MigrationOptionsDialog
}
fun updateOptions() {
hideNotFound = preferences.hideNotFoundMigration().get()
showOnlyUpdates = preferences.showOnlyUpdatesMigration().get()
useSourceWithMost = preferences.useSourceWithMost().get()
useSmartSearch = preferences.smartMigration().get()
}
// KMK <--
sealed class Dialog {
data class MigrateMangaDialog(val copy: Boolean, val mangaSet: Int, val mangaSkipped: Int) : Dialog()
object MigrationExitDialog : Dialog()
data object MigrationExitDialog : Dialog()
// KMK -->
data object MigrationOptionsDialog : Dialog()
// KMK <--
}
}