Optimize partition search

This commit is contained in:
Hasinjato 2026-10-07 15:30:40 +03:00
parent b1b6a5ca4b
commit b5fdd7c30b
2 changed files with 42 additions and 9 deletions

View file

@ -7,13 +7,49 @@ import kotlinx.serialization.json.Json
import mg.dot.feufaro.FileRepository
import java.io.File
fun String.normalizeForSearch(): String {
return this.lowercase().filter { it.isLetterOrDigit() }
}
data class DrawerItem(
val id: Int,
val title: String,
val contentTitle: String,
val firstNotes: String = "",
val path: String
)
) {
fun matchesQuery(query: String): Boolean {
if (query.isBlank()) return true
val cleanQuery = query.normalizeForSearch()
val cleanTitle = title.normalizeForSearch()
val cleanContent = contentTitle.normalizeForSearch()
return (cleanTitle + cleanContent).contains(cleanQuery)
}
fun getSearchScore(query: String): Int {
if (query.isBlank()) return 0
val cleanQuery = query.normalizeForSearch()
val cleanTitle = title.normalizeForSearch()
val cleanContent = contentTitle.normalizeForSearch()
if (cleanTitle == cleanQuery) return 1000
if (cleanTitle.startsWith(cleanQuery)) {
val nextCharIndex = cleanQuery.length
val isNextCharDigit = nextCharIndex < cleanTitle.length && cleanTitle[nextCharIndex].isDigit()
return if (isNextCharDigit) {
100
} else {
800
}
}
if (cleanTitle.contains(cleanQuery)) return 50
if (cleanContent.contains(cleanQuery)) return 10
return 0
}
}
@Serializable
data class FeuIndex(

View file

@ -248,15 +248,12 @@ class SharedScreenModel(private val fileRepository: FileRepository) : ScreenMode
}
@OptIn(ExperimentalCoroutinesApi::class)
val filteredSongs: StateFlow<List<DrawerItem>> = searchTitle
.mapLatest { currentTitle ->
val searchTxt = if (currentTitle == "") "" else currentTitle.trim()
return@mapLatest if(searchTxt.isEmpty()) {
emptyList()
val filteredSongs: StateFlow<List<DrawerItem>> = combine(drawerItems, searchTitle) { items, query ->
if (query.isBlank()) {
items
} else {
drawerItems.value.filter { item ->
item.contentTitle.contains(searchTxt, ignoreCase = true)
}
items.filter { item -> item.matchesQuery(query) }
.sortedByDescending { item -> item.getSearchScore(query) }
}
}.stateIn (
scope = CoroutineScope(Dispatchers.Default),