Allow migrate mangas when using Bulk-favorite (#824)

* Combine ChangeMangaCategoryDialog

* Allow migrating a single manga when using Bulk-favorite

* Allow migrating mangas one by one when using Bulk-favorite

* set visibility

* Fix duplicate toggleSelection after migration

* After migration, continue adding favorites if there are more to bulk-favorite or push new Manga screen if it's a single manga being added by long-click

* fix usage of ChangeMangaCategory

* improve toggleSelection code

* refactoring ChangeMangasCategory

* switch LocalNavigator.currentOrThrow to current

* split composable to `presentation`

* hoisting the state to a common parent composable

* Fix migration dialog dismissed when clicking on Show entry

* Don't push new Manga screen after migration of duplicated entries everywhere
This commit is contained in:
Cuong-Tran 2025-04-09 11:42:43 +07:00 committed by GitHub
parent 8d94c09a43
commit fa7b18590e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
19 changed files with 282 additions and 231 deletions

View file

@ -17,13 +17,13 @@ import eu.kanade.presentation.browse.components.GlobalSearchCardRow
import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem import eu.kanade.presentation.browse.components.GlobalSearchErrorResultItem
import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem import eu.kanade.presentation.browse.components.GlobalSearchLoadingResultItem
import eu.kanade.presentation.browse.components.GlobalSearchResultItem import eu.kanade.presentation.browse.components.GlobalSearchResultItem
import eu.kanade.presentation.browse.components.bulkSelectionButton
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.AppBarTitle import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.components.BulkSelectionToolbar import eu.kanade.presentation.components.BulkSelectionToolbar
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.bulkSelectionButton
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga

View file

@ -14,7 +14,6 @@ import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.DropdownMenu import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.components.RadioMenuItem import eu.kanade.presentation.components.RadioMenuItem
import eu.kanade.tachiyomi.ui.browse.bulkSelectionButton
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode
import tachiyomi.i18n.MR import tachiyomi.i18n.MR

View file

@ -20,7 +20,6 @@ import eu.kanade.presentation.components.RadioMenuItem
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.ui.browse.bulkSelectionButton
import exh.source.anyIs import exh.source.anyIs
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.domain.library.model.LibraryDisplayMode import tachiyomi.domain.library.model.LibraryDisplayMode

View file

@ -0,0 +1,225 @@
package eu.kanade.presentation.browse.components
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Checklist
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.Navigator
import eu.kanade.presentation.category.components.ChangeCategoryDialog
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.manga.DuplicateMangaDialog
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel.Dialog
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialog
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialogScreenModel
import eu.kanade.tachiyomi.ui.category.CategoryScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.kmk.KMR
import tachiyomi.presentation.core.i18n.stringResource
/**
* Compose to shows the bulk favorite dialogs.
*
* @param bulkFavoriteScreenModel the screen model.
* @param dialog the dialog to show.
*/
@Composable
fun BulkFavoriteDialogs(
bulkFavoriteScreenModel: BulkFavoriteScreenModel,
dialog: Dialog?,
) {
val navigator = LocalNavigator.current
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
when (dialog) {
/* Bulk-favorite actions */
is Dialog.ChangeMangasCategory ->
ChangeMangasCategoryDialog(
dialog = dialog,
navigator = navigator,
onDismiss = bulkFavoriteScreenModel::dismissDialog,
onConfirm = { include, exclude ->
bulkFavoriteScreenModel.setMangasCategories(dialog.mangas, include, exclude)
},
)
is Dialog.BulkAllowDuplicate ->
BulkAllowDuplicateDialog(
dialog = dialog,
navigator = navigator,
onDismiss = bulkFavoriteScreenModel::dismissDialog,
stopRunning = bulkFavoriteScreenModel::stopRunning,
addFavorite = bulkFavoriteScreenModel::addFavorite,
showMigrateDialog = bulkFavoriteScreenModel::showMigrateDialog,
addFavoriteDuplicate = bulkFavoriteScreenModel::addFavoriteDuplicate,
removeDuplicateSelectedManga = bulkFavoriteScreenModel::removeDuplicateSelectedManga,
)
/* Single-favorite actions for screens originally don't have it */
is Dialog.AddDuplicateManga ->
AddDuplicateMangaDialog(
dialog = dialog,
navigator = navigator,
state = bulkFavoriteState,
onDismiss = bulkFavoriteScreenModel::dismissDialog,
stopRunning = bulkFavoriteScreenModel::stopRunning,
toggleSelectionMode = bulkFavoriteScreenModel::toggleSelectionMode,
addFavorite = bulkFavoriteScreenModel::addFavorite,
showMigrateDialog = bulkFavoriteScreenModel::showMigrateDialog,
)
is Dialog.RemoveManga ->
RemoveMangaDialog(
dialog = dialog,
onDismiss = bulkFavoriteScreenModel::dismissDialog,
changeMangaFavorite = bulkFavoriteScreenModel::changeMangaFavorite,
)
is Dialog.Migrate ->
ShowMigrateDialog(
dialog = dialog,
navigator = navigator,
state = bulkFavoriteState,
onDismiss = bulkFavoriteScreenModel::dismissDialog,
stopRunning = bulkFavoriteScreenModel::stopRunning,
toggleSelection = bulkFavoriteScreenModel::toggleSelection,
addFavorite = bulkFavoriteScreenModel::addFavorite,
)
else -> {}
}
}
@Composable
private fun ShowMigrateDialog(
dialog: Dialog.Migrate,
navigator: Navigator?,
state: BulkFavoriteScreenModel.State,
onDismiss: () -> Unit,
stopRunning: () -> Unit,
toggleSelection: (Manga, toSelectedState: Boolean) -> Unit,
addFavorite: () -> Unit,
) {
stopRunning()
MigrateDialog(
oldManga = dialog.oldManga,
newManga = dialog.newManga,
screenModel = MigrateDialogScreenModel(),
onDismissRequest = onDismiss,
onClickTitle = { navigator?.push(MangaScreen(dialog.oldManga.id)) },
onPopScreen = {
toggleSelection(dialog.newManga, false)
onDismiss()
// `selection.size` is at current value before calling above `toggleSelection`
if (state.selection.size > 1) {
// Continue adding favorites
addFavorite()
}
},
)
}
/**
* Shows dialog to add a single manga to library when there are duplicates.
*/
@Composable
private fun AddDuplicateMangaDialog(
dialog: Dialog.AddDuplicateManga,
navigator: Navigator?,
state: BulkFavoriteScreenModel.State,
onDismiss: () -> Unit,
stopRunning: () -> Unit,
toggleSelectionMode: () -> Unit,
addFavorite: (Manga) -> Unit,
showMigrateDialog: (manga: Manga, duplicate: Manga) -> Unit,
) {
stopRunning()
DuplicateMangaDialog(
duplicates = dialog.duplicates,
onDismissRequest = onDismiss,
onConfirm = {
if (state.selectionMode) {
toggleSelectionMode()
}
addFavorite(dialog.manga)
},
onOpenManga = { navigator?.push(MangaScreen(it.id)) },
onMigrate = { showMigrateDialog(dialog.manga, it) },
)
}
@Composable
private fun RemoveMangaDialog(
dialog: Dialog.RemoveManga,
onDismiss: () -> Unit,
changeMangaFavorite: (Manga) -> Unit,
) {
RemoveMangaDialog(
onDismissRequest = onDismiss,
onConfirm = { changeMangaFavorite(dialog.manga) },
mangaToRemove = dialog.manga,
)
}
@Composable
private fun ChangeMangasCategoryDialog(
dialog: Dialog.ChangeMangasCategory,
navigator: Navigator?,
onDismiss: () -> Unit,
onConfirm: (List<Long>, List<Long>) -> Unit,
) {
ChangeCategoryDialog(
initialSelection = dialog.initialSelection,
onDismissRequest = onDismiss,
onEditCategories = { navigator?.push(CategoryScreen()) },
onConfirm = onConfirm,
)
}
/**
* Shows dialog to bulk allow/skip or migrate multiple manga to library when there are duplicates.
*/
@Composable
private fun BulkAllowDuplicateDialog(
dialog: Dialog.BulkAllowDuplicate,
navigator: Navigator?,
onDismiss: () -> Unit,
stopRunning: () -> Unit,
addFavorite: (startIdx: Int) -> Unit,
showMigrateDialog: (manga: Manga, duplicate: Manga) -> Unit,
addFavoriteDuplicate: (skipAllDuplicates: Boolean) -> Unit,
removeDuplicateSelectedManga: (index: Int) -> Unit,
) {
DuplicateMangaDialog(
duplicates = dialog.duplicates,
onDismissRequest = onDismiss,
onConfirm = { addFavorite(dialog.currentIdx + 1) },
onOpenManga = { navigator?.push(MangaScreen(it.id)) },
onMigrate = { showMigrateDialog(dialog.manga, it) },
bulkFavoriteManga = dialog.manga,
onAllowAllDuplicate = { addFavoriteDuplicate(false) },
onSkipAllDuplicate = { addFavoriteDuplicate(true) },
onSkipDuplicate = {
removeDuplicateSelectedManga(dialog.currentIdx)
addFavorite(dialog.currentIdx)
},
stopRunning = stopRunning,
)
}
@Composable
fun bulkSelectionButton(
isRunning: Boolean,
toggleSelectionMode: () -> Unit,
) = AppBar.Action(
title = stringResource(KMR.strings.action_bulk_select),
icon = Icons.Outlined.Checklist,
iconTint = MaterialTheme.colorScheme.primary.takeIf { isRunning },
onClick = toggleSelectionMode,
)

View file

@ -28,7 +28,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.tachiyomi.ui.browse.bulkSelectionButton
import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter import eu.kanade.tachiyomi.ui.browse.source.globalsearch.SourceFilter
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
import tachiyomi.i18n.MR import tachiyomi.i18n.MR

View file

@ -147,12 +147,7 @@ fun DuplicateMangaDialog(
DuplicateMangaListItem( DuplicateMangaListItem(
manga = it, manga = it,
getSource = { sourceManager.getOrStub(it.source) }, getSource = { sourceManager.getOrStub(it.source) },
onMigrate = { onMigrate = { onMigrate(it) },
// KMK -->
if (bulkFavoriteManga == null) onDismissRequest()
// KMK <--
onMigrate(it)
},
onOpenManga = { onOpenManga(it) }, onOpenManga = { onOpenManga(it) },
) )
@ -184,7 +179,7 @@ fun DuplicateMangaDialog(
}, },
Modifier.align(Alignment.CenterHorizontally), Modifier.align(Alignment.CenterHorizontally),
) { ) {
Text(text = stringResource(KMR.strings.action_allow_duplicate_manga)) Text(text = stringResource(MR.strings.action_add_anyway))
} }
TextButton( TextButton(

View file

@ -1,12 +1,6 @@
package eu.kanade.tachiyomi.ui.browse package eu.kanade.tachiyomi.ui.browse
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Checklist
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable import androidx.compose.runtime.Immutable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.hapticfeedback.HapticFeedback import androidx.compose.ui.hapticfeedback.HapticFeedback
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.util.fastAny import androidx.compose.ui.util.fastAny
@ -15,20 +9,11 @@ import androidx.compose.ui.util.fastForEach
import androidx.compose.ui.util.fastForEachIndexed import androidx.compose.ui.util.fastForEachIndexed
import cafe.adriel.voyager.core.model.StateScreenModel import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.screenModelScope import cafe.adriel.voyager.core.model.screenModelScope
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.domain.manga.interactor.UpdateManga import eu.kanade.domain.manga.interactor.UpdateManga
import eu.kanade.domain.track.interactor.AddTracks import eu.kanade.domain.track.interactor.AddTracks
import eu.kanade.presentation.browse.components.RemoveMangaDialog
import eu.kanade.presentation.category.components.ChangeCategoryDialog
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.BulkSelectionToolbar import eu.kanade.presentation.components.BulkSelectionToolbar
import eu.kanade.presentation.manga.DuplicateMangaDialog import eu.kanade.presentation.manga.DuplicateMangaDialog
import eu.kanade.tachiyomi.data.cache.CoverCache import eu.kanade.tachiyomi.data.cache.CoverCache
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel.Dialog
import eu.kanade.tachiyomi.ui.browse.migration.advanced.design.PreMigrationScreen
import eu.kanade.tachiyomi.ui.category.CategoryScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen
import eu.kanade.tachiyomi.util.removeCovers import eu.kanade.tachiyomi.util.removeCovers
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.PersistentList
@ -43,7 +28,6 @@ import tachiyomi.core.common.preference.CheckboxState
import tachiyomi.core.common.preference.mapAsCheckboxState import tachiyomi.core.common.preference.mapAsCheckboxState
import tachiyomi.core.common.util.lang.launchIO import tachiyomi.core.common.util.lang.launchIO
import tachiyomi.core.common.util.lang.launchNonCancellable import tachiyomi.core.common.util.lang.launchNonCancellable
import tachiyomi.domain.UnsortedPreferences
import tachiyomi.domain.category.interactor.GetCategories import tachiyomi.domain.category.interactor.GetCategories
import tachiyomi.domain.category.interactor.SetMangaCategories import tachiyomi.domain.category.interactor.SetMangaCategories
import tachiyomi.domain.category.model.Category import tachiyomi.domain.category.model.Category
@ -53,8 +37,6 @@ import tachiyomi.domain.manga.interactor.GetDuplicateLibraryManga
import tachiyomi.domain.manga.model.Manga import tachiyomi.domain.manga.model.Manga
import tachiyomi.domain.manga.model.toMangaUpdate import tachiyomi.domain.manga.model.toMangaUpdate
import tachiyomi.domain.source.service.SourceManager import tachiyomi.domain.source.service.SourceManager
import tachiyomi.i18n.kmk.KMR
import tachiyomi.presentation.core.i18n.stringResource
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
import java.time.Instant import java.time.Instant
@ -76,11 +58,11 @@ class BulkFavoriteScreenModel(
toggleSelectionMode() toggleSelectionMode()
} }
fun toggleSelectionMode() { fun toggleSelectionMode(newMode: Boolean? = null) {
if (state.value.selectionMode) { if (state.value.selectionMode) {
clearSelection() clearSelection()
} }
mutableState.update { it.copy(selectionMode = !it.selectionMode) } mutableState.update { it.copy(selectionMode = newMode ?: !it.selectionMode) }
} }
private fun clearSelection() { private fun clearSelection() {
@ -97,10 +79,13 @@ class BulkFavoriteScreenModel(
fun toggleSelection(manga: Manga, toSelectedState: Boolean? = null) { fun toggleSelection(manga: Manga, toSelectedState: Boolean? = null) {
mutableState.update { state -> mutableState.update { state ->
val newSelection = state.selection.mutate { list -> val newSelection = state.selection.mutate { list ->
if (toSelectedState != true && list.fastAny { it.id == manga.id }) { val isSelected = list.fastAny { it.id == manga.id }
list.removeAll { it.id == manga.id } val shouldSelect = toSelectedState ?: !isSelected
} else if (toSelectedState != false && list.none { it.id == manga.id }) { // Both condition to avoid adding duplicate entries
if (shouldSelect && !isSelected) {
list.add(manga) list.add(manga)
} else if (!shouldSelect && isSelected) {
list.removeAll { it.id == manga.id }
} }
} }
state.copy( state.copy(
@ -151,8 +136,11 @@ class BulkFavoriteScreenModel(
/** /**
* Add mangas to library if there is default category or no category exists. * Add mangas to library if there is default category or no category exists.
* If not, it shows the categories list. * If not, it shows the categories list.
*
* @param skipAllDuplicates if true, skip all duplicates and add all selected mangas to library.
* if false, allow all duplicates and add all selected mangas to library
*/ */
fun addFavoriteDuplicate(skipAllDuplicates: Boolean = false) { internal fun addFavoriteDuplicate(skipAllDuplicates: Boolean = false) {
screenModelScope.launch { screenModelScope.launch {
val mangaList = if (skipAllDuplicates) getNotDuplicateLibraryMangas() else state.value.selection val mangaList = if (skipAllDuplicates) getNotDuplicateLibraryMangas() else state.value.selection
if (mangaList.isEmpty()) { if (mangaList.isEmpty()) {
@ -216,7 +204,7 @@ class BulkFavoriteScreenModel(
return null return null
} }
fun removeDuplicateSelectedManga(index: Int) { internal fun removeDuplicateSelectedManga(index: Int) {
mutableState.update { state -> mutableState.update { state ->
val newSelection = state.selection.mutate { list -> val newSelection = state.selection.mutate { list ->
list.removeAt(index) list.removeAt(index)
@ -232,7 +220,7 @@ class BulkFavoriteScreenModel(
* @param addCategories the categories to add for all mangas. * @param addCategories the categories to add for all mangas.
* @param removeCategories the categories to remove in all mangas. * @param removeCategories the categories to remove in all mangas.
*/ */
fun setMangasCategories(mangaList: List<Manga>, addCategories: List<Long>, removeCategories: List<Long>) { internal fun setMangasCategories(mangaList: List<Manga>, addCategories: List<Long>, removeCategories: List<Long>) {
screenModelScope.launchNonCancellable { screenModelScope.launchNonCancellable {
startRunning() startRunning()
mangaList.fastForEach { manga -> mangaList.fastForEach { manga ->
@ -246,7 +234,7 @@ class BulkFavoriteScreenModel(
} }
stopRunning() stopRunning()
} }
toggleSelectionMode() toggleSelectionMode(newMode = false)
} }
private fun moveMangaToCategoriesAndAddToLibrary(manga: Manga, categories: List<Long>) { private fun moveMangaToCategoriesAndAddToLibrary(manga: Manga, categories: List<Long>) {
@ -293,7 +281,7 @@ class BulkFavoriteScreenModel(
* *
* @return List of categories, not including the default category * @return List of categories, not including the default category
*/ */
suspend fun getCategories(): List<Category> { private suspend fun getCategories(): List<Category> {
return getCategories.subscribe() return getCategories.subscribe()
.firstOrNull() .firstOrNull()
?.filterNot { it.isSystemCategory } ?.filterNot { it.isSystemCategory }
@ -304,7 +292,7 @@ class BulkFavoriteScreenModel(
moveMangaToCategories(manga, categories.filter { it.id != 0L }.map { it.id }) moveMangaToCategories(manga, categories.filter { it.id != 0L }.map { it.id })
} }
fun moveMangaToCategories(manga: Manga, categoryIds: List<Long>) { private fun moveMangaToCategories(manga: Manga, categoryIds: List<Long>) {
screenModelScope.launchIO { screenModelScope.launchIO {
setMangaCategories.await( setMangaCategories.await(
mangaId = manga.id, mangaId = manga.id,
@ -318,7 +306,7 @@ class BulkFavoriteScreenModel(
* *
* @param manga the manga to update. * @param manga the manga to update.
*/ */
fun changeMangaFavorite(manga: Manga) { internal fun changeMangaFavorite(manga: Manga) {
val source = sourceManager.getOrStub(manga.source) val source = sourceManager.getOrStub(manga.source)
screenModelScope.launch { screenModelScope.launch {
@ -341,7 +329,7 @@ class BulkFavoriteScreenModel(
} }
} }
fun addFavorite(manga: Manga) { internal fun addFavorite(manga: Manga) {
screenModelScope.launch { screenModelScope.launch {
val categories = getCategories() val categories = getCategories()
val defaultCategoryId = libraryPreferences.defaultCategory().get() val defaultCategoryId = libraryPreferences.defaultCategory().get()
@ -364,8 +352,8 @@ class BulkFavoriteScreenModel(
else -> { else -> {
val preselectedIds = getCategories.await(manga.id).map { it.id } val preselectedIds = getCategories.await(manga.id).map { it.id }
setDialog( setDialog(
Dialog.ChangeMangaCategory( Dialog.ChangeMangasCategory(
manga, listOf(manga),
categories.mapAsCheckboxState { it.id in preselectedIds }.toImmutableList(), categories.mapAsCheckboxState { it.id in preselectedIds }.toImmutableList(),
), ),
) )
@ -388,13 +376,17 @@ class BulkFavoriteScreenModel(
} }
} }
internal fun showMigrateDialog(manga: Manga, duplicate: Manga) {
setDialog(Dialog.Migrate(newManga = manga, oldManga = duplicate))
}
private fun setDialog(dialog: Dialog?) { private fun setDialog(dialog: Dialog?) {
mutableState.update { mutableState.update {
it.copy(dialog = dialog) it.copy(dialog = dialog)
} }
} }
fun dismissDialog() { internal fun dismissDialog() {
mutableState.update { mutableState.update {
it.copy(dialog = null) it.copy(dialog = null)
} }
@ -406,20 +398,17 @@ class BulkFavoriteScreenModel(
} }
} }
fun stopRunning() { internal fun stopRunning() {
mutableState.update { mutableState.update {
it.copy(isRunning = false) it.copy(isRunning = false)
} }
} }
interface Dialog { sealed interface Dialog {
data class Migrate(val newManga: Manga, val oldManga: Manga) : Dialog
data class AddDuplicateManga(val manga: Manga, val duplicates: List<Manga>) : Dialog data class AddDuplicateManga(val manga: Manga, val duplicates: List<Manga>) : Dialog
data class BulkAllowDuplicate(val manga: Manga, val duplicates: List<Manga>, val currentIdx: Int) : Dialog data class BulkAllowDuplicate(val manga: Manga, val duplicates: List<Manga>, val currentIdx: Int) : Dialog
data class RemoveManga(val manga: Manga) : Dialog data class RemoveManga(val manga: Manga) : Dialog
data class ChangeMangaCategory(
val manga: Manga,
val initialSelection: ImmutableList<CheckboxState.State<Category>>,
) : Dialog
data class ChangeMangasCategory( data class ChangeMangasCategory(
val mangas: List<Manga>, val mangas: List<Manga>,
val initialSelection: ImmutableList<CheckboxState<Category>>, val initialSelection: ImmutableList<CheckboxState<Category>>,
@ -434,158 +423,3 @@ class BulkFavoriteScreenModel(
val isRunning: Boolean = false, val isRunning: Boolean = false,
) )
} }
/**
* Compose to shows the bulk favorite dialogs.
*
* @param bulkFavoriteScreenModel the screen model.
* @param dialog the dialog to show.
*/
@Composable
fun BulkFavoriteDialogs(
bulkFavoriteScreenModel: BulkFavoriteScreenModel,
dialog: Dialog?,
) {
when (dialog) {
/* Bulk-favorite actions */
is Dialog.ChangeMangasCategory ->
ChangeMangasCategoryDialog(bulkFavoriteScreenModel)
is Dialog.BulkAllowDuplicate ->
BulkAllowDuplicateDialog(bulkFavoriteScreenModel)
/* Single-favorite actions for screens originally don't have it */
is Dialog.AddDuplicateManga ->
AddDuplicateMangaDialog(bulkFavoriteScreenModel)
is Dialog.RemoveManga ->
RemoveMangaDialog(bulkFavoriteScreenModel)
is Dialog.ChangeMangaCategory ->
ChangeMangaCategoryDialog(bulkFavoriteScreenModel)
}
}
/**
* Shows dialog to add a single manga to library when there are duplicates.
*
* @param bulkFavoriteScreenModel the screen model.
*/
@Composable
fun AddDuplicateMangaDialog(bulkFavoriteScreenModel: BulkFavoriteScreenModel) {
val navigator = LocalNavigator.currentOrThrow
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
val dialog = bulkFavoriteState.dialog as Dialog.AddDuplicateManga
bulkFavoriteScreenModel.stopRunning()
DuplicateMangaDialog(
duplicates = dialog.duplicates,
onDismissRequest = bulkFavoriteScreenModel::dismissDialog,
onConfirm = {
if (bulkFavoriteState.selectionMode) {
bulkFavoriteScreenModel.toggleSelectionMode()
}
bulkFavoriteScreenModel.addFavorite(dialog.manga)
},
onOpenManga = { navigator.push(MangaScreen(it.id)) },
onMigrate = {
PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(),
navigator,
it.id,
dialog.manga.id,
)
},
)
}
@Composable
fun RemoveMangaDialog(bulkFavoriteScreenModel: BulkFavoriteScreenModel) {
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
val dialog = bulkFavoriteState.dialog as Dialog.RemoveManga
RemoveMangaDialog(
onDismissRequest = bulkFavoriteScreenModel::dismissDialog,
onConfirm = {
bulkFavoriteScreenModel.changeMangaFavorite(dialog.manga)
},
mangaToRemove = dialog.manga,
)
}
@Composable
fun ChangeMangaCategoryDialog(bulkFavoriteScreenModel: BulkFavoriteScreenModel) {
val navigator = LocalNavigator.currentOrThrow
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
val dialog = bulkFavoriteState.dialog as Dialog.ChangeMangaCategory
ChangeCategoryDialog(
initialSelection = dialog.initialSelection,
onDismissRequest = bulkFavoriteScreenModel::dismissDialog,
onEditCategories = { navigator.push(CategoryScreen()) },
onConfirm = { include, _ ->
bulkFavoriteScreenModel.changeMangaFavorite(dialog.manga)
bulkFavoriteScreenModel.moveMangaToCategories(dialog.manga, include)
},
)
}
@Composable
fun ChangeMangasCategoryDialog(bulkFavoriteScreenModel: BulkFavoriteScreenModel) {
val navigator = LocalNavigator.currentOrThrow
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
val dialog = bulkFavoriteState.dialog as Dialog.ChangeMangasCategory
ChangeCategoryDialog(
initialSelection = dialog.initialSelection,
onDismissRequest = bulkFavoriteScreenModel::dismissDialog,
onEditCategories = { navigator.push(CategoryScreen()) },
onConfirm = { include, exclude ->
bulkFavoriteScreenModel.setMangasCategories(dialog.mangas, include, exclude)
},
)
}
/**
* Shows dialog to bulk allow/skip or migrate multiple manga to library when there are duplicates.
*
* @param bulkFavoriteScreenModel the screen model.
*/
@Composable
fun BulkAllowDuplicateDialog(bulkFavoriteScreenModel: BulkFavoriteScreenModel) {
val navigator = LocalNavigator.currentOrThrow
val bulkFavoriteState by bulkFavoriteScreenModel.state.collectAsState()
val dialog = bulkFavoriteState.dialog as Dialog.BulkAllowDuplicate
DuplicateMangaDialog(
duplicates = dialog.duplicates,
onDismissRequest = bulkFavoriteScreenModel::dismissDialog,
onConfirm = {
bulkFavoriteScreenModel.addFavorite(startIdx = dialog.currentIdx + 1)
},
onOpenManga = { navigator.push(MangaScreen(it.id)) },
onMigrate = { navigator.push(MangaScreen(it.id)) },
bulkFavoriteManga = dialog.manga,
onAllowAllDuplicate = bulkFavoriteScreenModel::addFavoriteDuplicate,
onSkipAllDuplicate = {
bulkFavoriteScreenModel.addFavoriteDuplicate(skipAllDuplicates = true)
},
onSkipDuplicate = {
bulkFavoriteScreenModel.removeDuplicateSelectedManga(index = dialog.currentIdx)
bulkFavoriteScreenModel.addFavorite(startIdx = dialog.currentIdx)
},
stopRunning = bulkFavoriteScreenModel::stopRunning,
)
}
@Composable
fun bulkSelectionButton(
isRunning: Boolean,
toggleSelectionMode: () -> Unit,
) = AppBar.Action(
title = stringResource(KMR.strings.action_bulk_select),
icon = Icons.Outlined.Checklist,
iconTint = MaterialTheme.colorScheme.primary.takeIf { isRunning },
onClick = toggleSelectionMode,
)

View file

@ -22,13 +22,13 @@ import eu.kanade.presentation.browse.FeedAddDialog
import eu.kanade.presentation.browse.FeedAddSearchDialog import eu.kanade.presentation.browse.FeedAddSearchDialog
import eu.kanade.presentation.browse.FeedOrderScreen import eu.kanade.presentation.browse.FeedOrderScreen
import eu.kanade.presentation.browse.FeedScreen import eu.kanade.presentation.browse.FeedScreen
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.browse.components.FeedActionsDialog import eu.kanade.presentation.browse.components.FeedActionsDialog
import eu.kanade.presentation.browse.components.SourceFeedDeleteDialog import eu.kanade.presentation.browse.components.SourceFeedDeleteDialog
import eu.kanade.presentation.browse.components.bulkSelectionButton
import eu.kanade.presentation.components.AppBar import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.TabContent import eu.kanade.presentation.components.TabContent
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.bulkSelectionButton
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen
import eu.kanade.tachiyomi.ui.home.HomeScreen import eu.kanade.tachiyomi.ui.home.HomeScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen

View file

@ -102,10 +102,7 @@ internal fun MigrateDialog(
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall), horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.extraSmall),
) { ) {
TextButton( TextButton(
onClick = { onClick = { onClickTitle() },
onDismissRequest()
onClickTitle()
},
) { ) {
Text(text = stringResource(MR.strings.action_show_manga)) Text(text = stringResource(MR.strings.action_show_manga))
} }

View file

@ -8,12 +8,15 @@ import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.browse.MigrateSearchScreen import eu.kanade.presentation.browse.MigrateSearchScreen
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen
/**
* Manual search [validSources] for manga to migrate to.
*/
class MigrateSearchScreen(private val mangaId: Long, private val validSources: List<Long>) : Screen() { class MigrateSearchScreen(private val mangaId: Long, private val validSources: List<Long>) : Screen() {
@Composable @Composable
@ -73,6 +76,7 @@ class MigrateSearchScreen(private val mangaId: Long, private val validSources: L
) )
// KMK --> // KMK -->
// Bulk-favorite actions only
BulkFavoriteDialogs( BulkFavoriteDialogs(
bulkFavoriteScreenModel = bulkFavoriteScreenModel, bulkFavoriteScreenModel = bulkFavoriteScreenModel,
dialog = bulkFavoriteState.dialog, dialog = bulkFavoriteState.dialog,

View file

@ -16,14 +16,14 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.core.util.ifSourcesLoaded import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.presentation.browse.BrowseSourceContent import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.components.BrowseSourceFloatingActionButton import eu.kanade.presentation.browse.components.BrowseSourceFloatingActionButton
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.browse.components.bulkSelectionButton
import eu.kanade.presentation.components.AppBarActions import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.BulkSelectionToolbar import eu.kanade.presentation.components.BulkSelectionToolbar
import eu.kanade.presentation.components.SearchToolbar import eu.kanade.presentation.components.SearchToolbar
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.bulkSelectionButton
import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen import eu.kanade.tachiyomi.ui.browse.migration.advanced.process.MigrationListScreen
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreenModel
import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterDialog import eu.kanade.tachiyomi.ui.browse.source.browse.SourceFilterDialog
@ -41,7 +41,7 @@ import tachiyomi.presentation.core.screens.LoadingScreen
import tachiyomi.source.local.LocalSource import tachiyomi.source.local.LocalSource
/** /**
* Opened when click on a source in [MigrateSearchScreen] * Opened when click on a source in [MigrateSearchScreen] while doing manual search for migration
*/ */
data class SourceSearchScreen( data class SourceSearchScreen(
private val oldManga: Manga, private val oldManga: Manga,
@ -212,6 +212,7 @@ data class SourceSearchScreen(
} }
// KMK --> // KMK -->
// Bulk-favorite actions only
BulkFavoriteDialogs( BulkFavoriteDialogs(
bulkFavoriteScreenModel = bulkFavoriteScreenModel, bulkFavoriteScreenModel = bulkFavoriteScreenModel,
dialog = bulkFavoriteState.dialog, dialog = bulkFavoriteState.dialog,

View file

@ -40,6 +40,7 @@ import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.presentation.browse.BrowseSourceContent import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.MissingSourceScreen import eu.kanade.presentation.browse.MissingSourceScreen
import eu.kanade.presentation.browse.components.BrowseSourceToolbar import eu.kanade.presentation.browse.components.BrowseSourceToolbar
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.browse.components.RemoveMangaDialog import eu.kanade.presentation.browse.components.RemoveMangaDialog
import eu.kanade.presentation.browse.components.SavedSearchCreateDialog import eu.kanade.presentation.browse.components.SavedSearchCreateDialog
import eu.kanade.presentation.browse.components.SavedSearchDeleteDialog import eu.kanade.presentation.browse.components.SavedSearchDeleteDialog
@ -52,7 +53,6 @@ import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialog import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialog
@ -463,9 +463,7 @@ data class BrowseSourceScreen(
screenModel = MigrateDialogScreenModel(), screenModel = MigrateDialogScreenModel(),
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) }, onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) },
onPopScreen = { onPopScreen = { onDismissRequest() },
onDismissRequest()
},
) )
} }
is BrowseSourceScreenModel.Dialog.RemoveManga -> { is BrowseSourceScreenModel.Dialog.RemoveManga -> {
@ -504,6 +502,7 @@ data class BrowseSourceScreen(
} }
// KMK --> // KMK -->
// Bulk-favorite actions only
BulkFavoriteDialogs( BulkFavoriteDialogs(
bulkFavoriteScreenModel = bulkFavoriteScreenModel, bulkFavoriteScreenModel = bulkFavoriteScreenModel,
dialog = bulkFavoriteState.dialog, dialog = bulkFavoriteState.dialog,

View file

@ -19,6 +19,7 @@ import eu.kanade.presentation.browse.MissingSourceScreen
import eu.kanade.presentation.browse.SourceFeedOrderScreen import eu.kanade.presentation.browse.SourceFeedOrderScreen
import eu.kanade.presentation.browse.SourceFeedScreen import eu.kanade.presentation.browse.SourceFeedScreen
import eu.kanade.presentation.browse.SourceFeedUI import eu.kanade.presentation.browse.SourceFeedUI
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.browse.components.FeedActionsDialog import eu.kanade.presentation.browse.components.FeedActionsDialog
import eu.kanade.presentation.browse.components.SourceFeedAddDialog import eu.kanade.presentation.browse.components.SourceFeedAddDialog
import eu.kanade.presentation.browse.components.SourceFeedDeleteDialog import eu.kanade.presentation.browse.components.SourceFeedDeleteDialog
@ -27,7 +28,6 @@ import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.source.ConfigurableSource import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen

View file

@ -14,8 +14,8 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.core.util.ifSourcesLoaded import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.presentation.browse.GlobalSearchScreen import eu.kanade.presentation.browse.GlobalSearchScreen
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen

View file

@ -141,7 +141,7 @@ data object HistoryTab : Tab {
screenModel = MigrateDialogScreenModel(), screenModel = MigrateDialogScreenModel(),
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) }, onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) },
onPopScreen = { navigator.replace(MangaScreen(dialog.newManga.id)) }, onPopScreen = { onDismissRequest() },
) )
} }
null -> {} null -> {}

View file

@ -44,6 +44,7 @@ import dev.chrisbanes.haze.hazeEffect
import eu.kanade.core.util.ifSourcesLoaded import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.domain.manga.model.hasCustomCover import eu.kanade.domain.manga.model.hasCustomCover
import eu.kanade.domain.manga.model.toSManga import eu.kanade.domain.manga.model.toSManga
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.category.components.ChangeCategoryDialog import eu.kanade.presentation.category.components.ChangeCategoryDialog
import eu.kanade.presentation.components.NavigatorAdaptiveSheet import eu.kanade.presentation.components.NavigatorAdaptiveSheet
import eu.kanade.presentation.manga.ChapterSettingsDialog import eu.kanade.presentation.manga.ChapterSettingsDialog
@ -63,7 +64,6 @@ import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.Source
import eu.kanade.tachiyomi.source.isLocalOrStub import eu.kanade.tachiyomi.source.isLocalOrStub
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsScreen import eu.kanade.tachiyomi.ui.browse.extension.ExtensionsScreen
import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen import eu.kanade.tachiyomi.ui.browse.extension.details.SourcePreferencesScreen
@ -470,7 +470,7 @@ class MangaScreen(
screenModel = MigrateDialogScreenModel(), screenModel = MigrateDialogScreenModel(),
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) }, onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) },
onPopScreen = { navigator.replace(MangaScreen(dialog.newManga.id)) }, onPopScreen = { onDismissRequest() },
) )
} }
MangaScreenModel.Dialog.SettingsSheet -> ChapterSettingsDialog( MangaScreenModel.Dialog.SettingsSheet -> ChapterSettingsDialog(

View file

@ -17,12 +17,12 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.core.util.ifSourcesLoaded import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.presentation.browse.BrowseSourceContent import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.browse.components.RemoveMangaDialog import eu.kanade.presentation.browse.components.RemoveMangaDialog
import eu.kanade.presentation.category.components.ChangeCategoryDialog import eu.kanade.presentation.category.components.ChangeCategoryDialog
import eu.kanade.presentation.components.BulkSelectionToolbar import eu.kanade.presentation.components.BulkSelectionToolbar
import eu.kanade.presentation.manga.DuplicateMangaDialog import eu.kanade.presentation.manga.DuplicateMangaDialog
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialog import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialog
import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialogScreenModel import eu.kanade.tachiyomi.ui.browse.migration.search.MigrateDialogScreenModel
@ -175,9 +175,7 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
screenModel = MigrateDialogScreenModel(), screenModel = MigrateDialogScreenModel(),
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) }, onClickTitle = { navigator.push(MangaScreen(dialog.oldManga.id)) },
onPopScreen = { onPopScreen = { onDismissRequest() },
onDismissRequest()
},
) )
} }
// KMK <-- // KMK <--
@ -207,6 +205,7 @@ class MangaDexFollowsScreen(private val sourceId: Long) : Screen() {
} }
// KMK --> // KMK -->
// Bulk-favorite actions only
BulkFavoriteDialogs( BulkFavoriteDialogs(
bulkFavoriteScreenModel = bulkFavoriteScreenModel, bulkFavoriteScreenModel = bulkFavoriteScreenModel,
dialog = bulkFavoriteState.dialog, dialog = bulkFavoriteState.dialog,

View file

@ -16,9 +16,9 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.core.util.ifSourcesLoaded import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.presentation.browse.BrowseSourceContent import eu.kanade.presentation.browse.BrowseSourceContent
import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar import eu.kanade.presentation.browse.components.BrowseSourceSimpleToolbar
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.components.BulkSelectionToolbar import eu.kanade.presentation.components.BulkSelectionToolbar
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen

View file

@ -10,8 +10,8 @@ import cafe.adriel.voyager.core.model.rememberScreenModel
import cafe.adriel.voyager.navigator.LocalNavigator import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.core.util.ifSourcesLoaded import eu.kanade.core.util.ifSourcesLoaded
import eu.kanade.presentation.browse.components.BulkFavoriteDialogs
import eu.kanade.presentation.util.Screen import eu.kanade.presentation.util.Screen
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteDialogs
import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel import eu.kanade.tachiyomi.ui.browse.BulkFavoriteScreenModel
import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen import eu.kanade.tachiyomi.ui.browse.source.SourcesScreen
import eu.kanade.tachiyomi.ui.manga.MangaScreen import eu.kanade.tachiyomi.ui.manga.MangaScreen