Skip to content

Commit

Permalink
Merge pull request #154 from YAPP-Github/QA/72-sent-friend-add
Browse files Browse the repository at this point in the history
Qa/72 인물 봉투 상세에서 봉투 생성 플로우 추가
  • Loading branch information
yangsooplus authored Feb 16, 2024
2 parents 3edddaa + e1569d2 commit 75f1e29
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.navigation.navOptions
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.model.Envelope
import com.susu.core.model.EnvelopeDetail
import com.susu.core.model.Friend
import com.susu.core.model.Ledger
import com.susu.core.model.Vote
import com.susu.feature.community.navigation.CommunityRoute
Expand Down Expand Up @@ -123,8 +124,8 @@ internal class MainNavigator(
navController.navigateSentEnvelopeEdit(envelopeDetail)
}

fun navigateSentEnvelopeAdd() {
navController.navigateSentEnvelopeAdd()
fun navigateSentEnvelopeAdd(friend: Friend? = null) {
navController.navigateSentEnvelopeAdd(friend)
}

fun navigateSentEnvelopeSearch() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.susu.feature.envelope

import com.susu.core.model.EnvelopeSearch
import com.susu.core.model.Friend
import com.susu.core.model.FriendStatistics
import com.susu.core.ui.base.SideEffect
import com.susu.core.ui.base.UiState
Expand All @@ -15,6 +16,7 @@ data class SentEnvelopeState(

sealed interface SentEnvelopeSideEffect : SideEffect {
data class NavigateEnvelopeDetail(val id: Long) : SentEnvelopeSideEffect
data class NavigateEnvelopeAdd(val friend: Friend) : SentEnvelopeSideEffect
data object PopBackStack : SentEnvelopeSideEffect
data class PopBackStackWithDeleteFriendId(val id: Long) : SentEnvelopeSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ import com.susu.core.designsystem.component.appbar.icon.BackIcon
import com.susu.core.designsystem.component.badge.BadgeColor
import com.susu.core.designsystem.component.badge.BadgeStyle
import com.susu.core.designsystem.component.badge.SusuBadge
import com.susu.core.designsystem.component.button.SusuFloatingButton
import com.susu.core.designsystem.theme.Gray10
import com.susu.core.designsystem.theme.Gray100
import com.susu.core.designsystem.theme.Gray20
import com.susu.core.designsystem.theme.Gray60
import com.susu.core.designsystem.theme.Gray90
import com.susu.core.designsystem.theme.Orange20
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.model.Friend
import com.susu.core.ui.extension.OnBottomReached
import com.susu.core.ui.extension.collectWithLifecycle
import com.susu.core.ui.extension.toMoneyFormat
Expand All @@ -63,6 +65,7 @@ fun SentEnvelopeRoute(
popBackStackWithEditedFriendId: (Long) -> Unit,
editedFriendId: Long?,
navigateSentEnvelopeDetail: (Long) -> Unit,
navigateSentEnvelopeAdd: (Friend) -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val historyListState = rememberLazyListState()
Expand All @@ -79,6 +82,7 @@ fun SentEnvelopeRoute(

is SentEnvelopeSideEffect.NavigateEnvelopeDetail -> navigateSentEnvelopeDetail(sideEffect.id)
is SentEnvelopeSideEffect.PopBackStackWithDeleteFriendId -> popBackStackWithDeleteFriendId(sideEffect.id)
is SentEnvelopeSideEffect.NavigateEnvelopeAdd -> navigateSentEnvelopeAdd(sideEffect.friend)
}
}

Expand Down Expand Up @@ -107,6 +111,7 @@ fun SentEnvelopeRoute(
refreshState = refreshState,
onClickBackIcon = viewModel::popBackStack,
onClickEnvelopeDetail = viewModel::navigateSentEnvelopeDetail,
onClickAddEnvelope = viewModel::navigateSentEnvelopeAdd,
)
}

Expand All @@ -119,6 +124,7 @@ fun SentEnvelopeScreen(
historyListState: LazyListState = rememberLazyListState(),
onClickBackIcon: () -> Unit = {},
onClickEnvelopeDetail: (Long) -> Unit = {},
onClickAddEnvelope: () -> Unit = {},
) {
val sent = uiState.envelopeInfo.sentAmounts
val received = uiState.envelopeInfo.receivedAmounts
Expand Down Expand Up @@ -234,6 +240,13 @@ fun SentEnvelopeScreen(
state = refreshState,
containerColor = Gray10,
)

SusuFloatingButton(
modifier = Modifier
.align(Alignment.BottomEnd)
.padding(SusuTheme.spacing.spacing_l),
onClick = onClickAddEnvelope,
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ class SentEnvelopeViewModel @Inject constructor(
}
}

fun navigateSentEnvelopeAdd() = postSideEffect(SentEnvelopeSideEffect.NavigateEnvelopeAdd(currentState.envelopeInfo.friend))
fun navigateSentEnvelopeDetail(id: Long) = postSideEffect(SentEnvelopeSideEffect.NavigateEnvelopeDetail(id = id))
fun popBackStack() = postSideEffect(SentEnvelopeSideEffect.PopBackStack)
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ sealed interface EnvelopeAddEffect : SideEffect {
data class HandleException(val throwable: Throwable, val retry: () -> Unit) : EnvelopeAddEffect
}

/**
* @param fromEnvelope 보내요 봉투 화면에서 추가 화면으로 진입할 시 true. MORE STEP에서 전화번호를 감추기 위함.
* */
data class EnvelopeAddState(
val isLoading: Boolean = false,
val buttonEnabled: Boolean = false,
val currentStep: EnvelopeAddStep = EnvelopeAddStep.MONEY,
val lastPage: Boolean = false,
val friendName: String = "",
val fromEnvelope: Boolean = false,
) : UiState {
val buttonResId = if (lastPage) {
com.susu.core.ui.R.string.word_done
Expand Down
Original file line number Diff line number Diff line change
@@ -1,24 +1,34 @@
package com.susu.feature.envelopeadd

import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
import com.susu.core.model.Category
import com.susu.core.model.Friend
import com.susu.core.model.Relationship
import com.susu.core.ui.MONEY_MAX_VALUE
import com.susu.core.ui.base.BaseViewModel
import com.susu.core.ui.extension.decodeFromUri
import com.susu.domain.usecase.envelope.CreateSentEnvelopeUseCase
import com.susu.feature.sent.navigation.SentRoute
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import kotlinx.datetime.toKotlinLocalDateTime
import kotlinx.serialization.json.Json
import java.time.LocalDateTime
import javax.inject.Inject

@HiltViewModel
class EnvelopeAddViewModel @Inject constructor(
private val createSentEnvelopeUseCase: CreateSentEnvelopeUseCase,
savedStateHandle: SavedStateHandle,
) : BaseViewModel<EnvelopeAddState, EnvelopeAddEffect>(EnvelopeAddState()) {
private val friendArgument = runCatching {
savedStateHandle.get<String>(SentRoute.FRIEND_ARGUMENT_NAME)?.let {
Json.decodeFromUri<Friend>(it)
}
}.getOrNull()

private var money: Long = 0
private var name: String = ""
private var friendId: Long? = null
private var relationShip: Relationship? = null
private var category: Category? = null
Expand All @@ -29,12 +39,21 @@ class EnvelopeAddViewModel @Inject constructor(
private var phoneNumber: String? = null
private var memo: String? = null

fun initData() {
friendArgument?.let {
updateFriendId(it.id)
updateName(it.name)
updatePhoneNumber(it.phoneNumber.ifEmpty { null })
intent { copy(fromEnvelope = true) }
} ?: intent { copy(fromEnvelope = false) }
}

private fun createEnvelope() {
viewModelScope.launch {
createSentEnvelopeUseCase(
param = CreateSentEnvelopeUseCase.Param(
friendId = friendId,
friendName = name,
friendName = currentState.friendName,
phoneNumber = phoneNumber,
relationshipId = relationShip?.id,
customRelation = relationShip?.customRelation,
Expand All @@ -55,7 +74,14 @@ class EnvelopeAddViewModel @Inject constructor(

fun goNextStep() {
when (uiState.value.currentStep) {
EnvelopeAddStep.MONEY -> intent { copy(currentStep = EnvelopeAddStep.NAME) }
EnvelopeAddStep.MONEY -> {
if (friendArgument == null) {
intent { copy(currentStep = EnvelopeAddStep.NAME) }
} else {
intent { copy(currentStep = EnvelopeAddStep.EVENT) }
}
}

EnvelopeAddStep.NAME -> {
intent {
if (friendId == null) {
Expand Down Expand Up @@ -89,13 +115,12 @@ class EnvelopeAddViewModel @Inject constructor(
EnvelopeAddStep.NAME -> intent { copy(currentStep = EnvelopeAddStep.MONEY) }
EnvelopeAddStep.RELATIONSHIP -> intent { copy(currentStep = EnvelopeAddStep.NAME) }
EnvelopeAddStep.EVENT -> {
intent {
if (friendId == null) {
copy(currentStep = EnvelopeAddStep.RELATIONSHIP)
} else {
copy(currentStep = EnvelopeAddStep.NAME)
}
val prevStep = when {
friendId == null -> EnvelopeAddStep.RELATIONSHIP
friendArgument != null -> EnvelopeAddStep.MONEY
else -> EnvelopeAddStep.NAME
}
intent { copy(currentStep = prevStep) }
}

EnvelopeAddStep.DATE -> intent { copy(currentStep = EnvelopeAddStep.EVENT) }
Expand Down Expand Up @@ -125,8 +150,7 @@ class EnvelopeAddViewModel @Inject constructor(
}

fun updateName(name: String) = intent {
this@EnvelopeAddViewModel.name = name
copy(buttonEnabled = name.isNotEmpty())
copy(friendName = name, buttonEnabled = name.isNotEmpty())
}

fun updateFriendId(friendId: Long?) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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
Expand Down Expand Up @@ -59,12 +60,12 @@ fun SentEnvelopeAddRoute(
}
}

var friendName by remember {
var categoryName by remember {
mutableStateOf("")
}

var categoryName by remember {
mutableStateOf("")
LaunchedEffect(key1 = Unit) {
viewModel.initData()
}

BackHandler {
Expand All @@ -73,15 +74,11 @@ fun SentEnvelopeAddRoute(

SentEnvelopeAddScreen(
uiState = uiState,
friendName = friendName,
categoryName = categoryName,
onClickBack = viewModel::goPrevStep,
onClickNext = viewModel::goNextStep,
updateParentMoney = viewModel::updateMoney,
updateParentName = { name ->
viewModel.updateName(name)
friendName = name
},
updateParentName = viewModel::updateName,
updateParentFriendId = viewModel::updateFriendId,
updateParentSelectedRelation = viewModel::updateSelectedRelationShip,
updateParentCategory = { category ->
Expand All @@ -101,7 +98,6 @@ fun SentEnvelopeAddRoute(
@Composable
fun SentEnvelopeAddScreen(
uiState: EnvelopeAddState = EnvelopeAddState(),
friendName: String = "",
onClickBack: () -> Unit = {},
onClickNext: () -> Unit = {},
updateParentMoney: (Long) -> Unit = {},
Expand Down Expand Up @@ -165,11 +161,12 @@ fun SentEnvelopeAddScreen(
)

EnvelopeAddStep.DATE -> DateContentRoute(
friendName = friendName,
friendName = uiState.friendName,
updateParentDate = updateParentDate,
)

EnvelopeAddStep.MORE -> MoreContentRoute(
fromEnvelope = uiState.fromEnvelope,
updateParentMoreStep = updateParentMoreStep,
)

Expand All @@ -184,7 +181,7 @@ fun SentEnvelopeAddScreen(
)

EnvelopeAddStep.PHONE -> PhoneContentRoute(
friendName = friendName,
friendName = uiState.friendName,
updateParentPhone = updateParentPhoneNumber,
onShowSnackbar = onShowSnackbar,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import com.susu.feature.sent.R
@Composable
fun MoreContentRoute(
viewModel: MoreViewModel = hiltViewModel(),
fromEnvelope: Boolean,
updateParentMoreStep: (List<EnvelopeAddStep>) -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
Expand All @@ -45,6 +46,7 @@ fun MoreContentRoute(

MoreContent(
uiState = uiState,
fromEnvelope = fromEnvelope,
onClickStepButton = viewModel::toggleStep,
)
}
Expand All @@ -57,6 +59,7 @@ fun MoreContent(
vertical = SusuTheme.spacing.spacing_xl,
),
uiState: MoreState = MoreState(),
fromEnvelope: Boolean = false,
onClickStepButton: (EnvelopeAddStep) -> Unit = {},
) {
val scrollState = rememberScrollState()
Expand Down Expand Up @@ -88,7 +91,9 @@ fun MoreContent(
Column(
verticalArrangement = Arrangement.spacedBy(SusuTheme.spacing.spacing_xxs),
) {
moreStep.forEach { (step, stringRes) ->
for ((step, stringRes) in moreStep) {
if (fromEnvelope && step == EnvelopeAddStep.PHONE) continue

if (step in uiState.selectedMoreStop) {
SusuFilledButton(
color = FilledButtonColor.Orange,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import androidx.navigation.NavType
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import com.susu.core.model.EnvelopeDetail
import com.susu.core.model.Friend
import com.susu.core.ui.DialogToken
import com.susu.core.ui.SnackbarToken
import com.susu.core.ui.extension.encodeToUri
Expand Down Expand Up @@ -36,8 +37,8 @@ fun NavController.navigateSentEnvelopeEdit(envelopeDetail: EnvelopeDetail) {
navigate(SentRoute.sentEnvelopeEditRoute(Json.encodeToUri(envelopeDetail)))
}

fun NavController.navigateSentEnvelopeAdd() {
navigate(SentRoute.sentEnvelopeAddRoute)
fun NavController.navigateSentEnvelopeAdd(friend: Friend?) {
navigate(SentRoute.sentEnvelopeAddRoute(Json.encodeToUri(friend)))
}

fun NavController.navigateSentEnvelopeSearch() {
Expand All @@ -57,7 +58,7 @@ fun NavGraphBuilder.sentNavGraph(
navigateSentEnvelope: (Long) -> Unit,
navigateSentEnvelopeDetail: (Long) -> Unit,
navigateSentEnvelopeEdit: (EnvelopeDetail) -> Unit,
navigateSentEnvelopeAdd: () -> Unit,
navigateSentEnvelopeAdd: (Friend?) -> Unit,
navigateSentEnvelopeSearch: () -> Unit,
navigateEnvelopeFilter: (String) -> Unit,
onShowSnackbar: (SnackbarToken) -> Unit,
Expand All @@ -81,7 +82,7 @@ fun NavGraphBuilder.sentNavGraph(
editedFriendId = editedFriendId,
refresh = refresh,
navigateSentEnvelope = navigateSentEnvelope,
navigateSentEnvelopeAdd = navigateSentEnvelopeAdd,
navigateSentEnvelopeAdd = { navigateSentEnvelopeAdd(null) },
navigateSentEnvelopeSearch = navigateSentEnvelopeSearch,
navigateEnvelopeFilter = navigateEnvelopeFilter,
)
Expand All @@ -102,6 +103,7 @@ fun NavGraphBuilder.sentNavGraph(
popBackStackWithEditedFriendId = popBackStackWithEditedFriendId,
navigateSentEnvelopeDetail = navigateSentEnvelopeDetail,
popBackStackWithDeleteFriendId = popBackStackWithDeleteFriendId,
navigateSentEnvelopeAdd = navigateSentEnvelopeAdd,
)
}

Expand Down Expand Up @@ -134,7 +136,7 @@ fun NavGraphBuilder.sentNavGraph(
)
}

composable(route = SentRoute.sentEnvelopeAddRoute) {
composable(route = SentRoute.sentEnvelopeAddRoute("{${SentRoute.FRIEND_ARGUMENT_NAME}}")) {
SentEnvelopeAddRoute(
popBackStack = popBackStack,
popBackStackWithRefresh = popBackStackWithRefresh,
Expand Down Expand Up @@ -163,8 +165,10 @@ fun NavGraphBuilder.sentNavGraph(

object SentRoute {
const val route = "sent"
const val sentEnvelopeAddRoute = "sent-envelope-add"
const val SENT_REFRESH_ARGUMENT_NAME = "sent-refresh"
fun sentEnvelopeAddRoute(friend: String) = "sent-envelope-add/$friend"
const val FRIEND_ARGUMENT_NAME = "sent-friend"

fun sentEnvelopeRoute(id: String) = "sent-envelope/$id"
const val FRIEND_ID_ARGUMENT_NAME = "sent-envelope-id"
const val EDITED_FRIEND_ID_ARGUMENT_NAME = "edited-friend-id"
Expand Down

0 comments on commit 75f1e29

Please sign in to comment.