diff --git a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt index adab93216..33c808502 100644 --- a/app/src/main/java/org/oxycblt/auxio/MainFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/MainFragment.kt @@ -7,6 +7,7 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.viewpager2.adapter.FragmentStateAdapter import com.google.android.material.tabs.TabLayout @@ -14,6 +15,7 @@ import com.google.android.material.tabs.TabLayoutMediator import org.oxycblt.auxio.databinding.FragmentMainBinding import org.oxycblt.auxio.library.LibraryFragment import org.oxycblt.auxio.music.MusicStore +import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.songs.SongsFragment import org.oxycblt.auxio.theme.accent import org.oxycblt.auxio.theme.getInactiveAlpha @@ -21,6 +23,8 @@ import org.oxycblt.auxio.theme.getTransparentAccent import org.oxycblt.auxio.theme.toColor class MainFragment : Fragment() { + private val playbackModel: PlaybackViewModel by activityViewModels() + private val shownFragments = listOf(0, 1) private val tabIcons = listOf( R.drawable.ic_library, @@ -83,6 +87,23 @@ class MainFragment : Fragment() { } ) + // --- VIEWMODEL SETUP --- + + // TODO: Add a slide animation to this + // Change CompactPlaybackFragment's visibility here so that an animation occurs. + playbackModel.currentSong.observe(viewLifecycleOwner) { + if (it == null) { + Log.d( + this::class.simpleName, + "Hiding CompactPlaybackFragment since no song is being played." + ) + + binding.compactPlayback.visibility = View.GONE + } else { + binding.compactPlayback.visibility = View.VISIBLE + } + } + Log.d(this::class.simpleName, "Fragment Created.") return binding.root diff --git a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt index 8755493db..0f4404f3c 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/AlbumDetailFragment.kt @@ -5,7 +5,6 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController @@ -49,9 +48,6 @@ class AlbumDetailFragment : Fragment() { playbackModel.update(it, PlaybackMode.IN_ALBUM) } - val playIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_play) - val pauseIcon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_pause) - // --- UI SETUP --- binding.lifecycleOwner = this @@ -125,9 +121,9 @@ class AlbumDetailFragment : Fragment() { } // Update the play button depending on the current playback status - // If the shown album is currently playing, set the button to the current isPlaying status and - // its behavior to modify the current playing status - // If the shown album isn't currently playing, set the button to "Play" and its behavior + // If the shown album is currently playing, set the button icon to the current isPlaying + // status, and then set its behavior to modify isPlaying. + // If the shown album isn't currently playing, set the button to Play and its behavior // to start the playback of the album. private fun updatePlayButton(mode: PlaybackMode, binding: FragmentAlbumDetailBinding) { playbackModel.currentSong.value?.let { song -> diff --git a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt index 4830b49b6..875093e24 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/ArtistDetailFragment.kt @@ -9,9 +9,12 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs +import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentArtistDetailBinding import org.oxycblt.auxio.detail.adapters.DetailAlbumAdapter import org.oxycblt.auxio.music.MusicStore +import org.oxycblt.auxio.playback.PlaybackMode +import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.theme.applyDivider import org.oxycblt.auxio.theme.disable @@ -22,6 +25,7 @@ class ArtistDetailFragment : Fragment() { private val args: ArtistDetailFragmentArgs by navArgs() private val detailModel: DetailViewModel by activityViewModels() + private val playbackModel: PlaybackViewModel by activityViewModels() override fun onCreateView( inflater: LayoutInflater, @@ -56,6 +60,7 @@ class ArtistDetailFragment : Fragment() { binding.lifecycleOwner = this binding.detailModel = detailModel + binding.playbackModel = playbackModel binding.artist = detailModel.currentArtist.value!! binding.artistToolbar.setNavigationOnClickListener { @@ -87,11 +92,48 @@ class ArtistDetailFragment : Fragment() { ) } + playbackModel.currentMode.observe(viewLifecycleOwner) { + updatePlayButton(it, binding) + } + + playbackModel.isPlaying.observe(viewLifecycleOwner) { + updatePlayButton(playbackModel.currentMode.value!!, binding) + } + Log.d(this::class.simpleName, "Fragment created.") return binding.root } + // Update the play button depending on the current playback status + // If the shown artist is currently playing, set the button icon to the current isPlaying + // status, and then set its behavior to modify isPlaying. + // If the shown artist isn't currently playing, set the button to Play and its behavior + // to start the playback of the artist. + private fun updatePlayButton(mode: PlaybackMode, binding: FragmentArtistDetailBinding) { + playbackModel.currentSong.value?.let { song -> + if (mode == PlaybackMode.IN_ARTIST && + song.album.artist == detailModel.currentArtist.value + ) { + if (playbackModel.isPlaying.value!!) { + binding.artistPlay.setImageResource(R.drawable.ic_pause) + } else { + binding.artistPlay.setImageResource(R.drawable.ic_play) + } + + binding.artistPlay.setOnClickListener { + playbackModel.invertPlayingStatus() + } + } else { + binding.artistPlay.setImageResource(R.drawable.ic_play) + + binding.artistPlay.setOnClickListener { + playbackModel.play(detailModel.currentArtist.value!!, false) + } + } + } + } + override fun onResume() { super.onResume() diff --git a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt index 587af7192..88f7ca594 100644 --- a/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/detail/GenreDetailFragment.kt @@ -9,9 +9,12 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs +import org.oxycblt.auxio.R import org.oxycblt.auxio.databinding.FragmentGenreDetailBinding import org.oxycblt.auxio.detail.adapters.DetailArtistAdapter import org.oxycblt.auxio.music.MusicStore +import org.oxycblt.auxio.playback.PlaybackMode +import org.oxycblt.auxio.playback.PlaybackViewModel import org.oxycblt.auxio.theme.applyDivider import org.oxycblt.auxio.theme.disable @@ -19,6 +22,7 @@ class GenreDetailFragment : Fragment() { private val args: GenreDetailFragmentArgs by navArgs() private val detailModel: DetailViewModel by activityViewModels() + private val playbackModel: PlaybackViewModel by activityViewModels() override fun onCreateView( inflater: LayoutInflater, @@ -53,6 +57,7 @@ class GenreDetailFragment : Fragment() { binding.lifecycleOwner = this binding.detailModel = detailModel + binding.playbackModel = playbackModel binding.genre = detailModel.currentGenre.value binding.genreToolbar.setNavigationOnClickListener { @@ -84,6 +89,14 @@ class GenreDetailFragment : Fragment() { ) } + playbackModel.currentMode.observe(viewLifecycleOwner) { + updatePlayButton(it, binding) + } + + playbackModel.isPlaying.observe(viewLifecycleOwner) { + updatePlayButton(playbackModel.currentMode.value!!, binding) + } + Log.d(this::class.simpleName, "Fragment created.") return binding.root @@ -94,4 +107,27 @@ class GenreDetailFragment : Fragment() { detailModel.updateNavigationStatus(false) } + + private fun updatePlayButton(mode: PlaybackMode, binding: FragmentGenreDetailBinding) { + if (mode == PlaybackMode.IN_GENRE && + detailModel.currentGenre.value == playbackModel.currentGenre.value + ) { + Log.d(this::class.simpleName, "Retard") + if (playbackModel.isPlaying.value!!) { + binding.genrePlay.setImageResource(R.drawable.ic_pause) + } else { + binding.genrePlay.setImageResource(R.drawable.ic_play) + } + + binding.genrePlay.setOnClickListener { + playbackModel.invertPlayingStatus() + } + } else { + binding.genrePlay.setImageResource(R.drawable.ic_play) + + binding.genrePlay.setOnClickListener { + playbackModel.play(detailModel.currentGenre.value!!, false) + } + } + } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt index 628444d4c..902cd3179 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/CompactPlaybackFragment.kt @@ -25,6 +25,7 @@ class CompactPlaybackFragment : Fragment() { ): View? { val binding = FragmentCompactPlaybackBinding.inflate(inflater) + // FIXME: Stop these icons from self-animating on creation. val iconPauseToPlay = ContextCompat.getDrawable( requireContext(), R.drawable.ic_pause_to_play ) as AnimatedVectorDrawable @@ -41,7 +42,6 @@ class CompactPlaybackFragment : Fragment() { // as for some reason the attach event doesn't register anymore w/LiveData binding.song = MusicStore.getInstance().songs[0] binding.playbackModel = playbackModel - binding.root.visibility = View.GONE binding.root.setOnClickListener { findNavController().navigate( @@ -51,18 +51,12 @@ class CompactPlaybackFragment : Fragment() { // --- VIEWMODEL SETUP --- - // TODO: Add some kind of animation to when this view becomes visible/invisible. playbackModel.currentSong.observe(viewLifecycleOwner) { - if (it == null) { - Log.d(this::class.simpleName, "Hiding playback bar due to no song being played.") - - binding.root.visibility = View.GONE - } else { + if (it != null) { Log.d(this::class.simpleName, "Updating song display to ${it.name}") binding.song = it binding.playbackProgress.max = it.seconds.toInt() - binding.root.visibility = View.VISIBLE } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt index 44f3269b7..27e77ea49 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt @@ -37,9 +37,6 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener { val accentColor = ColorStateList.valueOf(accent.first.toColor(requireContext())) val controlColor = ColorStateList.valueOf(R.color.control_color.toColor(requireContext())) val normalTextColor = binding.playbackDurationCurrent.currentTextColor - val disabledColor = ColorStateList.valueOf( - R.color.inactive_color.toColor(requireContext()) - ) val iconPauseToPlay = ContextCompat.getDrawable( requireContext(), R.drawable.ic_pause_to_play diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt index 589688ff8..46982395a 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackViewModel.kt @@ -21,6 +21,9 @@ class PlaybackViewModel : ViewModel() { private val mCurrentSong = MutableLiveData() val currentSong: LiveData get() = mCurrentSong + private val mCurrentGenre = MutableLiveData() + val currentGenre: LiveData get() = mCurrentGenre + private val mQueue = MutableLiveData(mutableListOf()) val queue: LiveData> get() = mQueue @@ -67,7 +70,7 @@ class PlaybackViewModel : ViewModel() { Log.d( this::class.simpleName, "update() was called with IN_GENRES, using " + - "most prominent genre instead of the song's genre." + "most prominent genre instead of the song's genre." ) song.album.artist.genres[0].songs @@ -109,6 +112,7 @@ class PlaybackViewModel : ViewModel() { updatePlayback(songs[0]) + mCurrentGenre.value = genre mQueue.value = songs mCurrentIndex.value = 0 mCurrentMode.value = PlaybackMode.IN_GENRE @@ -141,7 +145,7 @@ class PlaybackViewModel : ViewModel() { private fun orderSongsInGenre(genre: Genre): MutableList { val final = mutableListOf() - genre.artists.sortedBy { it.name }.forEach { artist -> + genre.artists.sortedByDescending { it.name }.forEach { artist -> artist.albums.sortedByDescending { it.year }.forEach { album -> final.addAll(album.songs.sortedBy { it.track }) } diff --git a/app/src/main/res/drawable/ic_pause.xml b/app/src/main/res/drawable/ic_pause.xml index 39eb975ac..c24a9a423 100644 --- a/app/src/main/res/drawable/ic_pause.xml +++ b/app/src/main/res/drawable/ic_pause.xml @@ -5,20 +5,7 @@ android:viewportWidth="24" android:viewportHeight="24" android:tint="@color/background"> - - - - - - - + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_artist_detail.xml b/app/src/main/res/layout/fragment_artist_detail.xml index 1761fc784..f07559831 100644 --- a/app/src/main/res/layout/fragment_artist_detail.xml +++ b/app/src/main/res/layout/fragment_artist_detail.xml @@ -13,6 +13,10 @@ + + + + + + + +