@@ -42,7 +42,7 @@ import javax.inject.Inject
4242class ForYouViewModel @Inject constructor(
4343 syncStatusMonitor : SyncStatusMonitor ,
4444 private val userDataRepository : UserDataRepository ,
45- private val getUserNewsResources : GetUserNewsResourcesUseCase ,
45+ getUserNewsResources : GetUserNewsResourcesUseCase ,
4646 getFollowableTopics : GetFollowableTopicsUseCase ,
4747) : ViewModel() {
4848
@@ -56,13 +56,14 @@ class ForYouViewModel @Inject constructor(
5656 initialValue = false ,
5757 )
5858
59- val feedState: StateFlow <NewsFeedUiState > = getFollowedUserNewsResources()
60- .map(NewsFeedUiState ::Success )
61- .stateIn(
62- scope = viewModelScope,
63- started = SharingStarted .WhileSubscribed (5_000 ),
64- initialValue = NewsFeedUiState .Loading ,
65- )
59+ val feedState: StateFlow <NewsFeedUiState > =
60+ userDataRepository.getFollowedUserNewsResources(getUserNewsResources)
61+ .map(NewsFeedUiState ::Success )
62+ .stateIn(
63+ scope = viewModelScope,
64+ started = SharingStarted .WhileSubscribed (5_000 ),
65+ initialValue = NewsFeedUiState .Loading ,
66+ )
6667
6768 val onboardingUiState: StateFlow <OnboardingUiState > =
6869 combine(
@@ -98,50 +99,30 @@ class ForYouViewModel @Inject constructor(
9899 userDataRepository.setShouldHideOnboarding(true )
99100 }
100101 }
101-
102- /* *
103- * This sequence of flow transformation functions does the following:
104- *
105- * - map: maps the user data into a set of followed topic IDs or null if we should return
106- * an empty list
107- * - distinctUntilChanged: will only emit a set of followed topic IDs if it's changed. This
108- * avoids calling potentially expensive operations (like setting up a new flow) when nothing
109- * has changed.
110- * - flatMapLatest: getUserNewsResources returns a flow, so we have a flow inside a
111- * flow. flatMapLatest moves the inner flow (the one we want to return) to the outer flow
112- * and cancels any previous flows created by getUserNewsResources.
113- */
114- private fun getFollowedUserNewsResources (): Flow <List <UserNewsResource >> =
115- userDataRepository.userData
116- .map { userData ->
117- if (userData.shouldShowEmptyFeed()) {
118- null
119- } else {
120- userData.followedTopics
121- }
122- }
123- .distinctUntilChanged()
124- .flatMapLatest { followedTopics ->
125- if (followedTopics == null ) {
126- flowOf(emptyList())
127- } else {
128- getUserNewsResources(filterTopicIds = followedTopics)
129- }
130- }
131102}
132103
133- // Alternative approach (not currently being called)
134- private fun Flow<UserData>.getFollowedUserNewsResources (
104+ /* *
105+ * Obtain a flow of user news resources whose topics match those the user is following.
106+ *
107+ * getUserNewsResources: The `UseCase` used to obtain the flow of user news resources.
108+ */
109+ private fun UserDataRepository.getFollowedUserNewsResources (
135110 getUserNewsResources : GetUserNewsResourcesUseCase ,
136- ): Flow <List <UserNewsResource >> =
137- map { userData ->
111+ ): Flow <List <UserNewsResource >> = userData
112+ // Map the user data into a set of followed topic IDs or null if we should return an empty list.
113+ .map { userData ->
138114 if (userData.shouldShowEmptyFeed()) {
139115 null
140116 } else {
141117 userData.followedTopics
142118 }
143119 }
120+ // Only emit a set of followed topic IDs if it's changed. This avoids calling potentially
121+ // expensive operations (like setting up a new flow) when nothing has changed.
144122 .distinctUntilChanged()
123+ // getUserNewsResources returns a flow, so we have a flow inside a flow. flatMapLatest moves
124+ // the inner flow (the one we want to return) to the outer flow and cancels any previous flows
125+ // created by getUserNewsResources.
145126 .flatMapLatest { followedTopics ->
146127 if (followedTopics == null ) {
147128 flowOf(emptyList())
0 commit comments