From 0f3d4b965cdfb1725b73aa43159521f799386d5a Mon Sep 17 00:00:00 2001 From: OneWay Date: Sat, 5 Sep 2026 03:00:44 +0800 Subject: [PATCH] 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. --- .../research/data/paging/IndexEntryPagingSource.kt | 8 ++++---- .../research/ui/main/components/SearchResultsList.kt | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/example/research/data/paging/IndexEntryPagingSource.kt b/app/src/main/java/com/example/research/data/paging/IndexEntryPagingSource.kt index 9584e0a..4e386aa 100644 --- a/app/src/main/java/com/example/research/data/paging/IndexEntryPagingSource.kt +++ b/app/src/main/java/com/example/research/data/paging/IndexEntryPagingSource.kt @@ -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() @@ -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? { return null diff --git a/app/src/main/java/com/example/research/ui/main/components/SearchResultsList.kt b/app/src/main/java/com/example/research/ui/main/components/SearchResultsList.kt index 077fb3c..0afac6e 100644 --- a/app/src/main/java/com/example/research/ui/main/components/SearchResultsList.kt +++ b/app/src/main/java/com/example/research/ui/main/components/SearchResultsList.kt @@ -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 ->