From 457e6712d4beb891ec43b573e26762c19897df62 Mon Sep 17 00:00:00 2001 From: vfsfitvnm Date: Mon, 25 Jul 2022 12:32:19 +0200 Subject: [PATCH] Implement #51 --- .../it/vfsfitvnm/vimusic/MainActivity.kt | 6 +- .../vimusic/service/PlayerService.kt | 6 +- .../vimusic/ui/components/BottomSheet.kt | 65 ++++++++++++++----- .../vfsfitvnm/vimusic/ui/views/PlayerView.kt | 1 + 4 files changed, 58 insertions(+), 20 deletions(-) diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt index 1e46af9..21bfdd3 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/MainActivity.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalHapticFeedback +import androidx.compose.ui.unit.dp import androidx.media3.common.MediaItem import androidx.media3.common.Player import com.google.accompanist.systemuicontroller.rememberSystemUiController @@ -215,7 +216,8 @@ class MainActivity : ComponentActivity() { when (val uri = uri) { null -> { val playerBottomSheetState = rememberBottomSheetState( - lowerBound = Dimensions.collapsedPlayer, + lowerBound = 0.dp, + collapsedBound = Dimensions.collapsedPlayer, upperBound = maxHeight, isExpanded = expandPlayerBottomSheet ) @@ -263,7 +265,7 @@ fun ExpandPlayerOnPlaylistChange(player: Player, expand: () -> Unit) { DisposableEffect(player, expand) { player.listener(object : Player.Listener { override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) { - if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED) { + if (reason == Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED && mediaItem != null) { expand() } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt index 0fc4596..5b884fd 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/service/PlayerService.kt @@ -213,7 +213,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene } override fun onTaskRemoved(rootIntent: Intent?) { - if (!player.playWhenReady) { + if (!player.shouldBePlaying) { if (isPersistentQueueEnabled) { broadCastPendingIntent().send() } else { @@ -398,7 +398,9 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene val notification = notification() if (notification == null) { - stopSelf() + isNotificationStarted = false + makeInvincible(false) + stopForeground(true) return } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt index f92dc5d..7bccdf1 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/components/BottomSheet.kt @@ -52,6 +52,7 @@ fun BottomSheet( modifier: Modifier = Modifier, peekHeight: Dp = 0.dp, elevation: Dp = 8.dp, + onSwiped: (() -> Unit)? = null, collapsedContent: @Composable BoxScope.() -> Unit, content: @Composable BoxScope.() -> Unit ) { @@ -85,18 +86,36 @@ fun BottomSheet( velocityTracker.resetTracking() if (velocity.absoluteValue > 300 && initialValue != state.value) { - if (initialValue > state.value) { - state.collapse() - } else { - state.expand() + when (initialValue) { + state.upperBound -> state.collapse() + state.collapsedBound -> if (initialValue > state.value && onSwiped != null) { + state.swipe() + onSwiped.invoke() + } else { + state.expand() + } } } else { - if (state.upperBound - state.value > state.value - state.lowerBound) { - state.collapse() - } else { - state.expand() + val l0 = state.lowerBound + val l1 = (state.collapsedBound - state.lowerBound) / 2 + val l2 = (state.upperBound - state.collapsedBound) / 2 + val l3 = state.upperBound + + when (state.value) { + in l0..l1 -> { + if (onSwiped != null) { + state.swipe() + onSwiped.invoke() + } else { + state.collapse() + } + } + in l1..l2 -> state.collapse() + in l2..l3 -> state.expand() + else -> {} } } + } ) } @@ -107,7 +126,7 @@ fun BottomSheet( content() } - if (!state.isExpanded) { + if (!state.isExpanded && (onSwiped == null || !state.isDismissed)) { Box( modifier = Modifier .graphicsLayer { @@ -119,7 +138,7 @@ fun BottomSheet( onClick = state::expandSoft ) .fillMaxWidth() - .height(state.lowerBound), + .height(state.collapsedBound), content = collapsedContent ) } @@ -132,6 +151,7 @@ class BottomSheetState( private val coroutineScope: CoroutineScope, private val animatable: Animatable, private val onWasExpandedChanged: (Boolean) -> Unit, + val collapsedBound: Dp, ) : DraggableState by draggableState { val lowerBound: Dp get() = animatable.lowerBound!! @@ -141,8 +161,12 @@ class BottomSheetState( val value by animatable.asState() + val isDismissed by derivedStateOf { + value == animatable.lowerBound!! + } + val isCollapsed by derivedStateOf { - value == animatable.lowerBound + value == collapsedBound } val isExpanded by derivedStateOf { @@ -150,13 +174,13 @@ class BottomSheetState( } val progress by derivedStateOf { - 1f - (animatable.upperBound!! - animatable.value) / (animatable.upperBound!! - animatable.lowerBound!!) + 1f - (animatable.upperBound!! - animatable.value) / (animatable.upperBound!! - collapsedBound) } private fun collapse(animationSpec: AnimationSpec) { onWasExpandedChanged(false) coroutineScope.launch { - animatable.animateTo(animatable.lowerBound!!, animationSpec) + animatable.animateTo(collapsedBound, animationSpec) } } @@ -183,6 +207,13 @@ class BottomSheetState( expand(tween(300)) } + fun swipe() { + onWasExpandedChanged(false) + coroutineScope.launch { + animatable.animateTo(animatable.lowerBound!!) + } + } + fun snapTo(value: Dp) { coroutineScope.launch { animatable.snapTo(value) @@ -224,7 +255,7 @@ class BottomSheetState( if (available.y.absoluteValue > 1000) { collapse() } else { - if (animatable.upperBound!! - value > value - animatable.lowerBound!!) { + if (animatable.upperBound!! - value > value - collapsedBound) { collapse() } else { expand() @@ -250,6 +281,7 @@ class BottomSheetState( fun rememberBottomSheetState( lowerBound: Dp, upperBound: Dp, + collapsedBound: Dp = lowerBound, isExpanded: Boolean = false ): BottomSheetState { val density = LocalDensity.current @@ -259,7 +291,7 @@ fun rememberBottomSheetState( mutableStateOf(isExpanded) } - return remember(lowerBound, upperBound, coroutineScope) { + return remember(lowerBound, upperBound, collapsedBound, coroutineScope) { val animatable = Animatable(if (wasExpanded) upperBound else lowerBound, Dp.VectorConverter).also { it.updateBounds(lowerBound.coerceAtMost(upperBound), upperBound) @@ -275,7 +307,8 @@ fun rememberBottomSheetState( wasExpanded = it }, coroutineScope = coroutineScope, - animatable = animatable + animatable = animatable, + collapsedBound = collapsedBound ) } } diff --git a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt index f0afb95..610c049 100644 --- a/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt +++ b/app/src/main/kotlin/it/vfsfitvnm/vimusic/ui/views/PlayerView.kt @@ -147,6 +147,7 @@ fun PlayerView( BottomSheet( state = layoutState, modifier = modifier, + onSwiped = binder.player::clearMediaItems, collapsedContent = { Row( horizontalArrangement = Arrangement.spacedBy(12.dp),