diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index 0fda51788..b70ffb4ec 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -24,10 +24,13 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Button +import androidx.activity.OnBackPressedCallback import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels +import androidx.navigation.findNavController +import androidx.navigation.fragment.findNavController import com.google.android.material.snackbar.Snackbar import org.oxycblt.auxio.databinding.FragmentMainBinding import org.oxycblt.auxio.detail.DetailViewModel @@ -41,12 +44,12 @@ import org.oxycblt.auxio.util.logD * A wrapper around the home fragment that shows the playback fragment and controls * the more high-level navigation features. * @author OxygenCobalt - * TODO: Handle backnav with playback view */ class MainFragment : Fragment(), PlaybackLayout.ActionCallback { private val playbackModel: PlaybackViewModel by activityViewModels() private val detailModel: DetailViewModel by activityViewModels() private val musicModel: MusicViewModel by activityViewModels() + private var callback: Callback? = null override fun onCreateView( inflater: LayoutInflater, @@ -66,24 +69,31 @@ class MainFragment : Fragment(), PlaybackLayout.ActionCallback { binding.lifecycleOwner = viewLifecycleOwner + requireActivity().onBackPressedDispatcher.addCallback( + viewLifecycleOwner, + Callback(binding).also { + callback = it + } + ) + // --- VIEWMODEL SETUP --- - binding.mainBarLayout.setActionCallback(this) + binding.playbackLayout.setActionCallback(this) - binding.mainBarLayout.setSong(playbackModel.song.value) - binding.mainBarLayout.setPlaying(playbackModel.isPlaying.value!!) - binding.mainBarLayout.setPosition(playbackModel.position.value!!) + binding.playbackLayout.setSong(playbackModel.song.value) + binding.playbackLayout.setPlaying(playbackModel.isPlaying.value!!) + binding.playbackLayout.setPosition(playbackModel.position.value!!) playbackModel.song.observe(viewLifecycleOwner) { song -> - binding.mainBarLayout.setSong(song) + binding.playbackLayout.setSong(song) } playbackModel.isPlaying.observe(viewLifecycleOwner) { isPlaying -> - binding.mainBarLayout.setPlaying(isPlaying) + binding.playbackLayout.setPlaying(isPlaying) } playbackModel.position.observe(viewLifecycleOwner) { pos -> - binding.mainBarLayout.setPosition(pos) + binding.playbackLayout.setPosition(pos) } // Initialize music loading. Do it here so that it shows on every fragment that this @@ -144,6 +154,23 @@ class MainFragment : Fragment(), PlaybackLayout.ActionCallback { return binding.root } + override fun onResume() { + super.onResume() + callback?.isEnabled = true + } + + override fun onPause() { + super.onPause() + callback?.isEnabled = false + } + + override fun onDestroyView() { + super.onDestroyView() + + // This callback has access to the binding, so make sure we clear it when we're done. + callback = null + } + override fun onNavToItem() { detailModel.navToItem(playbackModel.song.value ?: return) } @@ -159,4 +186,24 @@ class MainFragment : Fragment(), PlaybackLayout.ActionCallback { override fun onNext() { playbackModel.skipNext() } + + /** + * A back press callback that handles how to respond to backwards navigation in the detail + * fragments and the playback panel. + */ + inner class Callback(private val binding: FragmentMainBinding) : OnBackPressedCallback(false) { + override fun handleOnBackPressed() { + if (!binding.playbackLayout.collapse()) { + val navController = binding.exploreNavHost.findNavController() + + if (navController.currentDestination?.id == navController.graph.startDestination) { + isEnabled = false + requireActivity().onBackPressed() + isEnabled = true + } else { + navController.navigateUp() + } + } + } + } } diff --git a/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt index 9cf59a489..7e67f1043 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/DetailFragment.kt @@ -18,9 +18,6 @@ package org.oxycblt.auxio.detail -import android.os.Bundle -import android.view.View -import androidx.activity.OnBackPressedCallback import androidx.annotation.MenuRes import androidx.appcompat.widget.PopupMenu import androidx.core.view.forEach @@ -44,22 +41,12 @@ abstract class DetailFragment : Fragment() { protected val playbackModel: PlaybackViewModel by activityViewModels() protected val binding by memberBinding(FragmentDetailBinding::inflate) - override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner, callback) - } - override fun onResume() { super.onResume() - callback.isEnabled = true detailModel.setNavigating(false) } - override fun onPause() { - super.onPause() - callback.isEnabled = false - } - override fun onStop() { super.onStop() @@ -149,21 +136,4 @@ abstract class DetailFragment : Fragment() { show() } } - - // Override the back button so that going back will only exit the detail fragments instead of - // the entire app. - private val callback = object : OnBackPressedCallback(false) { - - override fun handleOnBackPressed() { - val navController = findNavController() - // Check if it's the root of nested fragments in this NavHost - if (navController.currentDestination?.id == navController.graph.startDestination) { - isEnabled = false - requireActivity().onBackPressed() - isEnabled = true - } else { - navController.navigateUp() - } - } - } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt index b84524ef8..21c8c9a45 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackLayout.kt @@ -23,6 +23,7 @@ import com.google.android.material.shape.MaterialShapeDrawable import org.oxycblt.auxio.BuildConfig import org.oxycblt.auxio.R import org.oxycblt.auxio.music.Song +import org.oxycblt.auxio.util.logD import org.oxycblt.auxio.util.resolveAttr import org.oxycblt.auxio.util.systemBarsCompat import kotlin.math.abs @@ -198,11 +199,17 @@ class PlaybackLayout @JvmOverloads constructor( /** * Collapse the panel if it is currently expanded. + * @return If the panel was collapsed or not. */ - fun collapse() { + fun collapse(): Boolean { + logD(panelState) if (panelState == PanelState.EXPANDED) { applyState(PanelState.COLLAPSED) + logD("I AM EXPANDED WILL COLLAPSE") + return true } + + return false } private fun applyState(state: PanelState) { diff --git a/app/src/main/res/layout/fragment_main.xml b/app/src/main/res/layout/fragment_main.xml index bc0e520f7..39c304534 100644 --- a/app/src/main/res/layout/fragment_main.xml +++ b/app/src/main/res/layout/fragment_main.xml @@ -5,10 +5,9 @@ tools:context=".MainFragment"> + android:layout_height="match_parent"> + app:enterAnim="@anim/nav_default_enter_anim" + app:exitAnim="@anim/nav_default_exit_anim" + app:popEnterAnim="@anim/nav_default_pop_enter_anim" + app:popExitAnim="@anim/nav_default_pop_exit_anim" /> + app:enterAnim="@anim/nav_default_enter_anim" + app:exitAnim="@anim/nav_default_exit_anim" + app:popEnterAnim="@anim/nav_default_pop_enter_anim" + app:popExitAnim="@anim/nav_default_pop_exit_anim" />