Consilidate wallet search#477
Open
gemdev111 wants to merge 14 commits into
Open
Conversation
Introduce a single search_priority table keyed by (query, type, item_id) to replace assets_priority, with Migration 79->80 and the exported schema.
Rank results via search_priority joins and match assets by contract/tokenId in local asset search.
Expose the unified /v1/search endpoint returning assets and perpetuals behind a GemSearch coordinator alongside SearchAssets.
Fetch via GemSearch and persist assets, perpetuals, and ranking; wire repositories, DI, and showPerpetuals gating.
Make assetRows public, add getAssetBadge, and support clickable section headers via nullable SubheaderItem onClick.
Port the iOS WalletSearchScene/AssetsResultsScene flow — sections, preview limits, onAction routing, perpetuals gating — and replace the old AssetsSearchScreen.
Pinned perpetuals and pinned assets share the Pinned header but were positioned independently, so a single pinned perpetual plus a single pinned asset rendered as two separate rounded cards instead of one joined card like iOS. Position both sub-lists against the combined count via itemsPositioned indexOffset/totalCount, and drop the now-unused getListPosition extension.
hasPriorities() is a Room flow that re-emits on every search_priority write, and the flatMapLatest keyed on it lacked distinctUntilChanged, so a repeated search for the same query restarted the inner query and reloaded the list. Add distinctUntilChanged across asset, swap, and perpetual search; priority ranking still updates reactively through the JOIN.
The network token search hung off the 5-input filters flow, firing on session/filter churn rather than only query/tag and without a real debounce, so fast typing launched overlapping searches racing on the no-results state. Drive it off a distinct (query, tag, currency, chains) stream with collectLatest, matching iOS which searches only on user input. Gate the trigger behind remoteSearch and disable it on the AssetsResults drill-down, which re-fetched results already in the store and rewrote search_priority, forcing a reload. It now renders straight from the store like iOS's read-only results view model.
Catch blocks on the token search path rethrow CancellationException so a search cancelled by a newer query under collectLatest stops instead of completing as a failure and writing a stale no-results marker. Move the remoteSearch toggle from an open property read in the base class init, a virtual call during construction, to a constructor parameter.
Only wallet search reset the tag when the user typed; Send, Buy, Swap, and price alert pickers kept it applied invisibly (the tag bar hides while typing), filtered results by query::tag so the local LIKE fallback matched nothing, and restored the stale tag when the query cleared. iOS resets the tag on search focus in every picker via SelectAssetViewModel.onChangeFocus. Move the rule from WalletSearchViewModel into the shared base.
# Conflicts: # android/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositories/assets/AssetsRepository.kt # android/data/repositories/src/main/kotlin/com/gemwallet/android/data/repositories/di/AssetsModule.kt # android/data/repositories/src/test/kotlin/com/gemwallet/android/data/repositories/assets/AssetsRepositoryTest.kt
gemcoder21
approved these changes
Jun 11, 2026
| perpetuals.map { PerpetualData(perpetual = it.perpetual, asset = it.asset, metadata = PerpetualMetadata(isPinned = false)) } | ||
| ) | ||
| searchPriorityDao.put(perpetuals.toSearchPriority(priorityQuery)) | ||
| } catch (err: CancellationException) { |
Contributor
There was a problem hiding this comment.
too much } catch (err: CancellationException) {
throw err handling,
| @Test | ||
| fun search_ingestsPerpetualsAndStoresPerpPriority() = runTest { | ||
| val perpAsset = mockAsset() | ||
| val perpetual = Perpetual( |
| import org.junit.Test | ||
| import org.junit.runner.RunWith | ||
|
|
||
| @RunWith(AndroidJUnit4::class) |
| override fun migrate(db: SupportSQLiteDatabase) { | ||
| db.execSQL("DROP TABLE IF EXISTS `assets_priority`") | ||
| db.execSQL( | ||
| "CREATE TABLE IF NOT EXISTS `search_priority` (" + |
Contributor
There was a problem hiding this comment.
is this consistent with ios naming?
| searchable = false, | ||
| onChainFilter = {}, | ||
| onBalanceFilter = {}, | ||
| onClearFilters = {}, |
Contributor
There was a problem hiding this comment.
too many methods? can we create onAction(action), and action is a enum? we have some examples
| @@ -0,0 +1,9 @@ | |||
| package com.gemwallet.android.features.assets.viewmodels | |||
|
|
|||
| object WalletSearchLimits { | |||
Contributor
There was a problem hiding this comment.
can we move those limits to gemstone? so it's reused for ios and android
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #354
images:
tags · recents · perpetuals · assets
perpetual + asset, one section
ranked perps + assets
token id → Tether
market screen
read-only, capped 100
opened from search
no results → Add Custom Token