Skip to content

Commit

Permalink
Fix nickname text field error ui.
Browse files Browse the repository at this point in the history
  • Loading branch information
bywindow committed Aug 22, 2024
1 parent 23ee7b9 commit 4d60b41
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
import com.goalpanzi.core.model.CharacterType
import com.goalpanzi.mission_mate.core.designsystem.component.MissionMateButtonType
import com.goalpanzi.mission_mate.core.designsystem.component.MissionMateTextButton
import com.goalpanzi.mission_mate.core.designsystem.component.MissionMateTextFieldGroup
Expand All @@ -59,12 +60,10 @@ import com.goalpanzi.mission_mate.core.designsystem.theme.ColorWhite_FFFFFFFF
import com.goalpanzi.mission_mate.core.designsystem.theme.MissionMateTypography
import com.goalpanzi.mission_mate.core.designsystem.theme.component.MissionMateTopAppBar
import com.goalpanzi.mission_mate.core.designsystem.theme.component.NavigationType
import com.goalpanzi.core.model.CharacterType
import com.goalpanzi.mission_mate.feature.profile.model.CharacterListItem
import com.goalpanzi.mission_mate.feature.profile.model.ProfileUiState
import com.luckyoct.feature.profile.R
import dagger.hilt.android.EntryPointAccessors
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest

@Composable
Expand All @@ -87,7 +86,7 @@ fun ProfileRoute(
val viewModel = profileViewModel(profileSettingType = profileSettingType)
val context = LocalContext.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
val isInvalidNickname by viewModel.isInvalidNickname.collectAsStateWithLifecycle()
val isNicknameDuplicated by viewModel.isNicknameDuplicated.collectAsStateWithLifecycle()
val isNotChangedProfileInput by viewModel.isNotChangedProfileInput.collectAsStateWithLifecycle()

val keyboardController = LocalSoftwareKeyboardController.current
Expand Down Expand Up @@ -125,16 +124,14 @@ fun ProfileRoute(
uiState = uiState,
profileSettingType = profileSettingType,
isNotChangedProfileInput = isNotChangedProfileInput,
nickname = viewModel.nickname,
onClickCharacter = { viewModel.selectCharacter(it) },
onClickSave = {
keyboardController?.hide()
viewModel.saveProfile(it)
},
onBackClick = onBackClick,
isInvalidNickname = isInvalidNickname,
isNicknameDuplicated = isNicknameDuplicated,
resetNicknameErrorState = { viewModel.resetNicknameErrorState() },
onNicknameChanged = viewModel::updateNickname
)
}
}
Expand All @@ -145,12 +142,10 @@ fun ProfileContent(
uiState: ProfileUiState,
profileSettingType: ProfileSettingType,
isNotChangedProfileInput: Boolean,
nickname : String,
onClickCharacter: (CharacterListItem) -> Unit = {},
onClickSave: (String) -> Unit = {},
onBackClick: (() -> Unit)? = null,
isInvalidNickname: Boolean,
onNicknameChanged : (String) -> Unit,
isNicknameDuplicated: Boolean,
resetNicknameErrorState: () -> Unit
) {
Column(
Expand All @@ -176,13 +171,10 @@ fun ProfileContent(
profileSettingType = profileSettingType,
initialNickname = uiState.nickname,
characters = uiState.characterList,
nickname = nickname,
isNotChangedProfileInput = isNotChangedProfileInput,
onClickCharacter = onClickCharacter,
onClickSave = onClickSave,
isInvalidNickname = isInvalidNickname,
resetNicknameErrorState = resetNicknameErrorState,
onNicknameChanged = onNicknameChanged
isNicknameDuplicated = isNicknameDuplicated,
)
}
}
Expand All @@ -196,16 +188,19 @@ fun ColumnScope.ProfileScreen(
profileSettingType: ProfileSettingType,
characters: List<CharacterListItem>,
isNotChangedProfileInput: Boolean,
nickname : String,
onClickCharacter: (CharacterListItem) -> Unit,
onClickSave: (String) -> Unit,
isInvalidNickname: Boolean,
onNicknameChanged : (String) -> Unit,
resetNicknameErrorState: () -> Unit = {}
isNicknameDuplicated: Boolean,
) {
// var nicknameInput by remember { mutableStateOf(initialNickname) }
var nicknameInput by remember { mutableStateOf(initialNickname) }
val scrollState = rememberScrollState()
val regex = Regex("^[가-힣ㅏ-ㅣㄱ-ㅎa-zA-Z0-9]{1,6}$")
var invalidNicknameError by remember { mutableStateOf(false) }

LaunchedEffect(nicknameInput) {
if (nicknameInput.isEmpty()) return@LaunchedEffect
invalidNicknameError = (nicknameInput.length > 6 || regex.matches(nicknameInput).not())
}

Column(
modifier = modifier
Expand All @@ -224,7 +219,7 @@ fun ColumnScope.ProfileScreen(
),
modifier = modifier
.align(Alignment.CenterHorizontally)
.padding(top = if(profileSettingType == ProfileSettingType.SETTING) 0.dp else 56.dp),
.padding(top = if (profileSettingType == ProfileSettingType.SETTING) 0.dp else 56.dp),
style = MissionMateTypography.heading_sm_bold,
color = ColorGray1_FF404249
)
Expand Down Expand Up @@ -252,17 +247,11 @@ fun ColumnScope.ProfileScreen(
.padding(top = 38.dp, start = 24.dp, end = 24.dp)
.fillMaxWidth()
.wrapContentHeight(),
text = nickname,
onValueChange = onNicknameChanged,
// {
// if (regex.matches(it) || it.isEmpty()) {
// nicknameInput = it
// }
// resetNicknameErrorState()
// },
text = nicknameInput,
onValueChange = { nicknameInput = it },
hintId = R.string.nickname_hint,
guidanceId = if (isInvalidNickname) R.string.err_duplicated_nickname else R.string.nickname_input_guide,
isError = isInvalidNickname
guidanceId = if (isNicknameDuplicated) R.string.err_duplicated_nickname else R.string.nickname_input_guide,
isError = invalidNicknameError || isNicknameDuplicated
)
}

