Skip to content

Commit

Permalink
feat: 닉네임 검증 로직 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
inseonyun committed Aug 8, 2023
1 parent 872c65f commit c9553f2
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,56 @@
package com.created.team201.presentation.onBoarding

import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.text.InputFilter.LengthFilter
import androidx.activity.viewModels
import androidx.annotation.ColorRes
import androidx.annotation.StringRes
import com.created.team201.R
import com.created.team201.databinding.ActivityOnBoardingBinding
import com.created.team201.presentation.common.BindingActivity

class OnBoardingActivity :
BindingActivity<ActivityOnBoardingBinding>(R.layout.activity_on_boarding) {
private val viewModel: OnBoardingViewModel by viewModels {
OnBoardingViewModel.Factory
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

initBinding()
initNickname()
setObserveNickname()
}

private fun initBinding() {
binding.lifecycleOwner = this
binding.viewModel = viewModel
}

private fun initNickname() {
binding.etOnBoardingNickname.filters =
arrayOf(viewModel.getInputFilter(), LengthFilter(MAX_NICKNAME_LENGTH))
}

private fun setObserveNickname() {
viewModel.nicknameState.observe(this) { state ->
setNicknameValidateIntroduction(state.color, state.introduction)
}
}

private fun setNicknameValidateIntroduction(
@ColorRes color: Int, @StringRes text: Int
) {
binding.tvOnBoardingNicknameValidateIntroduction.setTextColor(getColor(color))
binding.tvOnBoardingNicknameValidateIntroduction.text = getString(text)
}

companion object {
private const val MAX_NICKNAME_LENGTH = 8

fun getIntent(context: Context): Intent = Intent(context, OnBoardingActivity::class.java)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package com.created.team201.presentation.onBoarding

import android.text.InputFilter
import android.text.Spanned
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import com.created.team201.presentation.onBoarding.model.NicknameState
import com.created.team201.presentation.onBoarding.model.NicknameUiModel
import com.created.team201.util.NonNullLiveData
import com.created.team201.util.NonNullMutableLiveData
import java.util.regex.Pattern

class OnBoardingViewModel : ViewModel() {
private val _nickname: MutableLiveData<NicknameUiModel> = MutableLiveData()
val nickname: LiveData<NicknameUiModel>
get() = _nickname

private val _introduction: NonNullMutableLiveData<String> = NonNullMutableLiveData("")
val introduction: NonNullLiveData<String>
get() = _introduction

private val _nicknameState: MutableLiveData<NicknameState> = MutableLiveData()
val nicknameState: LiveData<NicknameState>
get() = _nicknameState

private val _isEnableSave: MediatorLiveData<Boolean> =
MediatorLiveData<Boolean>().apply {
addSourceList(nickname, nicknameState) {
isInitializeOnBoarding()
}
}
val isEnableSave: LiveData<Boolean>
get() = _isEnableSave

fun setNickname(nickname: String) {
_nickname.value = NicknameUiModel(nickname)
}

fun getInputFilter(): InputFilter = object : InputFilter {
override fun filter(
text: CharSequence,
start: Int,
end: Int,
dest: Spanned,
dStart: Int,
dEnd: Int
): CharSequence {
if (text.isBlank() || PATTERN_NICKNAME.matcher(text).matches())
return text

_nicknameState.value = NicknameState.UNAVAILABLE
return ""
}
}

private fun isInitializeOnBoarding(): Boolean =
nickname.value != null && nicknameState.value == NicknameState.AVAILABLE

private fun <T> MediatorLiveData<T>.addSourceList(
vararg liveDataArgument: LiveData<*>,
onChanged: () -> T,
) {
liveDataArgument.forEach {
this.addSource(it) {
value = onChanged()
}
}
}

companion object {
private val PATTERN_NICKNAME = Pattern.compile("^[_a-zA-Z0-9가-힣ㄱ-ㅎㅏ-ㅣ]+$")

val Factory: ViewModelProvider.Factory = viewModelFactory {
initializer {
OnBoardingViewModel()
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.created.team201.presentation.onBoarding.model

import androidx.annotation.ColorRes
import androidx.annotation.StringRes
import com.created.team201.R

sealed interface NicknameState {
@get:ColorRes
val color: Int

@get:StringRes
val introduction: Int

object AVAILABLE : NicknameState {
override val color: Int
get() = R.color.blue_9BB9F2
override val introduction: Int
get() = R.string.onBoarding_available_nickname
}

object UNAVAILABLE : NicknameState {
override val color: Int
get() = R.color.red_EB7A7A
override val introduction: Int
get() = R.string.onBoarding_unAvailable_nickname
}

object DUPLICATE : NicknameState {
override val color: Int
get() = R.color.red_EB7A7A
override val introduction: Int
get() = R.string.onBoarding_duplicate_nickname
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.created.team201.presentation.onBoarding.model

data class NicknameUiModel(
val nickname: String
)
5 changes: 5 additions & 0 deletions android/app/src/main/res/layout/activity_on_boarding.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@

<data>

<variable
name="viewModel"
type="com.created.team201.presentation.onBoarding.OnBoardingViewModel" />
</data>

<androidx.constraintlayout.widget.ConstraintLayout
Expand Down Expand Up @@ -72,6 +75,7 @@
android:inputType="text"
android:maxLength="8"
android:maxLines="1"
android:onTextChanged="@{(text, start, before, count) -> viewModel.setNickname(text)}"
android:paddingHorizontal="12dp"
android:textAppearance="@style/text_r14"
android:textColor="@color/white"
Expand Down Expand Up @@ -144,6 +148,7 @@
android:layout_marginHorizontal="16dp"
android:layout_marginBottom="28dp"
android:background="@drawable/bg_btn_color_and_radius_10dp_disabled"
android:enabled="@{viewModel.isEnableSave()}"
android:paddingVertical="14dp"
android:text="@string/onBoarding_btn_text"
android:textAlignment="center"
Expand Down

0 comments on commit c9553f2

Please sign in to comment.