diff --git a/core/ui/src/main/res/drawable/ic_24_change.xml b/core/ui/src/main/res/drawable/ic_24_change.xml
new file mode 100644
index 00000000..884f8b89
--- /dev/null
+++ b/core/ui/src/main/res/drawable/ic_24_change.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/data/auth/src/main/java/com/yapp/ndgl/data/auth/local/LocalAuthDataSource.kt b/data/auth/src/main/java/com/yapp/ndgl/data/auth/local/LocalAuthDataSource.kt
index ac9561ff..0e630920 100644
--- a/data/auth/src/main/java/com/yapp/ndgl/data/auth/local/LocalAuthDataSource.kt
+++ b/data/auth/src/main/java/com/yapp/ndgl/data/auth/local/LocalAuthDataSource.kt
@@ -45,15 +45,28 @@ class LocalAuthDataSource @Inject constructor(
}
}
+ suspend fun getNickname(): String = dataStore.data
+ .handleException()
+ .map { preferences -> preferences[NICKNAME_KEY] ?: "" }
+ .first()
+
+ suspend fun setNickname(nickname: String) {
+ dataStore.edit { preferences ->
+ preferences[NICKNAME_KEY] = nickname
+ }
+ }
+
suspend fun clearSession() {
dataStore.edit { preferences ->
preferences.remove(ACCESS_TOKEN_KEY)
preferences.remove(UUID_KEY)
+ preferences.remove(NICKNAME_KEY)
}
}
private companion object {
private val ACCESS_TOKEN_KEY = stringPreferencesKey("access_token")
private val UUID_KEY = stringPreferencesKey("uuid")
+ private val NICKNAME_KEY = stringPreferencesKey("nickname")
}
}
diff --git a/data/auth/src/main/java/com/yapp/ndgl/data/auth/repository/AuthRepository.kt b/data/auth/src/main/java/com/yapp/ndgl/data/auth/repository/AuthRepository.kt
index 1d8c6d17..447577cf 100644
--- a/data/auth/src/main/java/com/yapp/ndgl/data/auth/repository/AuthRepository.kt
+++ b/data/auth/src/main/java/com/yapp/ndgl/data/auth/repository/AuthRepository.kt
@@ -39,6 +39,7 @@ class AuthRepository @Inject constructor(
localAuthDataSource.setAccessToken(response.accessToken)
localAuthDataSource.setUuid(response.uuid)
+ localAuthDataSource.setNickname(response.nickname)
return isFirstUser
}
@@ -66,5 +67,7 @@ class AuthRepository @Inject constructor(
}
}
+ suspend fun getNickname(): String = localAuthDataSource.getNickname()
+
suspend fun getIdentifierCode(): String = localAuthDataSource.getUuid()
}
diff --git a/feature/home/src/main/java/com/yapp/ndgl/feature/home/main/HomeViewModel.kt b/feature/home/src/main/java/com/yapp/ndgl/feature/home/main/HomeViewModel.kt
index 0a9ca209..de0307e1 100644
--- a/feature/home/src/main/java/com/yapp/ndgl/feature/home/main/HomeViewModel.kt
+++ b/feature/home/src/main/java/com/yapp/ndgl/feature/home/main/HomeViewModel.kt
@@ -3,6 +3,7 @@ package com.yapp.ndgl.feature.home.main
import androidx.lifecycle.viewModelScope
import com.yapp.ndgl.core.base.BaseViewModel
import com.yapp.ndgl.core.util.suspendRunCatching
+import com.yapp.ndgl.data.auth.repository.AuthRepository
import com.yapp.ndgl.data.travel.model.TravelProgram
import com.yapp.ndgl.data.travel.model.TravelTemplateSummary
import com.yapp.ndgl.data.travel.repository.TravelProgramRepository
@@ -21,6 +22,7 @@ import javax.inject.Inject
@HiltViewModel
class HomeViewModel @Inject constructor(
+ private val authRepository: AuthRepository,
private val travelProgramRepository: TravelProgramRepository,
private val travelTemplateRepository: TravelTemplateRepository,
private val userTravelRepository: UserTravelRepository,
@@ -28,10 +30,18 @@ class HomeViewModel @Inject constructor(
initialState = HomeState(),
) {
init {
+ loadUserName()
loadHomeContents()
subscribeToTravelCreatedEvent()
}
+ private fun loadUserName() {
+ viewModelScope.launch {
+ val nickname = authRepository.getNickname()
+ reduce { copy(userName = nickname) }
+ }
+ }
+
private fun loadHomeContents() {
loadMyTravel()
loadPopularTemplates()
diff --git a/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/main/CurrencyCalculatorSection.kt b/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/main/CurrencyCalculatorSection.kt
index faaa6a3e..aa971f9e 100644
--- a/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/main/CurrencyCalculatorSection.kt
+++ b/feature/travel-helper/src/main/java/com/yapp/ndgl/feature/travelhelper/main/CurrencyCalculatorSection.kt
@@ -41,6 +41,7 @@ import androidx.compose.ui.text.input.TransformedText
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.yapp.ndgl.core.ui.theme.NDGLTheme
import com.yapp.ndgl.feature.travelhelper.R
@@ -113,7 +114,7 @@ internal fun CurrencyCalculatorSection(
contentAlignment = Alignment.Center,
) {
Icon(
- imageVector = ImageVector.vectorResource(R.drawable.ic_24_updown),
+ imageVector = ImageVector.vectorResource(CoreR.drawable.ic_24_change),
contentDescription = null,
modifier = Modifier.size(24.dp),
tint = NDGLTheme.colors.black900,
@@ -173,7 +174,7 @@ private fun CurrencyCard(
) {
ForeignCurrencyLeft(
modifier = Modifier.wrapContentWidth(),
- showCurrencySelector = isEditable,
+ isEditable = isEditable,
flagEmoji = flagEmoji,
currencyName = currencyName,
currencyCode = currencyCode,
@@ -194,7 +195,7 @@ private fun CurrencyCard(
@Composable
private fun ForeignCurrencyLeft(
modifier: Modifier,
- showCurrencySelector: Boolean,
+ isEditable: Boolean,
flagEmoji: String,
currencyName: String,
currencyCode: String,
@@ -211,7 +212,7 @@ private fun ForeignCurrencyLeft(
shape = RoundedCornerShape(topStart = 4.dp, bottomStart = 4.dp),
)
.then(
- if (showCurrencySelector) {
+ if (isEditable) {
Modifier.clickable(
interactionSource = null,
indication = ripple(),
@@ -241,7 +242,7 @@ private fun ForeignCurrencyLeft(
Text(
text = currencyName,
modifier = Modifier.fillMaxWidth(),
- color = NDGLTheme.colors.black800,
+ color = if (isEditable) NDGLTheme.colors.black800 else NDGLTheme.colors.black500,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
style = NDGLTheme.typography.bodyLgSemiBold,
@@ -249,12 +250,12 @@ private fun ForeignCurrencyLeft(
Text(
text = currencyCode,
modifier = Modifier.fillMaxWidth(),
- color = NDGLTheme.colors.black400,
+ color = if (isEditable) NDGLTheme.colors.black400 else NDGLTheme.colors.black300,
style = NDGLTheme.typography.bodyMdMedium,
)
}
}
- if (showCurrencySelector) {
+ if (isEditable) {
Icon(
imageVector = ImageVector.vectorResource(CoreR.drawable.ic_24_chevron_down),
contentDescription = null,
@@ -265,7 +266,7 @@ private fun ForeignCurrencyLeft(
Box(modifier = Modifier.size(24.dp))
}
}
- if (showCurrencySelector) {
+ if (isEditable) {
DropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
@@ -352,10 +353,17 @@ private fun ForeignCurrencyRight(
onValueChange = onInputChange,
modifier = Modifier.fillMaxWidth(),
readOnly = isEditable.not(),
- textStyle = NDGLTheme.typography.bodyLgSemiBold.copy(
- color = NDGLTheme.colors.black800,
- textAlign = TextAlign.End,
- ),
+ textStyle = if (isEditable) {
+ NDGLTheme.typography.bodyLgSemiBold.copy(
+ color = NDGLTheme.colors.green500,
+ textAlign = TextAlign.End,
+ )
+ } else {
+ NDGLTheme.typography.bodyLgMedium.copy(
+ color = NDGLTheme.colors.black500,
+ textAlign = TextAlign.End,
+ )
+ },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Decimal),
singleLine = true,
cursorBrush = SolidColor(NDGLTheme.colors.green500),
@@ -389,7 +397,7 @@ private fun ForeignCurrencyRight(
Text(
text = "$displayInput $currencyLabel",
modifier = Modifier.fillMaxWidth(),
- color = NDGLTheme.colors.black400,
+ color = if (isEditable) NDGLTheme.colors.black400 else NDGLTheme.colors.black300,
textAlign = TextAlign.End,
overflow = TextOverflow.Ellipsis,
maxLines = 1,
@@ -437,3 +445,37 @@ private class ThousandSeparatorTransformation : VisualTransformation {
return TransformedText(AnnotatedString(formatted), offsetMapping)
}
}
+
+@Preview(showBackground = true)
+@Composable
+private fun CurrencyCalculatorSectionPreview() {
+ NDGLTheme {
+ CurrencyCalculatorSection(
+ exchangeRateInfo = ExchangeRateInfo(
+ topCurrency = TravelHelperState.CurrencyInfo(
+ currencyCode = "JPY",
+ currencyLabel = "엔",
+ countryName = "일본",
+ flagEmoji = "\uD83C\uDDEF\uD83C\uDDF5",
+ ),
+ bottomCurrency = TravelHelperState.CurrencyInfo(
+ currencyCode = "KRW",
+ currencyLabel = "원",
+ countryName = "대한민국",
+ flagEmoji = "\uD83C\uDDF0\uD83C\uDDF7",
+ ),
+ rate = 9.5,
+ rateDate = java.time.LocalDate.of(2025, 1, 1),
+ ),
+ currencyInput = "1000",
+ convertedAmount = 9500.0,
+ availableCurrencies = persistentListOf(
+ CurrencyOption(currencyCode = "JPY", countryName = "일본"),
+ CurrencyOption(currencyCode = "KRW", countryName = "대한민국"),
+ ),
+ onInputChange = {},
+ onSwap = {},
+ onCurrencySelect = {},
+ )
+ }
+}
diff --git a/feature/travel-helper/src/main/res/drawable/ic_24_updown.xml b/feature/travel-helper/src/main/res/drawable/ic_24_updown.xml
deleted file mode 100644
index 7fc8aabf..00000000
--- a/feature/travel-helper/src/main/res/drawable/ic_24_updown.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-