diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 310c0ae4..4c29b984 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -4,9 +4,7 @@
-
+
-
diff --git a/domain/src/main/kotlin/com/going/domain/entity/NameState.kt b/domain/src/main/kotlin/com/going/domain/entity/NameState.kt
index 413b375a..765922df 100644
--- a/domain/src/main/kotlin/com/going/domain/entity/NameState.kt
+++ b/domain/src/main/kotlin/com/going/domain/entity/NameState.kt
@@ -1,5 +1,5 @@
package com.going.domain.entity
enum class NameState {
- Empty, Success, Blank
+ Empty, Success, Blank, OVER
}
diff --git a/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripActivity.kt b/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripActivity.kt
index 31b5c0b0..1eb96960 100644
--- a/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripActivity.kt
+++ b/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripActivity.kt
@@ -23,7 +23,6 @@ class CreateTripActivity :
super.onCreate(savedInstanceState)
initBindingViewModel()
- observeTextLength()
observeIsNameAvailable()
observeCheckStartDateAvailable()
observeCheckEndDateAvailable()
@@ -37,24 +36,10 @@ class CreateTripActivity :
binding.viewModel = viewModel
}
- private fun observeTextLength() {
- viewModel.nameLength.observe(this) { length ->
- val maxNameLength = viewModel.getMaxNameLen()
-
- if (length > maxNameLength) {
- binding.etCreateTripName.apply {
- setText(text?.subSequence(0, maxNameLength))
- setSelection(maxNameLength)
- }
- }
- }
- }
-
private fun observeIsNameAvailable() {
viewModel.isNameAvailable.observe(this) { state ->
setColors(
- false,
- viewModel.nameLength.value ?: 0,
+ state,
binding.tvNameCounter,
) { background ->
binding.etCreateTripName.background = ResourcesCompat.getDrawable(
@@ -99,17 +84,17 @@ class CreateTripActivity :
}
private fun setColors(
- hasFocus: Boolean,
- length: Int,
+ state: NameState,
counter: TextView,
setBackground: (Int) -> Unit,
) {
- val (color, background) = when {
- viewModel.isNameAvailable.value != NameState.Blank && hasFocus -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
- length == 0 -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
- viewModel.isNameAvailable.value == NameState.Blank && counter == binding.tvNameCounter -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
- else -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ val (color, background) = when (state) {
+ NameState.Empty -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
+ NameState.Success -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ NameState.Blank -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
+ NameState.OVER -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
}
+
setCounterColor(counter, color)
setBackground(background)
}
diff --git a/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripViewModel.kt b/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripViewModel.kt
index 80485bfc..0b8cbe63 100644
--- a/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripViewModel.kt
+++ b/presentation/src/main/java/com/going/presentation/entertrip/createtrip/choosedate/CreateTripViewModel.kt
@@ -24,13 +24,12 @@ class CreateTripViewModel : ViewModel() {
val isTripAvailable = MutableLiveData(false)
var isCheckTripAvailable = MutableLiveData(false)
- fun getMaxNameLen() = MAX_TRIP_LEN
-
fun checkNameAvailable() {
nameLength.value = name.value?.getGraphemeLength()
isNameAvailable.value = when {
nameLength.value == 0 -> NameState.Empty
+ (nameLength.value ?: 0) > MAX_TRIP_LEN -> NameState.OVER
name.value.isNullOrBlank() -> NameState.Blank
else -> NameState.Success
}
@@ -60,7 +59,6 @@ class CreateTripViewModel : ViewModel() {
} else {
isEndDateAvailable.value = false
checkTripAvailable()
-
}
}
diff --git a/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingActivity.kt b/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingActivity.kt
index a9798d0e..24f18f38 100644
--- a/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingActivity.kt
+++ b/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingActivity.kt
@@ -33,10 +33,9 @@ class OnboardingProfileSettingActivity :
initBindingViewModel()
initOnLineInfoEditorActionListener()
- initSetOnFocusChangeListener()
initSignUpBtnClickListener()
observeIsNameAvailable()
- observeTextLength()
+ observeIsInfoAvailable()
observeIsSignUpState()
initOnBackPressedListener()
}
@@ -52,12 +51,17 @@ class OnboardingProfileSettingActivity :
}
}
- private fun initSetOnFocusChangeListener() {
- binding.etOnboardingProfileSettingName.setOnFocusChangeListener { _, hasFocus ->
+ private fun initSignUpBtnClickListener() {
+ binding.btnOnboardingProfileSettingFinish.setOnSingleClickListener {
+ viewModel.startSignUp()
+ }
+ }
+
+ private fun observeIsNameAvailable() {
+ viewModel.isNameAvailable.observe(this) { state ->
setColors(
- hasFocus,
- viewModel.nowNameLength.value ?: 0,
binding.tvNameCounter,
+ state,
) { background ->
binding.etOnboardingProfileSettingName.background = ResourcesCompat.getDrawable(
this.resources,
@@ -66,12 +70,13 @@ class OnboardingProfileSettingActivity :
)
}
}
+ }
- binding.etOnboardingProfileSettingInfo.setOnFocusChangeListener { _, hasFocus ->
+ private fun observeIsInfoAvailable() {
+ viewModel.isInfoAvailable.observe(this) { state ->
setColors(
- hasFocus,
- viewModel.nowInfoLength.value ?: 0,
binding.tvInfoCounter,
+ state,
) { background ->
binding.etOnboardingProfileSettingInfo.background = ResourcesCompat.getDrawable(
this.resources,
@@ -82,39 +87,16 @@ class OnboardingProfileSettingActivity :
}
}
- private fun initSignUpBtnClickListener() {
- binding.btnOnboardingProfileSettingFinish.setOnSingleClickListener {
- viewModel.startSignUp()
- }
- }
-
- private fun observeIsNameAvailable() {
- viewModel.isNameAvailable.observe(this) { state ->
- setColors(
- false,
- viewModel.nowNameLength.value ?: 0,
- binding.tvNameCounter,
- ) { background ->
- binding.etOnboardingProfileSettingName.background = ResourcesCompat.getDrawable(
- this.resources,
- background,
- theme,
- )
- }
- }
- }
-
private fun setColors(
- hasFocus: Boolean,
- length: Int,
counter: TextView,
+ state: NameState,
setBackground: (Int) -> Unit,
) {
- val (color, background) = when {
- viewModel.isNameAvailable.value != NameState.Blank && hasFocus -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
- length == 0 -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
- viewModel.isNameAvailable.value == NameState.Blank && counter == binding.tvNameCounter -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
- else -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ val (color, background) = when (state) {
+ NameState.Empty -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
+ NameState.Success -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ NameState.Blank -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
+ NameState.OVER -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
}
setCounterColor(counter, color)
@@ -125,31 +107,6 @@ class OnboardingProfileSettingActivity :
counter.setTextColor(getColor(color))
}
- // 커스텀 글자수 제한 함수
- private fun observeTextLength() {
- viewModel.nowNameLength.observe(this) { length ->
- val maxNameLength = viewModel.getMaxNameLen()
-
- if (length > maxNameLength) {
- binding.etOnboardingProfileSettingName.apply {
- setText(text?.subSequence(0, maxNameLength))
- setSelection(maxNameLength)
- }
- }
- }
-
- viewModel.nowInfoLength.observe(this) { length ->
- val maxInfoLength = viewModel.getMaxInfoLen()
-
- if (length > maxInfoLength) {
- binding.etOnboardingProfileSettingInfo.apply {
- setText(text?.subSequence(0, maxInfoLength))
- setSelection(maxInfoLength)
- }
- }
- }
- }
-
private fun observeIsSignUpState() {
viewModel.isSignUpState.flowWithLifecycle(lifecycle).onEach { state ->
when (state) {
diff --git a/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingViewModel.kt b/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingViewModel.kt
index fdaf97c9..02c39836 100644
--- a/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingViewModel.kt
+++ b/presentation/src/main/java/com/going/presentation/onboarding/signup/OnboardingProfileSettingViewModel.kt
@@ -30,14 +30,12 @@ class OnboardingProfileSettingViewModel @Inject constructor(
val nowInfoLength = MutableLiveData(0)
val isNameAvailable = MutableLiveData(NameState.Empty)
+ val isInfoAvailable = MutableLiveData(NameState.Empty)
val isProfileAvailable = MutableLiveData(false)
private val _isSignUpState = MutableStateFlow(AuthState.LOADING)
val isSignUpState: StateFlow = _isSignUpState
- fun getMaxNameLen() = MAX_NAME_LEN
- fun getMaxInfoLen() = MAX_INFO_LEN
-
fun checkProfileAvailable() {
nowNameLength.value = name.value.getGraphemeLength()
nowInfoLength.value = info.value.getGraphemeLength()
@@ -45,13 +43,18 @@ class OnboardingProfileSettingViewModel @Inject constructor(
isNameAvailable.value = when {
nowNameLength.value == 0 -> NameState.Empty
name.value.isBlank() -> NameState.Blank
+ (nowNameLength.value ?: 0) > 3 -> NameState.OVER
else -> NameState.Success
}
- val isInfoAvailable = nowInfoLength.value in 1..MAX_INFO_LEN
+ isInfoAvailable.value = when {
+ nowInfoLength.value == 0 -> NameState.Empty
+ (nowInfoLength.value ?: 0) > MAX_INFO_LEN -> NameState.OVER
+ else -> NameState.Success
+ }
isProfileAvailable.value =
- (isNameAvailable.value == NameState.Success) && isInfoAvailable
+ (isNameAvailable.value == NameState.Success) && (isInfoAvailable.value == NameState.Success)
}
fun startSignUp() {
diff --git a/presentation/src/main/java/com/going/presentation/onboarding/splash/SplashActivity.kt b/presentation/src/main/java/com/going/presentation/onboarding/splash/SplashActivity.kt
index 2d314a1b..e6a57847 100644
--- a/presentation/src/main/java/com/going/presentation/onboarding/splash/SplashActivity.kt
+++ b/presentation/src/main/java/com/going/presentation/onboarding/splash/SplashActivity.kt
@@ -30,7 +30,6 @@ class SplashActivity : BaseActivity(R.layout.activity_spl
setStatusBarColor()
checkConnectedNetwork()
observeUserState()
-
}
private fun setStatusBarColor() {
@@ -105,5 +104,4 @@ class SplashActivity : BaseActivity(R.layout.activity_spl
}
finish()
}
-
}
diff --git a/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateActivity.kt b/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateActivity.kt
index 15d0e0f8..26039134 100644
--- a/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateActivity.kt
+++ b/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateActivity.kt
@@ -7,9 +7,9 @@ import androidx.activity.viewModels
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
+import com.going.domain.entity.NameState
import com.going.presentation.R
import com.going.presentation.databinding.ActivityMyTodoCreateBinding
-import com.going.presentation.todo.TodoActivity
import com.going.presentation.todo.TodoActivity.Companion.EXTRA_TRIP_ID
import com.going.presentation.todo.ourtodo.create.OurTodoCreateActivity.Companion.EXTRA_PARTICIPANT_ID
import com.going.ui.base.BaseActivity
@@ -32,8 +32,6 @@ class MyTodoCreateActivity :
super.onCreate(savedInstanceState)
initViewModel()
- initTodoFocusListener()
- initMemoFocusListener()
initDateClickListener()
initFinishBtnListener()
initBackBtnListener()
@@ -48,30 +46,6 @@ class MyTodoCreateActivity :
binding.vm = viewModel
}
- private fun initTodoFocusListener() {
- binding.etMyTodoCreateTodo.setOnFocusChangeListener { _, hasFocus ->
- setColors(
- hasFocus,
- viewModel.nowTodoLength.value ?: 0,
- binding.tvMyTodoTodoCounter,
- ) { background ->
- binding.etMyTodoCreateTodo.background = setBackgroundColor(background)
- }
- }
- }
-
- private fun initMemoFocusListener() {
- binding.etMyTodoCreateMemo.setOnFocusChangeListener { _, hasFocus ->
- setColors(
- hasFocus,
- viewModel.nowMemoLength.value ?: 0,
- binding.tvMyTodoMemoCounter,
- ) { background ->
- binding.etMyTodoCreateMemo.background = setBackgroundColor(background)
- }
- }
- }
-
private fun initDateClickListener() {
binding.etMyTodoCreateDate.setOnSingleClickListener {
myTodoCreateBottomSheet = MyTodoCreateBottomSheet()
@@ -92,8 +66,8 @@ class MyTodoCreateActivity :
}
private fun getId() {
- viewModel.tripId = intent.getLongExtra(EXTRA_TRIP_ID,0)
- viewModel.participantId = intent.getLongExtra(EXTRA_PARTICIPANT_ID,0)
+ viewModel.tripId = intent.getLongExtra(EXTRA_TRIP_ID, 0)
+ viewModel.participantId = intent.getLongExtra(EXTRA_PARTICIPANT_ID, 0)
}
private fun observeTodoCreateState() {
@@ -114,18 +88,9 @@ class MyTodoCreateActivity :
}
private fun observeTextLength() {
- viewModel.nowTodoLength.observe(this) { length ->
- val maxTodoLen = viewModel.getMaxTodoLen()
-
- if (length > maxTodoLen) {
- binding.etMyTodoCreateTodo.apply {
- setText(text?.subSequence(0, maxTodoLen))
- setSelection(maxTodoLen)
- }
- }
+ viewModel.isTodoAvailable.observe(this) { state ->
setColors(
- false,
- viewModel.nowTodoLength.value ?: 0,
+ state,
binding.tvMyTodoTodoCounter,
) { background ->
binding.etMyTodoCreateTodo.background = setBackgroundColor(background)
@@ -134,17 +99,9 @@ class MyTodoCreateActivity :
}
private fun observeMemoLength() {
- viewModel.nowMemoLength.observe(this) { length ->
- val maxMemoLen = viewModel.getMaxMemoLen()
- if (length > maxMemoLen) {
- binding.etMyTodoCreateTodo.apply {
- setText(text?.subSequence(0, maxMemoLen))
- setSelection(maxMemoLen)
- }
- }
+ viewModel.isMemoAvailable.observe(this) { state ->
setColors(
- false,
- viewModel.nowMemoLength.value ?: 0,
+ state,
binding.tvMyTodoMemoCounter,
) { background ->
binding.etMyTodoCreateMemo.background = setBackgroundColor(background)
@@ -163,16 +120,17 @@ class MyTodoCreateActivity :
}
private fun setColors(
- hasFocus: Boolean,
- length: Int,
+ state: NameState,
counter: TextView,
setBackground: (Int) -> Unit,
) {
- val (color, background) = when {
- hasFocus || viewModel.nowTodoLength.value != 0 -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
- length == 0 -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
- else -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ val (color, background) = when (state) {
+ NameState.Empty -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
+ NameState.Success -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ NameState.Blank -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
+ NameState.OVER -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
}
+
setCounterColor(counter, color)
setBackground(background)
}
@@ -197,4 +155,4 @@ class MyTodoCreateActivity :
companion object {
private const val DATE_BOTTOM_SHEET = "DATE_BOTTOM_SHEET"
}
-}
\ No newline at end of file
+}
diff --git a/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateViewModel.kt b/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateViewModel.kt
index 634ce1d5..edcf9a9a 100644
--- a/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateViewModel.kt
+++ b/presentation/src/main/java/com/going/presentation/todo/mytodo/create/MyTodoCreateViewModel.kt
@@ -3,8 +3,10 @@ package com.going.presentation.todo.mytodo.create
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.going.domain.entity.NameState
import com.going.domain.entity.request.TodoCreateRequestModel
import com.going.domain.repository.TodoRepository
+import com.going.presentation.todo.ourtodo.create.OurTodoCreateViewModel
import com.going.ui.extension.UiState
import com.going.ui.extension.getGraphemeLength
import dagger.hilt.android.lifecycle.HiltViewModel
@@ -19,11 +21,13 @@ class MyTodoCreateViewModel @Inject constructor(
) : ViewModel() {
val todo = MutableLiveData("")
+ val isTodoAvailable = MutableLiveData(NameState.Empty)
val nowTodoLength = MutableLiveData(0)
val endDate = MutableLiveData("")
val memo = MutableLiveData("")
+ val isMemoAvailable = MutableLiveData(NameState.Empty)
val nowMemoLength = MutableLiveData(0)
val isFinishAvailable = MutableLiveData(false)
@@ -34,15 +38,25 @@ class MyTodoCreateViewModel @Inject constructor(
var tripId: Long = 0
var participantId: Long = 0
- fun getMaxTodoLen() = MAX_TODO_LEN
-
- fun getMaxMemoLen() = MAX_MEMO_LEN
-
fun checkIsFinishAvailable() {
nowTodoLength.value = todo.value?.getGraphemeLength()
+ isTodoAvailable.value = when {
+ nowTodoLength.value == 0 -> NameState.Empty
+ (nowTodoLength.value ?: 0) > MAX_TODO_LEN -> NameState.OVER
+ todo.value.isNullOrBlank() -> NameState.Blank
+ else -> NameState.Success
+ }
+
nowMemoLength.value = memo.value?.getGraphemeLength()
+ isMemoAvailable.value = when {
+ nowMemoLength.value == 0 -> NameState.Empty
+ (nowMemoLength.value ?: 0) > MAX_MEMO_LEN -> NameState.OVER
+ memo.value.isNullOrBlank() -> NameState.Blank
+ else -> NameState.Success
+ }
+
isFinishAvailable.value =
- todo.value?.isNotEmpty() == true && endDate.value?.isNotEmpty() == true
+ todo.value?.isNotEmpty() == true && endDate.value?.isNotEmpty() == true && isTodoAvailable.value == NameState.Success && isMemoAvailable.value != NameState.OVER
}
fun postToCreateTodoFromServer() {
@@ -71,5 +85,4 @@ class MyTodoCreateViewModel @Inject constructor(
const val MAX_TODO_LEN = 15
const val MAX_MEMO_LEN = 1000
}
-
}
diff --git a/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateActivity.kt b/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateActivity.kt
index 86d0a192..a4dbaefb 100644
--- a/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateActivity.kt
+++ b/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateActivity.kt
@@ -7,6 +7,7 @@ import androidx.activity.viewModels
import androidx.core.content.res.ResourcesCompat
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
+import com.going.domain.entity.NameState
import com.going.domain.entity.response.TripParticipantModel
import com.going.presentation.R
import com.going.presentation.databinding.ActivityOurTodoCreateBinding
@@ -36,8 +37,6 @@ class OurTodoCreateActivity :
initViewModel()
initNameListAdapter()
- initTodoFocusListener()
- initMemoFocusListener()
initDateClickListener()
initFinishBtnListener()
initBackBtnListener()
@@ -62,30 +61,6 @@ class OurTodoCreateActivity :
binding.rvOurTodoCreatePerson.adapter = adapter
}
- private fun initTodoFocusListener() {
- binding.etOurTodoCreateTodo.setOnFocusChangeListener { _, hasFocus ->
- setColors(
- hasFocus,
- viewModel.nowTodoLength.value ?: 0,
- binding.tvOurTodoTodoCounter,
- ) { background ->
- binding.etOurTodoCreateTodo.background = setBackgroundColor(background)
- }
- }
- }
-
- private fun initMemoFocusListener() {
- binding.etOurTodoCreateMemo.setOnFocusChangeListener { _, hasFocus ->
- setColors(
- hasFocus,
- viewModel.nowMemoLength.value ?: 0,
- binding.tvOurTodoMemoCounter,
- ) { background ->
- binding.etOurTodoCreateMemo.background = setBackgroundColor(background)
- }
- }
- }
-
private fun initDateClickListener() {
binding.etOurTodoCreateDate.setOnSingleClickListener {
ourTodoCreateBottomSheet = OurTodoCreateBottomSheet()
@@ -107,7 +82,7 @@ class OurTodoCreateActivity :
}
private fun getTripId() {
- viewModel.tripId = intent.getLongExtra(EXTRA_TRIP_ID,0)
+ viewModel.tripId = intent.getLongExtra(EXTRA_TRIP_ID, 0)
}
private fun setParticipantList() {
@@ -140,18 +115,9 @@ class OurTodoCreateActivity :
}
private fun observeTextLength() {
- viewModel.nowTodoLength.observe(this) { length ->
- val maxTodoLen = viewModel.getMaxTodoLen()
-
- if (length > maxTodoLen) {
- binding.etOurTodoCreateTodo.apply {
- setText(text?.subSequence(0, maxTodoLen))
- setSelection(maxTodoLen)
- }
- }
+ viewModel.isTodoAvailable.observe(this) { state ->
setColors(
- false,
- viewModel.nowTodoLength.value ?: 0,
+ state,
binding.tvOurTodoTodoCounter,
) { background ->
binding.etOurTodoCreateTodo.background = setBackgroundColor(background)
@@ -160,17 +126,9 @@ class OurTodoCreateActivity :
}
private fun observeMemoLength() {
- viewModel.nowMemoLength.observe(this) { length ->
- val maxMemoLen = viewModel.getMaxMemoLen()
- if (length > maxMemoLen) {
- binding.etOurTodoCreateTodo.apply {
- setText(text?.subSequence(0, maxMemoLen))
- setSelection(maxMemoLen)
- }
- }
+ viewModel.isMemoAvailable.observe(this) { state ->
setColors(
- false,
- viewModel.nowMemoLength.value ?: 0,
+ state,
binding.tvOurTodoMemoCounter,
) { background ->
binding.etOurTodoCreateMemo.background = setBackgroundColor(background)
@@ -189,16 +147,17 @@ class OurTodoCreateActivity :
}
private fun setColors(
- hasFocus: Boolean,
- length: Int,
+ state: NameState,
counter: TextView,
setBackground: (Int) -> Unit,
) {
- val (color, background) = when {
- hasFocus || viewModel.nowTodoLength.value != 0 -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
- length == 0 -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
- else -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ val (color, background) = when (state) {
+ NameState.Empty -> R.color.gray_200 to R.drawable.shape_rect_4_gray200_line
+ NameState.Success -> R.color.gray_700 to R.drawable.shape_rect_4_gray700_line
+ NameState.Blank -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
+ NameState.OVER -> R.color.red_500 to R.drawable.shape_rect_4_red500_line
}
+
setCounterColor(counter, color)
setBackground(background)
}
@@ -228,5 +187,4 @@ class OurTodoCreateActivity :
const val EXTRA_NAME = "EXTRA_NAME"
const val EXTRA_RESULT = "EXTRA_RESULT"
}
-
-}
\ No newline at end of file
+}
diff --git a/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateViewModel.kt b/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateViewModel.kt
index d9103cbf..237dcfcd 100644
--- a/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateViewModel.kt
+++ b/presentation/src/main/java/com/going/presentation/todo/ourtodo/create/OurTodoCreateViewModel.kt
@@ -1,8 +1,10 @@
package com.going.presentation.todo.ourtodo.create
+import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.going.domain.entity.NameState
import com.going.domain.entity.request.TodoCreateRequestModel
import com.going.domain.entity.response.TripParticipantModel
import com.going.domain.repository.TodoRepository
@@ -12,7 +14,6 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
-import java.text.BreakIterator
import javax.inject.Inject
@HiltViewModel
@@ -21,11 +22,13 @@ class OurTodoCreateViewModel @Inject constructor(
) : ViewModel() {
val todo = MutableLiveData("")
+ val isTodoAvailable = MutableLiveData(NameState.Empty)
val nowTodoLength = MutableLiveData(0)
val endDate = MutableLiveData("")
val memo = MutableLiveData("")
+ val isMemoAvailable = MutableLiveData(NameState.Empty)
val nowMemoLength = MutableLiveData(0)
val isFinishAvailable = MutableLiveData(false)
@@ -38,15 +41,24 @@ class OurTodoCreateViewModel @Inject constructor(
var tripId: Long = 0
- fun getMaxTodoLen() = MAX_TODO_LEN
-
- fun getMaxMemoLen() = MAX_MEMO_LEN
-
fun checkIsFinishAvailable() {
nowTodoLength.value = todo.value?.getGraphemeLength()
+ isTodoAvailable.value = when {
+ nowTodoLength.value == 0 -> NameState.Empty
+ (nowTodoLength.value ?: 0) > MAX_TODO_LEN -> NameState.OVER
+ todo.value.isNullOrBlank() -> NameState.Blank
+ else -> NameState.Success
+ }
+
nowMemoLength.value = memo.value?.getGraphemeLength()
+ isMemoAvailable.value = when {
+ nowMemoLength.value == 0 -> NameState.Empty
+ (nowMemoLength.value ?: 0) > MAX_MEMO_LEN -> NameState.OVER
+ else -> NameState.Success
+ }
+
isFinishAvailable.value =
- todo.value?.isNotEmpty() == true && endDate.value?.isNotEmpty() == true && participantList.any { it.isSelected }
+ todo.value?.isNotEmpty() == true && endDate.value?.isNotEmpty() == true && participantList.any { it.isSelected } && isTodoAvailable.value == NameState.Success && isMemoAvailable.value != NameState.OVER
}
fun postToCreateTodoFromServer() {
diff --git a/presentation/src/main/java/com/going/presentation/util/ActivityExt.kt b/presentation/src/main/java/com/going/presentation/util/ActivityExt.kt
index a8ba1ec9..ebf7e59c 100644
--- a/presentation/src/main/java/com/going/presentation/util/ActivityExt.kt
+++ b/presentation/src/main/java/com/going/presentation/util/ActivityExt.kt
@@ -1,38 +1,42 @@
package com.going.presentation.util
-import android.Manifest
import android.app.Activity
-import android.content.pm.PackageManager
+import android.app.AlertDialog
+import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.media.MediaScannerConnection
import android.os.Build
import android.os.Environment
+import android.os.Environment.DIRECTORY_DOWNLOADS
+import android.provider.Settings
import androidx.activity.ComponentActivity
import androidx.activity.OnBackPressedCallback
-import androidx.core.app.ActivityCompat
-import androidx.core.content.ContextCompat
import com.going.presentation.R
-import com.going.presentation.tendency.result.TendencyResultActivity
import com.going.presentation.tendency.result.UserTendencyResultList
import com.going.ui.extension.toast
import java.io.File
import java.io.FileOutputStream
fun Activity.downloadImage(number: Int) {
- val downloadPath = "/Download/"
val downloadImageName = "img_tendency_result%s.png"
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission(
- this,
- Manifest.permission.WRITE_EXTERNAL_STORAGE,
- ) != PackageManager.PERMISSION_GRANTED
- ) {
- ActivityCompat.requestPermissions(
- this,
- arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
- TendencyResultActivity.PERMISSION_REQUEST_CODE,
- )
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager()) {
+ AlertDialog.Builder(this)
+ .setTitle(R.string.notice)
+ .setMessage(R.string.profile_image_permission_error)
+ .setCancelable(false)
+ .setPositiveButton(
+ R.string.okay,
+ ) { _, _ ->
+ val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
+ this.startActivity(intent)
+ }
+ .setNegativeButton(
+ R.string.setting_logout_negative,
+ ) { _, _ -> }
+ .create()
+ .show()
} else {
val imageBitmap: Bitmap = BitmapFactory.decodeResource(
resources,
@@ -41,26 +45,31 @@ fun Activity.downloadImage(number: Int) {
val imageFileName =
downloadImageName.replace("%s", number.toString())
- val uploadFolder = Environment.getExternalStoragePublicDirectory(downloadPath)
+ val uploadFolder =
+ Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS)
+
if (!uploadFolder.exists()) {
uploadFolder.mkdirs()
}
- val imageFile = File(uploadFolder, imageFileName)
+ val imageFile = File(uploadFolder.toString(), imageFileName)
- val outputStream = FileOutputStream(imageFile)
- imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
- outputStream.flush()
- outputStream.close()
+ try {
+ val outputStream = FileOutputStream(imageFile)
+ imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream)
+ outputStream.flush()
+ outputStream.close()
- MediaScannerConnection.scanFile(
- this,
- arrayOf(imageFile.absolutePath),
- arrayOf("image/jpeg"),
- null,
- )
-
- toast(getString(R.string.profile_image_download_success))
+ MediaScannerConnection.scanFile(
+ this,
+ arrayOf(imageFile.absolutePath),
+ arrayOf("image/jpeg"),
+ null,
+ )
+ toast(getString(R.string.profile_image_download_success))
+ } catch (e: Exception) {
+ toast(getString(R.string.profile_image_download_error))
+ }
}
}
diff --git a/presentation/src/main/res/drawable/ic_kakao.xml b/presentation/src/main/res/drawable/ic_kakao.xml
new file mode 100644
index 00000000..beecf8a0
--- /dev/null
+++ b/presentation/src/main/res/drawable/ic_kakao.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/presentation/src/main/res/drawable/shape_kakao_yellow_fill_8_rect.xml b/presentation/src/main/res/drawable/shape_kakao_yellow_fill_8_rect.xml
new file mode 100644
index 00000000..fe492bfa
--- /dev/null
+++ b/presentation/src/main/res/drawable/shape_kakao_yellow_fill_8_rect.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/presentation/src/main/res/layout/activity_create_trip.xml b/presentation/src/main/res/layout/activity_create_trip.xml
index 2d6b3cea..840395bf 100644
--- a/presentation/src/main/res/layout/activity_create_trip.xml
+++ b/presentation/src/main/res/layout/activity_create_trip.xml
@@ -87,9 +87,9 @@
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
- android:text="@string/name_blank_error"
- android:textColor="@{viewModel.isNameAvailable() == NameState.Blank ? @color/red_500 : @color/gray_700}"
- android:visibility="@{viewModel.isNameAvailable() == NameState.Blank ? View.VISIBLE : View.GONE}"
+ android:text="@{viewModel.isNameAvailable() == NameState.Blank ? @string/name_blank_error : @string/trip_over_error}"
+ android:textColor="@color/red_500"
+ android:visibility="@{(viewModel.isNameAvailable() == NameState.Blank) || (viewModel.isNameAvailable() == NameState.OVER) ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="@id/et_create_trip_name"
app:layout_constraintTop_toBottomOf="@id/et_create_trip_name" />
diff --git a/presentation/src/main/res/layout/activity_my_todo_create.xml b/presentation/src/main/res/layout/activity_my_todo_create.xml
index 0c1d2acd..0f1dc0e1 100644
--- a/presentation/src/main/res/layout/activity_my_todo_create.xml
+++ b/presentation/src/main/res/layout/activity_my_todo_create.xml
@@ -7,6 +7,8 @@
+
+
@@ -96,7 +98,7 @@
android:includeFontPadding="false"
android:inputType="text"
android:afterTextChanged="@{(text) -> vm.checkIsFinishAvailable()}"
- android:maxLines="1"
+ android:maxLines="5"
android:paddingHorizontal="12dp"
android:paddingVertical="19dp"
android:text="@={vm.todo}"
@@ -106,6 +108,18 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_my_todo_create_todo_title" />
+
+
+
+
-
\ No newline at end of file
+
diff --git a/presentation/src/main/res/layout/activity_onboarding_profile_setting.xml b/presentation/src/main/res/layout/activity_onboarding_profile_setting.xml
index f1d07fdf..3a86eb1a 100644
--- a/presentation/src/main/res/layout/activity_onboarding_profile_setting.xml
+++ b/presentation/src/main/res/layout/activity_onboarding_profile_setting.xml
@@ -68,9 +68,9 @@
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginTop="4dp"
- android:text="@string/name_blank_error"
- android:textColor="@{viewModel.isNameAvailable() == NameState.Blank ? @color/red_500 : @color/gray_700}"
- android:visibility="@{viewModel.isNameAvailable() == NameState.Blank ? View.VISIBLE : View.GONE}"
+ android:text="@{viewModel.isNameAvailable() == NameState.Blank ? @string/name_blank_error : @string/name_over_error}"
+ android:textColor="@color/red_500"
+ android:visibility="@{(viewModel.isNameAvailable() == NameState.Blank) || (viewModel.isNameAvailable() == NameState.OVER) ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="@id/et_onboarding_profile_setting_name"
app:layout_constraintTop_toBottomOf="@id/et_onboarding_profile_setting_name" />
@@ -115,6 +115,18 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_onboarding_profile_setting_on_line_info_title" />
+
+
+
+
@@ -106,6 +108,19 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_our_todo_create_todo_title" />
+
+
+
+
+
-
\ No newline at end of file
+
diff --git a/presentation/src/main/res/layout/activity_signin.xml b/presentation/src/main/res/layout/activity_signin.xml
index 5075e3d5..740c8c72 100644
--- a/presentation/src/main/res/layout/activity_signin.xml
+++ b/presentation/src/main/res/layout/activity_signin.xml
@@ -32,17 +32,42 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
-
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/btn_terms">
+
+
+
+
+
+
+
+ app:layout_constraintStart_toEndOf="@id/tv_sign_in_terms_icon" />
서버 통신에 실패했습니다
이름에는 공백만 입력할 수 없어요
+ 이름은 3자 이하여야 합니다
+ 자기소개는 20자 이하여야 합니다
+ 여행이름은 15자 이하여야 합니다
+ 할일은 15자 이하여야 합니다
+ 메모는 1000자 이하여야 합니다
해당 기능은 추후 업데이트 예정이에요 :)
+ 카카오 로그인
우리만의 여행을 하다
+
개인정보처리방침
버튼을 한번 더 누르면 종료됩니다
@@ -162,8 +169,9 @@
나는 두릅이 좋다.
다시 해볼래요
존재하지 않는 여행입니다.
- 이미지가 저장되었어요\n친구에게 내 캐릭터를 공유해 보세요
+ 이미지가 저장되었어요.\n친구들에게 공유해보세요!
저장할 수 없습니다\ndoorip에 사진에 대한 엑세스 권한이 없습니다
+ "사진 접근 권한이 없습니다.\n설정으로 이동하여 권한 설정을 해주세요"
여행 입장하기
@@ -172,6 +180,8 @@
잘못된 초대코드예요.
초대코드 확인하기
존재하지 않는 여행입니다
+ 존재하지 않는 여행입니다.
+ 입장할 수 있는 최대 인원은 6명입니다.
초대받은 여행이 맞는지\n 확인해 주세요