diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml
deleted file mode 100644
index 08b32826e..000000000
--- a/app/src/debug/AndroidManifest.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/debug/res/drawable-v24/ic_launcher_foreground.xml b/app/src/debug/res/drawable-v24/ic_launcher_foreground.xml
deleted file mode 100644
index de78f6455..000000000
--- a/app/src/debug/res/drawable-v24/ic_launcher_foreground.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
deleted file mode 100644
index bbd3e0212..000000000
--- a/app/src/debug/res/mipmap-anydpi-v26/ic_launcher.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/app/src/debug/res/values/strings.xml b/app/src/debug/res/values/strings.xml
new file mode 100644
index 000000000..bb857a700
--- /dev/null
+++ b/app/src/debug/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Auxio Debug
+
\ No newline at end of file
diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
index c830b2cf2..6962cbdee 100644
--- a/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryFragment.kt
@@ -41,6 +41,8 @@ import org.oxycblt.auxio.ui.toColor
* search functionality.
* FIXME: Heisenleak when navving from search
* FIXME: Heisenleak on older versions
+ * TODO: Filtering & Search order upgrades
+ * TODO: Show result counts?
*/
class LibraryFragment : Fragment(), SearchView.OnQueryTextListener {
diff --git a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt b/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt
index 68b254806..e9b81c44f 100644
--- a/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt
+++ b/app/src/main/java/org/oxycblt/auxio/library/LibraryViewModel.kt
@@ -61,44 +61,80 @@ class LibraryViewModel : ViewModel(), SettingsManager.Callback {
return
}
- // Search MusicStore for all the items [Artists, Albums, Songs] that contain
- // the query, and update the LiveData with those items. This is done on a separate
- // thread as it can be a very long operation for large music libraries.
viewModelScope.launch {
val combined = mutableListOf()
- val children = mDisplayMode.getChildren()
- // If the Library DisplayMode supports it, include artists / genres in the search.
- if (children.contains(DisplayMode.SHOW_GENRES)) {
- val genres = musicStore.genres.filter { it.name.contains(query, true) }
-
- if (genres.isNotEmpty()) {
- combined.add(Header(name = context.getString(R.string.label_genres)))
- combined.addAll(genres)
+ // Searching is done in a different order depending on which items are being shown
+ // E.G If albums are being shown, then they will be the first items on the list.
+ when (mDisplayMode) {
+ DisplayMode.SHOW_GENRES -> {
+ searchForGenres(combined, query, context)
+ searchForArtists(combined, query, context)
+ searchForAlbums(combined, query, context)
}
- }
- if (children.contains(DisplayMode.SHOW_ARTISTS)) {
- val artists = musicStore.artists.filter { it.name.contains(query, true) }
-
- if (artists.isNotEmpty()) {
- combined.add(Header(name = context.getString(R.string.label_artists)))
- combined.addAll(artists)
+ DisplayMode.SHOW_ARTISTS -> {
+ searchForArtists(combined, query, context) -
+ searchForAlbums(combined, query, context)
+ searchForGenres(combined, query, context)
}
- }
- // Albums & Songs are always included.
- val albums = musicStore.albums.filter { it.name.contains(query, true) }
-
- if (albums.isNotEmpty()) {
- combined.add(Header(name = context.getString(R.string.label_albums)))
- combined.addAll(albums)
+ DisplayMode.SHOW_ALBUMS -> {
+ searchForAlbums(combined, query, context)
+ searchForArtists(combined, query, context)
+ searchForGenres(combined, query, context)
+ }
}
mSearchResults.value = combined
}
}
+ private fun searchForGenres(
+ data: MutableList,
+ query: String,
+ context: Context
+ ): MutableList {
+ val genres = musicStore.genres.filter { it.name.contains(query, true) }
+
+ if (genres.isNotEmpty()) {
+ data.add(Header(id = 0, name = context.getString(R.string.label_genres)))
+ data.addAll(genres)
+ }
+
+ return data
+ }
+
+ private fun searchForArtists(
+ data: MutableList,
+ query: String,
+ context: Context
+ ): MutableList {
+ val artists = musicStore.artists.filter { it.name.contains(query, true) }
+
+ if (artists.isNotEmpty()) {
+ data.add(Header(id = 1, name = context.getString(R.string.label_artists)))
+ data.addAll(artists)
+ }
+
+ return data
+ }
+
+ private fun searchForAlbums(
+ data: MutableList,
+ query: String,
+ context: Context
+ ): MutableList {
+ val albums = musicStore.albums.filter { it.name.contains(query, true) }
+
+ if (albums.isNotEmpty()) {
+ data.add(Header(id = 2, name = context.getString(R.string.label_albums)))
+ data.addAll(albums)
+ }
+
+ return data
+ }
+
fun resetQuery() {
mSearchResults.value = listOf()
}
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 8352d50c8..5577cb1d0 100644
--- a/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt
+++ b/app/src/main/java/org/oxycblt/auxio/music/MusicUtils.kt
@@ -10,6 +10,7 @@ import android.widget.TextView
import androidx.databinding.BindingAdapter
import org.oxycblt.auxio.R
import org.oxycblt.auxio.recycler.SortMode
+import org.oxycblt.auxio.ui.getPlural
/**
* List of ID3 genres + Winamp extensions, each index corresponds to their int value.
@@ -120,12 +121,8 @@ fun TextView.bindArtistGenre(artist: Artist) {
*/
@BindingAdapter("artistCounts")
fun TextView.bindArtistCounts(artist: Artist) {
- val albums = context.resources.getQuantityString(
- R.plurals.format_album_count, artist.albums.size, artist.albums.size
- )
- val songs = context.resources.getQuantityString(
- R.plurals.format_song_count, artist.songs.size, artist.songs.size
- )
+ val albums = context.getPlural(R.plurals.format_album_count, artist.albums.size)
+ val songs = context.getPlural(R.plurals.format_song_count, artist.songs.size)
text = context.getString(R.string.format_double_counts, albums, songs)
}
@@ -138,10 +135,7 @@ fun TextView.bindAllAlbumDetails(album: Album) {
text = context.getString(
R.string.format_double_info,
album.year.toYear(context),
- context.resources.getQuantityString(
- R.plurals.format_song_count,
- album.songs.size, album.songs.size
- ),
+ context.getPlural(R.plurals.format_song_count, album.songs.size),
album.totalDuration
)
}
@@ -154,10 +148,7 @@ fun TextView.bindAlbumInfo(album: Album) {
text = context.getString(
R.string.format_info,
album.artist.name,
- context.resources.getQuantityString(
- R.plurals.format_song_count,
- album.songs.size, album.songs.size
- )
+ context.getPlural(R.plurals.format_song_count, album.songs.size),
)
}
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 16b8de562..ed9a1f04b 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
@@ -20,14 +20,17 @@ import org.oxycblt.auxio.settings.SettingsManager
import kotlin.random.Random
/**
- * Master class for the playback state. This should ***not*** be used outside of the playback module.
+ * Master class (and possible god object) for the playback state.
+ *
+ * This should ***NOT*** be used outside of the playback module.
* - If you want to use the playback state in the UI, use [org.oxycblt.auxio.playback.PlaybackViewModel].
* - If you want to use the playback state with the ExoPlayer instance or system-side things,
* use [org.oxycblt.auxio.playback.PlaybackService].
*
* All access should be done with [PlaybackStateManager.getInstance].
* @author OxygenCobalt
- * // TODO: Sort queues
+ *
+ * TODO: Sort queues
*/
class PlaybackStateManager private constructor() {
// Playback
diff --git a/app/src/main/java/org/oxycblt/auxio/recycler/CenterSmoothScroller.kt b/app/src/main/java/org/oxycblt/auxio/recycler/CenterSmoothScroller.kt
index 419bbc829..8dea77946 100644
--- a/app/src/main/java/org/oxycblt/auxio/recycler/CenterSmoothScroller.kt
+++ b/app/src/main/java/org/oxycblt/auxio/recycler/CenterSmoothScroller.kt
@@ -3,6 +3,11 @@ package org.oxycblt.auxio.recycler
import android.content.Context
import androidx.recyclerview.widget.LinearSmoothScroller
+/**
+ * [LinearSmoothScroller] subclass that centers the item on the screen instead of snapping to the
+ * top or bottom.
+ * @author OxygenCobalt
+ */
class CenterSmoothScroller(context: Context, target: Int) : LinearSmoothScroller(context) {
init {
targetPosition = target
diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
index 493b1e4a7..bb3810639 100644
--- a/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
+++ b/app/src/main/java/org/oxycblt/auxio/songs/SongsFragment.kt
@@ -126,9 +126,8 @@ class SongsFragment : Fragment(), SearchView.OnQueryTextListener {
if (isLandscape(resources)) {
val spans = getLandscapeSpans(resources)
- layoutManager = GridLayoutManager(requireContext(), GridLayoutManager.VERTICAL).also {
- it.spanCount = spans
- it.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
+ layoutManager = GridLayoutManager(requireContext(), spans).apply {
+ spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
override fun getSpanSize(position: Int): Int {
return if (binding.songRecycler.adapter == searchAdapter && position == 0)
2 else 1
diff --git a/app/src/main/java/org/oxycblt/auxio/songs/SongsViewModel.kt b/app/src/main/java/org/oxycblt/auxio/songs/SongsViewModel.kt
index 7b7cb75b8..af1e81bd7 100644
--- a/app/src/main/java/org/oxycblt/auxio/songs/SongsViewModel.kt
+++ b/app/src/main/java/org/oxycblt/auxio/songs/SongsViewModel.kt
@@ -34,17 +34,16 @@ class SongsViewModel : ViewModel() {
}
viewModelScope.launch {
- val songs = mutableListOf().also {
- it.addAll(musicStore.songs.filter { it.name.contains(query, true) }.toMutableList())
+ val songs = mutableListOf().also { list ->
+ list.addAll(
+ musicStore.songs.filter {
+ it.name.contains(query, true)
+ }.toMutableList()
+ )
}
if (songs.isNotEmpty()) {
- songs.add(
- 0,
- Header(
- name = context.getString(R.string.label_songs)
- )
- )
+ songs.add(0, Header(id = 0, name = context.getString(R.string.label_songs)))
}
mSearchResults.value = songs
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 48c90bdce..359225458 100644
--- a/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt
+++ b/app/src/main/java/org/oxycblt/auxio/ui/InterfaceUtils.kt
@@ -13,6 +13,7 @@ import android.widget.TextView
import android.widget.Toast
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
+import androidx.annotation.PluralsRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
@@ -111,3 +112,13 @@ fun Fragment.requireCompatActivity(): AppCompatActivity {
error("Required AppCompatActivity, got ${activity::class.simpleName} instead.")
}
}
+
+/**
+ * Convenience method for getting a plural.
+ * @param pluralsRes Resource for the plural
+ * @param value Int value for the plural.
+ * @return The formatted string requested
+ */
+fun Context.getPlural(@PluralsRes pluralsRes: Int, value: Int): String {
+ return resources.getQuantityString(pluralsRes, value, value)
+}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index d1e840884..ffc6540b0 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -174,5 +174,4 @@
- %s Album
- %s Albums
-
\ No newline at end of file