From 8fe39d42cc6d74444e30f7f6d6945de6b75cf34f Mon Sep 17 00:00:00 2001 From: jinukeu Date: Wed, 31 Jan 2024 14:44:28 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=EB=B0=9B=EC=9D=80=20=EB=B4=89=ED=88=AC?= =?UTF-8?q?=20=ED=8E=B8=EC=A7=91=20=EB=8F=99=EC=9E=91=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ReceivedEnvelopeEditContract.kt | 7 +- .../ReceivedEnvelopeEditScreen.kt | 35 +++-- .../ReceivedEnvelopeEditViewModel.kt | 127 +++++++++++++++++- 3 files changed, 159 insertions(+), 10 deletions(-) diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditContract.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditContract.kt index 3785dd52..a5a2ea0f 100644 --- a/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditContract.kt +++ b/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditContract.kt @@ -4,7 +4,6 @@ import com.susu.core.model.Envelope import com.susu.core.model.Relationship import com.susu.core.ui.base.SideEffect import com.susu.core.ui.base.UiState -import com.susu.feature.received.envelopeadd.content.relationship.RelationShipSideEffect import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf @@ -15,9 +14,15 @@ data class ReceivedEnvelopeEditState( val showDateBottomSheet: Boolean = false, val isRelationSaved: Boolean = false, ) : UiState { + val buttonEnabled = when { + envelope.friend.name.isEmpty() -> false + envelope.relationship.id == relationshipConfig.last().id && isRelationSaved.not() -> false + else -> true + } } sealed interface ReceivedEnvelopeEditSideEffect : SideEffect { + data object FocusCustomRelation : ReceivedEnvelopeEditSideEffect data object PopBackStack : ReceivedEnvelopeEditSideEffect data class HandleException(val throwable: Throwable, val retry: () -> Unit) : ReceivedEnvelopeEditSideEffect } diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditScreen.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditScreen.kt index cf78aad1..f0bf7710 100644 --- a/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditScreen.kt +++ b/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditScreen.kt @@ -16,11 +16,8 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text 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.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester @@ -34,7 +31,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.susu.core.designsystem.component.appbar.SusuDefaultAppBar import com.susu.core.designsystem.component.appbar.icon.BackIcon import com.susu.core.designsystem.component.bottomsheet.datepicker.SusuDatePickerBottomSheet -import com.susu.core.designsystem.component.bottomsheet.datepicker.SusuLimitDatePickerBottomSheet import com.susu.core.designsystem.component.button.AddConditionButton import com.susu.core.designsystem.component.button.FilledButtonColor import com.susu.core.designsystem.component.button.MediumButtonStyle @@ -48,14 +44,14 @@ import com.susu.core.designsystem.component.textfieldbutton.style.SmallTextField import com.susu.core.designsystem.theme.Gray30 import com.susu.core.designsystem.theme.Gray40 import com.susu.core.designsystem.theme.Gray70 -import com.susu.core.designsystem.theme.Gray80 import com.susu.core.designsystem.theme.SusuTheme import com.susu.core.model.Relationship import com.susu.core.ui.extension.collectWithLifecycle import com.susu.core.ui.extension.susuClickable -import com.susu.core.ui.util.AnnotatedText import com.susu.feature.received.R import com.susu.feature.received.envelopeedit.component.EditDetailItem +import kotlinx.coroutines.android.awaitFrame +import kotlinx.coroutines.launch @Composable fun ReceivedEnvelopeEditRoute( @@ -76,6 +72,10 @@ fun ReceivedEnvelopeEditRoute( ) ReceivedEnvelopeEditSideEffect.PopBackStack -> popBackStack() + ReceivedEnvelopeEditSideEffect.FocusCustomRelation -> scope.launch { + awaitFrame() + focusRequester.requestFocus() + } } } @@ -88,6 +88,22 @@ fun ReceivedEnvelopeEditRoute( uiState = uiState, focusRequester = focusRequester, onClickBackIcon = viewModel::popBackStack, + onClickSave = {}, + onTextChangeMoney = viewModel::updateMoney, + onTextChangeName = viewModel::updateName, + onTextChangeRelation = viewModel::updateCustomRelation, + onClickRelation = viewModel::updateRelation, + onClickCustomRelationClear = { viewModel.updateCustomRelation("") }, + onClickCustomRelationClose = viewModel::closeCustomRelation, + onClickRelationInnerButton = viewModel::toggleRelationSaved, + onClickAddConditionButton = viewModel::showCustomRelation, + onClickDate = viewModel::showDateBottomSheet, + onClickHasVisited = viewModel::updateHasVisited, + onTextChangeGift = viewModel::updateGift, + onTextChangePhoneNumber = viewModel::updatePhoneNumber, + onTextChangeMemo = viewModel::updateMemo, + onDismissDateBottomSheet = viewModel::hideDateBottomSheet, + onItemSelectedDateBottomSheet = viewModel::updateDate, ) } @@ -100,6 +116,7 @@ fun ReceivedEnvelopeEditScreen( onClickSave: () -> Unit = {}, onTextChangeMoney: (String) -> Unit = {}, onTextChangeName: (String) -> Unit = {}, + onTextChangeRelation: (String) -> Unit = {}, onClickRelation: (Relationship) -> Unit = {}, onClickCustomRelationClear: () -> Unit = {}, onClickCustomRelationClose: () -> Unit = {}, @@ -173,10 +190,10 @@ fun ReceivedEnvelopeEditScreen( if (uiState.showCustomRelationButton) { SusuTextFieldWrapContentButton( focusRequester = focusRequester, - onTextChange = {}, + onTextChange = onTextChangeRelation, color = TextFieldButtonColor.Orange, style = SmallTextFieldButtonStyle.height32, - text = uiState.envelope.relationship.customRelation ?: "", + text = uiState.relationshipConfig.last().customRelation ?: "", isFocused = uiState.relationshipConfig.last().id == uiState.envelope.relationship.id, isSaved = uiState.isRelationSaved, onClickClearIcon = onClickCustomRelationClear, @@ -285,6 +302,8 @@ fun ReceivedEnvelopeEditScreen( color = FilledButtonColor.Black, style = MediumButtonStyle.height60, shape = RectangleShape, + isActive = uiState.buttonEnabled, + isClickable = uiState.buttonEnabled, text = stringResource(com.susu.core.ui.R.string.word_save), onClick = onClickSave, ) diff --git a/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditViewModel.kt b/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditViewModel.kt index dae702d6..c2772641 100644 --- a/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditViewModel.kt +++ b/feature/received/src/main/java/com/susu/feature/received/envelopeedit/ReceivedEnvelopeEditViewModel.kt @@ -3,7 +3,10 @@ package com.susu.feature.received.envelopeedit import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.susu.core.model.Envelope +import com.susu.core.model.Friend +import com.susu.core.model.Relationship import com.susu.core.ui.base.BaseViewModel +import com.susu.core.ui.base.SideEffect import com.susu.core.ui.extension.decodeFromUri import com.susu.core.ui.extension.encodeToUri import com.susu.domain.usecase.envelope.DeleteEnvelopeUseCase @@ -13,8 +16,10 @@ import com.susu.feature.received.navigation.ReceivedRoute import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.collections.immutable.toPersistentList import kotlinx.coroutines.launch +import kotlinx.datetime.toKotlinLocalDateTime import kotlinx.serialization.json.Json import timber.log.Timber +import java.time.LocalDateTime import javax.inject.Inject @HiltViewModel @@ -39,7 +44,10 @@ class ReceivedEnvelopeEditViewModel @Inject constructor( intent { copy( envelope = envelope, - relationshipConfig = it.toPersistentList(), + relationshipConfig = it.map { + if (it.id == envelope.relationship.id) it.copy(customRelation = envelope.relationship.customRelation) + else it + }.toPersistentList(), showCustomRelationButton = it.last().id == envelope.relationship.id, isRelationSaved = it.last().id == envelope.relationship.id, ) @@ -50,4 +58,121 @@ class ReceivedEnvelopeEditViewModel @Inject constructor( fun popBackStack() = postSideEffect(ReceivedEnvelopeEditSideEffect.PopBackStack) + fun updateMoney(money: String) = intent { + copy( + envelope = envelope.copy(amount = money.toLongOrNull() ?: 0L), + ) + } + + fun updateName(name: String) = intent { + copy( + envelope = envelope.copy(friend = Friend(name = name)), + ) + } + + fun updateRelation(relationship: Relationship) = intent { + copy( + envelope = envelope.copy(relationship = relationship), + ) + } + + fun updateCustomRelation(customRelation: String?) = intent { + copy( + envelope = envelope.copy(relationship = envelope.relationship.copy(customRelation = customRelation)), + relationshipConfig = relationshipConfig.map { + if (it.id == envelope.relationship.id) { + it.copy(customRelation = customRelation) + } else it + }.toPersistentList(), + ) + } + + fun closeCustomRelation() = intent { + copy( + envelope = if (envelope.relationship.id == relationshipConfig.last().id) { + envelope.copy(relationship = relationshipConfig.first()) + } else { + envelope + }, + relationshipConfig = relationshipConfig.map { + it.copy(customRelation = null) + }.toPersistentList(), + isRelationSaved = false, + showCustomRelationButton = false, + ) + } + + fun toggleRelationSaved() = intent { + copy( + isRelationSaved = !isRelationSaved, + ) + } + + fun showCustomRelation() = intent { + postSideEffect(ReceivedEnvelopeEditSideEffect.FocusCustomRelation) + copy( + isRelationSaved = false, + showCustomRelationButton = true, + envelope = envelope.copy( + relationship = relationshipConfig.last(), + ), + ) + } + + fun showDateBottomSheet() = intent { + copy( + showDateBottomSheet = true, + ) + } + + fun updateHasVisited(visited: Boolean) = intent { + copy( + envelope = envelope.copy( + hasVisited = if (visited == envelope.hasVisited) null else visited, + ), + ) + } + + fun updateGift(gift: String) = intent { + copy( + envelope = envelope.copy( + gift = gift.ifEmpty { null }, + ), + ) + } + + fun updatePhoneNumber(phoneNumber: String) = intent { + copy( + envelope = envelope.copy( + friend = envelope.friend.copy( + phoneNumber = phoneNumber, + ), + ), + ) + } + + fun updateMemo(memo: String) = intent { + copy( + envelope = envelope.copy( + memo = memo.ifEmpty { null }, + ), + ) + } + + fun hideDateBottomSheet(year: Int, month: Int, day: Int) = intent { + copy( + envelope = envelope.copy( + handedOverAt = LocalDateTime.of(year, month, day, 0, 0).toKotlinLocalDateTime(), + ), + showDateBottomSheet = false, + ) + } + + fun updateDate(year: Int, month: Int, day: Int) = intent { + copy( + envelope = envelope.copy( + handedOverAt = LocalDateTime.of(year, month, day, 0, 0).toKotlinLocalDateTime(), + ), + ) + } }