This commit is contained in:
vfsfitvnm 2022-07-25 12:32:19 +02:00
parent 9ed2c84822
commit 457e6712d4
4 changed files with 58 additions and 20 deletions

View file

@ -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()
}
}

View file

@ -213,7 +213,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
}
override fun onTaskRemoved(rootIntent: Intent?) {
if (!player.playWhenReady) {
if (!player.shouldBePlaying) {
if (isPersistentQueueEnabled) {
broadCastPendingIntent<NotificationDismissReceiver>().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
}

View file

@ -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<Dp, AnimationVector1D>,
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<Dp>) {
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
)
}
}

View file

@ -147,6 +147,7 @@ fun PlayerView(
BottomSheet(
state = layoutState,
modifier = modifier,
onSwiped = binder.player::clearMediaItems,
collapsedContent = {
Row(
horizontalArrangement = Arrangement.spacedBy(12.dp),