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:
parent
e881178c4c
commit
ad45b3edb3
5 changed files with 36 additions and 29 deletions
|
|
@ -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. */
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue