Merge pull request #131 from lihenggui/feature/interests

Migrate search module
pull/2064/head
Mercury Li 2 years ago committed by GitHub
commit ce3d08b8ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -62,7 +62,7 @@ As Firebase Analytics does not yet support Kotlin Multiplatform, the implementat
| :feature:bookmarks | In progress | ✔️ | ✔️ | ✔️ | ❌ |
| :feature:foryou | In progress | ✔️ | ✔️ | ✔️ | ❌ |
| :feature:interests | In progress | ✔️ | ✔️ | ✔️ | ❌ |
| :feature:search | Not started | ❌ | ❌ | ❌ | ❌ |
| :feature:search | In progress | ✔️ | ✔️ | ✔️ | ❌ |
| :feature:settings | Not started | ❌ | ❌ | ❌ | ❌ |
| :feature:topic | Not started | ❌ | ❌ | ❌ | ❌ |
| lint | Not started | ❌ | ❌ | ❌ | ❌ |

@ -21,6 +21,7 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.dependencies
import org.jetbrains.kotlin.compose.compiler.gradle.ComposeCompilerGradlePluginExtension
// Convention plugin for the Compose Multiplatform feature module
class CmpFeatureConventionPlugin : Plugin<Project> {
@ -29,6 +30,8 @@ class CmpFeatureConventionPlugin : Plugin<Project> {
pluginManager.apply {
apply("nowinandroid.kmp.library")
apply("nowinandroid.kmp.inject")
apply("org.jetbrains.kotlin.plugin.compose")
apply("org.jetbrains.compose")
}
extensions.configure<LibraryExtension> {
defaultConfig {
@ -50,7 +53,13 @@ class CmpFeatureConventionPlugin : Plugin<Project> {
add("androidMainImplementation", libs.findLibrary("androidx.lifecycle.viewModelCompose").get())
add("androidMainImplementation", libs.findLibrary("androidx.tracing.ktx").get())
add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.compose.ui.test").get())
add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.lifecycle.runtimeTesting").get())
add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.test.core").get())
add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.test.ext").get())
add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.test.junit").get())
add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.test.runner").get())
add("androidInstrumentedTestImplementation", libs.findLibrary("androidx.test.espresso.core").get())
}
}
}

@ -48,3 +48,8 @@ kotlin {
}
}
}
compose.resources {
publicResClass = true
generateResClass = always
}

@ -16,9 +16,8 @@
plugins {
alias(libs.plugins.nowinandroid.cmp.feature)
alias(libs.plugins.jetbrains.compose)
alias(libs.plugins.compose)
alias(libs.plugins.nowinandroid.android.library.jacoco)
alias(libs.plugins.roborazzi)
}
android {

@ -37,6 +37,12 @@ import androidx.lifecycle.testing.TestLifecycleOwner
import com.google.samples.apps.nowinandroid.core.testing.data.userNewsResourcesTestData
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import kotlinx.coroutines.test.runTest
import nowinandroid.core.ui.generated.resources.core_ui_unbookmark
import nowinandroid.feature.bookmarks.generated.resources.Res
import nowinandroid.feature.bookmarks.generated.resources.feature_bookmarks_empty_description
import nowinandroid.feature.bookmarks.generated.resources.feature_bookmarks_empty_error
import nowinandroid.feature.bookmarks.generated.resources.feature_bookmarks_loading
import org.jetbrains.compose.resources.getString
import org.junit.Rule
import org.junit.Test
import kotlin.test.assertEquals
@ -51,7 +57,7 @@ class BookmarksScreenTest {
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
@Test
fun loading_showsLoadingSpinner() {
fun loading_showsLoadingSpinner() = runTest {
composeTestRule.setContent {
BookmarksScreen(
feedState = NewsFeedUiState.Loading,
@ -64,7 +70,7 @@ class BookmarksScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.feature_bookmarks_loading),
getString(Res.string.feature_bookmarks_loading),
)
.assertExists()
}
@ -109,7 +115,7 @@ class BookmarksScreenTest {
}
@Test
fun feed_whenRemovingBookmark_removesBookmark() {
fun feed_whenRemovingBookmark_removesBookmark() = runTest {
var removeFromBookmarksCalled = false
composeTestRule.setContent {
@ -129,8 +135,8 @@ class BookmarksScreenTest {
composeTestRule
.onAllNodesWithContentDescription(
composeTestRule.activity.getString(
com.google.samples.apps.nowinandroid.core.ui.R.string.core_ui_unbookmark,
getString(
nowinandroid.core.ui.generated.resources.Res.string.core_ui_unbookmark,
),
).filter(
hasAnyAncestor(
@ -148,7 +154,7 @@ class BookmarksScreenTest {
}
@Test
fun feed_whenHasNoBookmarks_showsEmptyState() {
fun feed_whenHasNoBookmarks_showsEmptyState() = runTest {
composeTestRule.setContent {
BookmarksScreen(
feedState = NewsFeedUiState.Success(emptyList()),
@ -161,13 +167,13 @@ class BookmarksScreenTest {
composeTestRule
.onNodeWithText(
composeTestRule.activity.getString(R.string.feature_bookmarks_empty_error),
getString(Res.string.feature_bookmarks_empty_error),
)
.assertExists()
composeTestRule
.onNodeWithText(
composeTestRule.activity.getString(R.string.feature_bookmarks_empty_description),
getString(Res.string.feature_bookmarks_empty_description),
)
.assertExists()
}

@ -16,8 +16,6 @@
plugins {
alias(libs.plugins.nowinandroid.cmp.feature)
alias(libs.plugins.jetbrains.compose)
alias(libs.plugins.compose)
alias(libs.plugins.nowinandroid.android.library.jacoco)
alias(libs.plugins.roborazzi)
}

@ -32,6 +32,12 @@ import com.google.samples.apps.nowinandroid.core.rules.GrantPostNotificationsPer
import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData
import com.google.samples.apps.nowinandroid.core.testing.data.userNewsResourcesTestData
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.test.runTest
import nowinandroid.feature.foryou.generated.resources.Res
import nowinandroid.feature.foryou.generated.resources.feature_foryou_done
import nowinandroid.feature.foryou.generated.resources.feature_foryou_loading
import org.jetbrains.compose.resources.getString
import org.junit.Rule
import org.junit.Test
@ -44,13 +50,13 @@ class ForYouScreenTest {
val composeTestRule = createAndroidComposeRule<ComponentActivity>()
private val doneButtonMatcher by lazy {
hasText(
composeTestRule.activity.resources.getString(R.string.feature_foryou_done),
)
runBlocking {
hasText(getString(Res.string.feature_foryou_done))
}
}
@Test
fun circularProgressIndicator_whenScreenIsLoading_exists() {
fun circularProgressIndicator_whenScreenIsLoading_exists() = runTest {
composeTestRule.setContent {
BoxWithConstraints {
ForYouScreen(
@ -70,13 +76,13 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
getString(Res.string.feature_foryou_loading),
)
.assertExists()
}
@Test
fun circularProgressIndicator_whenScreenIsSyncing_exists() {
fun circularProgressIndicator_whenScreenIsSyncing_exists() = runTest {
composeTestRule.setContent {
BoxWithConstraints {
ForYouScreen(
@ -96,7 +102,7 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
getString(Res.string.feature_foryou_loading),
)
.assertExists()
}
@ -194,7 +200,7 @@ class ForYouScreenTest {
}
@Test
fun feed_whenInterestsSelectedAndLoading_showsLoadingIndicator() {
fun feed_whenInterestsSelectedAndLoading_showsLoadingIndicator() = runTest {
composeTestRule.setContent {
BoxWithConstraints {
ForYouScreen(
@ -215,13 +221,13 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
getString(Res.string.feature_foryou_loading),
)
.assertExists()
}
@Test
fun feed_whenNoInterestsSelectionAndLoading_showsLoadingIndicator() {
fun feed_whenNoInterestsSelectionAndLoading_showsLoadingIndicator() = runTest {
composeTestRule.setContent {
BoxWithConstraints {
ForYouScreen(
@ -241,7 +247,7 @@ class ForYouScreenTest {
composeTestRule
.onNodeWithContentDescription(
composeTestRule.activity.resources.getString(R.string.feature_foryou_loading),
getString(Res.string.feature_foryou_loading),
)
.assertExists()
}

@ -16,8 +16,6 @@
plugins {
alias(libs.plugins.nowinandroid.cmp.feature)
alias(libs.plugins.jetbrains.compose)
alias(libs.plugins.compose)
alias(libs.plugins.nowinandroid.android.library.jacoco)
alias(libs.plugins.roborazzi)
}

@ -27,11 +27,17 @@ import androidx.compose.ui.test.onNodeWithText
import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData
import com.google.samples.apps.nowinandroid.feature.interests.InterestsScreen
import com.google.samples.apps.nowinandroid.feature.interests.InterestsUiState
import kotlinx.coroutines.runBlocking
import nowinandroid.core.ui.generated.resources.core_ui_interests_card_follow_button_content_desc
import nowinandroid.core.ui.generated.resources.core_ui_interests_card_unfollow_button_content_desc
import nowinandroid.feature.interests.generated.resources.feature_interests_empty_header
import nowinandroid.feature.interests.generated.resources.feature_interests_loading
import org.jetbrains.compose.resources.getString
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import com.google.samples.apps.nowinandroid.core.ui.R as CoreUiR
import com.google.samples.apps.nowinandroid.feature.interests.R as InterestsR
import nowinandroid.core.ui.generated.resources.Res as CoreUiR
import nowinandroid.feature.interests.generated.resources.Res as InterestsR
/**
* UI test for checking the correct behaviour of the Interests screen;
@ -50,7 +56,8 @@ class InterestsScreenTest {
@Before
fun setup() {
composeTestRule.activity.apply {
// Temp solution to call getString
runBlocking {
interestsLoading = getString(InterestsR.string.feature_interests_loading)
interestsEmptyHeader = getString(InterestsR.string.feature_interests_empty_header)
interestsTopicCardFollowButton =

@ -15,22 +15,41 @@
*/
plugins {
alias(libs.plugins.nowinandroid.android.feature)
alias(libs.plugins.nowinandroid.android.library.compose)
alias(libs.plugins.nowinandroid.cmp.feature)
alias(libs.plugins.nowinandroid.android.library.jacoco)
alias(libs.plugins.roborazzi)
}
android {
namespace = "com.google.samples.apps.nowinandroid.feature.search"
}
dependencies {
implementation(projects.core.data)
implementation(projects.core.domain)
implementation(projects.core.ui)
testImplementation(projects.core.testing)
androidTestImplementation(projects.core.testing)
kotlin {
sourceSets {
commonMain.dependencies {
implementation(projects.core.data)
implementation(projects.core.domain)
implementation(projects.core.ui)
implementation(compose.material3)
implementation(compose.foundation)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
}
commonMain.dependencies {
implementation(projects.core.testing)
}
androidUnitTest.dependencies {
implementation(libs.robolectric)
implementation(libs.roborazzi)
implementation(projects.core.screenshotTesting)
}
androidInstrumentedTest.dependencies {
implementation(projects.core.testing)
}
}
}
compose.resources {
publicResClass = true
}

@ -35,10 +35,23 @@ import com.google.samples.apps.nowinandroid.core.model.data.UserData
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import com.google.samples.apps.nowinandroid.core.testing.data.followableTopicTestData
import com.google.samples.apps.nowinandroid.core.testing.data.newsResourcesTestData
import com.google.samples.apps.nowinandroid.core.ui.R.string
import kotlinx.coroutines.runBlocking
import nowinandroid.core.ui.generated.resources.core_ui_interests_card_follow_button_content_desc
import nowinandroid.core.ui.generated.resources.core_ui_interests_card_unfollow_button_content_desc
import nowinandroid.feature.search.generated.resources.Res
import nowinandroid.feature.search.generated.resources.feature_search_clear_recent_searches_content_desc
import nowinandroid.feature.search.generated.resources.feature_search_clear_search_text_content_desc
import nowinandroid.feature.search.generated.resources.feature_search_interests
import nowinandroid.feature.search.generated.resources.feature_search_not_ready
import nowinandroid.feature.search.generated.resources.feature_search_to_browse_topics
import nowinandroid.feature.search.generated.resources.feature_search_topics
import nowinandroid.feature.search.generated.resources.feature_search_try_another_search
import nowinandroid.feature.search.generated.resources.feature_search_updates
import org.jetbrains.compose.resources.getString
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import nowinandroid.core.ui.generated.resources.Res as uiR
/**
* UI test for checking the correct behaviour of the Search screen.
@ -68,20 +81,18 @@ class SearchScreenTest {
)
@Before
fun setup() {
composeTestRule.activity.apply {
clearSearchContentDesc = getString(R.string.feature_search_clear_search_text_content_desc)
clearRecentSearchesContentDesc = getString(R.string.feature_search_clear_recent_searches_content_desc)
followButtonContentDesc =
getString(string.core_ui_interests_card_follow_button_content_desc)
unfollowButtonContentDesc =
getString(string.core_ui_interests_card_unfollow_button_content_desc)
topicsString = getString(R.string.feature_search_topics)
updatesString = getString(R.string.feature_search_updates)
tryAnotherSearchString = getString(R.string.feature_search_try_another_search) +
" " + getString(R.string.feature_search_interests) + " " + getString(R.string.feature_search_to_browse_topics)
searchNotReadyString = getString(R.string.feature_search_not_ready)
}
fun setup() = runBlocking {
clearSearchContentDesc = getString(Res.string.feature_search_clear_search_text_content_desc)
clearRecentSearchesContentDesc = getString(Res.string.feature_search_clear_recent_searches_content_desc)
followButtonContentDesc =
getString(uiR.string.core_ui_interests_card_follow_button_content_desc)
unfollowButtonContentDesc =
getString(uiR.string.core_ui_interests_card_unfollow_button_content_desc)
topicsString = getString(Res.string.feature_search_topics)
updatesString = getString(Res.string.feature_search_updates)
tryAnotherSearchString = getString(Res.string.feature_search_try_another_search) +
" " + getString(Res.string.feature_search_interests) + " " + getString(Res.string.feature_search_to_browse_topics)
searchNotReadyString = getString(Res.string.feature_search_not_ready)
}
@Test

@ -64,7 +64,6 @@ import androidx.compose.ui.input.key.key
import androidx.compose.ui.input.key.onKeyEvent
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
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
@ -74,11 +73,7 @@ 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
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.DraggableScrollbar
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.rememberDraggableScroller
import com.google.samples.apps.nowinandroid.core.designsystem.component.scrollbar.scrollbarState
@ -89,10 +84,26 @@ import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
import com.google.samples.apps.nowinandroid.core.ui.DevicePreviews
import com.google.samples.apps.nowinandroid.core.ui.InterestsItem
import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState.Success
import com.google.samples.apps.nowinandroid.core.ui.R.string
import com.google.samples.apps.nowinandroid.core.ui.TrackScreenViewEvent
import com.google.samples.apps.nowinandroid.core.ui.collectAsStateWithLifecycle
import com.google.samples.apps.nowinandroid.core.ui.newsFeed
import com.google.samples.apps.nowinandroid.feature.search.R as searchR
import nowinandroid.core.ui.generated.resources.core_ui_back
import nowinandroid.feature.search.generated.resources.feature_search_clear_recent_searches_content_desc
import nowinandroid.feature.search.generated.resources.feature_search_clear_search_text_content_desc
import nowinandroid.feature.search.generated.resources.feature_search_interests
import nowinandroid.feature.search.generated.resources.feature_search_not_ready
import nowinandroid.feature.search.generated.resources.feature_search_recent_searches
import nowinandroid.feature.search.generated.resources.feature_search_result_not_found
import nowinandroid.feature.search.generated.resources.feature_search_title
import nowinandroid.feature.search.generated.resources.feature_search_to_browse_topics
import nowinandroid.feature.search.generated.resources.feature_search_topics
import nowinandroid.feature.search.generated.resources.feature_search_try_another_search
import nowinandroid.feature.search.generated.resources.feature_search_updates
import org.jetbrains.compose.resources.stringResource
import org.jetbrains.compose.ui.tooling.preview.Preview
import org.jetbrains.compose.ui.tooling.preview.PreviewParameter
import nowinandroid.core.ui.generated.resources.Res as uiR
import nowinandroid.feature.search.generated.resources.Res as searchR
@Composable
internal fun SearchRoute(
@ -100,7 +111,7 @@ internal fun SearchRoute(
onInterestsClick: () -> Unit,
onTopicClick: (String) -> Unit,
modifier: Modifier = Modifier,
searchViewModel: SearchViewModel = hiltViewModel(),
searchViewModel: SearchViewModel,
) {
val recentSearchQueriesUiState by searchViewModel.recentSearchQueriesUiState.collectAsStateWithLifecycle()
val searchResultUiState by searchViewModel.searchResultUiState.collectAsStateWithLifecycle()
@ -210,7 +221,7 @@ fun EmptySearchResultBody(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.padding(horizontal = 48.dp),
) {
val message = stringResource(id = searchR.string.feature_search_result_not_found, searchQuery)
val message = stringResource(searchR.string.feature_search_result_not_found, searchQuery)
val start = message.indexOf(searchQuery)
Text(
text = AnnotatedString(
@ -227,9 +238,9 @@ fun EmptySearchResultBody(
textAlign = TextAlign.Center,
modifier = Modifier.padding(vertical = 24.dp),
)
val interests = stringResource(id = searchR.string.feature_search_interests)
val interests = stringResource(searchR.string.feature_search_interests)
val tryAnotherSearchString = buildAnnotatedString {
append(stringResource(id = searchR.string.feature_search_try_another_search))
append(stringResource(searchR.string.feature_search_try_another_search))
append(" ")
withStyle(
style = SpanStyle(
@ -241,7 +252,7 @@ fun EmptySearchResultBody(
append(interests)
}
append(" ")
append(stringResource(id = searchR.string.feature_search_to_browse_topics))
append(stringResource(searchR.string.feature_search_to_browse_topics))
}
ClickableText(
text = tryAnotherSearchString,
@ -269,7 +280,7 @@ private fun SearchNotReadyBody() {
modifier = Modifier.padding(horizontal = 48.dp),
) {
Text(
text = stringResource(id = searchR.string.feature_search_not_ready),
text = stringResource(searchR.string.feature_search_not_ready),
style = MaterialTheme.typography.bodyLarge,
textAlign = TextAlign.Center,
modifier = Modifier.padding(vertical = 24.dp),
@ -310,7 +321,7 @@ private fun SearchResultBody(
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(id = searchR.string.feature_search_topics))
append(stringResource(searchR.string.feature_search_topics))
}
},
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
@ -346,7 +357,7 @@ private fun SearchResultBody(
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(id = searchR.string.feature_search_updates))
append(stringResource(searchR.string.feature_search_updates))
}
},
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
@ -398,7 +409,7 @@ private fun RecentSearchesBody(
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(stringResource(id = searchR.string.feature_search_recent_searches))
append(stringResource(searchR.string.feature_search_recent_searches))
}
},
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
@ -413,7 +424,7 @@ private fun RecentSearchesBody(
Icon(
imageVector = NiaIcons.Close,
contentDescription = stringResource(
id = searchR.string.feature_search_clear_recent_searches_content_desc,
searchR.string.feature_search_clear_recent_searches_content_desc,
),
tint = MaterialTheme.colorScheme.onSurface,
)
@ -451,7 +462,7 @@ private fun SearchToolbar(
Icon(
imageVector = NiaIcons.ArrowBack,
contentDescription = stringResource(
id = string.core_ui_back,
uiR.string.core_ui_back,
),
)
}
@ -487,7 +498,7 @@ private fun SearchTextField(
Icon(
imageVector = NiaIcons.Search,
contentDescription = stringResource(
id = searchR.string.feature_search_title,
searchR.string.feature_search_title,
),
tint = MaterialTheme.colorScheme.onSurface,
)
@ -502,7 +513,7 @@ private fun SearchTextField(
Icon(
imageVector = NiaIcons.Close,
contentDescription = stringResource(
id = searchR.string.feature_search_clear_search_text_content_desc,
searchR.string.feature_search_clear_search_text_content_desc,
),
tint = MaterialTheme.colorScheme.onSurface,
)

@ -18,10 +18,10 @@
package com.google.samples.apps.nowinandroid.feature.search
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.newsResources
import com.google.samples.apps.nowinandroid.core.ui.PreviewParameterData.topics
import org.jetbrains.compose.ui.tooling.preview.PreviewParameterProvider
/**
* This [PreviewParameterProvider](https://developer.android.com/reference/kotlin/androidx/compose/ui/tooling/preview/PreviewParameterProvider)

@ -28,7 +28,7 @@ import com.google.samples.apps.nowinandroid.core.data.repository.UserDataReposit
import com.google.samples.apps.nowinandroid.core.domain.GetRecentSearchQueriesUseCase
import com.google.samples.apps.nowinandroid.core.domain.GetSearchContentsUseCase
import com.google.samples.apps.nowinandroid.core.model.data.UserSearchResult
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.catch
@ -37,9 +37,9 @@ import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import javax.inject.Inject
import me.tatarka.inject.annotations.Inject
@HiltViewModel
@OptIn(ExperimentalCoroutinesApi::class)
class SearchViewModel @Inject constructor(
getSearchContentsUseCase: GetSearchContentsUseCase,
recentSearchQueriesUseCase: GetRecentSearchQueriesUseCase,

@ -20,7 +20,6 @@ import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.google.samples.apps.nowinandroid.feature.search.SearchRoute
const val SEARCH_ROUTE = "search_route"
@ -34,10 +33,10 @@ fun NavGraphBuilder.searchScreen(
// TODO: Handle back stack for each top-level destination. At the moment each top-level
// destination may have own search screen's back stack.
composable(route = SEARCH_ROUTE) {
SearchRoute(
onBackClick = onBackClick,
onInterestsClick = onInterestsClick,
onTopicClick = onTopicClick,
)
// SearchRoute(
// onBackClick = onBackClick,
// onInterestsClick = onInterestsClick,
// onTopicClick = onTopicClick,
// )
}
}

@ -1,17 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest />
Loading…
Cancel
Save