Improve Progress Bars on Playback Fragments

Change the Progress Bars on PlaybackFragment/CompactFragment to reflect the total seconds in a song, instead of the percentage of completion.
This commit is contained in:
OxygenCobalt 2020-10-12 19:36:32 -06:00
parent 3bafc17d0c
commit a72ab10007
9 changed files with 30 additions and 32 deletions

View file

@ -135,13 +135,15 @@ class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
// Update the adapter with the new data
libraryAdapter.updateData(
when (libraryModel.showMode.value) {
ShowMode.SHOW_GENRES -> mode.getSortedGenreList(musicModel.genres.value!!)
ShowMode.SHOW_ARTISTS -> mode.getSortedArtistList(musicModel.artists.value!!)
ShowMode.SHOW_ALBUMS -> mode.getSortedAlbumList(musicModel.albums.value!!)
mode.getSortedBaseModelList(
when (libraryModel.showMode.value) {
ShowMode.SHOW_GENRES -> musicModel.genres.value!!
ShowMode.SHOW_ARTISTS -> musicModel.artists.value!!
ShowMode.SHOW_ALBUMS -> musicModel.albums.value!!
else -> mode.getSortedArtistList(musicModel.artists.value!!)
}
else -> musicModel.artists.value!!
}
)
)
// Then update the menu item in the toolbar to reflect the new mode

View file

@ -56,14 +56,14 @@ class LoadingFragment : Fragment(R.layout.fragment_loading) {
LoadingFragmentDirections.actionToMain()
)
} else {
// If the response wasn't a success, then show the specific error message
// depending on which error response was given, along with a retry button
binding.loadingErrorText.text =
if (it == MusicLoaderResponse.NO_MUSIC)
getString(R.string.error_no_music)
else
getString(R.string.error_music_load_failed)
// If the response wasn't a success, then show the specific error message
// depending on which error response was given, along with a retry button
showError(binding)
binding.loadingRetryButton.visibility = View.VISIBLE
}

View file

@ -4,7 +4,7 @@ import android.net.Uri
// --- MUSIC MODELS ---
// TODO: Remove parent/child references so that they can be parcelable [Would require genre rework]
// TODO: Dont determine artist/album/song counts on the fly [If possible]
// TODO: Don't determine artist/album/song counts on the fly [If possible]
// The base model for all music
// This is used in a lot of general functions in order to cut down on code
@ -99,5 +99,5 @@ data class Genre(
// Header [Used for search, nothing else]
data class Header(
override val id: Long = -1,
override var name: String = ""
override var name: String = "",
) : BaseModel()

View file

@ -12,7 +12,7 @@ import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
// Get the cover art for a song or album
// Get the cover art for a song
@BindingAdapter("coverArt")
fun ImageView.bindCoverArt(song: Song) {
val request = getDefaultRequest(context, this)
@ -23,6 +23,7 @@ fun ImageView.bindCoverArt(song: Song) {
Coil.imageLoader(context).enqueue(request)
}
// Get the cover art for an album
@BindingAdapter("coverArt")
fun ImageView.bindCoverArt(album: Album) {
val request = getDefaultRequest(context, this)
@ -38,7 +39,7 @@ fun ImageView.bindCoverArt(album: Album) {
fun ImageView.bindArtistImage(artist: Artist) {
val request: ImageRequest
// If there are more than one albums, then create a mosaic of them.
// If there is more than one album, then create a mosaic of them.
if (artist.numAlbums >= 4) {
val uris = mutableListOf<Uri>()
@ -114,7 +115,7 @@ fun ImageView.bindGenreImage(genre: Genre) {
Coil.imageLoader(context).enqueue(request)
}
// Get the base request used across the app.
// Get the base request used across the other functions.
private fun getDefaultRequest(context: Context, imageView: ImageView): ImageRequest.Builder {
return ImageRequest.Builder(context)
.crossfade(true)

View file

@ -14,6 +14,7 @@ import org.oxycblt.auxio.MainFragmentDirections
import org.oxycblt.auxio.R
import org.oxycblt.auxio.databinding.FragmentCompactPlaybackBinding
import org.oxycblt.auxio.music.MusicViewModel
import kotlin.time.seconds
class CompactPlaybackFragment : Fragment() {
private val musicModel: MusicViewModel by activityViewModels {
@ -65,7 +66,7 @@ class CompactPlaybackFragment : Fragment() {
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
}
}
@ -81,6 +82,10 @@ class CompactPlaybackFragment : Fragment() {
}
}
playbackModel.formattedSeekBarProgress.observe(viewLifecycleOwner) {
binding.playbackProgress.progress = it
}
Log.d(this::class.simpleName, "Fragment Created")
return binding.root

View file

@ -59,6 +59,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener {
playbackModel.currentSong.observe(viewLifecycleOwner) {
binding.song = it
binding.playbackSeekBar.max = it.seconds.toInt()
}
playbackModel.isPlaying.observe(viewLifecycleOwner) {

View file

@ -24,16 +24,18 @@ class PlaybackViewModel : ViewModel() {
private val mIsSeeking = MutableLiveData(false)
val isSeeking: LiveData<Boolean> get() = mIsSeeking
// Formatted variants of the duration
val formattedCurrentDuration = Transformations.map(currentDuration) {
it.toDuration()
}
val formattedSeekBarProgress = Transformations.map(currentDuration) {
((it.toDouble() / mCurrentSong.value!!.seconds) * 100).toInt()
if (mCurrentSong.value != null) it.toInt() else 0
}
fun updateSong(song: Song) {
mCurrentSong.value = song
mCurrentDuration.value = 0
if (!mIsPlaying.value!!) {
mIsPlaying.value = true
@ -45,12 +47,13 @@ class PlaybackViewModel : ViewModel() {
mIsPlaying.value = !mIsPlaying.value!!
}
// Set the seeking status
fun setSeekingStatus(status: Boolean) {
mIsSeeking.value = status
}
// Update the current duration using a SeekBar progress
fun updateCurrentDurationWithProgress(progress: Int) {
mCurrentDuration.value =
((progress.toDouble() / 100) * mCurrentSong.value!!.seconds).toLong()
mCurrentDuration.value = progress.toLong()
}
}

View file

@ -1,5 +1,6 @@
package org.oxycblt.auxio.recycler
// TODO: Swap these temp values for actual constants
enum class ShowMode(val constant: Long) {
SHOW_GENRES(0), SHOW_ARTISTS(1), SHOW_ALBUMS(2), SHOW_SONGS(3);

View file

@ -4,7 +4,6 @@ import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Song
// Sorting modes
@ -16,20 +15,6 @@ enum class SortMode(val iconRes: Int) {
NUMERIC_UP(R.drawable.ic_sort_numeric_up),
NUMERIC_DOWN(R.drawable.ic_sort_numeric_down);
fun getSortedGenreList(list: List<Genre>): List<Genre> {
return when (this) {
ALPHA_UP -> list.sortedWith(
compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name }
)
ALPHA_DOWN -> list.sortedWith(
compareBy(String.CASE_INSENSITIVE_ORDER) { it.name }
)
else -> list
}
}
fun getSortedArtistList(list: List<Artist>): List<Artist> {
return when (this) {
ALPHA_UP -> list.sortedWith(