From 93ca5c68cad214af64f9fb41386813bb31cc3f9d Mon Sep 17 00:00:00 2001 From: LEE YOU BIN Date: Wed, 4 Sep 2024 07:54:35 +0900 Subject: [PATCH] =?UTF-8?q?[FEAT/#218]=20=ED=95=84=ED=84=B0=EB=A7=81=20?= =?UTF-8?q?=EC=9B=90=20=EB=A1=9C=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eringOneScreen.kt => FilteringOneRoute.kt} | 61 ++++++++++++++----- .../filteringone/FilteringOneSideEffect.kt | 5 ++ .../filteringone/FilteringOneState.kt | 6 ++ .../filteringone/FilteringOneViewModel.kt | 31 ++++++++++ .../navigation/FilteringOneNavigation.kt | 4 +- .../filteringthree/FilteringThreeRoute.kt | 2 +- ...lteringState.kt => FilteringThreeState.kt} | 2 +- ...iewModel.kt => FilteringThreeViewModel.kt} | 6 +- 8 files changed, 96 insertions(+), 21 deletions(-) rename feature/src/main/java/com/terning/feature/filtering/filteringone/{FilteringOneScreen.kt => FilteringOneRoute.kt} (69%) create mode 100644 feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneSideEffect.kt create mode 100644 feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneState.kt create mode 100644 feature/src/main/java/com/terning/feature/filtering/filteringone/FilteringOneViewModel.kt rename feature/src/main/java/com/terning/feature/filtering/filteringthree/{FilteringState.kt => FilteringThreeState.kt} (84%) rename feature/src/main/java/com/terning/feature/filtering/filteringthree/{FilteringViewModel.kt => FilteringThreeViewModel.kt} (92%) 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()