fix migration

This commit is contained in:
Cuong-Tran 2024-10-25 15:48:45 +07:00
parent f1310ba879
commit 2979caa676
No known key found for this signature in database
GPG Key ID: 733AA7624B9315C2
5 changed files with 13 additions and 230 deletions

View File

@ -1,6 +1,5 @@
package eu.kanade.presentation.libraryUpdateError
import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.animateFloatAsState
@ -26,9 +25,6 @@ import androidx.compose.foundation.shape.ZeroCornerSize
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDownward
import androidx.compose.material.icons.outlined.ArrowUpward
import androidx.compose.material.icons.outlined.FindReplace
import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material.icons.outlined.SelectAll
import androidx.compose.material.icons.outlined.VerticalAlignBottom
import androidx.compose.material.icons.outlined.VerticalAlignTop
import androidx.compose.material3.Icon
@ -53,11 +49,9 @@ import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.libraryUpdateError.components.libraryUpdateErrorUiItems
import eu.kanade.tachiyomi.ui.libraryUpdateError.LibraryUpdateErrorItem
import eu.kanade.tachiyomi.ui.libraryUpdateError.LibraryUpdateErrorScreenState
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
@ -76,10 +70,6 @@ fun LibraryUpdateErrorScreen(
modifier: Modifier = Modifier,
onClick: (LibraryUpdateErrorItem) -> Unit,
onClickCover: (LibraryUpdateErrorItem) -> Unit,
onMultiMigrateClicked: (() -> Unit),
onSelectAll: (Boolean) -> Unit,
onInvertSelection: () -> Unit,
onErrorSelected: (LibraryUpdateErrorItem, Boolean, Boolean, Boolean) -> Unit,
navigateUp: () -> Unit,
) {
val listState = rememberLazyListState()
@ -112,8 +102,6 @@ fun LibraryUpdateErrorScreen(
}
}
BackHandler(enabled = state.selectionMode, onBack = { onSelectAll(false) })
Scaffold(
topBar = { scrollBehavior ->
LibraryUpdateErrorsAppBar(
@ -121,20 +109,13 @@ fun LibraryUpdateErrorScreen(
MR.strings.label_library_update_errors,
state.items.size,
),
itemCnt = state.items.size,
navigateUp = navigateUp,
selectedCount = state.selected.size,
onClickUnselectAll = { onSelectAll(false) },
onClickSelectAll = { onSelectAll(true) },
onClickInvertSelection = onInvertSelection,
scrollBehavior = scrollBehavior,
)
},
bottomBar = {
LibraryUpdateErrorsBottomBar(
modifier = modifier,
selected = state.selected,
onMultiMigrateClicked = onMultiMigrateClicked,
enableScrollToTop = enableScrollToTop,
enableScrollToBottom = enableScrollToBottom,
scrollToTop = {
@ -185,8 +166,6 @@ fun LibraryUpdateErrorScreen(
) {
libraryUpdateErrorUiItems(
uiModels = state.getUiModel(),
selectionMode = state.selectionMode,
onErrorSelected = onErrorSelected,
onClick = onClick,
onClickCover = onClickCover,
)
@ -199,8 +178,6 @@ fun LibraryUpdateErrorScreen(
@Composable
private fun LibraryUpdateErrorsBottomBar(
modifier: Modifier = Modifier,
selected: List<LibraryUpdateErrorItem>,
onMultiMigrateClicked: (() -> Unit),
enableScrollToTop: Boolean,
enableScrollToBottom: Boolean,
scrollToTop: () -> Unit,
@ -220,11 +197,11 @@ private fun LibraryUpdateErrorsBottomBar(
color = MaterialTheme.colorScheme.surfaceContainerHigh,
) {
val haptic = LocalHapticFeedback.current
val confirm = remember { mutableStateListOf(false, false, false, false, false) }
val confirm = remember { mutableStateListOf(false, false, false, false) }
var resetJob: Job? = remember { null }
val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
(0 until 5).forEach { i -> confirm[i] = i == toConfirmIndex }
(0 until 4).forEach { i -> confirm[i] = i == toConfirmIndex }
resetJob?.cancel()
resetJob = scope.launch {
delay(1.seconds)
@ -264,23 +241,11 @@ private fun LibraryUpdateErrorsBottomBar(
},
enabled = enableScrollToPrevious,
)
Button(
title = stringResource(MR.strings.migrate),
icon = Icons.Outlined.FindReplace,
toConfirm = confirm[2],
onLongClick = { onLongClickItem(2) },
onClick = if (selected.isNotEmpty()) {
onMultiMigrateClicked
} else {
{}
},
enabled = selected.isNotEmpty(),
)
Button(
title = stringResource(MR.strings.action_scroll_to_next),
icon = Icons.Outlined.ArrowDownward,
toConfirm = confirm[3],
onLongClick = { onLongClickItem(3) },
toConfirm = confirm[2],
onLongClick = { onLongClickItem(2) },
onClick = if (enableScrollToNext) {
scrollToNext
} else {
@ -291,8 +256,8 @@ private fun LibraryUpdateErrorsBottomBar(
Button(
title = stringResource(MR.strings.action_scroll_to_bottom),
icon = Icons.Outlined.VerticalAlignBottom,
toConfirm = confirm[4],
onLongClick = { onLongClickItem(4) },
toConfirm = confirm[3],
onLongClick = { onLongClickItem(3) },
onClick = if (enableScrollToBottom) {
scrollToBottom
} else {
@ -362,48 +327,12 @@ private fun RowScope.Button(
@Composable
private fun LibraryUpdateErrorsAppBar(
title: String,
itemCnt: Int,
navigateUp: () -> Unit,
selectedCount: Int,
onClickUnselectAll: () -> Unit,
onClickSelectAll: () -> Unit,
onClickInvertSelection: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior,
) {
AppBar(
title = title,
navigateUp = navigateUp,
actions = {
if (itemCnt > 0) {
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll,
onClick = onClickSelectAll,
),
),
)
}
},
actionModeCounter = selectedCount,
onCancelActionMode = onClickUnselectAll,
actionModeActions = {
AppBarActions(
persistentListOf(
AppBar.Action(
title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll,
onClick = onClickSelectAll,
),
AppBar.Action(
title = stringResource(MR.strings.action_select_inverse),
icon = Icons.Outlined.FlipToBack,
onClick = onClickInvertSelection,
),
),
)
},
scrollBehavior = scrollBehavior,
)
}

View File

@ -11,8 +11,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import eu.kanade.presentation.manga.components.MangaCover
@ -24,14 +22,11 @@ import tachiyomi.presentation.core.components.ListGroupHeader
import tachiyomi.presentation.core.components.Scroller.STICKY_HEADER_KEY_PREFIX
import tachiyomi.presentation.core.components.material.padding
import tachiyomi.presentation.core.util.secondaryItemAlpha
import tachiyomi.presentation.core.util.selectedBackground
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
internal fun LazyListScope.libraryUpdateErrorUiItems(
uiModels: List<LibraryUpdateErrorUiModel>,
selectionMode: Boolean,
onErrorSelected: (LibraryUpdateErrorItem, Boolean, Boolean, Boolean) -> Unit,
onClick: (LibraryUpdateErrorItem) -> Unit,
onClickCover: (LibraryUpdateErrorItem) -> Unit,
) {
@ -57,28 +52,10 @@ internal fun LazyListScope.libraryUpdateErrorUiItems(
LibraryUpdateErrorUiItem(
modifier = Modifier.animateItemFastScroll(),
error = libraryUpdateErrorItem.error,
selected = libraryUpdateErrorItem.selected,
onClick = {
when {
selectionMode -> onErrorSelected(
libraryUpdateErrorItem,
!libraryUpdateErrorItem.selected,
true,
false,
)
else -> onClick(libraryUpdateErrorItem)
}
onClick(libraryUpdateErrorItem)
},
onLongClick = {
onErrorSelected(
libraryUpdateErrorItem,
!libraryUpdateErrorItem.selected,
true,
true,
)
},
onClickCover = { onClickCover(libraryUpdateErrorItem) }.takeIf { !selectionMode },
onClickCover = { onClickCover(libraryUpdateErrorItem) },
)
}
}
@ -90,22 +67,13 @@ internal fun LazyListScope.libraryUpdateErrorUiItems(
private fun LibraryUpdateErrorUiItem(
modifier: Modifier,
error: LibraryUpdateErrorWithRelations,
selected: Boolean,
onClick: () -> Unit,
onLongClick: () -> Unit,
onClickCover: (() -> Unit)?,
) {
val haptic = LocalHapticFeedback.current
Row(
modifier = modifier
.selectedBackground(selected)
.combinedClickable(
onClick = onClick,
onLongClick = {
onLongClick()
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
},
)
.padding(horizontal = MaterialTheme.padding.medium),
verticalAlignment = Alignment.Top,

View File

@ -8,11 +8,8 @@ import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
import eu.kanade.presentation.libraryUpdateError.LibraryUpdateErrorScreen
import eu.kanade.presentation.util.Screen
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
import tachiyomi.domain.UnsortedPreferences
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
class LibraryUpdateErrorScreen : Screen() {
@ -25,23 +22,9 @@ class LibraryUpdateErrorScreen : Screen() {
LibraryUpdateErrorScreen(
state = state,
onClick = { item ->
PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(),
navigator,
listOf(item.error.mangaId),
)
navigator.push(MigrateSearchScreen(item.error.mangaId))
},
onClickCover = { item -> navigator.push(MangaScreen(item.error.mangaId)) },
onMultiMigrateClicked = {
PreMigrationScreen.navigateToMigration(
Injekt.get<UnsortedPreferences>().skipPreMigration().get(),
navigator,
state.selected.map { it.error.mangaId },
)
},
onSelectAll = screenModel::toggleAllSelection,
onInvertSelection = screenModel::invertSelection,
onErrorSelected = screenModel::toggleSelection,
navigateUp = navigator::pop,
)
}

View File

@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.ui.libraryUpdateError
import androidx.compose.runtime.Immutable
import cafe.adriel.voyager.core.model.StateScreenModel
import cafe.adriel.voyager.core.model.screenModelScope
import eu.kanade.core.util.addOrRemove
import eu.kanade.presentation.libraryUpdateError.components.LibraryUpdateErrorUiModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
@ -20,10 +19,6 @@ class LibraryUpdateErrorScreenModel(
private val getLibraryUpdateErrorMessages: GetLibraryUpdateErrorMessages = Injekt.get(),
) : StateScreenModel<LibraryUpdateErrorScreenState>(LibraryUpdateErrorScreenState()) {
// First and last selected index in list
private val selectedPositions: Array<Int> = arrayOf(-1, -1)
private val selectedErrorIds: HashSet<Long> = HashSet()
init {
screenModelScope.launchIO {
getLibraryUpdateErrorWithRelations.subscribeAll()
@ -44,99 +39,9 @@ class LibraryUpdateErrorScreenModel(
return errors.map { error ->
LibraryUpdateErrorItem(
error = error,
selected = error.errorId in selectedErrorIds,
)
}
}
fun toggleSelection(
item: LibraryUpdateErrorItem,
selected: Boolean,
userSelected: Boolean = false,
fromLongPress: Boolean = false,
) {
mutableState.update { state ->
val newItems = state.items.toMutableList().apply {
val selectedIndex = indexOfFirst { it.error.errorId == item.error.errorId }
if (selectedIndex < 0) return@apply
val selectedItem = get(selectedIndex)
if (selectedItem.selected == selected) return@apply
val firstSelection = none { it.selected }
set(selectedIndex, selectedItem.copy(selected = selected))
selectedErrorIds.addOrRemove(item.error.errorId, selected)
if (selected && userSelected && fromLongPress) {
if (firstSelection) {
selectedPositions[0] = selectedIndex
selectedPositions[1] = selectedIndex
} else {
// Try to select the items in-between when possible
val range: IntRange
if (selectedIndex < selectedPositions[0]) {
range = selectedIndex + 1 until selectedPositions[0]
selectedPositions[0] = selectedIndex
} else if (selectedIndex > selectedPositions[1]) {
range = (selectedPositions[1] + 1) until selectedIndex
selectedPositions[1] = selectedIndex
} else {
// Just select itself
range = IntRange.EMPTY
}
range.forEach {
val inbetweenItem = get(it)
if (!inbetweenItem.selected) {
selectedErrorIds.add(inbetweenItem.error.errorId)
set(it, inbetweenItem.copy(selected = true))
}
}
}
} else if (userSelected && !fromLongPress) {
if (!selected) {
if (selectedIndex == selectedPositions[0]) {
selectedPositions[0] = indexOfFirst { it.selected }
} else if (selectedIndex == selectedPositions[1]) {
selectedPositions[1] = indexOfLast { it.selected }
}
} else {
if (selectedIndex < selectedPositions[0]) {
selectedPositions[0] = selectedIndex
} else if (selectedIndex > selectedPositions[1]) {
selectedPositions[1] = selectedIndex
}
}
}
}
state.copy(items = newItems)
}
}
fun toggleAllSelection(selected: Boolean) {
mutableState.update { state ->
val newItems = state.items.map {
selectedErrorIds.addOrRemove(it.error.errorId, selected)
it.copy(selected = selected)
}
state.copy(items = newItems)
}
selectedPositions[0] = -1
selectedPositions[1] = -1
}
fun invertSelection() {
mutableState.update { state ->
val newItems = state.items.map {
selectedErrorIds.addOrRemove(it.error.errorId, !it.selected)
it.copy(selected = !it.selected)
}
state.copy(items = newItems)
}
selectedPositions[0] = -1
selectedPositions[1] = -1
}
}
@Immutable
@ -146,9 +51,6 @@ data class LibraryUpdateErrorScreenState(
val messages: List<LibraryUpdateErrorMessage> = emptyList(),
) {
val selected = items.filter { it.selected }
val selectionMode = selected.isNotEmpty()
fun getUiModel(): List<LibraryUpdateErrorUiModel> {
val uiModels = mutableListOf<LibraryUpdateErrorUiModel>()
val errorMap = items.groupBy { it.error.messageId }
@ -169,5 +71,4 @@ data class LibraryUpdateErrorScreenState(
@Immutable
data class LibraryUpdateErrorItem(
val error: LibraryUpdateErrorWithRelations,
val selected: Boolean,
)

View File

@ -36,7 +36,9 @@ class LibraryUpdateErrorMessageRepositoryImpl(
}
}
override suspend fun insertAll(libraryUpdateErrorMessages: List<LibraryUpdateErrorMessage>): List<Pair<Long, String>> {
override suspend fun insertAll(
libraryUpdateErrorMessages: List<LibraryUpdateErrorMessage>,
): List<Pair<Long, String>> {
return handler.await(inTransaction = true) {
libraryUpdateErrorMessages.map {
libraryUpdateErrorMessageQueries.insert(it.message)