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 @@ - - - -