(cherry picked from commit 2b126f1ff56b63e470b48a04149e28c609f01148) Co-authored-by: Cuong-Tran <16017808+cuong-tran@users.noreply.github.com>
178 lines
6.7 KiB
Kotlin
178 lines
6.7 KiB
Kotlin
package mihon.feature.migration.dialog
|
|
|
|
import androidx.compose.foundation.background
|
|
import androidx.compose.foundation.layout.Arrangement
|
|
import androidx.compose.foundation.layout.Column
|
|
import androidx.compose.foundation.layout.FlowRow
|
|
import androidx.compose.foundation.layout.Spacer
|
|
import androidx.compose.foundation.rememberScrollState
|
|
import androidx.compose.foundation.verticalScroll
|
|
import androidx.compose.material3.AlertDialog
|
|
import androidx.compose.material3.MaterialTheme
|
|
import androidx.compose.material3.Text
|
|
import androidx.compose.material3.TextButton
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.collectAsState
|
|
import androidx.compose.runtime.getValue
|
|
import androidx.compose.runtime.rememberCoroutineScope
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.util.fastForEach
|
|
import cafe.adriel.voyager.core.model.StateScreenModel
|
|
import cafe.adriel.voyager.core.model.rememberScreenModel
|
|
import cafe.adriel.voyager.core.screen.Screen
|
|
import eu.kanade.domain.manga.model.hasCustomCover
|
|
import eu.kanade.domain.source.service.SourcePreferences
|
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
|
import kotlinx.coroutines.flow.update
|
|
import mihon.domain.migration.models.MigrationFlag
|
|
import mihon.domain.migration.usecases.MigrateMangaUseCase
|
|
import mihon.feature.common.utils.getLabel
|
|
import tachiyomi.core.common.util.lang.launchIO
|
|
import tachiyomi.core.common.util.lang.withUIContext
|
|
import tachiyomi.domain.manga.model.Manga
|
|
import tachiyomi.i18n.MR
|
|
import tachiyomi.presentation.core.components.LabeledCheckbox
|
|
import tachiyomi.presentation.core.components.material.padding
|
|
import tachiyomi.presentation.core.i18n.stringResource
|
|
import tachiyomi.presentation.core.screens.LoadingScreen
|
|
import uy.kohesive.injekt.Injekt
|
|
import uy.kohesive.injekt.api.get
|
|
|
|
@Composable
|
|
internal fun Screen.MigrateMangaDialog(
|
|
current: Manga,
|
|
target: Manga,
|
|
onClickTitle: () -> Unit,
|
|
onDismissRequest: () -> Unit,
|
|
onComplete: () -> Unit = onDismissRequest,
|
|
) {
|
|
val scope = rememberCoroutineScope()
|
|
|
|
val screenModel = rememberScreenModel { MigrateDialogScreenModel(current, target) }
|
|
val state by screenModel.state.collectAsState()
|
|
|
|
if (state.isMigrating) {
|
|
LoadingScreen(
|
|
modifier = Modifier.background(MaterialTheme.colorScheme.background.copy(alpha = 0.7f)),
|
|
)
|
|
return
|
|
}
|
|
|
|
AlertDialog(
|
|
onDismissRequest = onDismissRequest,
|
|
title = {
|
|
Text(text = stringResource(MR.strings.migration_dialog_what_to_include))
|
|
},
|
|
text = {
|
|
Column(
|
|
modifier = Modifier.verticalScroll(rememberScrollState()),
|
|
) {
|
|
state.applicableFlags.fastForEach { flag ->
|
|
LabeledCheckbox(
|
|
label = stringResource(flag.getLabel()),
|
|
checked = flag in state.selectedFlags,
|
|
onCheckedChange = { screenModel.toggleSelection(flag) },
|
|
)
|
|
}
|
|
}
|
|
},
|
|
confirmButton = {
|
|
FlowRow(
|
|
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
|
|
) {
|
|
TextButton(
|
|
onClick = {
|
|
// KMK -->
|
|
// Allow `migrate` mangas when using `Bulk-favorite`
|
|
// onDismissRequest()
|
|
// KMK <--
|
|
onClickTitle()
|
|
},
|
|
) {
|
|
Text(text = stringResource(MR.strings.action_show_manga))
|
|
}
|
|
|
|
Spacer(modifier = Modifier.weight(1f))
|
|
|
|
TextButton(
|
|
onClick = {
|
|
scope.launchIO {
|
|
screenModel.migrateManga(replace = false)
|
|
withUIContext { onComplete() }
|
|
}
|
|
},
|
|
) {
|
|
Text(text = stringResource(MR.strings.copy))
|
|
}
|
|
TextButton(
|
|
onClick = {
|
|
scope.launchIO {
|
|
screenModel.migrateManga(replace = true)
|
|
withUIContext { onComplete() }
|
|
}
|
|
},
|
|
) {
|
|
Text(text = stringResource(MR.strings.migrate))
|
|
}
|
|
}
|
|
},
|
|
)
|
|
}
|
|
|
|
private class MigrateDialogScreenModel(
|
|
private val current: Manga,
|
|
private val target: Manga,
|
|
sourcePreference: SourcePreferences = Injekt.get(),
|
|
private val coverCache: CoverCache = Injekt.get(),
|
|
private val downloadManager: DownloadManager = Injekt.get(),
|
|
private val migrateManga: MigrateMangaUseCase = Injekt.get(),
|
|
) : StateScreenModel<MigrateDialogScreenModel.State>(State()) {
|
|
|
|
init {
|
|
val applicableFlags = buildList {
|
|
MigrationFlag.entries.forEach {
|
|
val applicable = when (it) {
|
|
MigrationFlag.CHAPTER -> true
|
|
MigrationFlag.CATEGORY -> true
|
|
// KMK -->
|
|
MigrationFlag.TRACK -> true
|
|
// KMK <--
|
|
MigrationFlag.CUSTOM_COVER -> current.hasCustomCover(coverCache)
|
|
MigrationFlag.NOTES -> current.notes.isNotBlank()
|
|
MigrationFlag.REMOVE_DOWNLOAD -> downloadManager.getDownloadCount(current) > 0
|
|
// KMK -->
|
|
MigrationFlag.EXTRA -> true
|
|
// KMK <--
|
|
}
|
|
if (applicable) add(it)
|
|
}
|
|
}
|
|
val selectedFlags = sourcePreference.migrationFlags().get()
|
|
mutableState.update { it.copy(applicableFlags = applicableFlags, selectedFlags = selectedFlags) }
|
|
}
|
|
|
|
fun toggleSelection(flag: MigrationFlag) {
|
|
mutableState.update {
|
|
val selectedFlags = it.selectedFlags.toMutableSet()
|
|
.apply { if (contains(flag)) remove(flag) else add(flag) }
|
|
.toSet()
|
|
it.copy(selectedFlags = selectedFlags)
|
|
}
|
|
}
|
|
|
|
suspend fun migrateManga(replace: Boolean) {
|
|
// KMK -->
|
|
// sourcePreference.migrationFlags().set(state.value.selectedFlags)
|
|
// KMK <--
|
|
mutableState.update { it.copy(isMigrating = true) }
|
|
migrateManga(current, target, replace, /* KMK --> */ state.value.selectedFlags /* KMK <-- */)
|
|
mutableState.update { it.copy(isMigrating = false) }
|
|
}
|
|
|
|
data class State(
|
|
val applicableFlags: List<MigrationFlag> = emptyList(),
|
|
val selectedFlags: Set<MigrationFlag> = emptySet(),
|
|
val isMigrating: Boolean = false,
|
|
)
|
|
}
|