diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchView.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchView.kt index 951154aa3..6ba109866 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchView.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchView.kt @@ -26,9 +26,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -53,14 +51,8 @@ private val bus = listOf(Bu.RTS, Bu.SRF, Bu.RSI, Bu.RTR, Bu.SWI) @Composable fun SearchView(searchViewModel: SearchViewModel, onSearchClicked: (Content.Media) -> Unit) { val lazyItems = searchViewModel.result.collectAsLazyPagingItems() - val currentBu = searchViewModel.bu.collectAsState() - val searchQuery = searchViewModel.query.collectAsState() - var queryState by remember(searchQuery.value) { - mutableStateOf(searchQuery.value) - } - LaunchedEffect(queryState) { - searchViewModel.query.value = queryState - } + val currentBu by searchViewModel.bu.collectAsState() + val searchQuery by searchViewModel.query.collectAsState() val focusRequester = remember { FocusRequester() } Column( modifier = Modifier.padding(8.dp), @@ -81,8 +73,8 @@ fun SearchView(searchViewModel: SearchViewModel, onSearchClicked: (Content.Media singleLine = true, maxLines = 1, placeholder = { Text(text = "Search") }, - value = queryState, - onValueChange = { queryState = it } + value = searchQuery, + onValueChange = searchViewModel::setQuery ) if (lazyItems.itemCount == 0 && lazyItems.loadState.refresh is LoadState.NotLoading) { Box( @@ -97,7 +89,7 @@ fun SearchView(searchViewModel: SearchViewModel, onSearchClicked: (Content.Media SearchResultList( lazyPagingItems = lazyItems, contentClick = onSearchClicked, - currentBu = currentBu.value, + currentBu = currentBu, buClicked = searchViewModel::selectBu ) } @@ -142,6 +134,16 @@ private fun SearchResultList( } } } + // We didn't receive any results + if (lazyPagingItems.itemCount == 1 && lazyPagingItems[0] is SearchContent.BuSelector) { + item { + NoResult( + modifier = Modifier + .fillMaxWidth() + .padding(12.dp) + ) + } + } if (lazyPagingItems.loadState.refresh is LoadState.Error) { item { ErrorView(error = (lazyPagingItems.loadState.refresh as LoadState.Error).error) @@ -174,6 +176,16 @@ private fun BuSelector(listBu: List, selectedBu: Bu, onBuSelected: (Bu) -> U } } +@Composable +private fun NoResult(modifier: Modifier = Modifier) { + Box( + modifier = modifier, + contentAlignment = Alignment.Center + ) { + Text(text = "No result") + } +} + @Composable private fun LoadingView(modifier: Modifier = Modifier) { Box(modifier = modifier, contentAlignment = Alignment.Center) { diff --git a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchViewModel.kt b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchViewModel.kt index db06d5679..92be55918 100644 --- a/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchViewModel.kt +++ b/pillarbox-demo/src/main/java/ch/srgssr/pillarbox/demo/ui/integrationLayer/SearchViewModel.kt @@ -19,6 +19,7 @@ import ch.srgssr.pillarbox.demo.ui.integrationLayer.data.ILRepository import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf @@ -31,15 +32,20 @@ import kotlinx.coroutines.flow.map * @constructor Create empty Search view model */ class SearchViewModel(private val ilRepository: ILRepository) : ViewModel() { + private val _bu = MutableStateFlow(Bu.RTS) + /** - * Current selected [Bu]. + * Currently selected [Bu]. */ - val bu = MutableStateFlow(Bu.RTS) + val bu: StateFlow = _bu + + private val _query = MutableStateFlow("") /** * Current search query string. */ - val query = MutableStateFlow("") + val query: StateFlow = _query + private val config = combine(bu, query) { bu, query -> Config(bu, query) } /** @@ -70,7 +76,16 @@ class SearchViewModel(private val ilRepository: ILRepository) : ViewModel() { * Clear search query parameter. */ fun clear() { - query.value = "" + _query.value = "" + } + + /** + * Set the search query. + * + * @param query The search query + */ + fun setQuery(query: String) { + _query.value = query } /** @@ -79,7 +94,7 @@ class SearchViewModel(private val ilRepository: ILRepository) : ViewModel() { * @param bu The [Bu] to select. */ fun selectBu(bu: Bu) { - this.bu.value = bu + _bu.value = bu } internal data class Config(val bu: Bu, val query: String)