Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qa/18 received overflow #160

Merged
merged 20 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3a58ca9
fix: λ°›μ•„μš” μž₯λΆ€ 생성 μœ νš¨μ„± 검사 (경쑰사)
syb8200 Feb 16, 2024
90db363
fix: λ°›μ•„μš” μž₯λΆ€ 생성 μœ νš¨μ„± 검사 (경쑰사λͺ…)
syb8200 Feb 16, 2024
786fb2e
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (κΈˆμ•‘)
syb8200 Feb 16, 2024
5095806
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (이름)
syb8200 Feb 16, 2024
dc0106d
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (μ„ λ¬Ό)
syb8200 Feb 16, 2024
e67e909
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (μ „ν™”λ²ˆν˜Έ)
syb8200 Feb 16, 2024
5fb9360
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (λ©”λͺ¨)
syb8200 Feb 16, 2024
1212989
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (κΈˆμ•‘) μˆ˜μ • β†’ κΈˆμ•‘ λ²„νŠΌ 클릭 μ‹œμ—λ„ 적용
syb8200 Feb 18, 2024
4e1b865
fix: λ°›μ•„μš” μž₯λΆ€ νŽΈμ§‘ μœ νš¨μ„± 검사 (경쑰사λͺ…, 경쑰사)
syb8200 Feb 18, 2024
92749f1
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ μˆ˜μ • (κΈˆμ•‘, 이름, 관계, μ„ λ¬Ό, μ—°λ½μ²˜, λ©”λͺ¨)
syb8200 Feb 18, 2024
a35c51a
fix: λ°›μ•„μš” λ΄‰νˆ¬ μœ νš¨μ„± 검사 (λ©”λͺ¨) μˆ˜μ •
syb8200 Feb 18, 2024
3ea28c3
fix: λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (관계)
syb8200 Feb 18, 2024
03008c2
fix: κΈˆμ•‘ κ΄€λ ¨ string, μ΅œλŒ“κ°’ μˆ˜μ • 및 λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ 생성 μœ νš¨μ„± 검사 (κΈˆμ•‘) μˆ˜μ •
syb8200 Feb 18, 2024
ebd807d
chore: ktlint 적용
syb8200 Feb 18, 2024
98ac937
chore: 주석 제거 및 λ°›μ•„μš” μž₯λΆ€ λ΄‰νˆ¬ ellipsis 적용
syb8200 Feb 18, 2024
32f230d
feat: μ—°λ½μ²˜ ν˜•μ‹ κ΄€λ ¨ μ •μ±… μˆ˜μ • β†’ ν•¨μˆ˜ μΆ”κ°€
syb8200 Feb 19, 2024
9a1b083
fix: λ³΄λ‚΄μš”, λ°›μ•„μš” μ—°λ½μ²˜ ν˜•μ‹ μˆ˜μ • (000-0000-0000)
syb8200 Feb 19, 2024
9c566d2
chore: ktlint 적용
syb8200 Feb 19, 2024
e3f6789
chore: pull develop branch
syb8200 Feb 19, 2024
1878a53
chore: pull develop branch
syb8200 Feb 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/ui/src/main/java/com/susu/core/ui/Consts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ val USER_INPUT_REGEX_LONG = Regex("[a-zA-Zγ„±-γ…Žγ…-γ…£κ°€-힣0-9]{0,30}")
val USER_INPUT_REGEX_INCLUDE_NUMBER = Regex("[a-zA-Zγ„±-γ…Žγ…-γ…£κ°€-힣0-9]{0,10}")

val USER_BIRTH_RANGE = 1930..currentDate.year
const val MONEY_MAX_VALUE = 2_000_000_000L // TODO: μ •μ±… ν™•μ • μ‹œ 99μ–΅μœΌλ‘œ λ³€κ²½
const val MONEY_MAX_VALUE = 9_999_999_999L

