search: dont compare genre sort names

Don't compare genre sort names when searching.

Genre names are identical to genre sort names, remove the useless
comparisons.
This commit is contained in:
OxygenCobalt 2022-07-17 10:44:21 -06:00
parent e881178c4c
commit ad45b3edb3
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
5 changed files with 36 additions and 29 deletions

View file

@ -169,11 +169,10 @@ data class Song(
/** Internal field. Do not use. */ /** Internal field. Do not use. */
val _artistGroupingSortName: String? val _artistGroupingSortName: String?
get() = get() =
// Only use the album artist sort name if we have one, otherwise ignore it. when {
if (_albumArtistName != null) { _albumArtistName != null -> _albumArtistSortName
_albumArtistSortName _artistName != null -> _artistSortName
} else { else -> null
_artistSortName
} }
/** Internal field. Do not use. */ /** Internal field. Do not use. */

View file

@ -28,8 +28,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.oxycblt.auxio.R import org.oxycblt.auxio.R
import org.oxycblt.auxio.music.Album
import org.oxycblt.auxio.music.Artist
import org.oxycblt.auxio.music.Genre
import org.oxycblt.auxio.music.Music import org.oxycblt.auxio.music.Music
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.MusicStore import org.oxycblt.auxio.music.MusicStore
import org.oxycblt.auxio.music.Song import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.settings.Settings
@ -85,21 +87,21 @@ class SearchViewModel(application: Application) :
// Note: a filter mode of null means to not filter at all. // Note: a filter mode of null means to not filter at all.
if (filterMode == null || filterMode == DisplayMode.SHOW_ARTISTS) { if (filterMode == null || filterMode == DisplayMode.SHOW_ARTISTS) {
library.artists.filterParentsBy(query)?.let { artists -> library.artists.filterArtistsBy(query)?.let { artists ->
results.add(Header(-1, R.string.lbl_artists)) results.add(Header(-1, R.string.lbl_artists))
results.addAll(sort.artists(artists)) results.addAll(sort.artists(artists))
} }
} }
if (filterMode == null || filterMode == DisplayMode.SHOW_ALBUMS) { if (filterMode == null || filterMode == DisplayMode.SHOW_ALBUMS) {
library.albums.filterParentsBy(query)?.let { albums -> library.albums.filterAlbumsBy(query)?.let { albums ->
results.add(Header(-2, R.string.lbl_albums)) results.add(Header(-2, R.string.lbl_albums))
results.addAll(sort.albums(albums)) results.addAll(sort.albums(albums))
} }
} }
if (filterMode == null || filterMode == DisplayMode.SHOW_GENRES) { if (filterMode == null || filterMode == DisplayMode.SHOW_GENRES) {
library.genres.filterParentsBy(query)?.let { genres -> library.genres.filterGenresBy(query)?.let { genres ->
results.add(Header(-3, R.string.lbl_genres)) results.add(Header(-3, R.string.lbl_genres))
results.addAll(sort.genres(genres)) results.addAll(sort.genres(genres))
} }
@ -137,27 +139,29 @@ class SearchViewModel(application: Application) :
search(lastQuery) search(lastQuery)
} }
/**
* Searches the song list by the normalized name, then the sort name, and then the file name.
*/
private fun List<Song>.filterSongsBy(value: String) = private fun List<Song>.filterSongsBy(value: String) =
baseFilterBy(value) { it.path.name.contains(value) }.ifEmpty { null } baseFilterBy(value) {
it.rawSortName?.contains(value) == true || it.path.name.contains(value)
}
/** Searches a list of parents by the normalized name, and then the sort name. */ private fun List<Album>.filterAlbumsBy(value: String) =
private fun <T : MusicParent> List<T>.filterParentsBy(value: String) = baseFilterBy(value) { it.rawSortName?.contains(value) == true }
baseFilterBy(value) { false }.ifEmpty { null }
private fun List<Artist>.filterArtistsBy(value: String) =
baseFilterBy(value) { it.rawSortName?.contains(value) == true }
private fun List<Genre>.filterGenresBy(value: String) = baseFilterBy(value) { false }
private inline fun <T : Music> List<T>.baseFilterBy(value: String, additional: (T) -> Boolean) = private inline fun <T : Music> List<T>.baseFilterBy(value: String, additional: (T) -> Boolean) =
filter { filter {
// The basic comparison is first by the *normalized* name, as that allows a non-unicode // The basic comparison is first by the *normalized* name, as that allows a
// search to match with some unicode characters. If that fails, we if there is a sort // non-unicode
// name // search to match with some unicode characters. If that fails, filter impls have
// we can leverage, as those are often used to make non-unicode variants of unicode // fallback values, primarily around sort tags or file names.
// titles. it.resolveNameNormalized(application).contains(value, ignoreCase = true) ||
it.resolveNameNormalized(application).contains(value, ignoreCase = true) || additional(it)
it.rawSortName?.contains(value, ignoreCase = true) == true || }
additional(it) .ifEmpty { null }
}
private fun Music.resolveNameNormalized(context: Context): String { private fun Music.resolveNameNormalized(context: Context): String {
// This method normalizes strings so that songs with accented characters will show // This method normalizes strings so that songs with accented characters will show

View file

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Note: Not actually transparent, making it transparent would actually make it translucent --> <!--
Used on devices when we can technically use "transparent" system bars, but fully
transparent system bars would actually be made translucent by the OS.
-->
<color name="chrome_transparent_ish">#01151515</color> <color name="chrome_transparent_ish">#01151515</color>
<!-- Replicate extra theme values for widgets -->
<color name="widget_surface">@color/material_dynamic_secondary20</color> <color name="widget_surface">@color/material_dynamic_secondary20</color>
<color name="widget_surface_inverse">@color/material_dynamic_neutral90</color> <color name="widget_surface_inverse">@color/material_dynamic_neutral90</color>
<color name="widget_on_surface_inverse">@color/material_dynamic_neutral20</color> <color name="widget_on_surface_inverse">@color/material_dynamic_neutral20</color>

View file

@ -4,11 +4,12 @@
<color name="chrome_translucent">#80000000</color> <color name="chrome_translucent">#80000000</color>
<!-- <!--
Used on devices when we can use "transparent" system bars, but fully transparent colors Used on devices when we can technically use "transparent" system bars, but fully
would cause the status bar to become translucent. transparent system bars would actually be made translucent by the OS.
--> -->
<color name="chrome_transparent_ish">#01fafafa</color> <color name="chrome_transparent_ish">#01fafafa</color>
<!-- Replicate extra theme values for widgets -->
<color name="widget_surface">@color/material_dynamic_primary95</color> <color name="widget_surface">@color/material_dynamic_primary95</color>
<color name="widget_surface_inverse">@color/material_dynamic_neutral20</color> <color name="widget_surface_inverse">@color/material_dynamic_neutral20</color>
<color name="widget_on_surface_inverse">@color/material_dynamic_neutral95</color> <color name="widget_on_surface_inverse">@color/material_dynamic_neutral95</color>

View file

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<style name="Theme.Auxio.Black" parent="Theme.Auxio.Base"> <style name="Theme.Auxio.Black" parent="Theme.Auxio.Base">
<item name="colorSurface">@android:color/black</item> <item name="colorSurface">@android:color/black</item>
</style> </style>