diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 464f5dfbc..555b5640f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,17 +1,20 @@ + + android:theme="@style/Theme.Base" + tools:ignore="AllowBackup"> get() = mShowMode private val mSortMode = MutableLiveData(SortMode.ALPHA_DOWN) diff --git a/app/src/main/java/org/oxycblt/auxio/music/Models.kt b/app/src/main/java/org/oxycblt/auxio/music/Models.kt index d0f63c3a3..c3292bf6c 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/Models.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/Models.kt @@ -45,7 +45,6 @@ data class Song( * @property year The year this album was released. 0 if there is none in the metadata. * @property artist The Album's parent [Artist]. use this instead of [artistId] * @property songs The Album's child [Song]s. - * @property numSongs The amount of songs in an Album. * @property totalDuration The combined duration of all of the album's child songs, formatted. * @author OxygenCobalt */ @@ -59,7 +58,6 @@ data class Album( lateinit var artist: Artist val songs = mutableListOf() - val numSongs: Int get() = songs.size val totalDuration: String by lazy { var seconds: Long = 0 songs.forEach { @@ -80,15 +78,7 @@ data class Artist( val albums = mutableListOf() val genres = mutableListOf() - val numAlbums: Int get() = albums.size - val numSongs: Int by lazy { - var num = 0 - albums.forEach { - num += it.numSongs - } - num - } - val songs: MutableList by lazy { + val songs: List by lazy { val songs = mutableListOf() albums.forEach { songs.addAll(it.songs) @@ -109,22 +99,14 @@ data class Genre( ) : BaseModel() { val artists = mutableListOf() - val numArtists: Int get() = artists.size - val numAlbums: Int by lazy { - var num = 0 + val albums: List by lazy { + val albums = mutableListOf() artists.forEach { - num += it.numAlbums + albums.addAll(it.albums) } - num + albums } - val numSongs: Int by lazy { - var num = 0 - artists.forEach { - num += it.numSongs - } - num - } - val songs: MutableList by lazy { + val songs: List by lazy { val songs = mutableListOf() artists.forEach { songs.addAll(it.songs) 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 0a3fcde34..cf79eaeab 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt @@ -92,10 +92,10 @@ fun Int.toYear(context: Context): String { @BindingAdapter("genreCounts") fun TextView.bindGenreCounts(genre: Genre) { val artists = context.resources.getQuantityString( - R.plurals.format_artist_count, genre.numArtists, genre.numArtists + R.plurals.format_artist_count, genre.artists.size, genre.artists.size ) val albums = context.resources.getQuantityString( - R.plurals.format_album_count, genre.numAlbums, genre.numAlbums + R.plurals.format_album_count, genre.albums.size, genre.albums.size ) text = context.getString(R.string.format_double_counts, artists, albums) @@ -116,10 +116,10 @@ fun TextView.bindArtistGenre(artist: Artist) { @BindingAdapter("artistCounts") fun TextView.bindArtistCounts(artist: Artist) { val albums = context.resources.getQuantityString( - R.plurals.format_album_count, artist.numAlbums, artist.numAlbums + R.plurals.format_album_count, artist.albums.size, artist.albums.size ) val songs = context.resources.getQuantityString( - R.plurals.format_song_count, artist.numSongs, artist.numSongs + R.plurals.format_song_count, artist.songs.size, artist.songs.size ) text = context.getString(R.string.format_double_counts, albums, songs) @@ -133,7 +133,7 @@ fun TextView.bindAllAlbumDetails(album: Album) { album.year.toYear(context), context.resources.getQuantityString( R.plurals.format_song_count, - album.numSongs, album.numSongs + album.songs.size, album.songs.size ), album.totalDuration ) @@ -147,7 +147,7 @@ fun TextView.bindAlbumInfo(album: Album) { album.artist.name, context.resources.getQuantityString( R.plurals.format_song_count, - album.numSongs, album.numSongs + album.songs.size, album.songs.size ) ) } diff --git a/app/src/main/java/org/oxycblt/auxio/music/coil/CoilUtils.kt b/app/src/main/java/org/oxycblt/auxio/music/coil/CoilUtils.kt index dcf31470b..2e5f847c3 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/coil/CoilUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/coil/CoilUtils.kt @@ -3,7 +3,6 @@ package org.oxycblt.auxio.music.coil import android.content.Context import android.graphics.Bitmap import android.net.Uri -import android.util.Log import android.widget.ImageView import androidx.core.graphics.drawable.toBitmap import androidx.databinding.BindingAdapter @@ -16,7 +15,7 @@ import org.oxycblt.auxio.music.Genre import org.oxycblt.auxio.music.Song // Get a bitmap for a song, onDone will be called when the bitmap is loaded. -// Don't use this on UI elements, thats what the BindingAdapters are for. +// Don't use this on UI elements, that's what the BindingAdapters are for. fun getBitmap(song: Song, context: Context, onDone: (Bitmap) -> Unit) { Coil.enqueue( ImageRequest.Builder(context) @@ -57,7 +56,7 @@ fun ImageView.bindArtistImage(artist: Artist) { val request: ImageRequest // If there is more than one album, then create a mosaic of them. - if (artist.numAlbums >= 4) { + if (artist.albums.size >= 4) { val uris = mutableListOf() for (i in 0..3) { @@ -93,11 +92,9 @@ fun ImageView.bindArtistImage(artist: Artist) { fun ImageView.bindGenreImage(genre: Genre) { val request: ImageRequest - if (genre.numArtists >= 4) { + if (genre.artists.size >= 4) { val uris = mutableListOf() - Log.d(this::class.simpleName, genre.numAlbums.toString()) - // Get the Nth cover from each artist, if possible. for (i in 0..3) { val artist = genre.artists[i] 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 d8b28f001..f5c59d255 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 @@ -21,7 +21,7 @@ enum class MusicLoaderResponse { // Class that loads music from the FileSystem. // TODO: Add custom artist images from the filesystem -// TODO: Move genre loading of songs [Loads would take longer though] +// TODO: Move genre loading to songs [Loads would take longer though] class MusicLoader( private val resolver: ContentResolver, @@ -219,7 +219,7 @@ class MusicLoader( } albums = albums.distinctBy { - it.name to it.artistId to it.year to it.numSongs + it.name to it.artistId to it.year }.toMutableList() Log.d( diff --git a/app/src/main/java/org/oxycblt/auxio/playback/NotificationUtils.kt b/app/src/main/java/org/oxycblt/auxio/playback/NotificationUtils.kt index 925b65b80..499ec4461 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/NotificationUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/NotificationUtils.kt @@ -57,8 +57,6 @@ fun NotificationManager.createMediaNotification( PendingIntent.FLAG_UPDATE_CURRENT ) - // TODO: Things that probably aren't possible but would be nice - // - Playing intent takes you to PlaybackFragment instead of MainFragment return NotificationCompat.Builder(context, NotificationUtils.CHANNEL_ID) .setSmallIcon(R.drawable.ic_song) .setStyle( @@ -124,7 +122,7 @@ fun NotificationCompat.Builder.updateMode(context: Context) { // If playing from all songs, set the subtext as that, otherwise the currently played parent. if (playbackManager.mode == PlaybackMode.ALL_SONGS) { - setSubText(context.getString(R.string.title_all_songs)) + setSubText(context.getString(R.string.label_all_songs)) } else { setSubText(playbackManager.parent!!.name) } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt index f58b04155..fb0237fcf 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/PlaybackFragment.kt @@ -158,7 +158,7 @@ class PlaybackFragment : Fragment(), SeekBar.OnSeekBarChangeListener { } } - // Updates for the current duration TextView/Seekbar + // Updates for the current duration TextView/SeekBar playbackModel.formattedPosition.observe(viewLifecycleOwner) { binding.playbackDurationCurrent.text = it } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt index b2f921636..707ffca6f 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueAdapter.kt @@ -80,20 +80,21 @@ class QueueAdapter( fun removeItem(adapterIndex: Int) { data.removeAt(adapterIndex) - notifyItemRemoved(adapterIndex) - // Check for two things: // If the data from the next queue is now entirely empty [Signified by a header at the end] // Or if the data from the last queue is now entirely empty [Signified by there being 2 headers with no items in between] if (data[data.lastIndex] is Header) { val lastIndex = data.lastIndex - // TODO: Do notifyItemRangeRemoved instead of notifyItemRemoved data.removeAt(lastIndex) - notifyItemRemoved(lastIndex) + + notifyItemRangeRemoved(lastIndex, 2) } else if (data.lastIndex >= 1 && data[0] is Header && data[1] is Header) { data.removeAt(0) - notifyItemRemoved(0) + + notifyItemRangeRemoved(0, 2) + } else { + notifyItemRemoved(adapterIndex) } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt index 6f902641d..631d805ad 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/queue/QueueFragment.kt @@ -85,7 +85,7 @@ class QueueFragment : Fragment() { name = getString( R.string.format_next_from, if (playbackModel.mode.value == PlaybackMode.ALL_SONGS) - getString(R.string.title_all_songs) + getString(R.string.label_all_songs) else playbackModel.parent.value!!.name ) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index 2dbc18f41..0f9d33e14 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -133,7 +133,7 @@ class PlaybackStateManager private constructor() { PlaybackMode.IN_ARTIST -> { mParent = song.album.artist - mQueue = song.album.artist.songs + mQueue = song.album.artist.songs.toMutableList() } PlaybackMode.IN_ALBUM -> { @@ -425,7 +425,7 @@ class PlaybackStateManager private constructor() { } // --- PERSISTENCE FUNCTIONS --- - // TODO: Implement a fast queue save function that can be enabled in settings + // TODO: Implement a fast queue save function suspend fun saveStateToDatabase(context: Context) { Log.d(this::class.simpleName, "Saving state to DB.") @@ -557,15 +557,15 @@ class PlaybackStateManager private constructor() { // Traverse albums and then album songs instead of just the songs, as its faster. musicStore.albums.find { it.id == item.albumId } ?.songs?.find { it.id == item.songId }?.let { - mQueue.add(it) - } + mQueue.add(it) + } } userQueueItems.forEach { item -> musicStore.albums.find { it.id == item.albumId } ?.songs?.find { it.id == item.songId }?.let { - mUserQueue.add(it) - } + mUserQueue.add(it) + } } forceQueueUpdate() diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/DiffCallback.kt b/app/src/main/java/org/oxycblt/auxio/recycler/DiffCallback.kt index f04767d61..fc321b0b0 100644 --- a/app/src/main/java/org/oxycblt/auxio/recycler/DiffCallback.kt +++ b/app/src/main/java/org/oxycblt/auxio/recycler/DiffCallback.kt @@ -6,7 +6,7 @@ import org.oxycblt.auxio.music.BaseModel // Base Diff callback class DiffCallback : DiffUtil.ItemCallback() { override fun areContentsTheSame(oldItem: T, newItem: T): Boolean { - return oldItem == newItem + return oldItem.hashCode() == newItem.hashCode() } override fun areItemsTheSame(oldItem: T, newItem: T): Boolean { diff --git a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt index 4b069676b..1dff0c81b 100644 --- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt +++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt @@ -43,7 +43,7 @@ fun ImageButton.disable(context: Context) { } fun String.createToast(context: Context) { - Toast.makeText(context, this, Toast.LENGTH_SHORT).show() + Toast.makeText(context.applicationContext, this, Toast.LENGTH_SHORT).show() } // Apply a custom vertical divider diff --git a/app/src/main/res/drawable/ui_indicator.xml b/app/src/main/res/drawable/ui_indicator.xml deleted file mode 100644 index 3bc8a98d0..000000000 --- a/app/src/main/res/drawable/ui_indicator.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index c02052b06..804ab6710 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,5 +1,6 @@ - + app:title="@string/label_library" /> + app:title="@string/label_library" /> + app:title="@string/label_library" /> diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index cf12da316..7f6fb174b 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -20,7 +20,7 @@ app:popupTheme="@style/AppThemeOverlay.Popup" app:menu="@menu/menu_library" app:titleTextAppearance="@style/TextAppearance.Toolbar.Header" - app:title="@string/title_library_fragment" /> + app:title="@string/label_library" /> diff --git a/app/src/main/res/layout/fragment_songs.xml b/app/src/main/res/layout/fragment_songs.xml index c50fb623d..4d42dedca 100644 --- a/app/src/main/res/layout/fragment_songs.xml +++ b/app/src/main/res/layout/fragment_songs.xml @@ -18,7 +18,7 @@ android:elevation="@dimen/elevation_normal" app:menu="@menu/menu_songs" app:titleTextAppearance="@style/TextAppearance.Toolbar.Header" - app:title="@string/title_all_songs" /> + app:title="@string/label_all_songs" /> 4dp 8dp 16dp - 24dp - 32dp - 64dp - 4dp 8dp 10dp 16dp 24dp - 32dp - 64dp - 40dp 2dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9b09a1edc..9dcc6550c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,18 +2,11 @@ Auxio - - Library - All Songs - Now Playing - - - No music found. - Music loading failed. - Permissions to read storage are needed. - Retry + Library + All Songs + Now Playing Grant Genres Artists @@ -28,7 +21,6 @@ Play from artist Play from album Go to artist - Go to album Queue Add to queue Added to queue @@ -36,6 +28,11 @@ Music Playback The music playback service for Auxio. + + No music found. + Music loading failed. + Permissions to read storage are needed. + Search Library… diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 73600e581..c80002eae 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -48,12 +48,13 @@ + + --> \ No newline at end of file