diff --git a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt index c75c72ea7..fb3ee92d2 100644 --- a/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt +++ b/core-model/src/main/java/com/google/samples/apps/nowinandroid/core/model/data/NewsResource.kt @@ -17,6 +17,7 @@ package com.google.samples.apps.nowinandroid.core.model.data import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Codelab +import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import kotlinx.datetime.Instant import kotlinx.datetime.LocalDateTime import kotlinx.datetime.TimeZone @@ -60,5 +61,35 @@ val previewNewsResources = listOf( ).toInstant(TimeZone.UTC), type = Codelab, topics = listOf(previewTopics[1]) + ), + NewsResource( + id = "2", + episodeId = "52", + title = "Thanks for helping us reach 1M YouTube Subscribers", + content = "Thank you everyone for following the Now in Android series and everything the " + + "Android Developers YouTube channel has to offer. During the Android Developer " + + "Summit, our YouTube channel reached 1 million subscribers! Here’s a small video to " + + "thank you all.", + url = "https://youtu.be/-fJ6poHQrjM", + headerImageUrl = "https://i.ytimg.com/vi/-fJ6poHQrjM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-09T00:00:00.000Z"), + type = Video, + authors = listOf(previewAuthors[1]), + topics = listOf(previewTopics[0], previewTopics[1]) + ), + NewsResource( + id = "3", + episodeId = "52", + title = "Transformations and customisations in the Paging Library", + content = "A demonstration of different operations that can be performed " + + "with Paging. Transformations like inserting separators, when to " + + "create a new pager, and customisation options for consuming " + + "PagingData.", + url = "https://youtu.be/ZARz0pjm5YM", + headerImageUrl = "https://i.ytimg.com/vi/ZARz0pjm5YM/maxresdefault.jpg", + publishDate = Instant.parse("2021-11-01T00:00:00.000Z"), + type = Video, + authors = listOf(previewAuthors[0], previewAuthors[1]), + topics = listOf(previewTopics[2]) ) ) diff --git a/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt new file mode 100644 index 000000000..c36ba72f1 --- /dev/null +++ b/core-ui/src/main/java/com/google/samples/apps/nowinandroid/core/ui/NewsFeed.kt @@ -0,0 +1,203 @@ +/* + * Copyright 2022 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 + * + * https://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. + */ + +package com.google.samples.apps.nowinandroid.core.ui + +import android.content.Intent +import android.net.Uri +import androidx.annotation.IntRange +import androidx.annotation.StringRes +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyListScope +import androidx.compose.foundation.lazy.items +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Devices +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.core.content.ContextCompat +import com.google.samples.apps.nowinandroid.core.designsystem.component.NiaLoadingWheel +import com.google.samples.apps.nowinandroid.core.designsystem.theme.NiaTheme +import com.google.samples.apps.nowinandroid.core.model.data.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources + +/** + * An extension on [LazyListScope] defining a feed with news resources. + * Depending on the [feedState], this might emit no items. + * + * @param showLoadingUIIfLoading if true, show a visual indication of loading if the + * [feedState] is loading. This allows a caller to suppress a loading visual if one is already + * present in the UI elsewhere. + */ +fun LazyListScope.NewsFeed( + feedState: NewsFeedUiState, + showLoadingUIIfLoading: Boolean, + @StringRes loadingContentDescription: Int, + @IntRange(from = 1) numberOfColumns: Int, + onNewsResourcesCheckedChanged: (String, Boolean) -> Unit +) { + when (feedState) { + NewsFeedUiState.Loading -> { + if (showLoadingUIIfLoading) { + item { + NiaLoadingWheel( + modifier = Modifier + .fillMaxWidth() + .wrapContentSize(), + contentDesc = stringResource(loadingContentDescription), + ) + } + } + } + is NewsFeedUiState.Success -> { + items( + feedState.feed.chunked(numberOfColumns) + ) { saveableNewsResources -> + Row( + modifier = Modifier.padding( + top = 32.dp, + start = 16.dp, + end = 16.dp + ), + horizontalArrangement = Arrangement.spacedBy(32.dp) + ) { + // The last row may not be complete, but for a consistent grid + // structure we still want an element taking up the empty space. + // Therefore, the last row may have empty boxes. + repeat(numberOfColumns) { index -> + Box( + modifier = Modifier.weight(1f) + ) { + val saveableNewsResource = + saveableNewsResources.getOrNull(index) + + if (saveableNewsResource != null) { + val launchResourceIntent = + Intent( + Intent.ACTION_VIEW, + Uri.parse(saveableNewsResource.newsResource.url) + ) + val context = LocalContext.current + + NewsResourceCardExpanded( + newsResource = saveableNewsResource.newsResource, + isBookmarked = saveableNewsResource.isSaved, + onClick = { + ContextCompat.startActivity( + context, + launchResourceIntent, + null + ) + }, + onToggleBookmark = { + onNewsResourcesCheckedChanged( + saveableNewsResource.newsResource.id, + !saveableNewsResource.isSaved + ) + } + ) + } + } + } + } + } + } + } +} + +/** + * A sealed hierarchy describing the state of the feed of news resources. + */ +sealed interface NewsFeedUiState { + /** + * The feed is still loading. + */ + object Loading : NewsFeedUiState + + /** + * The feed is loaded with the given list of news resources. + */ + data class Success( + /** + * The list of news resources contained in this feed. + */ + val feed: List + ) : NewsFeedUiState +} + +@Preview +@Composable +fun NewsFeedLoadingPreview() { + NiaTheme { + LazyColumn { + NewsFeed( + feedState = NewsFeedUiState.Loading, + showLoadingUIIfLoading = true, + loadingContentDescription = 0, + numberOfColumns = 1, + onNewsResourcesCheckedChanged = { _, _ -> } + ) + } + } +} + +@Preview +@Composable +fun NewsFeedSingleColumnPreview() { + NiaTheme { + LazyColumn { + NewsFeed( + feedState = NewsFeedUiState.Success( + previewNewsResources.map { + SaveableNewsResource(it, false) + } + ), + showLoadingUIIfLoading = true, + loadingContentDescription = 0, + numberOfColumns = 1, + onNewsResourcesCheckedChanged = { _, _ -> } + ) + } + } +} + +@Preview(device = Devices.TABLET) +@Composable +fun NewsFeedTwoColumnPreview() { + NiaTheme { + LazyColumn { + NewsFeed( + feedState = NewsFeedUiState.Success( + (previewNewsResources + previewNewsResources).map { + SaveableNewsResource(it, false) + } + ), + showLoadingUIIfLoading = true, + loadingContentDescription = 0, + numberOfColumns = 2, + onNewsResourcesCheckedChanged = { _, _ -> } + ) + } + } +} diff --git a/docs/ArchitectureLearningJourney.md b/docs/ArchitectureLearningJourney.md index f711284e0..b28c864dd 100644 --- a/docs/ArchitectureLearningJourney.md +++ b/docs/ArchitectureLearningJourney.md @@ -72,7 +72,7 @@ Here's what's happening in each step. The easiest way to find the associated cod The initial news feed state is set to Loading, which causes the UI to show a loading spinner on the screen. - Search for usages of ForYouFeedState.Loading + Search for usages of NewsFeedUiState.Loading @@ -138,7 +138,7 @@ Here's what's happening in each step. The easiest way to find the associated cod

The screen shows the newly retrieved news resources (as long as the user has chosen at least one topic or author). - Search for instances of ForYouFeedState.Success + Search for instances of NewsFeedUiState.Success @@ -260,7 +260,7 @@ UI state is modeled as a sealed hierarchy using interfaces and immutable data cl **Example: News feed on For You screen** -The feed (a list) of news resources on the For You screen is modeled using `ForYouFeedState`. This is a sealed interface which creates a hierarchy of two possible states: +The feed (a list) of news resources on the For You screen is modeled using `NewsFeedUiState`. This is a sealed interface which creates a hierarchy of two possible states: diff --git a/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt b/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt index bc54741e6..554928f84 100644 --- a/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt +++ b/feature-foryou/src/androidTest/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreenTest.kt @@ -41,6 +41,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.NewsResourceType.Video import com.google.samples.apps.nowinandroid.core.model.data.SaveableNewsResource import com.google.samples.apps.nowinandroid.core.model.data.Topic +import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import kotlinx.datetime.Instant import org.junit.Assert import org.junit.Rule @@ -66,7 +67,7 @@ class ForYouScreenTest { DpSize(maxWidth, maxHeight) ), interestsSelectionState = ForYouInterestsSelectionUiState.Loading, - feedState = ForYouFeedUiState.Loading, + feedState = NewsFeedUiState.Loading, onAuthorCheckedChanged = { _, _ -> }, onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -95,7 +96,7 @@ class ForYouScreenTest { topics = testTopics, authors = testAuthors ), - feedState = ForYouFeedUiState.Success( + feedState = NewsFeedUiState.Success( feed = emptyList() ), onAuthorCheckedChanged = { _, _ -> }, @@ -149,7 +150,7 @@ class ForYouScreenTest { }, authors = testAuthors ), - feedState = ForYouFeedUiState.Success( + feedState = NewsFeedUiState.Success( feed = emptyList() ), onAuthorCheckedChanged = { _, _ -> }, @@ -203,7 +204,7 @@ class ForYouScreenTest { testAuthor.copy(isFollowed = index == 1) } ), - feedState = ForYouFeedUiState.Success( + feedState = NewsFeedUiState.Success( feed = emptyList() ), onAuthorCheckedChanged = { _, _ -> }, @@ -254,7 +255,7 @@ class ForYouScreenTest { topics = testTopics, authors = testAuthors ), - feedState = ForYouFeedUiState.Loading, + feedState = NewsFeedUiState.Loading, onAuthorCheckedChanged = { _, _ -> }, onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -289,7 +290,7 @@ class ForYouScreenTest { DpSize(maxWidth, maxHeight) ), interestsSelectionState = ForYouInterestsSelectionUiState.NoInterestsSelection, - feedState = ForYouFeedUiState.Loading, + feedState = NewsFeedUiState.Loading, onAuthorCheckedChanged = { _, _ -> }, onTopicCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, @@ -328,7 +329,7 @@ class ForYouScreenTest { ForYouScreen( windowSizeClass = windowSizeClass, interestsSelectionState = ForYouInterestsSelectionUiState.NoInterestsSelection, - feedState = ForYouFeedUiState.Success( + feedState = NewsFeedUiState.Success( feed = testNewsResources ), onAuthorCheckedChanged = { _, _ -> }, diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouFeedUiState.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouFeedUiState.kt deleted file mode 100644 index c6c6c345c..000000000 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouFeedUiState.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2022 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 - * - * https://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. - */ - -package com.google.samples.apps.nowinandroid.feature.foryou - -import com.google.samples.apps.nowinandroid.core.model.data.SaveableNewsResource - -/** - * A sealed hierarchy describing the state of the feed on the for you screen. - */ -sealed interface ForYouFeedUiState { - /** - * The feed is still loading. - */ - object Loading : ForYouFeedUiState - - /** - * The feed is loaded with the given list of news resources. - */ - data class Success( - /** - * The list of news resources contained in this [PopulatedFeed]. - */ - val feed: List - ) : ForYouFeedUiState -} diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt index a918f2a87..c8e36c641 100644 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt +++ b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouScreen.kt @@ -96,6 +96,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.SaveableNewsResource import com.google.samples.apps.nowinandroid.core.model.data.previewAuthors import com.google.samples.apps.nowinandroid.core.model.data.previewNewsResources import com.google.samples.apps.nowinandroid.core.model.data.previewTopics +import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.core.ui.NewsResourceCardExpanded import kotlin.math.floor @@ -124,7 +125,7 @@ fun ForYouRoute( fun ForYouScreen( windowSizeClass: WindowSizeClass, interestsSelectionState: ForYouInterestsSelectionUiState, - feedState: ForYouFeedUiState, + feedState: NewsFeedUiState, onTopicCheckedChanged: (String, Boolean) -> Unit, onAuthorCheckedChanged: (String, Boolean) -> Unit, saveFollowedTopics: () -> Unit, @@ -172,7 +173,7 @@ fun ForYouScreen( // and relates to Time To Full Display. val interestsLoaded = interestsSelectionState !is ForYouInterestsSelectionUiState.Loading - val feedLoaded = feedState !is ForYouFeedUiState.Loading + val feedLoaded = feedState !is NewsFeedUiState.Loading if (interestsLoaded && feedLoaded) { val localView = LocalView.current @@ -426,13 +427,13 @@ fun TopicIcon( * states. */ private fun LazyListScope.Feed( - feedState: ForYouFeedUiState, + feedState: NewsFeedUiState, showLoadingUIIfLoading: Boolean, @IntRange(from = 1) numberOfColumns: Int, onNewsResourcesCheckedChanged: (String, Boolean) -> Unit ) { when (feedState) { - ForYouFeedUiState.Loading -> { + NewsFeedUiState.Loading -> { if (showLoadingUIIfLoading) { item { NiaLoadingWheel( @@ -444,7 +445,7 @@ private fun LazyListScope.Feed( } } } - is ForYouFeedUiState.Success -> { + is NewsFeedUiState.Success -> { items( feedState.feed.chunked(numberOfColumns) ) { saveableNewsResources -> @@ -512,7 +513,7 @@ fun ForYouScreenPopulatedFeed() { ForYouScreen( windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(maxWidth, maxHeight)), interestsSelectionState = ForYouInterestsSelectionUiState.NoInterestsSelection, - feedState = ForYouFeedUiState.Success( + feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { SaveableNewsResource(it, false) } @@ -541,7 +542,7 @@ fun ForYouScreenTopicSelection() { topics = previewTopics.map { FollowableTopic(it, false) }, authors = previewAuthors.map { FollowableAuthor(it, false) } ), - feedState = ForYouFeedUiState.Success( + feedState = NewsFeedUiState.Success( feed = previewNewsResources.map { SaveableNewsResource(it, false) } @@ -567,7 +568,7 @@ fun ForYouScreenLoading() { ForYouScreen( windowSizeClass = WindowSizeClass.calculateFromSize(DpSize(maxWidth, maxHeight)), interestsSelectionState = ForYouInterestsSelectionUiState.Loading, - feedState = ForYouFeedUiState.Loading, + feedState = NewsFeedUiState.Loading, onTopicCheckedChanged = { _, _ -> }, onAuthorCheckedChanged = { _, _ -> }, saveFollowedTopics = {}, diff --git a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt index 8f7a424f2..bc2834c2b 100644 --- a/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt +++ b/feature-foryou/src/main/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModel.kt @@ -32,6 +32,7 @@ import com.google.samples.apps.nowinandroid.core.model.data.FollowableAuthor import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.NewsResource import com.google.samples.apps.nowinandroid.core.model.data.SaveableNewsResource +import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import com.google.samples.apps.nowinandroid.feature.foryou.FollowedInterestsState.FollowedInterests import com.google.samples.apps.nowinandroid.feature.foryou.FollowedInterestsState.None import com.google.samples.apps.nowinandroid.feature.foryou.FollowedInterestsState.Unknown @@ -103,7 +104,7 @@ class ForYouViewModel @Inject constructor( mutableStateOf>(emptySet()) } - val feedState: StateFlow = + val feedState: StateFlow = combine( followedInterestsState, snapshotFlow { inProgressTopicSelection }, @@ -114,7 +115,7 @@ class ForYouViewModel @Inject constructor( when (followedInterestsUserState) { // If we don't know the current selection state, emit loading. - Unknown -> flowOf(ForYouFeedUiState.Loading) + Unknown -> flowOf(NewsFeedUiState.Loading) // If the user has followed topics, use those followed topics to populate the feed is FollowedInterests -> { newsRepository.getNewsResourcesStream( @@ -126,7 +127,7 @@ class ForYouViewModel @Inject constructor( // on the in-progress interests selections, if there are any. None -> { if (inProgressTopicSelection.isEmpty() && inProgressAuthorSelection.isEmpty()) { - flowOf(ForYouFeedUiState.Success(emptyList())) + flowOf(NewsFeedUiState.Success(emptyList())) } else { newsRepository.getNewsResourcesStream( filterTopicIds = inProgressTopicSelection, @@ -143,7 +144,7 @@ class ForYouViewModel @Inject constructor( .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), - initialValue = ForYouFeedUiState.Loading + initialValue = NewsFeedUiState.Loading ) val interestsSelectionState: StateFlow = @@ -245,7 +246,7 @@ class ForYouViewModel @Inject constructor( private fun Flow>.mapToFeedState( savedNewsResources: Set -): Flow = +): Flow = filterNot { it.isEmpty() } .map { newsResources -> newsResources.map { newsResource -> @@ -255,5 +256,5 @@ private fun Flow>.mapToFeedState( ) } } - .map, ForYouFeedUiState>(ForYouFeedUiState::Success) - .onStart { emit(ForYouFeedUiState.Loading) } + .map, NewsFeedUiState>(NewsFeedUiState::Success) + .onStart { emit(NewsFeedUiState.Loading) } diff --git a/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt b/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt index ca4ef7094..aadaa962b 100644 --- a/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt +++ b/feature-foryou/src/test/java/com/google/samples/apps/nowinandroid/feature/foryou/ForYouViewModelTest.kt @@ -29,6 +29,7 @@ import com.google.samples.apps.nowinandroid.core.testing.repository.TestNewsRepo import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository import com.google.samples.apps.nowinandroid.core.testing.repository.TestUserDataRepository import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule +import com.google.samples.apps.nowinandroid.core.ui.NewsFeedUiState import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import kotlinx.coroutines.test.UnconfinedTestDispatcher @@ -71,7 +72,7 @@ class ForYouViewModelTest { ForYouInterestsSelectionUiState.Loading, viewModel.interestsSelectionState.value ) - assertEquals(ForYouFeedUiState.Loading, viewModel.feedState.value) + assertEquals(NewsFeedUiState.Loading, viewModel.feedState.value) } @Test @@ -86,7 +87,7 @@ class ForYouViewModelTest { ForYouInterestsSelectionUiState.Loading, viewModel.interestsSelectionState.value ) - assertEquals(ForYouFeedUiState.Loading, viewModel.feedState.value) + assertEquals(NewsFeedUiState.Loading, viewModel.feedState.value) collectJob1.cancel() collectJob2.cancel() @@ -104,7 +105,7 @@ class ForYouViewModelTest { ForYouInterestsSelectionUiState.Loading, viewModel.interestsSelectionState.value ) - assertEquals(ForYouFeedUiState.Loading, viewModel.feedState.value) + assertEquals(NewsFeedUiState.Loading, viewModel.feedState.value) collectJob1.cancel() collectJob2.cancel() @@ -122,7 +123,7 @@ class ForYouViewModelTest { ForYouInterestsSelectionUiState.Loading, viewModel.interestsSelectionState.value ) - assertEquals(ForYouFeedUiState.Success(emptyList()), viewModel.feedState.value) + assertEquals(NewsFeedUiState.Success(emptyList()), viewModel.feedState.value) collectJob1.cancel() collectJob2.cancel() @@ -140,7 +141,7 @@ class ForYouViewModelTest { ForYouInterestsSelectionUiState.Loading, viewModel.interestsSelectionState.value ) - assertEquals(ForYouFeedUiState.Success(emptyList()), viewModel.feedState.value) + assertEquals(NewsFeedUiState.Success(emptyList()), viewModel.feedState.value) collectJob1.cancel() collectJob2.cancel() @@ -233,7 +234,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList() ), viewModel.feedState.value @@ -331,7 +332,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList() ), @@ -357,7 +358,7 @@ class ForYouViewModelTest { ForYouInterestsSelectionUiState.NoInterestsSelection, viewModel.interestsSelectionState.value ) - assertEquals(ForYouFeedUiState.Loading, viewModel.feedState.value) + assertEquals(NewsFeedUiState.Loading, viewModel.feedState.value) newsRepository.sendNewsResources(sampleNewsResources) @@ -366,7 +367,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = sampleNewsResources.map { SaveableNewsResource( @@ -398,7 +399,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Loading, + NewsFeedUiState.Loading, viewModel.feedState.value ) @@ -409,7 +410,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = sampleNewsResources.map { SaveableNewsResource( newsResource = it, @@ -512,7 +513,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList(), ), viewModel.feedState.value @@ -596,7 +597,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = listOf( SaveableNewsResource( newsResource = sampleNewsResources[1], @@ -703,7 +704,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList(), ), viewModel.feedState.value @@ -787,7 +788,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = listOf( SaveableNewsResource( newsResource = sampleNewsResources[1], @@ -897,7 +898,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList() ), viewModel.feedState.value @@ -998,7 +999,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList() ), viewModel.feedState.value @@ -1028,7 +1029,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = listOf( SaveableNewsResource( newsResource = sampleNewsResources[1], @@ -1069,7 +1070,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = listOf( SaveableNewsResource( newsResource = sampleNewsResources[0], @@ -1107,7 +1108,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = listOf( SaveableNewsResource( newsResource = sampleNewsResources[1], @@ -1220,7 +1221,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList() ), viewModel.feedState.value @@ -1322,7 +1323,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = emptyList() ), viewModel.feedState.value @@ -1350,7 +1351,7 @@ class ForYouViewModelTest { viewModel.interestsSelectionState.value ) assertEquals( - ForYouFeedUiState.Success( + NewsFeedUiState.Success( feed = listOf( SaveableNewsResource( newsResource = sampleNewsResources[1],