replace object with data object in search feature, simple format code for the reader

pull/913/head
hoangchungk53qx1 2 years ago
parent 014d388e92
commit cd30ecf359

@ -19,7 +19,7 @@ package com.google.samples.apps.nowinandroid.feature.search
import com.google.samples.apps.nowinandroid.core.data.model.RecentSearchQuery import com.google.samples.apps.nowinandroid.core.data.model.RecentSearchQuery
sealed interface RecentSearchQueriesUiState { sealed interface RecentSearchQueriesUiState {
object Loading : RecentSearchQueriesUiState data object Loading : RecentSearchQueriesUiState
data class Success( data class Success(
val recentQueries: List<RecentSearchQuery> = emptyList(), val recentQueries: List<RecentSearchQuery> = emptyList(),

@ -20,14 +20,14 @@ import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource import com.google.samples.apps.nowinandroid.core.model.data.UserNewsResource
sealed interface SearchResultUiState { sealed interface SearchResultUiState {
object Loading : SearchResultUiState data object Loading : SearchResultUiState
/** /**
* The state query is empty or too short. To distinguish the state between the * The state query is empty or too short. To distinguish the state between the
* (initial state or when the search query is cleared) vs the state where no search * (initial state or when the search query is cleared) vs the state where no search
* result is returned, explicitly define the empty query state. * result is returned, explicitly define the empty query state.
*/ */
object EmptyQuery : SearchResultUiState data object EmptyQuery : SearchResultUiState
object LoadFailed : SearchResultUiState object LoadFailed : SearchResultUiState
@ -42,5 +42,5 @@ sealed interface SearchResultUiState {
* A state where the search contents are not ready. This happens when the *Fts tables are not * A state where the search contents are not ready. This happens when the *Fts tables are not
* populated yet. * populated yet.
*/ */
object SearchNotReady : SearchResultUiState data object SearchNotReady : SearchResultUiState
} }

@ -312,11 +312,7 @@ private fun SearchResultBody(
state = state, state = state,
) { ) {
if (topics.isNotEmpty()) { if (topics.isNotEmpty()) {
item( item(span = { GridItemSpan(maxLineSpan) }) {
span = {
GridItemSpan(maxLineSpan)
},
) {
Text( Text(
text = buildAnnotatedString { text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
@ -330,9 +326,7 @@ private fun SearchResultBody(
val topicId = followableTopic.topic.id val topicId = followableTopic.topic.id
item( item(
key = "topic-$topicId", // Append a prefix to distinguish a key for news resources key = "topic-$topicId", // Append a prefix to distinguish a key for news resources
span = { span = { GridItemSpan(maxLineSpan) },
GridItemSpan(maxLineSpan)
},
) { ) {
InterestsItem( InterestsItem(
name = followableTopic.topic.name, name = followableTopic.topic.name,
@ -351,11 +345,7 @@ private fun SearchResultBody(
} }
if (newsResources.isNotEmpty()) { if (newsResources.isNotEmpty()) {
item( item(span = { GridItemSpan(maxLineSpan) }) {
span = {
GridItemSpan(maxLineSpan)
},
) {
Text( Text(
text = buildAnnotatedString { text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) { withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
@ -440,9 +430,7 @@ private fun RecentSearchesBody(
style = MaterialTheme.typography.headlineSmall, style = MaterialTheme.typography.headlineSmall,
modifier = Modifier modifier = Modifier
.padding(vertical = 16.dp) .padding(vertical = 16.dp)
.clickable { .clickable { onRecentSearchClicked(recentSearch) }
onRecentSearchClicked(recentSearch)
}
.fillMaxWidth(), .fillMaxWidth(),
) )
} }

@ -51,7 +51,8 @@ class SearchViewModel @Inject constructor(
val searchQuery = savedStateHandle.getStateFlow(SEARCH_QUERY, "") val searchQuery = savedStateHandle.getStateFlow(SEARCH_QUERY, "")
val searchResultUiState: StateFlow<SearchResultUiState> = val searchResultUiState: StateFlow<SearchResultUiState> =
getSearchContentsCountUseCase().flatMapLatest { totalCount -> getSearchContentsCountUseCase()
.flatMapLatest { totalCount ->
if (totalCount < SEARCH_MIN_FTS_ENTITY_COUNT) { if (totalCount < SEARCH_MIN_FTS_ENTITY_COUNT) {
flowOf(SearchResultUiState.SearchNotReady) flowOf(SearchResultUiState.SearchNotReady)
} else { } else {
@ -59,35 +60,32 @@ class SearchViewModel @Inject constructor(
if (query.length < SEARCH_QUERY_MIN_LENGTH) { if (query.length < SEARCH_QUERY_MIN_LENGTH) {
flowOf(SearchResultUiState.EmptyQuery) flowOf(SearchResultUiState.EmptyQuery)
} else { } else {
getSearchContentsUseCase(query).asResult().map { getSearchContentsUseCase(query)
when (it) { .asResult()
is Result.Success -> { .map { result ->
SearchResultUiState.Success( when (result) {
topics = it.data.topics, is Result.Success -> SearchResultUiState.Success(
newsResources = it.data.newsResources, topics = result.data.topics,
newsResources = result.data.newsResources,
) )
}
is Result.Loading -> {
SearchResultUiState.Loading
}
is Result.Error -> { is Result.Loading -> SearchResultUiState.Loading
SearchResultUiState.LoadFailed is Result.Error -> SearchResultUiState.LoadFailed
} }
} }
} }
} }
} }
} }
}.stateIn( .stateIn(
scope = viewModelScope, scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000), started = SharingStarted.WhileSubscribed(5_000),
initialValue = SearchResultUiState.Loading, initialValue = SearchResultUiState.Loading,
) )
val recentSearchQueriesUiState: StateFlow<RecentSearchQueriesUiState> = val recentSearchQueriesUiState: StateFlow<RecentSearchQueriesUiState> =
recentSearchQueriesUseCase().map(RecentSearchQueriesUiState::Success) recentSearchQueriesUseCase()
.map(RecentSearchQueriesUiState::Success)
.stateIn( .stateIn(
scope = viewModelScope, scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000), started = SharingStarted.WhileSubscribed(5_000),
@ -109,14 +107,9 @@ class SearchViewModel @Inject constructor(
viewModelScope.launch { viewModelScope.launch {
recentSearchRepository.insertOrReplaceRecentSearch(query) recentSearchRepository.insertOrReplaceRecentSearch(query)
} }
analyticsHelper.logEvent( val eventExtras = listOf(element = Param(key = SEARCH_QUERY, value = query))
AnalyticsEvent( val analyticsEvent = AnalyticsEvent(type = SEARCH_QUERY, extras = eventExtras)
type = SEARCH_QUERY, analyticsHelper.logEvent(event = analyticsEvent)
extras = listOf(
Param(SEARCH_QUERY, query),
),
),
)
} }
fun clearRecentSearches() { fun clearRecentSearches() {

Loading…
Cancel
Save