Implement #51
This commit is contained in:
@@ -40,6 +40,7 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.media3.common.MediaItem
|
import androidx.media3.common.MediaItem
|
||||||
import androidx.media3.common.Player
|
import androidx.media3.common.Player
|
||||||
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
import com.google.accompanist.systemuicontroller.rememberSystemUiController
|
||||||
@@ -215,7 +216,8 @@ class MainActivity : ComponentActivity() {
|
|||||||
when (val uri = uri) {
|
when (val uri = uri) {
|
||||||
null -> {
|
null -> {
|
||||||
val playerBottomSheetState = rememberBottomSheetState(
|
val playerBottomSheetState = rememberBottomSheetState(
|
||||||
lowerBound = Dimensions.collapsedPlayer,
|
lowerBound = 0.dp,
|
||||||
|
collapsedBound = Dimensions.collapsedPlayer,
|
||||||
upperBound = maxHeight,
|
upperBound = maxHeight,
|
||||||
isExpanded = expandPlayerBottomSheet
|
isExpanded = expandPlayerBottomSheet
|
||||||
)
|
)
|
||||||
@@ -263,7 +265,7 @@ fun ExpandPlayerOnPlaylistChange(player: Player, expand: () -> Unit) {
|
|||||||
DisposableEffect(player, expand) {
|
DisposableEffect(player, expand) {
|
||||||
player.listener(object : Player.Listener {
|
player.listener(object : Player.Listener {
|
||||||
override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
|
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()
|
expand()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -213,7 +213,7 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onTaskRemoved(rootIntent: Intent?) {
|
override fun onTaskRemoved(rootIntent: Intent?) {
|
||||||
if (!player.playWhenReady) {
|
if (!player.shouldBePlaying) {
|
||||||
if (isPersistentQueueEnabled) {
|
if (isPersistentQueueEnabled) {
|
||||||
broadCastPendingIntent<NotificationDismissReceiver>().send()
|
broadCastPendingIntent<NotificationDismissReceiver>().send()
|
||||||
} else {
|
} else {
|
||||||
@@ -398,7 +398,9 @@ class PlayerService : InvincibleService(), Player.Listener, PlaybackStatsListene
|
|||||||
val notification = notification()
|
val notification = notification()
|
||||||
|
|
||||||
if (notification == null) {
|
if (notification == null) {
|
||||||
stopSelf()
|
isNotificationStarted = false
|
||||||
|
makeInvincible(false)
|
||||||
|
stopForeground(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ fun BottomSheet(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
peekHeight: Dp = 0.dp,
|
peekHeight: Dp = 0.dp,
|
||||||
elevation: Dp = 8.dp,
|
elevation: Dp = 8.dp,
|
||||||
|
onSwiped: (() -> Unit)? = null,
|
||||||
collapsedContent: @Composable BoxScope.() -> Unit,
|
collapsedContent: @Composable BoxScope.() -> Unit,
|
||||||
content: @Composable BoxScope.() -> Unit
|
content: @Composable BoxScope.() -> Unit
|
||||||
) {
|
) {
|
||||||
@@ -85,18 +86,36 @@ fun BottomSheet(
|
|||||||
velocityTracker.resetTracking()
|
velocityTracker.resetTracking()
|
||||||
|
|
||||||
if (velocity.absoluteValue > 300 && initialValue != state.value) {
|
if (velocity.absoluteValue > 300 && initialValue != state.value) {
|
||||||
if (initialValue > state.value) {
|
when (initialValue) {
|
||||||
state.collapse()
|
state.upperBound -> state.collapse()
|
||||||
} else {
|
state.collapsedBound -> if (initialValue > state.value && onSwiped != null) {
|
||||||
state.expand()
|
state.swipe()
|
||||||
|
onSwiped.invoke()
|
||||||
|
} else {
|
||||||
|
state.expand()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (state.upperBound - state.value > state.value - state.lowerBound) {
|
val l0 = state.lowerBound
|
||||||
state.collapse()
|
val l1 = (state.collapsedBound - state.lowerBound) / 2
|
||||||
} else {
|
val l2 = (state.upperBound - state.collapsedBound) / 2
|
||||||
state.expand()
|
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()
|
content()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!state.isExpanded) {
|
if (!state.isExpanded && (onSwiped == null || !state.isDismissed)) {
|
||||||
Box(
|
Box(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.graphicsLayer {
|
.graphicsLayer {
|
||||||
@@ -119,7 +138,7 @@ fun BottomSheet(
|
|||||||
onClick = state::expandSoft
|
onClick = state::expandSoft
|
||||||
)
|
)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(state.lowerBound),
|
.height(state.collapsedBound),
|
||||||
content = collapsedContent
|
content = collapsedContent
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -132,6 +151,7 @@ class BottomSheetState(
|
|||||||
private val coroutineScope: CoroutineScope,
|
private val coroutineScope: CoroutineScope,
|
||||||
private val animatable: Animatable<Dp, AnimationVector1D>,
|
private val animatable: Animatable<Dp, AnimationVector1D>,
|
||||||
private val onWasExpandedChanged: (Boolean) -> Unit,
|
private val onWasExpandedChanged: (Boolean) -> Unit,
|
||||||
|
val collapsedBound: Dp,
|
||||||
) : DraggableState by draggableState {
|
) : DraggableState by draggableState {
|
||||||
val lowerBound: Dp
|
val lowerBound: Dp
|
||||||
get() = animatable.lowerBound!!
|
get() = animatable.lowerBound!!
|
||||||
@@ -141,8 +161,12 @@ class BottomSheetState(
|
|||||||
|
|
||||||
val value by animatable.asState()
|
val value by animatable.asState()
|
||||||
|
|
||||||
|
val isDismissed by derivedStateOf {
|
||||||
|
value == animatable.lowerBound!!
|
||||||
|
}
|
||||||
|
|
||||||
val isCollapsed by derivedStateOf {
|
val isCollapsed by derivedStateOf {
|
||||||
value == animatable.lowerBound
|
value == collapsedBound
|
||||||
}
|
}
|
||||||
|
|
||||||
val isExpanded by derivedStateOf {
|
val isExpanded by derivedStateOf {
|
||||||
@@ -150,13 +174,13 @@ class BottomSheetState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val progress by derivedStateOf {
|
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>) {
|
private fun collapse(animationSpec: AnimationSpec<Dp>) {
|
||||||
onWasExpandedChanged(false)
|
onWasExpandedChanged(false)
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
animatable.animateTo(animatable.lowerBound!!, animationSpec)
|
animatable.animateTo(collapsedBound, animationSpec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +207,13 @@ class BottomSheetState(
|
|||||||
expand(tween(300))
|
expand(tween(300))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun swipe() {
|
||||||
|
onWasExpandedChanged(false)
|
||||||
|
coroutineScope.launch {
|
||||||
|
animatable.animateTo(animatable.lowerBound!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun snapTo(value: Dp) {
|
fun snapTo(value: Dp) {
|
||||||
coroutineScope.launch {
|
coroutineScope.launch {
|
||||||
animatable.snapTo(value)
|
animatable.snapTo(value)
|
||||||
@@ -224,7 +255,7 @@ class BottomSheetState(
|
|||||||
if (available.y.absoluteValue > 1000) {
|
if (available.y.absoluteValue > 1000) {
|
||||||
collapse()
|
collapse()
|
||||||
} else {
|
} else {
|
||||||
if (animatable.upperBound!! - value > value - animatable.lowerBound!!) {
|
if (animatable.upperBound!! - value > value - collapsedBound) {
|
||||||
collapse()
|
collapse()
|
||||||
} else {
|
} else {
|
||||||
expand()
|
expand()
|
||||||
@@ -250,6 +281,7 @@ class BottomSheetState(
|
|||||||
fun rememberBottomSheetState(
|
fun rememberBottomSheetState(
|
||||||
lowerBound: Dp,
|
lowerBound: Dp,
|
||||||
upperBound: Dp,
|
upperBound: Dp,
|
||||||
|
collapsedBound: Dp = lowerBound,
|
||||||
isExpanded: Boolean = false
|
isExpanded: Boolean = false
|
||||||
): BottomSheetState {
|
): BottomSheetState {
|
||||||
val density = LocalDensity.current
|
val density = LocalDensity.current
|
||||||
@@ -259,7 +291,7 @@ fun rememberBottomSheetState(
|
|||||||
mutableStateOf(isExpanded)
|
mutableStateOf(isExpanded)
|
||||||
}
|
}
|
||||||
|
|
||||||
return remember(lowerBound, upperBound, coroutineScope) {
|
return remember(lowerBound, upperBound, collapsedBound, coroutineScope) {
|
||||||
val animatable =
|
val animatable =
|
||||||
Animatable(if (wasExpanded) upperBound else lowerBound, Dp.VectorConverter).also {
|
Animatable(if (wasExpanded) upperBound else lowerBound, Dp.VectorConverter).also {
|
||||||
it.updateBounds(lowerBound.coerceAtMost(upperBound), upperBound)
|
it.updateBounds(lowerBound.coerceAtMost(upperBound), upperBound)
|
||||||
@@ -275,7 +307,8 @@ fun rememberBottomSheetState(
|
|||||||
wasExpanded = it
|
wasExpanded = it
|
||||||
},
|
},
|
||||||
coroutineScope = coroutineScope,
|
coroutineScope = coroutineScope,
|
||||||
animatable = animatable
|
animatable = animatable,
|
||||||
|
collapsedBound = collapsedBound
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ fun PlayerView(
|
|||||||
BottomSheet(
|
BottomSheet(
|
||||||
state = layoutState,
|
state = layoutState,
|
||||||
modifier = modifier,
|
modifier = modifier,
|
||||||
|
onSwiped = binder.player::clearMediaItems,
|
||||||
collapsedContent = {
|
collapsedContent = {
|
||||||
Row(
|
Row(
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
||||||
|
|||||||
Reference in New Issue
Block a user