🚀 Add scrollbar

Added scrollbar to non-primary screens. Not doable for all screens due to problems.

Partly Resolves: #45
This commit is contained in:
Acclorite 2024-08-24 11:53:33 +03:00
parent 2a8bddcfcb
commit a03d144885
16 changed files with 127 additions and 25 deletions

View file

@ -36,7 +36,7 @@ android {
getByName("debug") {
applicationIdSuffix = ".debug"
}
getByName("release") {
isMinifyEnabled = true
isShrinkResources = false
@ -163,4 +163,7 @@ dependencies {
// Drag & Drop
implementation("sh.calvin.reorderable:reorderable:2.3.0")
// Scrollbar
implementation("com.github.nanihadesuka:LazyColumnScrollbar:2.2.0")
}

View file

@ -1,12 +1,20 @@
@file:Suppress("unused")
package ua.acclorite.book_story.domain.util
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.unit.dp
import my.nanihadesuka.compose.ScrollbarSelectionMode
import my.nanihadesuka.compose.ScrollbarSettings
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.model.Badge
import ua.acclorite.book_story.domain.model.Book
@ -55,6 +63,10 @@ object Constants {
// Default Color Preset (Used when creating new color presets)
val DEFAULT_COLOR_PRESET = provideDefaultColorPreset()
// Scrollbars (Primary unused, awaiting for fixes)
val PRIMARY_SCROLLBAR @Composable get() = providePrimaryScrollbar()
val SECONDARY_SCROLLBAR @Composable get() = provideSecondaryScrollbar()
}
private fun provideSupportedExtensions() = listOf(
@ -544,4 +556,27 @@ private fun provideDefaultColorPreset() = ColorPreset(
backgroundColor = Color(0xFFFAF8FF), // Blue Light Surface (hardcoded)
fontColor = Color(0xFF44464F), // Blue Light OnSurfaceVariant (hardcoded)
isSelected = false
)
@Composable
private fun providePrimaryScrollbar() = ScrollbarSettings(
thumbUnselectedColor = MaterialTheme.colorScheme.primary,
hideDelayMillis = 2000,
durationAnimationMillis = 300,
selectionMode = ScrollbarSelectionMode.Disabled,
thumbThickness = 8.dp,
scrollbarPadding = 4.dp
)
@Composable
private fun provideSecondaryScrollbar() = ScrollbarSettings(
thumbUnselectedColor = MaterialTheme.colorScheme.onSurfaceVariant.copy(0.5f),
hideDelayMillis = 500,
durationAnimationMillis = 200,
thumbMinLength = 0.4f,
selectionMode = ScrollbarSelectionMode.Disabled,
thumbThickness = 4.dp,
thumbShape = RectangleShape,
hideDisplacement = 0.dp,
scrollbarPadding = 0.dp
)

View file

@ -0,0 +1,62 @@
package ua.acclorite.book_story.presentation.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import my.nanihadesuka.compose.InternalLazyColumnScrollbar
import my.nanihadesuka.compose.ScrollbarSettings
import ua.acclorite.book_story.domain.util.Constants
/**
* Custom Lazy Column.
* Has scrollbar.
*
* @param modifier Modifier.
* @param state [LazyListState].
* @param scrollbarSettings [ScrollbarSettings]. [Constants.SECONDARY_SCROLLBAR] by default.
* @param enableScrollbar Whether scrollbar is enabled.
* @param contentPadding [PaddingValues].
* @param verticalArrangement Vertical item arrangement.
* @param content Content of the column.
*/
@Composable
fun CustomLazyColumn(
modifier: Modifier = Modifier,
state: LazyListState = rememberLazyListState(),
scrollbarSettings: ScrollbarSettings = Constants.SECONDARY_SCROLLBAR,
enableScrollbar: Boolean = true,
contentPadding: PaddingValues = PaddingValues(0.dp),
verticalArrangement: Arrangement.Vertical = Arrangement.Top,
content: LazyListScope.() -> Unit
) {
val enabled = remember {
derivedStateOf {
enableScrollbar && (state.canScrollBackward || state.canScrollForward)
}
}
Box(modifier = modifier) {
LazyColumn(
state = state,
verticalArrangement = verticalArrangement,
contentPadding = contentPadding
) {
content()
}
if (enabled.value) {
InternalLazyColumnScrollbar(
state = state,
settings = scrollbarSettings
)
}
}
}

View file

@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@ -34,6 +33,7 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.data.LocalNavigator
@ -98,7 +98,7 @@ private fun AboutScreen(
)
}
) { paddingValues ->
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
@ -22,6 +21,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.Constants
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.components.customItems
@ -72,7 +72,7 @@ private fun CreditsScreen(
)
}
) { paddingValues ->
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -13,7 +13,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Language
@ -39,6 +38,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomIconButton
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.components.customItems
@ -148,7 +148,7 @@ private fun LicenseInfoScreen(
DefaultTransition(
visible = state.value.license != null
) {
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
@ -30,6 +29,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.components.customItems
@ -94,7 +94,7 @@ private fun LicensesScreen(
enter = fadeIn(tween(300)),
exit = fadeOut(tween(300))
) {
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.RestartAlt
@ -36,6 +35,7 @@ import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.Constants
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomIconButton
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.components.customItems
@ -155,7 +155,7 @@ private fun HelpScreen(
}
}
) { paddingValues ->
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(paddingValues)

View file

@ -22,6 +22,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@ -68,7 +69,7 @@ fun LibraryBookItem(
else onSurfaceColor
}
val progress = remember(book.first) {
val progress = rememberSaveable(book.first) {
"${
(book.first.progress * 100)
.toDouble()

View file

@ -7,7 +7,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.MenuBook
import androidx.compose.material.icons.filled.DisplaySettings
@ -26,6 +25,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.data.LocalNavigator
@ -68,7 +68,7 @@ private fun SettingsScreen(
)
}
) { paddingValues ->
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
@ -22,6 +21,7 @@ import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.data.LocalNavigator
@ -85,8 +85,8 @@ private fun AppearanceSettings(
)
}
) { paddingValues ->
LazyColumn(
Modifier
CustomLazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),
state = scrollState.second

View file

@ -6,7 +6,6 @@ import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
@ -22,6 +21,7 @@ import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.data.LocalNavigator
@ -76,7 +76,7 @@ private fun BrowseSettings(
)
}
) { paddingValues ->
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
@ -21,6 +20,7 @@ import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.data.LocalNavigator
@ -80,7 +80,7 @@ private fun GeneralSettings(
)
}
) { paddingValues ->
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.LargeTopAppBar
import androidx.compose.material3.MaterialTheme
@ -21,6 +20,7 @@ import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel
import ua.acclorite.book_story.R
import ua.acclorite.book_story.domain.util.OnNavigate
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.components.GoBackButton
import ua.acclorite.book_story.presentation.components.collapsibleUntilExitScrollBehaviorWithLazyListState
import ua.acclorite.book_story.presentation.data.LocalNavigator
@ -74,7 +74,7 @@ private fun ReaderSettings(
)
}
) { paddingValues ->
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.padding(top = paddingValues.calculateTopPadding()),

View file

@ -2,7 +2,6 @@ package ua.acclorite.book_story.presentation.screens.start.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme
@ -10,6 +9,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.State
import androidx.compose.ui.Modifier
import ua.acclorite.book_story.presentation.components.CustomAnimatedVisibility
import ua.acclorite.book_story.presentation.components.CustomLazyColumn
import ua.acclorite.book_story.presentation.screens.start.data.StartNavigationScreen
import ua.acclorite.book_story.presentation.screens.start.data.StartState
import ua.acclorite.book_story.presentation.ui.Transitions
@ -32,7 +32,7 @@ fun StartNavigationScreenItem(
exit = if (state.value.useBackAnimation) Transitions.BackSlidingTransitionOut
else Transitions.SlidingTransitionOut
) {
LazyColumn(
CustomLazyColumn(
Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.surfaceContainerLow),