pull/2028/merge
junior-od 1 week ago committed by GitHub
commit ebb567b764
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -47,8 +47,6 @@ fun InterestsScreen(
uiState = uiState, uiState = uiState,
followTopic = viewModel::followTopic, followTopic = viewModel::followTopic,
onTopicClick = { onTopicClick = {
// TODO: this violates SSOT, events should go through the ViewModel
viewModel.onTopicClick(it)
onTopicClick(it) onTopicClick(it)
}, },
shouldHighlightSelectedTopic = shouldHighlightSelectedTopic, shouldHighlightSelectedTopic = shouldHighlightSelectedTopic,

@ -16,14 +16,16 @@
package com.google.samples.apps.nowinandroid.feature.interests.impl package com.google.samples.apps.nowinandroid.feature.interests.impl
import androidx.lifecycle.SavedStateHandle import androidx.compose.runtime.snapshotFlow
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase
import com.google.samples.apps.nowinandroid.core.domain.TopicSortField import com.google.samples.apps.nowinandroid.core.domain.TopicSortField
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.navigation.NavigationState
import com.google.samples.apps.nowinandroid.feature.interests.api.navigation.InterestsNavKey import com.google.samples.apps.nowinandroid.feature.interests.api.navigation.InterestsNavKey
import com.google.samples.apps.nowinandroid.feature.topic.api.navigation.TopicNavKey
import dagger.assisted.Assisted import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject import dagger.assisted.AssistedInject
@ -36,22 +38,24 @@ import kotlinx.coroutines.launch
@HiltViewModel(assistedFactory = InterestsViewModel.Factory::class) @HiltViewModel(assistedFactory = InterestsViewModel.Factory::class)
class InterestsViewModel @AssistedInject constructor( class InterestsViewModel @AssistedInject constructor(
private val savedStateHandle: SavedStateHandle,
val userDataRepository: UserDataRepository, val userDataRepository: UserDataRepository,
getFollowableTopics: GetFollowableTopicsUseCase, getFollowableTopics: GetFollowableTopicsUseCase,
// TODO: see comment below @Assisted val navigationState: NavigationState,
@Assisted val key: InterestsNavKey, @Assisted val key: InterestsNavKey,
) : ViewModel() { ) : ViewModel() {
// TODO: this should no longer be necessary, the currently selected topic should be // Derive selected topic from navigation state
// available through the navigation state private val selectedTopicId: StateFlow<String?> =
// Key used to save and retrieve the currently selected topic id from saved state. snapshotFlow {
private val selectedTopicIdKey = "selectedTopicIdKey" navigationState.currentSubStack
.filterIsInstance<TopicNavKey>()
private val selectedTopicId = savedStateHandle.getStateFlow( .lastOrNull()
key = selectedTopicIdKey, ?.id
initialValue = key.initialTopicId, }.stateIn(
) scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5_000),
initialValue = key.initialTopicId,
)
val uiState: StateFlow<InterestsUiState> = combine( val uiState: StateFlow<InterestsUiState> = combine(
selectedTopicId, selectedTopicId,
@ -69,15 +73,9 @@ class InterestsViewModel @AssistedInject constructor(
} }
} }
fun onTopicClick(topicId: String?) {
// TODO: This should modify the navigation state directly rather than just updating the
// savedStateHandle
savedStateHandle[selectedTopicIdKey] = topicId
}
@AssistedFactory @AssistedFactory
interface Factory { interface Factory {
fun create(key: InterestsNavKey): InterestsViewModel fun create(navigationState: NavigationState, key: InterestsNavKey): InterestsViewModel
} }
} }

@ -36,7 +36,7 @@ fun EntryProviderScope<NavKey>.interestsEntry(navigator: Navigator) {
}, },
) { key -> ) { key ->
val viewModel = hiltViewModel<InterestsViewModel, InterestsViewModel.Factory> { val viewModel = hiltViewModel<InterestsViewModel, InterestsViewModel.Factory> {
it.create(key) it.create(navigator.state, key)
} }
InterestsScreen( InterestsScreen(
// TODO: This event should either be provided by the ViewModel or by the navigator, not both // TODO: This event should either be provided by the ViewModel or by the navigator, not both

@ -16,17 +16,18 @@
package com.google.samples.apps.nowinandroid.interests.impl package com.google.samples.apps.nowinandroid.interests.impl
import androidx.lifecycle.SavedStateHandle import androidx.navigation3.runtime.NavBackStack
import androidx.navigation.testing.invoke
import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase import com.google.samples.apps.nowinandroid.core.domain.GetFollowableTopicsUseCase
import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic import com.google.samples.apps.nowinandroid.core.model.data.FollowableTopic
import com.google.samples.apps.nowinandroid.core.model.data.Topic import com.google.samples.apps.nowinandroid.core.model.data.Topic
import com.google.samples.apps.nowinandroid.core.navigation.NavigationState
import com.google.samples.apps.nowinandroid.core.testing.repository.TestTopicsRepository 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.repository.TestUserDataRepository
import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule import com.google.samples.apps.nowinandroid.core.testing.util.MainDispatcherRule
import com.google.samples.apps.nowinandroid.feature.interests.api.navigation.InterestsNavKey import com.google.samples.apps.nowinandroid.feature.interests.api.navigation.InterestsNavKey
import com.google.samples.apps.nowinandroid.feature.interests.impl.InterestsUiState import com.google.samples.apps.nowinandroid.feature.interests.impl.InterestsUiState
import com.google.samples.apps.nowinandroid.feature.interests.impl.InterestsViewModel import com.google.samples.apps.nowinandroid.feature.interests.impl.InterestsViewModel
import com.google.samples.apps.nowinandroid.feature.topic.api.navigation.TopicNavKey
import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.UnconfinedTestDispatcher
@ -66,13 +67,23 @@ class InterestsViewModelTest {
@Before @Before
fun setup() { fun setup() {
val initialTopicId = testInputTopics[0].topic.id
val interestsKey = InterestsNavKey(initialTopicId = initialTopicId)
viewModel = InterestsViewModel( viewModel = InterestsViewModel(
savedStateHandle = SavedStateHandle(
route = InterestsNavKey(initialTopicId = testInputTopics[0].topic.id),
),
userDataRepository = userDataRepository, userDataRepository = userDataRepository,
getFollowableTopics = getFollowableTopicsUseCase, getFollowableTopics = getFollowableTopicsUseCase,
InterestsNavKey(initialTopicId = testInputTopics[0].topic.id), navigationState = NavigationState(
startKey = interestsKey,
topLevelStack = NavBackStack(interestsKey),
subStacks = mapOf(
interestsKey to NavBackStack(
interestsKey,
TopicNavKey(id = initialTopicId), // Add TopicNavKey to the sub-stack
),
),
),
key = interestsKey,
) )
} }

Loading…
Cancel
Save