Implement #51
This commit is contained in:
parent
9ed2c84822
commit
457e6712d4
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
} else {
|
||||
if (state.upperBound - state.value > state.value - state.lowerBound) {
|
||||
state.collapse()
|
||||
when (initialValue) {
|
||||
state.upperBound -> state.collapse()
|
||||
state.collapsedBound -> if (initialValue > state.value && onSwiped != null) {
|
||||
state.swipe()
|
||||
onSwiped.invoke()
|
||||
} else {
|
||||
state.expand()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,6 +147,7 @@ fun PlayerView(
|
|||
BottomSheet(
|
||||
state = layoutState,
|
||||
modifier = modifier,
|
||||
onSwiped = binder.player::clearMediaItems,
|
||||
collapsedContent = {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||
|
|
Loading…
Reference in a new issue