Expand All @@ -271,23 +260,26 @@ fun ColumnScope.ProfileScreen(
.padding(bottom = 36.dp, start = 24.dp, end = 24.dp)
.fillMaxWidth(),
textId = R.string.save,
buttonType =
if (profileSettingType == ProfileSettingType.CREATE) {
if (nickname.trim().isEmpty()) {
MissionMateButtonType.DISABLED
} else {
MissionMateButtonType.ACTIVE
buttonType = when (profileSettingType) {
ProfileSettingType.CREATE -> {
if (nicknameInput.trim().isEmpty() || invalidNicknameError) {
MissionMateButtonType.DISABLED
} else {
MissionMateButtonType.ACTIVE
}
}
} else {
if ((initialNickname == nickname && isNotChangedProfileInput) ||
nickname.trim().isEmpty()
) {
MissionMateButtonType.DISABLED
} else {
MissionMateButtonType.ACTIVE

ProfileSettingType.SETTING -> {
if ((initialNickname == nicknameInput && isNotChangedProfileInput) ||
nicknameInput.trim().isEmpty() || invalidNicknameError
) {
MissionMateButtonType.DISABLED
} else {
MissionMateButtonType.ACTIVE
}
}
},
onClick = { onClickSave(nickname) }
onClick = { onClickSave(nicknameInput) }
)
}

Expand Down Expand Up @@ -416,12 +408,10 @@ fun ColumnScope.ProfileScreenPreview() {
backgroundResId = com.goalpanzi.mission_mate.core.designsystem.R.drawable.background_panda
),
),
nickname = "미션메이트",
onClickCharacter = {},
onClickSave = {},
isInvalidNickname = false,
isNicknameDuplicated = false,
isNotChangedProfileInput = false,
onNicknameChanged = {}
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
package com.goalpanzi.mission_mate.feature.profile

import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
Expand Down Expand Up @@ -46,17 +43,14 @@ class ProfileViewModel @AssistedInject constructor(

private val defaultCharacters = CharacterListItem.createDefaultList()

var nickname by mutableStateOf("")
private set

private val _uiState = MutableStateFlow<ProfileUiState>(ProfileUiState.Loading)
val uiState = _uiState.asStateFlow()

private val _isInvalidNickname = MutableStateFlow(false)
val isInvalidNickname = _isInvalidNickname.asStateFlow()
private val _isNicknameDuplicated = MutableStateFlow(false)
val isNicknameDuplicated = _isNicknameDuplicated.asStateFlow()

private val _isNotChangedProfileInput = MutableStateFlow(true)
val isNotChangedProfileInput : StateFlow<Boolean> = _isNotChangedProfileInput.asStateFlow()
val isNotChangedProfileInput: StateFlow<Boolean> = _isNotChangedProfileInput.asStateFlow()

private val _isSaveSuccess = MutableSharedFlow<Boolean>()
val isSaveSuccess = _isSaveSuccess.asSharedFlow()
Expand Down Expand Up @@ -93,10 +87,19 @@ class ProfileViewModel @AssistedInject constructor(
}
}

fun updateNickname(input: String) {
nickname = input

}
// fun updateNickname(input: String) {
// viewModelScope.launch {
// _invalidNicknameError.emit(
// if (input.length > 6) {
// InvalidNicknameError.TooLong
// } else if (input.contains(Regex("[^가-힣a-zA-Z0-9]"))) {
// InvalidNicknameError.IncludeSpecial
// } else {
// InvalidNicknameError.Duplicated
// }
// )
// }
// }

fun selectCharacter(character: CharacterListItem) {
val state = uiState.value as? ProfileUiState.Success ?: return
Expand All @@ -112,7 +115,7 @@ class ProfileViewModel @AssistedInject constructor(
}

fun resetNicknameErrorState() {
_isInvalidNickname.value = false
_isNicknameDuplicated.value = false
}

fun saveProfile(nickname: String) {
Expand All @@ -122,7 +125,7 @@ class ProfileViewModel @AssistedInject constructor(
it.isSelected
} ?: return@launch

when(
when (
val response = profileUseCase
.saveProfile(
nickname = nickname,
Expand All @@ -133,13 +136,14 @@ class ProfileViewModel @AssistedInject constructor(
is NetworkResult.Success -> {
_isSaveSuccess.emit(true)
}

is NetworkResult.Exception -> {}
is NetworkResult.Error -> {
if (response.code == 409) {
_isInvalidNickname.emit(true)
_isNicknameDuplicated.emit(true)
}
}
}
}
}
}
}

0 comments on commit 4d60b41

Please sign in to comment.