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 mg.dot.feufaro.FileRepository
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
fun String.normalizeForSearch(): String {
|
||||||
|
return this.lowercase().filter { it.isLetterOrDigit() }
|
||||||
|
}
|
||||||
data class DrawerItem(
|
data class DrawerItem(
|
||||||
val id: Int,
|
val id: Int,
|
||||||
val title: String,
|
val title: String,
|
||||||
val contentTitle: String,
|
val contentTitle: String,
|
||||||
val firstNotes: String = "",
|
val firstNotes: String = "",
|
||||||
val path: 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
|
@Serializable
|
||||||
data class FeuIndex(
|
data class FeuIndex(
|
||||||
|
|
|
||||||
|
|
@ -248,15 +248,12 @@ class SharedScreenModel(private val fileRepository: FileRepository) : ScreenMode
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
val filteredSongs: StateFlow<List<DrawerItem>> = searchTitle
|
val filteredSongs: StateFlow<List<DrawerItem>> = combine(drawerItems, searchTitle) { items, query ->
|
||||||
.mapLatest { currentTitle ->
|
if (query.isBlank()) {
|
||||||
val searchTxt = if (currentTitle == "") "" else currentTitle.trim()
|
items
|
||||||
return@mapLatest if(searchTxt.isEmpty()) {
|
|
||||||
emptyList()
|
|
||||||
} else {
|
} else {
|
||||||
drawerItems.value.filter { item ->
|
items.filter { item -> item.matchesQuery(query) }
|
||||||
item.contentTitle.contains(searchTxt, ignoreCase = true)
|
.sortedByDescending { item -> item.getSearchScore(query) }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}.stateIn (
|
}.stateIn (
|
||||||
scope = CoroutineScope(Dispatchers.Default),
|
scope = CoroutineScope(Dispatchers.Default),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue