Add nav to playing song's album

Add the ability to navigate from CompactPlaybackFragment to the album where the current song is.
This commit is contained in:
OxygenCobalt 2020-11-08 15:39:18 -07:00
parent a192fb52c3
commit b5552411b6
6 changed files with 44 additions and 8 deletions

View file

@ -120,6 +120,8 @@ class AlbumDetailFragment : Fragment() {
binding.albumArtist.setBackgroundResource(R.drawable.ui_ripple) binding.albumArtist.setBackgroundResource(R.drawable.ui_ripple)
} }
// TODO: Make DetailFragment scroll to song if navigated from CompactPlaybackFragment
Log.d(this::class.simpleName, "Fragment created.") Log.d(this::class.simpleName, "Fragment created.")
return binding.root return binding.root

View file

@ -162,6 +162,18 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
} }
} }
playbackModel.navToPlayingSong.observe(viewLifecycleOwner) {
if (it) {
findNavController().navigate(
MainFragmentDirections.actionShowAlbum(
playbackModel.song.value!!.album.id, true
)
)
playbackModel.doneWithNavToPlayingSong()
}
}
Log.d(this::class.simpleName, "Fragment created.") Log.d(this::class.simpleName, "Fragment created.")
return binding.root return binding.root

View file

@ -42,12 +42,19 @@ class CompactPlaybackFragment : Fragment() {
binding.song = MusicStore.getInstance().songs[0] binding.song = MusicStore.getInstance().songs[0]
binding.playbackModel = playbackModel binding.playbackModel = playbackModel
binding.root.setOnClickListener { binding.root.apply {
setOnClickListener {
findNavController().navigate( findNavController().navigate(
MainFragmentDirections.actionGoToPlayback() MainFragmentDirections.actionGoToPlayback()
) )
} }
setOnLongClickListener {
playbackModel.navigateToPlayingSong()
true
}
}
// --- VIEWMODEL SETUP --- // --- VIEWMODEL SETUP ---
playbackModel.song.observe(viewLifecycleOwner) { playbackModel.song.observe(viewLifecycleOwner) {

View file

@ -23,7 +23,6 @@ import org.oxycblt.auxio.ui.toColor
class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener { class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
private val playbackModel: PlaybackViewModel by activityViewModels() private val playbackModel: PlaybackViewModel by activityViewModels()
// TODO: Implement nav to artists/albums
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@ -78,6 +77,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
} }
// Make marquee scroll work // Make marquee scroll work
// TODO: Add nav here as well
binding.playbackSong.isSelected = true binding.playbackSong.isSelected = true
binding.playbackSeekBar.setOnSeekBarChangeListener(this) binding.playbackSeekBar.setOnSeekBarChangeListener(this)
@ -91,7 +91,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
binding.song = it binding.song = it
binding.playbackSeekBar.max = it.seconds.toInt() binding.playbackSeekBar.max = it.seconds.toInt()
} else { } else {
Log.d(this::class.simpleName, "No song played anymore, leaving.") Log.d(this::class.simpleName, "No song is being played, leaving.")
findNavController().navigateUp() findNavController().navigateUp()
} }

View file

@ -16,7 +16,6 @@ import org.oxycblt.auxio.playback.state.PlaybackMode
import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.playback.state.PlaybackStateManager
// A ViewModel that acts as an intermediary between the UI and PlaybackStateManager // A ViewModel that acts as an intermediary between the UI and PlaybackStateManager
// TODO: Implement User Queue
// TODO: Implement Persistence through a Database // TODO: Implement Persistence through a Database
class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback { class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
// Playback // Playback
@ -56,6 +55,9 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
private val mIsSeeking = MutableLiveData(false) private val mIsSeeking = MutableLiveData(false)
val isSeeking: LiveData<Boolean> get() = mIsSeeking val isSeeking: LiveData<Boolean> get() = mIsSeeking
private val mNavToPlayingSong = MutableLiveData(false)
val navToPlayingSong: LiveData<Boolean> get() = mNavToPlayingSong
val formattedPosition = Transformations.map(mPosition) { val formattedPosition = Transformations.map(mPosition) {
it.toDuration() it.toDuration()
} }
@ -206,6 +208,14 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
mIsSeeking.value = value mIsSeeking.value = value
} }
fun navigateToPlayingSong() {
mNavToPlayingSong.value = true
}
fun doneWithNavToPlayingSong() {
mNavToPlayingSong.value = false
}
// --- OVERRIDES --- // --- OVERRIDES ---
override fun onCleared() { override fun onCleared() {

View file

@ -75,6 +75,7 @@ class PlaybackStateManager private constructor() {
field = value field = value
callbacks.forEach { it.onLoopUpdate(value) } callbacks.forEach { it.onLoopUpdate(value) }
} }
private var mIsInUserQueue = false
val song: Song? get() = mSong val song: Song? get() = mSong
val parent: BaseModel? get() = mParent val parent: BaseModel? get() = mParent
@ -194,6 +195,8 @@ class PlaybackStateManager private constructor() {
if (!mIsPlaying) { if (!mIsPlaying) {
mIsPlaying = true mIsPlaying = true
} }
mIsInUserQueue = false
} }
fun setPosition(position: Long) { fun setPosition(position: Long) {
@ -220,6 +223,8 @@ class PlaybackStateManager private constructor() {
updatePlayback(mUserQueue[0]) updatePlayback(mUserQueue[0])
mUserQueue.removeAt(0) mUserQueue.removeAt(0)
mIsInUserQueue = true
forceUserQueueUpdate() forceUserQueueUpdate()
} else { } else {
if (mIndex < mQueue.lastIndex) { if (mIndex < mQueue.lastIndex) {
@ -239,7 +244,7 @@ class PlaybackStateManager private constructor() {
} }
fun prev() { fun prev() {
if (mIndex > 0) { if (mIndex > 0 && !mIsInUserQueue) {
mIndex = mIndex.dec() mIndex = mIndex.dec()
} }