Skip to content

Commit

Permalink
Make draggableScrollbar thinner.
Browse files Browse the repository at this point in the history
  • Loading branch information
oxyroid committed Jul 7, 2024
1 parent 530a584 commit a2d9cf1
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells
import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridItemSpan
import androidx.compose.foundation.lazy.staggeredgrid.items
import androidx.compose.foundation.lazy.staggeredgrid.rememberLazyStaggeredGridState
import androidx.compose.foundation.shape.AbsoluteRoundedCornerShape
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.ListItem
Expand All @@ -26,10 +28,12 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import com.m3u.core.util.basic.title
import com.m3u.core.wrapper.Resource
import com.m3u.data.database.model.Channel
import com.m3u.i18n.R.string
import com.m3u.material.components.VerticalDraggableScrollbar
import com.m3u.material.ktx.leanback
import com.m3u.material.ktx.plus
import com.m3u.material.model.LocalSpacing
Expand Down Expand Up @@ -64,34 +68,47 @@ internal fun FavouriteGallery(
}

is Resource.Success -> {
@Suppress("NAME_SHADOWING")
val channels = channels.data
LazyVerticalStaggeredGrid(
columns = StaggeredGridCells.Fixed(rowCount),
verticalItemSpacing = spacing.medium,
horizontalArrangement = Arrangement.spacedBy(spacing.large),
contentPadding = PaddingValues(spacing.medium) + contentPadding,
modifier = modifier.fillMaxSize(),
Row(
modifier = modifier
.fillMaxSize()
.padding(start = spacing.medium),
horizontalArrangement = Arrangement.spacedBy(4.dp)
) {
item(span = StaggeredGridItemSpan.FullLine) {
RandomTips(
onClick = onClickRandomTips
)
}
items(
items = channels,
key = { it.id },
contentType = { it.cover.isNullOrEmpty() }
) { channel ->
FavoriteItem(
channel = channel,
zapping = zapping == channel,
onClick = { onClick(channel) },
onLongClick = { onLongClick(channel) },
recently = recently,
modifier = Modifier.fillMaxWidth()
)
@Suppress("NAME_SHADOWING")
val channels = channels.data
val lazyStaggeredGridState = rememberLazyStaggeredGridState()

LazyVerticalStaggeredGrid(
state = lazyStaggeredGridState,
columns = StaggeredGridCells.Fixed(rowCount),
verticalItemSpacing = spacing.medium,
horizontalArrangement = Arrangement.spacedBy(spacing.large),
contentPadding = PaddingValues(vertical = spacing.medium) + contentPadding,
modifier = Modifier
.fillMaxHeight()
.weight(1f),
) {
// item(span = StaggeredGridItemSpan.FullLine) {
// RandomTips(
// onClick = onClickRandomTips
// )
// }
items(
items = channels,
key = { it.id },
contentType = { it.cover.isNullOrEmpty() }
) { channel ->
FavoriteItem(
channel = channel,
zapping = zapping == channel,
onClick = { onClick(channel) },
onLongClick = { onLongClick(channel) },
recently = recently,
modifier = Modifier.fillMaxWidth()
)
}
}
VerticalDraggableScrollbar(lazyStaggeredGridState = lazyStaggeredGridState)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,7 @@ internal fun SmartphoneChannelGallery(
}
}
VerticalDraggableScrollbar(
lazyStaggeredGridState = state,
modifier = Modifier.padding(5.dp)
lazyStaggeredGridState = state
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.compose.foundation.gestures.rememberDraggableState
import androidx.compose.foundation.gestures.scrollBy
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyListState
Expand All @@ -30,21 +31,28 @@ import androidx.compose.ui.geometry.CornerRadius
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.m3u.material.model.LocalSpacing
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import kotlin.time.Duration.Companion.milliseconds

data class DraggableScrollbarWidth(
val inactive: Dp,
val active: Dp
)

@Composable
fun VerticalDraggableScrollbar(
lazyListState: LazyListState,
modifier: Modifier = Modifier,
color: Color = Color.White
color: Color = Color.White,
width: DraggableScrollbarWidth = DraggableScrollbarWidth(8.dp, 12.dp),
coefficient: Float = 0.85f
) {
val visibleCountPercent by remember {
derivedStateOf {
Expand All @@ -54,9 +62,15 @@ fun VerticalDraggableScrollbar(
else visibleItemsCount.toFloat() / totalItemsCount
}
}
val isVisible by remember {
derivedStateOf {
visibleCountPercent > 0f && visibleCountPercent <= coefficient
}
}
val coroutineScope = rememberCoroutineScope()
val draggableState = rememberDraggableState { delta ->
coroutineScope.launch {
if (!isVisible) return@launch
lazyListState.scrollBy(delta / visibleCountPercent)
}
}
Expand Down Expand Up @@ -85,9 +99,7 @@ fun VerticalDraggableScrollbar(
isScrolling = false
}
}
val onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit =
{ isDragging = true }
val onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = { isDragging = false }

val percent by remember(lazyListState) {
derivedStateOf {
val totalItemsCount = lazyListState.layoutInfo.totalItemsCount
Expand Down Expand Up @@ -115,34 +127,42 @@ fun VerticalDraggableScrollbar(
animationSpec = tween(200, delayMillis = 200)
)
val currentWidth by animateDpAsState(
targetValue = if (isDragging) 16.dp else 12.dp,
targetValue = if (isDragging) width.active else width.inactive,
label = "current-width"
)
Canvas(
modifier = modifier
.fillMaxHeight()
.requiredWidth(currentWidth)
.draggable(
state = draggableState,
orientation = Orientation.Vertical,
onDragStarted = onDragStarted,
onDragStopped = onDragStopped

if (isVisible) {
Canvas(
modifier = modifier
.fillMaxHeight()
.padding(5.dp)
.requiredWidth(currentWidth)
.draggable(
state = draggableState,
orientation = Orientation.Vertical,
onDragStarted = { isDragging = true },
onDragStopped = { isDragging = false }
)
) {
drawVerticalDraggableScrollbar(
color = color,
currentAlpha = currentAlpha,
currentPosition = currentPosition,
currentVisibleCountPercent = currentVisibleCountPercent
)
) {
drawVerticalDraggableScrollbar(
color = color,
currentAlpha = currentAlpha,
currentPosition = currentPosition,
currentVisibleCountPercent = currentVisibleCountPercent
)
}
} else {
Spacer(modifier = Modifier.width(LocalSpacing.current.medium))
}
}

@Composable
fun VerticalDraggableScrollbar(
lazyGridState: LazyGridState,
modifier: Modifier = Modifier,
color: Color = Color.White
color: Color = Color.White,
width: DraggableScrollbarWidth = DraggableScrollbarWidth(8.dp, 12.dp),
coefficient: Float = 0.85f
) {
val visibleCountPercent by remember {
derivedStateOf {
Expand All @@ -152,9 +172,15 @@ fun VerticalDraggableScrollbar(
else visibleItemsCount.toFloat() / totalItemsCount
}
}
val isVisible by remember {
derivedStateOf {
visibleCountPercent > 0f && visibleCountPercent <= coefficient
}
}
val coroutineScope = rememberCoroutineScope()
val draggableState = rememberDraggableState { delta ->
coroutineScope.launch {
if (!isVisible) return@launch
lazyGridState.scrollBy(delta / visibleCountPercent)
}
}
Expand Down Expand Up @@ -183,9 +209,6 @@ fun VerticalDraggableScrollbar(
isScrolling = false
}
}
val onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit =
{ isDragging = true }
val onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = { isDragging = false }
val percent by remember(lazyGridState) {
derivedStateOf {
val totalItemsCount = lazyGridState.layoutInfo.totalItemsCount
Expand Down Expand Up @@ -213,26 +236,32 @@ fun VerticalDraggableScrollbar(
animationSpec = tween(200, delayMillis = 200)
)
val currentWidth by animateDpAsState(
targetValue = if (isDragging) 16.dp else 12.dp,
targetValue = if (isDragging) width.active else width.inactive,
label = "current-width"
)
Canvas(
modifier = modifier
.fillMaxHeight()
.requiredWidth(currentWidth)
.draggable(
state = draggableState,
orientation = Orientation.Vertical,
onDragStarted = onDragStarted,
onDragStopped = onDragStopped

if (isVisible) {
Canvas(
modifier = modifier
.fillMaxHeight()
.padding(5.dp)
.requiredWidth(currentWidth)
.draggable(
state = draggableState,
orientation = Orientation.Vertical,
onDragStarted = { isDragging = true },
onDragStopped = { isDragging = false }
)
) {
drawVerticalDraggableScrollbar(
color = color,
currentAlpha = currentAlpha,
currentPosition = currentPosition,
currentVisibleCountPercent = currentVisibleCountPercent
)
) {
drawVerticalDraggableScrollbar(
color = color,
currentAlpha = currentAlpha,
currentPosition = currentPosition,
currentVisibleCountPercent = currentVisibleCountPercent
)
}
} else {
Spacer(modifier = Modifier.width(LocalSpacing.current.medium))
}
}

Expand All @@ -241,7 +270,8 @@ fun VerticalDraggableScrollbar(
lazyStaggeredGridState: LazyStaggeredGridState,
modifier: Modifier = Modifier,
color: Color = Color.White,
alwaysShow: Boolean = false
width: DraggableScrollbarWidth = DraggableScrollbarWidth(8.dp, 12.dp),
coefficient: Float = 0.85f
) {
val visibleCountPercent by remember {
derivedStateOf {
Expand All @@ -251,15 +281,15 @@ fun VerticalDraggableScrollbar(
else visibleItemsCount.toFloat() / totalItemsCount
}
}
val shouldShow by remember(alwaysShow) {
val isVisible by remember {
derivedStateOf {
alwaysShow || (visibleCountPercent > 0f && visibleCountPercent <= 0.85f)
visibleCountPercent > 0f && visibleCountPercent <= coefficient
}
}
val coroutineScope = rememberCoroutineScope()
val draggableState = rememberDraggableState { delta ->
coroutineScope.launch {
if (!shouldShow) return@launch
if (!isVisible) return@launch
lazyStaggeredGridState.scrollBy(delta / visibleCountPercent)
}
}
Expand Down Expand Up @@ -288,9 +318,6 @@ fun VerticalDraggableScrollbar(
isScrolling = false
}
}
val onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit =
{ isDragging = true }
val onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = { isDragging = false }
val percent by remember(lazyStaggeredGridState) {
derivedStateOf {
val totalItemsCount = lazyStaggeredGridState.layoutInfo.totalItemsCount
Expand Down Expand Up @@ -318,19 +345,20 @@ fun VerticalDraggableScrollbar(
animationSpec = tween(200, delayMillis = 200)
)
val currentWidth by animateDpAsState(
targetValue = if (isDragging) 16.dp else 12.dp,
targetValue = if (isDragging) width.active else width.inactive,
label = "current-width"
)
if (shouldShow) {
if (isVisible) {
Canvas(
modifier = modifier
.fillMaxHeight()
.padding(5.dp)
.requiredWidth(currentWidth)
.draggable(
state = draggableState,
orientation = Orientation.Vertical,
onDragStarted = onDragStarted,
onDragStopped = onDragStopped
onDragStarted = { isDragging = true },
onDragStopped = { isDragging = false }
)
) {
drawVerticalDraggableScrollbar(
Expand All @@ -343,7 +371,6 @@ fun VerticalDraggableScrollbar(
} else {
Spacer(modifier = Modifier.width(LocalSpacing.current.medium))
}

}

private fun DrawScope.drawVerticalDraggableScrollbar(
Expand Down

0 comments on commit a2d9cf1

Please sign in to comment.