🚀 Replace DropDown with BottomSheet

* Replaced DropDown with NavigationBottomSheet
* Renamed LocalOnNavigate → LocalNavigator, LocalNavigator → LocalNavigatorInstance
This commit is contained in:
Acclorite 2024-10-08 20:44:40 +03:00
parent 7618190ada
commit 2e2dee9e26
47 changed files with 408 additions and 307 deletions

View file

@ -0,0 +1,8 @@
package ua.acclorite.book_story.domain.util
import androidx.compose.runtime.Immutable
@Immutable
enum class Position {
TOP, CENTER, BOTTOM, SOLO
}

View file

@ -1,47 +0,0 @@
package ua.acclorite.book_story.presentation.core.components
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.size
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
/**
* Custom Dropdown Menu Item. Used in Dropdown.
*/
@Composable
fun CustomDropDownMenuItem(
leadingIcon: ImageVector,
text: String,
onClick: () -> Unit
) {
DropdownMenuItem(
leadingIcon = {
Icon(
leadingIcon,
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant
)
},
trailingIcon = {
},
text = {
Text(
text = text,
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyLarge
)
},
onClick = {
onClick()
},
contentPadding = PaddingValues(start = 12.dp, end = 0.dp)
)
}

View file

@ -1,93 +0,0 @@
package ua.acclorite.book_story.presentation.core.components
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen
/**
* More drop down.
* Navigates to Settings, About and Help screens.
*/
@Composable
fun MoreDropDown() {
val navigator = LocalNavigator.current
var showDropDown by remember { mutableStateOf(false) }
val startPadding = remember { 12.dp }
val endPadding = remember { 36.dp }
Box {
CustomIconButton(
icon = Icons.Default.MoreVert,
contentDescription = R.string.show_dropdown_content_desc,
disableOnClick = false,
enabled = !showDropDown
) {
showDropDown = true
}
DropdownMenu(
expanded = showDropDown,
onDismissRequest = { showDropDown = false },
offset = DpOffset((-15).dp, 0.dp)
) {
DropdownMenuItem(
text = {
Text(
text = stringResource(id = R.string.settings_screen),
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyLarge
)
},
onClick = {
navigator.navigate(Screen.Settings)
},
contentPadding = PaddingValues(start = startPadding, end = endPadding)
)
DropdownMenuItem(
text = {
Text(
text = stringResource(id = R.string.help_screen),
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyLarge
)
},
onClick = {
navigator.navigate(Screen.Help(false))
},
contentPadding = PaddingValues(start = startPadding, end = endPadding)
)
DropdownMenuItem(
text = {
Text(
text = stringResource(id = R.string.about_screen),
color = MaterialTheme.colorScheme.onSurface,
style = MaterialTheme.typography.bodyLarge
)
},
onClick = {
navigator.navigate(Screen.About)
},
contentPadding = PaddingValues(start = startPadding, end = endPadding)
)
}
}
}

View file

@ -9,7 +9,7 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import ua.acclorite.book_story.domain.util.Route import ua.acclorite.book_story.domain.util.Route
import ua.acclorite.book_story.presentation.core.constants.Constants import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator import ua.acclorite.book_story.presentation.core.navigation.LocalNavigatorInstance
/** /**
* Bottom navigation bar, uses default [NavigationBar]. * Bottom navigation bar, uses default [NavigationBar].
@ -17,7 +17,7 @@ import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
@Composable @Composable
fun BottomNavigationBar() { fun BottomNavigationBar() {
var currentScreen: Route? by remember { mutableStateOf(null) } var currentScreen: Route? by remember { mutableStateOf(null) }
val navigator = LocalNavigator.current val navigator = LocalNavigatorInstance.current
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
navigator.currentScreen.collect { route -> navigator.currentScreen.collect { route ->

View file

@ -25,7 +25,7 @@ import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.domain.util.Route import ua.acclorite.book_story.domain.util.Route
import ua.acclorite.book_story.presentation.core.constants.Constants import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator import ua.acclorite.book_story.presentation.core.navigation.LocalNavigatorInstance
/** /**
* Custom Navigation Rail. It is used to be shown on Tablets. * Custom Navigation Rail. It is used to be shown on Tablets.
@ -33,7 +33,7 @@ import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
@Composable @Composable
fun CustomNavigationRail() { fun CustomNavigationRail() {
var currentScreen: Route? by remember { mutableStateOf(null) } var currentScreen: Route? by remember { mutableStateOf(null) }
val navigator = LocalNavigator.current val navigator = LocalNavigatorInstance.current
val layoutDirection = LocalLayoutDirection.current val layoutDirection = LocalLayoutDirection.current
LaunchedEffect(Unit) { LaunchedEffect(Unit) {

View file

@ -41,6 +41,9 @@ import dagger.assisted.AssistedInject
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.lifecycle.withCreationCallback import dagger.hilt.android.lifecycle.withCreationCallback
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -54,13 +57,10 @@ private const val BACKSTACK = "back_stack"
private const val USE_BACK_ANIM = "use_back_animation" private const val USE_BACK_ANIM = "use_back_animation"
private const val SCREENS = "screens" private const val SCREENS = "screens"
/** val LocalNavigatorInstance = compositionLocalOf<Navigator> {
* Passed in [CompositionLocalProvider].
*/
val LocalNavigator = compositionLocalOf<Navigator> {
error("Cannot initialize Navigator.") error("Cannot initialize Navigator.")
} }
val LocalOnNavigate = compositionLocalOf<OnNavigate> { val LocalNavigator = compositionLocalOf<OnNavigate> {
error("Cannot initialize Navigator.") error("Cannot initialize Navigator.")
} }
@ -162,6 +162,9 @@ class Navigator @AssistedInject constructor(
private val backStack = savedStateHandle.getStateFlow(BACKSTACK, mutableListOf<Route>()) private val backStack = savedStateHandle.getStateFlow(BACKSTACK, mutableListOf<Route>())
val screens = savedStateHandle.getStateFlow(SCREENS, mutableListOf<Screen>()) val screens = savedStateHandle.getStateFlow(SCREENS, mutableListOf<Screen>())
private val _showNavigationBottomSheet = MutableStateFlow(false)
private val showNavigationBottomSheet = _showNavigationBottomSheet.asStateFlow()
init { init {
putScreen(startScreen) putScreen(startScreen)
} }
@ -276,6 +279,20 @@ class Navigator @AssistedInject constructor(
return this::class.simpleName!! return this::class.simpleName!!
} }
/**
* Shows navigation bottom sheet.
*/
fun showNavigationBottomSheet() {
_showNavigationBottomSheet.update { true }
}
/**
* Hides navigation bottom sheet.
*/
fun hideNavigationBottomSheet() {
_showNavigationBottomSheet.update { false }
}
/** /**
* Animated Screen. Used in [NavigationHost]. * Animated Screen. Used in [NavigationHost].
* Each [composable] should have unique [Screen]. * Each [composable] should have unique [Screen].
@ -340,27 +357,36 @@ class Navigator @AssistedInject constructor(
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
val activity = LocalContext.current as ComponentActivity val activity = LocalContext.current as ComponentActivity
val currentScreen = currentScreen.collectAsState()
val useBackAnimation by useBackAnimation.collectAsState()
val shouldShow by remember {
derivedStateOf {
screens.any { it == currentScreen.value }
}
}
val windowClass = calculateWindowSizeClass(activity = activity) val windowClass = calculateWindowSizeClass(activity = activity)
val tabletUI = remember(windowClass) { val tabletUI = remember(windowClass) {
windowClass.widthSizeClass != WindowWidthSizeClass.Compact windowClass.widthSizeClass != WindowWidthSizeClass.Compact
} }
val layoutDirection = LocalLayoutDirection.current val layoutDirection = LocalLayoutDirection.current
val currentScreen = currentScreen.collectAsState()
val useBackAnimation by useBackAnimation.collectAsState()
val showNavigation = remember {
derivedStateOf {
screens.any { it == currentScreen.value }
}
}
val showNavigationBottomSheet = showNavigationBottomSheet.collectAsState()
CustomAnimatedVisibility( CustomAnimatedVisibility(
visible = shouldShow, visible = showNavigation.value,
enter = if (useBackAnimation) backEnterBarAnim enter = if (useBackAnimation) backEnterBarAnim
else enterBarAnim, else enterBarAnim,
exit = if (useBackAnimation) backExitBarAnim exit = if (useBackAnimation) backExitBarAnim
else exitBarAnim else exitBarAnim
) { ) {
if (showNavigationBottomSheet.value) {
NavigationBottomSheet(
onDismissRequest = {
hideNavigationBottomSheet()
}
)
}
Scaffold( Scaffold(
bottomBar = { bottomBar = {
if (!tabletUI) { if (!tabletUI) {
@ -440,8 +466,8 @@ fun NavigationHost(
) )
CompositionLocalProvider( CompositionLocalProvider(
LocalNavigator provides navigator, LocalNavigatorInstance provides navigator,
LocalOnNavigate provides { navigator.it() } LocalNavigator provides { navigator.it() }
) { ) {
content(navigator) content(navigator)
} }

View file

@ -0,0 +1,79 @@
package ua.acclorite.book_story.presentation.core.navigation
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.Position
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
/**
* Navigation Bottom Sheet.
* Previously known as More Drop-Down.
* Bottom sheet allows to have more options and it generally looks better.
*
* @param onDismissRequest Dismiss callback.
*/
@Composable
fun NavigationBottomSheet(onDismissRequest: () -> Unit) {
val onNavigate = LocalNavigator.current
CustomBottomSheet(
modifier = Modifier.fillMaxWidth(),
onDismissRequest = onDismissRequest
) {
LazyColumn(Modifier.fillMaxWidth()) {
item {
NavigationItem(
title = stringResource(id = R.string.about_screen),
primary = false,
position = Position.TOP
) {
onNavigate {
navigate(screen = Screen.About)
hideNavigationBottomSheet()
}
}
}
item {
NavigationItem(
title = stringResource(id = R.string.help_screen),
primary = false,
position = Position.BOTTOM
) {
onNavigate {
navigate(screen = Screen.Help(fromStart = false))
hideNavigationBottomSheet()
}
}
}
item {
Spacer(Modifier.height(18.dp))
}
item {
NavigationItem(
title = stringResource(id = R.string.settings_screen),
primary = true,
position = Position.SOLO
) {
onNavigate {
navigate(screen = Screen.Settings)
hideNavigationBottomSheet()
}
}
}
item {
Spacer(modifier = Modifier.height(8.dp))
}
}
}
}

View file

@ -0,0 +1,25 @@
package ua.acclorite.book_story.presentation.core.navigation
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.runtime.Composable
import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
/**
* Navigation Icon Button.
* Used to display [NavigationBottomSheet].
*/
@Composable
fun NavigationIconButton(
onClick: Navigator.() -> Unit = { showNavigationBottomSheet() }
) {
val navigator = LocalNavigatorInstance.current
CustomIconButton(
icon = Icons.Default.MoreVert,
contentDescription = R.string.more_content_desc,
disableOnClick = false,
) {
navigator.onClick()
}
}

View file

@ -0,0 +1,88 @@
package ua.acclorite.book_story.presentation.core.navigation
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.domain.util.Position
/**
* Navigation item.
*
* @param title Title.
* @param primary Whether this item is primary.
* @param position Position of the item.
* @param onClick OnClick callback.
*/
@Composable
fun NavigationItem(
title: String,
primary: Boolean,
position: Position,
onClick: () -> Unit
) {
val largeShape = MaterialTheme.shapes.large
val shape = remember(position) {
when (position) {
Position.TOP -> largeShape.copy(
bottomStart = CornerSize(0.dp),
bottomEnd = CornerSize(0.dp)
)
Position.CENTER -> RoundedCornerShape(0.dp)
Position.SOLO -> largeShape
Position.BOTTOM -> largeShape.copy(
topStart = CornerSize(0.dp),
topEnd = CornerSize(0.dp)
)
}
}
val paddingValues = remember(position) {
when (position) {
Position.TOP -> PaddingValues(bottom = 1.dp)
Position.CENTER -> PaddingValues(vertical = 1.dp)
Position.SOLO -> PaddingValues(0.dp)
Position.BOTTOM -> PaddingValues(top = 1.dp)
}
}
Box(
modifier = Modifier
.padding(paddingValues)
.fillMaxWidth()
.padding(horizontal = 18.dp)
.clip(shape = shape)
.background(
if (primary) MaterialTheme.colorScheme.primaryContainer
else MaterialTheme.colorScheme.surfaceContainer
)
.clickable {
onClick()
}
.padding(horizontal = 18.dp, vertical = 18.dp),
contentAlignment = Alignment.Center
) {
Text(
text = title,
style = MaterialTheme.typography.labelLarge,
color = if (primary) MaterialTheme.colorScheme.onPrimaryContainer
else MaterialTheme.colorScheme.onSurface,
overflow = TextOverflow.Ellipsis
)
}
}

View file

@ -33,7 +33,7 @@ import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.LocalAboutViewModel import ua.acclorite.book_story.presentation.core.components.LocalAboutViewModel
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.constants.Constants import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
import ua.acclorite.book_story.presentation.screens.about.components.AboutItem import ua.acclorite.book_story.presentation.screens.about.components.AboutItem
@ -51,7 +51,7 @@ fun AboutScreenRoot() {
private fun AboutScreen() { private fun AboutScreen() {
val state = LocalAboutViewModel.current.state val state = LocalAboutViewModel.current.state
val onEvent = LocalAboutViewModel.current.onEvent val onEvent = LocalAboutViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()

View file

@ -23,7 +23,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalAboutViewModel
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.constants.Constants import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
import ua.acclorite.book_story.presentation.screens.about.data.AboutEvent import ua.acclorite.book_story.presentation.screens.about.data.AboutEvent
import ua.acclorite.book_story.presentation.screens.about.nested.credits.components.CreditItem import ua.acclorite.book_story.presentation.screens.about.nested.credits.components.CreditItem
@ -37,7 +37,7 @@ fun CreditsScreenRoot() {
@Composable @Composable
private fun CreditsScreen() { private fun CreditsScreen() {
val onEvent = LocalAboutViewModel.current.onEvent val onEvent = LocalAboutViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()

View file

@ -38,7 +38,7 @@ import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.LocalLicenseInfoViewModel import ua.acclorite.book_story.presentation.core.components.LocalLicenseInfoViewModel
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
import ua.acclorite.book_story.presentation.screens.about.nested.license_info.data.LicenseInfoEvent import ua.acclorite.book_story.presentation.screens.about.nested.license_info.data.LicenseInfoEvent
@ -48,7 +48,7 @@ import ua.acclorite.book_story.presentation.ui.SlidingTransition
@Composable @Composable
fun LicenseInfoScreenRoot(screen: Screen.About.LicenseInfo) { fun LicenseInfoScreenRoot(screen: Screen.About.LicenseInfo) {
val viewModel = LocalLicenseInfoViewModel.current.viewModel val viewModel = LocalLicenseInfoViewModel.current.viewModel
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
@ -68,7 +68,7 @@ private fun LicenseInfoScreen() {
val state = LocalLicenseInfoViewModel.current.state val state = LocalLicenseInfoViewModel.current.state
val onEvent = LocalLicenseInfoViewModel.current.onEvent val onEvent = LocalLicenseInfoViewModel.current.onEvent
val context = LocalContext.current val context = LocalContext.current
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
val licenses = remember(state.value.license?.licenses) { val licenses = remember(state.value.license?.licenses) {

View file

@ -30,7 +30,7 @@ import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.LocalLicensesViewModel import ua.acclorite.book_story.presentation.core.components.LocalLicensesViewModel
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.screens.about.nested.licenses.components.LicenseItem import ua.acclorite.book_story.presentation.screens.about.nested.licenses.components.LicenseItem
@ -50,7 +50,7 @@ fun LicensesScreenRoot() {
@Composable @Composable
private fun LicensesScreen() { private fun LicensesScreen() {
val state = LocalLicensesViewModel.current.state val state = LocalLicensesViewModel.current.state
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState( val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState(
state.value.listState state.value.listState

View file

@ -47,11 +47,12 @@ import ua.acclorite.book_story.R
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.CustomSnackbar import ua.acclorite.book_story.presentation.core.components.CustomSnackbar
import ua.acclorite.book_story.presentation.core.components.LocalBookInfoViewModel import ua.acclorite.book_story.presentation.core.components.LocalBookInfoViewModel
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoBackground import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoBackground
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoDescriptionSection import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoDescriptionSection
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoInfoSection import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoInfoSection
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoMoreBottomSheet
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoStatisticSection import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoStatisticSection
import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoTopBar import ua.acclorite.book_story.presentation.screens.book_info.components.BookInfoTopBar
import ua.acclorite.book_story.presentation.screens.book_info.components.change_cover_bottom_sheet.BookInfoChangeCoverBottomSheet import ua.acclorite.book_story.presentation.screens.book_info.components.change_cover_bottom_sheet.BookInfoChangeCoverBottomSheet
@ -64,7 +65,7 @@ import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
@Composable @Composable
fun BookInfoScreenRoot(screen: Screen.BookInfo) { fun BookInfoScreenRoot(screen: Screen.BookInfo) {
val viewModel = LocalBookInfoViewModel.current.viewModel val viewModel = LocalBookInfoViewModel.current.viewModel
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
val snackbarState = remember { SnackbarHostState() } val snackbarState = remember { SnackbarHostState() }
@ -95,7 +96,7 @@ private fun BookInfoScreen(snackbarState: SnackbarHostState) {
val context = LocalContext.current val context = LocalContext.current
val state = LocalBookInfoViewModel.current.state val state = LocalBookInfoViewModel.current.state
val onEvent = LocalBookInfoViewModel.current.onEvent val onEvent = LocalBookInfoViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val listState = rememberLazyListState() val listState = rememberLazyListState()
val refreshState = rememberPullRefreshState( val refreshState = rememberPullRefreshState(
@ -125,6 +126,9 @@ private fun BookInfoScreen(snackbarState: SnackbarHostState) {
if (state.value.showConfirmTextUpdateDialog) { if (state.value.showConfirmTextUpdateDialog) {
BookInfoConfirmUpdateDialog(snackbarHostState = snackbarState) BookInfoConfirmUpdateDialog(snackbarHostState = snackbarState)
} }
if (state.value.showMoreBottomSheet) {
BookInfoMoreBottomSheet(snackbarState = snackbarState)
}
Scaffold( Scaffold(
Modifier Modifier

View file

@ -0,0 +1,76 @@
package ua.acclorite.book_story.presentation.screens.book_info.components
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.Position
import ua.acclorite.book_story.presentation.core.components.LocalBookInfoViewModel
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
import ua.acclorite.book_story.presentation.core.navigation.NavigationItem
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
/**
* Book Info More Bottom Sheet.
* Replaces DropDown.
*
* @param snackbarState [SnackbarHostState].
*/
@Composable
fun BookInfoMoreBottomSheet(snackbarState: SnackbarHostState) {
val onEvent = LocalBookInfoViewModel.current.onEvent
CustomBottomSheet(
modifier = Modifier.fillMaxWidth(),
onDismissRequest = {
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(false))
}
) {
LazyColumn(Modifier.fillMaxWidth()) {
item {
NavigationItem(
title = stringResource(id = R.string.details_book),
primary = false,
position = Position.SOLO
) {
snackbarState.currentSnackbarData?.dismiss()
onEvent(BookInfoEvent.OnShowHideDetailsBottomSheet)
}
}
item {
Spacer(Modifier.height(18.dp))
}
item {
NavigationItem(
title = stringResource(id = R.string.delete_this_book),
primary = true,
position = Position.TOP
) {
onEvent(BookInfoEvent.OnShowHideDeleteDialog)
}
}
item {
NavigationItem(
title = stringResource(id = R.string.move_this_book),
primary = true,
position = Position.BOTTOM
) {
onEvent(BookInfoEvent.OnShowHideMoveDialog)
}
}
item {
Spacer(modifier = Modifier.height(8.dp))
}
}
}
}

View file

@ -1,77 +0,0 @@
package ua.acclorite.book_story.presentation.screens.book_info.components
import androidx.compose.foundation.layout.Box
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.DriveFileMove
import androidx.compose.material.icons.outlined.Delete
import androidx.compose.material.icons.outlined.Info
import androidx.compose.material.icons.outlined.MoreVert
import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.DpOffset
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.CustomDropDownMenuItem
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
import ua.acclorite.book_story.presentation.core.components.LocalBookInfoViewModel
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
/**
* Book info more dropdown. Has three options: Delete, Move and Details.
*/
@Composable
fun BookInfoMoreDropDown(snackbarState: SnackbarHostState) {
val state = LocalBookInfoViewModel.current.state
val onEvent = LocalBookInfoViewModel.current.onEvent
var showDropDown by remember { mutableStateOf(false) }
Box {
CustomIconButton(
icon = Icons.Outlined.MoreVert,
contentDescription = R.string.show_dropdown_content_desc,
disableOnClick = false,
enabled = !showDropDown &&
!state.value.updating
) {
showDropDown = true
}
DropdownMenu(
expanded = showDropDown,
onDismissRequest = {
showDropDown = false
},
offset = DpOffset((-15).dp, 0.dp)
) {
CustomDropDownMenuItem(
leadingIcon = Icons.AutoMirrored.Outlined.DriveFileMove,
text = stringResource(id = R.string.move_this_book)
) {
onEvent(BookInfoEvent.OnShowHideMoveDialog)
showDropDown = false
}
CustomDropDownMenuItem(
leadingIcon = Icons.Outlined.Delete,
text = stringResource(id = R.string.delete_this_book)
) {
onEvent(BookInfoEvent.OnShowHideDeleteDialog)
showDropDown = false
}
CustomDropDownMenuItem(
leadingIcon = Icons.Outlined.Info,
text = stringResource(id = R.string.details_book)
) {
snackbarState.currentSnackbarData?.dismiss()
onEvent(BookInfoEvent.OnShowHideDetailsBottomSheet)
showDropDown = false
}
}
}
}

View file

@ -27,7 +27,8 @@ import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.LocalBookInfoViewModel import ua.acclorite.book_story.presentation.core.components.LocalBookInfoViewModel
import ua.acclorite.book_story.presentation.core.components.LocalHistoryViewModel import ua.acclorite.book_story.presentation.core.components.LocalHistoryViewModel
import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.NavigationIconButton
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
@ -50,7 +51,7 @@ fun BookInfoTopBar(
val onEvent = LocalBookInfoViewModel.current.onEvent val onEvent = LocalBookInfoViewModel.current.onEvent
val onLibraryEvent = LocalLibraryViewModel.current.onEvent val onLibraryEvent = LocalLibraryViewModel.current.onEvent
val onHistoryEvent = LocalHistoryViewModel.current.onEvent val onHistoryEvent = LocalHistoryViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
val firstVisibleItemIndex by remember { derivedStateOf { listState.firstVisibleItemIndex } } val firstVisibleItemIndex by remember { derivedStateOf { listState.firstVisibleItemIndex } }
@ -127,7 +128,9 @@ fun BookInfoTopBar(
!state.value.editAuthor && !state.value.editAuthor &&
!state.value.editDescription !state.value.editDescription
) { ) {
BookInfoMoreDropDown(snackbarState = snackbarState) NavigationIconButton {
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(true))
}
} }
CustomAnimatedVisibility( CustomAnimatedVisibility(
visible = state.value.editTitle || visible = state.value.editTitle ||

View file

@ -11,7 +11,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalBrowseViewModel
import ua.acclorite.book_story.presentation.core.components.LocalHistoryViewModel import ua.acclorite.book_story.presentation.core.components.LocalHistoryViewModel
import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithContent import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithContent
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
@ -27,7 +27,7 @@ fun BookInfoDeleteDialog() {
val onLibraryEvent = LocalLibraryViewModel.current.onEvent val onLibraryEvent = LocalLibraryViewModel.current.onEvent
val onHistoryEvent = LocalHistoryViewModel.current.onEvent val onHistoryEvent = LocalHistoryViewModel.current.onEvent
val onBrowseEvent = LocalBrowseViewModel.current.onEvent val onBrowseEvent = LocalBrowseViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
CustomDialogWithContent( CustomDialogWithContent(
@ -51,6 +51,7 @@ fun BookInfoDeleteDialog() {
} }
) )
) )
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(false))
context.getString(R.string.book_deleted) context.getString(R.string.book_deleted)
.showToast(context = context) .showToast(context = context)
} }

View file

@ -15,7 +15,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewMode
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithLazyColumn import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithLazyColumn
import ua.acclorite.book_story.presentation.core.components.custom_dialog.SelectableDialogItem import ua.acclorite.book_story.presentation.core.components.custom_dialog.SelectableDialogItem
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
@ -31,7 +31,7 @@ fun BookInfoMoveDialog() {
val onEvent = LocalBookInfoViewModel.current.onEvent val onEvent = LocalBookInfoViewModel.current.onEvent
val onLibraryEvent = LocalLibraryViewModel.current.onEvent val onLibraryEvent = LocalLibraryViewModel.current.onEvent
val onHistoryEvent = LocalHistoryViewModel.current.onEvent val onHistoryEvent = LocalHistoryViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
val categories = remember { val categories = remember {
@ -64,6 +64,7 @@ fun BookInfoMoveDialog() {
onNavigate = onNavigate onNavigate = onNavigate
) )
) )
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(false))
context.getString(R.string.book_moved) context.getString(R.string.book_moved)
.showToast(context = context) .showToast(context = context)
}, },

View file

@ -124,4 +124,6 @@ sealed class BookInfoEvent {
val context: Context, val context: Context,
val refreshList: (Book) -> Unit val refreshList: (Book) -> Unit
) : BookInfoEvent() ) : BookInfoEvent()
data class OnShowHideMoreBottomSheet(val show: Boolean) : BookInfoEvent()
} }

View file

@ -37,4 +37,6 @@ data class BookInfoState(
val showDeleteDialog: Boolean = false, val showDeleteDialog: Boolean = false,
val showMoveDialog: Boolean = false, val showMoveDialog: Boolean = false,
val selectedCategory: Category = Category.READING, val selectedCategory: Category = Category.READING,
val showMoreBottomSheet: Boolean = false,
) )

View file

@ -728,6 +728,14 @@ class BookInfoViewModel @Inject constructor(
} }
} }
} }
is BookInfoEvent.OnShowHideMoreBottomSheet -> {
_state.update {
it.copy(
showMoreBottomSheet = event.show
)
}
}
} }
} }
} }

View file

@ -26,7 +26,7 @@ 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.LocalBrowseViewModel import ua.acclorite.book_story.presentation.core.components.LocalBrowseViewModel
import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
import ua.acclorite.book_story.presentation.screens.browse.components.BrowseEmptyPlaceholder import ua.acclorite.book_story.presentation.screens.browse.components.BrowseEmptyPlaceholder
@ -89,7 +89,7 @@ private fun BrowseScreen(
val state = LocalBrowseViewModel.current.state val state = LocalBrowseViewModel.current.state
val mainState = LocalMainViewModel.current.state val mainState = LocalMainViewModel.current.state
val onEvent = LocalBrowseViewModel.current.onEvent val onEvent = LocalBrowseViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
val refreshState = rememberPullRefreshState( val refreshState = rememberPullRefreshState(

View file

@ -13,7 +13,7 @@ import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibi
import ua.acclorite.book_story.presentation.core.components.LocalBrowseViewModel import ua.acclorite.book_story.presentation.core.components.LocalBrowseViewModel
import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty
import ua.acclorite.book_story.presentation.core.components.is_messages.IsError import ua.acclorite.book_story.presentation.core.components.is_messages.IsError
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
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.ui.Transitions import ua.acclorite.book_story.presentation.ui.Transitions
@ -33,7 +33,7 @@ fun BoxScope.BrowseEmptyPlaceholder(
) { ) {
val state = LocalBrowseViewModel.current.state val state = LocalBrowseViewModel.current.state
val onEvent = LocalBrowseViewModel.current.onEvent val onEvent = LocalBrowseViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
CustomAnimatedVisibility( CustomAnimatedVisibility(
visible = state.value.isError, visible = state.value.isError,

View file

@ -21,7 +21,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalBrowseViewModel
import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithLazyColumn import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithLazyColumn
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
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.library.data.LibraryEvent import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
@ -36,7 +36,7 @@ fun BrowseAddingDialog() {
val state = LocalBrowseViewModel.current.state val state = LocalBrowseViewModel.current.state
val onEvent = LocalBrowseViewModel.current.onEvent val onEvent = LocalBrowseViewModel.current.onEvent
val onLibraryEvent = LocalLibraryViewModel.current.onEvent val onLibraryEvent = LocalLibraryViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
CustomDialogWithLazyColumn( CustomDialogWithLazyColumn(
title = stringResource(id = R.string.add_books), title = stringResource(id = R.string.add_books),

View file

@ -31,7 +31,7 @@ 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
import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel
import ua.acclorite.book_story.presentation.core.components.MoreDropDown import ua.acclorite.book_story.presentation.core.navigation.NavigationIconButton
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
@ -119,7 +119,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
) { ) {
onEvent(BrowseEvent.OnShowHideFilterBottomSheet) onEvent(BrowseEvent.OnShowHideFilterBottomSheet)
} }
MoreDropDown() NavigationIconButton()
} }
), ),
@ -164,7 +164,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
) { ) {
onEvent(BrowseEvent.OnShowHideFilterBottomSheet) onEvent(BrowseEvent.OnShowHideFilterBottomSheet)
} }
MoreDropDown() NavigationIconButton()
} }
), ),
@ -200,7 +200,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
) )
}, },
contentActions = { contentActions = {
MoreDropDown() NavigationIconButton()
} }
), ),

View file

@ -37,7 +37,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalStartViewModel
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.constants.Constants import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.data.MainEvent import ua.acclorite.book_story.presentation.data.MainEvent
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
@ -65,7 +65,7 @@ private fun HelpScreen() {
val onMainEvent = LocalMainViewModel.current.onEvent val onMainEvent = LocalMainViewModel.current.onEvent
val onBrowseEvent = LocalBrowseViewModel.current.onEvent val onBrowseEvent = LocalBrowseViewModel.current.onEvent
val onStartEvent = LocalStartViewModel.current.onEvent val onStartEvent = LocalStartViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()

View file

@ -30,7 +30,7 @@ import androidx.compose.ui.text.buildAnnotatedString
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.domain.model.HelpTip import ua.acclorite.book_story.domain.model.HelpTip
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.util.noRippleClickable import ua.acclorite.book_story.presentation.core.util.noRippleClickable
import ua.acclorite.book_story.presentation.ui.ExpandingTransition import ua.acclorite.book_story.presentation.ui.ExpandingTransition
@ -46,7 +46,7 @@ fun HelpItem(
helpTip: HelpTip, helpTip: HelpTip,
fromStart: Boolean fromStart: Boolean
) { ) {
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val showDescription = rememberSaveable { val showDescription = rememberSaveable {
mutableStateOf(false) mutableStateOf(false)

View file

@ -44,10 +44,10 @@ import ua.acclorite.book_story.presentation.core.components.CustomSearchTextFiel
import ua.acclorite.book_story.presentation.core.components.CustomSnackbar import ua.acclorite.book_story.presentation.core.components.CustomSnackbar
import ua.acclorite.book_story.presentation.core.components.LocalHistoryViewModel import ua.acclorite.book_story.presentation.core.components.LocalHistoryViewModel
import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel
import ua.acclorite.book_story.presentation.core.components.MoreDropDown
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.NavigationIconButton
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.screens.history.components.HistoryDeleteWholeHistoryDialog import ua.acclorite.book_story.presentation.screens.history.components.HistoryDeleteWholeHistoryDialog
import ua.acclorite.book_story.presentation.screens.history.components.HistoryItem import ua.acclorite.book_story.presentation.screens.history.components.HistoryItem
@ -77,7 +77,7 @@ private fun HistoryScreen() {
val state = LocalHistoryViewModel.current.state val state = LocalHistoryViewModel.current.state
val onEvent = LocalHistoryViewModel.current.onEvent val onEvent = LocalHistoryViewModel.current.onEvent
val onLibraryEvent = LocalLibraryViewModel.current.onEvent val onLibraryEvent = LocalLibraryViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val refreshState = rememberPullRefreshState( val refreshState = rememberPullRefreshState(
refreshing = state.value.isRefreshing, refreshing = state.value.isRefreshing,
@ -132,7 +132,7 @@ private fun HistoryScreen() {
) { ) {
onEvent(HistoryEvent.OnShowHideDeleteWholeHistoryDialog) onEvent(HistoryEvent.OnShowHideDeleteWholeHistoryDialog)
} }
MoreDropDown() NavigationIconButton()
} }
), ),
@ -168,7 +168,7 @@ private fun HistoryScreen() {
) )
}, },
contentActions = { contentActions = {
MoreDropDown() NavigationIconButton()
}, },
) )
) )

View file

@ -51,7 +51,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel
import ua.acclorite.book_story.presentation.core.components.customItems import ua.acclorite.book_story.presentation.core.components.customItems
import ua.acclorite.book_story.presentation.core.components.header import ua.acclorite.book_story.presentation.core.components.header
import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
import ua.acclorite.book_story.presentation.screens.library.components.LibraryBookItem import ua.acclorite.book_story.presentation.screens.library.components.LibraryBookItem
@ -102,7 +102,7 @@ private fun LibraryScreen(
val state = LocalLibraryViewModel.current.state val state = LocalLibraryViewModel.current.state
val mainState = LocalMainViewModel.current.state val mainState = LocalMainViewModel.current.state
val onEvent = LocalLibraryViewModel.current.onEvent val onEvent = LocalLibraryViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
var isScrollInProgress by remember { mutableStateOf(false) } var isScrollInProgress by remember { mutableStateOf(false) }

View file

@ -36,7 +36,7 @@ import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarDat
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
import ua.acclorite.book_story.presentation.core.components.MoreDropDown import ua.acclorite.book_story.presentation.core.navigation.NavigationIconButton
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
/** /**
@ -90,7 +90,7 @@ fun LibraryTopBar(pagerState: PagerState) {
) { ) {
onEvent(LibraryEvent.OnSearchShowHide) onEvent(LibraryEvent.OnSearchShowHide)
} }
MoreDropDown() NavigationIconButton()
} }
), ),
@ -128,7 +128,7 @@ fun LibraryTopBar(pagerState: PagerState) {
) )
}, },
contentActions = { contentActions = {
MoreDropDown() NavigationIconButton()
}, },
), ),

View file

@ -68,7 +68,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalSettingsViewMod
import ua.acclorite.book_story.presentation.core.components.customItemsIndexed import ua.acclorite.book_story.presentation.core.components.customItemsIndexed
import ua.acclorite.book_story.presentation.core.components.is_messages.IsError import ua.acclorite.book_story.presentation.core.components.is_messages.IsError
import ua.acclorite.book_story.presentation.core.constants.Constants import ua.acclorite.book_story.presentation.core.constants.Constants
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.core.util.noRippleClickable import ua.acclorite.book_story.presentation.core.util.noRippleClickable
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
@ -94,7 +94,7 @@ fun ReaderScreenRoot(screen: Screen.Reader) {
val onHistoryEvent = LocalHistoryViewModel.current.onEvent val onHistoryEvent = LocalHistoryViewModel.current.onEvent
val viewModel = LocalReaderViewModel.current.viewModel val viewModel = LocalReaderViewModel.current.viewModel
val context = LocalContext.current as ComponentActivity val context = LocalContext.current as ComponentActivity
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val lazyListState = rememberSaveable( val lazyListState = rememberSaveable(
@ -202,7 +202,7 @@ private fun ReaderScreen(lazyListState: LazyListState) {
val onLibraryEvent = LocalLibraryViewModel.current.onEvent val onLibraryEvent = LocalLibraryViewModel.current.onEvent
val onHistoryEvent = LocalHistoryViewModel.current.onEvent val onHistoryEvent = LocalHistoryViewModel.current.onEvent
val context = LocalContext.current as ComponentActivity val context = LocalContext.current as ComponentActivity
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val nestedScrollConnection = remember(state) { val nestedScrollConnection = remember(state) {
object : NestedScrollConnection { object : NestedScrollConnection {

View file

@ -9,7 +9,7 @@ import androidx.compose.ui.res.stringResource
import ua.acclorite.book_story.R import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.LocalReaderViewModel import ua.acclorite.book_story.presentation.core.components.LocalReaderViewModel
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithContent import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithContent
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent
/** /**
@ -19,7 +19,7 @@ import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent
@Composable @Composable
fun ReaderUpdateDialog() { fun ReaderUpdateDialog() {
val onEvent = LocalReaderViewModel.current.onEvent val onEvent = LocalReaderViewModel.current.onEvent
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val context = LocalContext.current val context = LocalContext.current
CustomDialogWithContent( CustomDialogWithContent(

View file

@ -42,7 +42,7 @@ import ua.acclorite.book_story.presentation.core.components.LocalHistoryViewMode
import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel import ua.acclorite.book_story.presentation.core.components.LocalLibraryViewModel
import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel import ua.acclorite.book_story.presentation.core.components.LocalMainViewModel
import ua.acclorite.book_story.presentation.core.components.LocalReaderViewModel import ua.acclorite.book_story.presentation.core.components.LocalReaderViewModel
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.core.util.noRippleClickable import ua.acclorite.book_story.presentation.core.util.noRippleClickable
import ua.acclorite.book_story.presentation.core.util.showToast import ua.acclorite.book_story.presentation.core.util.showToast
@ -64,7 +64,7 @@ fun ReaderTopBar() {
val onLibraryEvent = LocalLibraryViewModel.current.onEvent val onLibraryEvent = LocalLibraryViewModel.current.onEvent
val onHistoryEvent = LocalHistoryViewModel.current.onEvent val onHistoryEvent = LocalHistoryViewModel.current.onEvent
val context = LocalContext.current as ComponentActivity val context = LocalContext.current as ComponentActivity
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val animatedChapterProgress = animateFloatAsState( val animatedChapterProgress = animateFloatAsState(
targetValue = state.value.currentChapterProgress targetValue = state.value.currentChapterProgress

View file

@ -27,7 +27,7 @@ import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.core.components.GoBackButton import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.core.navigation.Screen import ua.acclorite.book_story.presentation.core.navigation.Screen
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryItem import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryItem
@ -39,7 +39,7 @@ fun SettingsScreenRoot() {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun SettingsScreen() { private fun SettingsScreen() {
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
Scaffold( Scaffold(

View file

@ -20,7 +20,7 @@ import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.core.components.GoBackButton import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.AppearanceSettingsCategory import ua.acclorite.book_story.presentation.screens.settings.nested.appearance.components.AppearanceSettingsCategory
@Composable @Composable
@ -31,7 +31,7 @@ fun AppearanceSettingsRoot() {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun AppearanceSettings() { private fun AppearanceSettings() {
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
Scaffold( Scaffold(

View file

@ -20,7 +20,7 @@ import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.core.components.GoBackButton import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.components.BrowseSettingsCategory import ua.acclorite.book_story.presentation.screens.settings.nested.browse.components.BrowseSettingsCategory
@Composable @Composable
@ -31,7 +31,7 @@ fun BrowseSettingsRoot() {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun BrowseSettings() { private fun BrowseSettings() {
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
Scaffold( Scaffold(

View file

@ -19,7 +19,7 @@ import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.core.components.GoBackButton import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.screens.settings.nested.general.components.GeneralSettingsCategory import ua.acclorite.book_story.presentation.screens.settings.nested.general.components.GeneralSettingsCategory
@Composable @Composable
@ -31,7 +31,7 @@ fun GeneralSettingsRoot() {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun GeneralSettings() { private fun GeneralSettings() {
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
Scaffold( Scaffold(

View file

@ -19,7 +19,7 @@ import ua.acclorite.book_story.R
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.core.components.GoBackButton import ua.acclorite.book_story.presentation.core.components.GoBackButton
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.core.navigation.LocalOnNavigate import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.ReaderSettingsCategory import ua.acclorite.book_story.presentation.screens.settings.nested.reader.components.ReaderSettingsCategory
@Composable @Composable
@ -30,7 +30,7 @@ fun ReaderSettingsRoot() {
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
private fun ReaderSettings() { private fun ReaderSettings() {
val onNavigate = LocalOnNavigate.current val onNavigate = LocalNavigator.current
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState() val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
Scaffold( Scaffold(

View file

@ -44,7 +44,7 @@ fun StartDone() {
val onEvent = LocalStartViewModel.current.onEvent val onEvent = LocalStartViewModel.current.onEvent
val onMainEvent = LocalMainViewModel.current.onEvent val onMainEvent = LocalMainViewModel.current.onEvent
val onBrowseEvent = LocalBrowseViewModel.current.onEvent val onBrowseEvent = LocalBrowseViewModel.current.onEvent
val navigator = LocalNavigator.current val onNavigate = LocalNavigator.current
StartNavigationTransition( StartNavigationTransition(
modifier = Modifier modifier = Modifier
@ -71,7 +71,7 @@ fun StartDone() {
onClick = { onClick = {
onEvent( onEvent(
StartEvent.OnGoToBrowse( StartEvent.OnGoToBrowse(
onNavigate = { navigator.it() }, onNavigate = onNavigate,
onCompletedStartGuide = { onCompletedStartGuide = {
onBrowseEvent(BrowseEvent.OnLoadList) onBrowseEvent(BrowseEvent.OnLoadList)
onMainEvent( onMainEvent(
@ -90,7 +90,7 @@ fun StartDone() {
shape = RoundedCornerShape(100), shape = RoundedCornerShape(100),
onClick = { onClick = {
onEvent( onEvent(
StartEvent.OnGoToHelp { navigator.it() } StartEvent.OnGoToHelp(onNavigate = onNavigate)
) )
} }
) { ) {

View file

@ -170,7 +170,6 @@
<string name="open_reader_settings_content_desc">Reader-Einstellungen</string> <string name="open_reader_settings_content_desc">Reader-Einstellungen</string>
<string name="file_icon_content_desc">Datei</string> <string name="file_icon_content_desc">Datei</string>
<string name="checkbox_content_desc">Checkbox</string> <string name="checkbox_content_desc">Checkbox</string>
<string name="show_dropdown_content_desc">Dropdown</string>
<string name="cover_image_not_found_content_desc">Titelbild nicht gefunden</string> <string name="cover_image_not_found_content_desc">Titelbild nicht gefunden</string>
<string name="apply_changes_content_desc">Änderungen übernehmen</string> <string name="apply_changes_content_desc">Änderungen übernehmen</string>
<string name="error_content_desc">Fehler</string> <string name="error_content_desc">Fehler</string>

View file

@ -246,7 +246,6 @@
<string name="go_back_content_desc">Regresar</string> <string name="go_back_content_desc">Regresar</string>
<string name="cover_image_content_desc">Portada</string> <string name="cover_image_content_desc">Portada</string>
<string name="file_icon_content_desc">Archivo</string> <string name="file_icon_content_desc">Archivo</string>
<string name="show_dropdown_content_desc">Desplegable</string>
<string name="cover_image_not_found_content_desc">Portada no encontrada</string> <string name="cover_image_not_found_content_desc">Portada no encontrada</string>
<string name="apply_changes_content_desc">Aplicar cambios</string> <string name="apply_changes_content_desc">Aplicar cambios</string>
<string name="error_content_desc">Error</string> <string name="error_content_desc">Error</string>

View file

@ -227,7 +227,6 @@
<string name="directory_icon_content_desc">Répertoire</string> <string name="directory_icon_content_desc">Répertoire</string>
<string name="path_arrow_icon_content_desc">Flèche du chemin</string> <string name="path_arrow_icon_content_desc">Flèche du chemin</string>
<string name="checkbox_content_desc">Case à cocher</string> <string name="checkbox_content_desc">Case à cocher</string>
<string name="show_dropdown_content_desc">Menu déroulant</string>
<string name="cover_image_not_found_content_desc">L\'image de couverture n\'a pas été trouvée</string> <string name="cover_image_not_found_content_desc">L\'image de couverture n\'a pas été trouvée</string>
<string name="apply_changes_content_desc">Appliquer les changements</string> <string name="apply_changes_content_desc">Appliquer les changements</string>
<string name="error_content_desc">Erreur</string> <string name="error_content_desc">Erreur</string>

View file

@ -206,7 +206,6 @@
<string name="credits_fonts">Czcionki</string> <string name="credits_fonts">Czcionki</string>
<string name="delete_books_content_desc">Usuń wybrane książki</string> <string name="delete_books_content_desc">Usuń wybrane książki</string>
<string name="browse_content_desc">Dodaj książki</string> <string name="browse_content_desc">Dodaj książki</string>
<string name="show_dropdown_content_desc">Rozwijany</string>
<string name="create_color_preset_content_desc">Utwórz nowe ustawienie koloru</string> <string name="create_color_preset_content_desc">Utwórz nowe ustawienie koloru</string>
<string name="help_desc_how_to_customize_app_3">Możesz to zrobić z poziomu ekranu Biblioteka, Historia i Przeglądaj, klikając trzy kropki w prawym górnym rogu i wybierając « Ustawienia » z menu rozwijanego. Następnie zobaczysz wszystkie dostępne ustawienia tej aplikacji. Eksperymentuj z nimi!</string> <string name="help_desc_how_to_customize_app_3">Możesz to zrobić z poziomu ekranu Biblioteka, Historia i Przeglądaj, klikając trzy kropki w prawym górnym rogu i wybierając « Ustawienia » z menu rozwijanego. Następnie zobaczysz wszystkie dostępne ustawienia tej aplikacji. Eksperymentuj z nimi!</string>
<string name="continue_reading_content_desc">Kontynuuj czytanie</string> <string name="continue_reading_content_desc">Kontynuuj czytanie</string>

View file

@ -298,7 +298,6 @@
<string name="sort_order_content_desc">Sıralama düzeni</string> <string name="sort_order_content_desc">Sıralama düzeni</string>
<string name="path_arrow_icon_content_desc">Yol oku</string> <string name="path_arrow_icon_content_desc">Yol oku</string>
<string name="checkbox_content_desc">Onay kutusu</string> <string name="checkbox_content_desc">Onay kutusu</string>
<string name="show_dropdown_content_desc">ılır menü</string>
<string name="cover_image_not_found_content_desc">Kapak resmi bulunamadı</string> <string name="cover_image_not_found_content_desc">Kapak resmi bulunamadı</string>
<string name="apply_changes_content_desc">Değişiklikleri uygula</string> <string name="apply_changes_content_desc">Değişiklikleri uygula</string>
<string name="error_content_desc">Hata</string> <string name="error_content_desc">Hata</string>

View file

@ -605,7 +605,6 @@
<string name="sort_order_content_desc">Порядок сортування</string> <string name="sort_order_content_desc">Порядок сортування</string>
<string name="path_arrow_icon_content_desc">Стрілка шляху</string> <string name="path_arrow_icon_content_desc">Стрілка шляху</string>
<string name="checkbox_content_desc">Галочка</string> <string name="checkbox_content_desc">Галочка</string>
<string name="show_dropdown_content_desc">Випадаючий список</string>
<string name="cover_image_not_found_content_desc">Обкладенка не знайдена</string> <string name="cover_image_not_found_content_desc">Обкладенка не знайдена</string>
<string name="apply_changes_content_desc">Застосувати зміни</string> <string name="apply_changes_content_desc">Застосувати зміни</string>
<string name="error_content_desc">Помилка</string> <string name="error_content_desc">Помилка</string>
@ -641,5 +640,6 @@
<string name="checkpoint_forward_content_desc">Чекпоінт вперед</string> <string name="checkpoint_forward_content_desc">Чекпоінт вперед</string>
<string name="chapters_content_desc">Розділи</string> <string name="chapters_content_desc">Розділи</string>
<string name="update_text_content_desc">Оновити текст</string> <string name="update_text_content_desc">Оновити текст</string>
<string name="more_content_desc">Більше</string>
</resources> </resources>

View file

@ -605,7 +605,6 @@
<string name="sort_order_content_desc">Sort order</string> <string name="sort_order_content_desc">Sort order</string>
<string name="path_arrow_icon_content_desc">Path arrow</string> <string name="path_arrow_icon_content_desc">Path arrow</string>
<string name="checkbox_content_desc">Checkbox</string> <string name="checkbox_content_desc">Checkbox</string>
<string name="show_dropdown_content_desc">Dropdown</string>
<string name="cover_image_not_found_content_desc">Cover image not found</string> <string name="cover_image_not_found_content_desc">Cover image not found</string>
<string name="apply_changes_content_desc">Apply changes</string> <string name="apply_changes_content_desc">Apply changes</string>
<string name="error_content_desc">Error</string> <string name="error_content_desc">Error</string>
@ -644,5 +643,6 @@
<string name="checkpoint_forward_content_desc">Checkpoint forward</string> <string name="checkpoint_forward_content_desc">Checkpoint forward</string>
<string name="chapters_content_desc">Chapters</string> <string name="chapters_content_desc">Chapters</string>
<string name="update_text_content_desc">Update text</string> <string name="update_text_content_desc">Update text</string>
<string name="more_content_desc">More</string>
</resources> </resources>