Reuse AppBar in manga screen (mihonapp/mihon#1367)

Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
(cherry picked from commit 2cd52d5a1ff48b0f9cf17245c1bfa66f99b8c187)
This commit is contained in:
Cuong-Tran 2025-02-25 04:33:47 +07:00
parent 42748f310f
commit ccebe08d00
No known key found for this signature in database
GPG key ID: 733AA7624B9315C2
4 changed files with 197 additions and 198 deletions

View file

@ -4,6 +4,7 @@ import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
@ -12,6 +13,7 @@ import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material.icons.outlined.Search
@ -128,6 +130,10 @@ fun AppBar(
isActionMode: Boolean = false,
onCancelActionMode: () -> Unit = {},
// KMK -->
goHome: (() -> Boolean?)? = null,
// KMK <--
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
Column(
@ -143,10 +149,21 @@ fun AppBar(
)
}
} else {
navigateUp?.let {
IconButton(onClick = it) {
UpIcon(navigationIcon = navigationIcon)
// KMK -->
Row {
// KMK <--
navigateUp?.let {
IconButton(onClick = it) {
UpIcon(navigationIcon = navigationIcon)
}
}
// KMK -->
goHome?.let {
IconButton(onClick = { it.invoke() }) {
UpIcon(navigationIcon = Icons.Filled.Home)
}
}
// KMK <--
}
}
},

View file

@ -145,7 +145,7 @@ fun MangaScreen(
isTabletUi: Boolean,
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onBackClicked: () -> Unit,
navigateUp: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?,
onAddToLibraryClicked: () -> Unit,
@ -223,7 +223,7 @@ fun MangaScreen(
nextUpdate = nextUpdate,
chapterSwipeStartAction = chapterSwipeStartAction,
chapterSwipeEndAction = chapterSwipeEndAction,
onBackClicked = onBackClicked,
navigateUp = navigateUp,
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
onAddToLibraryClicked = onAddToLibraryClicked,
@ -281,7 +281,7 @@ fun MangaScreen(
chapterSwipeStartAction = chapterSwipeStartAction,
chapterSwipeEndAction = chapterSwipeEndAction,
nextUpdate = nextUpdate,
onBackClicked = onBackClicked,
navigateUp = navigateUp,
onChapterClicked = onChapterClicked,
onDownloadChapter = onDownloadChapter,
onAddToLibraryClicked = onAddToLibraryClicked,
@ -342,7 +342,7 @@ private fun MangaScreenSmallImpl(
nextUpdate: Instant?,
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onBackClicked: () -> Unit,
navigateUp: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?,
onAddToLibraryClicked: () -> Unit,
@ -436,14 +436,13 @@ private fun MangaScreenSmallImpl(
val readButtonPosition = uiPreferences.readButtonPosition()
// KMK <--
val internalOnBackPressed = {
BackHandler(onBack = {
if (isAnySelected) {
onAllChapterSelected(false)
} else {
onBackClicked()
navigateUp()
}
}
BackHandler(onBack = internalOnBackPressed)
})
Scaffold(
topBar = {
@ -456,20 +455,18 @@ private fun MangaScreenSmallImpl(
val isFirstItemScrolled by remember {
derivedStateOf { chapterListState.firstVisibleItemScrollOffset > 0 }
}
val animatedTitleAlpha by animateFloatAsState(
val titleAlpha by animateFloatAsState(
if (!isFirstItemVisible) 1f else 0f,
label = "Top Bar Title",
)
val animatedBgAlpha by animateFloatAsState(
val backgroundAlpha by animateFloatAsState(
if (!isFirstItemVisible || isFirstItemScrolled) 1f else 0f,
label = "Top Bar Background",
)
MangaToolbar(
title = state.manga.title,
titleAlphaProvider = { animatedTitleAlpha },
backgroundAlphaProvider = { animatedBgAlpha },
hasFilters = state.filterActive,
onBackClicked = internalOnBackPressed,
navigateUp = navigateUp,
onClickFilter = onFilterClicked,
onClickShare = onShareClicked,
onClickDownload = onDownloadActionClicked,
@ -490,8 +487,11 @@ private fun MangaScreenSmallImpl(
onClickMerge = onMergeClicked.takeIf { state.showMergeInOverflow },
// SY <--
actionModeCounter = selectedChapterCount,
onCancelActionMode = { onAllChapterSelected(false) },
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
titleAlphaProvider = { titleAlpha },
backgroundAlphaProvider = { backgroundAlpha },
// KMK -->
onPaletteScreenClick = onPaletteScreenClick,
// KMK <--
@ -797,7 +797,7 @@ private fun MangaScreenLargeImpl(
nextUpdate: Instant?,
chapterSwipeStartAction: LibraryPreferences.ChapterSwipeAction,
chapterSwipeEndAction: LibraryPreferences.ChapterSwipeAction,
onBackClicked: () -> Unit,
navigateUp: () -> Unit,
onChapterClicked: (Chapter) -> Unit,
onDownloadChapter: ((List<ChapterList.Item>, ChapterDownloadAction) -> Unit)?,
onAddToLibraryClicked: () -> Unit,
@ -895,14 +895,13 @@ private fun MangaScreenLargeImpl(
val chapterListState = rememberLazyListState()
val internalOnBackPressed = {
BackHandler(onBack = {
if (isAnySelected) {
onAllChapterSelected(false)
} else {
onBackClicked()
navigateUp()
}
}
BackHandler(onBack = internalOnBackPressed)
})
Scaffold(
topBar = {
@ -912,16 +911,15 @@ private fun MangaScreenLargeImpl(
MangaToolbar(
modifier = Modifier.onSizeChanged { topBarHeight = it.height },
title = state.manga.title,
titleAlphaProvider = { if (isAnySelected) 1f else 0f },
backgroundAlphaProvider = { 1f },
hasFilters = state.filterActive,
onBackClicked = internalOnBackPressed,
navigateUp = navigateUp,
onClickFilter = onFilterButtonClicked,
onClickShare = onShareClicked,
onClickDownload = onDownloadActionClicked,
onClickEditCategory = onEditCategoryClicked,
onClickRefresh = onRefresh,
onClickMigrate = onMigrateClicked,
onCancelActionMode = { onAllChapterSelected(false) },
// SY -->
onClickEditInfo = onEditInfoClicked.takeIf { state.manga.favorite },
// KMK -->
@ -938,6 +936,8 @@ private fun MangaScreenLargeImpl(
actionModeCounter = selectedChapterCount,
onSelectAll = { onAllChapterSelected(true) },
onInvertSelection = { onInvertSelection() },
titleAlphaProvider = { 1f },
backgroundAlphaProvider = { 1f },
// KMK -->
onPaletteScreenClick = onPaletteScreenClick,
// KMK <--

View file

@ -1,20 +1,12 @@
package eu.kanade.presentation.manga.components
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.outlined.Close
import androidx.compose.material.icons.outlined.Download
import androidx.compose.material.icons.outlined.FilterList
import androidx.compose.material.icons.outlined.FlipToBack
import androidx.compose.material.icons.outlined.SelectAll
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -22,14 +14,14 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.unit.dp
import cafe.adriel.voyager.navigator.LocalNavigator
import eu.kanade.domain.ui.UiPreferences
import eu.kanade.presentation.components.AppBar
import eu.kanade.presentation.components.AppBarActions
import eu.kanade.presentation.components.AppBarTitle
import eu.kanade.presentation.components.DownloadDropdownMenu
import eu.kanade.presentation.components.UpIcon
import eu.kanade.presentation.manga.DownloadAction
import eu.kanade.tachiyomi.ui.browse.source.browse.BrowseSourceScreen
import eu.kanade.tachiyomi.ui.browse.source.feed.SourceFeedScreen
@ -47,9 +39,8 @@ import uy.kohesive.injekt.api.get
@Composable
fun MangaToolbar(
title: String,
titleAlphaProvider: () -> Float,
hasFilters: Boolean,
onBackClicked: () -> Unit,
navigateUp: () -> Unit,
onClickFilter: () -> Unit,
onClickShare: (() -> Unit)?,
onClickDownload: ((DownloadAction) -> Unit)?,
@ -68,14 +59,16 @@ fun MangaToolbar(
// For action mode
actionModeCounter: Int,
onCancelActionMode: () -> Unit,
onSelectAll: () -> Unit,
onInvertSelection: () -> Unit,
modifier: Modifier = Modifier,
backgroundAlphaProvider: () -> Float = titleAlphaProvider,
titleAlphaProvider: () -> Float,
backgroundAlphaProvider: () -> Float,
// KMK -->
onPaletteScreenClick: () -> Unit,
// KMK <--
modifier: Modifier = Modifier,
) {
// KMK -->
val navigator = LocalNavigator.current
@ -84,180 +77,169 @@ fun MangaToolbar(
}
val isHomeEnabled = Injekt.get<UiPreferences>().showHomeOnRelatedMangas().get()
// KMK <--
Column(
val isActionMode = actionModeCounter > 0
AppBar(
titleContent = {
if (isActionMode) {
AppBarTitle(actionModeCounter.toString())
} else {
AppBarTitle(title, modifier = Modifier.alpha(titleAlphaProvider()))
}
},
modifier = modifier,
) {
val isActionMode = actionModeCounter > 0
TopAppBar(
title = {
Text(
text = if (isActionMode) actionModeCounter.toString() else title,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
color = LocalContentColor.current.copy(alpha = if (isActionMode) 1f else titleAlphaProvider()),
backgroundColor = MaterialTheme.colorScheme
.surfaceColorAtElevation(3.dp)
.copy(alpha = if (isActionMode) 1f else backgroundAlphaProvider()),
// KMK -->
goHome = { onHomeClicked() }.takeIf {
isHomeEnabled &&
navigator != null &&
(
navigator.size >= 2 &&
navigator.items[navigator.size - 2] is MangaScreen ||
navigator.size >= 5
)
},
// KMK <--
navigateUp = navigateUp,
actions = {
var downloadExpanded by remember { mutableStateOf(false) }
if (onClickDownload != null) {
val onDismissRequest = { downloadExpanded = false }
DownloadDropdownMenu(
expanded = downloadExpanded,
onDismissRequest = onDismissRequest,
onDownloadClicked = onClickDownload,
)
},
navigationIcon = {
Row {
IconButton(onClick = onBackClicked) {
UpIcon(navigationIcon = Icons.Outlined.Close.takeIf { isActionMode })
}
// KMK -->
if (isHomeEnabled && navigator != null) {
if (navigator.size >= 2 &&
navigator.items[navigator.size - 2] is MangaScreen ||
navigator.size >= 5
) {
IconButton(onClick = { onHomeClicked() }) {
UpIcon(navigationIcon = Icons.Filled.Home)
}
}
}
// KMK <--
}
},
actions = {
if (isActionMode) {
AppBarActions(
persistentListOf(
}
val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current
AppBarActions(
actions = persistentListOf<AppBar.AppBarAction>().builder().apply {
if (isActionMode) {
add(
AppBar.Action(
title = stringResource(MR.strings.action_select_all),
icon = Icons.Outlined.SelectAll,
onClick = onSelectAll,
),
)
add(
AppBar.Action(
title = stringResource(MR.strings.action_select_inverse),
icon = Icons.Outlined.FlipToBack,
onClick = onInvertSelection,
),
),
)
} else {
var downloadExpanded by remember { mutableStateOf(false) }
)
return@apply
}
if (onClickDownload != null) {
val onDismissRequest = { downloadExpanded = false }
DownloadDropdownMenu(
expanded = downloadExpanded,
onDismissRequest = onDismissRequest,
onDownloadClicked = onClickDownload,
add(
AppBar.Action(
title = stringResource(MR.strings.manga_download),
icon = Icons.Outlined.Download,
onClick = { downloadExpanded = !downloadExpanded },
),
)
}
val filterTint = if (hasFilters) MaterialTheme.colorScheme.active else LocalContentColor.current
AppBarActions(
actions = persistentListOf<AppBar.AppBarAction>().builder()
.apply {
if (onClickDownload != null) {
add(
AppBar.Action(
title = stringResource(MR.strings.manga_download),
icon = Icons.Outlined.Download,
onClick = { downloadExpanded = !downloadExpanded },
),
)
}
add(
AppBar.Action(
title = stringResource(MR.strings.action_filter),
icon = Icons.Outlined.FilterList,
iconTint = filterTint,
onClick = onClickFilter,
),
)
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_webview_refresh),
onClick = onClickRefresh,
),
)
if (onClickEditCategory != null) {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_edit_categories),
onClick = onClickEditCategory,
),
)
}
if (onClickMigrate != null) {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_migrate),
onClick = onClickMigrate,
),
)
}
if (onClickShare != null) {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_share),
onClick = onClickShare,
),
)
}
// SY -->
if (onClickMerge != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.merge),
onClick = onClickMerge,
),
)
}
if (onClickEditInfo != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.action_edit_info),
onClick = onClickEditInfo,
),
)
}
// KMK -->
if (onClickRelatedMangas != null) {
add(
AppBar.OverflowAction(
title = stringResource(KMR.strings.pref_source_related_mangas),
onClick = onClickRelatedMangas,
),
)
}
// KMK <--
if (onClickRecommend != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.az_recommends),
onClick = onClickRecommend,
),
)
}
if (onClickMergedSettings != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.merge_settings),
onClick = onClickMergedSettings,
),
)
}
// SY <--
// KMK -->
if (isDevFlavor) {
add(
AppBar.OverflowAction(
title = "Colors Palette",
onClick = onPaletteScreenClick,
),
)
}
// KMK <--
}
.build(),
add(
AppBar.Action(
title = stringResource(MR.strings.action_filter),
icon = Icons.Outlined.FilterList,
iconTint = filterTint,
onClick = onClickFilter,
),
)
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_webview_refresh),
onClick = onClickRefresh,
),
)
if (onClickEditCategory != null) {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_edit_categories),
onClick = onClickEditCategory,
),
)
}
if (onClickMigrate != null) {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_migrate),
onClick = onClickMigrate,
),
)
}
if (onClickShare != null) {
add(
AppBar.OverflowAction(
title = stringResource(MR.strings.action_share),
onClick = onClickShare,
),
)
}
// SY -->
if (onClickMerge != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.merge),
onClick = onClickMerge,
),
)
}
if (onClickEditInfo != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.action_edit_info),
onClick = onClickEditInfo,
),
)
}
// KMK -->
if (onClickRelatedMangas != null) {
add(
AppBar.OverflowAction(
title = stringResource(KMR.strings.pref_source_related_mangas),
onClick = onClickRelatedMangas,
),
)
}
// KMK <--
if (onClickRecommend != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.az_recommends),
onClick = onClickRecommend,
),
)
}
if (onClickMergedSettings != null) {
add(
AppBar.OverflowAction(
title = stringResource(SYMR.strings.merge_settings),
onClick = onClickMergedSettings,
),
)
}
// SY <--
// KMK -->
if (isDevFlavor) {
add(
AppBar.OverflowAction(
title = "Colors Palette",
onClick = onPaletteScreenClick,
),
)
}
// KMK <--
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme
.surfaceColorAtElevation(3.dp)
.copy(alpha = if (isActionMode) 1f else backgroundAlphaProvider()),
),
)
}
.build(),
)
},
isActionMode = isActionMode,
onCancelActionMode = onCancelActionMode,
)
}

View file

@ -279,7 +279,7 @@ class MangaScreen(
isTabletUi = isTabletUi(),
chapterSwipeStartAction = screenModel.chapterSwipeStartAction,
chapterSwipeEndAction = screenModel.chapterSwipeEndAction,
onBackClicked = navigator::pop,
navigateUp = navigator::pop,
onChapterClicked = { openChapter(context, it) },
onDownloadChapter = screenModel::runChapterDownloadActions.takeIf { !successState.source.isLocalOrStub() },
onAddToLibraryClicked = {