fix: key search result rows by dictionary, offset and word

Paging result rows had no keys and were matched by position: appended
pages and query diffs could not reuse row state. Keys derived from
dictionaryPath+offset+word are stable per row, and the paging source
collapses duplicate entries for one dictionary card: case and diacritic
alias variants of a headword share the normalized word, so entries are
deduplicated by dictionaryPath+word+offset before emitting.
This commit is contained in:
2026-09-05 03:00:44 +08:00
parent 944d2e6634
commit 4a00d8adff
2 changed files with 5 additions and 4 deletions
@@ -46,9 +46,8 @@ class IndexEntryPagingSource(
private data class EmittedKey(
val dictPosition: Int,
val originalWord: String,
val offset: Long,
val length: Int
val word: String,
val offset: Long
)
private val emittedArticles = HashSet<EmittedKey>()
@@ -103,6 +102,7 @@ class IndexEntryPagingSource(
val normalizedQuery = query.sanitizeQuery().lowercase().trim()
val ranked = rawResults.map { it.second }
.rankBySearchRelevance(SearchRankingContext(normalizedQuery))
.distinctBy { Triple(it.dictionaryPath, it.word, it.offset.value) }
rawResults.forEach { (position, entry) -> emittedArticles.add(entry.emittedKey(position)) }
@@ -184,7 +184,7 @@ class IndexEntryPagingSource(
}
private fun IndexEntry.emittedKey(dictPosition: Int) =
EmittedKey(dictPosition, originalWord, offset.value, length.value)
EmittedKey(dictPosition, word, offset.value)
override fun getRefreshKey(state: PagingState<TailKey, IndexEntry>): TailKey? {
return null
@@ -41,6 +41,7 @@ fun SearchResultsList(
) {
items(
count = results.itemCount,
key = results.itemKey { "${it.dictionaryPath}:${it.offset.value}:${it.word}" },
contentType = results.itemContentType { "search_result" }
) { index ->
results[index]?.let { entry ->