🚀 Replace DropDown with BottomSheet
* Replaced DropDown with NavigationBottomSheet * Renamed LocalOnNavigate → LocalNavigator, LocalNavigator → LocalNavigatorInstance
This commit is contained in:
parent
7618190ada
commit
2e2dee9e26
47 changed files with 408 additions and 307 deletions
|
|
@ -0,0 +1,8 @@
|
|||
package ua.acclorite.book_story.domain.util
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
|
||||
@Immutable
|
||||
enum class Position {
|
||||
TOP, CENTER, BOTTOM, SOLO
|
||||
}
|
||||
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
|
|
@ -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)
|
||||
)
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ import androidx.compose.runtime.remember
|
|||
import androidx.compose.runtime.setValue
|
||||
import ua.acclorite.book_story.domain.util.Route
|
||||
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].
|
||||
|
|
@ -17,7 +17,7 @@ import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
|||
@Composable
|
||||
fun BottomNavigationBar() {
|
||||
var currentScreen: Route? by remember { mutableStateOf(null) }
|
||||
val navigator = LocalNavigator.current
|
||||
val navigator = LocalNavigatorInstance.current
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
navigator.currentScreen.collect { route ->
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ import androidx.compose.ui.platform.LocalLayoutDirection
|
|||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.domain.util.Route
|
||||
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.
|
||||
|
|
@ -33,7 +33,7 @@ import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
|||
@Composable
|
||||
fun CustomNavigationRail() {
|
||||
var currentScreen: Route? by remember { mutableStateOf(null) }
|
||||
val navigator = LocalNavigator.current
|
||||
val navigator = LocalNavigatorInstance.current
|
||||
val layoutDirection = LocalLayoutDirection.current
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ import dagger.assisted.AssistedInject
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import dagger.hilt.android.lifecycle.withCreationCallback
|
||||
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.parcelize.Parcelize
|
||||
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 SCREENS = "screens"
|
||||
|
||||
/**
|
||||
* Passed in [CompositionLocalProvider].
|
||||
*/
|
||||
val LocalNavigator = compositionLocalOf<Navigator> {
|
||||
val LocalNavigatorInstance = compositionLocalOf<Navigator> {
|
||||
error("Cannot initialize Navigator.")
|
||||
}
|
||||
val LocalOnNavigate = compositionLocalOf<OnNavigate> {
|
||||
val LocalNavigator = compositionLocalOf<OnNavigate> {
|
||||
error("Cannot initialize Navigator.")
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +162,9 @@ class Navigator @AssistedInject constructor(
|
|||
private val backStack = savedStateHandle.getStateFlow(BACKSTACK, mutableListOf<Route>())
|
||||
val screens = savedStateHandle.getStateFlow(SCREENS, mutableListOf<Screen>())
|
||||
|
||||
private val _showNavigationBottomSheet = MutableStateFlow(false)
|
||||
private val showNavigationBottomSheet = _showNavigationBottomSheet.asStateFlow()
|
||||
|
||||
init {
|
||||
putScreen(startScreen)
|
||||
}
|
||||
|
|
@ -276,6 +279,20 @@ class Navigator @AssistedInject constructor(
|
|||
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].
|
||||
* Each [composable] should have unique [Screen].
|
||||
|
|
@ -340,27 +357,36 @@ class Navigator @AssistedInject constructor(
|
|||
content: @Composable () -> Unit
|
||||
) {
|
||||
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 tabletUI = remember(windowClass) {
|
||||
windowClass.widthSizeClass != WindowWidthSizeClass.Compact
|
||||
}
|
||||
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(
|
||||
visible = shouldShow,
|
||||
visible = showNavigation.value,
|
||||
enter = if (useBackAnimation) backEnterBarAnim
|
||||
else enterBarAnim,
|
||||
exit = if (useBackAnimation) backExitBarAnim
|
||||
else exitBarAnim
|
||||
) {
|
||||
if (showNavigationBottomSheet.value) {
|
||||
NavigationBottomSheet(
|
||||
onDismissRequest = {
|
||||
hideNavigationBottomSheet()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
bottomBar = {
|
||||
if (!tabletUI) {
|
||||
|
|
@ -440,8 +466,8 @@ fun NavigationHost(
|
|||
)
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalNavigator provides navigator,
|
||||
LocalOnNavigate provides { navigator.it() }
|
||||
LocalNavigatorInstance provides navigator,
|
||||
LocalNavigator provides { navigator.it() }
|
||||
) {
|
||||
content(navigator)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
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.util.showToast
|
||||
import ua.acclorite.book_story.presentation.screens.about.components.AboutItem
|
||||
|
|
@ -51,7 +51,7 @@ fun AboutScreenRoot() {
|
|||
private fun AboutScreen() {
|
||||
val state = LocalAboutViewModel.current.state
|
||||
val onEvent = LocalAboutViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
|
|
|||
|
|
@ -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.customItems
|
||||
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.screens.about.data.AboutEvent
|
||||
import ua.acclorite.book_story.presentation.screens.about.nested.credits.components.CreditItem
|
||||
|
|
@ -37,7 +37,7 @@ fun CreditsScreenRoot() {
|
|||
@Composable
|
||||
private fun CreditsScreen() {
|
||||
val onEvent = LocalAboutViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
|
|
|||
|
|
@ -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.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
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.util.showToast
|
||||
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
|
||||
fun LicenseInfoScreenRoot(screen: Screen.About.LicenseInfo) {
|
||||
val viewModel = LocalLicenseInfoViewModel.current.viewModel
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
|
@ -68,7 +68,7 @@ private fun LicenseInfoScreen() {
|
|||
val state = LocalLicenseInfoViewModel.current.state
|
||||
val onEvent = LocalLicenseInfoViewModel.current.onEvent
|
||||
val context = LocalContext.current
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
val licenses = remember(state.value.license?.licenses) {
|
||||
|
|
|
|||
|
|
@ -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.collapsibleUntilExitScrollBehaviorWithLazyListState
|
||||
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.screens.about.nested.licenses.components.LicenseItem
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ fun LicensesScreenRoot() {
|
|||
@Composable
|
||||
private fun LicensesScreen() {
|
||||
val state = LocalLicensesViewModel.current.state
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState(
|
||||
state.value.listState
|
||||
|
|
|
|||
|
|
@ -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.CustomSnackbar
|
||||
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.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.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.BookInfoTopBar
|
||||
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
|
||||
fun BookInfoScreenRoot(screen: Screen.BookInfo) {
|
||||
val viewModel = LocalBookInfoViewModel.current.viewModel
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val snackbarState = remember { SnackbarHostState() }
|
||||
|
|
@ -95,7 +96,7 @@ private fun BookInfoScreen(snackbarState: SnackbarHostState) {
|
|||
val context = LocalContext.current
|
||||
val state = LocalBookInfoViewModel.current.state
|
||||
val onEvent = LocalBookInfoViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val listState = rememberLazyListState()
|
||||
val refreshState = rememberPullRefreshState(
|
||||
|
|
@ -125,6 +126,9 @@ private fun BookInfoScreen(snackbarState: SnackbarHostState) {
|
|||
if (state.value.showConfirmTextUpdateDialog) {
|
||||
BookInfoConfirmUpdateDialog(snackbarHostState = snackbarState)
|
||||
}
|
||||
if (state.value.showMoreBottomSheet) {
|
||||
BookInfoMoreBottomSheet(snackbarState = snackbarState)
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
Modifier
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.LocalHistoryViewModel
|
||||
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.history.data.HistoryEvent
|
||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
||||
|
|
@ -50,7 +51,7 @@ fun BookInfoTopBar(
|
|||
val onEvent = LocalBookInfoViewModel.current.onEvent
|
||||
val onLibraryEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onHistoryEvent = LocalHistoryViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val firstVisibleItemIndex by remember { derivedStateOf { listState.firstVisibleItemIndex } }
|
||||
|
|
@ -127,7 +128,9 @@ fun BookInfoTopBar(
|
|||
!state.value.editAuthor &&
|
||||
!state.value.editDescription
|
||||
) {
|
||||
BookInfoMoreDropDown(snackbarState = snackbarState)
|
||||
NavigationIconButton {
|
||||
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(true))
|
||||
}
|
||||
}
|
||||
CustomAnimatedVisibility(
|
||||
visible = state.value.editTitle ||
|
||||
|
|
|
|||
|
|
@ -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.LocalLibraryViewModel
|
||||
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.screens.book_info.data.BookInfoEvent
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||
|
|
@ -27,7 +27,7 @@ fun BookInfoDeleteDialog() {
|
|||
val onLibraryEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onHistoryEvent = LocalHistoryViewModel.current.onEvent
|
||||
val onBrowseEvent = LocalBrowseViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
CustomDialogWithContent(
|
||||
|
|
@ -51,6 +51,7 @@ fun BookInfoDeleteDialog() {
|
|||
}
|
||||
)
|
||||
)
|
||||
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(false))
|
||||
context.getString(R.string.book_deleted)
|
||||
.showToast(context = context)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.custom_dialog.CustomDialogWithLazyColumn
|
||||
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.screens.book_info.data.BookInfoEvent
|
||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||
|
|
@ -31,7 +31,7 @@ fun BookInfoMoveDialog() {
|
|||
val onEvent = LocalBookInfoViewModel.current.onEvent
|
||||
val onLibraryEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onHistoryEvent = LocalHistoryViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val categories = remember {
|
||||
|
|
@ -64,6 +64,7 @@ fun BookInfoMoveDialog() {
|
|||
onNavigate = onNavigate
|
||||
)
|
||||
)
|
||||
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(false))
|
||||
context.getString(R.string.book_moved)
|
||||
.showToast(context = context)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -124,4 +124,6 @@ sealed class BookInfoEvent {
|
|||
val context: Context,
|
||||
val refreshList: (Book) -> Unit
|
||||
) : BookInfoEvent()
|
||||
|
||||
data class OnShowHideMoreBottomSheet(val show: Boolean) : BookInfoEvent()
|
||||
}
|
||||
|
|
@ -37,4 +37,6 @@ data class BookInfoState(
|
|||
val showDeleteDialog: Boolean = false,
|
||||
val showMoveDialog: Boolean = false,
|
||||
val selectedCategory: Category = Category.READING,
|
||||
|
||||
val showMoreBottomSheet: Boolean = false,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -728,6 +728,14 @@ class BookInfoViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
is BookInfoEvent.OnShowHideMoreBottomSheet -> {
|
||||
_state.update {
|
||||
it.copy(
|
||||
showMoreBottomSheet = event.show
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ import ua.acclorite.book_story.R
|
|||
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.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.util.showToast
|
||||
import ua.acclorite.book_story.presentation.screens.browse.components.BrowseEmptyPlaceholder
|
||||
|
|
@ -89,7 +89,7 @@ private fun BrowseScreen(
|
|||
val state = LocalBrowseViewModel.current.state
|
||||
val mainState = LocalMainViewModel.current.state
|
||||
val onEvent = LocalBrowseViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
val refreshState = rememberPullRefreshState(
|
||||
|
|
|
|||
|
|
@ -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.is_messages.IsEmpty
|
||||
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.screens.browse.data.BrowseEvent
|
||||
import ua.acclorite.book_story.presentation.ui.Transitions
|
||||
|
|
@ -33,7 +33,7 @@ fun BoxScope.BrowseEmptyPlaceholder(
|
|||
) {
|
||||
val state = LocalBrowseViewModel.current.state
|
||||
val onEvent = LocalBrowseViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
CustomAnimatedVisibility(
|
||||
visible = state.value.isError,
|
||||
|
|
|
|||
|
|
@ -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.customItems
|
||||
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.screens.browse.data.BrowseEvent
|
||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
||||
|
|
@ -36,7 +36,7 @@ fun BrowseAddingDialog() {
|
|||
val state = LocalBrowseViewModel.current.state
|
||||
val onEvent = LocalBrowseViewModel.current.onEvent
|
||||
val onLibraryEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
CustomDialogWithLazyColumn(
|
||||
title = stringResource(id = R.string.add_books),
|
||||
|
|
|
|||
|
|
@ -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.LocalBrowseViewModel
|
||||
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.settings.nested.browse.data.BrowseFilesStructure
|
||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseLayout
|
||||
|
|
@ -119,7 +119,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
|||
) {
|
||||
onEvent(BrowseEvent.OnShowHideFilterBottomSheet)
|
||||
}
|
||||
MoreDropDown()
|
||||
NavigationIconButton()
|
||||
}
|
||||
),
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
|||
) {
|
||||
onEvent(BrowseEvent.OnShowHideFilterBottomSheet)
|
||||
}
|
||||
MoreDropDown()
|
||||
NavigationIconButton()
|
||||
}
|
||||
),
|
||||
|
||||
|
|
@ -200,7 +200,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
|||
)
|
||||
},
|
||||
contentActions = {
|
||||
MoreDropDown()
|
||||
NavigationIconButton()
|
||||
}
|
||||
),
|
||||
|
||||
|
|
|
|||
|
|
@ -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.customItems
|
||||
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.data.MainEvent
|
||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||
|
|
@ -65,7 +65,7 @@ private fun HelpScreen() {
|
|||
val onMainEvent = LocalMainViewModel.current.onEvent
|
||||
val onBrowseEvent = LocalBrowseViewModel.current.onEvent
|
||||
val onStartEvent = LocalStartViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import androidx.compose.ui.text.buildAnnotatedString
|
|||
import androidx.compose.ui.unit.dp
|
||||
import ua.acclorite.book_story.R
|
||||
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.ui.ExpandingTransition
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ fun HelpItem(
|
|||
helpTip: HelpTip,
|
||||
fromStart: Boolean
|
||||
) {
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val showDescription = rememberSaveable {
|
||||
mutableStateOf(false)
|
||||
|
|
|
|||
|
|
@ -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.LocalHistoryViewModel
|
||||
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.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.screens.history.components.HistoryDeleteWholeHistoryDialog
|
||||
import ua.acclorite.book_story.presentation.screens.history.components.HistoryItem
|
||||
|
|
@ -77,7 +77,7 @@ private fun HistoryScreen() {
|
|||
val state = LocalHistoryViewModel.current.state
|
||||
val onEvent = LocalHistoryViewModel.current.onEvent
|
||||
val onLibraryEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val refreshState = rememberPullRefreshState(
|
||||
refreshing = state.value.isRefreshing,
|
||||
|
|
@ -132,7 +132,7 @@ private fun HistoryScreen() {
|
|||
) {
|
||||
onEvent(HistoryEvent.OnShowHideDeleteWholeHistoryDialog)
|
||||
}
|
||||
MoreDropDown()
|
||||
NavigationIconButton()
|
||||
}
|
||||
),
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ private fun HistoryScreen() {
|
|||
)
|
||||
},
|
||||
contentActions = {
|
||||
MoreDropDown()
|
||||
NavigationIconButton()
|
||||
},
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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.header
|
||||
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.util.showToast
|
||||
import ua.acclorite.book_story.presentation.screens.library.components.LibraryBookItem
|
||||
|
|
@ -102,7 +102,7 @@ private fun LibraryScreen(
|
|||
val state = LocalLibraryViewModel.current.state
|
||||
val mainState = LocalMainViewModel.current.state
|
||||
val onEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
var isScrollInProgress by remember { mutableStateOf(false) }
|
||||
|
||||
|
|
|
|||
|
|
@ -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.CustomSearchTextField
|
||||
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
|
||||
|
||||
/**
|
||||
|
|
@ -90,7 +90,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
|||
) {
|
||||
onEvent(LibraryEvent.OnSearchShowHide)
|
||||
}
|
||||
MoreDropDown()
|
||||
NavigationIconButton()
|
||||
}
|
||||
),
|
||||
|
||||
|
|
@ -128,7 +128,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
|||
)
|
||||
},
|
||||
contentActions = {
|
||||
MoreDropDown()
|
||||
NavigationIconButton()
|
||||
},
|
||||
),
|
||||
|
||||
|
|
|
|||
|
|
@ -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.is_messages.IsError
|
||||
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.util.noRippleClickable
|
||||
import ua.acclorite.book_story.presentation.core.util.showToast
|
||||
|
|
@ -94,7 +94,7 @@ fun ReaderScreenRoot(screen: Screen.Reader) {
|
|||
val onHistoryEvent = LocalHistoryViewModel.current.onEvent
|
||||
val viewModel = LocalReaderViewModel.current.viewModel
|
||||
val context = LocalContext.current as ComponentActivity
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
|
||||
val lazyListState = rememberSaveable(
|
||||
|
|
@ -202,7 +202,7 @@ private fun ReaderScreen(lazyListState: LazyListState) {
|
|||
val onLibraryEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onHistoryEvent = LocalHistoryViewModel.current.onEvent
|
||||
val context = LocalContext.current as ComponentActivity
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val nestedScrollConnection = remember(state) {
|
||||
object : NestedScrollConnection {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import androidx.compose.ui.res.stringResource
|
|||
import ua.acclorite.book_story.R
|
||||
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.navigation.LocalOnNavigate
|
||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
||||
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
|
||||
fun ReaderUpdateDialog() {
|
||||
val onEvent = LocalReaderViewModel.current.onEvent
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val context = LocalContext.current
|
||||
|
||||
CustomDialogWithContent(
|
||||
|
|
|
|||
|
|
@ -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.LocalMainViewModel
|
||||
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.util.noRippleClickable
|
||||
import ua.acclorite.book_story.presentation.core.util.showToast
|
||||
|
|
@ -64,7 +64,7 @@ fun ReaderTopBar() {
|
|||
val onLibraryEvent = LocalLibraryViewModel.current.onEvent
|
||||
val onHistoryEvent = LocalHistoryViewModel.current.onEvent
|
||||
val context = LocalContext.current as ComponentActivity
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
val animatedChapterProgress = animateFloatAsState(
|
||||
targetValue = state.value.currentChapterProgress
|
||||
|
|
|
|||
|
|
@ -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.GoBackButton
|
||||
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.screens.settings.components.SettingsCategoryItem
|
||||
|
||||
|
|
@ -39,7 +39,7 @@ fun SettingsScreenRoot() {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun SettingsScreen() {
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
Scaffold(
|
||||
|
|
|
|||
|
|
@ -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.GoBackButton
|
||||
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
|
||||
|
||||
@Composable
|
||||
|
|
@ -31,7 +31,7 @@ fun AppearanceSettingsRoot() {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun AppearanceSettings() {
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
Scaffold(
|
||||
|
|
|
|||
|
|
@ -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.GoBackButton
|
||||
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
|
||||
|
||||
@Composable
|
||||
|
|
@ -31,7 +31,7 @@ fun BrowseSettingsRoot() {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun BrowseSettings() {
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
Scaffold(
|
||||
|
|
|
|||
|
|
@ -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.GoBackButton
|
||||
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
|
||||
|
||||
@Composable
|
||||
|
|
@ -31,7 +31,7 @@ fun GeneralSettingsRoot() {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun GeneralSettings() {
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
Scaffold(
|
||||
|
|
|
|||
|
|
@ -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.GoBackButton
|
||||
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
|
||||
|
||||
@Composable
|
||||
|
|
@ -30,7 +30,7 @@ fun ReaderSettingsRoot() {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun ReaderSettings() {
|
||||
val onNavigate = LocalOnNavigate.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
||||
|
||||
Scaffold(
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ fun StartDone() {
|
|||
val onEvent = LocalStartViewModel.current.onEvent
|
||||
val onMainEvent = LocalMainViewModel.current.onEvent
|
||||
val onBrowseEvent = LocalBrowseViewModel.current.onEvent
|
||||
val navigator = LocalNavigator.current
|
||||
val onNavigate = LocalNavigator.current
|
||||
|
||||
StartNavigationTransition(
|
||||
modifier = Modifier
|
||||
|
|
@ -71,7 +71,7 @@ fun StartDone() {
|
|||
onClick = {
|
||||
onEvent(
|
||||
StartEvent.OnGoToBrowse(
|
||||
onNavigate = { navigator.it() },
|
||||
onNavigate = onNavigate,
|
||||
onCompletedStartGuide = {
|
||||
onBrowseEvent(BrowseEvent.OnLoadList)
|
||||
onMainEvent(
|
||||
|
|
@ -90,7 +90,7 @@ fun StartDone() {
|
|||
shape = RoundedCornerShape(100),
|
||||
onClick = {
|
||||
onEvent(
|
||||
StartEvent.OnGoToHelp { navigator.it() }
|
||||
StartEvent.OnGoToHelp(onNavigate = onNavigate)
|
||||
)
|
||||
}
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -170,7 +170,6 @@
|
|||
<string name="open_reader_settings_content_desc">Reader-Einstellungen</string>
|
||||
<string name="file_icon_content_desc">Datei</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="apply_changes_content_desc">Änderungen übernehmen</string>
|
||||
<string name="error_content_desc">Fehler</string>
|
||||
|
|
|
|||
|
|
@ -246,7 +246,6 @@
|
|||
<string name="go_back_content_desc">Regresar</string>
|
||||
<string name="cover_image_content_desc">Portada</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="apply_changes_content_desc">Aplicar cambios</string>
|
||||
<string name="error_content_desc">Error</string>
|
||||
|
|
|
|||
|
|
@ -227,7 +227,6 @@
|
|||
<string name="directory_icon_content_desc">Répertoire</string>
|
||||
<string name="path_arrow_icon_content_desc">Flèche du chemin</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="apply_changes_content_desc">Appliquer les changements</string>
|
||||
<string name="error_content_desc">Erreur</string>
|
||||
|
|
|
|||
|
|
@ -206,7 +206,6 @@
|
|||
<string name="credits_fonts">Czcionki</string>
|
||||
<string name="delete_books_content_desc">Usuń wybrane 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="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>
|
||||
|
|
|
|||
|
|
@ -298,7 +298,6 @@
|
|||
<string name="sort_order_content_desc">Sıralama düzeni</string>
|
||||
<string name="path_arrow_icon_content_desc">Yol oku</string>
|
||||
<string name="checkbox_content_desc">Onay kutusu</string>
|
||||
<string name="show_dropdown_content_desc">Açılır menü</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="error_content_desc">Hata</string>
|
||||
|
|
|
|||
|
|
@ -605,7 +605,6 @@
|
|||
<string name="sort_order_content_desc">Порядок сортування</string>
|
||||
<string name="path_arrow_icon_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="apply_changes_content_desc">Застосувати зміни</string>
|
||||
<string name="error_content_desc">Помилка</string>
|
||||
|
|
@ -641,5 +640,6 @@
|
|||
<string name="checkpoint_forward_content_desc">Чекпоінт вперед</string>
|
||||
<string name="chapters_content_desc">Розділи</string>
|
||||
<string name="update_text_content_desc">Оновити текст</string>
|
||||
<string name="more_content_desc">Більше</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -605,7 +605,6 @@
|
|||
<string name="sort_order_content_desc">Sort order</string>
|
||||
<string name="path_arrow_icon_content_desc">Path arrow</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="apply_changes_content_desc">Apply changes</string>
|
||||
<string name="error_content_desc">Error</string>
|
||||
|
|
@ -644,5 +643,6 @@
|
|||
<string name="checkpoint_forward_content_desc">Checkpoint forward</string>
|
||||
<string name="chapters_content_desc">Chapters</string>
|
||||
<string name="update_text_content_desc">Update text</string>
|
||||
<string name="more_content_desc">More</string>
|
||||
|
||||
</resources>
|
||||
Loading…
Add table
Add a link
Reference in a new issue