playback: add predictive back to queue
This commit is contained in:
parent
deaed1fb79
commit
0b8c3abd7f
1 changed files with 47 additions and 35 deletions
|
@ -239,38 +239,53 @@ class MainFragment :
|
||||||
binding.queueSheet.coordinatorLayoutBehavior as QueueBottomSheetBehavior?
|
binding.queueSheet.coordinatorLayoutBehavior as QueueBottomSheetBehavior?
|
||||||
|
|
||||||
val playbackRatio = max(playbackSheetBehavior.calculateSlideOffset(), 0f)
|
val playbackRatio = max(playbackSheetBehavior.calculateSlideOffset(), 0f)
|
||||||
if (playbackRatio > 0f && homeModel.speedDialOpen.value) {
|
if (playbackRatio > 0f) {
|
||||||
|
if (homeModel.speedDialOpen.value) {
|
||||||
// Stupid hack to prevent you from sliding the sheet up without closing the speed
|
// Stupid hack to prevent you from sliding the sheet up without closing the speed
|
||||||
// dial. Filtering out ACTION_MOVE events will cause back gestures to close the speed
|
// dial. Filtering out ACTION_MOVE events will cause back gestures to close the
|
||||||
|
// speed
|
||||||
// dial, which is super finicky behavior.
|
// dial, which is super finicky behavior.
|
||||||
homeModel.setSpeedDialOpen(false)
|
homeModel.setSpeedDialOpen(false)
|
||||||
}
|
}
|
||||||
|
homeModel.setSheetRising(true)
|
||||||
|
} else {
|
||||||
|
homeModel.setSheetRising(false)
|
||||||
|
}
|
||||||
|
|
||||||
val outPlaybackRatio = 1 - playbackRatio
|
val playbackOutRatio = 1 - min(playbackRatio * 2, 1f)
|
||||||
val halfOutRatio = min(playbackRatio * 2, 1f)
|
val playbackInRatio = max(playbackRatio - 0.5f, 0f) * 2
|
||||||
val halfInPlaybackRatio = max(playbackRatio - 0.5f, 0f) * 2
|
|
||||||
|
val playbackMaxXScaleDelta = maxScaleXDistance / binding.playbackSheet.width
|
||||||
|
val playbackEdgeRatio = max(playbackRatio - 0.9f, 0f) / 0.1f
|
||||||
|
val playbackBackRatio =
|
||||||
|
max(1 - ((1 - binding.playbackSheet.scaleX) / playbackMaxXScaleDelta), 0f)
|
||||||
|
val playbackLastStretchRatio = min(playbackEdgeRatio * playbackBackRatio, 1f)
|
||||||
|
binding.mainSheetScrim.alpha = playbackLastStretchRatio
|
||||||
|
|
||||||
val maxScaleXDelta = maxScaleXDistance / binding.playbackSheet.width
|
|
||||||
val closeRatio = max(playbackRatio - 0.9f, 0f) / 0.1f
|
|
||||||
val backRatio = max(1 - ((1 - binding.playbackSheet.scaleX) / maxScaleXDelta), 0f)
|
|
||||||
val lastStretchRatio = min(closeRatio * backRatio, 1f)
|
|
||||||
binding.mainSheetScrim.alpha = lastStretchRatio
|
|
||||||
playbackSheetBehavior.sheetBackgroundDrawable.setCornerSize(
|
playbackSheetBehavior.sheetBackgroundDrawable.setCornerSize(
|
||||||
normalCornerSize * (1 - lastStretchRatio))
|
normalCornerSize * (1 - playbackLastStretchRatio))
|
||||||
binding.exploreNavHost.isInvisible = lastStretchRatio == 1f
|
binding.exploreNavHost.isInvisible = playbackLastStretchRatio == 1f
|
||||||
binding.playbackSheet.translationZ = (1 - lastStretchRatio) * elevationNormal
|
binding.playbackSheet.translationZ = (1 - playbackLastStretchRatio) * elevationNormal
|
||||||
|
|
||||||
if (queueSheetBehavior != null) {
|
if (queueSheetBehavior != null) {
|
||||||
// Queue sheet available, the normal transition applies, but it now much be combined
|
|
||||||
// with another transition where the playback panel disappears and the playback bar
|
|
||||||
// appears as the queue sheet expands.
|
|
||||||
val queueRatio = max(queueSheetBehavior.calculateSlideOffset(), 0f)
|
val queueRatio = max(queueSheetBehavior.calculateSlideOffset(), 0f)
|
||||||
val halfOutQueueRatio = min(queueRatio * 2, 1f)
|
val queueInRatio = max(queueRatio - 0.5f, 0f) * 2
|
||||||
val halfInQueueRatio = max(queueRatio - 0.5f, 0f) * 2
|
|
||||||
|
|
||||||
binding.playbackBarFragment.alpha = max(1 - halfOutRatio, halfInQueueRatio)
|
val queueMaxXScaleDelta = maxScaleXDistance / binding.queueSheet.width
|
||||||
binding.playbackPanelFragment.alpha = min(halfInPlaybackRatio, 1 - halfOutQueueRatio)
|
val queueBackRatio =
|
||||||
binding.queueFragment.alpha = queueRatio
|
max(1 - ((1 - binding.queueSheet.scaleX) / queueMaxXScaleDelta), 0f)
|
||||||
|
|
||||||
|
val queueBarEdgeRatio = max(queueRatio - 0.9f, 0f) / 0.1f
|
||||||
|
val queueBarBackRatio = max(queueBackRatio - 0.5f, 0f) * 2
|
||||||
|
val queueBarRatio = min(queueBarEdgeRatio * queueBarBackRatio, 1f)
|
||||||
|
|
||||||
|
val queuePanelEdgeRatio = min(max(queueRatio - 0.8f, 0f) / 0.1f, 1f)
|
||||||
|
val queuePanelBackRatio = min(queueBackRatio * 2, 1f)
|
||||||
|
val queuePanelRatio = 1 - min(queuePanelEdgeRatio * queuePanelBackRatio, 1f)
|
||||||
|
|
||||||
|
binding.playbackBarFragment.alpha = max(playbackOutRatio, queueBarRatio)
|
||||||
|
binding.playbackPanelFragment.alpha = min(playbackInRatio, queuePanelRatio)
|
||||||
|
binding.queueFragment.alpha = queueInRatio
|
||||||
|
|
||||||
if (playbackModel.song.value != null) {
|
if (playbackModel.song.value != null) {
|
||||||
// Playback sheet intercepts queue sheet touch events, prevent that from
|
// Playback sheet intercepts queue sheet touch events, prevent that from
|
||||||
|
@ -280,12 +295,12 @@ class MainFragment :
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No queue sheet, fade normally based on the playback sheet
|
// No queue sheet, fade normally based on the playback sheet
|
||||||
binding.playbackBarFragment.alpha = 1 - halfOutRatio
|
binding.playbackBarFragment.alpha = playbackOutRatio
|
||||||
binding.playbackPanelFragment.alpha = halfInPlaybackRatio
|
binding.playbackPanelFragment.alpha = playbackInRatio
|
||||||
(binding.queueSheet.background as MaterialShapeDrawable).shapeAppearanceModel =
|
(binding.queueSheet.background as MaterialShapeDrawable).shapeAppearanceModel =
|
||||||
ShapeAppearanceModel.builder()
|
ShapeAppearanceModel.builder()
|
||||||
.setTopLeftCornerSize(normalCornerSize)
|
.setTopLeftCornerSize(normalCornerSize)
|
||||||
.setTopRightCornerSize(normalCornerSize * (1 - lastStretchRatio))
|
.setTopRightCornerSize(normalCornerSize * (1 - playbackLastStretchRatio))
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
// Fade out the playback bar as the panel expands.
|
// Fade out the playback bar as the panel expands.
|
||||||
|
@ -299,7 +314,7 @@ class MainFragment :
|
||||||
|
|
||||||
binding.queueSheet.apply {
|
binding.queueSheet.apply {
|
||||||
// Queue sheet (not queue content) should fade out with the playback panel.
|
// Queue sheet (not queue content) should fade out with the playback panel.
|
||||||
alpha = halfInPlaybackRatio
|
alpha = playbackInRatio
|
||||||
// Prevent interactions when the queue sheet fully fades out.
|
// Prevent interactions when the queue sheet fully fades out.
|
||||||
binding.queueSheet.isInvisible = alpha == 0f
|
binding.queueSheet.isInvisible = alpha == 0f
|
||||||
}
|
}
|
||||||
|
@ -469,24 +484,23 @@ class MainFragment :
|
||||||
) : OnBackPressedCallback(false) {
|
) : OnBackPressedCallback(false) {
|
||||||
override fun handleOnBackStarted(backEvent: BackEventCompat) {
|
override fun handleOnBackStarted(backEvent: BackEventCompat) {
|
||||||
if (queueSheetShown()) {
|
if (queueSheetShown()) {
|
||||||
return
|
unlikelyToBeNull(queueSheetBehavior).startBackProgress(backEvent)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playbackSheetShown()) {
|
if (playbackSheetShown()) {
|
||||||
playbackSheetBehavior.startBackProgress(backEvent)
|
playbackSheetBehavior.startBackProgress(backEvent)
|
||||||
logD("Collapsed playback sheet")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleOnBackProgressed(backEvent: BackEventCompat) {
|
override fun handleOnBackProgressed(backEvent: BackEventCompat) {
|
||||||
if (queueSheetShown()) {
|
if (queueSheetShown()) {
|
||||||
|
unlikelyToBeNull(queueSheetBehavior).updateBackProgress(backEvent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playbackSheetShown()) {
|
if (playbackSheetShown()) {
|
||||||
playbackSheetBehavior.updateBackProgress(backEvent)
|
playbackSheetBehavior.updateBackProgress(backEvent)
|
||||||
logD("Collapsed playback sheet")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,22 +508,20 @@ class MainFragment :
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
// If expanded, collapse the queue sheet first.
|
// If expanded, collapse the queue sheet first.
|
||||||
if (queueSheetShown()) {
|
if (queueSheetShown()) {
|
||||||
unlikelyToBeNull(queueSheetBehavior).state =
|
unlikelyToBeNull(queueSheetBehavior).handleBackInvoked()
|
||||||
BackportBottomSheetBehavior.STATE_COLLAPSED
|
|
||||||
logD("Collapsed queue sheet")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// If expanded, collapse the playback sheet next.
|
// If expanded, collapse the playback sheet next.
|
||||||
if (playbackSheetShown()) {
|
if (playbackSheetShown()) {
|
||||||
playbackSheetBehavior.handleBackInvoked()
|
playbackSheetBehavior.handleBackInvoked()
|
||||||
logD("Collapsed playback sheet")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleOnBackCancelled() {
|
override fun handleOnBackCancelled() {
|
||||||
if (queueSheetShown()) {
|
if (queueSheetShown()) {
|
||||||
|
unlikelyToBeNull(queueSheetBehavior).cancelBackProgress()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue