Skip to content

Commit

Permalink
refactor: 장부 생성 설계 변경
Browse files Browse the repository at this point in the history
  • Loading branch information
jinukeu committed Jan 21, 2024
1 parent 87dbc7f commit 2ae42b1
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.imePadding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -30,27 +30,14 @@ import com.susu.core.model.Category
import com.susu.core.ui.R
import com.susu.core.ui.extension.collectWithLifecycle
import com.susu.core.ui.extension.susuDefaultAnimatedContentTransitionSpec
import com.susu.feature.received.Category.category.CategoryViewModel
import com.susu.feature.received.ledgeradd.content.category.CategoryContent
import com.susu.feature.received.ledgeradd.content.category.CategorySideEffect
import com.susu.feature.received.ledgeradd.content.category.CategoryState
import com.susu.feature.received.ledgeradd.content.date.DateContent
import com.susu.feature.received.ledgeradd.content.date.DateSideEffect
import com.susu.feature.received.ledgeradd.content.date.DateState
import com.susu.feature.received.ledgeradd.content.date.DateViewModel
import com.susu.feature.received.ledgeradd.content.name.NameContent
import com.susu.feature.received.ledgeradd.content.name.NameSideEffect
import com.susu.feature.received.ledgeradd.content.name.NameState
import com.susu.feature.received.ledgeradd.content.name.NameViewModel
import kotlinx.coroutines.android.awaitFrame
import kotlinx.coroutines.launch
import com.susu.feature.received.ledgeradd.content.category.CategoryContentRoute
import com.susu.feature.received.ledgeradd.content.date.DateContentRoute
import com.susu.feature.received.ledgeradd.content.name.NameContentRoute
import java.time.LocalDateTime

@Composable
fun LedgerAddRoute(
viewModel: LedgerAddViewModel = hiltViewModel(),
categoryViewModel: CategoryViewModel = hiltViewModel(),
nameViewModel: NameViewModel = hiltViewModel(),
dateViewModel: DateViewModel = hiltViewModel(),
popBackStack: () -> Unit,
popBackStackWithLedger: (String) -> Unit,
handleException: (Throwable, () -> Unit) -> Unit,
Expand All @@ -64,48 +51,12 @@ fun LedgerAddRoute(
}
}

val categoryState = categoryViewModel.uiState.collectAsStateWithLifecycle().value
val focusRequester = remember { FocusRequester() }
val scope = rememberCoroutineScope()
categoryViewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
is CategorySideEffect.UpdateParentSelectedCategory -> {
viewModel.updateSelectedCategory(sideEffect.category)
dateViewModel.updateNameAndCategory(
name = null,
categoryName = sideEffect.category?.customCategory ?: sideEffect.category?.name,
)
}

CategorySideEffect.FocusCustomCategory -> scope.launch {
awaitFrame()
focusRequester.requestFocus()
}
}
}

LaunchedEffect(key1 = Unit) {
categoryViewModel.getCategoryConfig()
var dateContentCategoryName: String by remember {
mutableStateOf("")
}

val nameState = nameViewModel.uiState.collectAsStateWithLifecycle().value
nameViewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
is NameSideEffect.UpdateParentName -> {
viewModel.updateName(sideEffect.name)
dateViewModel.updateNameAndCategory(
name = sideEffect.name,
categoryName = null,
)
}
}
}

val dateState = dateViewModel.uiState.collectAsStateWithLifecycle().value
dateViewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
is DateSideEffect.UpdateParentDate -> viewModel.updateDate(sideEffect.startAt, sideEffect.endAt)
}
var dateContentName: String by remember {
mutableStateOf("")
}

BackHandler {
Expand All @@ -116,26 +67,19 @@ fun LedgerAddRoute(
uiState = uiState,
onClickBack = viewModel::goToPrevStep,
onClickNextButton = viewModel::goToNextStep,
categoryState = categoryState,
focusRequester = focusRequester,
onClickCategoryButton = categoryViewModel::selectCategory,
onClickCustomCategoryButton = categoryViewModel::showCustomCategoryTextField,
onClickCustomCategoryTextFieldCloseIcon = categoryViewModel::hideCustomCategoryTextField,
onClickCustomCategoryTextField = categoryViewModel::selectCustomCategory,
onClickCustomCategoryTextFieldClearIcon = { categoryViewModel.updateCustomCategoryText("") },
onTextChangeCustomCategoryTextField = categoryViewModel::updateCustomCategoryText,
onClickTextFieldInnerButton = categoryViewModel::toggleTextFieldSaved,
updateParentSelectedCategory = categoryViewModel::updateParentSelectedCategory,
nameState = nameState,
onTextChangeName = nameViewModel::updateName,
dateState = dateState,
onStartDateItemSelected = dateViewModel::updateStartDate,
onClickStartDateText = dateViewModel::showStartDateBottomSheet,
onDismissStartDateBottomSheet = dateViewModel::hideStartDateBottomSheet,
onEndDateItemSelected = dateViewModel::updateEndDate,
onClickEndDateText = dateViewModel::showEndDateBottomSheet,
onDismissEndDateBottomSheet = dateViewModel::hideEndDateBottomSheet,
updateParentDate = dateViewModel::updateParentDate,
updateParentSelectedCategory = { category ->
viewModel.updateSelectedCategory(category)
dateContentCategoryName = category?.customCategory ?: category?.name ?: ""
},
updateParentName = { name ->
viewModel.updateName(name)
dateContentName = name
},
dateContentName = dateContentName,
dateContentCategoryName = dateContentCategoryName,
updateParentDate = { startAt, endAt ->
viewModel.updateDate(startAt, endAt)
},
)
}

Expand All @@ -144,26 +88,11 @@ fun LedgerAddScreen(
uiState: LedgerAddState = LedgerAddState(),
onClickBack: () -> Unit = {},
onClickNextButton: () -> Unit = {},
categoryState: CategoryState = CategoryState(),
focusRequester: FocusRequester = remember { FocusRequester() },
onClickCategoryButton: (Category) -> Unit = {},
onClickCustomCategoryButton: () -> Unit = {},
onClickCustomCategoryTextFieldCloseIcon: () -> Unit = {},
onClickCustomCategoryTextField: () -> Unit = {},
onClickCustomCategoryTextFieldClearIcon: () -> Unit = {},
onTextChangeCustomCategoryTextField: (String) -> Unit = {},
onClickTextFieldInnerButton: () -> Unit = {},
updateParentSelectedCategory: () -> Unit = {},
nameState: NameState = NameState(),
onTextChangeName: (String) -> Unit = {},
dateState: DateState = DateState(),
onStartDateItemSelected: (Int, Int, Int) -> Unit = { _, _, _ -> },
onClickStartDateText: () -> Unit = {},
onDismissStartDateBottomSheet: () -> Unit = {},
onEndDateItemSelected: (Int, Int, Int) -> Unit = { _, _, _ -> },
onClickEndDateText: () -> Unit = {},
onDismissEndDateBottomSheet: () -> Unit = {},
updateParentDate: () -> Unit = {},
updateParentSelectedCategory: (Category?) -> Unit = {},
updateParentName: (String) -> Unit = {},
dateContentCategoryName: String = "",
dateContentName: String = "",
updateParentDate: (LocalDateTime?, LocalDateTime?) -> Unit = { _, _ -> },
) {
Box(
modifier = Modifier
Expand All @@ -190,32 +119,17 @@ fun LedgerAddScreen(
},
) { targetState ->
when (targetState) {
LedgerAddStep.CATEGORY -> CategoryContent(
uiState = categoryState,
focusRequester = focusRequester,
onClickCategoryButton = onClickCategoryButton,
onClickCustomCategoryButton = onClickCustomCategoryButton,
onClickCustomCategoryTextFieldCloseIcon = onClickCustomCategoryTextFieldCloseIcon,
onClickCustomCategoryTextField = onClickCustomCategoryTextField,
onClickCustomCategoryTextFieldClearIcon = onClickCustomCategoryTextFieldClearIcon,
onTextChangeCustomCategoryTextField = onTextChangeCustomCategoryTextField,
onClickTextFieldInnerButton = onClickTextFieldInnerButton,
LedgerAddStep.CATEGORY -> CategoryContentRoute(
updateParentSelectedCategory = updateParentSelectedCategory,
)

LedgerAddStep.NAME -> NameContent(
uiState = nameState,
onTextChangeName = onTextChangeName,
LedgerAddStep.NAME -> NameContentRoute(
updateParentName = updateParentName,
)

LedgerAddStep.DATE -> DateContent(
uiState = dateState,
onStartDateItemSelected = onStartDateItemSelected,
onClickStartDateText = onClickStartDateText,
onDismissStartDateBottomSheet = onDismissStartDateBottomSheet,
onEndDateItemSelected = onEndDateItemSelected,
onClickEndDateText = onClickEndDateText,
onDismissEndDateBottomSheet = onDismissEndDateBottomSheet,
LedgerAddStep.DATE -> DateContentRoute(
name = dateContentName,
categoryName = dateContentCategoryName,
updateParentDate = updateParentDate,
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ class LedgerAddViewModel @Inject constructor(
) : BaseViewModel<LedgerAddState, LedgerAddSideEffect>(
LedgerAddState(),
) {
private var selectedCategory: Category? = null
private var name: String = ""
var selectedCategory: Category? = null
private set
var name: String = ""
private set
private var startAt: LocalDateTime? = null
private var endAt: LocalDateTime? = null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,14 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.susu.core.designsystem.component.button.FilledButtonColor
import com.susu.core.designsystem.component.button.GhostButtonColor
import com.susu.core.designsystem.component.button.MediumButtonStyle
Expand All @@ -28,8 +31,63 @@ import com.susu.core.designsystem.component.textfieldbutton.TextFieldButtonColor
import com.susu.core.designsystem.component.textfieldbutton.style.MediumTextFieldButtonStyle
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.model.Category
import com.susu.core.ui.extension.collectWithLifecycle
import com.susu.feature.received.R
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.android.awaitFrame
import kotlinx.coroutines.launch

@Composable
fun CategoryContentRoute(
viewModel: CategoryViewModel = hiltViewModel(),
updateParentSelectedCategory: (Category?) -> Unit = {},
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val focusRequester = remember { FocusRequester() }
val scope = rememberCoroutineScope()
viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
is CategorySideEffect.UpdateParentSelectedCategory -> {
updateParentSelectedCategory(sideEffect.category)
// viewModel.updateSelectedCategory(sideEffect.category)
// dateViewModel.updateNameAndCategory(
// name = null,
// categoryName = sideEffect.category?.customCategory ?: sideEffect.category?.name,
// )
}

CategorySideEffect.FocusCustomCategory -> scope.launch {
awaitFrame()
focusRequester.requestFocus()
}
}
}

LaunchedEffect(key1 = Unit) {
viewModel.getCategoryConfig()
}

LaunchedEffect(
key1 = uiState.selectedCategory,
key2 = uiState.isSavedCustomCategory,
) {
snapshotFlow { uiState.selectedCategory }
.collect {
viewModel.updateParentSelectedCategory()
}
}

CategoryContent(
uiState = uiState,
focusRequester = focusRequester,
onClickCategoryButton = viewModel::selectCategory,
onClickCustomCategoryButton = viewModel::showCustomCategoryTextField,
onClickCustomCategoryTextFieldCloseIcon = viewModel::hideCustomCategoryTextField,
onClickCustomCategoryTextField = viewModel::selectCustomCategory,
onClickCustomCategoryTextFieldClearIcon = { viewModel.updateCustomCategoryText("") },
onTextChangeCustomCategoryTextField = viewModel::updateCustomCategoryText,
onClickTextFieldInnerButton = viewModel::toggleTextFieldSaved,
)
}

@Composable
fun CategoryContent(
Expand All @@ -42,18 +100,7 @@ fun CategoryContent(
onClickCustomCategoryTextFieldClearIcon: () -> Unit = {},
onTextChangeCustomCategoryTextField: (String) -> Unit = {},
onClickTextFieldInnerButton: () -> Unit = {},
updateParentSelectedCategory: () -> Unit = {},
) {
LaunchedEffect(
key1 = uiState.selectedCategory,
key2 = uiState.isSavedCustomCategory,
) {
snapshotFlow { uiState.selectedCategory }
.collect {
updateParentSelectedCategory()
}
}

val scrollState = rememberScrollState()

Column(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
package com.susu.feature.received.Category.category
package com.susu.feature.received.ledgeradd.content.category

import androidx.lifecycle.viewModelScope
import com.susu.core.model.Category
import com.susu.core.ui.base.BaseViewModel
import com.susu.domain.usecase.categoryconfig.GetCategoryConfigUseCase
import com.susu.feature.received.ledgeradd.content.category.CategorySideEffect
import com.susu.feature.received.ledgeradd.content.category.CategoryState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.collections.immutable.toPersistentList
import kotlinx.coroutines.launch
Expand All @@ -27,6 +25,8 @@ class CategoryViewModel @Inject constructor(
}

fun getCategoryConfig() = viewModelScope.launch {
if (currentState.categoryConfig.isNotEmpty()) return@launch

getCategoryConfigUseCase()
.onSuccess {
intent {
Expand Down Expand Up @@ -75,5 +75,7 @@ class CategoryViewModel @Inject constructor(
)
}

fun updateParentSelectedCategory() = postSideEffect(CategorySideEffect.UpdateParentSelectedCategory(parentSelectedCategory))
fun updateParentSelectedCategory(category: Category? = parentSelectedCategory) = postSideEffect(
CategorySideEffect.UpdateParentSelectedCategory(category),
)
}
Loading

0 comments on commit 2ae42b1

Please sign in to comment.