Re-add playback nav
Re-add the ability to navigate back to the currently playing song. Now with a scroll!
This commit is contained in:
parent
0627677569
commit
d46b99400f
8 changed files with 64 additions and 20 deletions
|
|
@ -4,7 +4,6 @@ import android.content.res.ColorStateList
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.Menu
|
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
|
@ -15,7 +14,9 @@ import androidx.navigation.NavOptions
|
||||||
import androidx.navigation.fragment.NavHostFragment
|
import androidx.navigation.fragment.NavHostFragment
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.navigation.ui.NavigationUI
|
import androidx.navigation.ui.NavigationUI
|
||||||
|
import androidx.navigation.ui.setupWithNavController
|
||||||
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
import org.oxycblt.auxio.databinding.FragmentMainBinding
|
||||||
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
import org.oxycblt.auxio.ui.accent
|
import org.oxycblt.auxio.ui.accent
|
||||||
|
|
@ -26,6 +27,7 @@ import java.lang.IllegalArgumentException
|
||||||
|
|
||||||
class MainFragment : Fragment() {
|
class MainFragment : Fragment() {
|
||||||
private val playbackModel: PlaybackViewModel by activityViewModels()
|
private val playbackModel: PlaybackViewModel by activityViewModels()
|
||||||
|
private val detailModel: DetailViewModel by activityViewModels()
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
|
|
@ -70,10 +72,8 @@ class MainFragment : Fragment() {
|
||||||
binding.navBar.itemIconTintList = navTints
|
binding.navBar.itemIconTintList = navTints
|
||||||
binding.navBar.itemTextColor = navTints
|
binding.navBar.itemTextColor = navTints
|
||||||
|
|
||||||
navController?.let {
|
navController?.let { controller ->
|
||||||
binding.navBar.setOnNavigationItemSelectedListener { item ->
|
binding.navBar.setupWithNavController(controller)
|
||||||
navigateWithItem(item, it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- VIEWMODEL SETUP ---
|
// --- VIEWMODEL SETUP ---
|
||||||
|
|
@ -93,6 +93,19 @@ class MainFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playbackModel.navToSong.observe(viewLifecycleOwner) {
|
||||||
|
if (it) {
|
||||||
|
if (binding.navBar.selectedItemId != R.id.library_fragment ||
|
||||||
|
navController!!.currentDestination?.id == R.id.artist_detail_fragment ||
|
||||||
|
navController.currentDestination?.id == R.id.genre_detail_fragment ||
|
||||||
|
detailModel.currentAlbum.value == null ||
|
||||||
|
detailModel.currentAlbum.value?.id != playbackModel.song.value!!.album.id
|
||||||
|
) {
|
||||||
|
binding.navBar.selectedItemId = R.id.library_fragment
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
playbackModel.restorePlaybackIfNeeded(requireContext())
|
playbackModel.restorePlaybackIfNeeded(requireContext())
|
||||||
|
|
||||||
Log.d(this::class.simpleName, "Fragment Created.")
|
Log.d(this::class.simpleName, "Fragment Created.")
|
||||||
|
|
@ -107,16 +120,11 @@ class MainFragment : Fragment() {
|
||||||
if (item.itemId != navController.currentDestination!!.id) {
|
if (item.itemId != navController.currentDestination!!.id) {
|
||||||
val builder = NavOptions.Builder().setLaunchSingleTop(true)
|
val builder = NavOptions.Builder().setLaunchSingleTop(true)
|
||||||
|
|
||||||
builder.setEnterAnim(R.anim.nav_default_enter_anim)
|
val options = builder.setEnterAnim(R.anim.nav_default_enter_anim)
|
||||||
.setExitAnim(R.anim.nav_default_exit_anim)
|
.setExitAnim(R.anim.nav_default_exit_anim)
|
||||||
.setPopEnterAnim(R.anim.nav_default_enter_anim)
|
.setPopEnterAnim(R.anim.nav_default_enter_anim)
|
||||||
.setPopExitAnim(R.anim.nav_default_exit_anim)
|
.setPopExitAnim(R.anim.nav_default_exit_anim)
|
||||||
|
.build()
|
||||||
if ((item.order and Menu.CATEGORY_SECONDARY) == 0) {
|
|
||||||
builder.setPopUpTo(navController.graph.startDestination, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
val options = builder.build()
|
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
navController.navigate(item.itemId, null, options)
|
navController.navigate(item.itemId, null, options)
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,25 @@ class AlbumDetailFragment : DetailFragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playbackModel.navToSong.observe(viewLifecycleOwner) {
|
||||||
|
if (it) {
|
||||||
|
val pos = detailModel.currentAlbum.value!!.songs.indexOf(playbackModel.song.value)
|
||||||
|
|
||||||
|
if (pos != -1) {
|
||||||
|
binding.albumSongRecycler.post {
|
||||||
|
val y = binding.albumSongRecycler.y +
|
||||||
|
binding.albumSongRecycler.getChildAt(pos).y
|
||||||
|
|
||||||
|
binding.nestedScroll.smoothScrollBy(0, y.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
playbackModel.doneWithNavToPlayingSong()
|
||||||
|
} else {
|
||||||
|
findNavController().navigateUp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(this::class.simpleName, "Fragment created.")
|
Log.d(this::class.simpleName, "Fragment created.")
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding
|
||||||
import org.oxycblt.auxio.detail.adapters.DetailAlbumAdapter
|
import org.oxycblt.auxio.detail.adapters.DetailAlbumAdapter
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
import org.oxycblt.auxio.playback.PlaybackViewModel
|
||||||
|
|
||||||
import org.oxycblt.auxio.ui.disable
|
import org.oxycblt.auxio.ui.disable
|
||||||
import org.oxycblt.auxio.ui.setupAlbumActions
|
import org.oxycblt.auxio.ui.setupAlbumActions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ abstract class DetailFragment : Fragment() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
callback.isEnabled = false
|
callback.isEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
private val callback = object : OnBackPressedCallback(false) {
|
private val callback = object : OnBackPressedCallback(false) {
|
||||||
|
|
||||||
override fun handleOnBackPressed() {
|
override fun handleOnBackPressed() {
|
||||||
|
|
|
||||||
|
|
@ -151,6 +151,14 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playbackModel.navToSong.observe(viewLifecycleOwner) {
|
||||||
|
if (it) {
|
||||||
|
libraryModel.updateNavigationStatus(false)
|
||||||
|
|
||||||
|
navToItem(playbackModel.song.value!!.album)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.d(this::class.simpleName, "Fragment created.")
|
Log.d(this::class.simpleName, "Fragment created.")
|
||||||
|
|
||||||
return binding.root
|
return binding.root
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import org.oxycblt.auxio.MainFragmentDirections
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.databinding.FragmentCompactPlaybackBinding
|
import org.oxycblt.auxio.databinding.FragmentCompactPlaybackBinding
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.ui.createToast
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A [Fragment] that displays the currently played song at a glance, with some basic controls.
|
* A [Fragment] that displays the currently played song at a glance, with some basic controls.
|
||||||
|
|
@ -57,8 +56,10 @@ class CompactPlaybackFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.root.setOnLongClickListener {
|
binding.root.setOnLongClickListener {
|
||||||
|
playbackModel.navToPlayingSong()
|
||||||
|
/*
|
||||||
playbackModel.save(requireContext())
|
playbackModel.save(requireContext())
|
||||||
getString(R.string.debug_state_saved).createToast(requireContext())
|
getString(R.string.debug_state_saved).createToast(requireContext()) */
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,16 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
private val mLoopMode = MutableLiveData(LoopMode.NONE)
|
private val mLoopMode = MutableLiveData(LoopMode.NONE)
|
||||||
val loopMode: LiveData<LoopMode> get() = mLoopMode
|
val loopMode: LiveData<LoopMode> get() = mLoopMode
|
||||||
|
|
||||||
private var mCanAnimate = false
|
|
||||||
val canAnimate: Boolean get() = mCanAnimate
|
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
private val mIsSeeking = MutableLiveData(false)
|
private val mIsSeeking = MutableLiveData(false)
|
||||||
val isSeeking: LiveData<Boolean> get() = mIsSeeking
|
val isSeeking: LiveData<Boolean> get() = mIsSeeking
|
||||||
|
|
||||||
|
private val mNavToSong = MutableLiveData(false)
|
||||||
|
val navToSong: LiveData<Boolean> get() = mNavToSong
|
||||||
|
|
||||||
|
private var mCanAnimate = false
|
||||||
|
val canAnimate: Boolean get() = mCanAnimate
|
||||||
|
|
||||||
val formattedPosition = Transformations.map(mPosition) {
|
val formattedPosition = Transformations.map(mPosition) {
|
||||||
it.toDuration()
|
it.toDuration()
|
||||||
}
|
}
|
||||||
|
|
@ -279,6 +282,14 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun navToPlayingSong() {
|
||||||
|
mNavToSong.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doneWithNavToPlayingSong() {
|
||||||
|
mNavToSong.value = false
|
||||||
|
}
|
||||||
|
|
||||||
fun resetCanAnimate() {
|
fun resetCanAnimate() {
|
||||||
mCanAnimate = false
|
mCanAnimate = false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import android.widget.Toast
|
||||||
import androidx.annotation.ColorInt
|
import androidx.annotation.ColorInt
|
||||||
import androidx.annotation.MenuRes
|
import androidx.annotation.MenuRes
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.detail.DetailViewModel
|
import org.oxycblt.auxio.detail.DetailViewModel
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue