More refactoring

pull/552/head
Don Turner 2 years ago
parent e536c396f9
commit f9dcdb4390

@ -42,7 +42,7 @@ import javax.inject.Inject
class ForYouViewModel @Inject constructor(
syncStatusMonitor: SyncStatusMonitor,
private val userDataRepository: UserDataRepository,
private val getUserNewsResources: GetUserNewsResourcesUseCase,
getUserNewsResources: GetUserNewsResourcesUseCase,
getFollowableTopics: GetFollowableTopicsUseCase,
) : ViewModel() {
@ -56,13 +56,14 @@ class ForYouViewModel @Inject constructor(
initialValue = false,
)
val feedState: StateFlow<NewsFeedUiState> = getFollowedUserNewsResources()
.map(NewsFeedUiState::Success)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = NewsFeedUiState.Loading,
)
val feedState: StateFlow<NewsFeedUiState> =
userDataRepository.getFollowedUserNewsResources(getUserNewsResources)
.map(NewsFeedUiState::Success)
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = NewsFeedUiState.Loading,
)
val onboardingUiState: StateFlow<OnboardingUiState> =
combine(
@ -98,50 +99,30 @@ class ForYouViewModel @Inject constructor(
userDataRepository.setShouldHideOnboarding(true)
}
}
/**
* This sequence of flow transformation functions does the following:
*
* - map: maps the user data into a set of followed topic IDs or null if we should return
* an empty list
* - distinctUntilChanged: will only emit a set of followed topic IDs if it's changed. This
* avoids calling potentially expensive operations (like setting up a new flow) when nothing
* has changed.
* - flatMapLatest: getUserNewsResources returns a flow, so we have a flow inside a
* flow. flatMapLatest moves the inner flow (the one we want to return) to the outer flow
* and cancels any previous flows created by getUserNewsResources.
*/
private fun getFollowedUserNewsResources(): Flow<List<UserNewsResource>> =
userDataRepository.userData
.map { userData ->
if (userData.shouldShowEmptyFeed()) {
null
} else {
userData.followedTopics
}
}
.distinctUntilChanged()
.flatMapLatest { followedTopics ->
if (followedTopics == null) {
flowOf(emptyList())
} else {
getUserNewsResources(filterTopicIds = followedTopics)
}
}
}
// Alternative approach (not currently being called)
private fun Flow<UserData>.getFollowedUserNewsResources(
/**
* Obtain a flow of user news resources whose topics match those the user is following.
*
* getUserNewsResources: The `UseCase` used to obtain the flow of user news resources.
*/
private fun UserDataRepository.getFollowedUserNewsResources(
getUserNewsResources: GetUserNewsResourcesUseCase,
): Flow<List<UserNewsResource>> =
map { userData ->
): Flow<List<UserNewsResource>> = userData
// Map the user data into a set of followed topic IDs or null if we should return an empty list.
.map { userData ->
if (userData.shouldShowEmptyFeed()) {
null
} else {
userData.followedTopics
}
}
// Only emit a set of followed topic IDs if it's changed. This avoids calling potentially
// expensive operations (like setting up a new flow) when nothing has changed.
.distinctUntilChanged()
// getUserNewsResources returns a flow, so we have a flow inside a flow. flatMapLatest moves
// the inner flow (the one we want to return) to the outer flow and cancels any previous flows
// created by getUserNewsResources.
.flatMapLatest { followedTopics ->
if (followedTopics == null) {
flowOf(emptyList())

Loading…
Cancel
Save