Move genre name code to genre objects
Instead of converting int-genres to normal genres during the music loader process, instead do it in the Genre object as a lazy initializer, so that the names remain [Probably] unique.
This commit is contained in:
parent
940746f248
commit
600aa2d6f1
9 changed files with 51 additions and 57 deletions
|
@ -160,9 +160,22 @@ class LibraryViewModel : ViewModel(), SettingsManager.Callback {
|
||||||
/**
|
/**
|
||||||
* Shortcut function for updating the library data with the current [SortMode]/[DisplayMode]
|
* Shortcut function for updating the library data with the current [SortMode]/[DisplayMode]
|
||||||
*/
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun updateLibraryData() {
|
private fun updateLibraryData() {
|
||||||
mLibraryData.value = mSortMode.value!!.getSortedBaseModelList(
|
mLibraryData.value = when (mDisplayMode) {
|
||||||
musicStore.getListForDisplayMode(mDisplayMode)
|
DisplayMode.SHOW_GENRES -> {
|
||||||
)
|
mSortMode.value!!.getSortedGenreList(musicStore.genres)
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayMode.SHOW_ARTISTS -> {
|
||||||
|
mSortMode.value!!.getSortedBaseModelList(musicStore.artists)
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayMode.SHOW_ALBUMS -> {
|
||||||
|
mSortMode.value!!.getSortedAlbumList(musicStore.albums)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> error("Unsupported Library DisplayMode $mDisplayMode")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ sealed class BaseModel {
|
||||||
*/
|
*/
|
||||||
data class Song(
|
data class Song(
|
||||||
override val id: Long = -1,
|
override val id: Long = -1,
|
||||||
override var name: String,
|
override val name: String,
|
||||||
val albumId: Long = -1,
|
val albumId: Long = -1,
|
||||||
val track: Int = -1,
|
val track: Int = -1,
|
||||||
val duration: Long = 0,
|
val duration: Long = 0,
|
||||||
|
@ -48,8 +48,6 @@ data class Song(
|
||||||
}
|
}
|
||||||
|
|
||||||
fun applyGenre(genre: Genre) {
|
fun applyGenre(genre: Genre) {
|
||||||
check(mGenre == null) { "Genre is already applied" }
|
|
||||||
|
|
||||||
mGenre = genre
|
mGenre = genre
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,7 +121,7 @@ data class Album(
|
||||||
*/
|
*/
|
||||||
data class Artist(
|
data class Artist(
|
||||||
override val id: Long = -1,
|
override val id: Long = -1,
|
||||||
override var name: String,
|
override val name: String,
|
||||||
val albums: List<Album>
|
val albums: List<Album>
|
||||||
) : BaseModel() {
|
) : BaseModel() {
|
||||||
init {
|
init {
|
||||||
|
@ -152,15 +150,24 @@ data class Artist(
|
||||||
/**
|
/**
|
||||||
* The data object for a genre. Inherits [BaseModel]
|
* The data object for a genre. Inherits [BaseModel]
|
||||||
* @property songs The list of all [Song]s in this genre.
|
* @property songs The list of all [Song]s in this genre.
|
||||||
|
* @property displayName A name that can be displayed without it showing up as an integer. ***USE THIS INSTEAD OF [name]!!!!***
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
data class Genre(
|
data class Genre(
|
||||||
override val id: Long = -1,
|
override val id: Long = -1,
|
||||||
override var name: String,
|
override val name: String,
|
||||||
) : BaseModel() {
|
) : BaseModel() {
|
||||||
private val mSongs = mutableListOf<Song>()
|
private val mSongs = mutableListOf<Song>()
|
||||||
val songs: List<Song> get() = mSongs
|
val songs: List<Song> get() = mSongs
|
||||||
|
|
||||||
|
val displayName: String by lazy {
|
||||||
|
if (name.contains(Regex("[0123456789)]"))) {
|
||||||
|
name.toNamedGenre() ?: name
|
||||||
|
} else {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val totalDuration: String by lazy {
|
val totalDuration: String by lazy {
|
||||||
var seconds: Long = 0
|
var seconds: Long = 0
|
||||||
songs.forEach {
|
songs.forEach {
|
||||||
|
@ -182,6 +189,6 @@ data class Genre(
|
||||||
*/
|
*/
|
||||||
data class Header(
|
data class Header(
|
||||||
override val id: Long = -1,
|
override val id: Long = -1,
|
||||||
override var name: String = "",
|
override val name: String = "",
|
||||||
val isAction: Boolean = false
|
val isAction: Boolean = false
|
||||||
) : BaseModel()
|
) : BaseModel()
|
||||||
|
|
|
@ -6,7 +6,6 @@ import kotlinx.coroutines.withContext
|
||||||
import org.oxycblt.auxio.logD
|
import org.oxycblt.auxio.logD
|
||||||
import org.oxycblt.auxio.music.processing.MusicLoader
|
import org.oxycblt.auxio.music.processing.MusicLoader
|
||||||
import org.oxycblt.auxio.music.processing.MusicSorter
|
import org.oxycblt.auxio.music.processing.MusicSorter
|
||||||
import org.oxycblt.auxio.recycler.DisplayMode
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main storage for music items. Use [MusicStore.getInstance] to get the single instance of it.
|
* The main storage for music items. Use [MusicStore.getInstance] to get the single instance of it.
|
||||||
|
@ -27,11 +26,11 @@ class MusicStore private constructor() {
|
||||||
|
|
||||||
/** All parent models (ex Albums, Artists) loaded by Auxio */
|
/** All parent models (ex Albums, Artists) loaded by Auxio */
|
||||||
val parents: MutableList<BaseModel> by lazy {
|
val parents: MutableList<BaseModel> by lazy {
|
||||||
val parents = mutableListOf<BaseModel>()
|
mutableListOf<BaseModel>().apply {
|
||||||
parents.addAll(mGenres)
|
addAll(mGenres)
|
||||||
parents.addAll(mArtists)
|
addAll(mArtists)
|
||||||
parents.addAll(mAlbums)
|
addAll(mAlbums)
|
||||||
parents
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var loaded = false
|
var loaded = false
|
||||||
|
@ -73,20 +72,6 @@ class MusicStore private constructor() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a list of data for a [DisplayMode].
|
|
||||||
* @param displayMode The [DisplayMode] given
|
|
||||||
* @return A list of [BaseModel]s for that [DisplayMode]
|
|
||||||
*/
|
|
||||||
fun getListForDisplayMode(displayMode: DisplayMode): List<BaseModel> {
|
|
||||||
return when (displayMode) {
|
|
||||||
DisplayMode.SHOW_GENRES -> mGenres
|
|
||||||
DisplayMode.SHOW_ARTISTS -> mArtists
|
|
||||||
DisplayMode.SHOW_ALBUMS -> mAlbums
|
|
||||||
DisplayMode.SHOW_SONGS -> mSongs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@Volatile
|
@Volatile
|
||||||
private var INSTANCE: MusicStore? = null
|
private var INSTANCE: MusicStore? = null
|
||||||
|
|
|
@ -110,7 +110,7 @@ fun Int.toYear(context: Context): String {
|
||||||
*/
|
*/
|
||||||
@BindingAdapter("artistGenre")
|
@BindingAdapter("artistGenre")
|
||||||
fun TextView.bindArtistGenre(artist: Artist) {
|
fun TextView.bindArtistGenre(artist: Artist) {
|
||||||
text = artist.genre?.name ?: context.getString(R.string.placeholder_genre)
|
text = artist.genre?.displayName ?: context.getString(R.string.placeholder_genre)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -14,7 +14,6 @@ import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Genre
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.music.toAlbumArtURI
|
import org.oxycblt.auxio.music.toAlbumArtURI
|
||||||
import org.oxycblt.auxio.music.toNamedGenre
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class that loads/constructs [Genre]s, [Album]s, and [Song] objects from the filesystem
|
* Class that loads/constructs [Genre]s, [Album]s, and [Song] objects from the filesystem
|
||||||
|
@ -69,19 +68,9 @@ class MusicLoader(private val app: Application) {
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
val id = cursor.getLong(idIndex)
|
val id = cursor.getLong(idIndex)
|
||||||
var name = cursor.getStringOrNull(nameIndex) ?: genrePlaceholder
|
val name = cursor.getStringOrNull(nameIndex) ?: genrePlaceholder
|
||||||
|
|
||||||
// If a genre is still in an old int-based format [Android formats it as "(INT)"],
|
genres.add(Genre(id, name))
|
||||||
// convert that to the corresponding ID3 genre.
|
|
||||||
if (name.contains(Regex("[0123456789)]"))) {
|
|
||||||
name = name.toNamedGenre() ?: genrePlaceholder
|
|
||||||
}
|
|
||||||
|
|
||||||
genres.add(
|
|
||||||
Genre(
|
|
||||||
id, name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
@ -207,9 +196,9 @@ class MusicLoader(private val app: Application) {
|
||||||
val idIndex = cursor.getColumnIndexOrThrow(Genres.Members._ID)
|
val idIndex = cursor.getColumnIndexOrThrow(Genres.Members._ID)
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
val id = cursor.getLong(idIndex)
|
val songId = cursor.getLong(idIndex)
|
||||||
|
|
||||||
songs.find { it.id == id }?.let {
|
songs.find { it.id == songId }?.let {
|
||||||
genre.addSong(it)
|
genre.addSong(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,8 @@ import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.IdRes
|
import androidx.annotation.IdRes
|
||||||
import org.oxycblt.auxio.R
|
import org.oxycblt.auxio.R
|
||||||
import org.oxycblt.auxio.music.Album
|
import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
|
||||||
import org.oxycblt.auxio.music.BaseModel
|
import org.oxycblt.auxio.music.BaseModel
|
||||||
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,21 +23,21 @@ enum class SortMode(@DrawableRes val iconRes: Int) {
|
||||||
NUMERIC_DOWN(R.drawable.ic_sort_numeric_down);
|
NUMERIC_DOWN(R.drawable.ic_sort_numeric_down);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a sorted list of artists for a SortMode. Only supports alphabetic sorting.
|
* Get a sorted list of genres for a SortMode. Only supports alphabetic sorting.
|
||||||
* @param artists An unsorted list of artists.
|
* @param genres An unsorted list of artists.
|
||||||
* @return The sorted list of artists.
|
* @return The sorted list of artists.
|
||||||
*/
|
*/
|
||||||
fun getSortedArtistList(artists: List<Artist>): List<Artist> {
|
fun getSortedGenreList(genres: List<Genre>): List<Genre> {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
ALPHA_UP -> artists.sortedWith(
|
ALPHA_UP -> genres.sortedWith(
|
||||||
compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.name }
|
compareByDescending(String.CASE_INSENSITIVE_ORDER) { it.displayName }
|
||||||
)
|
)
|
||||||
|
|
||||||
ALPHA_DOWN -> artists.sortedWith(
|
ALPHA_DOWN -> genres.sortedWith(
|
||||||
compareBy(String.CASE_INSENSITIVE_ORDER) { it.name }
|
compareBy(String.CASE_INSENSITIVE_ORDER) { it.displayName }
|
||||||
)
|
)
|
||||||
|
|
||||||
else -> artists
|
else -> genres
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="@dimen/margin_medium"
|
android:layout_marginStart="@dimen/margin_medium"
|
||||||
android:layout_marginEnd="@dimen/margin_medium"
|
android:layout_marginEnd="@dimen/margin_medium"
|
||||||
android:text="@{genre.name}"
|
android:text="@{genre.displayName}"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/genre_song_count"
|
app:layout_constraintBottom_toTopOf="@+id/genre_song_count"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
android:layout_marginStart="@dimen/margin_medium"
|
android:layout_marginStart="@dimen/margin_medium"
|
||||||
android:layout_marginTop="@dimen/margin_medium"
|
android:layout_marginTop="@dimen/margin_medium"
|
||||||
android:layout_marginEnd="@dimen/margin_medium"
|
android:layout_marginEnd="@dimen/margin_medium"
|
||||||
android:text="@{genre.name}"
|
android:text="@{genre.displayName}"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/genre_name"
|
android:id="@+id/genre_name"
|
||||||
style="@style/ItemText.Primary"
|
style="@style/ItemText.Primary"
|
||||||
android:text="@{genre.name}"
|
android:text="@{genre.displayName}"
|
||||||
app:layout_constraintBottom_toTopOf="@+id/genre_count"
|
app:layout_constraintBottom_toTopOf="@+id/genre_count"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toEndOf="@+id/genre_image"
|
app:layout_constraintStart_toEndOf="@+id/genre_image"
|
||||||
|
|
Loading…
Reference in a new issue