🛠️ Unlimited amount of AnimatedTopAppBars
* Changed fixed 3 bars to listOf AnimatedTopAppBarData
This commit is contained in:
parent
e7a2d780d7
commit
863e76d905
5 changed files with 457 additions and 483 deletions
|
|
@ -23,6 +23,13 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.lerp
|
import androidx.compose.ui.graphics.lerp
|
||||||
|
|
||||||
|
data class AnimatedTopAppBarData(
|
||||||
|
val contentVisibility: Boolean? = null,
|
||||||
|
val contentNavigationIcon: @Composable () -> Unit,
|
||||||
|
val contentTitle: @Composable () -> Unit,
|
||||||
|
val contentActions: @Composable RowScope.() -> Unit
|
||||||
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animated top app bar.
|
* Animated top app bar.
|
||||||
* Has up to 3 different top bars inside it. Follow [TopAppBar] for more info.
|
* Has up to 3 different top bars inside it. Follow [TopAppBar] for more info.
|
||||||
|
|
@ -31,9 +38,7 @@ import androidx.compose.ui.graphics.lerp
|
||||||
* @param scrolledContainerColor Scrolled container color of the TopBar.
|
* @param scrolledContainerColor Scrolled container color of the TopBar.
|
||||||
* @param scrollBehavior [TopAppBarScrollBehavior].
|
* @param scrollBehavior [TopAppBarScrollBehavior].
|
||||||
* @param isTopBarScrolled Whether isScrolled state should be forced or not.
|
* @param isTopBarScrolled Whether isScrolled state should be forced or not.
|
||||||
* @param content1Visibility Whether first top app bar should be shown.
|
* @param animatedTopBars Pass a list of all [AnimatedTopAppBarData] to show.
|
||||||
* @param content2Visibility Whether second top app bar should be shown.
|
|
||||||
* @param content3Visibility Whether third top app bar should be shown.
|
|
||||||
* @param customContent Custom content below [TopAppBar].
|
* @param customContent Custom content below [TopAppBar].
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
|
@ -45,21 +50,7 @@ fun AnimatedTopAppBar(
|
||||||
scrollBehavior: TopAppBarScrollBehavior?,
|
scrollBehavior: TopAppBarScrollBehavior?,
|
||||||
isTopBarScrolled: Boolean?,
|
isTopBarScrolled: Boolean?,
|
||||||
|
|
||||||
content1Visibility: Boolean? = null,
|
animatedTopBars: List<AnimatedTopAppBarData>,
|
||||||
content1NavigationIcon: @Composable () -> Unit,
|
|
||||||
content1Title: @Composable () -> Unit,
|
|
||||||
content1Actions: @Composable RowScope.() -> Unit,
|
|
||||||
|
|
||||||
content2Visibility: Boolean? = null,
|
|
||||||
content2NavigationIcon: @Composable () -> Unit = {},
|
|
||||||
content2Title: @Composable () -> Unit = {},
|
|
||||||
content2Actions: @Composable RowScope.() -> Unit = {},
|
|
||||||
|
|
||||||
content3Visibility: Boolean? = null,
|
|
||||||
content3NavigationIcon: @Composable () -> Unit = {},
|
|
||||||
content3Title: @Composable () -> Unit = {},
|
|
||||||
content3Actions: @Composable RowScope.() -> Unit = {},
|
|
||||||
|
|
||||||
customContent: @Composable ColumnScope.() -> Unit = {}
|
customContent: @Composable ColumnScope.() -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val animatedContainerColor = lerp(
|
val animatedContainerColor = lerp(
|
||||||
|
|
@ -79,59 +70,17 @@ fun AnimatedTopAppBar(
|
||||||
.background(animatedContainerColor)
|
.background(animatedContainerColor)
|
||||||
) {
|
) {
|
||||||
Box(modifier = Modifier.fillMaxWidth()) {
|
Box(modifier = Modifier.fillMaxWidth()) {
|
||||||
CustomAnimatedVisibility(
|
animatedTopBars.forEach { data ->
|
||||||
visible = content1Visibility ?: true,
|
|
||||||
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
|
|
||||||
exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow))
|
|
||||||
) {
|
|
||||||
TopAppBar(
|
|
||||||
windowInsets = WindowInsets.statusBars,
|
|
||||||
navigationIcon = content1NavigationIcon,
|
|
||||||
title = content1Title,
|
|
||||||
actions = content1Actions,
|
|
||||||
scrollBehavior = scrollBehavior,
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
|
||||||
containerColor = if (isTopBarScrolled != null) Color.Transparent
|
|
||||||
else containerColor,
|
|
||||||
scrolledContainerColor = scrolledContainerColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content2Visibility != null) {
|
|
||||||
CustomAnimatedVisibility(
|
CustomAnimatedVisibility(
|
||||||
visible = content2Visibility,
|
visible = data.contentVisibility ?: false,
|
||||||
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
|
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
|
||||||
exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow))
|
exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow))
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
windowInsets = WindowInsets.statusBars,
|
windowInsets = WindowInsets.statusBars,
|
||||||
navigationIcon = content2NavigationIcon,
|
navigationIcon = data.contentNavigationIcon,
|
||||||
title = content2Title,
|
title = data.contentTitle,
|
||||||
actions = content2Actions,
|
actions = data.contentActions,
|
||||||
scrollBehavior = scrollBehavior,
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
|
||||||
containerColor = if (isTopBarScrolled != null) Color.Transparent
|
|
||||||
else containerColor,
|
|
||||||
scrolledContainerColor = scrolledContainerColor
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content3Visibility != null) {
|
|
||||||
CustomAnimatedVisibility(
|
|
||||||
visible = content3Visibility,
|
|
||||||
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
|
|
||||||
exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow))
|
|
||||||
) {
|
|
||||||
TopAppBar(
|
|
||||||
windowInsets = WindowInsets.statusBars,
|
|
||||||
navigationIcon = content3NavigationIcon,
|
|
||||||
title = content3Title,
|
|
||||||
actions = content3Actions,
|
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
colors = TopAppBarDefaults.topAppBarColors(
|
colors = TopAppBarDefaults.topAppBarColors(
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
||||||
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
||||||
|
|
@ -59,120 +60,125 @@ fun BookInfoTopBar(
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = listState.canScrollBackward,
|
isTopBarScrolled = listState.canScrollBackward,
|
||||||
|
|
||||||
content1NavigationIcon = {
|
animatedTopBars = listOf(
|
||||||
if (
|
AnimatedTopAppBarData(
|
||||||
state.value.editTitle ||
|
contentVisibility = true,
|
||||||
state.value.editAuthor ||
|
contentNavigationIcon = {
|
||||||
state.value.editDescription
|
if (
|
||||||
) {
|
state.value.editTitle ||
|
||||||
CustomIconButton(
|
state.value.editAuthor ||
|
||||||
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
state.value.editDescription
|
||||||
contentDescription = R.string.exit_editing_content_desc,
|
) {
|
||||||
disableOnClick = true
|
CustomIconButton(
|
||||||
) {
|
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
||||||
if (state.value.editTitle) {
|
contentDescription = R.string.exit_editing_content_desc,
|
||||||
onEvent(BookInfoEvent.OnShowHideEditTitle)
|
disableOnClick = true
|
||||||
}
|
) {
|
||||||
|
if (state.value.editTitle) {
|
||||||
|
onEvent(BookInfoEvent.OnShowHideEditTitle)
|
||||||
|
}
|
||||||
|
|
||||||
if (state.value.editAuthor) {
|
if (state.value.editAuthor) {
|
||||||
onEvent(BookInfoEvent.OnShowHideEditAuthor)
|
onEvent(BookInfoEvent.OnShowHideEditAuthor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.value.editDescription) {
|
if (state.value.editDescription) {
|
||||||
onEvent(BookInfoEvent.OnShowHideEditDescription)
|
onEvent(BookInfoEvent.OnShowHideEditDescription)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GoBackButton(onNavigate = onNavigate, enabled = !state.value.updating) {
|
||||||
|
onEvent(BookInfoEvent.OnCancelUpdate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
} else {
|
contentTitle = {
|
||||||
GoBackButton(onNavigate = onNavigate, enabled = !state.value.updating) {
|
DefaultTransition(
|
||||||
onEvent(BookInfoEvent.OnCancelUpdate)
|
firstVisibleItemIndex > 0 && !state.value.editTitle
|
||||||
}
|
) {
|
||||||
}
|
Text(
|
||||||
},
|
state.value.book.title,
|
||||||
content1Title = {
|
style = MaterialTheme.typography.titleLarge,
|
||||||
DefaultTransition(
|
color = MaterialTheme.colorScheme.onSurface,
|
||||||
firstVisibleItemIndex > 0 && !state.value.editTitle
|
overflow = TextOverflow.Ellipsis,
|
||||||
) {
|
maxLines = 1
|
||||||
Text(
|
)
|
||||||
state.value.book.title,
|
}
|
||||||
style = MaterialTheme.typography.titleLarge,
|
},
|
||||||
color = MaterialTheme.colorScheme.onSurface,
|
contentActions = {
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
maxLines = 1
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content1Actions = {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.Outlined.Refresh,
|
|
||||||
contentDescription = R.string.refresh_book_content_desc,
|
|
||||||
disableOnClick = false,
|
|
||||||
enabled = !state.value.updating && !state.value.checkingForUpdate
|
|
||||||
) {
|
|
||||||
onEvent(
|
|
||||||
BookInfoEvent.OnCheckForUpdate(
|
|
||||||
snackbarState,
|
|
||||||
context
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Box {
|
|
||||||
DefaultTransition(
|
|
||||||
visible = !state.value.editTitle &&
|
|
||||||
!state.value.editAuthor &&
|
|
||||||
!state.value.editDescription
|
|
||||||
) {
|
|
||||||
BookInfoMoreDropDown(snackbarState = snackbarState)
|
|
||||||
}
|
|
||||||
CustomAnimatedVisibility(
|
|
||||||
visible = state.value.editTitle ||
|
|
||||||
state.value.editAuthor ||
|
|
||||||
state.value.editDescription,
|
|
||||||
enter = Transitions.DefaultTransitionIn,
|
|
||||||
exit = fadeOut(tween(200))
|
|
||||||
) {
|
|
||||||
CustomIconButton(
|
CustomIconButton(
|
||||||
icon = Icons.Outlined.Done,
|
icon = Icons.Outlined.Refresh,
|
||||||
contentDescription = R.string.apply_changes_content_desc,
|
contentDescription = R.string.refresh_book_content_desc,
|
||||||
disableOnClick = true,
|
disableOnClick = false,
|
||||||
enabled = !state.value.updating &&
|
enabled = !state.value.updating && !state.value.checkingForUpdate
|
||||||
(state.value.titleValue.isNotBlank() &&
|
|
||||||
state.value.titleValue.trim() !=
|
|
||||||
state.value.book.title.trim()) ||
|
|
||||||
|
|
||||||
(state.value.authorValue.isNotBlank() &&
|
|
||||||
state.value.authorValue.trim() !=
|
|
||||||
state.value.book.author.getAsString()?.trim()) ||
|
|
||||||
|
|
||||||
(state.value.descriptionValue.isNotBlank() &&
|
|
||||||
state.value.descriptionValue.trim() !=
|
|
||||||
state.value.book.description?.trim()),
|
|
||||||
|
|
||||||
color = if ((state.value.titleValue.isNotBlank() &&
|
|
||||||
state.value.titleValue.trim() !=
|
|
||||||
state.value.book.title.trim()) ||
|
|
||||||
|
|
||||||
(state.value.authorValue.isNotBlank() &&
|
|
||||||
state.value.authorValue.trim() !=
|
|
||||||
state.value.book.author.getAsString()?.trim()) ||
|
|
||||||
|
|
||||||
(state.value.descriptionValue.isNotBlank() &&
|
|
||||||
state.value.descriptionValue.trim() !=
|
|
||||||
state.value.book.description?.trim())
|
|
||||||
) MaterialTheme.colorScheme.onSurface
|
|
||||||
else MaterialTheme.colorScheme.onSurfaceVariant
|
|
||||||
) {
|
) {
|
||||||
onEvent(
|
onEvent(
|
||||||
BookInfoEvent.OnUpdateData(
|
BookInfoEvent.OnCheckForUpdate(
|
||||||
refreshList = {
|
snackbarState,
|
||||||
onLibraryEvent(LibraryEvent.OnUpdateBook(it))
|
context
|
||||||
onHistoryEvent(HistoryEvent.OnUpdateBook(it))
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Box {
|
||||||
|
DefaultTransition(
|
||||||
|
visible = !state.value.editTitle &&
|
||||||
|
!state.value.editAuthor &&
|
||||||
|
!state.value.editDescription
|
||||||
|
) {
|
||||||
|
BookInfoMoreDropDown(snackbarState = snackbarState)
|
||||||
|
}
|
||||||
|
CustomAnimatedVisibility(
|
||||||
|
visible = state.value.editTitle ||
|
||||||
|
state.value.editAuthor ||
|
||||||
|
state.value.editDescription,
|
||||||
|
enter = Transitions.DefaultTransitionIn,
|
||||||
|
exit = fadeOut(tween(200))
|
||||||
|
) {
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.Outlined.Done,
|
||||||
|
contentDescription = R.string.apply_changes_content_desc,
|
||||||
|
disableOnClick = true,
|
||||||
|
enabled = !state.value.updating &&
|
||||||
|
(state.value.titleValue.isNotBlank() &&
|
||||||
|
state.value.titleValue.trim() !=
|
||||||
|
state.value.book.title.trim()) ||
|
||||||
|
|
||||||
|
(state.value.authorValue.isNotBlank() &&
|
||||||
|
state.value.authorValue.trim() !=
|
||||||
|
state.value.book.author.getAsString()?.trim()) ||
|
||||||
|
|
||||||
|
(state.value.descriptionValue.isNotBlank() &&
|
||||||
|
state.value.descriptionValue.trim() !=
|
||||||
|
state.value.book.description?.trim()),
|
||||||
|
|
||||||
|
color = if ((state.value.titleValue.isNotBlank() &&
|
||||||
|
state.value.titleValue.trim() !=
|
||||||
|
state.value.book.title.trim()) ||
|
||||||
|
|
||||||
|
(state.value.authorValue.isNotBlank() &&
|
||||||
|
state.value.authorValue.trim() !=
|
||||||
|
state.value.book.author.getAsString()?.trim()) ||
|
||||||
|
|
||||||
|
(state.value.descriptionValue.isNotBlank() &&
|
||||||
|
state.value.descriptionValue.trim() !=
|
||||||
|
state.value.book.description?.trim())
|
||||||
|
) MaterialTheme.colorScheme.onSurface
|
||||||
|
else MaterialTheme.colorScheme.onSurfaceVariant
|
||||||
|
) {
|
||||||
|
onEvent(
|
||||||
|
BookInfoEvent.OnUpdateData(
|
||||||
|
refreshList = {
|
||||||
|
onLibraryEvent(LibraryEvent.OnUpdateBook(it))
|
||||||
|
onHistoryEvent(HistoryEvent.OnUpdateBook(it))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -1,14 +1,6 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.browse.components.top_bar
|
package ua.acclorite.book_story.presentation.screens.browse.components.top_bar
|
||||||
|
|
||||||
import androidx.compose.animation.animateColorAsState
|
import androidx.compose.animation.animateColorAsState
|
||||||
import androidx.compose.animation.core.tween
|
|
||||||
import androidx.compose.animation.expandHorizontally
|
|
||||||
import androidx.compose.animation.fadeIn
|
|
||||||
import androidx.compose.animation.fadeOut
|
|
||||||
import androidx.compose.animation.shrinkHorizontally
|
|
||||||
import androidx.compose.animation.slideInHorizontally
|
|
||||||
import androidx.compose.animation.slideOutHorizontally
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.Check
|
import androidx.compose.material.icons.filled.Check
|
||||||
|
|
@ -25,7 +17,6 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.FocusRequester
|
import androidx.compose.ui.focus.FocusRequester
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
|
|
@ -35,7 +26,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSearchTextField
|
import ua.acclorite.book_story.presentation.core.components.CustomSearchTextField
|
||||||
import ua.acclorite.book_story.presentation.core.components.LocalBrowseViewModel
|
import ua.acclorite.book_story.presentation.core.components.LocalBrowseViewModel
|
||||||
|
|
@ -44,7 +35,6 @@ import ua.acclorite.book_story.presentation.core.components.MoreDropDown
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseFilesStructure
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseFilesStructure
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseLayout
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseLayout
|
||||||
import ua.acclorite.book_story.presentation.ui.FadeTransitionPreservingSpace
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Browse Top Bar.
|
* Browse Top Bar.
|
||||||
|
|
@ -88,157 +78,173 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
|
|
||||||
AnimatedTopAppBar(
|
AnimatedTopAppBar(
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = state.value.hasSelectedItems ||
|
isTopBarScrolled = isScrolled.value || inNestedDirectory.value,
|
||||||
isScrolled.value ||
|
|
||||||
inNestedDirectory.value,
|
|
||||||
|
|
||||||
content1Visibility = !state.value.hasSelectedItems && !state.value.showSearch,
|
animatedTopBars = listOf(
|
||||||
content1NavigationIcon = {
|
AnimatedTopAppBarData(
|
||||||
CustomAnimatedVisibility(
|
contentVisibility = !state.value.hasSelectedItems &&
|
||||||
visible = inNestedDirectory.value,
|
!state.value.showSearch &&
|
||||||
enter = expandHorizontally(tween(200))
|
!inNestedDirectory.value,
|
||||||
+ slideInHorizontally(tween(200))
|
contentNavigationIcon = {},
|
||||||
+ fadeIn(tween(250)),
|
contentTitle = {
|
||||||
exit = shrinkHorizontally(tween(150))
|
|
||||||
+ slideOutHorizontally(tween(150))
|
|
||||||
+ fadeOut(tween(200))
|
|
||||||
) {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
|
||||||
contentDescription = R.string.go_back_content_desc,
|
|
||||||
disableOnClick = false,
|
|
||||||
enabled = inNestedDirectory.value
|
|
||||||
) {
|
|
||||||
onEvent(BrowseEvent.OnGoBackDirectory)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content1Title = {
|
|
||||||
Box(contentAlignment = Alignment.CenterStart) {
|
|
||||||
FadeTransitionPreservingSpace(
|
|
||||||
visible = inNestedDirectory.value,
|
|
||||||
animationSpec = tween(200)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
selectedDirectoryName.value,
|
|
||||||
maxLines = 1,
|
|
||||||
overflow = TextOverflow.Ellipsis
|
|
||||||
)
|
|
||||||
}
|
|
||||||
FadeTransitionPreservingSpace(
|
|
||||||
visible = !inNestedDirectory.value,
|
|
||||||
animationSpec = tween(200)
|
|
||||||
) {
|
|
||||||
Text(
|
Text(
|
||||||
stringResource(id = R.string.browse_screen),
|
stringResource(id = R.string.browse_screen),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
|
},
|
||||||
|
contentActions = {
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.Default.Search,
|
||||||
|
contentDescription = R.string.search_content_desc,
|
||||||
|
disableOnClick = true
|
||||||
|
) {
|
||||||
|
onEvent(BrowseEvent.OnSearchShowHide)
|
||||||
|
}
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.Default.FilterList,
|
||||||
|
contentDescription = R.string.filter_content_desc,
|
||||||
|
disableOnClick = false,
|
||||||
|
color = animateColorAsState(
|
||||||
|
if (mainState.value.browseIncludedFilterItems.isNotEmpty()) {
|
||||||
|
MaterialTheme.colorScheme.primary
|
||||||
|
} else LocalContentColor.current,
|
||||||
|
label = ""
|
||||||
|
).value,
|
||||||
|
enabled = !state.value.showFilterBottomSheet
|
||||||
|
) {
|
||||||
|
onEvent(BrowseEvent.OnShowHideFilterBottomSheet)
|
||||||
|
}
|
||||||
|
MoreDropDown()
|
||||||
}
|
}
|
||||||
}
|
),
|
||||||
},
|
|
||||||
content1Actions = {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.Default.Search,
|
|
||||||
contentDescription = R.string.search_content_desc,
|
|
||||||
disableOnClick = true
|
|
||||||
) {
|
|
||||||
onEvent(BrowseEvent.OnSearchShowHide)
|
|
||||||
}
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.Default.FilterList,
|
|
||||||
contentDescription = R.string.filter_content_desc,
|
|
||||||
disableOnClick = false,
|
|
||||||
color = animateColorAsState(
|
|
||||||
if (mainState.value.browseIncludedFilterItems.isNotEmpty()) {
|
|
||||||
MaterialTheme.colorScheme.primary
|
|
||||||
} else LocalContentColor.current,
|
|
||||||
label = ""
|
|
||||||
).value,
|
|
||||||
enabled = !state.value.showFilterBottomSheet
|
|
||||||
) {
|
|
||||||
onEvent(BrowseEvent.OnShowHideFilterBottomSheet)
|
|
||||||
}
|
|
||||||
MoreDropDown()
|
|
||||||
},
|
|
||||||
|
|
||||||
content2Visibility = state.value.hasSelectedItems,
|
AnimatedTopAppBarData(
|
||||||
content2NavigationIcon = {
|
contentVisibility = inNestedDirectory.value,
|
||||||
CustomIconButton(
|
contentNavigationIcon = {
|
||||||
icon = Icons.Default.Clear,
|
CustomIconButton(
|
||||||
contentDescription = R.string.clear_selected_items_content_desc,
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
disableOnClick = true
|
contentDescription = R.string.go_back_content_desc,
|
||||||
) {
|
disableOnClick = false,
|
||||||
onEvent(BrowseEvent.OnClearSelectedFiles)
|
enabled = inNestedDirectory.value
|
||||||
}
|
) {
|
||||||
},
|
onEvent(BrowseEvent.OnGoBackDirectory)
|
||||||
content2Title = {
|
}
|
||||||
Text(
|
},
|
||||||
stringResource(
|
contentTitle = {
|
||||||
id = R.string.selected_items_count_query,
|
Text(
|
||||||
state.value.selectedItemsCount.coerceAtLeast(1)
|
selectedDirectoryName.value,
|
||||||
),
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis
|
||||||
maxLines = 1
|
|
||||||
)
|
|
||||||
},
|
|
||||||
content2Actions = {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.Default.SelectAll,
|
|
||||||
contentDescription = R.string.select_all_files_content_desc,
|
|
||||||
disableOnClick = false,
|
|
||||||
) {
|
|
||||||
onEvent(
|
|
||||||
BrowseEvent.OnSelectFiles(
|
|
||||||
includedFileFormats = mainState.value.browseIncludedFilterItems,
|
|
||||||
files = filteredFiles
|
|
||||||
)
|
)
|
||||||
)
|
},
|
||||||
}
|
contentActions = {
|
||||||
CustomIconButton(
|
CustomIconButton(
|
||||||
icon = Icons.Default.Check,
|
icon = Icons.Default.Search,
|
||||||
contentDescription = R.string.add_files_content_desc,
|
contentDescription = R.string.search_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = true
|
||||||
enabled = !state.value.showAddingDialog
|
) {
|
||||||
) {
|
onEvent(BrowseEvent.OnSearchShowHide)
|
||||||
onEvent(BrowseEvent.OnAddingDialogRequest)
|
}
|
||||||
}
|
CustomIconButton(
|
||||||
},
|
icon = Icons.Default.FilterList,
|
||||||
|
contentDescription = R.string.filter_content_desc,
|
||||||
|
disableOnClick = false,
|
||||||
|
color = animateColorAsState(
|
||||||
|
if (mainState.value.browseIncludedFilterItems.isNotEmpty()) {
|
||||||
|
MaterialTheme.colorScheme.primary
|
||||||
|
} else LocalContentColor.current,
|
||||||
|
label = ""
|
||||||
|
).value,
|
||||||
|
enabled = !state.value.showFilterBottomSheet
|
||||||
|
) {
|
||||||
|
onEvent(BrowseEvent.OnShowHideFilterBottomSheet)
|
||||||
|
}
|
||||||
|
MoreDropDown()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
content3Visibility = state.value.showSearch && !state.value.hasSelectedItems,
|
AnimatedTopAppBarData(
|
||||||
content3NavigationIcon = {
|
contentVisibility = state.value.hasSelectedItems,
|
||||||
CustomIconButton(
|
contentNavigationIcon = {
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
CustomIconButton(
|
||||||
contentDescription = R.string.exit_search_content_desc,
|
icon = Icons.Default.Clear,
|
||||||
disableOnClick = true
|
contentDescription = R.string.clear_selected_items_content_desc,
|
||||||
) {
|
disableOnClick = true
|
||||||
onEvent(BrowseEvent.OnSearchShowHide)
|
) {
|
||||||
}
|
onEvent(BrowseEvent.OnClearSelectedFiles)
|
||||||
},
|
}
|
||||||
content3Title = {
|
|
||||||
CustomSearchTextField(
|
|
||||||
modifier = Modifier
|
|
||||||
.focusRequester(focusRequester)
|
|
||||||
.onGloballyPositioned {
|
|
||||||
onEvent(BrowseEvent.OnRequestFocus(focusRequester))
|
|
||||||
},
|
|
||||||
query = state.value.searchQuery,
|
|
||||||
onQueryChange = {
|
|
||||||
onEvent(BrowseEvent.OnSearchQueryChange(it))
|
|
||||||
},
|
},
|
||||||
onSearch = {
|
contentTitle = {
|
||||||
onEvent(BrowseEvent.OnSearch)
|
Text(
|
||||||
|
stringResource(
|
||||||
|
id = R.string.selected_items_count_query,
|
||||||
|
state.value.selectedItemsCount.coerceAtLeast(1)
|
||||||
|
),
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1
|
||||||
|
)
|
||||||
},
|
},
|
||||||
placeholder = stringResource(
|
contentActions = {
|
||||||
id = R.string.search_query,
|
CustomIconButton(
|
||||||
stringResource(id = R.string.files)
|
icon = Icons.Default.SelectAll,
|
||||||
)
|
contentDescription = R.string.select_all_files_content_desc,
|
||||||
|
disableOnClick = false,
|
||||||
|
) {
|
||||||
|
onEvent(
|
||||||
|
BrowseEvent.OnSelectFiles(
|
||||||
|
includedFileFormats = mainState.value.browseIncludedFilterItems,
|
||||||
|
files = filteredFiles
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.Default.Check,
|
||||||
|
contentDescription = R.string.add_files_content_desc,
|
||||||
|
disableOnClick = false,
|
||||||
|
enabled = !state.value.showAddingDialog
|
||||||
|
) {
|
||||||
|
onEvent(BrowseEvent.OnAddingDialogRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
AnimatedTopAppBarData(
|
||||||
|
contentVisibility = state.value.showSearch && !state.value.hasSelectedItems,
|
||||||
|
contentNavigationIcon = {
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
|
contentDescription = R.string.exit_search_content_desc,
|
||||||
|
disableOnClick = true
|
||||||
|
) {
|
||||||
|
onEvent(BrowseEvent.OnSearchShowHide)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentTitle = {
|
||||||
|
CustomSearchTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onGloballyPositioned {
|
||||||
|
onEvent(BrowseEvent.OnRequestFocus(focusRequester))
|
||||||
|
},
|
||||||
|
query = state.value.searchQuery,
|
||||||
|
onQueryChange = {
|
||||||
|
onEvent(BrowseEvent.OnSearchQueryChange(it))
|
||||||
|
},
|
||||||
|
onSearch = {
|
||||||
|
onEvent(BrowseEvent.OnSearch)
|
||||||
|
},
|
||||||
|
placeholder = stringResource(
|
||||||
|
id = R.string.search_query,
|
||||||
|
stringResource(id = R.string.files)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
contentActions = {
|
||||||
|
MoreDropDown()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
},
|
),
|
||||||
content3Actions = {
|
|
||||||
MoreDropDown()
|
|
||||||
},
|
|
||||||
|
|
||||||
customContent = {
|
customContent = {
|
||||||
BrowseTopBarDirectoryPath()
|
BrowseTopBarDirectoryPath()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
||||||
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
||||||
|
|
@ -101,69 +102,72 @@ private fun HistoryScreen() {
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = state.value.listState.canScrollBackward,
|
isTopBarScrolled = state.value.listState.canScrollBackward,
|
||||||
|
|
||||||
content1Visibility = !state.value.showSearch,
|
animatedTopBars = listOf(
|
||||||
content1NavigationIcon = {},
|
AnimatedTopAppBarData(
|
||||||
content1Title = {
|
contentVisibility = !state.value.showSearch,
|
||||||
Text(
|
contentNavigationIcon = {},
|
||||||
stringResource(id = R.string.history_screen)
|
contentTitle = {
|
||||||
)
|
Text(stringResource(id = R.string.history_screen))
|
||||||
},
|
},
|
||||||
content1Actions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
CustomIconButton(
|
||||||
icon = Icons.Default.Search,
|
icon = Icons.Default.Search,
|
||||||
contentDescription = R.string.search_content_desc,
|
contentDescription = R.string.search_content_desc,
|
||||||
disableOnClick = true,
|
disableOnClick = true,
|
||||||
) {
|
) {
|
||||||
onEvent(HistoryEvent.OnSearchShowHide)
|
onEvent(HistoryEvent.OnSearchShowHide)
|
||||||
}
|
}
|
||||||
CustomIconButton(
|
CustomIconButton(
|
||||||
icon = Icons.Outlined.DeleteSweep,
|
icon = Icons.Outlined.DeleteSweep,
|
||||||
contentDescription = R.string.delete_whole_history_content_desc,
|
contentDescription = R.string.delete_whole_history_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
enabled = !state.value.isLoading
|
enabled = !state.value.isLoading
|
||||||
&& !state.value.isRefreshing
|
&& !state.value.isRefreshing
|
||||||
&& state.value.history.isNotEmpty()
|
&& state.value.history.isNotEmpty()
|
||||||
&& !state.value.showDeleteWholeHistoryDialog
|
&& !state.value.showDeleteWholeHistoryDialog
|
||||||
) {
|
) {
|
||||||
onEvent(HistoryEvent.OnShowHideDeleteWholeHistoryDialog)
|
onEvent(HistoryEvent.OnShowHideDeleteWholeHistoryDialog)
|
||||||
}
|
}
|
||||||
MoreDropDown()
|
MoreDropDown()
|
||||||
},
|
}
|
||||||
|
),
|
||||||
|
|
||||||
content2Visibility = state.value.showSearch,
|
AnimatedTopAppBarData(
|
||||||
content2NavigationIcon = {
|
contentVisibility = state.value.showSearch,
|
||||||
CustomIconButton(
|
contentNavigationIcon = {
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
CustomIconButton(
|
||||||
contentDescription = R.string.exit_search_content_desc,
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
disableOnClick = true
|
contentDescription = R.string.exit_search_content_desc,
|
||||||
) {
|
disableOnClick = true
|
||||||
onEvent(HistoryEvent.OnSearchShowHide)
|
) {
|
||||||
}
|
onEvent(HistoryEvent.OnSearchShowHide)
|
||||||
},
|
}
|
||||||
content2Title = {
|
|
||||||
CustomSearchTextField(
|
|
||||||
modifier = Modifier
|
|
||||||
.focusRequester(focusRequester)
|
|
||||||
.onGloballyPositioned {
|
|
||||||
onEvent(HistoryEvent.OnRequestFocus(focusRequester))
|
|
||||||
},
|
|
||||||
query = state.value.searchQuery,
|
|
||||||
onQueryChange = {
|
|
||||||
onEvent(HistoryEvent.OnSearchQueryChange(it))
|
|
||||||
},
|
},
|
||||||
onSearch = {
|
contentTitle = {
|
||||||
onEvent(HistoryEvent.OnSearch)
|
CustomSearchTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onGloballyPositioned {
|
||||||
|
onEvent(HistoryEvent.OnRequestFocus(focusRequester))
|
||||||
|
},
|
||||||
|
query = state.value.searchQuery,
|
||||||
|
onQueryChange = {
|
||||||
|
onEvent(HistoryEvent.OnSearchQueryChange(it))
|
||||||
|
},
|
||||||
|
onSearch = {
|
||||||
|
onEvent(HistoryEvent.OnSearch)
|
||||||
|
},
|
||||||
|
placeholder = stringResource(
|
||||||
|
id = R.string.search_query,
|
||||||
|
stringResource(id = R.string.history)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
contentActions = {
|
||||||
|
MoreDropDown()
|
||||||
},
|
},
|
||||||
placeholder = stringResource(
|
|
||||||
id = R.string.search_query,
|
|
||||||
stringResource(id = R.string.history)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
},
|
)
|
||||||
content2Actions = {
|
|
||||||
MoreDropDown()
|
|
||||||
},
|
|
||||||
content3Visibility = false
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
||||||
|
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSearchTextField
|
import ua.acclorite.book_story.presentation.core.components.CustomSearchTextField
|
||||||
import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel
|
import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel
|
||||||
|
|
@ -55,115 +56,123 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = state.value.hasSelectedItems,
|
isTopBarScrolled = state.value.hasSelectedItems,
|
||||||
|
|
||||||
content1Visibility = !state.value.hasSelectedItems && !state.value.showSearch,
|
animatedTopBars = listOf(
|
||||||
content1NavigationIcon = {},
|
AnimatedTopAppBarData(
|
||||||
content1Title = {
|
contentVisibility = !state.value.hasSelectedItems && !state.value.showSearch,
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
contentNavigationIcon = {},
|
||||||
Text(stringResource(id = R.string.library_screen))
|
contentTitle = {
|
||||||
Spacer(modifier = Modifier.width(6.dp))
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Text(
|
Text(stringResource(id = R.string.library_screen))
|
||||||
text = state.value.books.size.toString(),
|
Spacer(modifier = Modifier.width(6.dp))
|
||||||
modifier = Modifier
|
Text(
|
||||||
.background(
|
text = state.value.books.size.toString(),
|
||||||
MaterialTheme.colorScheme.surfaceContainer,
|
modifier = Modifier
|
||||||
RoundedCornerShape(14.dp)
|
.background(
|
||||||
|
MaterialTheme.colorScheme.surfaceContainer,
|
||||||
|
RoundedCornerShape(14.dp)
|
||||||
|
)
|
||||||
|
.padding(horizontal = 8.dp, vertical = 3.dp),
|
||||||
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
fontSize = 16.sp
|
||||||
)
|
)
|
||||||
.padding(horizontal = 8.dp, vertical = 3.dp),
|
}
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
|
||||||
fontSize = 16.sp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content1Actions = {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.Default.Search,
|
|
||||||
contentDescription = R.string.search_content_desc,
|
|
||||||
disableOnClick = true,
|
|
||||||
) {
|
|
||||||
onEvent(LibraryEvent.OnSearchShowHide)
|
|
||||||
}
|
|
||||||
MoreDropDown()
|
|
||||||
},
|
|
||||||
|
|
||||||
content2Visibility = state.value.hasSelectedItems,
|
|
||||||
content2NavigationIcon = {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.Default.Clear,
|
|
||||||
contentDescription = R.string.clear_selected_items_content_desc,
|
|
||||||
disableOnClick = true
|
|
||||||
) {
|
|
||||||
onEvent(LibraryEvent.OnClearSelectedBooks)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content2Title = {
|
|
||||||
Text(
|
|
||||||
stringResource(
|
|
||||||
id = R.string.selected_items_count_query,
|
|
||||||
state.value.selectedItemsCount.coerceAtLeast(1)
|
|
||||||
),
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
maxLines = 1
|
|
||||||
)
|
|
||||||
},
|
|
||||||
content2Actions = {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
|
||||||
contentDescription = R.string.move_books_content_desc,
|
|
||||||
enabled = !state.value.isLoading
|
|
||||||
&& !state.value.isRefreshing
|
|
||||||
&& !state.value.showMoveDialog,
|
|
||||||
disableOnClick = false,
|
|
||||||
|
|
||||||
) {
|
|
||||||
onEvent(LibraryEvent.OnShowHideMoveDialog)
|
|
||||||
}
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.Outlined.Delete,
|
|
||||||
contentDescription = R.string.delete_books_content_desc,
|
|
||||||
enabled = !state.value.isLoading
|
|
||||||
&& !state.value.isRefreshing
|
|
||||||
&& !state.value.showDeleteDialog,
|
|
||||||
disableOnClick = false
|
|
||||||
) {
|
|
||||||
onEvent(LibraryEvent.OnShowHideDeleteDialog)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
content3Visibility = state.value.showSearch && !state.value.hasSelectedItems,
|
|
||||||
content3NavigationIcon = {
|
|
||||||
CustomIconButton(
|
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
|
||||||
contentDescription = R.string.exit_search_content_desc,
|
|
||||||
disableOnClick = true
|
|
||||||
) {
|
|
||||||
onEvent(
|
|
||||||
LibraryEvent.OnSearchShowHide
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
content3Title = {
|
|
||||||
CustomSearchTextField(
|
|
||||||
modifier = Modifier
|
|
||||||
.focusRequester(focusRequester)
|
|
||||||
.onGloballyPositioned {
|
|
||||||
onEvent(LibraryEvent.OnRequestFocus(focusRequester))
|
|
||||||
},
|
|
||||||
query = state.value.searchQuery,
|
|
||||||
onQueryChange = {
|
|
||||||
onEvent(LibraryEvent.OnSearchQueryChange(it))
|
|
||||||
},
|
},
|
||||||
onSearch = {
|
contentActions = {
|
||||||
onEvent(LibraryEvent.OnSearch)
|
CustomIconButton(
|
||||||
|
icon = Icons.Default.Search,
|
||||||
|
contentDescription = R.string.search_content_desc,
|
||||||
|
disableOnClick = true,
|
||||||
|
) {
|
||||||
|
onEvent(LibraryEvent.OnSearchShowHide)
|
||||||
|
}
|
||||||
|
MoreDropDown()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
AnimatedTopAppBarData(
|
||||||
|
contentVisibility = state.value.hasSelectedItems,
|
||||||
|
contentNavigationIcon = {
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.Default.Clear,
|
||||||
|
contentDescription = R.string.clear_selected_items_content_desc,
|
||||||
|
disableOnClick = true
|
||||||
|
) {
|
||||||
|
onEvent(LibraryEvent.OnClearSelectedBooks)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentTitle = {
|
||||||
|
Text(
|
||||||
|
stringResource(
|
||||||
|
id = R.string.selected_items_count_query,
|
||||||
|
state.value.selectedItemsCount.coerceAtLeast(1)
|
||||||
|
),
|
||||||
|
overflow = TextOverflow.Ellipsis,
|
||||||
|
maxLines = 1
|
||||||
|
)
|
||||||
|
},
|
||||||
|
contentActions = {
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
||||||
|
contentDescription = R.string.move_books_content_desc,
|
||||||
|
enabled = !state.value.isLoading
|
||||||
|
&& !state.value.isRefreshing
|
||||||
|
&& !state.value.showMoveDialog,
|
||||||
|
disableOnClick = false,
|
||||||
|
|
||||||
|
) {
|
||||||
|
onEvent(LibraryEvent.OnShowHideMoveDialog)
|
||||||
|
}
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.Outlined.Delete,
|
||||||
|
contentDescription = R.string.delete_books_content_desc,
|
||||||
|
enabled = !state.value.isLoading
|
||||||
|
&& !state.value.isRefreshing
|
||||||
|
&& !state.value.showDeleteDialog,
|
||||||
|
disableOnClick = false
|
||||||
|
) {
|
||||||
|
onEvent(LibraryEvent.OnShowHideDeleteDialog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
),
|
||||||
|
|
||||||
|
AnimatedTopAppBarData(
|
||||||
|
contentVisibility = state.value.showSearch && !state.value.hasSelectedItems,
|
||||||
|
contentNavigationIcon = {
|
||||||
|
CustomIconButton(
|
||||||
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
|
contentDescription = R.string.exit_search_content_desc,
|
||||||
|
disableOnClick = true
|
||||||
|
) {
|
||||||
|
onEvent(
|
||||||
|
LibraryEvent.OnSearchShowHide
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
contentTitle = {
|
||||||
|
CustomSearchTextField(
|
||||||
|
modifier = Modifier
|
||||||
|
.focusRequester(focusRequester)
|
||||||
|
.onGloballyPositioned {
|
||||||
|
onEvent(LibraryEvent.OnRequestFocus(focusRequester))
|
||||||
|
},
|
||||||
|
query = state.value.searchQuery,
|
||||||
|
onQueryChange = {
|
||||||
|
onEvent(LibraryEvent.OnSearchQueryChange(it))
|
||||||
|
},
|
||||||
|
onSearch = {
|
||||||
|
onEvent(LibraryEvent.OnSearch)
|
||||||
|
},
|
||||||
|
placeholder = stringResource(
|
||||||
|
id = R.string.search_query,
|
||||||
|
stringResource(id = R.string.books)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
contentActions = {
|
||||||
|
MoreDropDown()
|
||||||
},
|
},
|
||||||
placeholder = stringResource(
|
|
||||||
id = R.string.search_query,
|
|
||||||
stringResource(id = R.string.books)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
},
|
),
|
||||||
content3Actions = {
|
|
||||||
MoreDropDown()
|
|
||||||
},
|
|
||||||
customContent = {
|
customContent = {
|
||||||
LibraryTabRow(
|
LibraryTabRow(
|
||||||
onEvent = onEvent,
|
onEvent = onEvent,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue