diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneScreen.kt b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneRoute.kt similarity index 69% rename from feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneScreen.kt rename to feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneRoute.kt index 8d0d3afcc..93166b9c8 100644 --- a/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneScreen.kt +++ b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneRoute.kt @@ -7,16 +7,17 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableIntStateOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.LocalLifecycleOwner +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.lifecycle.flowWithLifecycle import com.terning.core.designsystem.component.button.RectangleButton import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar import com.terning.core.designsystem.theme.Grey300 @@ -26,20 +27,52 @@ import com.terning.feature.R import com.terning.feature.filtering.filteringone.component.StatusOneRadioGroup @Composable -fun FilteringOneScreen( +fun FilteringOneRoute( name: String, onNextClick: (Int) -> Unit, navigateUp: () -> Unit, - onButtonClick: (Int) -> Unit = {}, + viewModel: FilteringOneViewModel = hiltViewModel() ) { - val isButtonValid = remember { mutableStateOf(false) } - var grade by remember { mutableIntStateOf(-1) } + val state by viewModel.state.collectAsStateWithLifecycle() + + val lifecycleOwner = LocalLifecycleOwner.current + + LaunchedEffect(viewModel.sideEffects, lifecycleOwner) { + viewModel.sideEffects.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle) + .collect { sideEffect -> + when (sideEffect) { + is FilteringOneSideEffect.NavigateUp -> navigateUp() + } + } + } + + FilteringOneScreen( + name = name, + onButtonClick = { index -> + viewModel.updateGrade(index) + viewModel.updateButtonValidation() + }, + onNextClick = onNextClick, + navigateUp = viewModel::navigateUp, + buttonState = state.isButtonValid, + gradeState = state.grade + ) +} +@Composable +fun FilteringOneScreen( + name: String, + onNextClick: (Int) -> Unit, + navigateUp: () -> Unit, + onButtonClick: (Int) -> Unit, + buttonState: Boolean, + gradeState: Int +) { Column( modifier = Modifier ) { BackButtonTopAppBar( - onBackButtonClick = { navigateUp() } + onBackButtonClick = navigateUp ) Column( modifier = Modifier.fillMaxSize() @@ -79,8 +112,6 @@ fun FilteringOneScreen( StatusOneRadioGroup( onButtonClick = { index -> onButtonClick(index) - isButtonValid.value = true - grade = index } ) Text( @@ -96,9 +127,9 @@ fun FilteringOneScreen( style = TerningTheme.typography.button0, paddingVertical = 20.dp, text = R.string.filtering_button, - onButtonClick = { onNextClick(grade) }, + onButtonClick = { onNextClick(gradeState) }, modifier = Modifier.padding(bottom = 12.dp), - isEnabled = isButtonValid.value + isEnabled = buttonState ) } } @@ -112,7 +143,9 @@ fun FilteringOneScreenPreview() { name = "터닝이", onButtonClick = {}, onNextClick = {}, - navigateUp = {} + navigateUp = {}, + buttonState = true, + gradeState = 1 ) } } \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneSideEffect.kt b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneSideEffect.kt new file mode 100644 index 000000000..5fdbaaaa6 --- /dev/null +++ b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneSideEffect.kt @@ -0,0 +1,5 @@ +package com.terning.feature.filtering.filteringone + +sealed class FilteringOneSideEffect { + data object NavigateUp : FilteringOneSideEffect() +} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneState.kt b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneState.kt new file mode 100644 index 000000000..06c28b481 --- /dev/null +++ b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneState.kt @@ -0,0 +1,6 @@ +package com.terning.feature.filtering.filteringone + +data class FilteringOneState( + val isButtonValid: Boolean = false, + val grade: Int = -1 +) \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneViewModel.kt b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneViewModel.kt new file mode 100644 index 000000000..214b0447d --- /dev/null +++ b/feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneViewModel.kt @@ -0,0 +1,31 @@ +package com.terning.feature.filtering.filteringone + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch + +class FilteringOneViewModel : ViewModel() { + + private val _state: MutableStateFlow = MutableStateFlow(FilteringOneState()) + val state: StateFlow get() = _state.asStateFlow() + + private val _sideEffects = MutableSharedFlow() + val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow() + + fun updateButtonValidation() { + _state.value = _state.value.copy(isButtonValid = true) + } + + fun updateGrade(grade: Int) { + _state.value = _state.value.copy(grade = grade) + } + + fun navigateUp() = + viewModelScope.launch { _sideEffects.emit(FilteringOneSideEffect.NavigateUp) } +} \ No newline at end of file diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringone/navigation/FilteringOneNavigation.kt b/feature/src/main/java/com/terning/feature/filtering/filteringone/navigation/FilteringOneNavigation.kt index e5f25807e..c260aaec1 100644 --- a/feature/src/main/java/com/terning/feature/filtering/filteringone/navigation/FilteringOneNavigation.kt +++ b/feature/src/main/java/com/terning/feature/filtering/filteringone/navigation/FilteringOneNavigation.kt @@ -7,7 +7,7 @@ import androidx.navigation.NavOptions import androidx.navigation.compose.composable import androidx.navigation.toRoute import com.terning.core.navigation.Route -import com.terning.feature.filtering.filteringone.FilteringOneScreen +import com.terning.feature.filtering.filteringone.FilteringOneRoute import com.terning.feature.filtering.filteringtwo.navigation.navigateFilteringTwo import kotlinx.serialization.Serializable @@ -26,7 +26,7 @@ fun NavGraphBuilder.filteringOneNavGraph( ) { composable { val args = it.toRoute() - FilteringOneScreen( + FilteringOneRoute( name = args.name, onNextClick = { grade -> navHostController.navigateFilteringTwo(grade) }, navigateUp = { navHostController.navigateUp() } diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt b/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt index 6e19a291a..ff3a10a0e 100644 --- a/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt +++ b/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeRoute.kt @@ -38,7 +38,7 @@ fun FilteringThreeRoute( workingPeriod: Int, navigateUp: () -> Unit, navigateToStartHome: () -> Unit, - viewModel: FilteringViewModel = hiltViewModel(), + viewModel: FilteringThreeViewModel = hiltViewModel(), ) { val state by viewModel.state.collectAsStateWithLifecycle() diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringState.kt b/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeState.kt similarity index 84% rename from feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringState.kt rename to feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeState.kt index 7f75fc847..d907353f9 100644 --- a/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringState.kt +++ b/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeState.kt @@ -1,6 +1,6 @@ package com.terning.feature.filtering.filteringthree -data class FilteringState( +data class FilteringThreeState( val grade: Int = -1, val workingPeriod: Int = -1, val startYear: Int = -1, diff --git a/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringViewModel.kt b/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeViewModel.kt similarity index 92% rename from feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringViewModel.kt rename to feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeViewModel.kt index d5d5f9b58..9c31c3c86 100644 --- a/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringViewModel.kt +++ b/feature/src/main/java/com/terning/feature/filtering/filteringthree/FilteringThreeViewModel.kt @@ -17,13 +17,13 @@ import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel -class FilteringViewModel @Inject constructor( +class FilteringThreeViewModel @Inject constructor( private val filteringRepository: FilteringRepository, private val tokenRepository: TokenRepository ) : ViewModel() { - private val _state = MutableStateFlow(FilteringState()) - val state: StateFlow get() = _state.asStateFlow() + private val _state = MutableStateFlow(FilteringThreeState()) + val state: StateFlow get() = _state.asStateFlow() private val _sideEffects = MutableSharedFlow() val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow()