1717
1818package org.akanework.gramophone.ui.components
1919
20+ import android.animation.Animator
21+ import android.animation.AnimatorListenerAdapter
22+ import android.annotation.SuppressLint
2023import android.content.Context
24+ import android.os.Build
2125import android.os.Handler
2226import android.os.Looper
2327import android.util.AttributeSet
@@ -37,6 +41,8 @@ import androidx.core.view.WindowInsetsCompat
3741import androidx.core.view.doOnLayout
3842import androidx.core.view.doOnNextLayout
3943import androidx.core.view.isVisible
44+ import androidx.fragment.app.Fragment
45+ import androidx.fragment.app.findFragment
4046import androidx.lifecycle.DefaultLifecycleObserver
4147import androidx.lifecycle.LifecycleOwner
4248import androidx.media3.common.MediaItem
@@ -52,6 +58,7 @@ import coil3.size.Scale
5258import com.google.android.material.bottomsheet.BottomSheetBehavior
5359import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
5460import com.google.android.material.button.MaterialButton
61+ import com.google.android.material.motion.MaterialBottomContainerBackHelper
5562import org.akanework.gramophone.BuildConfig
5663import org.akanework.gramophone.R
5764import org.akanework.gramophone.logic.clone
@@ -77,6 +84,8 @@ class PlayerBottomSheet private constructor(
7784
7885 private var lastDisposable: Disposable ? = null
7986 private var standardBottomSheetBehavior: MyBottomSheetBehavior <FrameLayout >? = null
87+ @SuppressLint(" RestrictedApi" )
88+ private var lyricsBackHelper: MaterialBottomContainerBackHelper ? = null
8089 private var bottomSheetBackCallback: OnBackPressedCallback ? = null
8190 val fullPlayer: FullBottomSheet
8291 private val previewPlayer: View
@@ -100,6 +109,8 @@ class PlayerBottomSheet private constructor(
100109 set(value) {
101110 if (field != value) {
102111 field = value
112+ // TODO: this should be animated with predictive back once we switch to a better
113+ // back stack.
103114 standardBottomSheetBehavior?.state =
104115 if ((instance?.mediaItemCount ? : 0 ) > 0 && value) {
105116 if (standardBottomSheetBehavior?.state
@@ -218,37 +229,51 @@ class PlayerBottomSheet private constructor(
218229 fullPlayer.minimize = {
219230 standardBottomSheetBehavior!! .state = BottomSheetBehavior .STATE_COLLAPSED
220231 }
232+ @SuppressLint(" RestrictedApi" )
233+ lyricsBackHelper = MaterialBottomContainerBackHelper (fullPlayer.bottomSheetFullLyricView)
221234 bottomSheetBackCallback = object : OnBackPressedCallback (enabled = false ) {
222235 override fun handleOnBackStarted (backEvent : BackEventCompat ) {
223236 if (fullPlayer.bottomSheetFullLyricView.isVisible) {
224- fullPlayer.bottomSheetFullLyricView.fadOutAnimation( FullBottomSheet . LYRIC_FADE_TRANSITION_SEC )
225- fullPlayer.bottomSheetLyricButton.isChecked = false
237+ @SuppressLint( " RestrictedApi " )
238+ lyricsBackHelper !! .startBackProgress(backEvent)
226239 } else {
227240 standardBottomSheetBehavior!! .startBackProgress(backEvent)
228241 }
229242 }
230243
231244 override fun handleOnBackProgressed (backEvent : BackEventCompat ) {
232245 if (fullPlayer.bottomSheetFullLyricView.isVisible) {
233- // TODO
246+ @SuppressLint(" RestrictedApi" )
247+ lyricsBackHelper!! .updateBackProgress(backEvent)
234248 } else {
235249 standardBottomSheetBehavior!! .updateBackProgress(backEvent)
236250 }
237251 }
238252
239253 override fun handleOnBackPressed () {
240254 if (fullPlayer.bottomSheetFullLyricView.isVisible) {
241- fullPlayer.bottomSheetFullLyricView.fadOutAnimation(FullBottomSheet .LYRIC_FADE_TRANSITION_SEC )
242- fullPlayer.bottomSheetLyricButton.isChecked = false
255+ @SuppressLint(" RestrictedApi" )
256+ val backEvent = lyricsBackHelper!! .onHandleBackInvoked()
257+ if (backEvent == null || backEvent.progress == 0f
258+ || Build .VERSION .SDK_INT < Build .VERSION_CODES .UPSIDE_DOWN_CAKE ) {
259+ fullPlayer.bottomSheetFullLyricView.fadOutAnimation(FullBottomSheet .LYRIC_FADE_TRANSITION_SEC )
260+ return
261+ }
262+ @SuppressLint(" RestrictedApi" )
263+ lyricsBackHelper!! .finishBackProgressNotPersistent(backEvent, object : AnimatorListenerAdapter () {
264+ override fun onAnimationEnd (animation : Animator ) {
265+ fullPlayer.bottomSheetFullLyricView.visibility = View .INVISIBLE
266+ }
267+ })
243268 } else {
244269 standardBottomSheetBehavior!! .handleBackInvoked()
245270 }
246271 }
247272
248273 override fun handleOnBackCancelled () {
249274 if (fullPlayer.bottomSheetFullLyricView.isVisible) {
250- fullPlayer.bottomSheetFullLyricView.fadInAnimation( FullBottomSheet . LYRIC_FADE_TRANSITION_SEC )
251- fullPlayer.bottomSheetLyricButton.isChecked = false
275+ @SuppressLint( " RestrictedApi " )
276+ lyricsBackHelper !! .cancelBackProgress()
252277 } else {
253278 standardBottomSheetBehavior!! .cancelBackProgress()
254279 }
0 commit comments