From 736e335ccfff227da9e0cf4780adc1e6820102d3 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Mon, 31 Aug 2020 16:10:32 -0600 Subject: [PATCH] Add Genre sorting & better placeholders * Add Genre sorting to MusicSorter. * Revamp placeholders so that theyre assigned when loading instead of using a BindingAdapter. --- .../oxycblt/auxio/music/MusicRepository.kt | 11 +++- .../org/oxycblt/auxio/music/MusicUtils.kt | 16 ----- .../org/oxycblt/auxio/music/models/Album.kt | 4 +- .../org/oxycblt/auxio/music/models/Artist.kt | 4 +- .../org/oxycblt/auxio/music/models/Genre.kt | 9 ++- .../org/oxycblt/auxio/music/models/Song.kt | 4 +- .../auxio/music/processing/MusicLoader.kt | 4 +- .../auxio/music/processing/MusicSorter.kt | 58 ++++++++++++++++++- .../auxio/recycler/adapters/AlbumAdapter.kt | 19 ------ .../auxio/recycler/adapters/SongAdapter.kt | 17 ------ app/src/main/res/layout/song_item.xml | 2 +- 11 files changed, 82 insertions(+), 66 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt index 374110cba..75c4aa6e7 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt @@ -2,8 +2,10 @@ package org.oxycblt.auxio.music import android.app.Application import android.util.Log +import org.oxycblt.auxio.R import org.oxycblt.auxio.music.models.Album import org.oxycblt.auxio.music.models.Artist +import org.oxycblt.auxio.music.models.Genre import org.oxycblt.auxio.music.models.Song import org.oxycblt.auxio.music.processing.MusicLoader import org.oxycblt.auxio.music.processing.MusicLoaderResponse @@ -12,6 +14,7 @@ import org.oxycblt.auxio.music.processing.MusicSorter // Storage for music data. class MusicRepository { + lateinit var genres: List lateinit var artists: List lateinit var albums: List lateinit var songs: List @@ -26,14 +29,20 @@ class MusicRepository { if (loader.response == MusicLoaderResponse.DONE) { // If the loading succeeds, then process the songs and set them. val sorter = MusicSorter( + loader.genres, loader.artists, loader.albums, - loader.songs + loader.songs, + + app.applicationContext.getString(R.string.label_unknown_genre), + app.applicationContext.getString(R.string.label_unknown_artist), + app.applicationContext.getString(R.string.label_unknown_album) ) songs = sorter.songs.toList() albums = sorter.albums.toList() artists = sorter.artists.toList() + genres = sorter.genres.toList() val elapsed = System.currentTimeMillis() - start diff --git a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt index be51c6eca..a59897fcc 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt @@ -92,19 +92,3 @@ fun TextView.getAlbumSongs(album: Album) { context.getString(R.string.format_multi_song_count, album.numSongs.toString()) } } - -@BindingAdapter("songInfo") -fun TextView.getSongInfo(song: Song) { - var artist = song.album.artist.name - var album = song.album.title - - if (artist == "") { - artist = context.getString(R.string.label_unknown_artist) - } - - if (album == "") { - album = context.getString(R.string.label_unknown_album) - } - - text = context.getString(R.string.format_song_info, artist, album) -} diff --git a/app/src/main/java/org/oxycblt/auxio/music/models/Album.kt b/app/src/main/java/org/oxycblt/auxio/music/models/Album.kt index 984337836..cd93caeb3 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/models/Album.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/models/Album.kt @@ -5,8 +5,8 @@ import android.net.Uri // Abstraction for Song data class Album( val id: Long = 0L, - val title: String = "", - val artistName: String = "", + var title: String = "", + val artistName: String = "", // Only used for sorting. Use artist for everything else. val coverUri: Uri = Uri.EMPTY, val year: Int = 0, var numSongs: Int = 0 diff --git a/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt b/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt index 41a56f1d0..308eec0e4 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/models/Artist.kt @@ -3,8 +3,8 @@ package org.oxycblt.auxio.music.models // Abstraction for mAlbums data class Artist( val id: Long = 0, - val name: String = "", - val genres: MutableList = mutableListOf("") + var name: String = "", + val genres: MutableList = mutableListOf(Genre()) ) { val albums = mutableListOf() var numAlbums = 0 diff --git a/app/src/main/java/org/oxycblt/auxio/music/models/Genre.kt b/app/src/main/java/org/oxycblt/auxio/music/models/Genre.kt index dc8f79bbf..dcbd66219 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/models/Genre.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/models/Genre.kt @@ -1,6 +1,9 @@ package org.oxycblt.auxio.music.models data class Genre( - val id: Long, - val name: String -) + val id: Long = 0, + var name: String = "", +) { + val artists = mutableListOf() + var numArtists = 0 +} diff --git a/app/src/main/java/org/oxycblt/auxio/music/models/Song.kt b/app/src/main/java/org/oxycblt/auxio/music/models/Song.kt index 28c553ccb..c0aaa8286 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/models/Song.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/models/Song.kt @@ -5,8 +5,8 @@ import android.text.format.DateUtils // Class containing all relevant values for a song. data class Song( val id: Long, - val title: String, - val albumName: String, + var title: String, + val albumName: String, // Only used for sorting. Use artist for everything else. val track: Int, val duration: Long ) { diff --git a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt index b010f218e..de7918844 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicLoader.kt @@ -130,12 +130,12 @@ class MusicLoader(private val resolver: ContentResolver) { val existingArtist = artists.find { it.name == name } if (existingArtist != null) { - existingArtist.genres.add(genre.name) + existingArtist.genres.add(genre) } else { artists.add( Artist( id, name, - mutableListOf(genre.name) + mutableListOf(genre) ) ) } diff --git a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt index 2e61f03f2..0cb378184 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/processing/MusicSorter.kt @@ -3,16 +3,25 @@ package org.oxycblt.auxio.music.processing import android.util.Log import org.oxycblt.auxio.music.models.Album import org.oxycblt.auxio.music.models.Artist +import org.oxycblt.auxio.music.models.Genre import org.oxycblt.auxio.music.models.Song class MusicSorter( + val genres: MutableList, val artists: MutableList, val albums: MutableList, - val songs: MutableList + val songs: MutableList, + + private val genrePlaceholder: String, + private val artistPlaceholder: String, + private val albumPlaceholder: String, ) { init { sortSongsIntoAlbums() sortAlbumsIntoArtists() + sortArtistsIntoGenres() + + addPlaceholders() } private fun sortSongsIntoAlbums() { @@ -88,10 +97,57 @@ class MusicSorter( unknownArtist.numAlbums = albums.size + artists.add(unknownArtist) + Log.d( this::class.simpleName, "${unknownAlbums.size} albums were placed into an unknown artist." ) } } + + private fun sortArtistsIntoGenres() { + Log.d(this::class.simpleName, "Sorting artists into genres...") + + val unknownArtists = artists.toMutableList() + + for (genre in genres) { + // Find all artists that match the current genre + val genreArtists = artists.filter { artist -> + artist.genres.any { + it.name == genre.name + } + } + + // Then add them to the genre, along with refreshing the amount of artists + genre.artists.addAll(genreArtists) + genre.numArtists = artists.size + + unknownArtists.removeAll(genreArtists) + } + + if (unknownArtists.size > 0) { + // Reuse an existing unknown genre if one is found + val unknownGenre = genres.find { it.name == "" } ?: Genre() + + for (artist in unknownArtists) { + artist.genres.add(unknownGenre) + unknownGenre.artists.add(artist) + } + + unknownGenre.numArtists = artists.size + + Log.d( + this::class.simpleName, + "${unknownArtists.size} albums were placed into an unknown genre." + ) + } + } + + // Correct any empty names [""] with the proper placeholders [Unknown Album] + private fun addPlaceholders() { + genres.forEach { if (it.name == "") it.name = genrePlaceholder } + artists.forEach { if (it.name == "") it.name = artistPlaceholder } + albums.forEach { if (it.title == "") it.title = albumPlaceholder } + } } diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt b/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt index 797fca6b4..0fcde37e0 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/adapters/AlbumAdapter.kt @@ -11,14 +11,7 @@ class AlbumAdapter(private val data: List) : RecyclerView.Adapter) : RecyclerView.Adapter) : RecyclerView.Adapter) : RecyclerView.Adapter