util: fix number issues
Fix issues where invalid durations and years would not be aliased to readable values.
This commit is contained in:
parent
e099d1c38c
commit
13730c303c
8 changed files with 55 additions and 20 deletions
|
@ -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
|
||||
|
|
|
@ -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 -> ""
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 ---
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ---
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue