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

[Refactor/#114] "회원가입 화면" 1차 QA 사항을 반영합니다. #116

Merged
merged 6 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import com.sopt.gongbaek.domain.usecase.ValidateNicknameUseCase
import com.sopt.gongbaek.presentation.util.base.BaseViewModel
import com.sopt.gongbaek.presentation.util.base.UiLoadState
import com.sopt.gongbaek.presentation.util.extension.createMbti
import com.sopt.gongbaek.presentation.util.extension.hasCompleteKoreanCharacters
import com.sopt.gongbaek.presentation.util.extension.isCompleteKorean
import com.sopt.gongbaek.presentation.util.extension.isKoreanChar
import com.sopt.gongbaek.presentation.util.timetable.convertToTimeTable
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -32,13 +34,20 @@ class AuthViewModel @Inject constructor(
override suspend fun handleEvent(event: AuthContract.Event) {
when (event) {
is AuthContract.Event.OnProfileImageSelected -> updateUserInfo { copy(profileImage = event.profileImage) }

is AuthContract.Event.OnNicknameChanged -> {
val filteredNickname = event.nickname.filter { it.isKoreanChar() }
val isValidNickname = filteredNickname.hasCompleteKoreanCharacters(2)
val containsIncompleteKorean = filteredNickname.any { it.isKoreanChar() && !it.isCompleteKorean() }
updateUserInfo { copy(nickname = filteredNickname) }
setState {
copy(
nicknameValidation = true,
nicknameErrorMessage = null
nicknameValidation = isValidNickname && !containsIncompleteKorean,
nicknameErrorMessage = when {
containsIncompleteKorean -> "완성되지 않은 글자가 포함되어 있습니다."
!isValidNickname -> "닉네임은 최소 2글자 이상의 완성된 한글이어야 합니다."
else -> null
}
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.sopt.gongbaek.presentation.ui.auth.screen

import android.app.Activity
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
Expand All @@ -11,10 +13,15 @@ import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableLongStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
Expand All @@ -35,6 +42,19 @@ fun CompleteAuthRoute(
) {
val lifecycleOwner = LocalLifecycleOwner.current

var backPressedTime by remember { mutableLongStateOf(0L) }
val backPressThreshold = 2000
val context = LocalContext.current

BackHandler {
val currentTimeMillis = System.currentTimeMillis()
if (currentTimeMillis - backPressedTime <= backPressThreshold) {
(context as? Activity)?.finish()
} else {
backPressedTime = currentTimeMillis
}
}

LaunchedEffect(viewModel.sideEffect, lifecycleOwner) {
viewModel.sideEffect
.flowWithLifecycle(lifecycleOwner.lifecycle)
Expand All @@ -59,8 +79,7 @@ private fun CompleteAuthScreen(
.padding(horizontal = 16.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
modifier = Modifier.fillMaxWidth()
) {
Text(
text = "가입이 완료되었어요!",
Expand All @@ -69,7 +88,7 @@ private fun CompleteAuthScreen(
textAlign = TextAlign.Center,
modifier = Modifier
.fillMaxWidth()
.padding(top = 109.dp, bottom = 8.dp)
.padding(top = 99.dp, bottom = 8.dp)
)

Text(
Expand Down Expand Up @@ -105,7 +124,7 @@ private fun CompleteAuthScreen(
contentScale = ContentScale.Crop,
modifier = Modifier
.align(Alignment.Center)
.padding(top = 24.dp)
.padding(top = 38.dp)
.width((LocalConfiguration.current.screenWidthDp * 0.9).dp)
.aspectRatio(328f / 343f)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
Expand All @@ -24,6 +23,7 @@ import com.sopt.gongbaek.presentation.ui.component.progressBar.GongBaekProgressB
import com.sopt.gongbaek.presentation.ui.component.section.PageDescriptionSection
import com.sopt.gongbaek.presentation.ui.component.textfield.GongBaekBasicTextField
import com.sopt.gongbaek.presentation.ui.component.topbar.StartTitleTopBar
import com.sopt.gongbaek.presentation.util.extension.hasCompleteKoreanCharacters
import com.sopt.gongbaek.ui.theme.GONGBAEKTheme

@Composable
Expand Down Expand Up @@ -66,9 +66,7 @@ private fun NicknameScreen(
onBackClick: () -> Unit = {}
) {
Box(
modifier = Modifier
.fillMaxSize()
.imePadding()
modifier = Modifier.fillMaxSize()
) {
NickNameInputSection(
nickname = nickname,
Expand All @@ -82,7 +80,7 @@ private fun NicknameScreen(

GongBaekBasicButton(
title = "다음",
enabled = nickname.isNotBlank() && errorMessage.isNullOrEmpty(),
enabled = nickname.hasCompleteKoreanCharacters(2) && errorMessage.isNullOrEmpty(),
onClick = navigateUnivMajor,
modifier = Modifier
.align(Alignment.BottomCenter)
Expand Down Expand Up @@ -121,8 +119,7 @@ private fun NickNameInputSection(
onValueChange = onNicknameChanged,
gongBaekBasicTextFieldType = GongBaekBasicTextFieldType.NICKNAME,
isError = !errorMessage.isNullOrEmpty(),
errorMessage = errorMessage.orEmpty(), // 에러 메시지 전달
onErrorChange = { /* 에러 변경 처리 */ }
errorMessage = errorMessage.orEmpty()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
Expand Down Expand Up @@ -70,9 +69,7 @@ private fun SelfIntroductionScreen(
onSelfIntroductionChanged: (String) -> Unit
) {
Box(
modifier = Modifier
.fillMaxSize()
.imePadding()
modifier = Modifier.fillMaxSize()
) {
SelfIntroductionSection(
onBackClick = navigateBack,
Expand All @@ -85,7 +82,7 @@ private fun SelfIntroductionScreen(

GongBaekBasicButton(
title = "다음",
enabled = selfIntroduction.isNotEmpty(),
enabled = selfIntroduction.length >= 20,
onClick = navigateEnterTimetable,
modifier = Modifier
.align(Alignment.BottomCenter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -21,7 +23,10 @@ import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.sopt.gongbaek.presentation.type.GongBaekBasicTextFieldType
Expand Down Expand Up @@ -89,6 +94,8 @@ private fun CustomTextField(
onErrorChange: (Boolean) -> Unit = {}
) {
var isFocused by remember { mutableStateOf(false) }
val focusManager = LocalFocusManager.current
val keyboardController = LocalSoftwareKeyboardController.current

val textStyle = gongBaekBasicTextFieldType.textFieldTextStyle.copy(
color = gongBaekBasicTextFieldType.textFieldFontColor
Expand Down Expand Up @@ -117,6 +124,15 @@ private fun CustomTextField(
.onFocusChanged { focusState ->
isFocused = focusState.isFocused
},
keyboardOptions = KeyboardOptions.Default.copy(
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
onDone = {
focusManager.clearFocus()
keyboardController?.hide()
}
),
textStyle = textStyle,
singleLine = gongBaekBasicTextFieldType.singLine,
cursorBrush = SolidColor(GongBaekTheme.colors.gray05)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ fun Char.isKoreanChar(): Boolean {
val regex = Regex("^[가-힣ㆍᆞᆢㄱ-ㅎㅏ-ㅣ]*$")
return regex.matches(this.toString())
}

fun Char.isCompleteKorean(): Boolean = this in '\uAC00'..'\uD7A3'
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.sopt.gongbaek.presentation.util.extension

fun String.hasCompleteKoreanCharacters(minLength: Int): Boolean {
val completeKoreanChars = this.filter { it.isCompleteKorean() }
return completeKoreanChars.length >= minLength
}
4 changes: 2 additions & 2 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
<string name="gongbaek_basic_textfield_nickname_title">닉네임</string>
<string name="gongbaek_basic_textfield_nickname_placeholder">한글을 활용해 최대 8자 이내로 입력해주세요.</string>
<string name="gongbaek_basic_textfield_self_introduction_title">소개글</string>
<string name="gongbaek_basic_textfield_self_introduction_palceholder">간단한 소개글을 입력해보세요.\nex) 안녕하세요. 복학한 화석입니다. 사람들을\n좋아하고 함께하는 활동을 좋아해요.</string>
<string name="gongbaek_basic_textfield_self_introduction_palceholder">간단한 소개글을 20자 이상 작성해보세요.\nex) 화석된 사람들끼리 소소한 점심 모임 어때요?</string>
<string name="gongbaek_basic_textfield_group_place_title">장소</string>
<string name="gongbaek_basic_textfield_group_place_placeholder">모임 장소를 입력해주세요. ex) M동 1층 로비</string>
<string name="gongbaek_basic_textfield_group_title_title">제목</string>
Expand Down Expand Up @@ -183,4 +183,4 @@

<!--GroupRegister-->
<string name="groupregister_complete_title">입력한 정보가 맞는지 확인해주세요!</string>
</resources>
</resources>