const val INTENT_ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE"
const val PRIVACY_POLICY_URL = "https://sites.google.com/view/team-oksusu/%ED%99%88"
Expand Down
5 changes: 5 additions & 0 deletions core/ui/src/main/java/com/susu/core/ui/extension/String.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.susu.core.ui.extension

fun String.toPhoneNumber(): String {
return "${this.substring(0, 3)}-${this.substring(3, 7)}-${this.substring(7)}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.susu.core.ui.util

import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.input.OffsetMapping
import androidx.compose.ui.text.input.TransformedText
import androidx.compose.ui.text.input.VisualTransformation

class PhoneVisualTransformation : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
val trimmed = if (text.text.length > 11) text.text.substring(0 until 11) else text.text
var out = ""
for (i in trimmed.indices) {
out += trimmed[i]
if (i == 2 || i == 6) out += "-"
}

return TransformedText(AnnotatedString(out), phoneOffsetTranslator)
}

private val phoneOffsetTranslator = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (offset <= 2) return offset
if (offset <= 6) return offset + 1
if (offset <= 11) return offset + 2
return 13
}

override fun transformedToOriginal(offset: Int): Int {
if (offset <= 3) return offset
if (offset <= 8) return offset - 1
if (offset <= 13) return offset - 2
return 11
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ fun ReceivedEnvelopeAddRoute(
friendName = friendName,
updateParentPhoneNumber = viewModel::updatePhoneNumber,
updateParentMemo = viewModel::updateMemo,
onShowSnackbar = onShowSnackbar,
)
}

Expand All @@ -138,6 +139,7 @@ fun ReceivedEnvelopeAddScreen(
friendName: String = "",
updateParentPhoneNumber: (String?) -> Unit = {},
updateParentMemo: (String?) -> Unit = {},
onShowSnackbar: (SnackbarToken) -> Unit = {},
) {
Column(
modifier = Modifier
Expand Down Expand Up @@ -166,14 +168,17 @@ fun ReceivedEnvelopeAddScreen(
when (targetState) {
EnvelopeAddStep.MONEY -> MoneyContentRoute(
updateParentMoney = updateParentMoney,
onShowSnackbar = onShowSnackbar,
)

EnvelopeAddStep.NAME -> NameContentRoute(
updateParentName = updateParentName,
updateParentFriendId = updateParentFriendId,
onShowSnackbar = onShowSnackbar,
)
EnvelopeAddStep.RELATIONSHIP -> RelationShipContentRoute(
updateParentSelectedRelation = updateParentSelectedRelationShip,
onShowSnackbar = onShowSnackbar,
)
EnvelopeAddStep.DATE -> DateContentRoute(
friendName = friendName,
Expand All @@ -190,13 +195,16 @@ fun ReceivedEnvelopeAddScreen(

EnvelopeAddStep.PRESENT -> PresentContentRoute(
updateParentPresent = updateParentPresent,
onShowSnackbar = onShowSnackbar,
)
EnvelopeAddStep.PHONE -> PhoneContentRoute(
friendName = friendName,
updateParentPhone = updateParentPhoneNumber,
onShowSnackbar = onShowSnackbar,
)
EnvelopeAddStep.MEMO -> MemoContentRoute(
updateParentMemo = updateParentMemo,
onShowSnackbar = onShowSnackbar,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
Expand All @@ -24,6 +25,7 @@ import com.susu.core.designsystem.component.textfield.SusuBasicTextField
import com.susu.core.designsystem.theme.Gray100
import com.susu.core.designsystem.theme.Gray40
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.ui.SnackbarToken
import com.susu.core.ui.extension.collectWithLifecycle
import com.susu.feature.received.R
import kotlinx.coroutines.android.awaitFrame
Expand All @@ -33,17 +35,25 @@ import kotlinx.coroutines.launch
fun MemoContentRoute(
viewModel: MemoViewModel = hiltViewModel(),
updateParentMemo: (String?) -> Unit,
onShowSnackbar: (SnackbarToken) -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val focusRequester = remember { FocusRequester() }
val scope = rememberCoroutineScope()
val context = LocalContext.current

viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
is MemoSideEffect.UpdateParentMemo -> updateParentMemo(sideEffect.memo)
MemoSideEffect.ShowKeyboard -> scope.launch {
awaitFrame()
focusRequester.requestFocus()
}
MemoSideEffect.ShowNotValidSnackbar -> onShowSnackbar(
SnackbarToken(
message = context.getString(R.string.memo_content_snackbar_validation),
),
)
}
}

Expand Down Expand Up @@ -91,6 +101,7 @@ fun MemoContent(
placeholder = stringResource(R.string.memo_content_placeholder),
placeholderColor = Gray40,
modifier = Modifier.fillMaxWidth().focusRequester(focusRequester),
maxLines = 5,
)
Spacer(modifier = Modifier.size(SusuTheme.spacing.spacing_xl))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ data class MemoState(
sealed interface MemoSideEffect : SideEffect {
data class UpdateParentMemo(val memo: String?) : MemoSideEffect
data object ShowKeyboard : MemoSideEffect
data object ShowNotValidSnackbar : MemoSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,16 @@ import javax.inject.Inject
class MemoViewModel @Inject constructor() : BaseViewModel<MemoState, MemoSideEffect>(
MemoState(),
) {
fun updateMemo(memo: String?) = intent {
postSideEffect(MemoSideEffect.UpdateParentMemo(memo))
copy(memo = memo ?: "")
fun updateMemo(memo: String?) {
if (memo != null && memo.length > 30) {
postSideEffect(MemoSideEffect.ShowNotValidSnackbar)
return
}

intent {
postSideEffect(MemoSideEffect.UpdateParentMemo(memo))
copy(memo = memo ?: "")
}
}

fun showKeyboardIfTextEmpty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
Expand All @@ -26,6 +27,7 @@ import com.susu.core.designsystem.component.button.SusuFilledButton
import com.susu.core.designsystem.component.textfield.SusuPriceTextField
import com.susu.core.designsystem.theme.Gray100
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.ui.SnackbarToken
import com.susu.core.ui.extension.collectWithLifecycle
import com.susu.core.ui.extension.toMoneyFormat
import com.susu.core.ui.moneyList
Expand All @@ -37,11 +39,12 @@ import kotlinx.coroutines.launch
fun MoneyContentRoute(
viewModel: MoneyViewModel = hiltViewModel(),
updateParentMoney: (Long) -> Unit,
onShowSnackbar: (SnackbarToken) -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value

val focusRequester = remember { FocusRequester() }
val scope = rememberCoroutineScope()
val context = LocalContext.current

viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
Expand All @@ -50,6 +53,12 @@ fun MoneyContentRoute(
awaitFrame()
focusRequester.requestFocus()
}

MoneySideEffect.ShowNotValidSnackbar -> onShowSnackbar(
SnackbarToken(
message = context.getString(R.string.money_content_snackbar_validation),
),
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ sealed interface MoneySideEffect : SideEffect {
data class UpdateParentMoney(val money: Long) : MoneySideEffect

data object ShowKeyboard : MoneySideEffect

data object ShowNotValidSnackbar : MoneySideEffect
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.susu.feature.received.envelopeadd.content.money

import com.susu.core.ui.MONEY_MAX_VALUE
import com.susu.core.ui.base.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
Expand All @@ -8,18 +9,33 @@ import javax.inject.Inject
class MoneyViewModel @Inject constructor() : BaseViewModel<MoneyState, MoneySideEffect>(
MoneyState(),
) {
fun updateMoney(money: String) = intent {
postSideEffect(MoneySideEffect.UpdateParentMoney(money.toLongOrNull() ?: 0))
copy(money = money)
fun updateMoney(money: String) {
if (money.length > 10) {
postSideEffect(MoneySideEffect.ShowNotValidSnackbar)
return
}

intent {
postSideEffect(MoneySideEffect.UpdateParentMoney(money.toLongOrNull() ?: 0))
copy(money = money)
}
}

fun addMoney(money: Int) = intent {
val currentMoney = this.money.toLongOrNull() ?: 0
val addedMoney = money + currentMoney
fun addMoney(money: Int) {
val currentMoney = currentState.money.toLongOrNull() ?: 0
val addedMoney = currentMoney + money

if (addedMoney > MONEY_MAX_VALUE) {
postSideEffect(MoneySideEffect.ShowNotValidSnackbar)
return
}
postSideEffect(MoneySideEffect.UpdateParentMoney(addedMoney))
copy(
money = addedMoney.toString(),
)

intent {
copy(
money = addedMoney.toString(),
)
}
}

fun showKeyboardIfMoneyEmpty() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
Expand All @@ -29,6 +30,7 @@ import com.susu.core.designsystem.theme.Gray100
import com.susu.core.designsystem.theme.Gray40
import com.susu.core.designsystem.theme.SusuTheme
import com.susu.core.model.FriendSearch
import com.susu.core.ui.SnackbarToken
import com.susu.core.ui.extension.collectWithLifecycle
import com.susu.feature.received.R
import com.susu.feature.received.envelopeadd.content.component.FriendListItem
Expand All @@ -43,11 +45,13 @@ fun NameContentRoute(
viewModel: NameViewModel = hiltViewModel(),
updateParentName: (String) -> Unit,
updateParentFriendId: (Long?) -> Unit,
onShowSnackbar: (SnackbarToken) -> Unit,
) {
val uiState = viewModel.uiState.collectAsStateWithLifecycle().value
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
val scope = rememberCoroutineScope()
val context = LocalContext.current

viewModel.sideEffect.collectWithLifecycle { sideEffect ->
when (sideEffect) {
Expand All @@ -58,6 +62,11 @@ fun NameContentRoute(
awaitFrame()
focusRequester.requestFocus()
}
NameSideEffect.ShowNotValidSnackbar -> onShowSnackbar(
SnackbarToken(
message = context.getString(R.string.name_content_snackbar_validation),
),
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ sealed interface NameSideEffect : SideEffect {
data class UpdateParentFriendId(val friendId: Long?) : NameSideEffect
data object FocusClear : NameSideEffect
data object ShowKeyboard : NameSideEffect
data object ShowNotValidSnackbar : NameSideEffect
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.susu.feature.received.envelopeadd.content.name

import androidx.lifecycle.viewModelScope
import com.susu.core.model.FriendSearch
import com.susu.core.ui.USER_INPUT_REGEX
import com.susu.core.ui.base.BaseViewModel
import com.susu.domain.usecase.friend.SearchFriendUseCase
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -16,16 +17,25 @@ class NameViewModel @Inject constructor(
) : BaseViewModel<NameState, NameSideEffect>(
NameState(),
) {
fun updateName(name: String) = intent {
postSideEffect(
NameSideEffect.UpdateParentName(name),
NameSideEffect.UpdateParentFriendId(null),
)
copy(
name = name,
friendList = if (name.isEmpty()) persistentListOf() else friendList,
isSelectedFriend = false,
)
fun updateName(name: String) {
if (!USER_INPUT_REGEX.matches(name)) { // ν•œκΈ€, 영문 0~10 κΈ€μž
if (name.length > 10) { // 길이 λ„˜μΉœ 경우
postSideEffect(NameSideEffect.ShowNotValidSnackbar)
}
return // νŠΉμˆ˜λ¬ΈμžλŠ” μž…λ ₯ μ•ˆ 됨
}

intent {
postSideEffect(
NameSideEffect.UpdateParentName(name),
NameSideEffect.UpdateParentFriendId(null),
)
copy(
name = name,
friendList = if (name.isEmpty()) persistentListOf() else friendList,
isSelectedFriend = false,
)
}
}

fun selectFriend(friend: FriendSearch) = intent {
Expand Down
Loading
Loading