diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e32610397..1addd618b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,7 @@ - + +) { + private var mTitle: String? = null + private var mArtist: String? = null + //private var mGenre: String? = null + private var mYear: Int = 0 + + // Immutable backings as the member variables are mutable + val title: String? get() = mTitle + val artist: String? get() = mArtist + //val genre: String? get() = genre + val year: Int get() = mYear + + val songs: List get() = mSongs + + init { + // Iterate through the child songs and inherit the first valid value + // for the Album name & year, otherwise it will revert to its defaults + for (song in mSongs) { + if (song.album != null) { + mTitle = song.album + } + + if (song.artist != null) { + mArtist = song.artist + } + + /* + if (song.genre != null) { + mGenre = song.genre + } + */ + + if (song.year != 0) { + mYear = song.year + } + } + + // Also sort the songs by track + mSongs = songs.sortedBy { it.track } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/oxycblt/auxio/music/Artist.kt b/app/src/main/java/org/oxycblt/auxio/music/Artist.kt new file mode 100644 index 000000000..fe270a15d --- /dev/null +++ b/app/src/main/java/org/oxycblt/auxio/music/Artist.kt @@ -0,0 +1,34 @@ +package org.oxycblt.auxio.music + +// Abstraction for mAlbums +data class Artist( + private var mAlbums: List +) { + private var mName: String? = null + //private var mGenre: String? = null + + // Immutable backings as the member variables are mutable + val name: String? get() = mName + //val genre: String? get() = mGenre + + val albums: List get() = mAlbums + + init { + // Like album, iterate through the child albums and pick out the first valid + // tag for Album/Genre + for (album in mAlbums) { + if (album.artist != null) { + mName = album.artist + } + + /* + if (album.genre != null) { + mGenre = album.genre + } + */ + } + + // Also sort the mAlbums by year + mAlbums = mAlbums.sortedBy { it.year } + } +} \ No newline at end of file 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 fae291c8f..d7bb3f2a1 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicRepository.kt @@ -9,21 +9,34 @@ import android.util.Log // Storage for music data. Design largely adapted from Music Player GO: // https://github.com/enricocid/Music-Player-GO -class MusicRepository() { +class MusicRepository { - var rawMusicList = mutableListOf() + private lateinit var mArtists: List + private lateinit var mAlbums: List + private lateinit var mSongs: List - fun getMusic(app: Application): MutableList { - findMusic(app)?.let { rm -> + // Not sure if backings are necessary but they're vars so better safe than sorry + val artists: List get() = mArtists + val albums: List get() = mAlbums + val songs: List get() = mSongs - // TODO: Sort the raw music - rawMusicList = rm + fun init(app: Application): Boolean { + findMusic(app)?.let { ss -> + if (ss.size > 0) { + processSongs(ss) + + return true + } } - return rawMusicList + // Return false if the load as failed for any reason, either + // through there being no music or an Exception. + return false } - private fun findMusic(app: Application): MutableList? { + private fun findMusic(app: Application): MutableList? { + + val songList = mutableListOf() try { val musicCursor = getCursor( @@ -42,8 +55,8 @@ class MusicRepository() { val idIndex = cursor.getColumnIndexOrThrow(AudioColumns._ID) while (cursor.moveToNext()) { - rawMusicList.add( - RawMusic( + songList.add( + Song( cursor.getString(nameIndex), cursor.getString(artistIndex), cursor.getString(albumIndex), @@ -58,10 +71,10 @@ class MusicRepository() { Log.d( this::class.simpleName, - "Music search ended with " + rawMusicList.size.toString() + " Songs found." + "Music search finished with " + songList.size.toString() + " Songs found." ) - return rawMusicList + return songList } catch (error: Exception) { // TODO: Add better error handling @@ -89,6 +102,61 @@ class MusicRepository() { AudioColumns.IS_MUSIC + "=1", null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER ) + + // TODO: Art Loading, since android cant do it on its own + // TODO: Genre Loading? + } + + // Sort the list of Song objects into an abstracted lis + private fun processSongs(songs: MutableList) { + // Eliminate all duplicates from the list + // excluding the ID, as that's guaranteed to be unique [I think] + val distinctSongs = songs.distinctBy { + it.name to it.artist to it.album to it.year to it.track to it.duration + }.toMutableList() + + // Sort the music by artists/albums + val songsByAlbum = distinctSongs.groupBy { it.album } + val albumList = mutableListOf() + + songsByAlbum.keys.iterator().forEach { album -> + val albumSongs = songsByAlbum[album] + + // Add an album abstraction for each album item in the list of songs. + albumSongs?.let { + albumList.add( + Album(albumSongs) + ) + } + } + + // Then abstract the remaining albums into artist objects + // TODO: If enabled + val albumsByArtist = albumList.groupBy { it.artist } + val artistList = mutableListOf() + + albumsByArtist.keys.iterator().forEach { artist -> + val artistAlbums = albumsByArtist[artist] + + artistAlbums?.let { + artistList.add( + Artist(artistAlbums) + ) + } + } + + Log.i(this::class.simpleName, + "Successfully sorted songs into " + + artistList.size.toString() + + " Artists and " + + albumList.size.toString() + + " Albums." + ) + + mArtists = artistList + mAlbums = albumList + mSongs = distinctSongs + } companion object { @@ -99,6 +167,11 @@ class MusicRepository() { val tempInstance = INSTANCE if (tempInstance != null) { + Log.d( + this::class.simpleName, + "Passed an existing instance of MusicRepository." + ) + return tempInstance } @@ -107,7 +180,7 @@ class MusicRepository() { INSTANCE = newInstance Log.d( - MusicRepository::class.simpleName, + this::class.simpleName, "Created an instance of MusicRepository." ) diff --git a/app/src/main/java/org/oxycblt/auxio/music/RawMusic.kt b/app/src/main/java/org/oxycblt/auxio/music/Song.kt similarity index 59% rename from app/src/main/java/org/oxycblt/auxio/music/RawMusic.kt rename to app/src/main/java/org/oxycblt/auxio/music/Song.kt index 5d513cf90..30663c157 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/RawMusic.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Song.kt @@ -1,13 +1,14 @@ package org.oxycblt.auxio.music -// Class containing all relevant values for a song -// TODO: Is broken into Artist, Album, and Song classes -data class RawMusic( +// Class containing all relevant values for a song. +data class Song( val name: String?, val artist: String?, val album: String?, + //val genre: String?, val year: Int, val track: Int, val duration: Long, val id: Long? ) + diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index 8be02910c..77475efbe 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -13,7 +13,6 @@ android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" android:elevation="@dimen/elevation_normal" - app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:title="@string/fragment_library_title" tools:titleTextColor="@color/primaryTextColor" /> diff --git a/app/src/main/res/navigation/nav_main.xml b/app/src/main/res/navigation/nav_main.xml index f645b4c8f..7e40d75fd 100644 --- a/app/src/main/res/navigation/nav_main.xml +++ b/app/src/main/res/navigation/nav_main.xml @@ -1,11 +1,13 @@ + android:label="PlayerFragment" + tools:layout="@layout/fragment_library" /> \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index f6fac20d2..548d426a4 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -1,6 +1,6 @@ - #272727 + #424242 #6d6d6d #1b1b1b #212121 diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 9eb744fff..b9d88b3c9 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -3,7 +3,7 @@ \ No newline at end of file