package eu.kanade.presentation.components import androidx.compose.foundation.gestures.FlingBehavior import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.calculateEndPadding 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.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.unit.dp import eu.kanade.presentation.util.drawVerticalScrollbar import eu.kanade.presentation.util.flingBehaviorIgnoringMotionScale /** * LazyColumn with fling animation fix * * @see flingBehaviorIgnoringMotionScale */ @Composable fun LazyColumn( modifier: Modifier = Modifier, state: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), reverseLayout: Boolean = false, verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, horizontalAlignment: Alignment.Horizontal = Alignment.Start, flingBehavior: FlingBehavior = flingBehaviorIgnoringMotionScale(), userScrollEnabled: Boolean = true, content: LazyListScope.() -> Unit, ) { androidx.compose.foundation.lazy.LazyColumn( modifier = modifier, state = state, contentPadding = contentPadding, reverseLayout = reverseLayout, verticalArrangement = verticalArrangement, horizontalAlignment = horizontalAlignment, flingBehavior = flingBehavior, userScrollEnabled = userScrollEnabled, content = content, ) } /** * LazyColumn with scrollbar. */ @Composable fun ScrollbarLazyColumn( modifier: Modifier = Modifier, state: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), reverseLayout: Boolean = false, verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, horizontalAlignment: Alignment.Horizontal = Alignment.Start, flingBehavior: FlingBehavior = flingBehaviorIgnoringMotionScale(), userScrollEnabled: Boolean = true, content: LazyListScope.() -> Unit, ) { val direction = LocalLayoutDirection.current val density = LocalDensity.current val positionOffset = remember(contentPadding) { with(density) { contentPadding.calculateEndPadding(direction).toPx() } } LazyColumn( modifier = modifier .drawVerticalScrollbar( state = state, reverseScrolling = reverseLayout, positionOffsetPx = positionOffset, ), state = state, contentPadding = contentPadding, reverseLayout = reverseLayout, verticalArrangement = verticalArrangement, horizontalAlignment = horizontalAlignment, flingBehavior = flingBehavior, userScrollEnabled = userScrollEnabled, content = content, ) } /** * LazyColumn with fast scroller. */ @Composable fun FastScrollLazyColumn( modifier: Modifier = Modifier, state: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), reverseLayout: Boolean = false, verticalArrangement: Arrangement.Vertical = if (!reverseLayout) Arrangement.Top else Arrangement.Bottom, horizontalAlignment: Alignment.Horizontal = Alignment.Start, flingBehavior: FlingBehavior = flingBehaviorIgnoringMotionScale(), userScrollEnabled: Boolean = true, content: LazyListScope.() -> Unit, ) { VerticalFastScroller( listState = state, modifier = modifier, topContentPadding = contentPadding.calculateTopPadding(), endContentPadding = contentPadding.calculateEndPadding(LocalLayoutDirection.current), ) { LazyColumn( state = state, contentPadding = contentPadding, reverseLayout = reverseLayout, verticalArrangement = verticalArrangement, horizontalAlignment = horizontalAlignment, flingBehavior = flingBehavior, userScrollEnabled = userScrollEnabled, content = content, ) } }