Optimize partition search
This commit is contained in:
parent
b1b6a5ca4b
commit
b5fdd7c30b
2 changed files with 42 additions and 9 deletions
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue