Skip to content

Commit

Permalink
Display "No result" when necessary (#284)
Browse files Browse the repository at this point in the history
Co-authored-by: Joaquim Stähli <[email protected]>
  • Loading branch information
MGaetan89 and StaehliJ authored Nov 2, 2023
1 parent ac03653 commit aa2245d
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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),
Expand All @@ -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(
Expand All @@ -97,7 +89,7 @@ fun SearchView(searchViewModel: SearchViewModel, onSearchClicked: (Content.Media
SearchResultList(
lazyPagingItems = lazyItems,
contentClick = onSearchClicked,
currentBu = currentBu.value,
currentBu = currentBu,
buClicked = searchViewModel::selectBu
)
}
Expand All @@ -115,6 +107,10 @@ private fun SearchResultList(
buClicked: (Bu) -> Unit,
modifier: Modifier = Modifier
) {
val hasNoResult = lazyPagingItems.loadState.refresh is LoadState.NotLoading &&
lazyPagingItems.itemCount == 1 &&
lazyPagingItems[0] is SearchContent.BuSelector

LazyColumn(modifier = modifier) {
items(count = lazyPagingItems.itemCount, key = lazyPagingItems.itemKey()) { index ->
val item = lazyPagingItems[index]
Expand Down Expand Up @@ -142,6 +138,15 @@ private fun SearchResultList(
}
}
}
if (hasNoResult) {
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)
Expand Down Expand Up @@ -174,6 +179,16 @@ private fun BuSelector(listBu: List<Bu>, 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ 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.debounce
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlin.time.Duration.Companion.milliseconds

/**
* Search view model to search media for the chosen bu
Expand All @@ -31,23 +34,28 @@ 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> = _bu

private val _query = MutableStateFlow("")

/**
* Current search query string.
*/
val query = MutableStateFlow("")
private val config = combine(bu, query) { bu, query -> Config(bu, query) }
val query: StateFlow<String> = _query

private val config = combine(bu, query) { bu, query -> Config(bu, query) }.debounce(600.milliseconds)

/**
* Result of the search trigger by [bu] and [query]
*/
@OptIn(ExperimentalCoroutinesApi::class)
val result: Flow<PagingData<SearchContent>> = config.flatMapLatest { config ->
if (config.query.isNotBlank() || config.query.length >= 3) {
if (config.query.length >= 3) {
ilRepository.search(config.bu, config.query).map { mediaPagingData ->
val pagingData: PagingData<SearchContent> = mediaPagingData.map { item -> SearchContent.MediaResult(Content.Media(item)) }
pagingData.insertHeaderItem(item = SearchContent.BuSelector)
Expand All @@ -70,7 +78,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
}

/**
Expand All @@ -79,7 +96,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)
Expand Down

0 comments on commit aa2245d

Please sign in to comment.