allow edit migration options while already being searching (#616)
This commit is contained in:
parent
468529cd47
commit
a6f3a2cdcf
5 changed files with 86 additions and 11 deletions
|
|
@ -14,6 +14,7 @@ import androidx.compose.material.icons.outlined.ContentCopy
|
||||||
import androidx.compose.material.icons.outlined.CopyAll
|
import androidx.compose.material.icons.outlined.CopyAll
|
||||||
import androidx.compose.material.icons.outlined.Done
|
import androidx.compose.material.icons.outlined.Done
|
||||||
import androidx.compose.material.icons.outlined.DoneAll
|
import androidx.compose.material.icons.outlined.DoneAll
|
||||||
|
import androidx.compose.material.icons.outlined.Settings
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
|
|
@ -54,6 +55,7 @@ fun MigrationListScreen(
|
||||||
// KMK -->
|
// KMK -->
|
||||||
cancelManga: (Long) -> Unit,
|
cancelManga: (Long) -> Unit,
|
||||||
navigateUp: () -> Unit,
|
navigateUp: () -> Unit,
|
||||||
|
openMigrationOptionsDialog: () -> Unit,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
searchManually: (MigratingManga) -> Unit,
|
searchManually: (MigratingManga) -> Unit,
|
||||||
migrateNow: (Long) -> Unit,
|
migrateNow: (Long) -> Unit,
|
||||||
|
|
@ -75,6 +77,13 @@ fun MigrationListScreen(
|
||||||
actions = {
|
actions = {
|
||||||
AppBarActions(
|
AppBarActions(
|
||||||
persistentListOf(
|
persistentListOf(
|
||||||
|
// KMK -->
|
||||||
|
AppBar.Action(
|
||||||
|
title = stringResource(MR.strings.action_settings),
|
||||||
|
icon = Icons.Outlined.Settings,
|
||||||
|
onClick = openMigrationOptionsDialog,
|
||||||
|
),
|
||||||
|
// KMK <--
|
||||||
AppBar.Action(
|
AppBar.Action(
|
||||||
title = stringResource(MR.strings.copy),
|
title = stringResource(MR.strings.copy),
|
||||||
icon = if (items.size == 1) Icons.Outlined.ContentCopy else Icons.Outlined.CopyAll,
|
icon = if (items.size == 1) Icons.Outlined.ContentCopy else Icons.Outlined.CopyAll,
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,11 @@ import eu.kanade.presentation.components.AdaptiveSheet
|
||||||
import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding
|
import eu.kanade.tachiyomi.databinding.MigrationBottomSheetBinding
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
import eu.kanade.tachiyomi.ui.browse.migration.MigrationFlags
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
import tachiyomi.core.common.preference.Preference
|
import tachiyomi.core.common.preference.Preference
|
||||||
import tachiyomi.core.common.util.lang.toLong
|
import tachiyomi.core.common.util.lang.toLong
|
||||||
import tachiyomi.domain.UnsortedPreferences
|
import tachiyomi.domain.UnsortedPreferences
|
||||||
|
import tachiyomi.i18n.MR
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
|
|
@ -32,10 +34,18 @@ import uy.kohesive.injekt.injectLazy
|
||||||
fun MigrationBottomSheetDialog(
|
fun MigrationBottomSheetDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
onStartMigration: (extraParam: String?) -> Unit,
|
onStartMigration: (extraParam: String?) -> Unit,
|
||||||
|
// KMK -->
|
||||||
|
fullSettings: Boolean = true,
|
||||||
|
// KMK <--
|
||||||
) {
|
) {
|
||||||
val startMigration = rememberUpdatedState(onStartMigration)
|
val startMigration = rememberUpdatedState(onStartMigration)
|
||||||
val state = remember {
|
val state = remember {
|
||||||
MigrationBottomSheetDialogState(startMigration)
|
MigrationBottomSheetDialogState(
|
||||||
|
startMigration,
|
||||||
|
// KMK -->
|
||||||
|
fullSettings,
|
||||||
|
// KMK <--
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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()
|
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) {
|
private fun setFlags(binding: MigrationBottomSheetBinding) {
|
||||||
|
|
|
||||||
|
|
@ -99,6 +99,9 @@ sealed class MigrationType : Serializable {
|
||||||
data class MangaSingle(val fromMangaId: Long, val toManga: Long?) : MigrationType()
|
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() {
|
class PreMigrationScreen(val migration: MigrationType) : Screen() {
|
||||||
@Composable
|
@Composable
|
||||||
override fun Content() {
|
override fun Content() {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import eu.kanade.presentation.browse.components.MigrationExitDialog
|
||||||
import eu.kanade.presentation.browse.components.MigrationMangaDialog
|
import eu.kanade.presentation.browse.components.MigrationMangaDialog
|
||||||
import eu.kanade.presentation.browse.components.MigrationProgressDialog
|
import eu.kanade.presentation.browse.components.MigrationProgressDialog
|
||||||
import eu.kanade.presentation.util.Screen
|
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.advanced.design.PreMigrationScreen
|
||||||
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchScreen
|
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateSearchScreen
|
||||||
import eu.kanade.tachiyomi.ui.manga.MangaScreen
|
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.core.common.util.lang.withUIContext
|
||||||
import tachiyomi.i18n.sy.SYMR
|
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() {
|
class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen() {
|
||||||
|
|
||||||
var newSelectedItem: Pair<Long, Long>? = null
|
var newSelectedItem: Pair<Long, Long>? = null
|
||||||
|
|
@ -106,6 +110,7 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
|
||||||
// KMK -->
|
// KMK -->
|
||||||
cancelManga = { screenModel.cancelManga(it) },
|
cancelManga = { screenModel.cancelManga(it) },
|
||||||
navigateUp = { navigator.pop() },
|
navigateUp = { navigator.pop() },
|
||||||
|
openMigrationOptionsDialog = screenModel::openMigrationOptionsDialog,
|
||||||
// KMK <--
|
// KMK <--
|
||||||
searchManually = { migrationItem ->
|
searchManually = { migrationItem ->
|
||||||
val sources = screenModel.getMigrationSources()
|
val sources = screenModel.getMigrationSources()
|
||||||
|
|
@ -143,6 +148,18 @@ class MigrationListScreen(private val config: MigrationProcedureConfig) : Screen
|
||||||
exitMigration = navigator::pop,
|
exitMigration = navigator::pop,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
// KMK -->
|
||||||
|
MigrationListScreenModel.Dialog.MigrationOptionsDialog -> {
|
||||||
|
MigrationBottomSheetDialog(
|
||||||
|
onDismissRequest = onDismissRequest,
|
||||||
|
onStartMigration = { _ ->
|
||||||
|
onDismissRequest()
|
||||||
|
screenModel.updateOptions()
|
||||||
|
},
|
||||||
|
fullSettings = false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
// KMK <--
|
||||||
null -> Unit
|
null -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ import tachiyomi.domain.track.interactor.DeleteTrack
|
||||||
import tachiyomi.domain.track.interactor.GetTracks
|
import tachiyomi.domain.track.interactor.GetTracks
|
||||||
import tachiyomi.domain.track.interactor.InsertTrack
|
import tachiyomi.domain.track.interactor.InsertTrack
|
||||||
import tachiyomi.i18n.sy.SYMR
|
import tachiyomi.i18n.sy.SYMR
|
||||||
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
|
@ -93,8 +94,10 @@ class MigrationListScreenModel(
|
||||||
|
|
||||||
val manualMigrations = MutableStateFlow(0)
|
val manualMigrations = MutableStateFlow(0)
|
||||||
|
|
||||||
val hideNotFound = preferences.hideNotFoundMigration().get()
|
var hideNotFound = preferences.hideNotFoundMigration().get()
|
||||||
val showOnlyUpdates = preferences.showOnlyUpdatesMigration().get()
|
private var showOnlyUpdates = preferences.showOnlyUpdatesMigration().get()
|
||||||
|
private var useSourceWithMost = preferences.useSourceWithMost().get()
|
||||||
|
private var useSmartSearch = preferences.smartMigration().get()
|
||||||
|
|
||||||
val navigateOut = MutableSharedFlow<Unit>()
|
val navigateOut = MutableSharedFlow<Unit>()
|
||||||
|
|
||||||
|
|
@ -144,7 +147,7 @@ class MigrationListScreenModel(
|
||||||
suspend fun getManga(result: SearchResult.Result) = getManga(result.id)
|
suspend fun getManga(result: SearchResult.Result) = getManga(result.id)
|
||||||
suspend fun getManga(id: Long) = getManga.await(id)
|
suspend fun getManga(id: Long) = getManga.await(id)
|
||||||
suspend fun getChapterInfo(result: SearchResult.Result) = getChapterInfo(result.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(
|
MigratingManga.ChapterInfo(
|
||||||
latestChapter = chapters.maxOfOrNull { it.chapterNumber },
|
latestChapter = chapters.maxOfOrNull { it.chapterNumber },
|
||||||
chapterCount = chapters.size,
|
chapterCount = chapters.size,
|
||||||
|
|
@ -160,8 +163,6 @@ class MigrationListScreenModel(
|
||||||
private suspend fun runMigrations(mangas: List<MigratingManga>) {
|
private suspend fun runMigrations(mangas: List<MigratingManga>) {
|
||||||
throttleManager.resetThrottle()
|
throttleManager.resetThrottle()
|
||||||
// KMK: finishedCount.value = mangas.size
|
// KMK: finishedCount.value = mangas.size
|
||||||
val useSourceWithMost = preferences.useSourceWithMost().get()
|
|
||||||
val useSmartSearch = preferences.smartMigration().get()
|
|
||||||
|
|
||||||
val sources = getMigrationSources()
|
val sources = getMigrationSources()
|
||||||
for (manga in mangas) {
|
for (manga in mangas) {
|
||||||
|
|
@ -311,6 +312,7 @@ class MigrationListScreenModel(
|
||||||
// Ignore cancellations
|
// Ignore cancellations
|
||||||
throw e
|
throw e
|
||||||
} catch (e: Exception) {
|
} 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 }
|
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(
|
private suspend fun migrateMangaInternal(
|
||||||
prevManga: Manga,
|
prevManga: Manga,
|
||||||
|
|
@ -480,6 +482,7 @@ class MigrationListScreenModel(
|
||||||
// Ignore cancellations
|
// Ignore cancellations
|
||||||
throw e
|
throw e
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Timber.tag("MigrationListScreenModel").e(e, "Error updating manga from source")
|
||||||
}
|
}
|
||||||
|
|
||||||
migratingManga.searchResult.value = SearchResult.Result(result.id)
|
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) {
|
when (val migration = config.migration) {
|
||||||
is MigrationType.MangaList -> {
|
is MigrationType.MangaList -> {
|
||||||
val ids = migration.mangaIds.toMutableList()
|
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 {
|
sealed class Dialog {
|
||||||
data class MigrateMangaDialog(val copy: Boolean, val mangaSet: Int, val mangaSkipped: Int) : 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 <--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue