migrate to AppBar

This commit is contained in:
Cuong-Tran 2024-10-23 23:49:05 +07:00
parent d61ec31624
commit 8aa2eccfaa
No known key found for this signature in database
GPG Key ID: 733AA7624B9315C2

View File

@ -3,7 +3,6 @@ package eu.kanade.presentation.libraryUpdateError
import androidx.activity.compose.BackHandler import androidx.activity.compose.BackHandler
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateColorAsState import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.animateFloatAsState import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.expandVertically import androidx.compose.animation.expandVertically
import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeIn
@ -25,22 +24,17 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.ZeroCornerSize import androidx.compose.foundation.shape.ZeroCornerSize
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.outlined.ArrowDownward
import androidx.compose.material.icons.outlined.ArrowUpward
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.FindReplace import androidx.compose.material.icons.outlined.FindReplace
import androidx.compose.material.icons.outlined.FlipToBack import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material.icons.outlined.SelectAll 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 import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.TopAppBarScrollBehavior import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.material3.ripple import androidx.compose.material3.ripple
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -54,11 +48,12 @@ import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.AppBarTitle import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.libraryUpdateError.components.libraryUpdateErrorUiItems import eu.kanade.presentation.libraryUpdateError.components.libraryUpdateErrorUiItems
import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.ui.libraryUpdateError.LibraryUpdateErrorItem import eu.kanade.tachiyomi.ui.libraryUpdateError.LibraryUpdateErrorItem
import eu.kanade.tachiyomi.ui.libraryUpdateError.LibraryUpdateErrorScreenState import eu.kanade.tachiyomi.ui.libraryUpdateError.LibraryUpdateErrorScreenState
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
@ -107,7 +102,12 @@ fun LibraryUpdateErrorScreen(
MR.strings.label_library_update_errors, MR.strings.label_library_update_errors,
state.items.size, state.items.size,
), ),
actionModeCounter = state.selected.size, itemCnt = state.items.size,
navigateUp = navigateUp,
selectedCount = state.selected.size,
onClickUnselectAll = { onSelectAll(false) },
onClickSelectAll = { onSelectAll(true) },
onClickInvertSelection = onInvertSelection,
scrollBehavior = scrollBehavior, scrollBehavior = scrollBehavior,
) )
}, },
@ -115,14 +115,9 @@ fun LibraryUpdateErrorScreen(
LibraryUpdateErrorsBottomBar( LibraryUpdateErrorsBottomBar(
modifier = modifier, modifier = modifier,
selected = state.selected, selected = state.selected,
itemCount = state.items.size, onMultiMigrateClicked = onMultiMigrateClicked,
enableScrollToTop = enableScrollToTop, enableScrollToTop = enableScrollToTop,
enableScrollToBottom = enableScrollToBottom, enableScrollToBottom = enableScrollToBottom,
onMultiMigrateClicked = onMultiMigrateClicked,
onSelectAll = { onSelectAll(true) },
onInvertSelection = onInvertSelection,
onCancelActionMode = { onSelectAll(false) },
navigateUp = navigateUp,
scrollToTop = { scrollToTop = {
scope.launch { scope.launch {
listState.scrollToItem(0) listState.scrollToItem(0)
@ -165,35 +160,27 @@ fun LibraryUpdateErrorScreen(
private fun LibraryUpdateErrorsBottomBar( private fun LibraryUpdateErrorsBottomBar(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
selected: List<LibraryUpdateErrorItem>, selected: List<LibraryUpdateErrorItem>,
itemCount: Int, onMultiMigrateClicked: (() -> Unit),
enableScrollToTop: Boolean, enableScrollToTop: Boolean,
enableScrollToBottom: Boolean, enableScrollToBottom: Boolean,
onMultiMigrateClicked: (() -> Unit),
onSelectAll: () -> Unit,
onInvertSelection: () -> Unit,
onCancelActionMode: () -> Unit,
navigateUp: () -> Unit,
scrollToTop: () -> Unit, scrollToTop: () -> Unit,
scrollToBottom: () -> Unit, scrollToBottom: () -> Unit,
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val animatedElevation by animateDpAsState(if (selected.isNotEmpty()) 3.dp else 0.dp)
Surface( Surface(
modifier = modifier, modifier = modifier,
shape = MaterialTheme.shapes.large.copy( shape = MaterialTheme.shapes.large.copy(
bottomEnd = ZeroCornerSize, bottomEnd = ZeroCornerSize,
bottomStart = ZeroCornerSize, bottomStart = ZeroCornerSize,
), ),
color = MaterialTheme.colorScheme.surfaceColorAtElevation( color = MaterialTheme.colorScheme.surfaceContainerHigh,
elevation = animatedElevation,
),
) { ) {
val haptic = LocalHapticFeedback.current val haptic = LocalHapticFeedback.current
val confirm = remember { mutableStateListOf(false, false, false, false, false, false) } val confirm = remember { mutableStateListOf(false, false, false) }
var resetJob: Job? = remember { null } var resetJob: Job? = remember { null }
val onLongClickItem: (Int) -> Unit = { toConfirmIndex -> val onLongClickItem: (Int) -> Unit = { toConfirmIndex ->
haptic.performHapticFeedback(HapticFeedbackType.LongPress) haptic.performHapticFeedback(HapticFeedbackType.LongPress)
(0 until 6).forEach { i -> confirm[i] = i == toConfirmIndex } (0 until 3).forEach { i -> confirm[i] = i == toConfirmIndex }
resetJob?.cancel() resetJob?.cancel()
resetJob = scope.launch { resetJob = scope.launch {
delay(1.seconds) delay(1.seconds)
@ -209,54 +196,11 @@ private fun LibraryUpdateErrorsBottomBar(
) )
.padding(horizontal = 8.dp, vertical = 12.dp), .padding(horizontal = 8.dp, vertical = 12.dp),
) { ) {
if (selected.isNotEmpty()) {
Button(
title = stringResource(MR.strings.action_cancel),
icon = Icons.Outlined.Close,
toConfirm = confirm[0],
onLongClick = { onLongClickItem(0) },
onClick = onCancelActionMode,
enabled = true,
)
} else {
Button(
title = androidx.compose.ui.res.stringResource(R.string.abc_action_bar_up_description),
icon = Icons.AutoMirrored.Outlined.ArrowBack,
toConfirm = confirm[0],
onLongClick = { onLongClickItem(0) },
onClick = navigateUp,
enabled = true,
)
}
Button(
title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll,
toConfirm = confirm[1],
onLongClick = { onLongClickItem(1) },
onClick = if (selected.isEmpty() or (selected.size != itemCount)) {
onSelectAll
} else {
{}
},
enabled = selected.isEmpty() or (selected.size != itemCount),
)
Button(
title = stringResource(MR.strings.action_select_inverse),
icon = Icons.Outlined.FlipToBack,
toConfirm = confirm[2],
onLongClick = { onLongClickItem(2) },
onClick = if (selected.isNotEmpty()) {
onInvertSelection
} else {
{}
},
enabled = selected.isNotEmpty(),
)
Button( Button(
title = stringResource(MR.strings.action_scroll_to_top), title = stringResource(MR.strings.action_scroll_to_top),
icon = Icons.Outlined.ArrowUpward, icon = Icons.Outlined.VerticalAlignTop,
toConfirm = confirm[3], toConfirm = confirm[0],
onLongClick = { onLongClickItem(3) }, onLongClick = { onLongClickItem(0) },
onClick = if (enableScrollToTop) { onClick = if (enableScrollToTop) {
scrollToTop scrollToTop
} else { } else {
@ -264,23 +208,11 @@ private fun LibraryUpdateErrorsBottomBar(
}, },
enabled = enableScrollToTop, enabled = enableScrollToTop,
) )
Button(
title = stringResource(MR.strings.action_scroll_to_bottom),
icon = Icons.Outlined.ArrowDownward,
toConfirm = confirm[4],
onLongClick = { onLongClickItem(4) },
onClick = if (enableScrollToBottom) {
scrollToBottom
} else {
{}
},
enabled = enableScrollToBottom,
)
Button( Button(
title = stringResource(MR.strings.migrate), title = stringResource(MR.strings.migrate),
icon = Icons.Outlined.FindReplace, icon = Icons.Outlined.FindReplace,
toConfirm = confirm[5], toConfirm = confirm[1],
onLongClick = { onLongClickItem(5) }, onLongClick = { onLongClickItem(1) },
onClick = if (selected.isNotEmpty()) { onClick = if (selected.isNotEmpty()) {
onMultiMigrateClicked onMultiMigrateClicked
} else { } else {
@ -288,6 +220,18 @@ private fun LibraryUpdateErrorsBottomBar(
}, },
enabled = selected.isNotEmpty(), enabled = selected.isNotEmpty(),
) )
Button(
title = stringResource(MR.strings.action_scroll_to_bottom),
icon = Icons.Outlined.VerticalAlignBottom,
toConfirm = confirm[2],
onLongClick = { onLongClickItem(2) },
onClick = if (enableScrollToBottom) {
scrollToBottom
} else {
{}
},
enabled = enableScrollToBottom,
)
} }
} }
} }
@ -349,33 +293,49 @@ private fun RowScope.Button(
@Composable @Composable
private fun LibraryUpdateErrorsAppBar( private fun LibraryUpdateErrorsAppBar(
modifier: Modifier = Modifier,
title: String, title: String,
actionModeCounter: Int, itemCnt: Int,
navigateUp: () -> Unit,
selectedCount: Int,
onClickUnselectAll: () -> Unit,
onClickSelectAll: () -> Unit,
onClickInvertSelection: () -> Unit,
scrollBehavior: TopAppBarScrollBehavior, scrollBehavior: TopAppBarScrollBehavior,
) { ) {
val isActionMode by remember(actionModeCounter) { AppBar(
derivedStateOf { actionModeCounter > 0 } title = title,
} navigateUp = navigateUp,
actions = {
Column( if (itemCnt > 0) {
modifier = modifier, AppBarActions(
) { persistentListOf(
TopAppBar( AppBar.Action(
title = { title = stringResource(MR.strings.action_select_all),
if (isActionMode) { icon = Icons.Outlined.SelectAll,
AppBarTitle("$actionModeCounter selected") onClick = onClickSelectAll,
} else { ),
AppBarTitle(title) ),
} )
}, }
actions = {}, },
colors = TopAppBarDefaults.topAppBarColors( actionModeCounter = selectedCount,
containerColor = MaterialTheme.colorScheme.surfaceColorAtElevation( onCancelActionMode = onClickUnselectAll,
elevation = if (isActionMode) 3.dp else 0.dp, 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, },
) scrollBehavior = scrollBehavior,
} )
} }