music: improve field management

Cache some music fields and make other fields more coherent given
recent changes.
This commit is contained in:
OxygenCobalt 2022-08-09 08:57:24 -06:00
parent 75e80a7253
commit bcc16fb88c
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
5 changed files with 23 additions and 25 deletions

View file

@ -241,10 +241,6 @@ class DetailViewModel(application: Application) :
val byReleaseGroup =
albums.groupBy {
if (it.releaseType == null) {
return@groupBy R.string.lbl_albums
}
when (it.releaseType.refinement) {
ReleaseType.Refinement.LIVE -> R.string.lbl_live_group
ReleaseType.Refinement.REMIX -> R.string.lbl_remix_group

View file

@ -115,8 +115,7 @@ private class AlbumDetailViewHolder private constructor(private val binding: Ite
override fun bind(item: Album, listener: AlbumDetailAdapter.Listener) {
binding.detailCover.bind(item)
binding.detailType.text =
binding.context.getString(item.releaseType?.stringRes ?: R.string.lbl_album)
binding.detailType.text = binding.context.getString(item.releaseType.stringRes)
binding.detailName.text = item.resolveName(binding.context)

View file

@ -123,8 +123,7 @@ data class Song(
override fun resolveName(context: Context) = rawName
/** The duration of this song, in seconds (rounded down) */
val durationSecs: Long
get() = durationMs / 1000
val durationSecs = durationMs / 1000
private var _album: Album? = null
/** The album of this song. */
@ -202,11 +201,8 @@ data class Album(
override val rawSortName: String?,
/** The date this album was released. */
val date: Date?,
/**
* The type of release this album represents. Null if release types were not applicable to this
* library.
*/
val releaseType: ReleaseType?,
/** The type of release this album has. */
val releaseType: ReleaseType,
/** The URI for the cover image corresponding to this album. */
val coverUri: Uri,
/** The songs of this album. */
@ -237,6 +233,9 @@ data class Album(
val artist: Artist
get() = unlikelyToBeNull(_artist)
/** The earliest date a song in this album was added. */
val dateAdded = songs.minOf { it.dateAdded }
/** Internal field. Do not use. */
val _artistGroupingId: Long
get() = _artistGroupingName.toMusicId()
@ -437,6 +436,15 @@ class Date private constructor(private val tokens: List<Int>) : Comparable<Date>
}
}
/**
* Represents the type of release a particular album is.
*
* This can be used to differentiate between album sub-types like Singles, EPs, Compilations, and
* others. Internally, it operates on a reduced version of the MusicBrainz release type
* specification. It can be extended if there is demand.
*
* @author OxygenCobalt
*/
sealed class ReleaseType {
abstract val refinement: Refinement?
abstract val stringRes: Int
@ -495,6 +503,11 @@ sealed class ReleaseType {
get() = R.string.lbl_mixtape
}
/**
* Roughly analogous to the MusicBrainz "live" and "remix" secondary types. Unlike the main
* types, these only modify an existing, primary type. They are not implemented for secondary
* types, however they may be expanded to compilations in the future.
*/
enum class Refinement {
LIVE,
REMIX

View file

@ -296,13 +296,6 @@ class Indexer {
val albums = mutableListOf<Album>()
val songsByAlbum = songs.groupBy { it._albumGroupingId }
// If album types aren't used by the music library (Represented by all songs having
// no album type), there is no point in displaying them.
val enableAlbumTypes = songs.any { it._albumReleaseType != null }
if (!enableAlbumTypes) {
logD("No distinct album types detected, ignoring them")
}
for (entry in songsByAlbum) {
val albumSongs = entry.value
@ -317,10 +310,7 @@ class Indexer {
rawName = templateSong._albumName,
rawSortName = templateSong._albumSortName,
date = templateSong._date,
releaseType =
if (enableAlbumTypes)
(templateSong._albumReleaseType ?: ReleaseType.Album(null))
else null,
releaseType = templateSong._albumReleaseType ?: ReleaseType.Album(null),
coverUri = templateSong._albumCoverUri,
songs = entry.value,
_artistGroupingName = templateSong._artistGroupingName,

View file

@ -350,7 +350,7 @@ data class Sort(val mode: Mode, val isAscending: Boolean) {
}
private class BasicComparator<T : Music> private constructor() : Comparator<T> {
// TODO: Use Collator for sorting?
// TODO: Perhaps I should leverage collator?
override fun compare(a: T, b: T): Int {
val aSortName = a.sortName