diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt index c8c09dba5..7762cfaa7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoClickableRow.kt @@ -47,7 +47,6 @@ import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.HalfHalfVertPadding import com.vitorpamplona.amethyst.ui.theme.HalfHorzPadding -import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding import com.vitorpamplona.amethyst.ui.theme.Height25Modifier import com.vitorpamplona.amethyst.ui.theme.LargeRelayIconModifier import com.vitorpamplona.amethyst.ui.theme.ReactionRowHeightChatMaxWidth @@ -63,6 +62,7 @@ fun BasicRelaySetupInfoClickableRow( onDelete: ((BasicRelaySetupInfo) -> Unit)?, onClick: () -> Unit, nip11CachedRetriever: Nip11CachedRetriever, + modifier: Modifier = Modifier, accountViewModel: AccountViewModel, nav: INav, ) { @@ -79,7 +79,7 @@ fun BasicRelaySetupInfoClickableRow( ) { Row( verticalAlignment = Alignment.CenterVertically, - modifier = HalfVertPadding, + modifier = modifier, ) { val iconUrlFromRelayInfoDoc by loadRelayInfo(item.relay, nip11CachedRetriever) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoDialog.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoDialog.kt index 372af3caa..1a85e2aec 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoDialog.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/BasicRelaySetupInfoDialog.kt @@ -25,6 +25,7 @@ import com.vitorpamplona.amethyst.model.nip11RelayInfo.Nip11CachedRetriever import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel +import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding @Composable fun BasicRelaySetupInfoDialog( @@ -41,6 +42,7 @@ fun BasicRelaySetupInfoDialog( onDelete = onDelete, onClick = { nav.nav(Route.RelayInfo(item.relay.url)) }, nip11CachedRetriever = nip11CachedRetriever, + modifier = HalfVertPadding, accountViewModel = accountViewModel, nav = nav, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/ShowRelaySuggestionList.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/ShowRelaySuggestionList.kt index 6f73a7782..39106f361 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/ShowRelaySuggestionList.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/relays/common/ShowRelaySuggestionList.kt @@ -31,6 +31,7 @@ import com.vitorpamplona.amethyst.model.nip11RelayInfo.Nip11CachedRetriever import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.theme.DividerThickness +import com.vitorpamplona.amethyst.ui.theme.HalfVertPadding import com.vitorpamplona.quartz.nip01Core.relay.normalizer.NormalizedRelayUrl @Composable @@ -54,6 +55,7 @@ fun ShowRelaySuggestionList( onClick = { onSelect(relayInfo.relay) }, onDelete = null, nip11CachedRetriever = nip11CachedRetriever, + modifier = HalfVertPadding, accountViewModel = accountViewModel, nav = nav, ) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt index 9947d9cda..ee4431623 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchBarViewModel.kt @@ -36,6 +36,7 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.User import com.vitorpamplona.amethyst.service.relayClient.searchCommand.SearchQueryState import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrder +import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.relaySetupInfoBuilder import com.vitorpamplona.quartz.nip05DnsIdentifiers.namecoin.NamecoinLookupException import com.vitorpamplona.quartz.nip05DnsIdentifiers.namecoin.NamecoinNameResolver import com.vitorpamplona.quartz.nip10Notes.content.findHashtags @@ -207,6 +208,24 @@ class SearchBarViewModel( }.flowOn(Dispatchers.IO) .stateIn(viewModelScope, WhileSubscribed(5000), emptyList()) + val relayResults = + combine( + searchValueFlow.debounce(100), + invalidations, + ) { term, version -> + if (term.length > 1) { + val lower = term.lowercase() + LocalCache.relayHints.relayDB + .filter { _, relay -> relay.url.contains(lower) } + .map { relaySetupInfoBuilder(it) } + .sortedByDescending { it.relayStat.receivedBytes } + .take(20) + } else { + emptyList() + } + }.flowOn(Dispatchers.IO) + .stateIn(viewModelScope, WhileSubscribed(5000), emptyList()) + override val isRefreshing = derivedStateOf { searchValue.isNotBlank() } override fun invalidateData(ignoreIfDoing: Boolean) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt index e9fd07139..da1f6c4b4 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/search/SearchScreen.kt @@ -54,6 +54,7 @@ import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.viewmodel.compose.viewModel +import com.vitorpamplona.amethyst.Amethyst import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.nip11RelayInfo.loadRelayInfo @@ -70,6 +71,7 @@ import com.vitorpamplona.amethyst.ui.note.SearchIcon import com.vitorpamplona.amethyst.ui.note.UserCompose import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.screen.loggedIn.chats.rooms.ChannelName +import com.vitorpamplona.amethyst.ui.screen.loggedIn.relays.common.BasicRelaySetupInfoClickableRow import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.FeedPadding @@ -242,6 +244,7 @@ private fun DisplaySearchResults( } val hashTags by searchBarViewModel.hashtagResults.collectAsStateWithLifecycle() + val relays by searchBarViewModel.relayResults.collectAsStateWithLifecycle() val users by searchBarViewModel.searchResultsUsers.collectAsStateWithLifecycle() val publicChatChannels by searchBarViewModel.searchResultsPublicChatChannels.collectAsStateWithLifecycle() val ephemeralChannels by searchBarViewModel.searchResultsEphemeralChannels.collectAsStateWithLifecycle() @@ -265,6 +268,23 @@ private fun DisplaySearchResults( ) } + itemsIndexed( + relays, + key = { _, item -> "relay${item.relay.url}" }, + ) { _, relayInfo -> + BasicRelaySetupInfoClickableRow( + item = relayInfo, + loadProfilePicture = accountViewModel.settings.showProfilePictures(), + loadRobohash = accountViewModel.settings.isNotPerformanceMode(), + onClick = { nav.nav(Route.RelayInfo(relayInfo.relay.url)) }, + onDelete = null, + nip11CachedRetriever = Amethyst.instance.nip11Cache, + modifier = Modifier.padding(vertical = 5.dp, horizontal = 10.dp), + accountViewModel = accountViewModel, + nav = nav, + ) + } + itemsIndexed( users, key = { _, item -> "u" + item.pubkeyHex },