🚀 Small UI changes & Code reformat
* Reformatted code (naming, packages) * Small UI changes
This commit is contained in:
parent
2875baf5ce
commit
aa68ba3ae8
156 changed files with 611 additions and 672 deletions
|
|
@ -19,8 +19,8 @@ import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import ua.acclorite.book_story.presentation.core.components.bottom_navigation_bar.BottomNavigationBar
|
import ua.acclorite.book_story.presentation.core.components.navigation_bar.NavigationBar
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_navigation_rail.CustomNavigationRail
|
import ua.acclorite.book_story.presentation.core.components.navigation_rail.NavigationRail
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.NavigationHost
|
import ua.acclorite.book_story.presentation.core.navigation.NavigationHost
|
||||||
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
|
||||||
|
|
@ -131,10 +131,10 @@ class Activity : AppCompatActivity() {
|
||||||
Screen.Browse.getRoute()
|
Screen.Browse.getRoute()
|
||||||
),
|
),
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
BottomNavigationBar()
|
NavigationBar()
|
||||||
},
|
},
|
||||||
navigationRail = {
|
navigationRail = {
|
||||||
CustomNavigationRail()
|
NavigationRail()
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
// Library
|
// Library
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.util
|
package ua.acclorite.book_story.domain.util
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
|
|
@ -8,18 +8,18 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
|
|
||||||
|
|
||||||
abstract class UiViewModel<S, E> : ViewModel() {
|
abstract class UIViewModel<S, E> : ViewModel() {
|
||||||
abstract val state: StateFlow<S>
|
abstract val state: StateFlow<S>
|
||||||
abstract fun onEvent(event: E)
|
abstract fun onEvent(event: E)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
inline fun <reified V : UiViewModel<S, E>, S, E> getState(): State<S> {
|
inline fun <reified V : UIViewModel<S, E>, S, E> getState(): State<S> {
|
||||||
return hiltViewModel<V>().state.collectAsStateWithLifecycle()
|
return hiltViewModel<V>().state.collectAsStateWithLifecycle()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
inline fun <reified V : UiViewModel<S, E>, S, E> getEvent(): (E) -> Unit {
|
inline fun <reified V : UIViewModel<S, E>, S, E> getEvent(): (E) -> Unit {
|
||||||
return hiltViewModel<V>()::onEvent
|
return hiltViewModel<V>()::onEvent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.EnterTransition
|
import androidx.compose.animation.EnterTransition
|
||||||
|
|
@ -12,7 +12,7 @@ import androidx.compose.ui.Modifier
|
||||||
* FIXED: This bug was fixed. I preserved initial code, if the bug happens again.
|
* FIXED: This bug was fixed. I preserved initial code, if the bug happens again.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomAnimatedVisibility(
|
fun AnimatedVisibility(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
visible: Boolean,
|
visible: Boolean,
|
||||||
enter: EnterTransition,
|
enter: EnterTransition,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
@ -14,7 +14,7 @@ import ua.acclorite.book_story.R
|
||||||
* Custom Cover Image. Has smooth appearing.
|
* Custom Cover Image. Has smooth appearing.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomCoverImage(
|
fun AsyncImage(
|
||||||
uri: Uri,
|
uri: Uri,
|
||||||
animationDurationMillis: Int = 100,
|
animationDurationMillis: Int = 100,
|
||||||
contentDescription: String? = stringResource(id = R.string.cover_image_content_desc),
|
contentDescription: String? = stringResource(id = R.string.cover_image_content_desc),
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
|
|
@ -18,7 +18,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Checkbox. Has a Circle shape.
|
* Checkbox. Has a Circle shape.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier.
|
* @param modifier Modifier.
|
||||||
* @param selected Whether checked or not.
|
* @param selected Whether checked or not.
|
||||||
|
|
@ -26,7 +26,7 @@ import ua.acclorite.book_story.R
|
||||||
* @param size Size of the checkbox icon(not the whole checkbox).
|
* @param size Size of the checkbox icon(not the whole checkbox).
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomCheckbox(
|
fun CircularCheckbox(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
selected: Boolean,
|
selected: Boolean,
|
||||||
containerColor: Color,
|
containerColor: Color,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
|
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
|
||||||
|
|
@ -8,15 +8,19 @@ import ua.acclorite.book_story.domain.util.OnNavigate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Go back arrow button.
|
* Go back arrow button.
|
||||||
* Prevents double or triple clicking on it while going back action is performed.
|
* Prevents double or triple clicking while going back action is performed.
|
||||||
*
|
*
|
||||||
* @param onNavigate [OnNavigate].
|
* @param onNavigate [OnNavigate].
|
||||||
* @param enabled Whether this button is enabled.
|
* @param enabled Whether this button is enabled.
|
||||||
* @param customOnClick Call before going back.
|
* @param customOnClick Call before going back.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun GoBackButton(onNavigate: OnNavigate, enabled: Boolean = true, customOnClick: () -> Unit = {}) {
|
fun GoBackButton(
|
||||||
CustomIconButton(
|
onNavigate: OnNavigate,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
customOnClick: () -> Unit = {}
|
||||||
|
) {
|
||||||
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
||||||
contentDescription = R.string.go_back_content_desc,
|
contentDescription = R.string.go_back_content_desc,
|
||||||
disableOnClick = true,
|
disableOnClick = true,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
|
@ -18,7 +18,7 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Icon Button.
|
* Icon Button.
|
||||||
* Can be disabled after click, so user can't press button fast 2 or 3 times.
|
* Can be disabled after click, so user can't press button fast 2 or 3 times.
|
||||||
*
|
*
|
||||||
* @param modifier [Modifier].
|
* @param modifier [Modifier].
|
||||||
|
|
@ -30,7 +30,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
* @param onClick OnClick callback.
|
* @param onClick OnClick callback.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomIconButton(
|
fun IconButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
icon: ImageVector,
|
icon: ImageVector,
|
||||||
@StringRes contentDescription: Int,
|
@StringRes contentDescription: Int,
|
||||||
|
|
@ -40,7 +40,7 @@ fun CustomIconButton(
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
var isClicked by remember { mutableStateOf(false) }
|
var isClicked by remember { mutableStateOf(false) }
|
||||||
CustomTooltip(text = stringResource(id = contentDescription), enabled = enabled) {
|
Tooltip(text = stringResource(id = contentDescription), enabled = enabled) {
|
||||||
IconButton(
|
IconButton(
|
||||||
enabled = enabled && !isClicked,
|
enabled = enabled && !isClicked,
|
||||||
modifier = Modifier.focusProperties {
|
modifier = Modifier.focusProperties {
|
||||||
|
|
@ -64,7 +64,7 @@ fun CustomIconButton(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Icon Button.
|
* Icon Button.
|
||||||
* Can be disabled after click, so user can't press button fast 2 or 3 times.
|
* Can be disabled after click, so user can't press button fast 2 or 3 times.
|
||||||
*
|
*
|
||||||
* @param modifier [Modifier].
|
* @param modifier [Modifier].
|
||||||
|
|
@ -76,7 +76,7 @@ fun CustomIconButton(
|
||||||
* @param onClick OnClick callback.
|
* @param onClick OnClick callback.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomIconButton(
|
fun IconButton(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
@DrawableRes icon: Int,
|
@DrawableRes icon: Int,
|
||||||
@StringRes contentDescription: Int,
|
@StringRes contentDescription: Int,
|
||||||
|
|
@ -86,7 +86,7 @@ fun CustomIconButton(
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
var isClicked by remember { mutableStateOf(false) }
|
var isClicked by remember { mutableStateOf(false) }
|
||||||
CustomTooltip(text = stringResource(id = contentDescription)) {
|
Tooltip(text = stringResource(id = contentDescription)) {
|
||||||
IconButton(
|
IconButton(
|
||||||
enabled = enabled && !isClicked,
|
enabled = enabled && !isClicked,
|
||||||
modifier = Modifier.focusProperties {
|
modifier = Modifier.focusProperties {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
|
@ -18,8 +18,8 @@ import ua.acclorite.book_story.presentation.core.constants.Constants
|
||||||
import ua.acclorite.book_story.presentation.core.constants.provideSecondaryScrollbar
|
import ua.acclorite.book_story.presentation.core.constants.provideSecondaryScrollbar
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Lazy Column.
|
* Lazy Column.
|
||||||
* Has scrollbar.
|
* Has a scrollbar.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier.
|
* @param modifier Modifier.
|
||||||
* @param state [LazyListState].
|
* @param state [LazyListState].
|
||||||
|
|
@ -30,7 +30,7 @@ import ua.acclorite.book_story.presentation.core.constants.provideSecondaryScrol
|
||||||
* @param content Content of the column.
|
* @param content Content of the column.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomLazyColumn(
|
fun LazyColumnWithScrollbar(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
state: LazyListState = rememberLazyListState(),
|
state: LazyListState = rememberLazyListState(),
|
||||||
scrollbarSettings: ScrollbarSettings = Constants.provideSecondaryScrollbar(),
|
scrollbarSettings: ScrollbarSettings = Constants.provideSecondaryScrollbar(),
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||||
import androidx.compose.foundation.lazy.grid.LazyGridItemScope
|
import androidx.compose.foundation.lazy.grid.LazyGridItemScope
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
|
|
@ -12,21 +12,28 @@ import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.SolidColor
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
import ua.acclorite.book_story.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Search Text Field. Used in main screens for searching.
|
* Search Text Field.
|
||||||
|
* Used in main screens for searching.
|
||||||
|
*
|
||||||
|
* @param modifier Modifier to apply.
|
||||||
|
* @param query Search query.
|
||||||
|
* @param onQueryChange Callback to change [query].
|
||||||
|
* @param onSearch Search action (refresh list, fetch filtered books etc..).
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomSearchTextField(
|
fun SearchTextField(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
query: String,
|
query: String,
|
||||||
onQueryChange: (String) -> Unit,
|
onQueryChange: (String) -> Unit,
|
||||||
onSearch: () -> Unit,
|
onSearch: () -> Unit
|
||||||
placeholder: String
|
|
||||||
) {
|
) {
|
||||||
val keyboardManager = LocalSoftwareKeyboardController.current
|
val keyboardManager = LocalSoftwareKeyboardController.current
|
||||||
|
|
||||||
|
|
@ -59,7 +66,7 @@ fun CustomSearchTextField(
|
||||||
) {
|
) {
|
||||||
if (query.isEmpty()) {
|
if (query.isEmpty()) {
|
||||||
Text(
|
Text(
|
||||||
placeholder,
|
text = stringResource(id = R.string.search_field_empty),
|
||||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
style = MaterialTheme.typography.titleLarge,
|
style = MaterialTheme.typography.titleLarge,
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@file:Suppress("DEPRECATION")
|
@file:Suppress("DEPRECATION")
|
||||||
|
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import android.content.ClipData
|
import android.content.ClipData
|
||||||
import android.content.ClipboardManager
|
import android.content.ClipboardManager
|
||||||
|
|
@ -35,9 +35,10 @@ private const val MENU_ITEM_TRANSLATE = 3
|
||||||
private const val MENU_ITEM_DICTIONARY = 4
|
private const val MENU_ITEM_DICTIONARY = 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Text ActionMode callback. Used in pair with [CustomSelectionToolbar]. Follow [TextToolbar] for more info.
|
* Text ActionMode callback.
|
||||||
|
* Used in pair with [SelectionToolbar]. Follow [TextToolbar] for more info.
|
||||||
*/
|
*/
|
||||||
private class CustomTextActionModeCallback(
|
private class TextActionModeCallback(
|
||||||
private val context: Context,
|
private val context: Context,
|
||||||
var rect: Rect = Rect.Zero,
|
var rect: Rect = Rect.Zero,
|
||||||
var onCopyRequested: (() -> Unit)? = null,
|
var onCopyRequested: (() -> Unit)? = null,
|
||||||
|
|
@ -99,10 +100,10 @@ private class CustomTextActionModeCallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Floating [CustomTextActionModeCallback].
|
* Floating [TextActionModeCallback].
|
||||||
*/
|
*/
|
||||||
private class FloatingTextActionModeCallback(
|
private class FloatingTextActionModeCallback(
|
||||||
val callback: CustomTextActionModeCallback
|
val callback: TextActionModeCallback
|
||||||
) : ActionMode.Callback2() {
|
) : ActionMode.Callback2() {
|
||||||
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
|
override fun onActionItemClicked(mode: ActionMode?, item: MenuItem?): Boolean {
|
||||||
return callback.onActionItemClicked(mode, item)
|
return callback.onActionItemClicked(mode, item)
|
||||||
|
|
@ -132,10 +133,10 @@ private class FloatingTextActionModeCallback(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Selection Toolbar.
|
* Selection Toolbar.
|
||||||
* Used in pair with [CustomSelectionContainer] to display custom toolbar.
|
* Used in pair with [SelectionContainer] to display custom toolbar.
|
||||||
*/
|
*/
|
||||||
private class CustomSelectionToolbar(
|
private class SelectionToolbar(
|
||||||
private val view: View,
|
private val view: View,
|
||||||
context: Context,
|
context: Context,
|
||||||
private val onCopyRequest: (() -> Unit)?,
|
private val onCopyRequest: (() -> Unit)?,
|
||||||
|
|
@ -145,7 +146,7 @@ private class CustomSelectionToolbar(
|
||||||
private val onDictionaryRequest: ((String) -> Unit)?
|
private val onDictionaryRequest: ((String) -> Unit)?
|
||||||
) : TextToolbar {
|
) : TextToolbar {
|
||||||
private var actionMode: ActionMode? = null
|
private var actionMode: ActionMode? = null
|
||||||
private val callback = CustomTextActionModeCallback(context = context)
|
private val callback = TextActionModeCallback(context = context)
|
||||||
|
|
||||||
val clipboardManager =
|
val clipboardManager =
|
||||||
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||||
|
|
@ -244,7 +245,7 @@ private class CustomSelectionToolbar(
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom selection container.
|
* Selection container.
|
||||||
*
|
*
|
||||||
* @param onCopyRequested Callback for when the copy option is clicked.
|
* @param onCopyRequested Callback for when the copy option is clicked.
|
||||||
* @param onTranslateRequested Callback for when the translate option is clicked.
|
* @param onTranslateRequested Callback for when the translate option is clicked.
|
||||||
|
|
@ -252,7 +253,7 @@ private class CustomSelectionToolbar(
|
||||||
* @param content Selection container content.
|
* @param content Selection container content.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomSelectionContainer(
|
fun SelectionContainer(
|
||||||
onCopyRequested: (() -> Unit),
|
onCopyRequested: (() -> Unit),
|
||||||
onShareRequested: ((String) -> Unit),
|
onShareRequested: ((String) -> Unit),
|
||||||
onWebSearchRequested: ((String) -> Unit),
|
onWebSearchRequested: ((String) -> Unit),
|
||||||
|
|
@ -263,8 +264,8 @@ fun CustomSelectionContainer(
|
||||||
val view = LocalView.current
|
val view = LocalView.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val customSelectionToolbar = remember {
|
val selectionToolbar = remember {
|
||||||
CustomSelectionToolbar(
|
SelectionToolbar(
|
||||||
view = view,
|
view = view,
|
||||||
context = context,
|
context = context,
|
||||||
|
|
||||||
|
|
@ -285,14 +286,14 @@ fun CustomSelectionContainer(
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
val isToolbarHidden = remember(customSelectionToolbar.status) {
|
val isToolbarHidden = remember(selectionToolbar.status) {
|
||||||
derivedStateOf {
|
derivedStateOf {
|
||||||
customSelectionToolbar.status == TextToolbarStatus.Hidden
|
selectionToolbar.status == TextToolbarStatus.Hidden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalTextToolbar provides customSelectionToolbar
|
LocalTextToolbar provides selectionToolbar
|
||||||
) {
|
) {
|
||||||
SelectionContainer(Modifier.fillMaxSize()) {
|
SelectionContainer(Modifier.fillMaxSize()) {
|
||||||
content(isToolbarHidden.value)
|
content(isToolbarHidden.value)
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
|
|
@ -34,18 +34,18 @@ import androidx.compose.ui.unit.dp
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Snackbar with vertical Swipe-To-Dismiss and animation.
|
* Snackbar with vertical Swipe-To-Dismiss and animation.
|
||||||
* It is recommended to put it in Scaffold bottomBar(this way padding is the same at all sides)
|
* It is recommended to put it in Scaffold bottomBar(this way padding is the same at all sides)
|
||||||
*
|
*
|
||||||
|
* @param modifier Modifier to be applied.
|
||||||
* @param snackbarState Regular [SnackbarHostState], use ..remember { SnackbarHostState() }
|
* @param snackbarState Regular [SnackbarHostState], use ..remember { SnackbarHostState() }
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomSnackbar(modifier: Modifier = Modifier, snackbarState: SnackbarHostState) {
|
fun Snackbar(modifier: Modifier = Modifier, snackbarState: SnackbarHostState) {
|
||||||
var showSnackbar by remember { mutableStateOf(false) }
|
var showSnackbar by remember { mutableStateOf(false) }
|
||||||
var snackbarData by remember { mutableStateOf(snackbarState.currentSnackbarData) }
|
var snackbarData by remember { mutableStateOf(snackbarState.currentSnackbarData) }
|
||||||
var offset by remember { mutableFloatStateOf(0f) }
|
var offset by remember { mutableFloatStateOf(0f) }
|
||||||
|
|
||||||
|
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
val mutableInteractionSource = remember { MutableInteractionSource() }
|
val mutableInteractionSource = remember { MutableInteractionSource() }
|
||||||
val isDragged by mutableInteractionSource.collectIsDraggedAsState()
|
val isDragged by mutableInteractionSource.collectIsDraggedAsState()
|
||||||
|
|
@ -56,7 +56,6 @@ fun CustomSnackbar(modifier: Modifier = Modifier, snackbarState: SnackbarHostSta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LaunchedEffect(offset, isDragged) {
|
LaunchedEffect(offset, isDragged) {
|
||||||
val offsetDp = with(density) { offset.toDp() }
|
val offsetDp = with(density) { offset.toDp() }
|
||||||
if (offsetDp > 35.dp && !isDragged) {
|
if (offsetDp > 35.dp && !isDragged) {
|
||||||
|
|
@ -81,7 +80,7 @@ fun CustomSnackbar(modifier: Modifier = Modifier, snackbarState: SnackbarHostSta
|
||||||
showSnackbar = true
|
showSnackbar = true
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = showSnackbar,
|
visible = showSnackbar,
|
||||||
enter = slideInVertically(tween(350)) { it } + fadeIn(tween(350)),
|
enter = slideInVertically(tween(350)) { it } + fadeIn(tween(350)),
|
||||||
exit = slideOutVertically(tween(200)) { it } + fadeOut(tween(100))
|
exit = slideOutVertically(tween(200)) { it } + fadeOut(tween(100))
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.common
|
||||||
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.PlainTooltip
|
import androidx.compose.material3.PlainTooltip
|
||||||
|
|
@ -11,7 +11,7 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Tooltip.
|
* Tooltip.
|
||||||
* Shows [text] on long press.
|
* Shows [text] on long press.
|
||||||
*
|
*
|
||||||
* @param text Text to show.
|
* @param text Text to show.
|
||||||
|
|
@ -21,7 +21,7 @@ import androidx.compose.ui.unit.dp
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomTooltip(
|
fun Tooltip(
|
||||||
text: String,
|
text: String,
|
||||||
padding: Dp = 14.dp,
|
padding: Dp = 14.dp,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_dialog
|
package ua.acclorite.book_story.presentation.core.components.dialog
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -38,7 +38,7 @@ import androidx.compose.ui.window.DialogWindowProvider
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Dialog with custom content.
|
* Dialog with custom content.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier to be applied.
|
* @param modifier Modifier to be applied.
|
||||||
* @param drawableIcon Drawable icon to show(1/2).
|
* @param drawableIcon Drawable icon to show(1/2).
|
||||||
|
|
@ -56,7 +56,7 @@ import ua.acclorite.book_story.R
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomDialogWithContent(
|
fun DialogWithContent(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
drawableIcon: Painter? = null,
|
drawableIcon: Painter? = null,
|
||||||
imageVectorIcon: ImageVector? = null,
|
imageVectorIcon: ImageVector? = null,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_dialog
|
package ua.acclorite.book_story.presentation.core.components.dialog
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -40,7 +40,7 @@ import ua.acclorite.book_story.R
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Dialog with lazy column.
|
* Dialog with lazy column.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier to be applied.
|
* @param modifier Modifier to be applied.
|
||||||
* @param drawableIcon Drawable icon to show(1/2).
|
* @param drawableIcon Drawable icon to show(1/2).
|
||||||
|
|
@ -58,7 +58,7 @@ import ua.acclorite.book_story.R
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomDialogWithLazyColumn(
|
fun DialogWithLazyColumn(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
drawableIcon: Painter? = null,
|
drawableIcon: Painter? = null,
|
||||||
imageVectorIcon: ImageVector? = null,
|
imageVectorIcon: ImageVector? = null,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_dialog
|
package ua.acclorite.book_story.presentation.core.components.dialog
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
|
@ -19,7 +19,13 @@ import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selectable dialog item. Perfectly combines with [CustomDialogWithLazyColumn].
|
* Selectable dialog item.
|
||||||
|
* Perfectly combines with [DialogWithLazyColumn].
|
||||||
|
*
|
||||||
|
* @param selected Whether item is selected.
|
||||||
|
* @param title Title of the item.
|
||||||
|
* @param horizontalPadding Horizontal padding of the item.
|
||||||
|
* @param onClick OnClick callback.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun SelectableDialogItem(
|
fun SelectableDialogItem(
|
||||||
|
|
@ -54,10 +60,3 @@ fun SelectableDialogItem(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet
|
package ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
|
@ -16,7 +16,8 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.Shape
|
import androidx.compose.ui.graphics.Shape
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Bottom Sheet. Fixes bugs with [ModalBottomSheet].
|
* Bottom Sheet.
|
||||||
|
* Fixes bugs with [ModalBottomSheet].
|
||||||
*
|
*
|
||||||
* @param modifier [Modifier].
|
* @param modifier [Modifier].
|
||||||
* @param hasFixedHeight Whether the bottom sheet has fixed height passed through [modifier] or not.
|
* @param hasFixedHeight Whether the bottom sheet has fixed height passed through [modifier] or not.
|
||||||
|
|
@ -29,7 +30,7 @@ import androidx.compose.ui.graphics.Shape
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomBottomSheet(
|
fun ModalBottomSheet(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
hasFixedHeight: Boolean = false,
|
hasFixedHeight: Boolean = false,
|
||||||
scrimColor: Color = BottomSheetDefaults.ScrimColor,
|
scrimColor: Color = BottomSheetDefaults.ScrimColor,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet
|
package ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
|
@ -12,7 +12,7 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Primary Row. Used in BottomSheet in pair with HorizontalPager.
|
* Primary Tab Row. Used in BottomSheet in pair with HorizontalPager.
|
||||||
* Better to not use too many tabs, as they will overflow.
|
* Better to not use too many tabs, as they will overflow.
|
||||||
*
|
*
|
||||||
* @param selectedTabIndex Selected index, typically pager.currentPage.
|
* @param selectedTabIndex Selected index, typically pager.currentPage.
|
||||||
|
|
@ -21,7 +21,7 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomBottomSheetTabRow(
|
fun ModalBottomSheetTabRow(
|
||||||
selectedTabIndex: Int,
|
selectedTabIndex: Int,
|
||||||
tabs: List<String>,
|
tabs: List<String>,
|
||||||
onClick: (index: Int) -> Unit
|
onClick: (index: Int) -> Unit
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_drawer
|
package ua.acclorite.book_story.presentation.core.components.modal_drawer
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
|
|
@ -31,14 +31,14 @@ import androidx.compose.ui.input.pointer.pointerInput
|
||||||
import androidx.compose.ui.platform.LocalDensity
|
import androidx.compose.ui.platform.LocalDensity
|
||||||
import androidx.compose.ui.unit.IntOffset
|
import androidx.compose.ui.unit.IntOffset
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
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.constants.providePrimaryScrollbar
|
import ua.acclorite.book_story.presentation.core.constants.providePrimaryScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Modal Drawer.
|
* Modal Drawer.
|
||||||
* Follows Material3 guidelines. Does not require to wrap screen's content and works independently.
|
* Follows Material3 guidelines. Does not require to wrap screen's content and works independently.
|
||||||
* Do not wrap in if(show) { ... }, use [show].
|
* Do not wrap in if(show) { ... }, use [show].
|
||||||
* Should be placed at the bottom of the composable to be shown at top.
|
* Should be placed at the bottom of the composable to be shown at top.
|
||||||
|
|
@ -50,7 +50,7 @@ import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||||
* @param content Content inside drawer.
|
* @param content Content inside drawer.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomModalDrawer(
|
fun ModalDrawer(
|
||||||
show: Boolean,
|
show: Boolean,
|
||||||
startIndex: Int = 0,
|
startIndex: Int = 0,
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
|
|
@ -85,7 +85,7 @@ fun CustomModalDrawer(
|
||||||
else Modifier.noRippleClickable(onClick = onDismissRequest)
|
else Modifier.noRippleClickable(onClick = onDismissRequest)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = show,
|
visible = show,
|
||||||
enter = slideInHorizontally { (-it + with(density) { -20.dp.toPx() }).toInt() },
|
enter = slideInHorizontally { (-it + with(density) { -20.dp.toPx() }).toInt() },
|
||||||
exit = slideOutHorizontally { (-it + with(density) { -20.dp.toPx() }).toInt() }
|
exit = slideOutHorizontally { (-it + with(density) { -20.dp.toPx() }).toInt() }
|
||||||
|
|
@ -125,7 +125,7 @@ fun CustomModalDrawer(
|
||||||
.systemBarsPadding()
|
.systemBarsPadding()
|
||||||
) {
|
) {
|
||||||
header()
|
header()
|
||||||
CustomLazyColumn(
|
LazyColumnWithScrollbar(
|
||||||
state = rememberLazyListState(startIndex),
|
state = rememberLazyListState(startIndex),
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
scrollbarSettings = Constants.providePrimaryScrollbar(),
|
scrollbarSettings = Constants.providePrimaryScrollbar(),
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_drawer
|
package ua.acclorite.book_story.presentation.core.components.modal_drawer
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
|
|
@ -19,7 +19,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.domain.util.Selected
|
import ua.acclorite.book_story.domain.util.Selected
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Modal Drawer Selectable Item.
|
* Modal Drawer Selectable Item.
|
||||||
* Can be selected.
|
* Can be selected.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier to be applied.
|
* @param modifier Modifier to be applied.
|
||||||
|
|
@ -29,7 +29,7 @@ import ua.acclorite.book_story.domain.util.Selected
|
||||||
* @param content Content of the item.
|
* @param content Content of the item.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomModalDrawerSelectableItem(
|
fun ModalDrawerSelectableItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
selected: Selected,
|
selected: Selected,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_drawer
|
package ua.acclorite.book_story.presentation.core.components.modal_drawer
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -14,14 +14,14 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Modal Drawer Title Item.
|
* Modal Drawer Title Item.
|
||||||
* Usually displayed at the top of the drawer.
|
* Usually displayed at the top of the drawer.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier to be applied.
|
* @param modifier Modifier to be applied.
|
||||||
* @param title Title to be shown.
|
* @param title Title to be shown.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomModalDrawerTitleItem(
|
fun ModalDrawerTitleItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
title: String
|
title: String
|
||||||
) {
|
) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.bottom_navigation_bar
|
package ua.acclorite.book_story.presentation.core.components.navigation_bar
|
||||||
|
|
||||||
import androidx.compose.material3.NavigationBar
|
import androidx.compose.material3.NavigationBar
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
|
@ -13,10 +13,10 @@ import ua.acclorite.book_story.presentation.core.constants.provideNavigationItem
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigatorInstance
|
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigatorInstance
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bottom navigation bar, uses default [NavigationBar].
|
* Navigation bar, uses default [NavigationBar].
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun BottomNavigationBar() {
|
fun NavigationBar() {
|
||||||
var currentScreen: Route? by remember { mutableStateOf(null) }
|
var currentScreen: Route? by remember { mutableStateOf(null) }
|
||||||
val navigator = LocalNavigatorInstance.current
|
val navigator = LocalNavigatorInstance.current
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ fun BottomNavigationBar() {
|
||||||
|
|
||||||
NavigationBar {
|
NavigationBar {
|
||||||
Constants.provideNavigationItems().forEach {
|
Constants.provideNavigationItems().forEach {
|
||||||
BottomNavigationBarItem(
|
NavigationBarItem(
|
||||||
item = it,
|
item = it,
|
||||||
isSelected = currentScreen == navigator.run { it.screen.getRoute() }
|
isSelected = currentScreen == navigator.run { it.screen.getRoute() }
|
||||||
) {
|
) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.bottom_navigation_bar
|
package ua.acclorite.book_story.presentation.core.components.navigation_bar
|
||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
|
@ -14,10 +14,10 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.domain.model.NavigationItem
|
import ua.acclorite.book_story.domain.model.NavigationItem
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomTooltip
|
import ua.acclorite.book_story.presentation.core.components.common.Tooltip
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bottom Navigation Bar Item, uses default [NavigationBarItem].
|
* Navigation Bar Item.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier.
|
* @param modifier Modifier.
|
||||||
* @param item [NavigationItem].
|
* @param item [NavigationItem].
|
||||||
|
|
@ -25,7 +25,7 @@ import ua.acclorite.book_story.presentation.core.components.CustomTooltip
|
||||||
* @param onClick OnClick callback.
|
* @param onClick OnClick callback.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun RowScope.BottomNavigationBarItem(
|
fun RowScope.NavigationBarItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
item: NavigationItem,
|
item: NavigationItem,
|
||||||
isSelected: Boolean,
|
isSelected: Boolean,
|
||||||
|
|
@ -33,7 +33,7 @@ fun RowScope.BottomNavigationBarItem(
|
||||||
) {
|
) {
|
||||||
NavigationBarItem(
|
NavigationBarItem(
|
||||||
label = {
|
label = {
|
||||||
CustomTooltip(
|
Tooltip(
|
||||||
text = stringResource(id = item.tooltip),
|
text = stringResource(id = item.tooltip),
|
||||||
padding = 64.dp
|
padding = 64.dp
|
||||||
) {
|
) {
|
||||||
|
|
@ -47,7 +47,7 @@ fun RowScope.BottomNavigationBarItem(
|
||||||
selected = isSelected,
|
selected = isSelected,
|
||||||
onClick = { onClick() },
|
onClick = { onClick() },
|
||||||
icon = {
|
icon = {
|
||||||
CustomTooltip(
|
Tooltip(
|
||||||
text = stringResource(id = item.tooltip),
|
text = stringResource(id = item.tooltip),
|
||||||
padding = 32.dp
|
padding = 32.dp
|
||||||
) {
|
) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_navigation_rail
|
package ua.acclorite.book_story.presentation.core.components.navigation_rail
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|
@ -29,10 +29,10 @@ import ua.acclorite.book_story.presentation.core.constants.provideNavigationItem
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigatorInstance
|
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigatorInstance
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Navigation Rail. It is used to be shown on Tablets.
|
* Navigation Rail. It is used to be shown on Tablets.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomNavigationRail() {
|
fun NavigationRail() {
|
||||||
var currentScreen: Route? by remember { mutableStateOf(null) }
|
var currentScreen: Route? by remember { mutableStateOf(null) }
|
||||||
val navigator = LocalNavigatorInstance.current
|
val navigator = LocalNavigatorInstance.current
|
||||||
val layoutDirection = LocalLayoutDirection.current
|
val layoutDirection = LocalLayoutDirection.current
|
||||||
|
|
@ -72,7 +72,7 @@ fun CustomNavigationRail() {
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
Constants.provideNavigationItems().forEach {
|
Constants.provideNavigationItems().forEach {
|
||||||
CustomNavigationRailItem(
|
NavigationRailItem(
|
||||||
item = it,
|
item = it,
|
||||||
isSelected = currentScreen == navigator.run { it.screen.getRoute() }
|
isSelected = currentScreen == navigator.run { it.screen.getRoute() }
|
||||||
) {
|
) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components.custom_navigation_rail
|
package ua.acclorite.book_story.presentation.core.components.navigation_rail
|
||||||
|
|
||||||
import androidx.compose.animation.Crossfade
|
import androidx.compose.animation.Crossfade
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
|
|
@ -13,10 +13,10 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.domain.model.NavigationItem
|
import ua.acclorite.book_story.domain.model.NavigationItem
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomTooltip
|
import ua.acclorite.book_story.presentation.core.components.common.Tooltip
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Navigation Rail item.
|
* Navigation Rail item.
|
||||||
*
|
*
|
||||||
* @param modifier Modifier.
|
* @param modifier Modifier.
|
||||||
* @param item [NavigationItem].
|
* @param item [NavigationItem].
|
||||||
|
|
@ -24,7 +24,7 @@ import ua.acclorite.book_story.presentation.core.components.CustomTooltip
|
||||||
* @param onClick OnClick callback.
|
* @param onClick OnClick callback.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CustomNavigationRailItem(
|
fun NavigationRailItem(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
item: NavigationItem,
|
item: NavigationItem,
|
||||||
isSelected: Boolean,
|
isSelected: Boolean,
|
||||||
|
|
@ -32,7 +32,7 @@ fun CustomNavigationRailItem(
|
||||||
) {
|
) {
|
||||||
NavigationRailItem(
|
NavigationRailItem(
|
||||||
label = {
|
label = {
|
||||||
CustomTooltip(
|
Tooltip(
|
||||||
text = stringResource(id = item.tooltip),
|
text = stringResource(id = item.tooltip),
|
||||||
padding = 48.dp
|
padding = 48.dp
|
||||||
) {
|
) {
|
||||||
|
|
@ -46,7 +46,7 @@ fun CustomNavigationRailItem(
|
||||||
selected = isSelected,
|
selected = isSelected,
|
||||||
onClick = { onClick() },
|
onClick = { onClick() },
|
||||||
icon = {
|
icon = {
|
||||||
CustomTooltip(
|
Tooltip(
|
||||||
text = stringResource(id = item.tooltip),
|
text = stringResource(id = item.tooltip),
|
||||||
padding = 16.dp
|
padding = 16.dp
|
||||||
) {
|
) {
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.components
|
package ua.acclorite.book_story.presentation.core.components.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -15,7 +15,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.domain.model.ButtonItem
|
import ua.acclorite.book_story.domain.model.ButtonItem
|
||||||
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryTitle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chips with title. Use list of [ButtonItem]s to display chips.
|
* Chips with title. Use list of [ButtonItem]s to display chips.
|
||||||
|
|
@ -35,7 +35,7 @@ fun ChipsWithTitle(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = horizontalPadding, vertical = verticalPadding)
|
.padding(horizontal = horizontalPadding, vertical = verticalPadding)
|
||||||
) {
|
) {
|
||||||
CategoryTitle(title = title, padding = 0.dp)
|
SettingsCategoryTitle(title = title, padding = 0.dp)
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
FlowRow(
|
FlowRow(
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.components
|
package ua.acclorite.book_story.presentation.core.components.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -30,8 +30,8 @@ import kotlinx.coroutines.FlowPreview
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.debounce
|
import kotlinx.coroutines.flow.debounce
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryTitle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Color picker with title.
|
* Color picker with title.
|
||||||
|
|
@ -71,7 +71,7 @@ fun ColorPickerWithTitle(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(vertical = verticalPadding, horizontal = horizontalPadding)
|
.padding(vertical = verticalPadding, horizontal = horizontalPadding)
|
||||||
) {
|
) {
|
||||||
CategoryTitle(
|
SettingsCategoryTitle(
|
||||||
title = title,
|
title = title,
|
||||||
padding = 0.dp
|
padding = 0.dp
|
||||||
)
|
)
|
||||||
|
|
@ -133,7 +133,7 @@ private fun RevertibleSlider(
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(10.dp))
|
Spacer(modifier = Modifier.width(10.dp))
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
modifier = Modifier.size(28.dp),
|
modifier = Modifier.size(28.dp),
|
||||||
icon = Icons.Default.History,
|
icon = Icons.Default.History,
|
||||||
contentDescription = R.string.revert_content_desc,
|
contentDescription = R.string.revert_content_desc,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.components
|
package ua.acclorite.book_story.presentation.core.components.settings
|
||||||
|
|
||||||
import androidx.compose.animation.expandHorizontally
|
import androidx.compose.animation.expandHorizontally
|
||||||
import androidx.compose.animation.fadeIn
|
import androidx.compose.animation.fadeIn
|
||||||
|
|
@ -39,8 +39,8 @@ import androidx.compose.ui.unit.Dp
|
||||||
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.ButtonItem
|
import ua.acclorite.book_story.domain.model.ButtonItem
|
||||||
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryTitle
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Segmented Button with Title.
|
* Segmented Button with Title.
|
||||||
|
|
@ -70,7 +70,7 @@ fun SegmentedButtonWithTitle(
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(horizontal = horizontalPadding, vertical = verticalPadding)
|
.padding(horizontal = horizontalPadding, vertical = verticalPadding)
|
||||||
) {
|
) {
|
||||||
CategoryTitle(title = title, padding = 0.dp)
|
SettingsCategoryTitle(title = title, padding = 0.dp)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
|
|
@ -151,7 +151,7 @@ private fun SegmentedButton(
|
||||||
.padding(horizontal = 18.dp),
|
.padding(horizontal = 18.dp),
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = button.selected,
|
visible = button.selected,
|
||||||
enter = expandHorizontally()
|
enter = expandHorizontally()
|
||||||
+ slideInVertically(initialOffsetY = { it / 2 })
|
+ slideInVertically(initialOffsetY = { it / 2 })
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.components
|
package ua.acclorite.book_story.presentation.core.components.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
|
|
@ -24,6 +24,7 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryTitle
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -69,7 +70,7 @@ fun SliderWithTitle(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth(0.2f)) {
|
Column(Modifier.fillMaxWidth(0.2f)) {
|
||||||
CategoryTitle(title = title, padding = 0.dp)
|
SettingsCategoryTitle(title = title, padding = 0.dp)
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
Text(
|
Text(
|
||||||
text = placeholder.value,
|
text = placeholder.value,
|
||||||
|
|
@ -157,7 +158,7 @@ fun SliderWithTitle(
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Column(Modifier.fillMaxWidth(0.2f)) {
|
Column(Modifier.fillMaxWidth(0.2f)) {
|
||||||
CategoryTitle(title = title, padding = 0.dp)
|
SettingsCategoryTitle(title = title, padding = 0.dp)
|
||||||
Spacer(modifier = Modifier.height(4.dp))
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
Text(
|
Text(
|
||||||
text = placeholder.value,
|
text = placeholder.value,
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.screens.settings.components
|
package ua.acclorite.book_story.presentation.core.components.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.top_bar
|
||||||
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
import androidx.compose.foundation.lazy.LazyListState
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||||
|
|
@ -19,7 +19,7 @@ import kotlinx.coroutines.flow.collectLatest
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState(
|
fun TopAppBarDefaults.collapsibleTopAppBarScrollBehavior(
|
||||||
listState: LazyListState? = null
|
listState: LazyListState? = null
|
||||||
): Pair<TopAppBarScrollBehavior, LazyListState> {
|
): Pair<TopAppBarScrollBehavior, LazyListState> {
|
||||||
val lazyListState = listState ?: rememberLazyListState()
|
val lazyListState = listState ?: rememberLazyListState()
|
||||||
|
|
@ -41,18 +41,3 @@ fun TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState(
|
||||||
|
|
||||||
return scrollBehavior to lazyListState
|
return scrollBehavior to lazyListState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.core.components.top_bar
|
||||||
|
|
||||||
import androidx.compose.animation.core.Spring
|
import androidx.compose.animation.core.Spring
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
|
|
@ -23,8 +23,9 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.lerp
|
import androidx.compose.ui.graphics.lerp
|
||||||
import ua.acclorite.book_story.domain.util.ID
|
import ua.acclorite.book_story.domain.util.ID
|
||||||
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
|
|
||||||
data class AnimatedTopAppBarData(
|
data class TopAppBarData(
|
||||||
val contentID: ID,
|
val contentID: ID,
|
||||||
val contentNavigationIcon: @Composable () -> Unit,
|
val contentNavigationIcon: @Composable () -> Unit,
|
||||||
val contentTitle: @Composable () -> Unit,
|
val contentTitle: @Composable () -> Unit,
|
||||||
|
|
@ -32,7 +33,7 @@ data class AnimatedTopAppBarData(
|
||||||
)
|
)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animated top app bar.
|
* Top app bar.
|
||||||
* Has up to 3 different top bars inside it. Follow [TopAppBar] for more info.
|
* Has up to 3 different top bars inside it. Follow [TopAppBar] for more info.
|
||||||
*
|
*
|
||||||
* @param containerColor Container color of the TopBar.
|
* @param containerColor Container color of the TopBar.
|
||||||
|
|
@ -40,12 +41,12 @@ data class AnimatedTopAppBarData(
|
||||||
* @param scrollBehavior [TopAppBarScrollBehavior].
|
* @param scrollBehavior [TopAppBarScrollBehavior].
|
||||||
* @param isTopBarScrolled Whether isScrolled state should be forced or not.
|
* @param isTopBarScrolled Whether isScrolled state should be forced or not.
|
||||||
* @param shownTopBar [ID] of the top bar to show.
|
* @param shownTopBar [ID] of the top bar to show.
|
||||||
* @param topBars Pass a list of all [AnimatedTopAppBarData] to show.
|
* @param topBars Pass a list of all [TopAppBarData] to show.
|
||||||
* @param customContent Custom content below [TopAppBar].
|
* @param customContent Custom content below [TopAppBar].
|
||||||
*/
|
*/
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun AnimatedTopAppBar(
|
fun TopAppBar(
|
||||||
containerColor: Color = MaterialTheme.colorScheme.surface,
|
containerColor: Color = MaterialTheme.colorScheme.surface,
|
||||||
scrolledContainerColor: Color = MaterialTheme.colorScheme.surfaceContainer,
|
scrolledContainerColor: Color = MaterialTheme.colorScheme.surfaceContainer,
|
||||||
|
|
||||||
|
|
@ -53,7 +54,7 @@ fun AnimatedTopAppBar(
|
||||||
isTopBarScrolled: Boolean?,
|
isTopBarScrolled: Boolean?,
|
||||||
|
|
||||||
shownTopBar: ID,
|
shownTopBar: ID,
|
||||||
topBars: List<AnimatedTopAppBarData>,
|
topBars: List<TopAppBarData>,
|
||||||
customContent: @Composable ColumnScope.() -> Unit = {}
|
customContent: @Composable ColumnScope.() -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val animatedContainerColor = lerp(
|
val animatedContainerColor = lerp(
|
||||||
|
|
@ -74,7 +75,7 @@ fun AnimatedTopAppBar(
|
||||||
) {
|
) {
|
||||||
Box(modifier = Modifier.fillMaxWidth()) {
|
Box(modifier = Modifier.fillMaxWidth()) {
|
||||||
topBars.forEach { data ->
|
topBars.forEach { data ->
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = data.contentID == shownTopBar,
|
visible = data.contentID == shownTopBar,
|
||||||
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
|
enter = fadeIn(spring(stiffness = Spring.StiffnessMediumLow)),
|
||||||
exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow))
|
exit = fadeOut(spring(stiffness = Spring.StiffnessMediumLow))
|
||||||
|
|
@ -98,10 +99,3 @@ fun AnimatedTopAppBar(
|
||||||
customContent()
|
customContent()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -49,7 +49,7 @@ import kotlinx.parcelize.Parcelize
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import ua.acclorite.book_story.domain.util.OnNavigate
|
import ua.acclorite.book_story.domain.util.OnNavigate
|
||||||
import ua.acclorite.book_story.domain.util.Route
|
import ua.acclorite.book_story.domain.util.Route
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.ui.Transitions
|
import ua.acclorite.book_story.presentation.ui.Transitions
|
||||||
|
|
||||||
private const val CURRENT_SCREEN = "current_screen"
|
private const val CURRENT_SCREEN = "current_screen"
|
||||||
|
|
@ -320,7 +320,7 @@ class Navigator @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = shouldShow,
|
visible = shouldShow,
|
||||||
enter = if (!useBackAnimation) enterAnim else backEnterAnim,
|
enter = if (!useBackAnimation) enterAnim else backEnterAnim,
|
||||||
exit = if (!useBackAnimation) exitAnim else backExitAnim
|
exit = if (!useBackAnimation) exitAnim else backExitAnim
|
||||||
|
|
@ -372,7 +372,7 @@ class Navigator @AssistedInject constructor(
|
||||||
}
|
}
|
||||||
val showNavigationBottomSheet = showNavigationBottomSheet.collectAsState()
|
val showNavigationBottomSheet = showNavigationBottomSheet.collectAsState()
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = showNavigation.value,
|
visible = showNavigation.value,
|
||||||
enter = if (useBackAnimation) backEnterBarAnim
|
enter = if (useBackAnimation) backEnterBarAnim
|
||||||
else enterBarAnim,
|
else enterBarAnim,
|
||||||
|
|
@ -428,7 +428,7 @@ class Navigator @AssistedInject constructor(
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom Navigation Host. Contains [Navigator.composable]s in [content].
|
* Custom Navigation Host. Contains [Navigator.composable]s in [content].
|
||||||
* Based on [CustomAnimatedVisibility].
|
* Based on [AnimatedVisibility].
|
||||||
*
|
*
|
||||||
* @param startScreen Start Screen. Be sure to pass [Screen] that uses in one of your [Navigator.composable]s.
|
* @param startScreen Start Screen. Be sure to pass [Screen] that uses in one of your [Navigator.composable]s.
|
||||||
* @param colorBetweenAnimations The color, that using between animations, recommended to set this to background or navigation bar color.
|
* @param colorBetweenAnimations The color, that using between animations, recommended to set this to background or navigation bar color.
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.util.Position
|
import ua.acclorite.book_story.domain.util.Position
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheet
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigation Bottom Sheet.
|
* Navigation Bottom Sheet.
|
||||||
|
|
@ -23,7 +23,7 @@ import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.
|
||||||
fun NavigationBottomSheet(onDismissRequest: () -> Unit) {
|
fun NavigationBottomSheet(onDismissRequest: () -> Unit) {
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
|
|
||||||
CustomBottomSheet(
|
ModalBottomSheet(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onDismissRequest = onDismissRequest
|
onDismissRequest = onDismissRequest
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
import androidx.compose.material.icons.filled.MoreVert
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Navigation Icon Button.
|
* Navigation Icon Button.
|
||||||
|
|
@ -15,7 +15,7 @@ fun NavigationIconButton(
|
||||||
onClick: Navigator.() -> Unit = { showNavigationBottomSheet() }
|
onClick: Navigator.() -> Unit = { showNavigationBottomSheet() }
|
||||||
) {
|
) {
|
||||||
val navigator = LocalNavigatorInstance.current
|
val navigator = LocalNavigatorInstance.current
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.MoreVert,
|
icon = Icons.Default.MoreVert,
|
||||||
contentDescription = R.string.more_content_desc,
|
contentDescription = R.string.more_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package ua.acclorite.book_story.presentation.core.util
|
||||||
|
|
||||||
|
fun <T> MutableList<T>.addAll(calculation: () -> List<T>) {
|
||||||
|
addAll(calculation())
|
||||||
|
}
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
package ua.acclorite.book_story.presentation.core.util
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
|
||||||
import androidx.compose.foundation.combinedClickable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
fun String.removeTrailingZero(): String {
|
|
||||||
if (!this.contains('.'))
|
|
||||||
return this
|
|
||||||
return this
|
|
||||||
.dropLastWhile { it == '0' }
|
|
||||||
.dropLastWhile { it == '.' }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Double.removeDigits(digits: Int) = "%.${digits}f".format(this).replace(",", ".")
|
|
||||||
|
|
||||||
fun Intent.launchActivity(
|
|
||||||
activity: ComponentActivity,
|
|
||||||
createChooser: Boolean = false,
|
|
||||||
openInNewWindow: Boolean = true,
|
|
||||||
error: () -> Unit
|
|
||||||
) {
|
|
||||||
val intent = if (createChooser) Intent.createChooser(this, "") else this
|
|
||||||
if (openInNewWindow) {
|
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
activity.baseContext.startActivity(intent)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
e.printStackTrace()
|
|
||||||
error()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Float.calculateProgress(digits: Int): String {
|
|
||||||
return (this * 100)
|
|
||||||
.toDouble()
|
|
||||||
.removeDigits(digits)
|
|
||||||
.removeTrailingZero()
|
|
||||||
.dropWhile { it == '-' }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Float.coerceAndPreventNaN(): Float {
|
|
||||||
if (isNaN()) return 0f
|
|
||||||
return this.coerceIn(0f, 1f)
|
|
||||||
}
|
|
||||||
|
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
fun Modifier.noRippleClickable(
|
|
||||||
enabled: Boolean = true,
|
|
||||||
onLongClick: (() -> Unit)? = null,
|
|
||||||
onDoubleClick: (() -> Unit)? = null,
|
|
||||||
onClick: () -> Unit
|
|
||||||
): Modifier {
|
|
||||||
return this.combinedClickable(
|
|
||||||
indication = null,
|
|
||||||
interactionSource = null,
|
|
||||||
enabled = enabled,
|
|
||||||
onLongClick = onLongClick,
|
|
||||||
onDoubleClick = onDoubleClick,
|
|
||||||
onClick = onClick
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun String.clearMarkdown(): String {
|
|
||||||
return replace(Regex("_|\\*\\*"), "")
|
|
||||||
}
|
|
||||||
|
|
||||||
fun <T> MutableList<T>.addAll(calculation: () -> List<T>) {
|
|
||||||
addAll(calculation())
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package ua.acclorite.book_story.presentation.core.util
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.activity.ComponentActivity
|
||||||
|
|
||||||
|
fun Intent.launchActivity(
|
||||||
|
activity: ComponentActivity,
|
||||||
|
createChooser: Boolean = false,
|
||||||
|
openInNewWindow: Boolean = true,
|
||||||
|
error: () -> Unit
|
||||||
|
) {
|
||||||
|
val intent = if (createChooser) Intent.createChooser(this, "") else this
|
||||||
|
if (openInNewWindow) {
|
||||||
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
activity.baseContext.startActivity(intent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
package ua.acclorite.book_story.presentation.core.util
|
||||||
|
|
||||||
|
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||||
|
import androidx.compose.foundation.combinedClickable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
|
||||||
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
|
fun Modifier.noRippleClickable(
|
||||||
|
enabled: Boolean = true,
|
||||||
|
onLongClick: (() -> Unit)? = null,
|
||||||
|
onDoubleClick: (() -> Unit)? = null,
|
||||||
|
onClick: () -> Unit
|
||||||
|
): Modifier {
|
||||||
|
return this.combinedClickable(
|
||||||
|
indication = null,
|
||||||
|
interactionSource = null,
|
||||||
|
enabled = enabled,
|
||||||
|
onLongClick = onLongClick,
|
||||||
|
onDoubleClick = onDoubleClick,
|
||||||
|
onClick = onClick
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
package ua.acclorite.book_story.presentation.core.util
|
||||||
|
|
||||||
|
fun String.removeTrailingZero(): String {
|
||||||
|
if (!this.contains('.'))
|
||||||
|
return this
|
||||||
|
return this
|
||||||
|
.dropLastWhile { it == '0' }
|
||||||
|
.dropLastWhile { it == '.' }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Double.removeDigits(digits: Int) = "%.${digits}f".format(this).replace(",", ".")
|
||||||
|
|
||||||
|
fun Float.calculateProgress(digits: Int): String {
|
||||||
|
return (this * 100)
|
||||||
|
.toDouble()
|
||||||
|
.removeDigits(digits)
|
||||||
|
.removeTrailingZero()
|
||||||
|
.dropWhile { it == '-' }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Float.coerceAndPreventNaN(): Float {
|
||||||
|
if (isNaN()) return 0f
|
||||||
|
return this.coerceIn(0f, 1f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.clearMarkdown(): String {
|
||||||
|
return replace(Regex("_|\\*\\*"), "")
|
||||||
|
}
|
||||||
|
|
@ -17,11 +17,11 @@ import ua.acclorite.book_story.domain.use_case.data_store.ChangeLanguage
|
||||||
import ua.acclorite.book_story.domain.use_case.data_store.GetAllSettings
|
import ua.acclorite.book_story.domain.use_case.data_store.GetAllSettings
|
||||||
import ua.acclorite.book_story.domain.use_case.data_store.SetDatastore
|
import ua.acclorite.book_story.domain.use_case.data_store.SetDatastore
|
||||||
import ua.acclorite.book_story.domain.use_case.remote.CheckForUpdates
|
import ua.acclorite.book_story.domain.use_case.remote.CheckForUpdates
|
||||||
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
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.constants.DataStoreConstants
|
import ua.acclorite.book_story.presentation.core.constants.DataStoreConstants
|
||||||
import ua.acclorite.book_story.presentation.core.constants.provideFonts
|
import ua.acclorite.book_story.presentation.core.constants.provideFonts
|
||||||
import ua.acclorite.book_story.presentation.core.constants.provideMainState
|
import ua.acclorite.book_story.presentation.core.constants.provideMainState
|
||||||
import ua.acclorite.book_story.presentation.core.util.UiViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseFilesStructure
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseFilesStructure
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseLayout
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseLayout
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseSortOrder
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.toBrowseSortOrder
|
||||||
|
|
@ -42,7 +42,7 @@ class MainViewModel @Inject constructor(
|
||||||
private val changeLanguage: ChangeLanguage,
|
private val changeLanguage: ChangeLanguage,
|
||||||
private val checkForUpdates: CheckForUpdates,
|
private val checkForUpdates: CheckForUpdates,
|
||||||
private val getAllSettings: GetAllSettings
|
private val getAllSettings: GetAllSettings
|
||||||
) : UiViewModel<MainState, MainEvent>() {
|
) : UIViewModel<MainState, MainEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -28,9 +28,9 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.buildAnnotatedString
|
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.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.GoBackButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
import ua.acclorite.book_story.presentation.core.components.top_bar.collapsibleTopAppBarScrollBehavior
|
||||||
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.constants.provideContributorsPage
|
import ua.acclorite.book_story.presentation.core.constants.provideContributorsPage
|
||||||
import ua.acclorite.book_story.presentation.core.constants.provideIssuesPage
|
import ua.acclorite.book_story.presentation.core.constants.provideIssuesPage
|
||||||
|
|
@ -58,7 +58,7 @@ private fun AboutScreen() {
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
val (scrollBehavior, lazyListState) = TopAppBarDefaults.collapsibleTopAppBarScrollBehavior()
|
||||||
|
|
||||||
if (state.value.showUpdateDialog) {
|
if (state.value.showUpdateDialog) {
|
||||||
AboutUpdateDialog()
|
AboutUpdateDialog()
|
||||||
|
|
@ -67,7 +67,7 @@ private fun AboutScreen() {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.nestedScroll(scrollState.first.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.windowInsetsPadding(WindowInsets.navigationBars),
|
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -78,7 +78,7 @@ private fun AboutScreen() {
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
GoBackButton(onNavigate = onNavigate)
|
GoBackButton(onNavigate = onNavigate)
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollState.first,
|
scrollBehavior = scrollBehavior,
|
||||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
|
|
@ -86,11 +86,11 @@ private fun AboutScreen() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
CustomLazyColumn(
|
LazyColumnWithScrollbar(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(top = paddingValues.calculateTopPadding()),
|
.padding(top = paddingValues.calculateTopPadding()),
|
||||||
state = scrollState.second
|
state = lazyListState
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_dialog.CustomDialogWithContent
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithContent
|
||||||
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.constants.provideReleasesPage
|
import ua.acclorite.book_story.presentation.core.constants.provideReleasesPage
|
||||||
import ua.acclorite.book_story.presentation.core.util.showToast
|
import ua.acclorite.book_story.presentation.core.util.showToast
|
||||||
|
|
@ -27,7 +27,7 @@ fun AboutUpdateDialog() {
|
||||||
state.value.updateInfo!!
|
state.value.updateInfo!!
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomDialogWithContent(
|
DialogWithContent(
|
||||||
title = stringResource(id = R.string.update_query, update.tagName),
|
title = stringResource(id = R.string.update_query, update.tagName),
|
||||||
imageVectorIcon = Icons.Default.Update,
|
imageVectorIcon = Icons.Default.Update,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.domain.model.Badge
|
import ua.acclorite.book_story.domain.model.Badge
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* About Badge Item.
|
* About Badge Item.
|
||||||
|
|
@ -20,7 +20,7 @@ fun AboutBadgeItem(
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
if (badge.imageVector == null && badge.drawable != null) {
|
if (badge.imageVector == null && badge.drawable != null) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
modifier = Modifier.size(22.dp),
|
modifier = Modifier.size(22.dp),
|
||||||
icon = badge.drawable,
|
icon = badge.drawable,
|
||||||
contentDescription = badge.contentDescription,
|
contentDescription = badge.contentDescription,
|
||||||
|
|
@ -30,7 +30,7 @@ fun AboutBadgeItem(
|
||||||
onClick()
|
onClick()
|
||||||
}
|
}
|
||||||
} else if (badge.imageVector != null && badge.drawable == null) {
|
} else if (badge.imageVector != null && badge.drawable == null) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
modifier = Modifier.size(22.dp),
|
modifier = Modifier.size(22.dp),
|
||||||
icon = badge.imageVector,
|
icon = badge.imageVector,
|
||||||
contentDescription = badge.contentDescription,
|
contentDescription = badge.contentDescription,
|
||||||
|
|
|
||||||
|
|
@ -12,14 +12,14 @@ import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.use_case.remote.CheckForUpdates
|
import ua.acclorite.book_story.domain.use_case.remote.CheckForUpdates
|
||||||
import ua.acclorite.book_story.presentation.core.util.UiViewModel
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class AboutViewModel @Inject constructor(
|
class AboutViewModel @Inject constructor(
|
||||||
private val checkForUpdates: CheckForUpdates,
|
private val checkForUpdates: CheckForUpdates,
|
||||||
) : UiViewModel<AboutState, AboutEvent>() {
|
) : UIViewModel<AboutState, AboutEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,9 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
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.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.GoBackButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
import ua.acclorite.book_story.presentation.core.components.top_bar.collapsibleTopAppBarScrollBehavior
|
||||||
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.constants.provideCredits
|
import ua.acclorite.book_story.presentation.core.constants.provideCredits
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
||||||
|
|
@ -41,12 +41,12 @@ private fun CreditsScreen() {
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
val (scrollBehavior, lazyListState) = TopAppBarDefaults.collapsibleTopAppBarScrollBehavior()
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.nestedScroll(scrollState.first.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.windowInsetsPadding(WindowInsets.navigationBars),
|
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -57,7 +57,7 @@ private fun CreditsScreen() {
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
GoBackButton(onNavigate = onNavigate)
|
GoBackButton(onNavigate = onNavigate)
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollState.first,
|
scrollBehavior = scrollBehavior,
|
||||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
|
|
@ -65,11 +65,11 @@ private fun CreditsScreen() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
CustomLazyColumn(
|
LazyColumnWithScrollbar(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(top = paddingValues.calculateTopPadding()),
|
.padding(top = paddingValues.calculateTopPadding()),
|
||||||
state = scrollState.second
|
state = lazyListState
|
||||||
) {
|
) {
|
||||||
items(Constants.provideCredits(), key = { it.name }) {
|
items(Constants.provideCredits(), key = { it.name }) {
|
||||||
CreditItem(credit = it) {
|
CreditItem(credit = it) {
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,10 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.common.GoBackButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
import ua.acclorite.book_story.presentation.core.components.top_bar.collapsibleTopAppBarScrollBehavior
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -76,7 +76,7 @@ private fun LicenseInfoScreen() {
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
|
|
||||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
val (scrollBehavior, lazyListState) = TopAppBarDefaults.collapsibleTopAppBarScrollBehavior()
|
||||||
val licenses = remember(state.value.license?.licenses) {
|
val licenses = remember(state.value.license?.licenses) {
|
||||||
state.value.license?.licenses?.toList()
|
state.value.license?.licenses?.toList()
|
||||||
}
|
}
|
||||||
|
|
@ -84,7 +84,7 @@ private fun LicenseInfoScreen() {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.nestedScroll(scrollState.first.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.windowInsetsPadding(WindowInsets.navigationBars),
|
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -105,7 +105,7 @@ private fun LicenseInfoScreen() {
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (state.value.license?.website?.isNotBlank() == true) {
|
if (state.value.license?.website?.isNotBlank() == true) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Outlined.Language,
|
icon = Icons.Outlined.Language,
|
||||||
contentDescription = R.string.open_in_web_content_desc,
|
contentDescription = R.string.open_in_web_content_desc,
|
||||||
disableOnClick = false
|
disableOnClick = false
|
||||||
|
|
@ -130,7 +130,7 @@ private fun LicenseInfoScreen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollState.first,
|
scrollBehavior = scrollBehavior,
|
||||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
|
|
@ -141,11 +141,11 @@ private fun LicenseInfoScreen() {
|
||||||
DefaultTransition(
|
DefaultTransition(
|
||||||
visible = state.value.license != null
|
visible = state.value.license != null
|
||||||
) {
|
) {
|
||||||
CustomLazyColumn(
|
LazyColumnWithScrollbar(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(top = paddingValues.calculateTopPadding()),
|
.padding(top = paddingValues.calculateTopPadding()),
|
||||||
state = scrollState.second,
|
state = lazyListState,
|
||||||
contentPadding = PaddingValues(horizontal = 16.dp),
|
contentPadding = PaddingValues(horizontal = 16.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(8.dp)
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -13,14 +13,14 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ua.acclorite.book_story.presentation.core.util.UiViewModel
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class LicenseInfoViewModel @Inject constructor(
|
class LicenseInfoViewModel @Inject constructor(
|
||||||
|
|
||||||
) : UiViewModel<LicenseInfoState, LicenseInfoEvent>() {
|
) : UIViewModel<LicenseInfoState, LicenseInfoEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.GoBackButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
import ua.acclorite.book_story.presentation.core.components.top_bar.collapsibleTopAppBarScrollBehavior
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -53,14 +53,14 @@ private fun LicensesScreen() {
|
||||||
val state = LicensesViewModel.getState()
|
val state = LicensesViewModel.getState()
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
|
|
||||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState(
|
val (scrollBehavior, lazyListState) = TopAppBarDefaults.collapsibleTopAppBarScrollBehavior(
|
||||||
state.value.listState
|
listState = state.value.listState
|
||||||
)
|
)
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.nestedScroll(scrollState.first.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.windowInsetsPadding(WindowInsets.navigationBars),
|
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -71,7 +71,7 @@ private fun LicensesScreen() {
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
GoBackButton(onNavigate = onNavigate)
|
GoBackButton(onNavigate = onNavigate)
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollState.first,
|
scrollBehavior = scrollBehavior,
|
||||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
|
|
@ -79,16 +79,16 @@ private fun LicensesScreen() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = state.value.licenses.isNotEmpty(),
|
visible = state.value.licenses.isNotEmpty(),
|
||||||
enter = fadeIn(tween(300)),
|
enter = fadeIn(tween(300)),
|
||||||
exit = fadeOut(tween(300))
|
exit = fadeOut(tween(300))
|
||||||
) {
|
) {
|
||||||
CustomLazyColumn(
|
LazyColumnWithScrollbar(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(top = paddingValues.calculateTopPadding()),
|
.padding(top = paddingValues.calculateTopPadding()),
|
||||||
state = scrollState.second
|
state = lazyListState
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.util.UiViewModel
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class LicensesViewModel @Inject constructor(
|
class LicensesViewModel @Inject constructor(
|
||||||
|
|
||||||
) : UiViewModel<LicensesState, LicensesEvent>() {
|
) : UIViewModel<LicensesState, LicensesEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSnackbar
|
import ua.acclorite.book_story.presentation.core.components.common.Snackbar
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -146,7 +146,7 @@ private fun BookInfoScreen(snackbarState: SnackbarHostState) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
CustomSnackbar(
|
Snackbar(
|
||||||
modifier = Modifier.padding(bottom = 70.dp),
|
modifier = Modifier.padding(bottom = 70.dp),
|
||||||
snackbarState = snackbarState
|
snackbarState = snackbarState
|
||||||
)
|
)
|
||||||
|
|
@ -212,7 +212,7 @@ private fun BookInfoScreen(snackbarState: SnackbarHostState) {
|
||||||
contentDescription = stringResource(id = R.string.continue_reading_content_desc),
|
contentDescription = stringResource(id = R.string.continue_reading_content_desc),
|
||||||
Modifier.size(24.dp)
|
Modifier.size(24.dp)
|
||||||
)
|
)
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = !listState.canScrollBackward,
|
visible = !listState.canScrollBackward,
|
||||||
enter = fadeIn() + expandHorizontally(),
|
enter = fadeIn() + expandHorizontally(),
|
||||||
exit = fadeOut() + shrinkHorizontally()
|
exit = fadeOut() + shrinkHorizontally()
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCoverImage
|
import ua.acclorite.book_story.presentation.core.components.common.AsyncImage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Background of the BookInfoScreen.
|
* Background of the BookInfoScreen.
|
||||||
|
|
@ -21,7 +21,7 @@ import ua.acclorite.book_story.presentation.core.components.CustomCoverImage
|
||||||
fun BookInfoBackground(height: Dp, image: Uri) {
|
fun BookInfoBackground(height: Dp, image: Uri) {
|
||||||
val background = MaterialTheme.colorScheme.surface
|
val background = MaterialTheme.colorScheme.surface
|
||||||
|
|
||||||
CustomCoverImage(
|
AsyncImage(
|
||||||
uri = image,
|
uri = image,
|
||||||
animationDurationMillis = 300,
|
animationDurationMillis = 300,
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCoverImage
|
import ua.acclorite.book_story.presentation.core.components.common.AsyncImage
|
||||||
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||||
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.book_info.data.BookInfoViewModel
|
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel
|
||||||
|
|
@ -73,7 +73,7 @@ fun BookInfoInfoSection() {
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
if (state.value.book.coverImage != null) {
|
if (state.value.book.coverImage != null) {
|
||||||
CustomCoverImage(
|
AsyncImage(
|
||||||
uri = state.value.book.coverImage!!,
|
uri = state.value.book.coverImage!!,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.util.Position
|
import ua.acclorite.book_story.domain.util.Position
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheet
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.NavigationItem
|
import ua.acclorite.book_story.presentation.core.navigation.NavigationItem
|
||||||
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.book_info.data.BookInfoViewModel
|
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel
|
||||||
|
|
@ -26,7 +26,7 @@ import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewM
|
||||||
fun BookInfoMoreBottomSheet(snackbarState: SnackbarHostState) {
|
fun BookInfoMoreBottomSheet(snackbarState: SnackbarHostState) {
|
||||||
val onEvent = BookInfoViewModel.getEvent()
|
val onEvent = BookInfoViewModel.getEvent()
|
||||||
|
|
||||||
CustomBottomSheet(
|
ModalBottomSheet(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(false))
|
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(false))
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
import ua.acclorite.book_story.presentation.core.components.common.GoBackButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBar
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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.NavigationIconButton
|
||||||
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
|
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoEvent
|
||||||
|
|
@ -56,14 +56,14 @@ fun BookInfoTopBar(
|
||||||
|
|
||||||
val firstVisibleItemIndex by remember { derivedStateOf { listState.firstVisibleItemIndex } }
|
val firstVisibleItemIndex by remember { derivedStateOf { listState.firstVisibleItemIndex } }
|
||||||
|
|
||||||
AnimatedTopAppBar(
|
TopAppBar(
|
||||||
containerColor = MaterialTheme.colorScheme.surface.copy(0f),
|
containerColor = MaterialTheme.colorScheme.surface.copy(0f),
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = listState.canScrollBackward,
|
isTopBarScrolled = listState.canScrollBackward,
|
||||||
|
|
||||||
shownTopBar = 0,
|
shownTopBar = 0,
|
||||||
topBars = listOf(
|
topBars = listOf(
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 0,
|
contentID = 0,
|
||||||
contentNavigationIcon = {
|
contentNavigationIcon = {
|
||||||
if (
|
if (
|
||||||
|
|
@ -71,7 +71,7 @@ fun BookInfoTopBar(
|
||||||
state.value.editAuthor ||
|
state.value.editAuthor ||
|
||||||
state.value.editDescription
|
state.value.editDescription
|
||||||
) {
|
) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
||||||
contentDescription = R.string.exit_editing_content_desc,
|
contentDescription = R.string.exit_editing_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
|
|
@ -108,7 +108,7 @@ fun BookInfoTopBar(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Outlined.Refresh,
|
icon = Icons.Outlined.Refresh,
|
||||||
contentDescription = R.string.refresh_book_content_desc,
|
contentDescription = R.string.refresh_book_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
@ -132,14 +132,14 @@ fun BookInfoTopBar(
|
||||||
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(true))
|
onEvent(BookInfoEvent.OnShowHideMoreBottomSheet(true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = state.value.editTitle ||
|
visible = state.value.editTitle ||
|
||||||
state.value.editAuthor ||
|
state.value.editAuthor ||
|
||||||
state.value.editDescription,
|
state.value.editDescription,
|
||||||
enter = Transitions.DefaultTransitionIn,
|
enter = Transitions.DefaultTransitionIn,
|
||||||
exit = fadeOut(tween(200))
|
exit = fadeOut(tween(200))
|
||||||
) {
|
) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Outlined.Done,
|
icon = Icons.Outlined.Done,
|
||||||
contentDescription = R.string.apply_changes_content_desc,
|
contentDescription = R.string.apply_changes_content_desc,
|
||||||
disableOnClick = true,
|
disableOnClick = true,
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheet
|
||||||
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.book_info.data.BookInfoViewModel
|
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel
|
||||||
|
|
@ -62,7 +62,7 @@ fun BookInfoChangeCoverBottomSheet() {
|
||||||
onEvent(BookInfoEvent.OnCheckCoverReset)
|
onEvent(BookInfoEvent.OnCheckCoverReset)
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomBottomSheet(
|
ModalBottomSheet(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
onEvent(BookInfoEvent.OnShowHideChangeCoverBottomSheet)
|
onEvent(BookInfoEvent.OnShowHideChangeCoverBottomSheet)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheet
|
||||||
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.book_info.data.BookInfoViewModel
|
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel
|
||||||
|
|
@ -55,7 +55,7 @@ fun BookInfoDetailsBottomSheet() {
|
||||||
else ""
|
else ""
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomBottomSheet(
|
ModalBottomSheet(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
onDismissRequest = {
|
onDismissRequest = {
|
||||||
onEvent(BookInfoEvent.OnShowHideDetailsBottomSheet)
|
onEvent(BookInfoEvent.OnShowHideDetailsBottomSheet)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_dialog.CustomDialogWithContent
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithContent
|
||||||
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.book_info.data.BookInfoViewModel
|
import ua.acclorite.book_story.presentation.screens.book_info.data.BookInfoViewModel
|
||||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||||
|
|
@ -28,7 +28,7 @@ fun BookInfoConfirmUpdateDialog(snackbarHostState: SnackbarHostState) {
|
||||||
val onHistoryEvent = HistoryViewModel.getEvent()
|
val onHistoryEvent = HistoryViewModel.getEvent()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
CustomDialogWithContent(
|
DialogWithContent(
|
||||||
title = stringResource(id = R.string.confirm_update),
|
title = stringResource(id = R.string.confirm_update),
|
||||||
imageVectorIcon = Icons.Default.Update,
|
imageVectorIcon = Icons.Default.Update,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_dialog.CustomDialogWithContent
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithContent
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -30,7 +30,7 @@ fun BookInfoDeleteDialog() {
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
CustomDialogWithContent(
|
DialogWithContent(
|
||||||
title = stringResource(id = R.string.delete_book),
|
title = stringResource(id = R.string.delete_book),
|
||||||
imageVectorIcon = Icons.Outlined.DeleteOutline,
|
imageVectorIcon = Icons.Outlined.DeleteOutline,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.model.Category
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithLazyColumn
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_dialog.SelectableDialogItem
|
import ua.acclorite.book_story.presentation.core.components.dialog.SelectableDialogItem
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -42,7 +42,7 @@ fun BookInfoMoveDialog() {
|
||||||
onEvent(BookInfoEvent.OnSelectCategory(categories[0]))
|
onEvent(BookInfoEvent.OnSelectCategory(categories[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomDialogWithLazyColumn(
|
DialogWithLazyColumn(
|
||||||
title = stringResource(id = R.string.move_book),
|
title = stringResource(id = R.string.move_book),
|
||||||
imageVectorIcon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
imageVectorIcon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ import ua.acclorite.book_story.domain.use_case.book.UpdateCoverImageOfBook
|
||||||
import ua.acclorite.book_story.domain.use_case.history.InsertHistory
|
import ua.acclorite.book_story.domain.use_case.history.InsertHistory
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.util.UIText
|
||||||
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
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.UiViewModel
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
@ -53,7 +53,7 @@ class BookInfoViewModel @Inject constructor(
|
||||||
private val canResetCover: CanResetCover,
|
private val canResetCover: CanResetCover,
|
||||||
private val resetCoverImage: ResetCoverImage,
|
private val resetCoverImage: ResetCoverImage,
|
||||||
private val checkForTextUpdate: CheckForTextUpdate,
|
private val checkForTextUpdate: CheckForTextUpdate,
|
||||||
) : UiViewModel<BookInfoState, BookInfoEvent>() {
|
) : UIViewModel<BookInfoState, BookInfoEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -9,9 +9,9 @@ import androidx.compose.ui.res.stringResource
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.PermissionState
|
import com.google.accompanist.permissions.PermissionState
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty
|
import ua.acclorite.book_story.presentation.core.components.placeholder.EmptyPlaceholder
|
||||||
import ua.acclorite.book_story.presentation.core.components.is_messages.IsError
|
import ua.acclorite.book_story.presentation.core.components.placeholder.ErrorPlaceholder
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -35,13 +35,13 @@ fun BoxScope.BrowseEmptyPlaceholder(
|
||||||
val onEvent = BrowseViewModel.getEvent()
|
val onEvent = BrowseViewModel.getEvent()
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = state.value.isError,
|
visible = state.value.isError,
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
enter = Transitions.DefaultTransitionIn,
|
enter = Transitions.DefaultTransitionIn,
|
||||||
exit = Transitions.NoExitAnimation
|
exit = Transitions.NoExitAnimation
|
||||||
) {
|
) {
|
||||||
IsError(
|
ErrorPlaceholder(
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
errorMessage = stringResource(id = R.string.error_permission),
|
errorMessage = stringResource(id = R.string.error_permission),
|
||||||
icon = painterResource(id = R.drawable.error),
|
icon = painterResource(id = R.drawable.error),
|
||||||
|
|
@ -53,7 +53,7 @@ fun BoxScope.BrowseEmptyPlaceholder(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = !state.value.isLoading
|
visible = !state.value.isLoading
|
||||||
&& isFilesEmpty
|
&& isFilesEmpty
|
||||||
&& !state.value.isError
|
&& !state.value.isError
|
||||||
|
|
@ -63,7 +63,7 @@ fun BoxScope.BrowseEmptyPlaceholder(
|
||||||
enter = Transitions.DefaultTransitionIn,
|
enter = Transitions.DefaultTransitionIn,
|
||||||
exit = Transitions.NoExitAnimation
|
exit = Transitions.NoExitAnimation
|
||||||
) {
|
) {
|
||||||
IsEmpty(
|
EmptyPlaceholder(
|
||||||
message = stringResource(id = R.string.browse_empty),
|
message = stringResource(id = R.string.browse_empty),
|
||||||
icon = painterResource(id = R.drawable.empty_browse),
|
icon = painterResource(id = R.drawable.empty_browse),
|
||||||
actionTitle = stringResource(id = R.string.get_help),
|
actionTitle = stringResource(id = R.string.get_help),
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||||
import com.google.accompanist.permissions.PermissionState
|
import com.google.accompanist.permissions.PermissionState
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithContent
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithContent
|
||||||
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.browse.data.BrowseViewModel
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ fun BrowseStoragePermissionDialog(
|
||||||
val activity = LocalContext.current as ComponentActivity
|
val activity = LocalContext.current as ComponentActivity
|
||||||
val onEvent = BrowseViewModel.getEvent()
|
val onEvent = BrowseViewModel.getEvent()
|
||||||
|
|
||||||
CustomDialogWithContent(
|
DialogWithContent(
|
||||||
title = stringResource(id = R.string.storage_permission),
|
title = stringResource(id = R.string.storage_permission),
|
||||||
description = stringResource(id = R.string.storage_permission_description),
|
description = stringResource(id = R.string.storage_permission_description),
|
||||||
actionText = stringResource(id = R.string.grant),
|
actionText = stringResource(id = R.string.grant),
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.NullableBook
|
import ua.acclorite.book_story.domain.model.NullableBook
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithLazyColumn
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -39,7 +39,7 @@ fun BrowseAddingDialog() {
|
||||||
val onLibraryEvent = LibraryViewModel.getEvent()
|
val onLibraryEvent = LibraryViewModel.getEvent()
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
|
|
||||||
CustomDialogWithLazyColumn(
|
DialogWithLazyColumn(
|
||||||
title = stringResource(id = R.string.add_books),
|
title = stringResource(id = R.string.add_books),
|
||||||
imageVectorIcon = Icons.Default.AddChart,
|
imageVectorIcon = Icons.Default.AddChart,
|
||||||
description = stringResource(id = R.string.add_books_description),
|
description = stringResource(id = R.string.add_books_description),
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ 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.NullableBook
|
import ua.acclorite.book_story.domain.model.NullableBook
|
||||||
import ua.acclorite.book_story.domain.util.Selected
|
import ua.acclorite.book_story.domain.util.Selected
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCheckbox
|
import ua.acclorite.book_story.presentation.core.components.common.CircularCheckbox
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adding dialog item.
|
* Adding dialog item.
|
||||||
|
|
@ -62,7 +62,7 @@ fun BrowseAddingDialogItem(result: Pair<NullableBook, Selected>, onClick: (Boole
|
||||||
}
|
}
|
||||||
Row {
|
Row {
|
||||||
Spacer(modifier = Modifier.width(24.dp))
|
Spacer(modifier = Modifier.width(24.dp))
|
||||||
CustomCheckbox(
|
CircularCheckbox(
|
||||||
selected = result.second,
|
selected = result.second,
|
||||||
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh
|
containerColor = MaterialTheme.colorScheme.surfaceContainerHigh
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheet
|
||||||
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.browse.data.BrowseViewModel
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.components.subcategories.BrowseFilterSubcategory
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.components.subcategories.BrowseFilterSubcategory
|
||||||
|
|
@ -37,7 +37,7 @@ fun BrowseFilterBottomSheet() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomBottomSheet(
|
ModalBottomSheet(
|
||||||
hasFixedHeight = true,
|
hasFixedHeight = true,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
|
|
@ -55,7 +55,7 @@ fun BrowseFilterBottomSheet() {
|
||||||
HorizontalPager(state = pagerState, modifier = Modifier.fillMaxSize()) { page ->
|
HorizontalPager(state = pagerState, modifier = Modifier.fillMaxSize()) { page ->
|
||||||
when (page) {
|
when (page) {
|
||||||
0 -> {
|
0 -> {
|
||||||
CustomLazyColumn(Modifier.fillMaxSize()) {
|
LazyColumnWithScrollbar(Modifier.fillMaxSize()) {
|
||||||
BrowseGeneralSubcategory(
|
BrowseGeneralSubcategory(
|
||||||
showTitle = false,
|
showTitle = false,
|
||||||
showDivider = false,
|
showDivider = false,
|
||||||
|
|
@ -66,7 +66,7 @@ fun BrowseFilterBottomSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
1 -> {
|
1 -> {
|
||||||
CustomLazyColumn(Modifier.fillMaxSize()) {
|
LazyColumnWithScrollbar(Modifier.fillMaxSize()) {
|
||||||
BrowseFilterSubcategory(
|
BrowseFilterSubcategory(
|
||||||
showTitle = false,
|
showTitle = false,
|
||||||
showDivider = false,
|
showDivider = false,
|
||||||
|
|
@ -77,7 +77,7 @@ fun BrowseFilterBottomSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
2 -> {
|
2 -> {
|
||||||
CustomLazyColumn(Modifier.fillMaxSize()) {
|
LazyColumnWithScrollbar(Modifier.fillMaxSize()) {
|
||||||
BrowseSortSubcategory(
|
BrowseSortSubcategory(
|
||||||
showTitle = false,
|
showTitle = false,
|
||||||
showDivider = false,
|
showDivider = false,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import androidx.compose.foundation.pager.PagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_bottom_sheet.CustomBottomSheetTabRow
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheetTabRow
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -25,7 +25,7 @@ fun BrowseFilterBottomSheetTabRow(
|
||||||
stringResource(id = R.string.sort_tab)
|
stringResource(id = R.string.sort_tab)
|
||||||
)
|
)
|
||||||
|
|
||||||
CustomBottomSheetTabRow(
|
ModalBottomSheetTabRow(
|
||||||
selectedTabIndex = pagerState.currentPage,
|
selectedTabIndex = pagerState.currentPage,
|
||||||
tabs = tabItems
|
tabs = tabItems
|
||||||
) { index ->
|
) { index ->
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCheckbox
|
import ua.acclorite.book_story.presentation.core.components.common.CircularCheckbox
|
||||||
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.DefaultTransition
|
import ua.acclorite.book_story.presentation.ui.DefaultTransition
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
|
@ -73,7 +73,7 @@ fun BrowseGridDirectoryItem(
|
||||||
.align(Alignment.TopStart)
|
.align(Alignment.TopStart)
|
||||||
.padding(12.dp)
|
.padding(12.dp)
|
||||||
) {
|
) {
|
||||||
CustomCheckbox(
|
CircularCheckbox(
|
||||||
selected = file.isSelected,
|
selected = file.isSelected,
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
size = 18.dp
|
size = 18.dp
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCheckbox
|
import ua.acclorite.book_story.presentation.core.components.common.CircularCheckbox
|
||||||
import ua.acclorite.book_story.presentation.ui.DefaultTransition
|
import ua.acclorite.book_story.presentation.ui.DefaultTransition
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
@ -76,7 +76,7 @@ fun BrowseGridFileItem(file: SelectableFile, hasSelectedFiles: Boolean) {
|
||||||
visible = hasSelectedFiles,
|
visible = hasSelectedFiles,
|
||||||
modifier = Modifier.align(Alignment.TopStart)
|
modifier = Modifier.align(Alignment.TopStart)
|
||||||
) {
|
) {
|
||||||
CustomCheckbox(
|
CircularCheckbox(
|
||||||
selected = file.isSelected,
|
selected = file.isSelected,
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
size = 18.dp,
|
size = 18.dp,
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
import ua.acclorite.book_story.presentation.core.components.header
|
import ua.acclorite.book_story.presentation.core.components.common.header
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.components.layout.BrowseItem
|
import ua.acclorite.book_story.presentation.screens.browse.components.layout.BrowseItem
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseLayout
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseLayout
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCheckbox
|
import ua.acclorite.book_story.presentation.core.components.common.CircularCheckbox
|
||||||
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.FadeTransitionPreservingSpace
|
import ua.acclorite.book_story.presentation.ui.FadeTransitionPreservingSpace
|
||||||
|
|
||||||
|
|
@ -68,7 +68,7 @@ fun BrowseListItem(
|
||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
|
||||||
CustomCheckbox(
|
CircularCheckbox(
|
||||||
selected = file.isSelected,
|
selected = file.isSelected,
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
size = 18.dp
|
size = 18.dp
|
||||||
|
|
@ -87,7 +87,7 @@ fun BrowseListItem(
|
||||||
|
|
||||||
Box(contentAlignment = Alignment.Center) {
|
Box(contentAlignment = Alignment.Center) {
|
||||||
FadeTransitionPreservingSpace(hasSelectedFiles) {
|
FadeTransitionPreservingSpace(hasSelectedFiles) {
|
||||||
CustomCheckbox(
|
CircularCheckbox(
|
||||||
selected = file.isSelected,
|
selected = file.isSelected,
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
size = 18.dp
|
size = 18.dp
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.SelectableFile
|
import ua.acclorite.book_story.domain.model.SelectableFile
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
import ua.acclorite.book_story.presentation.core.components.common.SearchTextField
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBar
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSearchTextField
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.NavigationIconButton
|
import ua.acclorite.book_story.presentation.core.navigation.NavigationIconButton
|
||||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||||
|
|
@ -76,7 +76,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedTopAppBar(
|
TopAppBar(
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = isScrolled.value || state.value.hasSelectedItems,
|
isTopBarScrolled = isScrolled.value || state.value.hasSelectedItems,
|
||||||
|
|
||||||
|
|
@ -87,7 +87,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
else -> 0
|
else -> 0
|
||||||
},
|
},
|
||||||
topBars = listOf(
|
topBars = listOf(
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 0,
|
contentID = 0,
|
||||||
contentNavigationIcon = {},
|
contentNavigationIcon = {},
|
||||||
contentTitle = {
|
contentTitle = {
|
||||||
|
|
@ -98,14 +98,14 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Search,
|
icon = Icons.Default.Search,
|
||||||
contentDescription = R.string.search_content_desc,
|
contentDescription = R.string.search_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
) {
|
) {
|
||||||
onEvent(BrowseEvent.OnSearchShowHide)
|
onEvent(BrowseEvent.OnSearchShowHide)
|
||||||
}
|
}
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.FilterList,
|
icon = Icons.Default.FilterList,
|
||||||
contentDescription = R.string.filter_content_desc,
|
contentDescription = R.string.filter_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
@ -123,10 +123,10 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 1,
|
contentID = 1,
|
||||||
contentNavigationIcon = {
|
contentNavigationIcon = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
contentDescription = R.string.go_back_content_desc,
|
contentDescription = R.string.go_back_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
@ -143,14 +143,14 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Search,
|
icon = Icons.Default.Search,
|
||||||
contentDescription = R.string.search_content_desc,
|
contentDescription = R.string.search_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
) {
|
) {
|
||||||
onEvent(BrowseEvent.OnSearchShowHide)
|
onEvent(BrowseEvent.OnSearchShowHide)
|
||||||
}
|
}
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.FilterList,
|
icon = Icons.Default.FilterList,
|
||||||
contentDescription = R.string.filter_content_desc,
|
contentDescription = R.string.filter_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
@ -168,10 +168,10 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 2,
|
contentID = 2,
|
||||||
contentNavigationIcon = {
|
contentNavigationIcon = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
contentDescription = R.string.exit_search_content_desc,
|
contentDescription = R.string.exit_search_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
|
|
@ -180,7 +180,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
contentTitle = {
|
contentTitle = {
|
||||||
CustomSearchTextField(
|
SearchTextField(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.focusRequester(focusRequester)
|
.focusRequester(focusRequester)
|
||||||
.onGloballyPositioned {
|
.onGloballyPositioned {
|
||||||
|
|
@ -192,11 +192,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
},
|
},
|
||||||
onSearch = {
|
onSearch = {
|
||||||
onEvent(BrowseEvent.OnSearch)
|
onEvent(BrowseEvent.OnSearch)
|
||||||
},
|
}
|
||||||
placeholder = stringResource(
|
|
||||||
id = R.string.search_query,
|
|
||||||
stringResource(id = R.string.files)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
|
|
@ -204,10 +200,10 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 3,
|
contentID = 3,
|
||||||
contentNavigationIcon = {
|
contentNavigationIcon = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Clear,
|
icon = Icons.Default.Clear,
|
||||||
contentDescription = R.string.clear_selected_items_content_desc,
|
contentDescription = R.string.clear_selected_items_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
|
|
@ -226,7 +222,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.SelectAll,
|
icon = Icons.Default.SelectAll,
|
||||||
contentDescription = R.string.select_all_files_content_desc,
|
contentDescription = R.string.select_all_files_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
@ -238,7 +234,7 @@ fun BrowseTopBar(filteredFiles: List<SelectableFile>) {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Check,
|
icon = Icons.Default.Check,
|
||||||
contentDescription = R.string.add_files_content_desc,
|
contentDescription = R.string.add_files_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||||
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseEvent
|
||||||
|
|
@ -84,7 +84,7 @@ fun BrowseTopBarDirectoryPath() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = !state.value.hasSelectedItems
|
visible = !state.value.hasSelectedItems
|
||||||
&& !state.value.hasSearched
|
&& !state.value.hasSearched
|
||||||
&& !state.value.isError
|
&& !state.value.isError
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,8 @@ import ua.acclorite.book_story.domain.use_case.book.InsertBook
|
||||||
import ua.acclorite.book_story.domain.use_case.favorite_directory.UpdateFavoriteDirectory
|
import ua.acclorite.book_story.domain.use_case.favorite_directory.UpdateFavoriteDirectory
|
||||||
import ua.acclorite.book_story.domain.use_case.file_system.GetBookFromFile
|
import ua.acclorite.book_story.domain.use_case.file_system.GetBookFromFile
|
||||||
import ua.acclorite.book_story.domain.use_case.file_system.GetFilesFromDevice
|
import ua.acclorite.book_story.domain.use_case.file_system.GetFilesFromDevice
|
||||||
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
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.UiViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
||||||
import ua.acclorite.book_story.presentation.data.MainState
|
import ua.acclorite.book_story.presentation.data.MainState
|
||||||
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseFilesStructure
|
import ua.acclorite.book_story.presentation.screens.settings.nested.browse.data.BrowseFilesStructure
|
||||||
|
|
@ -44,7 +44,7 @@ class BrowseViewModel @Inject constructor(
|
||||||
private val getFilesFromDevice: GetFilesFromDevice,
|
private val getFilesFromDevice: GetFilesFromDevice,
|
||||||
private val insertBook: InsertBook,
|
private val insertBook: InsertBook,
|
||||||
private val updateFavoriteDirectory: UpdateFavoriteDirectory,
|
private val updateFavoriteDirectory: UpdateFavoriteDirectory,
|
||||||
) : UiViewModel<BrowseState, BrowseEvent>() {
|
) : UIViewModel<BrowseState, BrowseEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -29,10 +29,10 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.util.Position
|
import ua.acclorite.book_story.domain.util.Position
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.common.GoBackButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
import ua.acclorite.book_story.presentation.core.components.top_bar.collapsibleTopAppBarScrollBehavior
|
||||||
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.constants.provideHelpTips
|
import ua.acclorite.book_story.presentation.core.constants.provideHelpTips
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
||||||
|
|
@ -74,12 +74,12 @@ private fun HelpScreen() {
|
||||||
val onStartEvent = StartViewModel.getEvent()
|
val onStartEvent = StartViewModel.getEvent()
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
|
|
||||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
val (scrollBehavior, lazyListState) = TopAppBarDefaults.collapsibleTopAppBarScrollBehavior()
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.nestedScroll(scrollState.first.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.windowInsetsPadding(WindowInsets.navigationBars),
|
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -94,7 +94,7 @@ private fun HelpScreen() {
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
if (!state.value.fromStart) {
|
if (!state.value.fromStart) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Outlined.RestartAlt,
|
icon = Icons.Outlined.RestartAlt,
|
||||||
contentDescription = R.string.reset_start_content_desc,
|
contentDescription = R.string.reset_start_content_desc,
|
||||||
disableOnClick = false
|
disableOnClick = false
|
||||||
|
|
@ -108,7 +108,7 @@ private fun HelpScreen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollState.first,
|
scrollBehavior = scrollBehavior,
|
||||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
|
|
@ -140,11 +140,11 @@ private fun HelpScreen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
CustomLazyColumn(
|
LazyColumnWithScrollbar(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(paddingValues),
|
.padding(paddingValues),
|
||||||
state = scrollState.second
|
state = lazyListState
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.AnnotatedString
|
import androidx.compose.ui.text.AnnotatedString
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomTooltip
|
import ua.acclorite.book_story.presentation.core.components.common.Tooltip
|
||||||
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
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ fun HelpClickableNote(text: AnnotatedString) {
|
||||||
val showNote = rememberSaveable { mutableStateOf(true) }
|
val showNote = rememberSaveable { mutableStateOf(true) }
|
||||||
|
|
||||||
Column(Modifier.padding(horizontal = 18.dp)) {
|
Column(Modifier.padding(horizontal = 18.dp)) {
|
||||||
CustomTooltip(text = stringResource(R.string.note_content_desc)) {
|
Tooltip(text = stringResource(R.string.note_content_desc)) {
|
||||||
Icon(
|
Icon(
|
||||||
imageVector = Icons.Outlined.Info,
|
imageVector = Icons.Outlined.Info,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import ua.acclorite.book_story.presentation.core.util.UiViewModel
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class HelpViewModel @Inject constructor(
|
class HelpViewModel @Inject constructor(
|
||||||
|
|
||||||
) : UiViewModel<HelpState, HelpEvent>() {
|
) : UIViewModel<HelpState, HelpEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -36,14 +36,13 @@ import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
import ua.acclorite.book_story.presentation.core.components.common.SearchTextField
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.Snackbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.placeholder.EmptyPlaceholder
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSearchTextField
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBar
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSnackbar
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty
|
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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.NavigationIconButton
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.Screen
|
import ua.acclorite.book_story.presentation.core.navigation.Screen
|
||||||
|
|
@ -53,6 +52,7 @@ import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
||||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
import ua.acclorite.book_story.presentation.screens.library.data.LibraryEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryViewModel
|
import ua.acclorite.book_story.presentation.screens.library.data.LibraryViewModel
|
||||||
|
import ua.acclorite.book_story.presentation.screens.settings.components.SettingsCategoryTitle
|
||||||
import ua.acclorite.book_story.presentation.ui.DefaultTransition
|
import ua.acclorite.book_story.presentation.ui.DefaultTransition
|
||||||
import ua.acclorite.book_story.presentation.ui.Transitions
|
import ua.acclorite.book_story.presentation.ui.Transitions
|
||||||
|
|
||||||
|
|
@ -98,7 +98,7 @@ private fun HistoryScreen() {
|
||||||
.pullRefresh(refreshState),
|
.pullRefresh(refreshState),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
AnimatedTopAppBar(
|
TopAppBar(
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = state.value.listState.canScrollBackward,
|
isTopBarScrolled = state.value.listState.canScrollBackward,
|
||||||
|
|
||||||
|
|
@ -107,21 +107,21 @@ private fun HistoryScreen() {
|
||||||
else -> 0
|
else -> 0
|
||||||
},
|
},
|
||||||
topBars = listOf(
|
topBars = listOf(
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 0,
|
contentID = 0,
|
||||||
contentNavigationIcon = {},
|
contentNavigationIcon = {},
|
||||||
contentTitle = {
|
contentTitle = {
|
||||||
Text(stringResource(id = R.string.history_screen))
|
Text(stringResource(id = R.string.history_screen))
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Search,
|
icon = Icons.Default.Search,
|
||||||
contentDescription = R.string.search_content_desc,
|
contentDescription = R.string.search_content_desc,
|
||||||
disableOnClick = true,
|
disableOnClick = true,
|
||||||
) {
|
) {
|
||||||
onEvent(HistoryEvent.OnSearchShowHide)
|
onEvent(HistoryEvent.OnSearchShowHide)
|
||||||
}
|
}
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Outlined.DeleteSweep,
|
icon = Icons.Outlined.DeleteSweep,
|
||||||
contentDescription = R.string.delete_whole_history_content_desc,
|
contentDescription = R.string.delete_whole_history_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
@ -136,10 +136,10 @@ private fun HistoryScreen() {
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 1,
|
contentID = 1,
|
||||||
contentNavigationIcon = {
|
contentNavigationIcon = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
contentDescription = R.string.exit_search_content_desc,
|
contentDescription = R.string.exit_search_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
|
|
@ -148,7 +148,7 @@ private fun HistoryScreen() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
contentTitle = {
|
contentTitle = {
|
||||||
CustomSearchTextField(
|
SearchTextField(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.focusRequester(focusRequester)
|
.focusRequester(focusRequester)
|
||||||
.onGloballyPositioned {
|
.onGloballyPositioned {
|
||||||
|
|
@ -160,11 +160,7 @@ private fun HistoryScreen() {
|
||||||
},
|
},
|
||||||
onSearch = {
|
onSearch = {
|
||||||
onEvent(HistoryEvent.OnSearch)
|
onEvent(HistoryEvent.OnSearch)
|
||||||
},
|
}
|
||||||
placeholder = stringResource(
|
|
||||||
id = R.string.search_query,
|
|
||||||
stringResource(id = R.string.history)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
|
|
@ -175,7 +171,7 @@ private fun HistoryScreen() {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
CustomSnackbar(snackbarState = snackbarState)
|
Snackbar(snackbarState = snackbarState)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
Box(
|
Box(
|
||||||
|
|
@ -199,7 +195,7 @@ private fun HistoryScreen() {
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
}
|
}
|
||||||
|
|
||||||
CategoryTitle(
|
SettingsCategoryTitle(
|
||||||
modifier = Modifier.animateItem(),
|
modifier = Modifier.animateItem(),
|
||||||
title = when (groupedHistory.title) {
|
title = when (groupedHistory.title) {
|
||||||
"today" -> stringResource(id = R.string.today)
|
"today" -> stringResource(id = R.string.today)
|
||||||
|
|
@ -263,7 +259,7 @@ private fun HistoryScreen() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = !state.value.isLoading
|
visible = !state.value.isLoading
|
||||||
&& state.value.history.isEmpty()
|
&& state.value.history.isEmpty()
|
||||||
&& !state.value.isRefreshing,
|
&& !state.value.isRefreshing,
|
||||||
|
|
@ -271,7 +267,7 @@ private fun HistoryScreen() {
|
||||||
enter = Transitions.DefaultTransitionIn,
|
enter = Transitions.DefaultTransitionIn,
|
||||||
exit = fadeOut(tween(0))
|
exit = fadeOut(tween(0))
|
||||||
) {
|
) {
|
||||||
IsEmpty(
|
EmptyPlaceholder(
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
message = stringResource(id = R.string.history_empty),
|
message = stringResource(id = R.string.history_empty),
|
||||||
icon = painterResource(id = R.drawable.empty_history)
|
icon = painterResource(id = R.drawable.empty_history)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_dialog.CustomDialogWithContent
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithContent
|
||||||
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.history.data.HistoryEvent
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
||||||
|
|
@ -22,7 +22,7 @@ fun HistoryDeleteWholeHistoryDialog() {
|
||||||
val onEvent = HistoryViewModel.getEvent()
|
val onEvent = HistoryViewModel.getEvent()
|
||||||
val onLibraryEvent = LibraryViewModel.getEvent()
|
val onLibraryEvent = LibraryViewModel.getEvent()
|
||||||
|
|
||||||
CustomDialogWithContent(
|
DialogWithContent(
|
||||||
title = stringResource(id = R.string.delete_history),
|
title = stringResource(id = R.string.delete_history),
|
||||||
imageVectorIcon = Icons.Outlined.DeleteOutline,
|
imageVectorIcon = Icons.Outlined.DeleteOutline,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -32,8 +32,8 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.History
|
import ua.acclorite.book_story.domain.model.History
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCoverImage
|
import ua.acclorite.book_story.presentation.core.components.common.AsyncImage
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
@ -88,7 +88,7 @@ fun HistoryItem(
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
if (history.book?.coverImage != null) {
|
if (history.book?.coverImage != null) {
|
||||||
CustomCoverImage(
|
AsyncImage(
|
||||||
uri = history.book.coverImage,
|
uri = history.book.coverImage,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
|
@ -141,7 +141,7 @@ fun HistoryItem(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Box(modifier = Modifier.weight(0.11f), contentAlignment = Alignment.CenterEnd) {
|
Box(modifier = Modifier.weight(0.11f), contentAlignment = Alignment.CenterEnd) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Outlined.Delete,
|
icon = Icons.Outlined.Delete,
|
||||||
contentDescription = R.string.delete_history_element_content_desc,
|
contentDescription = R.string.delete_history_element_content_desc,
|
||||||
disableOnClick = true,
|
disableOnClick = true,
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ import ua.acclorite.book_story.domain.use_case.history.DeleteHistory
|
||||||
import ua.acclorite.book_story.domain.use_case.history.DeleteWholeHistory
|
import ua.acclorite.book_story.domain.use_case.history.DeleteWholeHistory
|
||||||
import ua.acclorite.book_story.domain.use_case.history.GetHistory
|
import ua.acclorite.book_story.domain.use_case.history.GetHistory
|
||||||
import ua.acclorite.book_story.domain.use_case.history.InsertHistory
|
import ua.acclorite.book_story.domain.use_case.history.InsertHistory
|
||||||
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
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.UiViewModel
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
|
@ -36,7 +36,7 @@ class HistoryViewModel @Inject constructor(
|
||||||
private val deleteWholeHistory: DeleteWholeHistory,
|
private val deleteWholeHistory: DeleteWholeHistory,
|
||||||
private val deleteHistory: DeleteHistory,
|
private val deleteHistory: DeleteHistory,
|
||||||
private val getBooksById: GetBooksById
|
private val getBooksById: GetBooksById
|
||||||
) : UiViewModel<HistoryState, HistoryEvent>() {
|
) : UIViewModel<HistoryState, HistoryEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.Book
|
import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.model.Category
|
||||||
import ua.acclorite.book_story.domain.util.Selected
|
import ua.acclorite.book_story.domain.util.Selected
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.header
|
import ua.acclorite.book_story.presentation.core.components.common.header
|
||||||
import ua.acclorite.book_story.presentation.core.components.is_messages.IsEmpty
|
import ua.acclorite.book_story.presentation.core.components.placeholder.EmptyPlaceholder
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -208,7 +208,7 @@ private fun LibraryScreen(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = !state.value.isLoading
|
visible = !state.value.isLoading
|
||||||
&& !state.value.isRefreshing
|
&& !state.value.isRefreshing
|
||||||
&& books.isEmpty(),
|
&& books.isEmpty(),
|
||||||
|
|
@ -216,7 +216,7 @@ private fun LibraryScreen(
|
||||||
enter = Transitions.DefaultTransitionIn,
|
enter = Transitions.DefaultTransitionIn,
|
||||||
exit = fadeOut(tween(0))
|
exit = fadeOut(tween(0))
|
||||||
) {
|
) {
|
||||||
IsEmpty(
|
EmptyPlaceholder(
|
||||||
message = stringResource(id = R.string.library_empty),
|
message = stringResource(id = R.string.library_empty),
|
||||||
icon = painterResource(id = R.drawable.empty_library),
|
icon = painterResource(id = R.drawable.empty_library),
|
||||||
modifier = Modifier.align(Alignment.Center),
|
modifier = Modifier.align(Alignment.Center),
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ 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.Book
|
import ua.acclorite.book_story.domain.model.Book
|
||||||
import ua.acclorite.book_story.domain.util.Selected
|
import ua.acclorite.book_story.domain.util.Selected
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomCoverImage
|
import ua.acclorite.book_story.presentation.core.components.common.AsyncImage
|
||||||
import ua.acclorite.book_story.presentation.core.util.calculateProgress
|
import ua.acclorite.book_story.presentation.core.util.calculateProgress
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -101,7 +101,7 @@ fun LibraryBookItem(
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
if (book.first.coverImage != null) {
|
if (book.first.coverImage != null) {
|
||||||
CustomCoverImage(
|
AsyncImage(
|
||||||
uri = book.first.coverImage!!,
|
uri = book.first.coverImage!!,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
|
|
|
||||||
|
|
@ -31,17 +31,17 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBar
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.AnimatedTopAppBarData
|
import ua.acclorite.book_story.presentation.core.components.common.SearchTextField
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBar
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSearchTextField
|
import ua.acclorite.book_story.presentation.core.components.top_bar.TopAppBarData
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.NavigationIconButton
|
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
|
||||||
import ua.acclorite.book_story.presentation.screens.library.data.LibraryViewModel
|
import ua.acclorite.book_story.presentation.screens.library.data.LibraryViewModel
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Library Top Bar.
|
* Library Top Bar.
|
||||||
* Contains [AnimatedTopAppBar] and [LibraryTabRow].
|
* Contains [TopAppBar] and [LibraryTabRow].
|
||||||
*
|
*
|
||||||
* @param pagerState [PagerState].
|
* @param pagerState [PagerState].
|
||||||
*/
|
*/
|
||||||
|
|
@ -52,7 +52,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
val onEvent = LibraryViewModel.getEvent()
|
val onEvent = LibraryViewModel.getEvent()
|
||||||
val focusRequester = remember { FocusRequester() }
|
val focusRequester = remember { FocusRequester() }
|
||||||
|
|
||||||
AnimatedTopAppBar(
|
TopAppBar(
|
||||||
scrollBehavior = null,
|
scrollBehavior = null,
|
||||||
isTopBarScrolled = state.value.hasSelectedItems,
|
isTopBarScrolled = state.value.hasSelectedItems,
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
else -> 0
|
else -> 0
|
||||||
},
|
},
|
||||||
topBars = listOf(
|
topBars = listOf(
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 0,
|
contentID = 0,
|
||||||
contentNavigationIcon = {},
|
contentNavigationIcon = {},
|
||||||
contentTitle = {
|
contentTitle = {
|
||||||
|
|
@ -83,7 +83,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Search,
|
icon = Icons.Default.Search,
|
||||||
contentDescription = R.string.search_content_desc,
|
contentDescription = R.string.search_content_desc,
|
||||||
disableOnClick = true,
|
disableOnClick = true,
|
||||||
|
|
@ -94,10 +94,10 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
|
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 1,
|
contentID = 1,
|
||||||
contentNavigationIcon = {
|
contentNavigationIcon = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
contentDescription = R.string.exit_search_content_desc,
|
contentDescription = R.string.exit_search_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
|
|
@ -108,7 +108,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
contentTitle = {
|
contentTitle = {
|
||||||
CustomSearchTextField(
|
SearchTextField(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.focusRequester(focusRequester)
|
.focusRequester(focusRequester)
|
||||||
.onGloballyPositioned {
|
.onGloballyPositioned {
|
||||||
|
|
@ -120,11 +120,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
},
|
},
|
||||||
onSearch = {
|
onSearch = {
|
||||||
onEvent(LibraryEvent.OnSearch)
|
onEvent(LibraryEvent.OnSearch)
|
||||||
},
|
}
|
||||||
placeholder = stringResource(
|
|
||||||
id = R.string.search_query,
|
|
||||||
stringResource(id = R.string.books)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
|
|
@ -132,10 +128,10 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
AnimatedTopAppBarData(
|
TopAppBarData(
|
||||||
contentID = 2,
|
contentID = 2,
|
||||||
contentNavigationIcon = {
|
contentNavigationIcon = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Clear,
|
icon = Icons.Default.Clear,
|
||||||
contentDescription = R.string.clear_selected_items_content_desc,
|
contentDescription = R.string.clear_selected_items_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
|
|
@ -154,7 +150,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
contentActions = {
|
contentActions = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
icon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
||||||
contentDescription = R.string.move_books_content_desc,
|
contentDescription = R.string.move_books_content_desc,
|
||||||
enabled = !state.value.isLoading
|
enabled = !state.value.isLoading
|
||||||
|
|
@ -165,7 +161,7 @@ fun LibraryTopBar(pagerState: PagerState) {
|
||||||
) {
|
) {
|
||||||
onEvent(LibraryEvent.OnShowHideMoveDialog)
|
onEvent(LibraryEvent.OnShowHideMoveDialog)
|
||||||
}
|
}
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Outlined.Delete,
|
icon = Icons.Outlined.Delete,
|
||||||
contentDescription = R.string.delete_books_content_desc,
|
contentDescription = R.string.delete_books_content_desc,
|
||||||
enabled = !state.value.isLoading
|
enabled = !state.value.isLoading
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_dialog.CustomDialogWithContent
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithContent
|
||||||
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.browse.data.BrowseViewModel
|
import ua.acclorite.book_story.presentation.screens.browse.data.BrowseViewModel
|
||||||
|
|
@ -26,7 +26,7 @@ fun LibraryDeleteDialog() {
|
||||||
val onBrowseEvent = BrowseViewModel.getEvent()
|
val onBrowseEvent = BrowseViewModel.getEvent()
|
||||||
val onHistoryEvent = HistoryViewModel.getEvent()
|
val onHistoryEvent = HistoryViewModel.getEvent()
|
||||||
|
|
||||||
CustomDialogWithContent(
|
DialogWithContent(
|
||||||
title = stringResource(id = R.string.delete_books),
|
title = stringResource(id = R.string.delete_books),
|
||||||
imageVectorIcon = Icons.Outlined.DeleteOutline,
|
imageVectorIcon = Icons.Outlined.DeleteOutline,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.Category
|
import ua.acclorite.book_story.domain.model.Category
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_dialog.CustomDialogWithLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithLazyColumn
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_dialog.SelectableDialogItem
|
import ua.acclorite.book_story.presentation.core.components.dialog.SelectableDialogItem
|
||||||
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.history.data.HistoryEvent
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
||||||
|
|
@ -27,7 +27,7 @@ fun LibraryMoveDialog(pagerState: PagerState) {
|
||||||
val onEvent = LibraryViewModel.getEvent()
|
val onEvent = LibraryViewModel.getEvent()
|
||||||
val onHistoryEvent = HistoryViewModel.getEvent()
|
val onHistoryEvent = HistoryViewModel.getEvent()
|
||||||
|
|
||||||
CustomDialogWithLazyColumn(
|
DialogWithLazyColumn(
|
||||||
title = stringResource(id = R.string.move_books),
|
title = stringResource(id = R.string.move_books),
|
||||||
imageVectorIcon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
imageVectorIcon = Icons.AutoMirrored.Outlined.DriveFileMove,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@ import ua.acclorite.book_story.domain.use_case.book.DeleteBooks
|
||||||
import ua.acclorite.book_story.domain.use_case.book.GetBooks
|
import ua.acclorite.book_story.domain.use_case.book.GetBooks
|
||||||
import ua.acclorite.book_story.domain.use_case.book.UpdateBook
|
import ua.acclorite.book_story.domain.use_case.book.UpdateBook
|
||||||
import ua.acclorite.book_story.domain.use_case.history.InsertHistory
|
import ua.acclorite.book_story.domain.use_case.history.InsertHistory
|
||||||
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
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.UiViewModel
|
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ class LibraryViewModel @Inject constructor(
|
||||||
private val updateBook: UpdateBook,
|
private val updateBook: UpdateBook,
|
||||||
private val deleteBooks: DeleteBooks,
|
private val deleteBooks: DeleteBooks,
|
||||||
private val insertHistory: InsertHistory
|
private val insertHistory: InsertHistory
|
||||||
) : UiViewModel<LibraryState, LibraryEvent>() {
|
) : UIViewModel<LibraryState, LibraryEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,9 @@ import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.domain.model.Chapter
|
import ua.acclorite.book_story.domain.model.Chapter
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomSelectionContainer
|
import ua.acclorite.book_story.presentation.core.components.common.SelectionContainer
|
||||||
import ua.acclorite.book_story.presentation.core.components.is_messages.IsError
|
import ua.acclorite.book_story.presentation.core.components.placeholder.ErrorPlaceholder
|
||||||
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.constants.provideFonts
|
import ua.acclorite.book_story.presentation.core.constants.provideFonts
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
||||||
|
|
@ -381,7 +381,7 @@ private fun ReaderScreen(lazyListState: LazyListState) {
|
||||||
.nestedScroll(nestedScrollConnection),
|
.nestedScroll(nestedScrollConnection),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = state.value.showMenu,
|
visible = state.value.showMenu,
|
||||||
enter = slideInVertically { -it },
|
enter = slideInVertically { -it },
|
||||||
exit = slideOutVertically { -it }
|
exit = slideOutVertically { -it }
|
||||||
|
|
@ -390,7 +390,7 @@ private fun ReaderScreen(lazyListState: LazyListState) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
bottomBar = {
|
bottomBar = {
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
visible = state.value.showMenu,
|
visible = state.value.showMenu,
|
||||||
enter = slideInVertically { it },
|
enter = slideInVertically { it },
|
||||||
|
|
@ -400,7 +400,7 @@ private fun ReaderScreen(lazyListState: LazyListState) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
CustomSelectionContainer(
|
SelectionContainer(
|
||||||
onCopyRequested = {
|
onCopyRequested = {
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
||||||
context.getString(R.string.copied)
|
context.getString(R.string.copied)
|
||||||
|
|
@ -537,7 +537,7 @@ private fun ReaderScreen(lazyListState: LazyListState) {
|
||||||
horizontalAlignment = Alignment.CenterHorizontally
|
horizontalAlignment = Alignment.CenterHorizontally
|
||||||
) {
|
) {
|
||||||
if (!state.value.loading) {
|
if (!state.value.loading) {
|
||||||
IsError(
|
ErrorPlaceholder(
|
||||||
errorMessage = state.value.errorMessage!!.asString(),
|
errorMessage = state.value.errorMessage!!.asString(),
|
||||||
icon = painterResource(id = R.drawable.error),
|
icon = painterResource(id = R.drawable.error),
|
||||||
actionTitle = stringResource(id = R.string.go_back),
|
actionTitle = stringResource(id = R.string.go_back),
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_drawer.CustomModalDrawer
|
import ua.acclorite.book_story.presentation.core.components.modal_drawer.ModalDrawer
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_drawer.CustomModalDrawerSelectableItem
|
import ua.acclorite.book_story.presentation.core.components.modal_drawer.ModalDrawerSelectableItem
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_drawer.CustomModalDrawerTitleItem
|
import ua.acclorite.book_story.presentation.core.components.modal_drawer.ModalDrawerTitleItem
|
||||||
import ua.acclorite.book_story.presentation.core.util.calculateProgress
|
import ua.acclorite.book_story.presentation.core.util.calculateProgress
|
||||||
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.history.data.HistoryViewModel
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryViewModel
|
||||||
|
|
@ -33,12 +33,12 @@ fun ReaderChaptersDrawer() {
|
||||||
val onLibraryEvent = LibraryViewModel.getEvent()
|
val onLibraryEvent = LibraryViewModel.getEvent()
|
||||||
val onHistoryEvent = HistoryViewModel.getEvent()
|
val onHistoryEvent = HistoryViewModel.getEvent()
|
||||||
|
|
||||||
CustomModalDrawer(
|
ModalDrawer(
|
||||||
show = state.value.showChaptersDrawer,
|
show = state.value.showChaptersDrawer,
|
||||||
startIndex = state.value.currentChapter?.index ?: 0,
|
startIndex = state.value.currentChapter?.index ?: 0,
|
||||||
onDismissRequest = { onEvent(ReaderEvent.OnShowHideChaptersDrawer(false)) },
|
onDismissRequest = { onEvent(ReaderEvent.OnShowHideChaptersDrawer(false)) },
|
||||||
header = {
|
header = {
|
||||||
CustomModalDrawerTitleItem(
|
ModalDrawerTitleItem(
|
||||||
title = stringResource(id = R.string.chapters)
|
title = stringResource(id = R.string.chapters)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ fun ReaderChaptersDrawer() {
|
||||||
chapter.index == state.value.currentChapter?.index
|
chapter.index == state.value.currentChapter?.index
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomModalDrawerSelectableItem(
|
ModalDrawerSelectableItem(
|
||||||
selected = selected,
|
selected = selected,
|
||||||
onClick = {
|
onClick = {
|
||||||
onEvent(
|
onEvent(
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_dialog.CustomDialogWithContent
|
import ua.acclorite.book_story.presentation.core.components.dialog.DialogWithContent
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel
|
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel
|
||||||
|
|
@ -22,7 +22,7 @@ fun ReaderUpdateDialog() {
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
CustomDialogWithContent(
|
DialogWithContent(
|
||||||
title = stringResource(id = R.string.update_book),
|
title = stringResource(id = R.string.update_book),
|
||||||
imageVectorIcon = Icons.Rounded.Upgrade,
|
imageVectorIcon = Icons.Rounded.Upgrade,
|
||||||
description = stringResource(
|
description = stringResource(
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ import androidx.compose.ui.draw.clip
|
||||||
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.util.Direction
|
import ua.acclorite.book_story.domain.util.Direction
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.util.calculateProgress
|
import ua.acclorite.book_story.presentation.core.util.calculateProgress
|
||||||
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
import ua.acclorite.book_story.presentation.core.util.noRippleClickable
|
||||||
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
import ua.acclorite.book_story.presentation.screens.history.data.HistoryEvent
|
||||||
|
|
@ -112,7 +112,7 @@ fun ReaderBottomBar() {
|
||||||
visible = arrowDirection == Direction.START,
|
visible = arrowDirection == Direction.START,
|
||||||
startDirection = true
|
startDirection = true
|
||||||
) {
|
) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Default.ArrowBack,
|
icon = Icons.AutoMirrored.Default.ArrowBack,
|
||||||
contentDescription = R.string.checkpoint_back_content_desc,
|
contentDescription = R.string.checkpoint_back_content_desc,
|
||||||
modifier = Modifier.size(24.dp),
|
modifier = Modifier.size(24.dp),
|
||||||
|
|
@ -143,7 +143,7 @@ fun ReaderBottomBar() {
|
||||||
visible = arrowDirection == Direction.END,
|
visible = arrowDirection == Direction.END,
|
||||||
startDirection = false
|
startDirection = false
|
||||||
) {
|
) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Default.ArrowForward,
|
icon = Icons.AutoMirrored.Default.ArrowForward,
|
||||||
contentDescription = R.string.checkpoint_forward_content_desc,
|
contentDescription = R.string.checkpoint_forward_content_desc,
|
||||||
modifier = Modifier.size(24.dp),
|
modifier = Modifier.size(24.dp),
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomAnimatedVisibility
|
import ua.acclorite.book_story.presentation.core.components.common.AnimatedVisibility
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomIconButton
|
import ua.acclorite.book_story.presentation.core.components.common.IconButton
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -91,7 +91,7 @@ fun ReaderTopBar() {
|
||||||
) {
|
) {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
icon = Icons.AutoMirrored.Outlined.ArrowBack,
|
||||||
contentDescription = R.string.go_back_content_desc,
|
contentDescription = R.string.go_back_content_desc,
|
||||||
disableOnClick = true
|
disableOnClick = true
|
||||||
|
|
@ -167,7 +167,7 @@ fun ReaderTopBar() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
CustomAnimatedVisibility(
|
AnimatedVisibility(
|
||||||
visible = state.value.checkingForUpdate || state.value.updateFound,
|
visible = state.value.checkingForUpdate || state.value.updateFound,
|
||||||
enter = fadeIn(),
|
enter = fadeIn(),
|
||||||
exit = shrinkHorizontally() + fadeOut()
|
exit = shrinkHorizontally() + fadeOut()
|
||||||
|
|
@ -177,7 +177,7 @@ fun ReaderTopBar() {
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
if (state.value.updateFound) {
|
if (state.value.updateFound) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Rounded.Upgrade,
|
icon = Icons.Rounded.Upgrade,
|
||||||
contentDescription = R.string.update_text_content_desc,
|
contentDescription = R.string.update_text_content_desc,
|
||||||
color = MaterialTheme.colorScheme.primary,
|
color = MaterialTheme.colorScheme.primary,
|
||||||
|
|
@ -202,7 +202,7 @@ fun ReaderTopBar() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.value.currentChapter != null) {
|
if (state.value.currentChapter != null) {
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Rounded.Menu,
|
icon = Icons.Rounded.Menu,
|
||||||
contentDescription = R.string.chapters_content_desc,
|
contentDescription = R.string.chapters_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
@ -214,7 +214,7 @@ fun ReaderTopBar() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomIconButton(
|
IconButton(
|
||||||
icon = Icons.Default.Settings,
|
icon = Icons.Default.Settings,
|
||||||
contentDescription = R.string.open_reader_settings_content_desc,
|
contentDescription = R.string.open_reader_settings_content_desc,
|
||||||
disableOnClick = false,
|
disableOnClick = false,
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,8 @@ import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.custom_bottom_sheet.CustomBottomSheet
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheet
|
||||||
import ua.acclorite.book_story.presentation.data.MainViewModel
|
import ua.acclorite.book_story.presentation.data.MainViewModel
|
||||||
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent
|
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel
|
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel
|
||||||
|
|
@ -73,7 +73,7 @@ fun ReaderSettingsBottomSheet() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
CustomBottomSheet(
|
ModalBottomSheet(
|
||||||
hasFixedHeight = true,
|
hasFixedHeight = true,
|
||||||
scrimColor = animatedScrimColor,
|
scrimColor = animatedScrimColor,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
@ -89,7 +89,7 @@ fun ReaderSettingsBottomSheet() {
|
||||||
HorizontalPager(state = pagerState) { page ->
|
HorizontalPager(state = pagerState) { page ->
|
||||||
when (page) {
|
when (page) {
|
||||||
0 -> {
|
0 -> {
|
||||||
CustomLazyColumn(Modifier.fillMaxSize()) {
|
LazyColumnWithScrollbar(Modifier.fillMaxSize()) {
|
||||||
PaddingSubcategory(
|
PaddingSubcategory(
|
||||||
titleColor = { MaterialTheme.colorScheme.onSurface },
|
titleColor = { MaterialTheme.colorScheme.onSurface },
|
||||||
topPadding = 22.dp,
|
topPadding = 22.dp,
|
||||||
|
|
@ -115,7 +115,7 @@ fun ReaderSettingsBottomSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
1 -> {
|
1 -> {
|
||||||
CustomLazyColumn(Modifier.fillMaxSize()) {
|
LazyColumnWithScrollbar(Modifier.fillMaxSize()) {
|
||||||
FontSubcategory(
|
FontSubcategory(
|
||||||
titleColor = { MaterialTheme.colorScheme.onSurface },
|
titleColor = { MaterialTheme.colorScheme.onSurface },
|
||||||
topPadding = 16.dp,
|
topPadding = 16.dp,
|
||||||
|
|
@ -136,7 +136,7 @@ fun ReaderSettingsBottomSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
2 -> {
|
2 -> {
|
||||||
CustomLazyColumn(Modifier.fillMaxSize()) {
|
LazyColumnWithScrollbar(Modifier.fillMaxSize()) {
|
||||||
ColorsSubcategory(
|
ColorsSubcategory(
|
||||||
showTitle = false,
|
showTitle = false,
|
||||||
showDivider = false,
|
showDivider = false,
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import androidx.compose.foundation.pager.PagerState
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.res.stringResource
|
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.custom_bottom_sheet.CustomBottomSheetTabRow
|
import ua.acclorite.book_story.presentation.core.components.modal_bottom_sheet.ModalBottomSheetTabRow
|
||||||
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent
|
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderEvent
|
||||||
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel
|
import ua.acclorite.book_story.presentation.screens.reader.data.ReaderViewModel
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ fun ReaderSettingsBottomSheetTabRow(pagerState: PagerState) {
|
||||||
stringResource(id = R.string.color_tab)
|
stringResource(id = R.string.color_tab)
|
||||||
)
|
)
|
||||||
|
|
||||||
CustomBottomSheetTabRow(
|
ModalBottomSheetTabRow(
|
||||||
selectedTabIndex = pagerState.currentPage,
|
selectedTabIndex = pagerState.currentPage,
|
||||||
tabs = tabItems
|
tabs = tabItems
|
||||||
) { index ->
|
) { index ->
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ import ua.acclorite.book_story.domain.use_case.book.UpdateBook
|
||||||
import ua.acclorite.book_story.domain.use_case.history.GetLatestHistory
|
import ua.acclorite.book_story.domain.use_case.history.GetLatestHistory
|
||||||
import ua.acclorite.book_story.domain.util.Resource
|
import ua.acclorite.book_story.domain.util.Resource
|
||||||
import ua.acclorite.book_story.domain.util.UIText
|
import ua.acclorite.book_story.domain.util.UIText
|
||||||
|
import ua.acclorite.book_story.domain.util.UIViewModel
|
||||||
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.UiViewModel
|
|
||||||
import ua.acclorite.book_story.presentation.core.util.coerceAndPreventNaN
|
import ua.acclorite.book_story.presentation.core.util.coerceAndPreventNaN
|
||||||
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
import ua.acclorite.book_story.presentation.core.util.launchActivity
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
@ -49,7 +49,7 @@ class ReaderViewModel @Inject constructor(
|
||||||
private val getLatestHistory: GetLatestHistory,
|
private val getLatestHistory: GetLatestHistory,
|
||||||
private val getBookById: GetBookById,
|
private val getBookById: GetBookById,
|
||||||
private val checkForTextUpdate: CheckForTextUpdate
|
private val checkForTextUpdate: CheckForTextUpdate
|
||||||
) : UiViewModel<ReaderState, ReaderEvent>() {
|
) : UIViewModel<ReaderState, ReaderEvent>() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.R
|
import ua.acclorite.book_story.R
|
||||||
import ua.acclorite.book_story.presentation.core.components.CustomLazyColumn
|
import ua.acclorite.book_story.presentation.core.components.common.GoBackButton
|
||||||
import ua.acclorite.book_story.presentation.core.components.GoBackButton
|
import ua.acclorite.book_story.presentation.core.components.common.LazyColumnWithScrollbar
|
||||||
import ua.acclorite.book_story.presentation.core.components.collapsibleUntilExitScrollBehaviorWithLazyListState
|
import ua.acclorite.book_story.presentation.core.components.top_bar.collapsibleTopAppBarScrollBehavior
|
||||||
import ua.acclorite.book_story.presentation.core.navigation.LocalNavigator
|
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
|
||||||
|
|
@ -40,12 +40,12 @@ fun SettingsScreenRoot() {
|
||||||
@Composable
|
@Composable
|
||||||
private fun SettingsScreen() {
|
private fun SettingsScreen() {
|
||||||
val onNavigate = LocalNavigator.current
|
val onNavigate = LocalNavigator.current
|
||||||
val scrollState = TopAppBarDefaults.collapsibleUntilExitScrollBehaviorWithLazyListState()
|
val (scrollBehavior, lazyListState) = TopAppBarDefaults.collapsibleTopAppBarScrollBehavior()
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.nestedScroll(scrollState.first.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.windowInsetsPadding(WindowInsets.navigationBars),
|
.windowInsetsPadding(WindowInsets.navigationBars),
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
topBar = {
|
topBar = {
|
||||||
|
|
@ -56,7 +56,7 @@ private fun SettingsScreen() {
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
GoBackButton(onNavigate = onNavigate)
|
GoBackButton(onNavigate = onNavigate)
|
||||||
},
|
},
|
||||||
scrollBehavior = scrollState.first,
|
scrollBehavior = scrollBehavior,
|
||||||
colors = TopAppBarDefaults.largeTopAppBarColors(
|
colors = TopAppBarDefaults.largeTopAppBarColors(
|
||||||
containerColor = MaterialTheme.colorScheme.surface,
|
containerColor = MaterialTheme.colorScheme.surface,
|
||||||
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
scrolledContainerColor = MaterialTheme.colorScheme.surfaceContainer
|
||||||
|
|
@ -64,11 +64,11 @@ private fun SettingsScreen() {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
CustomLazyColumn(
|
LazyColumnWithScrollbar(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxSize()
|
.fillMaxSize()
|
||||||
.padding(top = paddingValues.calculateTopPadding()),
|
.padding(top = paddingValues.calculateTopPadding()),
|
||||||
state = scrollState.second
|
state = lazyListState
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package ua.acclorite.book_story.presentation.core.components
|
package ua.acclorite.book_story.presentation.screens.settings.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
|
@ -15,10 +15,10 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Category Title. Used to name a category.
|
* Settings Category Title. Used to name a category.
|
||||||
*/
|
*/
|
||||||
@Composable
|
@Composable
|
||||||
fun CategoryTitle(
|
fun SettingsCategoryTitle(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
title: String,
|
title: String,
|
||||||
color: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
color: Color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||||
|
|
@ -13,7 +13,6 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.coerceAtLeast
|
import androidx.compose.ui.unit.coerceAtLeast
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ua.acclorite.book_story.presentation.core.components.CategoryTitle
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Settings Subcategory.
|
* Settings Subcategory.
|
||||||
|
|
@ -38,7 +37,7 @@ fun LazyListScope.SettingsSubcategory(
|
||||||
) {
|
) {
|
||||||
item {
|
item {
|
||||||
if (showTitle) {
|
if (showTitle) {
|
||||||
CategoryTitle(
|
SettingsCategoryTitle(
|
||||||
title = title.invoke(),
|
title = title.invoke(),
|
||||||
color = titleColor.invoke(),
|
color = titleColor.invoke(),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue