util: fix number issues

Fix issues where invalid durations and years would not be aliased to
readable values.
This commit is contained in:
OxygenCobalt 2022-01-08 08:59:11 -07:00
parent e099d1c38c
commit 13730c303c
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
8 changed files with 55 additions and 20 deletions

View file

@ -31,6 +31,7 @@ import org.oxycblt.auxio.music.ActionHeader
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.BaseModel
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.toDate
import org.oxycblt.auxio.playback.PlaybackViewModel
import org.oxycblt.auxio.ui.ActionHeaderViewHolder
import org.oxycblt.auxio.ui.BaseViewHolder
@ -154,7 +155,7 @@ class AlbumDetailAdapter(
binding.detailInfo.text = binding.detailInfo.context.getString(
R.string.fmt_three,
data.year.toString(),
data.year.toDate(binding.detailInfo.context),
binding.detailInfo.context.getPlural(
R.plurals.fmt_song_count,
data.songs.size

View file

@ -26,6 +26,7 @@ import androidx.navigation.fragment.findNavController
import org.oxycblt.auxio.R
import org.oxycblt.auxio.home.HomeFragmentDirections
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.toDate
import org.oxycblt.auxio.ui.AlbumViewHolder
import org.oxycblt.auxio.ui.DisplayMode
import org.oxycblt.auxio.ui.Sort
@ -73,7 +74,7 @@ class AlbumListFragment : HomeListFragment() {
.first().uppercase()
// Year -> Use Full Year
is Sort.ByYear -> album.year.toString()
is Sort.ByYear -> album.year.toDate(requireContext())
// Unsupported sort, error gracefully
else -> ""

View file

@ -24,6 +24,7 @@ import android.view.View
import android.view.ViewGroup
import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.music.toDate
import org.oxycblt.auxio.ui.DisplayMode
import org.oxycblt.auxio.ui.SongViewHolder
import org.oxycblt.auxio.ui.Sort
@ -74,7 +75,7 @@ class SongListFragment : HomeListFragment() {
.first().uppercase()
// Year -> Use Full Year
is Sort.ByYear -> song.album.year.toString()
is Sort.ByYear -> song.album.year.toDate(requireContext())
}
}

View file

@ -84,7 +84,7 @@ data class Song(
val album: Album get() = requireNotNull(mAlbum)
val seconds: Long get() = duration / 1000
val formattedDuration: String get() = (duration / 1000).toDuration()
val formattedDuration: String get() = (duration / 1000).toDuration(false)
override val hash: Long get() {
var result = name.hashCode().toLong()
@ -129,7 +129,7 @@ data class Album(
val artist: Artist get() = requireNotNull(mArtist)
val totalDuration: String get() =
songs.sumOf { it.seconds }.toDuration()
songs.sumOf { it.seconds }.toDuration(false)
fun linkArtist(artist: Artist) {
mArtist = artist
@ -190,7 +190,7 @@ data class Genre(
val songs: List<Song> get() = mSongs
val totalDuration: String get() =
songs.sumOf { it.seconds }.toDuration()
songs.sumOf { it.seconds }.toDuration(false)
fun linkSong(song: Song) {
mSongs.add(song)

View file

@ -19,6 +19,7 @@
package org.oxycblt.auxio.music
import android.content.ContentUris
import android.content.Context
import android.net.Uri
import android.provider.MediaStore
import android.text.format.DateUtils
@ -109,8 +110,14 @@ fun Long.toAlbumArtURI(): Uri {
/**
* Convert a [Long] of seconds into a string duration.
* @param isElapsed Whether this duration is represents elapsed time. If this is false, then
* --:-- will be returned if the second value is 0.
*/
fun Long.toDuration(): String {
fun Long.toDuration(isElapsed: Boolean): String {
if (!isElapsed && this == 0L) {
return "--:--"
}
var durationString = DateUtils.formatElapsedTime(this)
// If the duration begins with a excess zero [e.g 01:42], then cut it off.
@ -121,6 +128,14 @@ fun Long.toDuration(): String {
return durationString
}
fun Int.toDate(context: Context): String {
return if (this == 0) {
context.getString(R.string.def_date)
} else {
toString()
}
}
// --- BINDING ADAPTERS ---
/**

View file

@ -29,7 +29,6 @@ import org.oxycblt.auxio.databinding.ViewSeekBarBinding
import org.oxycblt.auxio.music.toDuration
import org.oxycblt.auxio.util.inflater
import org.oxycblt.auxio.util.resolveAttr
import kotlin.math.max
/**
* A custom view that bundles together a seekbar with a current duration and a total duration.
@ -63,13 +62,29 @@ class PlaybackSeekBar @JvmOverloads constructor(
// Don't update the progress while we are seeking, that will make the SeekBar jump around.
if (!isSeeking) {
binding.seekBar.value = seconds.toFloat()
binding.playbackDurationCurrent.text = seconds.toDuration()
binding.playbackDurationCurrent.text = seconds.toDuration(true)
}
}
fun setDuration(seconds: Long) {
binding.seekBar.valueTo = max(seconds.toFloat(), 1f)
binding.playbackSongDuration.text = seconds.toDuration()
if (seconds == 0L) {
// One of two things occured:
// - Android couldn't get the total duration of the song
// - The duration of the song was so low as to be rounded to zero when converted
// to seconds.
// In either of these cases, the seekbar is more or less useless. Disable it.
binding.seekBar.apply {
valueTo = 1f
isEnabled = false
}
} else {
binding.seekBar.apply {
valueTo = seconds.toFloat()
isEnabled = true
}
}
binding.playbackSongDuration.text = seconds.toDuration(false)
}
override fun onStartTrackingTouch(slider: Slider) {
@ -85,7 +100,7 @@ class PlaybackSeekBar @JvmOverloads constructor(
if (fromUser) {
// Don't actually seek yet when the user moves the progress bar, as to make our
// player seek during every movement is both inefficient and weird.
binding.playbackDurationCurrent.text = value.toLong().toDuration()
binding.playbackDurationCurrent.text = value.toLong().toDuration(true)
}
}
}

View file

@ -333,14 +333,14 @@ class PlaybackViewModel : ViewModel(), PlaybackStateManager.Callback {
private fun restorePlaybackState() {
logD("Attempting to restore playback state.")
mSong.value = playbackManager.song
mPosition.value = playbackManager.position / 1000
mParent.value = playbackManager.parent
mNextUp.value = playbackManager.queue
mMode.value = playbackManager.playbackMode
mIsPlaying.value = playbackManager.isPlaying
mIsShuffling.value = playbackManager.isShuffling
mLoopMode.value = playbackManager.loopMode
onSongUpdate(playbackManager.song)
onPositionUpdate(playbackManager.position)
onParentUpdate(playbackManager.parent)
onQueueUpdate(playbackManager.queue, playbackManager.index)
onModeUpdate(playbackManager.playbackMode)
onPlayingUpdate(playbackManager.isPlaying)
onShuffleUpdate(playbackManager.isShuffling)
onLoopUpdate(playbackManager.loopMode)
}
// --- OVERRIDES ---

View file

@ -99,6 +99,8 @@ class PlaybackStateManager private constructor() {
val position: Long get() = mPosition
/** The current queue determined by [parent] and [playbackMode] */
val queue: List<Song> get() = mQueue
/** The current position in the queue */
val index: Int get() = mIndex
/** The current [PlaybackMode] */
val playbackMode: PlaybackMode get() = mPlaybackMode
/** Whether playback is paused or not */