diff --git a/core/ui/src/main/java/co/kr/tnt/ui/model/RecordChip.kt b/core/ui/src/main/java/co/kr/tnt/ui/model/RecordChip.kt
index c231018d..f667a5b7 100644
--- a/core/ui/src/main/java/co/kr/tnt/ui/model/RecordChip.kt
+++ b/core/ui/src/main/java/co/kr/tnt/ui/model/RecordChip.kt
@@ -2,7 +2,16 @@ package co.kr.tnt.ui.model
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
-import co.kr.tnt.core.ui.R
+import co.kr.tnt.core.ui.R.string.core_exercise_back
+import co.kr.tnt.core.ui.R.string.core_exercise_cardio
+import co.kr.tnt.core.ui.R.string.core_exercise_lower_body
+import co.kr.tnt.core.ui.R.string.core_exercise_shoulder
+import co.kr.tnt.core.ui.R.string.core_exercise_upper_body
+import co.kr.tnt.core.ui.R.string.core_meal_breakfast
+import co.kr.tnt.core.ui.R.string.core_meal_dinner
+import co.kr.tnt.core.ui.R.string.core_meal_lunch
+import co.kr.tnt.core.ui.R.string.core_meal_snack
+import co.kr.tnt.core.ui.R.string.core_pt_session
import co.kr.tnt.designsystem.component.chip.model.ChipStyle
import co.kr.tnt.domain.model.RecordType
@@ -34,10 +43,10 @@ sealed interface RecordChip {
return when (type) {
is RecordType.MealType -> {
val title = when (type) {
- RecordType.MealType.BREAKFAST -> stringResource(R.string.meal_breakfast)
- RecordType.MealType.LUNCH -> stringResource(R.string.meal_lunch)
- RecordType.MealType.DINNER -> stringResource(R.string.meal_dinner)
- RecordType.MealType.SNACK -> stringResource(R.string.meal_snack)
+ RecordType.MealType.BREAKFAST -> stringResource(core_meal_breakfast)
+ RecordType.MealType.LUNCH -> stringResource(core_meal_lunch)
+ RecordType.MealType.DINNER -> stringResource(core_meal_dinner)
+ RecordType.MealType.SNACK -> stringResource(core_meal_snack)
}
val emoji = when (type) {
RecordType.MealType.BREAKFAST -> "π"
@@ -50,11 +59,11 @@ sealed interface RecordChip {
is RecordType.ExerciseType -> {
val title = when (type) {
- RecordType.ExerciseType.UPPER_BODY -> stringResource(R.string.exercise_upper_body)
- RecordType.ExerciseType.LOWER_BODY -> stringResource(R.string.exercise_lower_body)
- RecordType.ExerciseType.BACK -> stringResource(R.string.exercise_back)
- RecordType.ExerciseType.SHOULDER -> stringResource(R.string.exercise_shoulder)
- RecordType.ExerciseType.CARDIO -> stringResource(R.string.exercise_cardio)
+ RecordType.ExerciseType.UPPER_BODY -> stringResource(core_exercise_upper_body)
+ RecordType.ExerciseType.LOWER_BODY -> stringResource(core_exercise_lower_body)
+ RecordType.ExerciseType.BACK -> stringResource(core_exercise_back)
+ RecordType.ExerciseType.SHOULDER -> stringResource(core_exercise_shoulder)
+ RecordType.ExerciseType.CARDIO -> stringResource(core_exercise_cardio)
}
ExerciseChip(
title = title,
@@ -63,7 +72,7 @@ sealed interface RecordChip {
}
is RecordType.PTSessionType -> {
- val title = stringResource(R.string.pt_session, type.sessionCount)
+ val title = stringResource(core_pt_session, type.sessionCount)
val emoji = "πͺ"
PTSessionChip(title, type.sessionCount, emoji, ChipStyle.BLUE)
}
diff --git a/core/ui/src/main/java/co/kr/tnt/ui/permission/PermissionRequestDialog.kt b/core/ui/src/main/java/co/kr/tnt/ui/permission/PermissionRequestDialog.kt
index da050d3a..146e3863 100644
--- a/core/ui/src/main/java/co/kr/tnt/ui/permission/PermissionRequestDialog.kt
+++ b/core/ui/src/main/java/co/kr/tnt/ui/permission/PermissionRequestDialog.kt
@@ -4,7 +4,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
-import co.kr.tnt.core.ui.R
+import co.kr.tnt.core.ui.R.string.core_close
+import co.kr.tnt.core.ui.R.string.core_move_to_setting
+import co.kr.tnt.core.ui.R.string.core_ok
import co.kr.tnt.designsystem.component.TnTPopupDialog
import co.kr.tnt.designsystem.theme.TnTTheme
@@ -32,12 +34,12 @@ fun PermissionRequestDialog(
permission.description
},
),
- leftButtonText = stringResource(R.string.close),
+ leftButtonText = stringResource(core_close),
rightButtonText = stringResource(
if (isPermanentlyDenied) {
- R.string.move_to_setting
+ core_move_to_setting
} else {
- R.string.ok
+ core_ok
},
),
onLeftButtonClick = onDismiss,
diff --git a/core/ui/src/main/java/co/kr/tnt/ui/permission/TnTPermission.kt b/core/ui/src/main/java/co/kr/tnt/ui/permission/TnTPermission.kt
index 3c929e50..32ff0f27 100644
--- a/core/ui/src/main/java/co/kr/tnt/ui/permission/TnTPermission.kt
+++ b/core/ui/src/main/java/co/kr/tnt/ui/permission/TnTPermission.kt
@@ -3,7 +3,10 @@ package co.kr.tnt.ui.permission
import android.Manifest.permission.POST_NOTIFICATIONS
import android.os.Build
import androidx.annotation.StringRes
-import co.kr.tnt.core.ui.R
+import co.kr.tnt.core.ui.R.string.core_alarm_permission_description
+import co.kr.tnt.core.ui.R.string.core_alarm_permission_permanently_description
+import co.kr.tnt.core.ui.R.string.core_alarm_permission_permanently_title
+import co.kr.tnt.core.ui.R.string.core_alarm_permission_title
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.MultiplePermissionsState
@@ -20,10 +23,10 @@ enum class TnTPermission(
} else {
emptyList()
},
- title = R.string.alarm_permission_title,
- description = R.string.alarm_permission_description,
- permanentlyDeniedTitle = R.string.alarm_permission_permanently_title,
- permanentlyDeniedDescription = R.string.alarm_permission_permanently_description,
+ title = core_alarm_permission_title,
+ description = core_alarm_permission_description,
+ permanentlyDeniedTitle = core_alarm_permission_permanently_title,
+ permanentlyDeniedDescription = core_alarm_permission_permanently_description,
),
;
diff --git a/core/ui/src/main/java/co/kr/tnt/ui/resource/DisplayText.kt b/core/ui/src/main/java/co/kr/tnt/ui/resource/DisplayText.kt
new file mode 100644
index 00000000..0241b0d4
--- /dev/null
+++ b/core/ui/src/main/java/co/kr/tnt/ui/resource/DisplayText.kt
@@ -0,0 +1,36 @@
+package co.kr.tnt.ui.resource
+
+import android.content.Context
+import androidx.annotation.StringRes
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.res.stringResource
+
+sealed interface DisplayText {
+ fun asString(context: Context): String
+
+ @JvmInline
+ value class Plain(
+ val value: String,
+ ) : DisplayText {
+ override fun asString(context: Context): String = value
+ }
+
+ class Resource(
+ @StringRes val resId: Int,
+ vararg val args: Any,
+ ) : DisplayText {
+ override fun asString(context: Context): String = context.getString(resId, *args)
+ }
+
+ @Composable
+ fun asString(): String {
+ return when (this) {
+ is Plain -> value
+ is Resource -> stringResource(resId, *args)
+ }
+ }
+
+ companion object {
+ val EMPTY = Plain("")
+ }
+}
diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml
index cfea4e00..b2da9602 100644
--- a/core/ui/src/main/res/values/strings.xml
+++ b/core/ui/src/main/res/values/strings.xml
@@ -1,78 +1,84 @@
- μΈμ
μ΄ λ§λ£λμμ΄μ
- μ₯μκ° λ―Έμ¬μ©μΌλ‘ λ‘κ·ΈμΈ νλ©΄μΌλ‘ μ΄λν΄μ
+ μλ² μμ²μ μ€ν¨νμ΄μ
+
+ μΈμ
μ΄ λ§λ£λμμ΄μ
+ μ₯μκ° λ―Έμ¬μ©μΌλ‘ λ‘κ·ΈμΈ νλ©΄μΌλ‘ μ΄λν΄μ
- TnTμμ μλ¦Όμ 보λ΄κ³ μ ν©λλ€.
- ν΄λΉ κΈ°κΈ°λ‘ μμ
μΌμ λ± μλΉμ€ μ΄μ©μ λμμ΄ λλ μλ΄ μ¬νμ νΈμ μλ¦ΌμΌλ‘ 보λ΄λλ¦¬κ² μ΅λλ€.
+ TnTμμ μλ¦Όμ 보λ΄κ³ μ ν©λλ€.
+ ν΄λΉ κΈ°κΈ°λ‘ μμ
μΌμ λ± μλΉμ€ μ΄μ©μ λμμ΄ λλ μλ΄ μ¬νμ νΈμ μλ¦ΌμΌλ‘ 보λ΄λλ¦¬κ² μ΅λλ€.
\nμ± νΈμ μλ¦Όμ μμ λμ νμκ² μ΅λκΉ?
- TnTμμ μλ¦Ό κΆνμ΄ νμν©λλ€.
- μμ
μΌμ λ° μ€μν κ³΅μ§ μλ¦Όμ λ°κΈ° μν΄ μλ¦Ό κΆνμ΄ νμν©λλ€.\nμ€μ μμ μλ¦Ό κΆνμ νμ±νν΄μ£ΌμΈμ.
+ TnTμμ μλ¦Ό κΆνμ΄ νμν©λλ€.
+ μμ
μΌμ λ° μ€μν κ³΅μ§ μλ¦Όμ λ°κΈ° μν΄ μλ¦Ό κΆνμ΄ νμν©λλ€.\nμ€μ μμ μλ¦Ό κΆνμ νμ±νν΄μ£ΌμΈμ.
+
+ νλ‘ν μ¬μ§ μ€μ μ μν΄ μ¬μ§ μ κ·Ό κΆνμ΄ νμν΄μ
+ μ¬μ§ μΆκ°λ νλ‘ν λ§κ³ λ μ΄λκ³Ό μλ¨ κΈ°λ‘μλ μ¬μ©λΌμ
- νλ‘ν μ¬μ§ μ€μ μ μν΄ μ¬μ§ μ κ·Ό κΆνμ΄ νμν΄μ
- μ¬μ§ μΆκ°λ νλ‘ν λ§κ³ λ μ΄λκ³Ό μλ¨ κΈ°λ‘μλ μ¬μ©λΌμ
+ νλ‘ν μ¬μ§ μ€μ κΆν λͺ
μ κ±°λΆ
+ κΆν μ€μ μ μν΄ μ€μ μ°½μΌλ‘ μ΄λν΄μ£ΌμΈμ.
- νλ‘ν μ¬μ§ μ€μ κΆν λͺ
μ κ±°λΆ
- κΆν μ€μ μ μν΄ μ€μ μ°½μΌλ‘ μ΄λν΄μ£ΌμΈμ.
- λ«κΈ°
- νμΈ
- μ€μ μΌλ‘ μ΄λ
+ λ«κΈ°
+ νμΈ
+ μ€μ μΌλ‘ μ΄λ
- μλͺ»λ μμΉλ₯Ό μ
λ ₯νμ΄μ
- %sμ λ―Έλ§μ νκΈ λλ μλ¬ΈμΌλ‘ μ
λ ₯ν΄μ£ΌμΈμ
+ μλͺ»λ μμΉλ₯Ό μ
λ ₯νμ΄μ
+ %sμ λ―Έλ§μ νκΈ λλ μλ¬ΈμΌλ‘ μ
λ ₯ν΄μ£ΌμΈμ
- νΈλ μ΄λ
- νΈλ μ΄λ
+ νΈλ μ΄λ
+ νΈλ μ΄λ
- λ€μ
- μ°κ²°νκΈ°
- μμνκΈ°
- 건λλ°κΈ°
- μ·¨μ
- λ€μμ
+ λ€μ
+ μ°κ²°νκΈ°
+ μμνκΈ°
+ 건λλ°κΈ°
+ μ·¨μ
+ λ€μμ
- μ΄λ¦
- λμ΄
- ν€
- 체μ€
- μΈ
- cm
- kg
+ μ΄λ¦
+ λμ΄
+ ν€
+ 체μ€
+ μΈ
+ cm
+ kg
- μλ¦Ό
- μ΅κ·Ό λ°μ μλ¦Όμ΄ μμ΄μ
+ μλ¦Ό
+ μ΅κ·Ό λ°μ μλ¦Όμ΄ μμ΄μ
- 3μΌ λμ λ³΄μ§ μκΈ°
+ 3μΌ λμ λ³΄μ§ μκΈ°
- μμΉ¨
- μ μ¬
- μ λ
- κ°μ
+ μμΉ¨
+ μ μ¬
+ μ λ
+ κ°μ
- μ체 μ΄λ
- ν체 μ΄λ
- λ± μ΄λ
- μ΄κΉ¨ μ΄λ
- μ μ°μ
+ μ체 μ΄λ
+ ν체 μ΄λ
+ λ± μ΄λ
+ μ΄κΉ¨ μ΄λ
+ μ μ°μ
- %dνμ°¨ μμ
+ %dνμ°¨ μμ
- κ°μΈμ 보 μμ
- μ± νΈμ μλ¦Ό
- μλΉμ€ μ΄μ©μ½κ΄
- κ°μΈμ 보 μ²λ¦¬λ°©μΉ¨
- λ²μ μ 보
- μ€νμμ€ λΌμ΄μ μ€
- λ‘κ·Έμμ
- κ³μ νν΄
-
- νμ¬ κ³μ μ λ‘κ·Έμμ ν κΉμ?
- μΈμ λ μ§ λ€μ λ‘κ·ΈμΈ ν μ μμ΄μ!
- λ‘κ·Έμμμ΄ μλ£λμμ΄μ
+ κ°μΈμ 보 μμ
+ μ± νΈμ μλ¦Ό
+ μλΉμ€ μ΄μ©μ½κ΄
+ κ°μΈμ 보 μ²λ¦¬λ°©μΉ¨
+ λ²μ μ 보
+ μ€νμμ€ λΌμ΄μ μ€
+ λ‘κ·Έμμ
+ κ³μ νν΄
+
+ νμ¬ κ³μ μ λ‘κ·Έμμ ν κΉμ?
+ μΈμ λ μ§ λ€μ λ‘κ·ΈμΈ ν μ μμ΄μ!
+ λ‘κ·Έμμμ΄ μλ£λμμ΄μ
+
+ %dμ λ―Έλ§μΌλ‘ μ
λ ₯ν΄μ£ΌμΈμ.
+ μμ§ λ±λ‘λ κΈ°λ‘μ΄ μμ΄μ
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
index 2bad615e..39e6559a 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginContract.kt
@@ -8,6 +8,7 @@ import co.kr.tnt.login.model.TermState
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
internal class LoginContract {
data class LoginUiState(
@@ -34,7 +35,7 @@ internal class LoginContract {
sealed interface LoginSideEffect : UiSideEffect {
data object ShowTermBottomSheet : LoginSideEffect
- data class ShowToast(val message: String) : LoginSideEffect
+ data class ShowToast(val message: DisplayText) : LoginSideEffect
data class NavigateToWebView(val url: String) : LoginSideEffect
data class NavigateToHome(val userType: UserType) : LoginSideEffect
data class NavigateToSignup(
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
index f56cfacf..e4377a88 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginScreen.kt
@@ -42,6 +42,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import co.kr.tnt.core.ui.R.string.core_next
import co.kr.tnt.designsystem.component.TnTDivider
import co.kr.tnt.designsystem.component.TnTModalBottomSheet
import co.kr.tnt.designsystem.component.button.TnTBottomButton
@@ -126,7 +127,7 @@ internal fun LoginRoute(
showBottomSheet = true
}
- is LoginSideEffect.ShowToast -> snackbar.show(effect.message)
+ is LoginSideEffect.ShowToast -> snackbar.show(effect.message.asString(context))
is LoginSideEffect.NavigateToWebView -> {
navigateToWebView(effect.url)
@@ -289,7 +290,7 @@ private fun TermBottomSheetContent(
}
Spacer(modifier = Modifier.height(94.dp))
TnTBottomButton(
- text = stringResource(R.string.next),
+ text = stringResource(core_next),
enabled = isAllTermChecked,
onClick = onClickNext,
)
diff --git a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
index 2729bace..e2cc7ea9 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/LoginViewModel.kt
@@ -1,14 +1,17 @@
package co.kr.tnt.login
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.model.AuthType
import co.kr.tnt.domain.model.LoginResult
import co.kr.tnt.domain.repository.LoginRepository
+import co.kr.tnt.feature.login.R
import co.kr.tnt.login.LoginContract.LoginSideEffect
import co.kr.tnt.login.LoginContract.LoginUiEvent
import co.kr.tnt.login.LoginContract.LoginUiState
import co.kr.tnt.login.model.TermState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -28,7 +31,11 @@ internal class LoginViewModel @Inject constructor(
is LoginUiEvent.OnAuthFail -> {
if (event.throwable !is LoginException.CancelException) {
- sendEffect(LoginSideEffect.ShowToast("λ‘κ·ΈμΈμ μ€ν¨νμμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ."))
+ sendEffect(
+ LoginSideEffect.ShowToast(
+ DisplayText.Resource(R.string.failed_login_try_again),
+ ),
+ )
}
}
@@ -67,8 +74,11 @@ internal class LoginViewModel @Inject constructor(
clearAllChecks()
sendEffect(LoginSideEffect.ShowTermBottomSheet)
}.onFailure {
- // TODO resource
- sendEffect(LoginSideEffect.ShowToast("μ μ μλ μ€λ₯κ° λ°μνμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ."))
+ sendEffect(
+ LoginSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -106,7 +116,11 @@ internal class LoginViewModel @Inject constructor(
sendEffect(LoginSideEffect.NavigateToSignup(loginResult, messagingToken))
this@LoginViewModel.loginResult = null
} ?: run {
- sendEffect(LoginSideEffect.ShowToast("λ‘κ·ΈμΈμ μ€ν¨νμμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ."))
+ sendEffect(
+ LoginSideEffect.ShowToast(
+ DisplayText.Resource(R.string.failed_login_try_again),
+ ),
+ )
}
}
}
diff --git a/feature/login/src/main/java/co/kr/tnt/login/model/TermState.kt b/feature/login/src/main/java/co/kr/tnt/login/model/TermState.kt
index 839b9bfd..cf6240fa 100644
--- a/feature/login/src/main/java/co/kr/tnt/login/model/TermState.kt
+++ b/feature/login/src/main/java/co/kr/tnt/login/model/TermState.kt
@@ -1,9 +1,10 @@
package co.kr.tnt.login.model
import androidx.annotation.StringRes
+import co.kr.tnt.core.ui.R.string.core_privacy_policy
+import co.kr.tnt.core.ui.R.string.core_terms_of_service
import co.kr.tnt.domain.model.Term
import co.kr.tnt.domain.utils.AppUrls
-import co.kr.tnt.feature.login.R
sealed class TermState(
@StringRes val titleRes: Int,
@@ -14,14 +15,14 @@ sealed class TermState(
data class TermsOfServiceState(
override val isRequired: Boolean,
) : TermState(
- titleRes = R.string.terms_of_service,
+ titleRes = core_terms_of_service,
link = AppUrls.TERMS_OF_SERVICE_URL,
)
data class PrivacyPolicyState(
override val isRequired: Boolean,
) : TermState(
- titleRes = R.string.privacy_policy,
+ titleRes = core_privacy_policy,
link = AppUrls.PRIVACY_POLICY_URL,
)
diff --git a/feature/login/src/main/res/values/strings.xml b/feature/login/src/main/res/values/strings.xml
index fe340b11..e73a7731 100644
--- a/feature/login/src/main/res/values/strings.xml
+++ b/feature/login/src/main/res/values/strings.xml
@@ -4,8 +4,6 @@
νΈλ μ΄λμ νΈλ μ΄λ\nμΌλ―Έ ν°νΈλ¦¬κΈ°
μΉ΄μΉ΄μ€λ‘ κ³μνκΈ°
- μλΉμ€ μ΄μ©μ½κ΄
- κ°μΈμ 보 μ²λ¦¬λ°©μΉ¨
λμ
νμ
μ ν
@@ -13,6 +11,7 @@
μ¬λ¬λΆμ κ°μΈμ 보μ μλΉμ€ μ΄μ© κΆλ¦¬\nμ μ§μΌλ릴κ²μ
λͺ¨λ λμ
μλΉμ€ μ΄μ©μ μν΄ μλ μ½κ΄μ λͺ¨λ λμν©λλ€.
- λ€μ
보기
+
+ λ‘κ·ΈμΈμ μ€ν¨νμμ΅λλ€. λ€μ μλν΄μ£ΌμΈμ.
diff --git a/feature/main/src/main/java/co/kr/tnt/main/MainActivity.kt b/feature/main/src/main/java/co/kr/tnt/main/MainActivity.kt
index 143383da..7f2e481b 100644
--- a/feature/main/src/main/java/co/kr/tnt/main/MainActivity.kt
+++ b/feature/main/src/main/java/co/kr/tnt/main/MainActivity.kt
@@ -63,7 +63,11 @@ class MainActivity : ComponentActivity() {
viewModel.effect.collect { effect ->
when (effect) {
is MainContract.MainSideEffect.ShowToast -> {
- Toast.makeText(this@MainActivity, effect.message, Toast.LENGTH_SHORT).show()
+ Toast.makeText(
+ this@MainActivity,
+ effect.message.asString(this@MainActivity),
+ Toast.LENGTH_SHORT,
+ ).show()
}
}
}
diff --git a/feature/main/src/main/java/co/kr/tnt/main/MainContract.kt b/feature/main/src/main/java/co/kr/tnt/main/MainContract.kt
index 878d165e..6cd7bccc 100644
--- a/feature/main/src/main/java/co/kr/tnt/main/MainContract.kt
+++ b/feature/main/src/main/java/co/kr/tnt/main/MainContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.navigation.Route
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
internal class MainContract {
data class MainUiState(
@@ -19,6 +20,6 @@ internal class MainContract {
}
sealed interface MainSideEffect : UiSideEffect {
- data class ShowToast(val message: String) : MainSideEffect
+ data class ShowToast(val message: DisplayText) : MainSideEffect
}
}
diff --git a/feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt b/feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt
index 65aa528b..c409e7ab 100644
--- a/feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt
+++ b/feature/main/src/main/java/co/kr/tnt/main/MainViewModel.kt
@@ -4,11 +4,13 @@ import androidx.lifecycle.viewModelScope
import co.kr.tnt.domain.model.UserType
import co.kr.tnt.domain.repository.LoginRepository
import co.kr.tnt.domain.repository.SettingRepository
+import co.kr.tnt.feature.main.R
import co.kr.tnt.main.MainContract.MainSideEffect
import co.kr.tnt.main.MainContract.MainUiEvent
import co.kr.tnt.main.MainContract.MainUiState
import co.kr.tnt.navigation.Route
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -38,7 +40,11 @@ internal class MainViewModel @Inject constructor(
// TODO API λ³κ²½ μ μ κ±° μμ μ½λ
MainUiEvent.OnGetMessagingTokenFailed -> {
- sendEffect(MainSideEffect.ShowToast("λ€νΈμν¬ νκ²½μ νμΈνμ ν μ±μ μ¬μ€νν΄μ£ΌμΈμ."))
+ sendEffect(
+ MainSideEffect.ShowToast(
+ DisplayText.Resource(R.string.network_error_check_environment),
+ ),
+ )
}
}
}
diff --git a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTApp.kt b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTApp.kt
index ac71c19a..8504d620 100644
--- a/feature/main/src/main/java/co/kr/tnt/main/ui/TnTApp.kt
+++ b/feature/main/src/main/java/co/kr/tnt/main/ui/TnTApp.kt
@@ -5,13 +5,15 @@ import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import co.kr.tnt.core.designsystem.R
+import co.kr.tnt.core.ui.R.string.core_ok
+import co.kr.tnt.core.ui.R.string.core_session_expired
+import co.kr.tnt.core.ui.R.string.core_session_expired_description
import co.kr.tnt.designsystem.component.TnTIconSingleButtonPopupDialog
import co.kr.tnt.designsystem.component.button.model.ButtonType
import co.kr.tnt.designsystem.snackbar.LocalSnackbar
import co.kr.tnt.designsystem.snackbar.TnTSnackbarLayout
import co.kr.tnt.designsystem.snackbar.rememberSnackbarState
import co.kr.tnt.login.navigation.navigateToLogin
-import co.kr.tnt.core.ui.R as coreR
@Composable
fun TnTApp(
@@ -21,10 +23,10 @@ fun TnTApp(
if (appState.showSessionExpiredDialog) {
TnTIconSingleButtonPopupDialog(
- title = stringResource(coreR.string.session_expired),
- content = stringResource(coreR.string.session_expired_description),
+ title = stringResource(core_session_expired),
+ content = stringResource(core_session_expired_description),
topIcon = painterResource(R.drawable.ic_round_warning),
- buttonText = stringResource(coreR.string.ok),
+ buttonText = stringResource(core_ok),
cancelable = false,
onButtonClick = {
appState.dismissSessionDialog()
diff --git a/feature/main/src/main/res/values/strings.xml b/feature/main/src/main/res/values/strings.xml
new file mode 100644
index 00000000..997040e1
--- /dev/null
+++ b/feature/main/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ "λ€νΈμν¬ νκ²½μ νμΈνμ ν μ±μ μ¬μ€νν΄μ£ΌμΈμ."
+
diff --git a/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt
index 6bf42c65..ba6cbb48 100644
--- a/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt
+++ b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/RoleSelectionScreen.kt
@@ -26,6 +26,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
+import co.kr.tnt.core.ui.R.string.core_next
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.component.button.TnTTextButton
import co.kr.tnt.designsystem.component.button.model.ButtonSize
@@ -36,7 +37,6 @@ import co.kr.tnt.feature.roleselect.R
import co.kr.tnt.roleselect.RoleSelectionContract.RoleSelectionEffect
import co.kr.tnt.roleselect.RoleSelectionContract.RoleSelectionUiEvent
import co.kr.tnt.roleselect.model.RoleState
-import co.kr.tnt.core.ui.R as uiResource
@Composable
internal fun RoleSelectionRoute(
@@ -67,7 +67,7 @@ fun RoleSelectionScreen(
Scaffold(
bottomBar = {
TnTBottomButton(
- text = stringResource(uiResource.string.next),
+ text = stringResource(core_next),
enabled = true,
onClick = { onClickNext(selectedRole) },
modifier = Modifier.navigationBarsPadding(),
diff --git a/feature/roleselect/src/main/java/co/kr/tnt/roleselect/model/RoleState.kt b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/model/RoleState.kt
index 7ff90ab4..f15e77be 100644
--- a/feature/roleselect/src/main/java/co/kr/tnt/roleselect/model/RoleState.kt
+++ b/feature/roleselect/src/main/java/co/kr/tnt/roleselect/model/RoleState.kt
@@ -2,21 +2,22 @@ package co.kr.tnt.roleselect.model
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
+import co.kr.tnt.core.ui.R.string.core_trainee
+import co.kr.tnt.core.ui.R.string.core_trainer
import co.kr.tnt.domain.model.UserType
import co.kr.tnt.feature.roleselect.R
-import co.kr.tnt.core.ui.R as uiResource
sealed class RoleState(
@StringRes val textResId: Int,
@DrawableRes val imageResId: Int,
) {
data object Trainer : RoleState(
- textResId = uiResource.string.trainer,
+ textResId = core_trainer,
imageResId = R.drawable.img_select_role_trainer,
)
data object Trainee : RoleState(
- textResId = uiResource.string.trainee,
+ textResId = core_trainee,
imageResId = R.drawable.img_select_role_trainee,
)
diff --git a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/CodeEntryPage.kt b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/CodeEntryPage.kt
index 4d53d829..23342d38 100644
--- a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/CodeEntryPage.kt
+++ b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/CodeEntryPage.kt
@@ -18,6 +18,11 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_cancel
+import co.kr.tnt.core.ui.R.string.core_connect
+import co.kr.tnt.core.ui.R.string.core_next
+import co.kr.tnt.core.ui.R.string.core_ok
+import co.kr.tnt.core.ui.R.string.core_skip
import co.kr.tnt.designsystem.component.TnTIconPopupDialog
import co.kr.tnt.designsystem.component.TnTTopBar
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
@@ -31,7 +36,6 @@ import co.kr.tnt.trainee.connect.component.CodeTextField
import co.kr.tnt.trainee.connect.model.InputState
import co.kr.tnt.ui.extensions.clearFocusOnTap
import co.kr.tnt.core.designsystem.R as uiResource
-import co.kr.tnt.core.ui.R as coreR
@Composable
internal fun CodeEntryPage(
@@ -60,16 +64,16 @@ internal fun CodeEntryPage(
when (screenMode) {
ScreenMode.BACK -> {
TnTTopBarWithBackButton(
- title = stringResource(coreR.string.connect),
+ title = stringResource(core_connect),
onBackClick = onClickBack,
)
}
ScreenMode.SKIP -> {
TnTTopBar(
- title = stringResource(coreR.string.connect),
+ title = stringResource(core_connect),
trailingComponent = {
Text(
- text = stringResource(coreR.string.skip),
+ text = stringResource(core_skip),
color = TnTTheme.colors.neutralColors.Neutral400,
style = TnTTheme.typography.body2Medium,
modifier = Modifier.clickable { onClickSkip() },
@@ -79,7 +83,7 @@ internal fun CodeEntryPage(
}
ScreenMode.CLOSE -> {
TnTTopBar(
- title = stringResource(coreR.string.connect),
+ title = stringResource(core_connect),
trailingComponent = {
IconButton(
onClick = onClickBack,
@@ -123,7 +127,7 @@ internal fun CodeEntryPage(
)
}
TnTBottomButton(
- text = stringResource(coreR.string.next),
+ text = stringResource(core_next),
enabled = inputState.isValid,
onClick = onClickNext,
modifier = Modifier.align(Alignment.BottomCenter),
@@ -135,8 +139,8 @@ internal fun CodeEntryPage(
TnTIconPopupDialog(
title = stringResource(R.string.stop_connecting_trainer),
content = stringResource(R.string.warning_reconnect_needed),
- leftButtonText = stringResource(coreR.string.cancel),
- rightButtonText = stringResource(coreR.string.ok),
+ leftButtonText = stringResource(core_cancel),
+ rightButtonText = stringResource(core_ok),
onLeftButtonClick = onClickCancel,
onRightButtonClick = onDismissDialog,
onDismiss = onDismissDialog,
diff --git a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/PTSessionFormPage.kt b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/PTSessionFormPage.kt
index 2501041d..72bd1b57 100644
--- a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/PTSessionFormPage.kt
+++ b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/PTSessionFormPage.kt
@@ -26,6 +26,8 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_entered_wrong_text
+import co.kr.tnt.core.ui.R.string.core_next
import co.kr.tnt.designsystem.component.TnTLabeledTextField
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.button.TnTBottomButton
@@ -37,7 +39,6 @@ import co.kr.tnt.ui.utils.throttled
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
-import co.kr.tnt.core.ui.R as uiResource
private const val MAX_COUNT = 99
@@ -159,7 +160,7 @@ internal fun PTSessionFormPage(
)
Text(
text = if (showCompletedSessionWarning || showTotalSessionWarning) {
- stringResource(uiResource.string.entered_wrong_text)
+ stringResource(core_entered_wrong_text)
} else {
""
},
@@ -195,7 +196,7 @@ internal fun PTSessionFormPage(
)
Text(
text = if (showTotalSessionWarning || showCompletedSessionWarning) {
- stringResource(uiResource.string.entered_wrong_text)
+ stringResource(core_entered_wrong_text)
} else {
""
},
@@ -207,7 +208,7 @@ internal fun PTSessionFormPage(
}
}
TnTBottomButton(
- text = stringResource(uiResource.string.next),
+ text = stringResource(core_next),
modifier = Modifier.align(Alignment.BottomCenter),
enabled = isFormValid,
onClick = throttled { onClickNext() },
diff --git a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectCompletePage.kt b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectCompletePage.kt
index 96c82bc9..77b36441 100644
--- a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectCompletePage.kt
+++ b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectCompletePage.kt
@@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_next
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.theme.TnTTheme
@@ -107,7 +108,7 @@ internal fun TraineeConnectCompletePage(
}
}
TnTBottomButton(
- text = stringResource(uiResource.string.next),
+ text = stringResource(core_next),
onClick = onClickNext,
modifier = Modifier.align(Alignment.BottomCenter),
)
diff --git a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectContract.kt b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectContract.kt
index 1e25adbf..4b369fe4 100644
--- a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectContract.kt
+++ b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.trainee.connect.model.InputState
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
import java.time.LocalDate
internal class TraineeConnectContract {
@@ -37,7 +38,7 @@ internal class TraineeConnectContract {
sealed interface TraineeConnectSideEffect : UiSideEffect {
data object NavigateToBack : TraineeConnectSideEffect
data object NavigateToHome : TraineeConnectSideEffect
- data class ShowToast(val message: String) : TraineeConnectSideEffect
+ data class ShowToast(val message: DisplayText) : TraineeConnectSideEffect
}
enum class TraineeConnectPage {
diff --git a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectScreen.kt b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectScreen.kt
index e73b4a17..13d2f520 100644
--- a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectScreen.kt
+++ b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectScreen.kt
@@ -3,6 +3,7 @@ package co.kr.tnt.trainee.connect
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.kr.tnt.designsystem.snackbar.LocalSnackbar
@@ -20,6 +21,7 @@ internal fun TraineeConnectRoute(
navigateToHome: (Boolean) -> Unit,
viewModel: TraineeConnectViewModel = hiltViewModel(),
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val state by viewModel.uiState.collectAsStateWithLifecycle()
@@ -53,7 +55,7 @@ internal fun TraineeConnectRoute(
when (effect) {
TraineeConnectSideEffect.NavigateToBack -> navigateToPrevious()
TraineeConnectSideEffect.NavigateToHome -> navigateToHome(false)
- is TraineeConnectSideEffect.ShowToast -> snackbar.show(effect.message)
+ is TraineeConnectSideEffect.ShowToast -> snackbar.show(effect.message.asString(context))
}
}
}
diff --git a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectViewModel.kt b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectViewModel.kt
index d09bdf20..d09deac5 100644
--- a/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectViewModel.kt
+++ b/feature/trainee/connect/src/main/java/co/kr/tnt/trainee/connect/TraineeConnectViewModel.kt
@@ -1,6 +1,7 @@
package co.kr.tnt.trainee.connect
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.repository.ConnectRepository
import co.kr.tnt.trainee.connect.TraineeConnectContract.TraineeConnectPage
import co.kr.tnt.trainee.connect.TraineeConnectContract.TraineeConnectSideEffect
@@ -10,6 +11,7 @@ import co.kr.tnt.trainee.connect.model.InputState.FOCUS
import co.kr.tnt.trainee.connect.model.InputState.INVALID
import co.kr.tnt.trainee.connect.model.InputState.VALID
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import java.time.LocalDate
@@ -53,7 +55,11 @@ internal class TraineeConnectViewModel @Inject constructor(
updateState { copy(inviteCodeInputState = INVALID) }
}
}.onFailure {
- sendEffect(TraineeConnectSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TraineeConnectSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -96,7 +102,11 @@ internal class TraineeConnectViewModel @Inject constructor(
}
navigateToNext()
}.onFailure {
- sendEffect(TraineeConnectSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TraineeConnectSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}.also {
updateState { copy(isLoading = false) }
}
diff --git a/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeContract.kt b/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeContract.kt
index 2884d91f..03109280 100644
--- a/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeContract.kt
+++ b/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeContract.kt
@@ -6,6 +6,7 @@ import co.kr.tnt.domain.model.trainee.TraineePtSession
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
import java.time.LocalDate
import java.time.YearMonth
@@ -36,6 +37,6 @@ internal class TraineeHomeContract {
data object NavigateToConnect : TraineeHomeEffect
data object NavigateToExerciseRecord : TraineeHomeEffect
data object NavigateToMealRecord : TraineeHomeEffect
- data class ShowToast(val message: String) : TraineeHomeEffect
+ data class ShowToast(val message: DisplayText) : TraineeHomeEffect
}
}
diff --git a/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeScreen.kt b/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeScreen.kt
index e5989a6d..f677dc52 100644
--- a/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeScreen.kt
+++ b/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeScreen.kt
@@ -41,6 +41,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import co.kr.tnt.core.ui.R.string.core_connect
+import co.kr.tnt.core.ui.R.string.core_do_not_see_for_three_days
+import co.kr.tnt.core.ui.R.string.core_next_time
import co.kr.tnt.designsystem.component.TnTModalBottomSheet
import co.kr.tnt.designsystem.component.calendar.TnTIndicatorWeekCalendar
import co.kr.tnt.designsystem.component.calendar.model.DayIndicatorState
@@ -75,7 +78,6 @@ import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalDateTime
import java.time.YearMonth
-import co.kr.tnt.core.ui.R as coreR
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -132,9 +134,9 @@ internal fun TraineeHomeRoute(
title = stringResource(R.string.please_connect_trainer),
content = stringResource(R.string.connect_dialog_warning),
isChecked = uiState.isDialogHiddenForThreeDays,
- checkToggleText = stringResource(coreR.string.do_not_see_for_three_days),
- leftButtonText = stringResource(coreR.string.next_time),
- rightButtonText = stringResource(coreR.string.connect),
+ checkToggleText = stringResource(core_do_not_see_for_three_days),
+ leftButtonText = stringResource(core_next_time),
+ rightButtonText = stringResource(core_connect),
onLeftButtonClick = { viewModel.setEvent(TraineeHomeUiEvent.OnDismissDialog) },
onRightButtonClick = { viewModel.setEvent(TraineeHomeUiEvent.OnConfirmConnectDialog) },
onClickCheck = { viewModel.setEvent(TraineeHomeUiEvent.OnChangeHideDialogOption) },
@@ -156,7 +158,7 @@ internal fun TraineeHomeRoute(
}
TraineeHomeEffect.NavigateToConnect -> navigateToConnect()
- is TraineeHomeEffect.ShowToast -> snackbar.show(effect.message)
+ is TraineeHomeEffect.ShowToast -> snackbar.show(effect.message.asString(context))
}
}
}
diff --git a/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeViewModel.kt b/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeViewModel.kt
index ff1dd2e7..08a082ab 100644
--- a/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeViewModel.kt
+++ b/feature/trainee/home/src/main/java/co/kr/tnt/trainee/home/TraineeHomeViewModel.kt
@@ -1,6 +1,7 @@
package co.kr.tnt.trainee.home
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.model.trainee.TraineeDailyRecordStatus
import co.kr.tnt.domain.repository.ConnectRepository
import co.kr.tnt.domain.repository.TraineeRepository
@@ -8,6 +9,7 @@ import co.kr.tnt.trainee.home.TraineeHomeContract.TraineeHomeEffect
import co.kr.tnt.trainee.home.TraineeHomeContract.TraineeHomeUiEvent
import co.kr.tnt.trainee.home.TraineeHomeContract.TraineeHomeUiState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import com.kizitonwose.calendar.core.yearMonth
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.firstOrNull
@@ -64,7 +66,11 @@ internal class TraineeHomeViewModel @Inject constructor(
updateMonthlyRecordStatus(mergedData)
}
}.onFailure {
- sendEffect(TraineeHomeEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ."))
+ sendEffect(
+ TraineeHomeEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -106,7 +112,11 @@ internal class TraineeHomeViewModel @Inject constructor(
)
}
}.onFailure {
- sendEffect(TraineeHomeEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ."))
+ sendEffect(
+ TraineeHomeEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -166,7 +176,11 @@ internal class TraineeHomeViewModel @Inject constructor(
return@launch
}
}.onFailure {
- sendEffect(TraineeHomeEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ."))
+ sendEffect(
+ TraineeHomeEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
val lastHiddenDate = connectRepository.getExplicitDeniedConnectDate().firstOrNull()
diff --git a/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailContract.kt b/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailContract.kt
index c8c98e67..153debbf 100644
--- a/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailContract.kt
+++ b/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.domain.model.RecordType.MealType
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
import java.time.LocalDateTime
internal class TraineeMealDetailContract {
@@ -22,6 +23,6 @@ internal class TraineeMealDetailContract {
sealed interface TraineeMealDetailSideEffect : UiSideEffect {
data object NavigateToHome : TraineeMealDetailSideEffect
- data class ShowToast(val message: String) : TraineeMealDetailSideEffect
+ data class ShowToast(val message: DisplayText) : TraineeMealDetailSideEffect
}
}
diff --git a/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailScreen.kt b/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailScreen.kt
index c51a6976..c8c68bcf 100644
--- a/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailScreen.kt
+++ b/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailScreen.kt
@@ -1,7 +1,6 @@
package co.kr.tnt.trainee.mealdetail
import android.content.Context
-import android.widget.Toast
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -36,6 +35,7 @@ import co.kr.tnt.core.designsystem.R
import co.kr.tnt.designsystem.component.TnTDivider
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.chip.TnTChip
+import co.kr.tnt.designsystem.snackbar.LocalSnackbar
import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.domain.IMAGE_MAX_SIZE
import co.kr.tnt.domain.model.RecordType.MealType
@@ -56,6 +56,7 @@ internal fun TraineeMealDetailRoute(
) {
val state by viewModel.uiState.collectAsStateWithLifecycle()
val context = LocalContext.current
+ val snackbar = LocalSnackbar.current
val dateFormatter = remember { DateFormatter() }
TraineeMealDetailScreen(
@@ -73,10 +74,7 @@ internal fun TraineeMealDetailRoute(
LaunchedEffect(viewModel.effect) {
viewModel.effect.collect { effect ->
when (effect) {
- is TraineeMealDetailSideEffect.ShowToast -> {
- Toast.makeText(context, effect.message, Toast.LENGTH_SHORT).show()
- }
-
+ is TraineeMealDetailSideEffect.ShowToast -> snackbar.show(effect.message.asString(context))
TraineeMealDetailSideEffect.NavigateToHome -> navigateToPrevious()
}
}
diff --git a/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailViewModel.kt b/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailViewModel.kt
index 0ffa54f1..12736033 100644
--- a/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailViewModel.kt
+++ b/feature/trainee/mealdetail/src/main/java/co/kr/tnt/trainee/mealdetail/TraineeMealDetailViewModel.kt
@@ -1,12 +1,14 @@
package co.kr.tnt.trainee.mealdetail
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.model.RecordType.MealType
import co.kr.tnt.domain.repository.TraineeRepository
import co.kr.tnt.trainee.mealdetail.TraineeMealDetailContract.TraineeMealDetailSideEffect
import co.kr.tnt.trainee.mealdetail.TraineeMealDetailContract.TraineeMealDetailUiEvent
import co.kr.tnt.trainee.mealdetail.TraineeMealDetailContract.TraineeMealDetailUiState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -39,7 +41,11 @@ internal class TraineeMealDetailViewModel @Inject constructor(
)
}
}.onFailure {
- sendEffect(TraineeMealDetailSideEffect.ShowToast("λ°μ΄ν° λΆλ¬μ€κΈ°μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TraineeMealDetailSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
diff --git a/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordContract.kt b/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordContract.kt
index 7e2f70f5..68bcc477 100644
--- a/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordContract.kt
+++ b/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordContract.kt
@@ -4,6 +4,7 @@ import android.net.Uri
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
import java.io.File
import java.time.LocalDate
import java.time.LocalDateTime
@@ -60,6 +61,6 @@ internal class TraineeMealRecordContract {
sealed interface TraineeMealRecordSideEffect : UiSideEffect {
data object NavigateToHome : TraineeMealRecordSideEffect
- data class ShowToast(val message: String) : TraineeMealRecordSideEffect
+ data class ShowToast(val message: DisplayText) : TraineeMealRecordSideEffect
}
}
diff --git a/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordScreen.kt b/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordScreen.kt
index e59060e4..f84a08bd 100644
--- a/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordScreen.kt
+++ b/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordScreen.kt
@@ -49,7 +49,12 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import co.kr.tnt.core.designsystem.R
+import co.kr.tnt.core.designsystem.R.drawable.ic_close
+import co.kr.tnt.core.designsystem.R.drawable.ic_image
+import co.kr.tnt.core.designsystem.R.drawable.ic_overlay_close
+import co.kr.tnt.core.ui.R.string.core_cancel
+import co.kr.tnt.core.ui.R.string.core_length_warning
+import co.kr.tnt.core.ui.R.string.core_ok
import co.kr.tnt.designsystem.component.TnTBottomSheetDialog
import co.kr.tnt.designsystem.component.TnTDivider
import co.kr.tnt.designsystem.component.TnTIconPopupDialog
@@ -70,6 +75,7 @@ import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.domain.IMAGE_MAX_SIZE
import co.kr.tnt.domain.model.RecordType.MealType
import co.kr.tnt.domain.utils.DateFormatter
+import co.kr.tnt.feature.trainee.mealrecord.R
import co.kr.tnt.trainee.mealrecord.TraineeMealRecordContract.TraineeMealRecordUiEvent
import co.kr.tnt.trainee.mealrecord.TraineeMealRecordContract.TraineeMealRecordUiState
import co.kr.tnt.trainee.mealrecord.TraineeMealRecordContract.TraineeMealRecordUiState.DialogState
@@ -89,7 +95,6 @@ import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalTime
import java.time.YearMonth
-import co.kr.tnt.core.ui.R as coreR
@Composable
internal fun TraineeMealRecordRoute(
@@ -199,7 +204,7 @@ internal fun TraineeMealRecordRoute(
when (effect) {
TraineeMealRecordContract.TraineeMealRecordSideEffect.NavigateToHome -> navigateToPrevious()
is TraineeMealRecordContract.TraineeMealRecordSideEffect.ShowToast -> snackbar.show(
- effect.message,
+ effect.message.asString(context),
)
}
}
@@ -231,7 +236,7 @@ private fun TraineeMealRecordScreen(
containerColor = TnTTheme.colors.commonColors.Common0,
topBar = {
TnTTopBarWithBackButton(
- title = "μλ¨ κΈ°λ‘",
+ title = stringResource(R.string.meal_record),
onBackClick = onClickBack,
showStoke = true,
)
@@ -321,9 +326,9 @@ private fun Dialog(
DialogState.NONE -> Unit
DialogState.COMPLETED -> {
TnTSingleButtonPopupDialog(
- title = "μλ¨μ κΈ°λ‘νμ΄μ!",
- content = "λ΄μΌλ κΈ°λ‘ν΄ μ£Όμ€ κ±°μ£ ?",
- buttonText = stringResource(coreR.string.ok),
+ title = stringResource(R.string.recorded_meal),
+ content = stringResource(R.string.will_you_record_tomorrow_too),
+ buttonText = stringResource(core_ok),
cancelable = false,
onButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -332,12 +337,12 @@ private fun Dialog(
DialogState.EXIT -> {
TnTIconPopupDialog(
- title = "μλ¨ κΈ°λ‘μ μ’
λ£ν κΉμ?",
- content = "κΈ°λ‘μ΄ μ μ₯λμ§ μμμ!",
- leftButtonText = "μ·¨μ",
- rightButtonText = "νμΈ",
- onLeftButtonClick = onDismissDialog,
- onRightButtonClick = onClickExit,
+ title = stringResource(R.string.exit_meal_recording),
+ content = stringResource(R.string.record_will_not_be_saved),
+ leftButtonText = stringResource(core_cancel),
+ rightButtonText = stringResource(core_ok),
+ onLeftButtonClick = onClickExit,
+ onRightButtonClick = onDismissDialog,
onDismiss = onDismissDialog,
)
}
@@ -374,11 +379,11 @@ private fun MealImageSelector(
) {
if (imageUri == null) {
Image(
- painter = painterResource(R.drawable.ic_image),
+ painter = painterResource(ic_image),
contentDescription = null,
)
Text(
- text = "μ€λ λ¨Ήμ μλ¨μ μΆκ°ν΄λ³΄μΈμ",
+ text = stringResource(R.string.add_todays_meal),
color = TnTTheme.colors.neutralColors.Neutral400,
style = TnTTheme.typography.body2Medium,
)
@@ -395,7 +400,7 @@ private fun MealImageSelector(
modifier = Modifier.align(Alignment.TopEnd),
) {
Icon(
- painter = painterResource(R.drawable.ic_overlay_close),
+ painter = painterResource(ic_overlay_close),
contentDescription = null,
tint = Color.Unspecified,
)
@@ -414,7 +419,7 @@ private fun MealDate(
onClick: () -> Unit,
) {
TnTSelectableTextField(
- title = "μμ¬ λ μ§",
+ title = stringResource(R.string.meal_date),
value = dateFormatter.format(date, "yyyy/MM/dd"),
onValueChange = { },
isRequired = true,
@@ -432,7 +437,7 @@ private fun MealTime(
) {
val now = LocalTime.now()
TnTSelectableTextField(
- title = "μμ¬ μκ°",
+ title = stringResource(R.string.meal_time),
value = time?.let { dateFormatter.format(it, "HH:mm") } ?: "",
onValueChange = { },
isRequired = true,
@@ -459,7 +464,7 @@ private fun MealTypes(
modifier = Modifier.fillMaxWidth(),
) {
Text(
- text = "λΆλ₯",
+ text = stringResource(R.string.category),
style = TnTTheme.typography.body1Bold,
color = TnTTheme.colors.neutralColors.Neutral900,
)
@@ -500,7 +505,7 @@ private fun MealMemo(
modifier = Modifier.fillMaxWidth(),
) {
Text(
- text = "λ©λͺ¨νκΈ°",
+ text = stringResource(R.string.wirte_memo),
style = TnTTheme.typography.body1Bold,
color = TnTTheme.colors.neutralColors.Neutral900,
)
@@ -516,10 +521,10 @@ private fun MealMemo(
onValueChange = { newValue ->
onValueChange(newValue)
},
- placeholder = "μλ¨μ λν μ 보λ₯Ό μ
λ ₯ν΄μ£ΌμΈμ!",
+ placeholder = stringResource(R.string.enter_meal_info),
maxLength = 100,
isError = state.showWarning,
- warningMessage = "100μ λ―Έλ§μΌλ‘ μ
λ ₯ν΄μ£ΌμΈμ",
+ warningMessage = stringResource(core_length_warning, 100),
)
}
}
@@ -542,13 +547,13 @@ private fun CalendarBottomSheetContent(
verticalAlignment = Alignment.CenterVertically,
) {
Text(
- text = "μλ¨ λ μ§ μ ννκΈ°",
+ text = stringResource(R.string.select_meal_date),
color = TnTTheme.colors.neutralColors.Neutral900,
style = TnTTheme.typography.h3,
modifier = Modifier.weight(1f),
)
Icon(
- painter = painterResource(R.drawable.ic_close),
+ painter = painterResource(ic_close),
contentDescription = null,
modifier = Modifier.clickable(onClick = onClickClose),
)
@@ -559,7 +564,7 @@ private fun CalendarBottomSheetContent(
onClickDay = { newDate -> selectedDate = newDate },
)
TnTTextButton(
- text = stringResource(coreR.string.ok),
+ text = stringResource(core_ok),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp),
@@ -633,13 +638,13 @@ private fun TimePickerBottomSheetContent(
modifier = Modifier.padding(20.dp),
) {
Text(
- text = "μλ¨ μκ° μ ννκΈ°",
+ text = stringResource(R.string.select_meal_time),
color = TnTTheme.colors.neutralColors.Neutral900,
style = TnTTheme.typography.h3,
modifier = Modifier.weight(1f),
)
Icon(
- painter = painterResource(R.drawable.ic_close),
+ painter = painterResource(ic_close),
contentDescription = null,
modifier = Modifier.clickable(onClick = onClickClose),
)
@@ -656,7 +661,7 @@ private fun TimePickerBottomSheetContent(
)
Spacer(Modifier.height(40.dp))
TnTTextButton(
- text = stringResource(coreR.string.ok),
+ text = stringResource(core_ok),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp),
diff --git a/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordViewModel.kt b/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordViewModel.kt
index cc228deb..b99c9acc 100644
--- a/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordViewModel.kt
+++ b/feature/trainee/mealrecord/src/main/java/co/kr/tnt/trainee/mealrecord/TraineeMealRecordViewModel.kt
@@ -3,11 +3,13 @@ package co.kr.tnt.trainee.mealrecord
import androidx.lifecycle.viewModelScope
import co.kr.tnt.domain.repository.TraineeRepository
import co.kr.tnt.domain.utils.DateFormatter
+import co.kr.tnt.feature.trainee.mealrecord.R
import co.kr.tnt.trainee.mealrecord.TraineeMealRecordContract.TraineeMealRecordSideEffect
import co.kr.tnt.trainee.mealrecord.TraineeMealRecordContract.TraineeMealRecordUiEvent
import co.kr.tnt.trainee.mealrecord.TraineeMealRecordContract.TraineeMealRecordUiState
import co.kr.tnt.trainee.mealrecord.TraineeMealRecordContract.TraineeMealRecordUiState.DialogState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import java.io.File
@@ -106,7 +108,11 @@ internal class TraineeMealRecordViewModel @Inject constructor(
}.onSuccess {
updateState { copy(dialogState = DialogState.COMPLETED) }
}.onFailure {
- sendEffect(TraineeMealRecordSideEffect.ShowToast("μλ¨ κΈ°λ‘μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TraineeMealRecordSideEffect.ShowToast(
+ DisplayText.Resource(R.string.failed_meal_record),
+ ),
+ )
}.also {
updateState { copy(isLoading = false) }
}
diff --git a/feature/trainee/mealrecord/src/main/res/values/strings.xml b/feature/trainee/mealrecord/src/main/res/values/strings.xml
new file mode 100644
index 00000000..7af49819
--- /dev/null
+++ b/feature/trainee/mealrecord/src/main/res/values/strings.xml
@@ -0,0 +1,17 @@
+
+
+ μλ¨ κΈ°λ‘μ μ€ν¨νμ΄μ
+ μλ¨ κΈ°λ‘
+ μλ¨μ κΈ°λ‘νμ΄μ!
+ λ΄μΌλ κΈ°λ‘ν΄ μ£Όμ€ κ±°μ£ ?
+ μλ¨ κΈ°λ‘μ μ’
λ£ν κΉμ?
+ κΈ°λ‘μ΄ μ μ₯λμ§ μμμ!
+ μ€λ λ¨Ήμ μλ¨μ μΆκ°ν΄λ³΄μΈμ
+ μμ¬ λ μ§
+ μμ¬ μκ°
+ λΆλ₯
+ λ©λͺ¨νκΈ°
+ μλ¨μ λν μ 보λ₯Ό μ
λ ₯ν΄μ£ΌμΈμ!
+ μλ¨ λ μ§ μ ννκΈ°
+ μλ¨ μκ° μ ννκΈ°
+
diff --git a/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageContract.kt b/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageContract.kt
index 862828af..20364dfc 100644
--- a/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageContract.kt
+++ b/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.domain.model.User
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
internal class TraineeMyPageContract {
data class TraineeMyPageUiState(
@@ -40,7 +41,7 @@ internal class TraineeMyPageContract {
}
sealed interface TraineeMyPageEffect : UiSideEffect {
- data class ShowToast(val message: String) : TraineeMyPageEffect
+ data class ShowToast(val message: DisplayText) : TraineeMyPageEffect
data object NavigateToConnect : TraineeMyPageEffect
data object NavigateToLogin : TraineeMyPageEffect
data class NavigateToWebView(val url: String) : TraineeMyPageEffect
diff --git a/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageScreen.kt b/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageScreen.kt
index 4b1cdc40..989e70b3 100644
--- a/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageScreen.kt
+++ b/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageScreen.kt
@@ -27,6 +27,18 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import co.kr.tnt.core.ui.R.string.core_app_push_notification
+import co.kr.tnt.core.ui.R.string.core_app_version
+import co.kr.tnt.core.ui.R.string.core_cancel
+import co.kr.tnt.core.ui.R.string.core_delete_account
+import co.kr.tnt.core.ui.R.string.core_logout
+import co.kr.tnt.core.ui.R.string.core_logout_complete_title
+import co.kr.tnt.core.ui.R.string.core_logout_content
+import co.kr.tnt.core.ui.R.string.core_logout_title
+import co.kr.tnt.core.ui.R.string.core_ok
+import co.kr.tnt.core.ui.R.string.core_open_source_license
+import co.kr.tnt.core.ui.R.string.core_privacy_policy
+import co.kr.tnt.core.ui.R.string.core_terms_of_service
import co.kr.tnt.designsystem.component.TnTIconPopupDialog
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.TnTSingleButtonPopupDialog
@@ -54,7 +66,6 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import java.time.LocalDate
-import co.kr.tnt.core.ui.R as coreR
@OptIn(ExperimentalPermissionsApi::class)
@Composable
@@ -106,7 +117,7 @@ internal fun TraineeMyPageRoute(
when (effect) {
TraineeMyPageEffect.NavigateToConnect -> navigateToConnect(ScreenMode.BACK)
TraineeMyPageEffect.NavigateToLogin -> navigateToLogin()
- is TraineeMyPageEffect.ShowToast -> snackbar.show(effect.message)
+ is TraineeMyPageEffect.ShowToast -> snackbar.show(effect.message.asString(context))
is TraineeMyPageEffect.NavigateToWebView -> navigateToWebView(effect.url)
is TraineeMyPageEffect.RequestPermission -> {
if (effect.isExplicitlyDenied) {
@@ -182,7 +193,7 @@ private fun TraineeMyPageScreen(
)
}
TnTMyPageButton(
- text = stringResource(coreR.string.app_push_notification),
+ text = stringResource(core_app_push_notification),
verticalPadding = 12.dp,
enabled = false,
trailingComponent = {
@@ -199,17 +210,17 @@ private fun TraineeMyPageScreen(
.padding(vertical = 12.dp),
) {
TnTMyPageButton(
- text = stringResource(coreR.string.terms_of_service),
+ text = stringResource(core_terms_of_service),
onClick = onClickTermsOfService,
verticalPadding = 8.dp,
)
TnTMyPageButton(
- text = stringResource(coreR.string.privacy_policy),
+ text = stringResource(core_privacy_policy),
onClick = onClickPrivacy,
verticalPadding = 8.dp,
)
TnTMyPageButton(
- text = stringResource(coreR.string.app_version),
+ text = stringResource(core_app_version),
verticalPadding = 12.dp,
enabled = false,
trailingComponent = {
@@ -221,7 +232,7 @@ private fun TraineeMyPageScreen(
},
)
TnTMyPageButton(
- text = stringResource(coreR.string.open_source_license),
+ text = stringResource(core_open_source_license),
onClick = onClickOpenSource,
verticalPadding = 8.dp,
)
@@ -234,12 +245,12 @@ private fun TraineeMyPageScreen(
.padding(vertical = 12.dp),
) {
TnTMyPageButton(
- text = stringResource(coreR.string.logout),
+ text = stringResource(core_logout),
onClick = onClickLogout,
verticalPadding = 8.dp,
)
TnTMyPageButton(
- text = stringResource(coreR.string.delete_account),
+ text = stringResource(core_delete_account),
onClick = onClickDeleteAccount,
verticalPadding = 8.dp,
)
@@ -258,10 +269,10 @@ private fun Dialog(
DialogState.NONE -> Unit
DialogState.LOGOUT_CONFIRM -> {
TnTIconPopupDialog(
- title = stringResource(coreR.string.logout_title),
- content = stringResource(coreR.string.logout_content),
- leftButtonText = stringResource(coreR.string.cancel),
- rightButtonText = stringResource(coreR.string.ok),
+ title = stringResource(core_logout_title),
+ content = stringResource(core_logout_content),
+ leftButtonText = stringResource(core_cancel),
+ rightButtonText = stringResource(core_ok),
onLeftButtonClick = onDismissDialog,
onRightButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -270,9 +281,9 @@ private fun Dialog(
DialogState.LOGOUT -> {
TnTSingleButtonPopupDialog(
- title = stringResource(coreR.string.logout_complete_title),
- content = stringResource(coreR.string.logout_content),
- buttonText = stringResource(coreR.string.ok),
+ title = stringResource(core_logout_complete_title),
+ content = stringResource(core_logout_content),
+ buttonText = stringResource(core_ok),
cancelable = false,
onButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -283,8 +294,8 @@ private fun Dialog(
TnTIconPopupDialog(
title = stringResource(R.string.delete_account_title),
content = stringResource(R.string.delete_account_content),
- leftButtonText = stringResource(coreR.string.cancel),
- rightButtonText = stringResource(coreR.string.ok),
+ leftButtonText = stringResource(core_cancel),
+ rightButtonText = stringResource(core_ok),
onLeftButtonClick = onDismissDialog,
onRightButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -295,7 +306,7 @@ private fun Dialog(
TnTSingleButtonPopupDialog(
title = stringResource(R.string.delete_account_complete_title),
content = stringResource(R.string.delete_account_complete_content),
- buttonText = stringResource(coreR.string.ok),
+ buttonText = stringResource(core_ok),
cancelable = false,
onButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
diff --git a/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageViewModel.kt b/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageViewModel.kt
index efadcd8f..67a4f272 100644
--- a/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageViewModel.kt
+++ b/feature/trainee/mypage/src/main/java/co/kr/tnt/trainee/mypage/TraineeMyPageViewModel.kt
@@ -1,16 +1,19 @@
package co.kr.tnt.trainee.mypage
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.repository.LoginRepository
import co.kr.tnt.domain.repository.SettingRepository
import co.kr.tnt.domain.repository.TraineeRepository
import co.kr.tnt.domain.utils.AppUrls
+import co.kr.tnt.feature.trainee.mypage.R
import co.kr.tnt.login.kakao.KakaoLoginSdk
import co.kr.tnt.trainee.mypage.TraineeMyPageContract.TraineeMyPageEffect
import co.kr.tnt.trainee.mypage.TraineeMyPageContract.TraineeMyPageUiEvent
import co.kr.tnt.trainee.mypage.TraineeMyPageContract.TraineeMyPageUiState
import co.kr.tnt.trainee.mypage.TraineeMyPageContract.TraineeMyPageUiState.DialogState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -39,6 +42,7 @@ internal class TraineeMyPageViewModel @Inject constructor(
isGrantedPermission = event.isGrantedPermission,
shouldShowRationale = event.shouldShowRationale,
)
+
TraineeMyPageUiEvent.OnClickTermsOfService -> sendEffect(
TraineeMyPageEffect.NavigateToWebView(AppUrls.TERMS_OF_SERVICE_URL),
)
@@ -70,7 +74,11 @@ internal class TraineeMyPageViewModel @Inject constructor(
}.onSuccess { user ->
updateState { copy(user = user) }
}.onFailure {
- sendEffect(TraineeMyPageEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ."))
+ sendEffect(
+ TraineeMyPageEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
settingRepository.isEnablePushNotification()
@@ -142,7 +150,7 @@ internal class TraineeMyPageViewModel @Inject constructor(
}.onSuccess {
updateState { copy(dialogState = DialogState.LOGOUT) }
}.onFailure {
- sendEffect(TraineeMyPageEffect.ShowToast("λ‘κ·Έμμμ μ€ν¨νμμ΅λλ€."))
+ sendEffect(TraineeMyPageEffect.ShowToast(DisplayText.Resource(R.string.failed_login)))
}.also {
updateState { copy(isLoading = false) }
}
@@ -158,7 +166,11 @@ internal class TraineeMyPageViewModel @Inject constructor(
}.onSuccess {
updateState { copy(dialogState = DialogState.DELETE_ACCOUNT) }
}.onFailure {
- sendEffect(TraineeMyPageEffect.ShowToast("νν΄μ μ€ν¨νμμ΅λλ€."))
+ sendEffect(
+ TraineeMyPageEffect.ShowToast(
+ DisplayText.Resource(R.string.failed_delete_account),
+ ),
+ )
}.also {
updateState { copy(isLoading = false) }
}
diff --git a/feature/trainee/mypage/src/main/res/values/strings.xml b/feature/trainee/mypage/src/main/res/values/strings.xml
index 4083b04b..a5221b2e 100644
--- a/feature/trainee/mypage/src/main/res/values/strings.xml
+++ b/feature/trainee/mypage/src/main/res/values/strings.xml
@@ -12,4 +12,7 @@
μ΄λ λ° μλ¨ κΈ°λ‘μ λν λ°μ΄ν°κ° μ¬λΌμ Έμ!
κ³μ νν΄κ° μλ£λμμ΄μ
λ€μμ λ νλ°μ μΈ μΌλ―Έλ‘ λ€μ λ§λμ! π£
+
+ λ‘κ·Έμμμ μ€ν¨νμμ΅λλ€.
+ νν΄μ μ€ν¨νμμ΅λλ€.
diff --git a/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationContract.kt b/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationContract.kt
index cb59f419..2e05df1e 100644
--- a/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationContract.kt
+++ b/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
import co.kr.tnt.ui.model.NotificationState
+import co.kr.tnt.ui.resource.DisplayText
internal class TraineeNotificationContract {
data class TraineeNotificationUiState(
@@ -15,7 +16,7 @@ internal class TraineeNotificationContract {
}
sealed interface TraineeNotificationEffect : UiSideEffect {
- data class ShowToast(val message: String) : TraineeNotificationEffect
+ data class ShowToast(val message: DisplayText) : TraineeNotificationEffect
data object NavigateToPrevious : TraineeNotificationEffect
}
}
diff --git a/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationScreen.kt b/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationScreen.kt
index a0e0b883..32ee6827 100644
--- a/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationScreen.kt
+++ b/feature/trainee/notification/src/main/java/co/kr/tnt/trainee/notification/TraineeNotificationScreen.kt
@@ -13,10 +13,13 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+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
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import co.kr.tnt.core.ui.R.string.core_no_recent_notifications
+import co.kr.tnt.core.ui.R.string.core_notification
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.notification.TnTNotification
import co.kr.tnt.designsystem.component.notification.model.NotificationIcon
@@ -25,13 +28,13 @@ import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.trainee.notification.TraineeNotificationContract.TraineeNotificationUiEvent
import co.kr.tnt.trainee.notification.TraineeNotificationContract.TraineeNotificationUiState
import co.kr.tnt.ui.model.NotificationState
-import co.kr.tnt.core.ui.R as uiResource
@Composable
internal fun TraineeNotificationRoute(
navigateToPrevious: () -> Unit,
viewModel: TraineeNotificationViewModel = hiltViewModel(),
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
@@ -44,7 +47,9 @@ internal fun TraineeNotificationRoute(
viewModel.effect.collect { effect ->
when (effect) {
TraineeNotificationContract.TraineeNotificationEffect.NavigateToPrevious -> navigateToPrevious()
- is TraineeNotificationContract.TraineeNotificationEffect.ShowToast -> snackbar.show(effect.message)
+ is TraineeNotificationContract.TraineeNotificationEffect.ShowToast -> snackbar.show(
+ effect.message.asString(context),
+ )
}
}
}
@@ -58,7 +63,7 @@ private fun TraineeNotificationScreen(
Scaffold(
topBar = {
TnTTopBarWithBackButton(
- title = stringResource(uiResource.string.notification),
+ title = stringResource(core_notification),
onBackClick = onClickBack,
showStoke = true,
)
@@ -72,7 +77,7 @@ private fun TraineeNotificationScreen(
contentAlignment = Alignment.Center,
) {
Text(
- text = stringResource(uiResource.string.no_recent_notifications),
+ text = stringResource(core_no_recent_notifications),
style = TnTTheme.typography.label1Medium,
color = TnTTheme.colors.neutralColors.Neutral400,
)
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeBasicInfoPage.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeBasicInfoPage.kt
index 66ac6573..fef4399e 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeBasicInfoPage.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeBasicInfoPage.kt
@@ -28,6 +28,12 @@ import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_entered_wrong_text
+import co.kr.tnt.core.ui.R.string.core_height_label
+import co.kr.tnt.core.ui.R.string.core_height_unit
+import co.kr.tnt.core.ui.R.string.core_next
+import co.kr.tnt.core.ui.R.string.core_weight_label
+import co.kr.tnt.core.ui.R.string.core_weight_unit
import co.kr.tnt.designsystem.component.TnTLabeledTextField
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.button.TnTBottomButton
@@ -39,7 +45,6 @@ import co.kr.tnt.ui.extensions.clearFocusOnTap
import java.time.LocalDate
import java.time.ZoneId
import java.time.format.DateTimeFormatter
-import co.kr.tnt.core.ui.R as uiResource
@Composable
internal fun TraineeBasicInfoPage(
@@ -101,29 +106,29 @@ internal fun TraineeBasicInfoPage(
.padding(horizontal = 20.dp),
) {
TnTLabeledTextField(
- title = stringResource(uiResource.string.height_label),
+ title = stringResource(core_height_label),
value = state.height ?: "",
placeholder = "0",
isSingleLine = true,
showWarning = state.isHeightValid.not(),
- warningMessage = stringResource(uiResource.string.entered_wrong_text),
+ warningMessage = stringResource(core_entered_wrong_text),
keyboardType = KeyboardType.Number,
trailingComponent = {
- UnitLabel(uiResource.string.height_unit)
+ UnitLabel(core_height_unit)
},
onValueChange = onChangeHeight,
modifier = Modifier.weight(1f),
)
TnTLabeledTextField(
- title = stringResource(uiResource.string.weight_label),
+ title = stringResource(core_weight_label),
value = state.weight ?: "",
placeholder = "00.0",
isSingleLine = true,
showWarning = state.isWeightValid.not(),
- warningMessage = stringResource(uiResource.string.entered_wrong_text),
+ warningMessage = stringResource(core_entered_wrong_text),
keyboardType = KeyboardType.Number,
trailingComponent = {
- UnitLabel(uiResource.string.weight_unit)
+ UnitLabel(core_weight_unit)
},
onValueChange = onChangeWeight,
modifier = Modifier.weight(1f),
@@ -131,7 +136,7 @@ internal fun TraineeBasicInfoPage(
}
}
TnTBottomButton(
- text = stringResource(uiResource.string.next),
+ text = stringResource(core_next),
modifier = Modifier.align(Alignment.BottomCenter),
enabled = state.isBasicInfoValid,
onClick = onClickNext,
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeNoteForTrainerPage.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeNoteForTrainerPage.kt
index a2844679..329a4978 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeNoteForTrainerPage.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeNoteForTrainerPage.kt
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_next
import co.kr.tnt.designsystem.component.TnTOutlinedTextField
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.button.TnTBottomButton
@@ -24,7 +25,6 @@ import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.feature.trainee.signup.R
import co.kr.tnt.trainee.signup.component.ProgressSteps
import co.kr.tnt.ui.extensions.clearFocusOnTap
-import co.kr.tnt.core.ui.R as uiResource
private const val MAX_LENGTH = 100
@@ -69,7 +69,7 @@ internal fun TraineeNoteForTrainerPage(
)
}
TnTBottomButton(
- text = stringResource(uiResource.string.next),
+ text = stringResource(core_next),
modifier = Modifier.align(Alignment.BottomCenter),
enabled = (caution?.length ?: 0) < MAX_LENGTH,
onClick = onClickNext,
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineePTPurposePage.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineePTPurposePage.kt
index 6e53c001..d6241011 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineePTPurposePage.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineePTPurposePage.kt
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_next
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.component.button.TnTTextButton
@@ -27,7 +28,6 @@ import co.kr.tnt.feature.trainee.signup.R
import co.kr.tnt.trainee.signup.TraineeSignUpContract.TraineeSignUpUiState
import co.kr.tnt.trainee.signup.component.ProgressSteps
import co.kr.tnt.trainee.signup.model.PTPurpose
-import co.kr.tnt.core.ui.R as uiResource
private const val ROW_NUM = 3
private const val COLUMNS_NUM = 2
@@ -76,7 +76,7 @@ internal fun TraineePTPurposePage(
}
}
TnTBottomButton(
- text = stringResource(uiResource.string.next),
+ text = stringResource(core_next),
onClick = onClickNext,
modifier = Modifier.align(Alignment.BottomCenter),
)
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeProfileSetupPage.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeProfileSetupPage.kt
index b4df61fc..99c7a1f8 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeProfileSetupPage.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeProfileSetupPage.kt
@@ -24,6 +24,9 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_name
+import co.kr.tnt.core.ui.R.string.core_next
+import co.kr.tnt.core.ui.R.string.core_text_length_and_format_warning
import co.kr.tnt.designsystem.component.TnTLabeledTextFieldWithCounter
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
@@ -38,7 +41,6 @@ import co.kr.tnt.ui.extensions.clearFocusOnTap
import co.kr.tnt.ui.model.DefaultUserProfile
import coil.compose.rememberAsyncImagePainter
import coil.request.ImageRequest
-import co.kr.tnt.core.ui.R as coreR
private const val MAX_LENGTH = 15
@@ -100,7 +102,7 @@ internal fun TraineeProfileSetupPage(
)
Spacer(Modifier.padding(top = 60.dp))
TnTLabeledTextFieldWithCounter(
- title = stringResource(coreR.string.name),
+ title = stringResource(core_name),
value = state.name,
onValueChange = { newValue ->
onChangeName(newValue)
@@ -111,11 +113,11 @@ internal fun TraineeProfileSetupPage(
isSingleLine = true,
showWarning = !state.isNameValid,
isRequired = true,
- warningMessage = stringResource(coreR.string.text_length_and_format_warning, MAX_LENGTH),
+ warningMessage = stringResource(core_text_length_and_format_warning, MAX_LENGTH),
)
}
TnTBottomButton(
- text = stringResource(coreR.string.next),
+ text = stringResource(core_next),
enabled = state.name.isNotBlank() && state.isNameValid,
onClick = onClickNext,
modifier = Modifier.align(Alignment.BottomCenter),
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpCompletePage.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpCompletePage.kt
index 8881204b..ce78b158 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpCompletePage.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpCompletePage.kt
@@ -22,6 +22,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign.Companion.Center
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_start
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.theme.TnTTheme
@@ -35,7 +36,6 @@ import coil.compose.rememberAsyncImagePainter
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
-import co.kr.tnt.core.ui.R as uiResource
@Composable
internal fun TraineeSignUpCompletePage(
@@ -98,7 +98,7 @@ internal fun TraineeSignUpCompletePage(
)
}
TnTBottomButton(
- text = stringResource(uiResource.string.start),
+ text = stringResource(core_start),
onClick = throttled { completeState.value = true },
modifier = Modifier.align(Alignment.BottomCenter),
)
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpContract.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpContract.kt
index 46f678bf..e13d115f 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpContract.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpContract.kt
@@ -4,6 +4,7 @@ import android.net.Uri
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
import java.io.File
import java.time.LocalDate
@@ -76,7 +77,7 @@ internal class TraineeSignUpContract {
}
sealed interface TraineeSignUpEffect : UiSideEffect {
- data class ShowToast(val message: String) : TraineeSignUpEffect
+ data class ShowToast(val message: DisplayText) : TraineeSignUpEffect
data object NavigateToBack : TraineeSignUpEffect
data object NavigateToConnect : TraineeSignUpEffect
}
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpScreen.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpScreen.kt
index e600c8f4..702e64d7 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpScreen.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpScreen.kt
@@ -4,6 +4,7 @@ import android.net.Uri
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.kr.tnt.designsystem.snackbar.LocalSnackbar
@@ -24,6 +25,7 @@ internal fun TraineeSignUpRoute(
navigateToConnect: () -> Unit,
viewModel: TraineeSignUpViewModel = hiltViewModel(),
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
@@ -56,7 +58,7 @@ internal fun TraineeSignUpRoute(
when (effect) {
TraineeSignUpEffect.NavigateToBack -> navigateToPrevious()
TraineeSignUpEffect.NavigateToConnect -> navigateToConnect()
- is TraineeSignUpEffect.ShowToast -> snackbar.show(effect.message)
+ is TraineeSignUpEffect.ShowToast -> snackbar.show(effect.message.asString(context))
}
}
}
diff --git a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpViewModel.kt b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpViewModel.kt
index 84655ef4..05f41f8e 100644
--- a/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpViewModel.kt
+++ b/feature/trainee/signup/src/main/java/co/kr/tnt/trainee/signup/TraineeSignUpViewModel.kt
@@ -2,6 +2,7 @@ package co.kr.tnt.trainee.signup
import android.net.Uri
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.model.User
import co.kr.tnt.domain.repository.SignUpRepository
import co.kr.tnt.trainee.signup.TraineeSignUpContract.TraineeSignUpEffect
@@ -9,6 +10,7 @@ import co.kr.tnt.trainee.signup.TraineeSignUpContract.TraineeSignUpPage
import co.kr.tnt.trainee.signup.TraineeSignUpContract.TraineeSignUpUiEvent
import co.kr.tnt.trainee.signup.TraineeSignUpContract.TraineeSignUpUiState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import java.io.File
@@ -75,7 +77,11 @@ internal class TraineeSignUpViewModel @Inject constructor(
}.onSuccess {
sendEffect(TraineeSignUpEffect.NavigateToConnect)
}.onFailure {
- sendEffect(TraineeSignUpEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ."))
+ sendEffect(
+ TraineeSignUpEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}.also {
updateState { copy(isLoading = false) }
}
diff --git a/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionContract.kt b/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionContract.kt
index d0f02780..b408cedd 100644
--- a/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionContract.kt
+++ b/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.domain.model.MemberInfo
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
import java.time.LocalDate
import java.time.LocalTime
import java.time.temporal.ChronoUnit
@@ -82,7 +83,7 @@ internal class AddPtSessionContract {
sealed interface AddPtSessionSideEffect : UiSideEffect {
data object ShowBottomSheet : AddPtSessionSideEffect
data object HideBottomSheet : AddPtSessionSideEffect
- data class ShowToast(val message: String) : AddPtSessionSideEffect
+ data class ShowToast(val message: DisplayText) : AddPtSessionSideEffect
data object NavigateToPrevious : AddPtSessionSideEffect
}
}
diff --git a/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionScreen.kt b/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionScreen.kt
index cb661879..c9aeadd5 100644
--- a/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionScreen.kt
+++ b/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionScreen.kt
@@ -36,6 +36,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -48,7 +49,13 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import co.kr.tnt.core.designsystem.R
+import co.kr.tnt.core.designsystem.R.drawable.ic_arrow_down
+import co.kr.tnt.core.designsystem.R.drawable.ic_check_true
+import co.kr.tnt.core.designsystem.R.drawable.ic_delete
+import co.kr.tnt.core.designsystem.R.drawable.ic_red_clock
+import co.kr.tnt.core.ui.R.string.core_cancel
+import co.kr.tnt.core.ui.R.string.core_length_warning
+import co.kr.tnt.core.ui.R.string.core_ok
import co.kr.tnt.designsystem.component.TnTBottomSheetDialog
import co.kr.tnt.designsystem.component.TnTDivider
import co.kr.tnt.designsystem.component.TnTIconPopupDialog
@@ -69,6 +76,7 @@ import co.kr.tnt.designsystem.snackbar.LocalSnackbar
import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.domain.model.MemberInfo
import co.kr.tnt.domain.utils.DateFormatter
+import co.kr.tnt.feature.trainer.addptsession.R
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionSideEffect
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionUiEvent
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionUiState
@@ -83,7 +91,6 @@ import kotlinx.coroutines.launch
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.LocalTime
-import co.kr.tnt.core.ui.R as coreR
@Composable
internal fun AddPtSessionRoute(
@@ -91,6 +98,7 @@ internal fun AddPtSessionRoute(
viewModel: AddPtSessionViewModel = hiltViewModel(),
navigateToPrevious: () -> Unit,
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val state by viewModel.uiState.collectAsStateWithLifecycle()
@@ -139,7 +147,7 @@ internal fun AddPtSessionRoute(
)
AddPtSessionUiState.BottomSheetType.SELECT_START_TIME -> TimePickerBottomSheetContent(
- title = "μμ μκ° μ ννκΈ°",
+ title = stringResource(R.string.select_start_time),
selectedTime = state.selectedStartTime,
onDismissRequest = { showBottomSheet = false },
onClickConfirm = { selectTime ->
@@ -148,7 +156,7 @@ internal fun AddPtSessionRoute(
)
AddPtSessionUiState.BottomSheetType.SELECT_END_TIME -> TimePickerBottomSheetContent(
- title = "μ’
λ£ μκ° μ ννκΈ°",
+ title = stringResource(R.string.select_end_time),
selectedTime = state.selectedEndTime,
onDismissRequest = { showBottomSheet = false },
onClickConfirm = { selectTime ->
@@ -181,7 +189,7 @@ internal fun AddPtSessionRoute(
showBottomSheet = false
}
- is AddPtSessionSideEffect.ShowToast -> snackbar.show(effect.message)
+ is AddPtSessionSideEffect.ShowToast -> snackbar.show(effect.message.asString(context))
AddPtSessionSideEffect.NavigateToPrevious -> navigateToPrevious()
}
}
@@ -206,7 +214,7 @@ private fun AddPtSessionScreen(
topBar = {
TnTTopBarWithBackButton(
modifier = Modifier.fillMaxWidth(),
- title = "μμ
μΆκ°νκΈ°",
+ title = stringResource(R.string.add_pt_session),
onBackClick = onClickBack,
showStoke = true,
)
@@ -236,18 +244,18 @@ private fun AddPtSessionScreen(
Description()
Spacer(modifier = Modifier.height(48.dp))
Selector(
- title = "νμ μ ν",
+ title = stringResource(R.string.select_member),
value = state.selectedMember?.traineeName ?: "",
- placeholder = "νμμ μ
λ ₯ν΄μ£ΌμΈμ",
+ placeholder = stringResource(R.string.insert_memeber),
onClick = onClickMember,
)
Spacer(modifier = Modifier.height(48.dp))
Selector(
- title = "PT λ μ§",
+ title = stringResource(R.string.pt_date),
value = state.selectedDate?.let { selectedDate ->
dateFormatter.format(selectedDate, "yyyy/MM/dd")
} ?: "",
- placeholder = "λ μ§λ₯Ό μ
λ ₯ν΄μ£ΌμΈμ",
+ placeholder = stringResource(R.string.insert_date),
onClick = onClickDate,
)
Spacer(modifier = Modifier.height(48.dp))
@@ -295,13 +303,13 @@ private fun AddPtSessionScreen(
@Composable
private fun Description() {
Text(
- text = "μΈμ μμ
ν κΉμ?",
+ text = stringResource(R.string.when_to_have_pt),
style = TnTTheme.typography.h2,
color = TnTTheme.colors.neutralColors.Neutral950,
)
Spacer(modifier = Modifier.height(8.dp))
Text(
- text = "μΌμ μ λ±λ‘νλ©΄ νμμκ²λ μΌμ μ΄ λ±λ‘λΌμ",
+ text = stringResource(R.string.schedule_registered_for_member),
style = TnTTheme.typography.body2Medium,
color = TnTTheme.colors.neutralColors.Neutral500,
)
@@ -346,7 +354,7 @@ private fun Selector(
},
trailingComponent = {
Icon(
- painter = painterResource(R.drawable.ic_arrow_down),
+ painter = painterResource(ic_arrow_down),
contentDescription = null,
tint = TnTTheme.colors.neutralColors.Neutral400,
)
@@ -368,7 +376,7 @@ private fun TimeSelector(
) {
Row(modifier = modifier.fillMaxWidth()) {
Selector(
- title = "μμ μκ°",
+ title = stringResource(R.string.start_time),
value = startTime?.let {
dateFormatter.format(it, "HH:mm")
} ?: "",
@@ -390,7 +398,7 @@ private fun TimeSelector(
.align(Alignment.Bottom),
)
Selector(
- title = "μ’
λ£ μκ°",
+ title = stringResource(R.string.end_time),
value = endTime?.let {
dateFormatter.format(it, "HH:mm")
} ?: "",
@@ -408,7 +416,7 @@ private fun MinuteChips(
onClickChip: (minute: Int) -> Unit,
) {
Text(
- text = "μμ
μκ°",
+ text = stringResource(R.string.pt_time),
style = TnTTheme.typography.body1Bold,
color = TnTTheme.colors.neutralColors.Neutral900,
)
@@ -444,7 +452,7 @@ private fun MinuteChip(
onClick: (minute: Int) -> Unit,
) {
TnTTextButton(
- "+${minute}λΆ",
+ stringResource(R.string.minute, minute),
modifier = modifier,
type = if (isSelected) ButtonType.RedOutline else ButtonType.GrayOutline,
onClick = { onClick(minute) },
@@ -467,18 +475,18 @@ private fun TotalSessionMinute(
),
) {
Icon(
- painter = painterResource(R.drawable.ic_red_clock),
+ painter = painterResource(ic_red_clock),
contentDescription = null,
tint = Color.Unspecified,
)
Spacer(modifier = Modifier.width(4.dp))
Text(
text = buildAnnotatedString {
- append("μ΄ ")
+ append(stringResource(R.string.total_prefix))
withStyle(SpanStyle(fontWeight = FontWeight.Bold)) {
append("${minute}λΆ")
}
- append(" μμ
μ΄μμ")
+ append(stringResource(R.string.minute_suffix))
},
style = TnTTheme.typography.body2Medium,
color = TnTTheme.colors.neutralColors.Neutral900,
@@ -493,7 +501,7 @@ private fun Memo(
onValueChanged: (String) -> Unit,
) {
Text(
- text = "λ©λͺ¨νκΈ°",
+ text = stringResource(R.string.write_memo),
style = TnTTheme.typography.body1Bold,
color = TnTTheme.colors.neutralColors.Neutral900,
)
@@ -503,7 +511,7 @@ private fun Memo(
onValueChange = onValueChanged,
maxLength = 30,
isError = isWarning,
- warningMessage = "30μ λ―Έλ§μΌλ‘ μ
λ ₯ν΄μ£ΌμΈμ",
+ warningMessage = stringResource(core_length_warning, 30),
modifier = Modifier.fillMaxWidth(),
)
}
@@ -520,7 +528,7 @@ private fun MembersBottomSheetContent(
modifier = modifier.heightIn(max = 708.dp),
) {
SheetTopBar(
- title = "νμ μ ννκΈ°",
+ title = stringResource(R.string.select_member),
onDismissRequest = onDismissRequest,
)
LazyColumn {
@@ -564,7 +572,7 @@ private fun MemberItem(
)
if (isSelected) {
Icon(
- painter = painterResource(R.drawable.ic_check_true),
+ painter = painterResource(ic_check_true),
contentDescription = null,
tint = Color.Unspecified,
)
@@ -596,7 +604,7 @@ private fun CalendarBottomSheetContent(
verticalArrangement = Arrangement.Center,
) {
SheetTopBar(
- title = "PT λ μ§ μ ννκΈ°",
+ title = stringResource(R.string.select_pt_date),
onDismissRequest = onDismissRequest,
)
Column(
@@ -695,7 +703,7 @@ private fun SheetTopBar(
.size(32.dp),
) {
Icon(
- painter = painterResource(R.drawable.ic_delete),
+ painter = painterResource(ic_delete),
contentDescription = null,
)
}
@@ -709,7 +717,7 @@ private fun SheetConfirm(
onClick: () -> Unit,
) {
TnTTextButton(
- text = stringResource(coreR.string.ok),
+ text = stringResource(core_ok),
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp),
@@ -729,10 +737,10 @@ private fun Dialog(
DialogState.NONE -> Unit
DialogState.CHECK_CANCEL_ADD -> {
TnTIconPopupDialog(
- title = "μμ
λ±λ‘μ μ·¨μν κΉμ?",
- content = "μΌμ μ΄ μ μ₯λμ§ μμμ",
- leftButtonText = stringResource(coreR.string.cancel),
- rightButtonText = stringResource(coreR.string.ok),
+ title = stringResource(R.string.cancel_pt_registration),
+ content = stringResource(R.string.schedule_will_not_be_saved),
+ leftButtonText = stringResource(core_cancel),
+ rightButtonText = stringResource(core_ok),
onLeftButtonClick = onDismissDialog,
onRightButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -741,9 +749,9 @@ private fun Dialog(
DialogState.SUCCESS_ADD -> {
TnTSingleButtonPopupDialog(
- title = "μμ
μΌμ μ΄ μΆκ°λμ΄μ",
- content = "λ±λ‘λ μΌμ μ νΈλ μ΄λμκ²λ νμλΌμ!",
- buttonText = stringResource(coreR.string.ok),
+ title = stringResource(R.string.added_pt_schedule),
+ content = stringResource(R.string.schedule_shown_to_trainee),
+ buttonText = stringResource(core_ok),
cancelable = false,
onButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
diff --git a/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionViewModel.kt b/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionViewModel.kt
index 1f92b033..52a63de8 100644
--- a/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionViewModel.kt
+++ b/feature/trainer/addptsession/src/main/java/co/kr/tnt/trainer/addptsession/AddPtSessionViewModel.kt
@@ -1,13 +1,16 @@
package co.kr.tnt.trainer.addptsession
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.repository.TrainerRepository
+import co.kr.tnt.feature.trainer.addptsession.R
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionSideEffect
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionUiEvent
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionUiState
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionUiState.BottomSheetType
import co.kr.tnt.trainer.addptsession.AddPtSessionContract.AddPtSessionUiState.DialogState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -25,7 +28,11 @@ internal class AddPtSessionViewModel @Inject constructor(
}.onSuccess { members ->
updateState { copy(members = members) }
}.onFailure {
- sendEffect(AddPtSessionSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ AddPtSessionSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -95,7 +102,11 @@ internal class AddPtSessionViewModel @Inject constructor(
private fun postPtSession() {
if (currentState.isEnableComplete.not()) {
- sendEffect(AddPtSessionSideEffect.ShowToast("νμ μ
λ ₯ νλͺ©μ λͺ¨λ μ
λ ₯ν΄μ£ΌμΈμ"))
+ sendEffect(
+ AddPtSessionSideEffect.ShowToast(
+ DisplayText.Resource(R.string.fill_required_fields),
+ ),
+ )
return
}
@@ -114,7 +125,12 @@ internal class AddPtSessionViewModel @Inject constructor(
}.onSuccess {
updateState { copy(dialogState = DialogState.SUCCESS_ADD) }
}.onFailure { throwable ->
- sendEffect(AddPtSessionSideEffect.ShowToast(throwable.message ?: "μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ AddPtSessionSideEffect.ShowToast(
+ throwable.message?.let(DisplayText::Plain)
+ ?: DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}.also {
updateState { copy(isLoading = false) }
}
diff --git a/feature/trainer/addptsession/src/main/res/values/strings.xml b/feature/trainer/addptsession/src/main/res/values/strings.xml
new file mode 100644
index 00000000..ea6d4ed2
--- /dev/null
+++ b/feature/trainer/addptsession/src/main/res/values/strings.xml
@@ -0,0 +1,26 @@
+
+
+ νμ μ
λ ₯ νλͺ©μ λͺ¨λ μ
λ ₯ν΄μ£ΌμΈμ
+ μμ μκ° μ ννκΈ°
+ μ’
λ£ μκ° μ ννκΈ°
+ μμ
μΆκ°νκΈ°
+ νμ μ ν
+ νμμ μ
λ ₯ν΄μ£ΌμΈμ
+ PT λ μ§
+ λ μ§λ₯Ό μ
λ ₯ν΄μ£ΌμΈμ
+ μΈμ μμ
ν κΉμ?
+ μΌμ μ λ±λ‘νλ©΄ νμμκ²λ μΌμ μ΄ λ±λ‘λΌμ
+ μμ μκ°
+ μ’
λ£ μκ°
+ μμ
μκ°
+ +%1$sλΆ
+ μ΄ %1$sλΆ μμ
μ΄μμ
+ λ©λͺ¨νκΈ°
+ PT λ μ§ μ ννκΈ°
+ μμ
λ±λ‘μ μ·¨μν κΉμ?
+ μΌμ μ΄ μ μ₯λμ§ μμμ
+ μμ
μΌμ μ΄ μΆκ°λμ΄μ
+ λ±λ‘λ μΌμ μ νΈλ μ΄λμκ²λ νμλΌμ!
+ "μ΄ "
+ " μμ
μ΄μμ"
+
diff --git a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TraineeProfilePage.kt b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TraineeProfilePage.kt
index 9805a9f3..483ad47f 100644
--- a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TraineeProfilePage.kt
+++ b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TraineeProfilePage.kt
@@ -32,6 +32,13 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_age_label
+import co.kr.tnt.core.ui.R.string.core_age_unit
+import co.kr.tnt.core.ui.R.string.core_height_label
+import co.kr.tnt.core.ui.R.string.core_height_unit
+import co.kr.tnt.core.ui.R.string.core_start
+import co.kr.tnt.core.ui.R.string.core_weight_label
+import co.kr.tnt.core.ui.R.string.core_weight_unit
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.theme.TnTTheme
@@ -115,17 +122,17 @@ internal fun TraineeProfilePage(
Spacer(Modifier.height(32.dp))
val traineeInfo = listOfNotNull(
trainee.age?.let {
- stringResource(uiResource.string.age_label) to
- it.toString() + stringResource(uiResource.string.age_unit)
+ stringResource(core_age_label) to
+ it.toString() + stringResource(core_age_unit)
},
trainee.height?.let {
- stringResource(uiResource.string.height_label) to
- it.toString() + stringResource(uiResource.string.height_unit)
+ stringResource(core_height_label) to
+ it.toString() + stringResource(core_height_unit)
},
trainee.weight?.let {
- stringResource(uiResource.string.weight_label) to
+ stringResource(core_weight_label) to
it.toString()
- .removeSuffix(".0") + stringResource(uiResource.string.weight_unit)
+ .removeSuffix(".0") + stringResource(core_weight_unit)
},
)
@@ -155,7 +162,7 @@ internal fun TraineeProfilePage(
Spacer(Modifier.height(24.dp))
}
TnTBottomButton(
- text = stringResource(uiResource.string.start),
+ text = stringResource(core_start),
onClick = onClickNext,
modifier = Modifier.align(Alignment.BottomCenter),
)
@@ -204,7 +211,7 @@ private fun TextWithBackground(
.padding(horizontal = 16.dp, vertical = 12.dp),
) {
Text(
- text = text.ifEmpty { "λ―Έμ
λ ₯" },
+ text = text.ifEmpty { stringResource(R.string.not_entered) },
style = TnTTheme.typography.label1Medium,
color =
if (text.isEmpty()) {
diff --git a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectCompletePage.kt b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectCompletePage.kt
index 0443e1c5..3129fb28 100644
--- a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectCompletePage.kt
+++ b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectCompletePage.kt
@@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_next
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.theme.TnTTheme
@@ -96,7 +97,7 @@ internal fun TrainerConnectCompletePage(
}
}
TnTBottomButton(
- text = stringResource(uiResource.string.next),
+ text = stringResource(core_next),
onClick = onClickNext,
modifier = Modifier.align(Alignment.BottomCenter),
)
diff --git a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectContract.kt b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectContract.kt
index 80dbafea..58bb7cde 100644
--- a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectContract.kt
+++ b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.domain.model.User
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
internal class TrainerConnectContract {
data class TrainerConnectUiState(
@@ -24,7 +25,7 @@ internal class TrainerConnectContract {
sealed interface TrainerConnectSideEffect : UiSideEffect {
data object NavigateToBack : TrainerConnectSideEffect
data object NavigateToHome : TrainerConnectSideEffect
- data class ShowToast(val message: String) : TrainerConnectSideEffect
+ data class ShowToast(val message: DisplayText) : TrainerConnectSideEffect
}
enum class TrainerConnectPage {
diff --git a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectScreen.kt b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectScreen.kt
index 2398a86b..9c5b7f3e 100644
--- a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectScreen.kt
+++ b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectScreen.kt
@@ -3,6 +3,7 @@ package co.kr.tnt.trainer.connect
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.kr.tnt.designsystem.snackbar.LocalSnackbar
@@ -19,6 +20,7 @@ internal fun TrainerConnectRoute(
navigateToHome: (Boolean) -> Unit,
viewModel: TrainerConnectViewModel = hiltViewModel(),
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val state by viewModel.uiState.collectAsStateWithLifecycle()
@@ -37,7 +39,7 @@ internal fun TrainerConnectRoute(
when (effect) {
TrainerConnectSideEffect.NavigateToBack -> navigateToPrevious()
TrainerConnectSideEffect.NavigateToHome -> navigateToHome(true)
- is TrainerConnectSideEffect.ShowToast -> snackbar.show(effect.message)
+ is TrainerConnectSideEffect.ShowToast -> snackbar.show(effect.message.asString(context))
}
}
}
diff --git a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectViewModel.kt b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectViewModel.kt
index 38172391..13ffb596 100644
--- a/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectViewModel.kt
+++ b/feature/trainer/connect/src/main/java/co/kr/tnt/trainer/connect/TrainerConnectViewModel.kt
@@ -1,6 +1,7 @@
package co.kr.tnt.trainer.connect
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.model.User
import co.kr.tnt.domain.model.trainer.TrainerManagementMemberCount
import co.kr.tnt.domain.repository.ConnectRepository
@@ -9,6 +10,7 @@ import co.kr.tnt.trainer.connect.TrainerConnectContract.TrainerConnectSideEffect
import co.kr.tnt.trainer.connect.TrainerConnectContract.TrainerConnectUiEvent
import co.kr.tnt.trainer.connect.TrainerConnectContract.TrainerConnectUiState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -62,7 +64,7 @@ internal class TrainerConnectViewModel @Inject constructor(
)
}
}.onFailure {
- sendEffect(TrainerConnectSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(TrainerConnectSideEffect.ShowToast(DisplayText.Resource(core_failed_to_server_request)))
}
}
}
diff --git a/feature/trainer/connect/src/main/res/values/strings.xml b/feature/trainer/connect/src/main/res/values/strings.xml
index a703db0f..8bb973ae 100644
--- a/feature/trainer/connect/src/main/res/values/strings.xml
+++ b/feature/trainer/connect/src/main/res/values/strings.xml
@@ -5,4 +5,5 @@
ν¨κ»ν νΈλ μ΄λλ μ΄λ° λΆμ΄μμ!
PT λͺ©ν
μ£Όμμ¬ν
+ λ―Έμ
λ ₯
diff --git a/feature/trainer/feedback/src/main/java/co/kr/tnt/trainer/feedback/TrainerFeedbackScreen.kt b/feature/trainer/feedback/src/main/java/co/kr/tnt/trainer/feedback/TrainerFeedbackScreen.kt
index b0eede23..8c4995c0 100644
--- a/feature/trainer/feedback/src/main/java/co/kr/tnt/trainer/feedback/TrainerFeedbackScreen.kt
+++ b/feature/trainer/feedback/src/main/java/co/kr/tnt/trainer/feedback/TrainerFeedbackScreen.kt
@@ -11,9 +11,12 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
+import co.kr.tnt.core.ui.R.string.core_no_records_yet
import co.kr.tnt.designsystem.theme.TnTTheme
+import co.kr.tnt.feature.trainer.feedback.R
import co.kr.tnt.ui.component.TnTCountTopBar
@Composable
@@ -35,7 +38,7 @@ private fun TrainerFeedbackScreen(
.padding(padding),
) {
TnTCountTopBar(
- title = "νΌλλ°±",
+ title = stringResource(R.string.feedback),
count = 0,
)
EmptyFeedback()
@@ -50,13 +53,13 @@ private fun EmptyFeedback() {
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
- text = "μμ§ λ±λ‘λ κΈ°λ‘μ΄ μμ΄μ",
+ text = stringResource(core_no_records_yet),
color = TnTTheme.colors.neutralColors.Neutral600,
style = TnTTheme.typography.body2Bold,
)
Spacer(modifier = Modifier.height(4.dp))
Text(
- text = "νΈλ μ΄λκ° κΈ°λ‘μ μ μ‘νλ©΄ μ¬κΈ°μ νμλΌμ!",
+ text = stringResource(R.string.records_shown_when_trainee_sends),
color = TnTTheme.colors.neutralColors.Neutral400,
style = TnTTheme.typography.label1Medium,
)
diff --git a/feature/trainer/feedback/src/main/res/values/strings.xml b/feature/trainer/feedback/src/main/res/values/strings.xml
new file mode 100644
index 00000000..3cea04b2
--- /dev/null
+++ b/feature/trainer/feedback/src/main/res/values/strings.xml
@@ -0,0 +1,5 @@
+
+
+ νΌλλ°±
+ νΈλ μ΄λκ° κΈ°λ‘μ μ μ‘νλ©΄ μ¬κΈ°μ νμλΌμ!
+
diff --git a/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeContract.kt b/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeContract.kt
index 1dede40b..15de08cf 100644
--- a/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeContract.kt
+++ b/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeContract.kt
@@ -5,6 +5,7 @@ import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
import co.kr.tnt.ui.model.SnackbarType
+import co.kr.tnt.ui.resource.DisplayText
import java.time.LocalDate
import java.time.YearMonth
@@ -40,7 +41,7 @@ internal class TrainerHomeContract {
data object NavigateToAddPtSession : TrainerHomeSideEffect
data object NavigateToInvite : TrainerHomeSideEffect
data class ShowToast(
- val message: String,
+ val message: DisplayText,
val type: SnackbarType = SnackbarType.WARNING,
) : TrainerHomeSideEffect
}
diff --git a/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeScreen.kt b/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeScreen.kt
index 52a60206..2c6fa741 100644
--- a/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeScreen.kt
+++ b/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeScreen.kt
@@ -38,7 +38,13 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import co.kr.tnt.core.designsystem.R
+import co.kr.tnt.core.designsystem.R.drawable.ic_add
+import co.kr.tnt.core.designsystem.R.drawable.ic_fill_check_false
+import co.kr.tnt.core.designsystem.R.drawable.ic_fill_check_true
+import co.kr.tnt.core.designsystem.R.drawable.img_default
+import co.kr.tnt.core.ui.R.string.core_connect
+import co.kr.tnt.core.ui.R.string.core_do_not_see_for_three_days
+import co.kr.tnt.core.ui.R.string.core_next_time
import co.kr.tnt.designsystem.component.TnTPopupDialog
import co.kr.tnt.designsystem.component.button.TnTFabButton
import co.kr.tnt.designsystem.component.calendar.TnTIndicatorMonthCalendar
@@ -50,6 +56,7 @@ import co.kr.tnt.designsystem.snackbar.LocalSnackbar
import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.domain.model.PtSession
import co.kr.tnt.domain.utils.DateFormatter
+import co.kr.tnt.feature.trainer.home.R
import co.kr.tnt.navigation.model.ScreenMode
import co.kr.tnt.trainer.home.TrainerHomeContract.TrainerHomeSideEffect
import co.kr.tnt.trainer.home.TrainerHomeContract.TrainerHomeUiEvent
@@ -65,7 +72,6 @@ import kotlinx.coroutines.launch
import java.time.DayOfWeek
import java.time.LocalDate
import java.time.YearMonth
-import co.kr.tnt.core.ui.R as coreR
@Composable
internal fun TrainerHomeRoute(
@@ -76,6 +82,7 @@ internal fun TrainerHomeRoute(
navigateToInvite: (ScreenMode) -> Unit,
) {
val toast = LocalSnackbar.current
+ val context = LocalContext.current
val state by viewModel.uiState.collectAsStateWithLifecycle()
TrainerHomeScreen(
@@ -95,7 +102,7 @@ internal fun TrainerHomeRoute(
TrainerHomeSideEffect.NavigateToAddPtSession -> navigateToAddPtSession(state.selectedDay.toString())
TrainerHomeSideEffect.NavigateToInvite -> navigateToInvite(ScreenMode.CLOSE)
is TrainerHomeSideEffect.ShowToast -> toast.show(
- message = effect.message,
+ message = effect.message.asString(context),
icon = effect.type.iconRes,
)
}
@@ -106,12 +113,12 @@ internal fun TrainerHomeRoute(
TrainerHomeUiState.DialogState.NONE -> Unit
TrainerHomeUiState.DialogState.HOME_CONNECT -> {
TnTCheckToggleDialog(
- title = "νμμ μ°κ²°ν΄ μ£ΌμΈμ",
- content = "μ°κ²°νμ§ μμ κ²½μ° μμ
μ μΆκ°ν μ μμ΄μ\nμ΄λ μ½λλ₯Ό 볡μ¬ν΄ μ°κ²°ν΄μ£Όμκ² μ΄μ?",
+ title = stringResource(R.string.please_connect_member),
+ content = stringResource(R.string.cannot_add_pt_without_connection),
isChecked = state.isDialogHiddenForThreeDays,
- checkToggleText = stringResource(coreR.string.do_not_see_for_three_days),
- leftButtonText = stringResource(coreR.string.next_time),
- rightButtonText = stringResource(coreR.string.connect),
+ checkToggleText = stringResource(core_do_not_see_for_three_days),
+ leftButtonText = stringResource(core_next_time),
+ rightButtonText = stringResource(core_connect),
onLeftButtonClick = { viewModel.setEvent(TrainerHomeUiEvent.OnDismissDialog) },
onRightButtonClick = { viewModel.setEvent(TrainerHomeUiEvent.OnConfirmConnectDialog) },
onClickCheck = { viewModel.setEvent(TrainerHomeUiEvent.OnChangeHideDialogOption) },
@@ -121,10 +128,10 @@ internal fun TrainerHomeRoute(
TrainerHomeUiState.DialogState.ADD_PT_CONNECT -> {
TnTPopupDialog(
- title = "νμμ μ°κ²°ν΄ μ£ΌμΈμ",
- content = "μ°κ²°νμ§ μμ κ²½μ° μμ
μ μΆκ°ν μ μμ΄μ\nμ΄λ μ½λλ₯Ό 볡μ¬ν΄ μ°κ²°ν΄μ£Όμκ² μ΄μ?",
- leftButtonText = stringResource(coreR.string.next_time),
- rightButtonText = stringResource(coreR.string.connect),
+ title = stringResource(R.string.please_connect_member),
+ content = stringResource(R.string.cannot_add_pt_without_connection),
+ leftButtonText = stringResource(core_next_time),
+ rightButtonText = stringResource(core_connect),
onLeftButtonClick = { viewModel.setEvent(TrainerHomeUiEvent.OnDismissDialog) },
onRightButtonClick = { viewModel.setEvent(TrainerHomeUiEvent.OnConfirmConnectDialog) },
onDismiss = { viewModel.setEvent(TrainerHomeUiEvent.OnDismissDialog) },
@@ -227,11 +234,11 @@ private fun TrainerHomeScreen(
bottom = 22.dp,
end = 28.dp,
),
- text = "μμ
μΆκ°",
+ text = stringResource(R.string.add_pt_session),
enabled = true,
leadingComposable = {
Icon(
- painter = painterResource(R.drawable.ic_add),
+ painter = painterResource(ic_add),
contentDescription = "add pt session",
)
},
@@ -302,7 +309,7 @@ private fun DailyPtSessionTitle(
) {
append(sessionCount.toString())
}
- append("κ°μ μμ
μ΄ μμ΄μ")
+ append(stringResource(R.string.pt_session_count_suffix))
},
style = TnTTheme.typography.label2Medium,
color = TnTTheme.colors.neutralColors.Neutral800,
@@ -320,13 +327,13 @@ private fun EmptyPtSessions(modifier: Modifier = Modifier) {
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
- text = "μμ§ λ±λ‘λ μμ
μ΄ μμ΄μ.",
+ text = stringResource(R.string.no_pt_session_yet),
style = TnTTheme.typography.body2Bold,
color = TnTTheme.colors.neutralColors.Neutral600,
)
Spacer(modifier = Modifier.height(4.dp))
Text(
- text = "μΆκ° λ²νΌμ λλ¬ PT μμ
μΌμ μ μΆκ°ν΄ 보μΈμ",
+ text = stringResource(R.string.press_add_button_to_add_pt_session),
style = TnTTheme.typography.label1Medium,
color = TnTTheme.colors.neutralColors.Neutral400,
)
@@ -343,8 +350,8 @@ private fun PtSessionCard(
val painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
.data(ptSession.traineeProfileUrl)
- .placeholder(R.drawable.img_default)
- .error(R.drawable.img_default)
+ .placeholder(img_default)
+ .error(img_default)
.build(),
)
@@ -367,9 +374,9 @@ private fun PtSessionCard(
.padding(4.dp),
painter = painterResource(
if (ptSession.isCompleted) {
- R.drawable.ic_fill_check_true
+ ic_fill_check_true
} else {
- R.drawable.ic_fill_check_false
+ ic_fill_check_false
},
),
contentDescription = null,
@@ -382,10 +389,10 @@ private fun PtSessionCard(
TnTSessionRecordCard(
isTrainer = true,
name = traineeName,
- tagText = "${round}νμ°¨ μμ
",
+ tagText = stringResource(R.string.pt_session_count, round),
startTime = dateFormatter.format(startTime, "a hh:mm"),
endTime = dateFormatter.format(endTime, "a hh:mm"),
- defaultImage = painterResource(R.drawable.img_default),
+ defaultImage = painterResource(img_default),
profileImage = painter,
leadingEmoji = "\uD83D\uDCAA",
showSessionRecordCreation = false,
diff --git a/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeViewModel.kt b/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeViewModel.kt
index f540964f..86099954 100644
--- a/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeViewModel.kt
+++ b/feature/trainer/home/src/main/java/co/kr/tnt/trainer/home/TrainerHomeViewModel.kt
@@ -1,16 +1,19 @@
package co.kr.tnt.trainer.home
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.model.PtSession
import co.kr.tnt.domain.model.trainer.TrainerDailyPtSessionCount
import co.kr.tnt.domain.repository.ConnectRepository
import co.kr.tnt.domain.repository.TrainerRepository
+import co.kr.tnt.feature.trainer.home.R
import co.kr.tnt.trainer.home.TrainerHomeContract.TrainerHomeSideEffect
import co.kr.tnt.trainer.home.TrainerHomeContract.TrainerHomeUiEvent
import co.kr.tnt.trainer.home.TrainerHomeContract.TrainerHomeUiState
import co.kr.tnt.trainer.home.TrainerHomeContract.TrainerHomeUiState.DialogState
import co.kr.tnt.ui.base.BaseViewModel
import co.kr.tnt.ui.model.SnackbarType
+import co.kr.tnt.ui.resource.DisplayText
import com.kizitonwose.calendar.core.yearMonth
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.async
@@ -77,7 +80,11 @@ internal class TrainerHomeViewModel @Inject constructor(
results.forEach(::updateMonthlyPtSessionCounts)
}.onFailure {
- sendEffect(TrainerHomeSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TrainerHomeSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -97,7 +104,11 @@ internal class TrainerHomeViewModel @Inject constructor(
updateState { copy(selectedDayPtSessions = selectedDayPtSessions) }
}.onFailure {
updateState { copy(selectedDayPtSessions = null) }
- sendEffect(TrainerHomeSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TrainerHomeSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -120,12 +131,18 @@ internal class TrainerHomeViewModel @Inject constructor(
getDailyPtSessions(currentState.selectedDay)
sendEffect(
TrainerHomeSideEffect.ShowToast(
- message = "PT μμ
μ μλ£νμ΄μ",
+ message = DisplayText.Resource(R.string.pt_completed),
type = SnackbarType.SUCCESS,
),
)
}.onFailure { throwable ->
- sendEffect(TrainerHomeSideEffect.ShowToast(throwable.message ?: "μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TrainerHomeSideEffect.ShowToast(
+ throwable.message?.let { message ->
+ DisplayText.Plain(message)
+ } ?: DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -140,7 +157,7 @@ internal class TrainerHomeViewModel @Inject constructor(
updateState { copy(selectedDayPtSessions = cachedDailyPtSession[day]) }
}
}.onFailure {
- sendEffect(TrainerHomeSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(TrainerHomeSideEffect.ShowToast(DisplayText.Resource(core_failed_to_server_request)))
}
}
}
diff --git a/feature/trainer/home/src/main/res/values/strings.xml b/feature/trainer/home/src/main/res/values/strings.xml
new file mode 100644
index 00000000..f9c25c95
--- /dev/null
+++ b/feature/trainer/home/src/main/res/values/strings.xml
@@ -0,0 +1,11 @@
+
+
+ PT μμ
μ μλ£νμ΄μ
+ νμμ μ°κ²°ν΄ μ£ΌμΈμ
+ μ°κ²°νμ§ μμ κ²½μ° μμ
μ μΆκ°ν μ μμ΄μ\nμ΄λ μ½λλ₯Ό 볡μ¬ν΄ μ°κ²°ν΄μ£Όμκ² μ΄μ?
+ μμ
μΆκ°
+ κ°μ μμ
μ΄ μμ΄μ
+ μμ§ λ±λ‘λ μμ
μ΄ μμ΄μ.
+ μΆκ° λ²νΌμ λλ¬ PT μμ
μΌμ μ μΆκ°ν΄ 보μΈμ
+ %1$sνμ°¨ μμ
+
diff --git a/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteContract.kt b/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteContract.kt
index e86e4cda..46b6793f 100644
--- a/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteContract.kt
+++ b/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteContract.kt
@@ -3,6 +3,7 @@ package co.kr.tnt.trainer.invite
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
internal class TrainerInviteContract {
data class TrainerInviteUiState(
@@ -19,7 +20,7 @@ internal class TrainerInviteContract {
sealed interface TrainerInviteSideEffect : UiSideEffect {
data object NavigateToBack : TrainerInviteSideEffect
data object NavigateToHome : TrainerInviteSideEffect
- data class ShowToast(val message: String) : TrainerInviteSideEffect
+ data class ShowToast(val message: DisplayText) : TrainerInviteSideEffect
data class CopyToClipBoard(val value: String) : TrainerInviteSideEffect
}
}
diff --git a/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteScreen.kt b/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteScreen.kt
index 41965cd9..eafb4be9 100644
--- a/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteScreen.kt
+++ b/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteScreen.kt
@@ -21,6 +21,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalClipboardManager
+import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
@@ -28,6 +29,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import co.kr.tnt.core.ui.R.string.core_connect
+import co.kr.tnt.core.ui.R.string.core_skip
import co.kr.tnt.designsystem.component.TnTTopBar
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.button.TnTTextButton
@@ -41,7 +44,6 @@ import co.kr.tnt.trainer.invite.TrainerInviteContract.TrainerInviteSideEffect
import co.kr.tnt.trainer.invite.TrainerInviteContract.TrainerInviteUiEvent
import co.kr.tnt.trainer.invite.TrainerInviteContract.TrainerInviteUiState
import kotlinx.coroutines.flow.collectLatest
-import co.kr.tnt.core.ui.R as coreR
@Composable
internal fun TrainerInviteRoute(
@@ -50,6 +52,7 @@ internal fun TrainerInviteRoute(
navigateToHome: (Boolean) -> Unit,
viewModel: TrainerInviteViewModel = hiltViewModel(),
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val state by viewModel.uiState.collectAsStateWithLifecycle()
val clipboardManager = LocalClipboardManager.current
@@ -68,7 +71,7 @@ internal fun TrainerInviteRoute(
when (effect) {
TrainerInviteSideEffect.NavigateToBack -> navigateToPrevious()
TrainerInviteSideEffect.NavigateToHome -> navigateToHome(true)
- is TrainerInviteSideEffect.ShowToast -> snackbar.show(effect.message)
+ is TrainerInviteSideEffect.ShowToast -> snackbar.show(effect.message.asString(context))
is TrainerInviteSideEffect.CopyToClipBoard ->
clipboardManager.setText(AnnotatedString(effect.value))
}
@@ -105,10 +108,10 @@ internal fun TrainerInviteScreen(
ScreenMode.SKIP -> {
TnTTopBar(
- title = stringResource(coreR.string.connect),
+ title = stringResource(core_connect),
trailingComponent = {
Text(
- text = stringResource(coreR.string.skip),
+ text = stringResource(core_skip),
color = TnTTheme.colors.neutralColors.Neutral400,
style = TnTTheme.typography.body2Medium,
modifier = Modifier.clickable {
diff --git a/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteViewModel.kt b/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteViewModel.kt
index 63e891c3..635f5806 100644
--- a/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteViewModel.kt
+++ b/feature/trainer/invite/src/main/java/co/kr/tnt/trainer/invite/TrainerInviteViewModel.kt
@@ -1,11 +1,14 @@
package co.kr.tnt.trainer.invite
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.repository.ConnectRepository
+import co.kr.tnt.feature.trainer.invite.R
import co.kr.tnt.trainer.invite.TrainerInviteContract.TrainerInviteSideEffect
import co.kr.tnt.trainer.invite.TrainerInviteContract.TrainerInviteUiEvent
import co.kr.tnt.trainer.invite.TrainerInviteContract.TrainerInviteUiState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -23,7 +26,11 @@ internal class TrainerInviteViewModel @Inject constructor(
TrainerInviteUiEvent.OnClickSkip -> navigateToHome()
is TrainerInviteUiEvent.OnClickCode -> {
sendEffect(TrainerInviteSideEffect.CopyToClipBoard(event.code))
- sendEffect(TrainerInviteSideEffect.ShowToast("μ½λκ° λ³΅μ¬λμμ΄μ!"))
+ sendEffect(
+ TrainerInviteSideEffect.ShowToast(
+ DisplayText.Resource(R.string.code_is_copied),
+ ),
+ )
}
}
}
@@ -39,7 +46,11 @@ internal class TrainerInviteViewModel @Inject constructor(
}.onSuccess { result ->
updateState { copy(inviteCode = result.invitationCode) }
}.onFailure {
- sendEffect(TrainerInviteSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TrainerInviteSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
@@ -51,7 +62,11 @@ internal class TrainerInviteViewModel @Inject constructor(
}.onSuccess { result ->
updateState { copy(inviteCode = result.invitationCode) }
}.onFailure {
- sendEffect(TrainerInviteSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(
+ TrainerInviteSideEffect.ShowToast(
+ DisplayText.Resource(core_failed_to_server_request),
+ ),
+ )
}
}
}
diff --git a/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMemberContract.kt b/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMemberContract.kt
index 09337727..4c200fa8 100644
--- a/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMemberContract.kt
+++ b/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMemberContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.domain.model.MemberInfo
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
internal class TrainerMemberContract {
data class TrainerMemberUiState(
@@ -16,6 +17,6 @@ internal class TrainerMemberContract {
sealed interface TrainerMemberSideEffect : UiSideEffect {
data object NavigateToInvite : TrainerMemberSideEffect
- data class ShowToast(val message: String) : TrainerMemberSideEffect
+ data class ShowToast(val message: DisplayText) : TrainerMemberSideEffect
}
}
diff --git a/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersScreen.kt b/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersScreen.kt
index 9298a7a3..21602fec 100644
--- a/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersScreen.kt
+++ b/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersScreen.kt
@@ -20,6 +20,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@@ -27,10 +28,11 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
-import co.kr.tnt.core.designsystem.R
+import co.kr.tnt.core.designsystem.R.drawable.img_default
import co.kr.tnt.designsystem.component.card.TnTMemberProfileCard
import co.kr.tnt.designsystem.theme.TnTTheme
import co.kr.tnt.domain.model.MemberInfo
+import co.kr.tnt.feature.trainer.members.R
import co.kr.tnt.navigation.model.ScreenMode
import co.kr.tnt.trainer.members.TrainerMemberContract.TrainerMemberUiState
import co.kr.tnt.ui.component.TnTCountTopBar
@@ -65,7 +67,7 @@ private fun TrainerMembersScreen(
) {
Column(modifier = Modifier.fillMaxSize()) {
TnTCountTopBar(
- title = "λ΄ νμ",
+ title = stringResource(R.string.my_member),
count = state.memberList.size,
trailingComponent = {
MemberInviteButton(onClickInviteButton)
@@ -104,7 +106,7 @@ private fun MemberInviteButton(
),
) {
Text(
- text = "νμ μ΄λνκΈ°",
+ text = stringResource(R.string.invite_member),
color = TnTTheme.colors.neutralColors.Neutral600,
style = TnTTheme.typography.label2Medium,
overflow = TextOverflow.Ellipsis,
@@ -121,14 +123,14 @@ private fun EmptyMemberList(modifier: Modifier = Modifier) {
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
- text = "μμ§ μ°κ²°λ νμμ΄ μμ΄μ",
+ text = stringResource(R.string.no_connected_member_yet),
color = TnTTheme.colors.neutralColors.Neutral600,
style = TnTTheme.typography.body2Bold,
textAlign = TextAlign.Center,
)
Spacer(Modifier.height(4.dp))
Text(
- text = "μΆκ° λ²νΌμ λλ¬ νμμ μΆκ°ν΄ 보μΈμ",
+ text = stringResource(R.string.press_add_button_to_add_member),
color = TnTTheme.colors.neutralColors.Neutral400,
style = TnTTheme.typography.label1Medium,
textAlign = TextAlign.Center,
@@ -141,8 +143,8 @@ private fun MemberList(member: MemberInfo) {
val painter = rememberAsyncImagePainter(
model = ImageRequest.Builder(LocalContext.current)
.data(member.profileUrl)
- .placeholder(R.drawable.img_default)
- .error(R.drawable.img_default)
+ .placeholder(img_default)
+ .error(img_default)
.build(),
)
// TODO : νμ μμΈ νμ΄μ§ μ°κ²° (λ°°ν¬ μ΄ν)
diff --git a/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersViewModel.kt b/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersViewModel.kt
index 49afdfd8..262d7d86 100644
--- a/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersViewModel.kt
+++ b/feature/trainer/members/src/main/java/co/kr/tnt/trainer/members/TrainerMembersViewModel.kt
@@ -1,11 +1,13 @@
package co.kr.tnt.trainer.members
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.repository.TrainerRepository
import co.kr.tnt.trainer.members.TrainerMemberContract.TrainerMemberSideEffect
import co.kr.tnt.trainer.members.TrainerMemberContract.TrainerMemberUiEvent
import co.kr.tnt.trainer.members.TrainerMemberContract.TrainerMemberUiState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -32,7 +34,7 @@ internal class TrainerMembersViewModel @Inject constructor(
}.onSuccess { members ->
updateState { copy(memberList = members) }
}.onFailure {
- sendEffect(TrainerMemberSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(TrainerMemberSideEffect.ShowToast(DisplayText.Resource(core_failed_to_server_request)))
}
}
}
diff --git a/feature/trainer/members/src/main/res/values/strings.xml b/feature/trainer/members/src/main/res/values/strings.xml
new file mode 100644
index 00000000..7b516f9d
--- /dev/null
+++ b/feature/trainer/members/src/main/res/values/strings.xml
@@ -0,0 +1,7 @@
+
+
+ λ΄ νμ
+ νμ μ΄λνκΈ°
+ μμ§ μ°κ²°λ νμμ΄ μμ΄μ
+ μΆκ° λ²νΌμ λλ¬ νμμ μΆκ°ν΄ 보μΈμ
+
diff --git a/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageContract.kt b/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageContract.kt
index 68521a35..767717b4 100644
--- a/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageContract.kt
+++ b/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.domain.model.User
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
internal class TrainerMyPageContract {
data class TrainerMyPageUiState(
@@ -42,6 +43,6 @@ internal class TrainerMyPageContract {
data class NavigateToWebView(val url: String) : TrainerMyPageSideEffect
data object NavigateToOpenSourceLicense : TrainerMyPageSideEffect
data class RequestPermission(val isExplicitlyDenied: Boolean) : TrainerMyPageSideEffect
- data class ShowToast(val message: String) : TrainerMyPageSideEffect
+ data class ShowToast(val message: DisplayText) : TrainerMyPageSideEffect
}
}
diff --git a/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageScreen.kt b/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageScreen.kt
index bd1c0b91..f7a43d1b 100644
--- a/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageScreen.kt
+++ b/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageScreen.kt
@@ -32,6 +32,18 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import co.kr.tnt.core.ui.R.string.core_app_push_notification
+import co.kr.tnt.core.ui.R.string.core_app_version
+import co.kr.tnt.core.ui.R.string.core_cancel
+import co.kr.tnt.core.ui.R.string.core_delete_account
+import co.kr.tnt.core.ui.R.string.core_logout
+import co.kr.tnt.core.ui.R.string.core_logout_complete_title
+import co.kr.tnt.core.ui.R.string.core_logout_content
+import co.kr.tnt.core.ui.R.string.core_logout_title
+import co.kr.tnt.core.ui.R.string.core_ok
+import co.kr.tnt.core.ui.R.string.core_open_source_license
+import co.kr.tnt.core.ui.R.string.core_privacy_policy
+import co.kr.tnt.core.ui.R.string.core_terms_of_service
import co.kr.tnt.designsystem.component.TnTIconPopupDialog
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.TnTSingleButtonPopupDialog
@@ -59,7 +71,6 @@ import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.google.android.gms.oss.licenses.OssLicensesMenuActivity
import co.kr.tnt.core.designsystem.R as designSystemR
-import co.kr.tnt.core.ui.R as coreR
@OptIn(ExperimentalPermissionsApi::class)
@Composable
@@ -108,7 +119,7 @@ internal fun TrainerMyPageRoute(
when (effect) {
TrainerMyPageSideEffect.NavigateToLogin -> navigateToLogin()
is TrainerMyPageSideEffect.NavigateToWebView -> navigateToWebView(effect.url)
- is TrainerMyPageSideEffect.ShowToast -> toast.show(effect.message)
+ is TrainerMyPageSideEffect.ShowToast -> toast.show(effect.message.asString(context))
is TrainerMyPageSideEffect.RequestPermission -> {
if (effect.isExplicitlyDenied) {
@@ -175,12 +186,12 @@ private fun TrainerMyPageScreen(
horizontalArrangement = Arrangement.Center,
) {
ManagementMemberCount(
- title = "κ΄λ¦¬ μ€μΈ νμ",
+ title = stringResource(R.string.managing_member),
count = state.user.memberCounts.activeCount,
)
Spacer(modifier = Modifier.width(8.dp))
ManagementMemberCount(
- title = "ν¨κ» νλ νμ",
+ title = stringResource(R.string.worked_together_member),
count = state.user.memberCounts.totalCount,
)
}
@@ -192,7 +203,7 @@ private fun TrainerMyPageScreen(
.padding(20.dp),
) {
TnTMyPageButton(
- text = stringResource(coreR.string.app_push_notification),
+ text = stringResource(core_app_push_notification),
verticalPadding = 12.dp,
enabled = false,
trailingComponent = {
@@ -209,17 +220,17 @@ private fun TrainerMyPageScreen(
.padding(vertical = 12.dp),
) {
TnTMyPageButton(
- text = stringResource(coreR.string.terms_of_service),
+ text = stringResource(core_terms_of_service),
onClick = onClickTermsOfService,
verticalPadding = 8.dp,
)
TnTMyPageButton(
- text = stringResource(coreR.string.privacy_policy),
+ text = stringResource(core_privacy_policy),
onClick = onClickPrivacy,
verticalPadding = 8.dp,
)
TnTMyPageButton(
- text = stringResource(coreR.string.app_version),
+ text = stringResource(core_app_version),
verticalPadding = 12.dp,
enabled = false,
onClick = onTogglePushNotification,
@@ -232,7 +243,7 @@ private fun TrainerMyPageScreen(
},
)
TnTMyPageButton(
- text = stringResource(coreR.string.open_source_license),
+ text = stringResource(core_open_source_license),
onClick = onClickOpenSourceLicense,
verticalPadding = 8.dp,
)
@@ -245,12 +256,12 @@ private fun TrainerMyPageScreen(
.padding(vertical = 12.dp),
) {
TnTMyPageButton(
- text = stringResource(coreR.string.logout),
+ text = stringResource(core_logout),
onClick = onClickLogout,
verticalPadding = 8.dp,
)
TnTMyPageButton(
- text = stringResource(coreR.string.delete_account),
+ text = stringResource(core_delete_account),
onClick = onClickDeleteAccount,
verticalPadding = 8.dp,
)
@@ -308,10 +319,10 @@ private fun Dialog(
DialogState.NONE -> Unit
DialogState.LOGOUT_CONFIRM -> {
TnTIconPopupDialog(
- title = stringResource(coreR.string.logout_title),
- content = stringResource(coreR.string.logout_content),
- leftButtonText = stringResource(coreR.string.cancel),
- rightButtonText = stringResource(coreR.string.ok),
+ title = stringResource(core_logout_title),
+ content = stringResource(core_logout_content),
+ leftButtonText = stringResource(core_cancel),
+ rightButtonText = stringResource(core_ok),
onLeftButtonClick = onDismissDialog,
onRightButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -320,9 +331,9 @@ private fun Dialog(
DialogState.LOGOUT -> {
TnTSingleButtonPopupDialog(
- title = stringResource(coreR.string.logout_complete_title),
- content = stringResource(coreR.string.logout_content),
- buttonText = stringResource(coreR.string.ok),
+ title = stringResource(core_logout_complete_title),
+ content = stringResource(core_logout_content),
+ buttonText = stringResource(core_ok),
cancelable = false,
onButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -333,8 +344,8 @@ private fun Dialog(
TnTIconPopupDialog(
title = stringResource(R.string.delete_account_title),
content = stringResource(R.string.delete_account_content),
- leftButtonText = stringResource(coreR.string.cancel),
- rightButtonText = stringResource(coreR.string.ok),
+ leftButtonText = stringResource(core_cancel),
+ rightButtonText = stringResource(core_ok),
onLeftButtonClick = onDismissDialog,
onRightButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
@@ -345,7 +356,7 @@ private fun Dialog(
TnTSingleButtonPopupDialog(
title = stringResource(R.string.delete_account_complete_title),
content = stringResource(R.string.delete_account_complete_content),
- buttonText = stringResource(coreR.string.ok),
+ buttonText = stringResource(core_ok),
cancelable = false,
onButtonClick = onClickConfirm,
onDismiss = onDismissDialog,
diff --git a/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageViewModel.kt b/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageViewModel.kt
index b8537ac7..eb859305 100644
--- a/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageViewModel.kt
+++ b/feature/trainer/mypage/src/main/java/co/kr/tnt/trainer/mypage/TrainerMyPageViewModel.kt
@@ -1,16 +1,19 @@
package co.kr.tnt.trainer.mypage
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.repository.LoginRepository
import co.kr.tnt.domain.repository.SettingRepository
import co.kr.tnt.domain.repository.TrainerRepository
import co.kr.tnt.domain.utils.AppUrls
+import co.kr.tnt.feature.trainer.mypage.R
import co.kr.tnt.login.kakao.KakaoLoginSdk
import co.kr.tnt.trainer.mypage.TrainerMyPageContract.TrainerMyPageSideEffect
import co.kr.tnt.trainer.mypage.TrainerMyPageContract.TrainerMyPageUiEvent
import co.kr.tnt.trainer.mypage.TrainerMyPageContract.TrainerMyPageUiState
import co.kr.tnt.trainer.mypage.TrainerMyPageContract.TrainerMyPageUiState.DialogState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@@ -31,7 +34,7 @@ internal class TrainerMyPageViewModel @Inject constructor(
}.onSuccess { user ->
updateState { copy(user = user) }
}.onFailure {
- sendEffect(TrainerMyPageSideEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(TrainerMyPageSideEffect.ShowToast(DisplayText.Resource(core_failed_to_server_request)))
}
settingRepository.isEnablePushNotification()
@@ -128,7 +131,11 @@ internal class TrainerMyPageViewModel @Inject constructor(
}.onSuccess {
updateState { copy(dialogState = DialogState.LOGOUT) }
}.onFailure {
- sendEffect(TrainerMyPageSideEffect.ShowToast("λ‘κ·Έμμμ μ€ν¨νμμ΅λλ€."))
+ sendEffect(
+ TrainerMyPageSideEffect.ShowToast(
+ DisplayText.Resource(R.string.failed_logout),
+ ),
+ )
}.also {
updateState { copy(isLoading = false) }
}
@@ -144,7 +151,7 @@ internal class TrainerMyPageViewModel @Inject constructor(
}.onSuccess {
updateState { copy(dialogState = DialogState.DELETE_ACCOUNT) }
}.onFailure {
- sendEffect(TrainerMyPageSideEffect.ShowToast("νν΄μ μ€ν¨νμμ΅λλ€."))
+ sendEffect(TrainerMyPageSideEffect.ShowToast(DisplayText.Resource(R.string.failed_delete_account)))
}.also {
updateState { copy(isLoading = false) }
}
diff --git a/feature/trainer/mypage/src/main/res/values/strings.xml b/feature/trainer/mypage/src/main/res/values/strings.xml
index 190d9935..63e2dff2 100644
--- a/feature/trainer/mypage/src/main/res/values/strings.xml
+++ b/feature/trainer/mypage/src/main/res/values/strings.xml
@@ -5,4 +5,8 @@
ν¨κ» νλ νμλ€μ λν λ°μ΄ν°κ° μ¬λΌμ Έμ!
κ³μ νν΄κ° μλ£λμμ΄μ
λ€μμ λ νλ°μ μΈ μΌλ―Έλ‘ λ€μ λ§λμ! π£
+ νν΄μ μ€ν¨νμμ΅λλ€.
+ λ‘κ·Έμμμ μ€ν¨νμμ΅λλ€.
+ κ΄λ¦¬ μ€μΈ νμ
+ ν¨κ» νλ νμ
diff --git a/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationContract.kt b/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationContract.kt
index dbaf002f..8afe4443 100644
--- a/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationContract.kt
+++ b/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationContract.kt
@@ -4,6 +4,7 @@ import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
import co.kr.tnt.ui.model.NotificationState
+import co.kr.tnt.ui.resource.DisplayText
internal class TrainerNotificationContract {
data class TrainerNotificationUiState(
@@ -18,7 +19,7 @@ internal class TrainerNotificationContract {
}
sealed interface TrainerNotificationEffect : UiSideEffect {
- data class ShowToast(val message: String) : TrainerNotificationEffect
+ data class ShowToast(val message: DisplayText) : TrainerNotificationEffect
data object NavigateToPrevious : TrainerNotificationEffect
data object NavigateToConnect : TrainerNotificationEffect
}
diff --git a/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationScreen.kt b/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationScreen.kt
index f146b236..53f11f85 100644
--- a/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationScreen.kt
+++ b/feature/trainer/notification/src/main/java/co/kr/tnt/trainer/notification/TrainerNotificationScreen.kt
@@ -13,10 +13,13 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
+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
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import co.kr.tnt.core.ui.R.string.core_no_recent_notifications
+import co.kr.tnt.core.ui.R.string.core_notification
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
import co.kr.tnt.designsystem.component.notification.TnTNotification
import co.kr.tnt.designsystem.component.notification.model.NotificationIcon
@@ -26,7 +29,6 @@ import co.kr.tnt.trainer.notification.TrainerNotificationContract.TrainerNotific
import co.kr.tnt.trainer.notification.TrainerNotificationContract.TrainerNotificationUiEvent
import co.kr.tnt.trainer.notification.TrainerNotificationContract.TrainerNotificationUiState
import co.kr.tnt.ui.model.NotificationState
-import co.kr.tnt.core.ui.R as uiResource
@Composable
internal fun TrainerNotificationRoute(
@@ -34,6 +36,7 @@ internal fun TrainerNotificationRoute(
navigateToConnect: (trainerId: String, traineeId: String) -> Unit,
viewModel: TrainerNotificationViewModel = hiltViewModel(),
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
@@ -52,7 +55,7 @@ internal fun TrainerNotificationRoute(
uiState.traineeId,
)
- is TrainerNotificationEffect.ShowToast -> snackbar.show(effect.message)
+ is TrainerNotificationEffect.ShowToast -> snackbar.show(effect.message.asString(context))
}
}
}
@@ -67,7 +70,7 @@ private fun TrainerNotificationScreen(
Scaffold(
topBar = {
TnTTopBarWithBackButton(
- title = stringResource(uiResource.string.notification),
+ title = stringResource(core_notification),
onBackClick = onClickBack,
showStoke = true,
)
@@ -85,7 +88,7 @@ private fun TrainerNotificationScreen(
contentAlignment = Alignment.Center,
) {
Text(
- text = stringResource(uiResource.string.no_recent_notifications),
+ text = stringResource(core_no_recent_notifications),
style = TnTTheme.typography.label1Medium,
color = TnTTheme.colors.neutralColors.Neutral400,
)
diff --git a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerProfileSetupPage.kt b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerProfileSetupPage.kt
index 3744723d..abe5c358 100644
--- a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerProfileSetupPage.kt
+++ b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerProfileSetupPage.kt
@@ -25,6 +25,9 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_name
+import co.kr.tnt.core.ui.R.string.core_next
+import co.kr.tnt.core.ui.R.string.core_text_length_and_format_warning
import co.kr.tnt.designsystem.component.TnTLabeledTextFieldWithCounter
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.TnTTopBarWithBackButton
@@ -38,7 +41,6 @@ import co.kr.tnt.ui.extensions.clearFocusOnTap
import co.kr.tnt.ui.model.DefaultUserProfile
import coil.compose.rememberAsyncImagePainter
import coil.request.ImageRequest
-import co.kr.tnt.core.ui.R as coreR
private const val MAX_LENGTH = 15
@@ -102,7 +104,7 @@ internal fun TrainerProfileSetupPage(
)
Spacer(Modifier.padding(top = 60.dp))
TnTLabeledTextFieldWithCounter(
- title = stringResource(coreR.string.name),
+ title = stringResource(core_name),
value = state.name,
onValueChange = { newValue ->
onChangeName(newValue)
@@ -113,11 +115,11 @@ internal fun TrainerProfileSetupPage(
isSingleLine = true,
showWarning = state.isNameValid.not(),
isRequired = true,
- warningMessage = stringResource(coreR.string.text_length_and_format_warning, MAX_LENGTH),
+ warningMessage = stringResource(core_text_length_and_format_warning, MAX_LENGTH),
)
}
TnTBottomButton(
- text = stringResource(coreR.string.next),
+ text = stringResource(core_next),
modifier = Modifier.align(Alignment.BottomCenter),
enabled = state.name.isNotBlank() && state.isNameValid,
onClick = onClickNext,
diff --git a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpCompletePage.kt b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpCompletePage.kt
index 85a5fe12..a3746df7 100644
--- a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpCompletePage.kt
+++ b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpCompletePage.kt
@@ -20,6 +20,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign.Companion.Center
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
+import co.kr.tnt.core.ui.R.string.core_start
import co.kr.tnt.designsystem.component.TnTProfileImage
import co.kr.tnt.designsystem.component.button.TnTBottomButton
import co.kr.tnt.designsystem.theme.TnTTheme
@@ -34,7 +35,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.File
-import co.kr.tnt.core.ui.R as uiResource
@Composable
internal fun TrainerSignUpCompletePage(
@@ -87,7 +87,7 @@ internal fun TrainerSignUpCompletePage(
)
}
TnTBottomButton(
- text = stringResource(uiResource.string.start),
+ text = stringResource(core_start),
onClick = throttled {
coroutineScope.launch {
val imageFile = withContext(Dispatchers.IO) {
diff --git a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpContract.kt b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpContract.kt
index 200d650b..98c9702c 100644
--- a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpContract.kt
+++ b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpContract.kt
@@ -4,6 +4,7 @@ import android.net.Uri
import co.kr.tnt.ui.base.UiEvent
import co.kr.tnt.ui.base.UiSideEffect
import co.kr.tnt.ui.base.UiState
+import co.kr.tnt.ui.resource.DisplayText
import java.io.File
private const val MAX_LENGTH = 15
@@ -37,7 +38,7 @@ internal class TrainerSignUpContract {
}
sealed interface TrainerSignUpEffect : UiSideEffect {
- data class ShowToast(val message: String) : TrainerSignUpEffect
+ data class ShowToast(val message: DisplayText) : TrainerSignUpEffect
data object NavigateToBack : TrainerSignUpEffect
data object NavigateToConnect : TrainerSignUpEffect
}
diff --git a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpScreen.kt b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpScreen.kt
index 262e7dde..1183584a 100644
--- a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpScreen.kt
+++ b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpScreen.kt
@@ -4,6 +4,7 @@ import android.net.Uri
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
+import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import co.kr.tnt.designsystem.snackbar.LocalSnackbar
@@ -22,6 +23,7 @@ internal fun TrainerSignUpRoute(
navigateToInvite: (ScreenMode) -> Unit,
viewModel: TrainerSignUpViewModel = hiltViewModel(),
) {
+ val context = LocalContext.current
val snackbar = LocalSnackbar.current
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
@@ -49,7 +51,9 @@ internal fun TrainerSignUpRoute(
when (effect) {
TrainerSignUpContract.TrainerSignUpEffect.NavigateToBack -> navigateToPrevious()
TrainerSignUpContract.TrainerSignUpEffect.NavigateToConnect -> navigateToInvite(ScreenMode.SKIP)
- is TrainerSignUpContract.TrainerSignUpEffect.ShowToast -> snackbar.show(effect.message)
+ is TrainerSignUpContract.TrainerSignUpEffect.ShowToast -> snackbar.show(
+ effect.message.asString(context),
+ )
}
}
}
diff --git a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpViewModel.kt b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpViewModel.kt
index 7e76a7eb..5403de87 100644
--- a/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpViewModel.kt
+++ b/feature/trainer/signup/src/main/java/co/kr/tnt/trainer/signup/TrainerSignUpViewModel.kt
@@ -2,6 +2,7 @@ package co.kr.tnt.trainer.signup
import android.net.Uri
import androidx.lifecycle.viewModelScope
+import co.kr.tnt.core.ui.R.string.core_failed_to_server_request
import co.kr.tnt.domain.model.User
import co.kr.tnt.domain.model.trainer.TrainerManagementMemberCount
import co.kr.tnt.domain.repository.SignUpRepository
@@ -10,6 +11,7 @@ import co.kr.tnt.trainer.signup.TrainerSignUpContract.TrainerSignUpPage
import co.kr.tnt.trainer.signup.TrainerSignUpContract.TrainerSignUpUiEvent
import co.kr.tnt.trainer.signup.TrainerSignUpContract.TrainerSignUpUiState
import co.kr.tnt.ui.base.BaseViewModel
+import co.kr.tnt.ui.resource.DisplayText
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -65,7 +67,7 @@ internal class TrainerSignUpViewModel @Inject constructor(
}.onSuccess {
sendEffect(TrainerSignUpEffect.NavigateToConnect)
}.onFailure {
- sendEffect(TrainerSignUpEffect.ShowToast("μλ² μμ²μ μ€ν¨νμ΄μ"))
+ sendEffect(TrainerSignUpEffect.ShowToast(DisplayText.Resource(core_failed_to_server_request)))
}.also {
updateState { copy(isLoading = false) }
}