From 1a543ff7b14a1538b9b7d5448c0dce541c35b68d Mon Sep 17 00:00:00 2001 From: Kgothatso Ngako Date: Wed, 1 Apr 2026 22:58:05 +0200 Subject: [PATCH] Almost time to do the search... --- .../ui/composable/SearchResultScreen.kt | 68 +++++++++++++++++-- .../ui/composable/navigation/AuxNavHost.kt | 3 +- .../ui/view/model/SearchResultViewModel.kt | 7 ++ .../ui/view/state/SearchResultListUIState.kt | 13 ++++ 4 files changed, 84 insertions(+), 7 deletions(-) create mode 100755 composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/state/SearchResultListUIState.kt diff --git a/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/SearchResultScreen.kt b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/SearchResultScreen.kt index ab859be1..7881fbba 100644 --- a/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/SearchResultScreen.kt +++ b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/SearchResultScreen.kt @@ -2,9 +2,13 @@ package ac.aux.compose.ui.composable import ac.aux.compose.repository.NostrRepository import ac.aux.compose.repository.SearchRepository +import ac.aux.compose.ui.composable.navigation.routes.ImplementationPendingRoute +import ac.aux.compose.ui.composable.navigation.routes.Route +import ac.aux.compose.ui.composable.widgets.feed.ListView import ac.aux.compose.ui.theme.AuxTheme import ac.aux.compose.ui.view.model.SearchResultType import ac.aux.compose.ui.view.model.SearchResultViewModel +import ac.aux.compose.ui.view.state.SearchResultListUIState import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -14,6 +18,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.text.input.rememberTextFieldState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBackIosNew @@ -45,6 +50,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.semantics.isTraversalGroup import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.traversalIndex +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -57,6 +63,7 @@ fun SearchResultScreen( nostrRepository: NostrRepository, searchRepository: SearchRepository, onNavigateBack: () -> Unit, + onNavigateToEvent: (Route) -> Unit ) { val searchViewModel: SearchResultViewModel = viewModel( factory = SearchResultViewModel.factory( @@ -203,12 +210,60 @@ fun SearchResultScreen( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(10.dp) ) { - item { - Spacer( - modifier = Modifier.height(50.dp) - ) - LoadingIndicator() + when (val searchResultListUIState = searchViewModel.searchResultListUIState) { + SearchResultListUIState.Error -> { + item { + Spacer( + modifier = Modifier.height(50.dp) + ) + Text( + text = "Something went wrong", + ) + } + } + is SearchResultListUIState.Loaded -> { + if (searchResultListUIState.localNostrEvents.isEmpty()) { + item { + Spacer( + modifier = Modifier.height(50.dp) + ) + Text( + text = "No events were found", + ) + } + } else { + items( + items = searchResultListUIState.localNostrEvents, + key = {localNostrEvent -> localNostrEvent.nostrEvent.id} + ) { localNostrEvent -> + localNostrEvent.ListView( + onNavigateToEvent = { + onNavigateToEvent.invoke( + ImplementationPendingRoute("Navigating to detail") + ) + } + ) + } + } + + } + SearchResultListUIState.Loading -> { + item { + Spacer( + modifier = Modifier.height(50.dp) + ) + Text( + text = "Searching for ${searchViewModel.searchResultType.name.lowercase()} on \"${searchQuery.lowercase()}\"", + textAlign = TextAlign.Center + ) + Spacer( + modifier = Modifier.height(50.dp) + ) + + LoadingIndicator() + } + } } } } @@ -228,7 +283,8 @@ private fun SearchResultScreenPreview() { searchQuery = "What happened...", nostrRepository = NostrRepository.NO_OP_NOSTR_REPOSITORY, searchRepository = SearchRepository.NO_OP_SEARCH_REPOSITORY, - onNavigateBack = {} + onNavigateBack = {}, + onNavigateToEvent = {} ) } } diff --git a/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/navigation/AuxNavHost.kt b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/navigation/AuxNavHost.kt index bf7afeb6..d6b646d8 100644 --- a/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/navigation/AuxNavHost.kt +++ b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/composable/navigation/AuxNavHost.kt @@ -357,7 +357,8 @@ fun AuxNavHost( searchRepository = searchRepository, onNavigateBack = { navController.popBackStack() - } + }, + onNavigateToEvent = {} ) } composable { backStackEntry -> diff --git a/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/model/SearchResultViewModel.kt b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/model/SearchResultViewModel.kt index 11dfed9e..e230ed1c 100755 --- a/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/model/SearchResultViewModel.kt +++ b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/model/SearchResultViewModel.kt @@ -5,6 +5,7 @@ import ac.aux.compose.database.model.types.SynchronizationFilter import ac.aux.compose.nostr.Relays import ac.aux.compose.repository.NostrRepository import ac.aux.compose.repository.SearchRepository +import ac.aux.compose.ui.view.state.SearchResultListUIState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -36,6 +37,8 @@ class SearchResultViewModel( var searchResultType: SearchResultType by mutableStateOf(initialSearchResultType) private set + var searchResultListUIState: SearchResultListUIState by mutableStateOf(SearchResultListUIState.Loading) + private set fun updateSearchResultType (searchResultType: SearchResultType) { this.searchResultType = searchResultType @@ -43,6 +46,10 @@ class SearchResultViewModel( // TODO: Reload search results... } + fun reloadSearchResult() { + searchResultListUIState = SearchResultListUIState.Loading + } + fun performSearch(searchQuery: String) { viewModelScope.launch(Dispatchers.IO) { // Sync Notifications... might want to also run this in the background diff --git a/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/state/SearchResultListUIState.kt b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/state/SearchResultListUIState.kt new file mode 100755 index 00000000..a63f655b --- /dev/null +++ b/composeApp/src/commonMain/kotlin/ac/aux/compose/ui/view/state/SearchResultListUIState.kt @@ -0,0 +1,13 @@ +package ac.aux.compose.ui.view.state + +import ac.aux.compose.database.model.intermdiate.LocalNostrEvent + +sealed interface SearchResultListUIState { + data class Loaded( + val localNostrEvents: List + ): SearchResultListUIState + + data object Error: SearchResultListUIState + data object Loading: SearchResultListUIState +} +