diff --git a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt index 63b20374d..913c21d9d 100644 --- a/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt +++ b/core/data/src/main/java/com/google/samples/apps/nowinandroid/core/data/repository/DefaultSearchContentsRepository.kt @@ -61,7 +61,7 @@ class DefaultSearchContentsRepository @Inject constructor( .mapLatest { it.toSet() } .distinctUntilChanged() .flatMapLatest { - newsResourceDao.getNewsResources(filterNewsIds = it) + newsResourceDao.getNewsResources(useFilterNewsIds = true, filterNewsIds = it) } val topicsFlow = topicIds .mapLatest { it.toSet() } diff --git a/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt b/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt index 3aa795332..760437af8 100644 --- a/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt +++ b/feature/search/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreenTest.kt @@ -102,6 +102,29 @@ class SearchScreenTest { .assertIsDisplayed() } + @Test + fun emptySearchResult_nonEmptyRecentSearches_emptySearchScreenAndRecentSearchesAreDisplayed() { + val recentSearches = listOf("kotlin") + composeTestRule.setContent { + SearchScreen( + searchResultUiState = SearchResultUiState.Success(), + recentSearchesUiState = RecentSearchQueriesUiState.Success( + recentQueries = recentSearches.map(::RecentSearchQuery), + ), + ) + } + + composeTestRule + .onNodeWithText(tryAnotherSearchString) + .assertIsDisplayed() + composeTestRule + .onNodeWithContentDescription(clearRecentSearchesContentDesc) + .assertIsDisplayed() + composeTestRule + .onNodeWithText("kotlin") + .assertIsDisplayed() + } + @Test fun searchResultWithTopics_allTopicsAreVisible_followButtonsVisibleForTheNumOfFollowedTopics() { composeTestRule.setContent { diff --git a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt b/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt index 82a455cb7..f5c588dbc 100644 --- a/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt +++ b/feature/search/src/main/java/com/google/samples/apps/nowinandroid/feature/search/SearchScreen.kt @@ -63,10 +63,12 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontFamily import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.text.withStyle import androidx.compose.ui.tooling.preview.Preview @@ -147,6 +149,7 @@ internal fun SearchScreen( SearchResultUiState.Loading, SearchResultUiState.LoadFailed, -> Unit + SearchResultUiState.EmptyQuery, -> { if (recentSearchesUiState is RecentSearchQueriesUiState.Success) { @@ -167,6 +170,16 @@ internal fun SearchScreen( onInterestsClick = onInterestsClick, searchQuery = searchQuery, ) + if (recentSearchesUiState is RecentSearchQueriesUiState.Success) { + RecentSearchesBody( + onClearRecentSearches = onClearRecentSearches, + onRecentSearchClicked = { + onSearchQueryChanged(it) + onSearchTriggered(it) + }, + recentSearchQueries = recentSearchesUiState.recentQueries.map { it.query }, + ) + } } else { SearchResultBody( topics = searchResultUiState.topics, @@ -189,7 +202,10 @@ fun EmptySearchResultBody( onInterestsClick: () -> Unit, searchQuery: String, ) { - Column(horizontalAlignment = Alignment.CenterHorizontally) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier.padding(horizontal = 48.dp), + ) { val message = stringResource(id = searchR.string.search_result_not_found, searchQuery) val start = message.indexOf(searchQuery) Text( @@ -203,26 +219,34 @@ fun EmptySearchResultBody( ), ), ), - modifier = Modifier.padding(horizontal = 36.dp, vertical = 24.dp), + fontSize = 18.sp, + textAlign = TextAlign.Center, + modifier = Modifier.padding(vertical = 24.dp), ) val interests = stringResource(id = searchR.string.interests) val tryAnotherSearchString = buildAnnotatedString { - append(stringResource(id = searchR.string.try_another_search)) - append(" ") - withStyle( - style = SpanStyle( - textDecoration = TextDecoration.Underline, - fontWeight = FontWeight.Bold, - ), - ) { - pushStringAnnotation(tag = interests, annotation = interests) - append(interests) + withStyle(style = SpanStyle(fontSize = 18.sp)) { + append(stringResource(id = searchR.string.try_another_search)) + append(" ") + withStyle( + style = SpanStyle( + textDecoration = TextDecoration.Underline, + fontWeight = FontWeight.Bold, + ), + ) { + pushStringAnnotation(tag = interests, annotation = interests) + append(interests) + } + append(" ") + append(stringResource(id = searchR.string.to_browse_topics)) } - append(" ") - append(stringResource(id = searchR.string.to_browse_topics)) } ClickableText( text = tryAnotherSearchString, + style = TextStyle( + textAlign = TextAlign.Center, + lineHeight = 24.sp, + ), modifier = Modifier .padding(start = 36.dp, end = 36.dp, bottom = 24.dp) .clickable {}, @@ -454,7 +478,8 @@ private fun SearchTextField( } else { false } - }.testTag("searchTextField"), + } + .testTag("searchTextField"), shape = RoundedCornerShape(32.dp), value = searchQuery, keyboardOptions = KeyboardOptions(