search: normalize unicode strings
Normalize unicode strings when making searches. This allows accented characters to be treated as typical characters/
This commit is contained in:
parent
dae334b1d6
commit
0433abc5cb
2 changed files with 31 additions and 3 deletions
|
@ -40,7 +40,6 @@ import org.oxycblt.auxio.music.Album
|
||||||
import org.oxycblt.auxio.music.Artist
|
import org.oxycblt.auxio.music.Artist
|
||||||
import org.oxycblt.auxio.music.Genre
|
import org.oxycblt.auxio.music.Genre
|
||||||
import org.oxycblt.auxio.music.Song
|
import org.oxycblt.auxio.music.Song
|
||||||
import org.oxycblt.auxio.playback.PlaybackViewModel
|
|
||||||
import org.oxycblt.auxio.ui.DisplayMode
|
import org.oxycblt.auxio.ui.DisplayMode
|
||||||
import org.oxycblt.auxio.util.applyEdge
|
import org.oxycblt.auxio.util.applyEdge
|
||||||
import org.oxycblt.auxio.util.logD
|
import org.oxycblt.auxio.util.logD
|
||||||
|
|
|
@ -31,10 +31,10 @@ import org.oxycblt.auxio.music.Header
|
||||||
import org.oxycblt.auxio.music.MusicStore
|
import org.oxycblt.auxio.music.MusicStore
|
||||||
import org.oxycblt.auxio.settings.SettingsManager
|
import org.oxycblt.auxio.settings.SettingsManager
|
||||||
import org.oxycblt.auxio.ui.DisplayMode
|
import org.oxycblt.auxio.ui.DisplayMode
|
||||||
|
import java.text.Normalizer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The [ViewModel] for the search functionality
|
* The [ViewModel] for the search functionality
|
||||||
* TODO: Try to find adjacent characters [e.g accented o == o]
|
|
||||||
* @author OxygenCobalt
|
* @author OxygenCobalt
|
||||||
*/
|
*/
|
||||||
class SearchViewModel : ViewModel() {
|
class SearchViewModel : ViewModel() {
|
||||||
|
@ -130,12 +130,41 @@ class SearchViewModel : ViewModel() {
|
||||||
*/
|
*/
|
||||||
private fun List<BaseModel>.filterByOrNull(value: String): List<BaseModel>? {
|
private fun List<BaseModel>.filterByOrNull(value: String): List<BaseModel>? {
|
||||||
val filtered = filter {
|
val filtered = filter {
|
||||||
it.name.contains(value, ignoreCase = true)
|
it.name.normalized().contains(value.normalized(), ignoreCase = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (filtered.isNotEmpty()) filtered else null
|
return if (filtered.isNotEmpty()) filtered else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun String.normalized(): String {
|
||||||
|
// This method normalizes strings so that songs with accented characters will show
|
||||||
|
// up in search even if the actual character was not inputted.
|
||||||
|
// https://stackoverflow.com/a/32030586/14143986
|
||||||
|
|
||||||
|
// Normalize with NFKD [Meaning that symbols with identical meanings will be turned into
|
||||||
|
// their letter variants].
|
||||||
|
val norm = Normalizer.normalize(this, Normalizer.Form.NFKD)
|
||||||
|
|
||||||
|
// Normalizer doesn't exactly finish the job though. We have to rebuild all the codepoints
|
||||||
|
// in the string and remove the hidden characters that were added by Normalizer.
|
||||||
|
var idx = 0
|
||||||
|
val sb = StringBuilder()
|
||||||
|
|
||||||
|
while (idx < norm.length) {
|
||||||
|
val cp = norm.codePointAt(idx)
|
||||||
|
idx += Character.charCount(cp)
|
||||||
|
|
||||||
|
when (Character.getType(cp)) {
|
||||||
|
Character.NON_SPACING_MARK.toInt(), Character.COMBINING_SPACING_MARK.toInt() ->
|
||||||
|
continue
|
||||||
|
|
||||||
|
else -> sb.appendCodePoint(cp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the current navigation status to [isNavigating]
|
* Update the current navigation status to [isNavigating]
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue