diff --git a/app/src/main/java/com/kiero/core/designsystem/component/chip/action/KieroCoinAction.kt b/app/src/main/java/com/kiero/core/designsystem/component/chip/action/KieroCoinAction.kt index 1293327c..e31cee6b 100644 --- a/app/src/main/java/com/kiero/core/designsystem/component/chip/action/KieroCoinAction.kt +++ b/app/src/main/java/com/kiero/core/designsystem/component/chip/action/KieroCoinAction.kt @@ -3,6 +3,7 @@ package com.kiero.core.designsystem.component.chip.action import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.size import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -30,7 +31,7 @@ class KieroCoinAction( ) : ChipAction { @Composable override fun invoke(modifier: Modifier) { - val coin = painterResource(id = R.drawable.img_kid_coin) + val coin = painterResource(id = R.drawable.img_coin) val targetColor = when { !isEnabled -> KieroTheme.colors.gray500 @@ -58,6 +59,7 @@ class KieroCoinAction( painter = coin, contentDescription = null, modifier = Modifier + .size(20.dp) .forcePixelToDp(coin) ) diff --git a/app/src/main/java/com/kiero/presentation/auth/AuthScreen.kt b/app/src/main/java/com/kiero/presentation/auth/AuthScreen.kt index 2e873653..add25316 100644 --- a/app/src/main/java/com/kiero/presentation/auth/AuthScreen.kt +++ b/app/src/main/java/com/kiero/presentation/auth/AuthScreen.kt @@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -59,7 +60,7 @@ fun AuthScreen( modifier: Modifier = Modifier, onEasterEggClick: () -> Unit = {}, ) { - val logoPainter = painterResource(id = R.drawable.img_auth_app_logo) + val logoPainter = painterResource(id = R.drawable.ic_logo) Column( modifier = modifier @@ -86,7 +87,9 @@ fun AuthScreen( Image( painter = logoPainter, contentDescription = null, - modifier = Modifier.forcePixelToDp(logoPainter) + modifier = Modifier + .size(width = 300.dp, height = 63.dp) + .forcePixelToDp(logoPainter) ) Spacer(modifier = Modifier.weight(1f)) diff --git a/app/src/main/java/com/kiero/presentation/auth/component/AuthButton.kt b/app/src/main/java/com/kiero/presentation/auth/component/AuthButton.kt index 80997765..e6c7ddc0 100644 --- a/app/src/main/java/com/kiero/presentation/auth/component/AuthButton.kt +++ b/app/src/main/java/com/kiero/presentation/auth/component/AuthButton.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.material3.ripple @@ -50,7 +51,9 @@ fun AuthButton( Image( painter = painter, contentDescription = null, - modifier = Modifier.forcePixelToDp(painter) + modifier = Modifier + .size(50.dp) + .forcePixelToDp(painter) ) Text( @@ -69,7 +72,7 @@ private fun AuthButtonPreview() { KieroTheme { AuthButton( text = "부모님으로 시작하기", - icon = com.kiero.R.drawable.img_auth_parent_goblin_small, + icon = com.kiero.R.drawable.img_auth_parent_goblin, onClickButton = {} ) } diff --git a/app/src/main/java/com/kiero/presentation/auth/kid/AuthKidSignupScreen.kt b/app/src/main/java/com/kiero/presentation/auth/kid/AuthKidSignupScreen.kt index 3e895760..566384c3 100644 --- a/app/src/main/java/com/kiero/presentation/auth/kid/AuthKidSignupScreen.kt +++ b/app/src/main/java/com/kiero/presentation/auth/kid/AuthKidSignupScreen.kt @@ -1,6 +1,7 @@ package com.kiero.presentation.auth.kid import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer @@ -13,7 +14,9 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusDirection +import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -80,6 +83,9 @@ fun AuthKidSignupScreen( onDone: () -> Unit, modifier: Modifier = Modifier, ) { + val focusManager = LocalFocusManager.current + val keyboardController = LocalSoftwareKeyboardController.current + with(state.kidSignUpUiModel) { Column( modifier = modifier @@ -87,6 +93,12 @@ fun AuthKidSignupScreen( .background( color = KieroTheme.colors.black ) + .pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + keyboardController?.hide() + }) + } .padding(paddingValues), horizontalAlignment = Alignment.CenterHorizontally, ) { diff --git a/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyGoblinMessage.kt b/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyGoblinMessage.kt index a77b31e4..50720f82 100644 --- a/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyGoblinMessage.kt +++ b/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyGoblinMessage.kt @@ -48,7 +48,7 @@ fun KidJourneyGoblinMessage( withStyle(SpanStyle(color = mainColor)) { append(content.scheduleName) } - append(" 야!") + append(" !") }, color = defaultColor, style = textStyle @@ -127,10 +127,10 @@ fun KidJourneyGoblinMessage( ) } - // "오늘의 여정은 모두 끝났어\n내일도 우리 함께하자!" + // "오늘의 여정은 모두 끝났어.\n내일도 우리 함께하자!" is KidJourneyContentUiModel.FireLit -> { Text( - text = "오늘의 여정은 모두 끝났어", + text = "오늘의 여정은 모두 끝났어.", color = defaultColor, style = textStyle ) @@ -151,7 +151,7 @@ private fun KidJourneyGoblinMessagePreview() { name = "꾸비" ) { KidJourneyGoblinMessage( - content = KidJourneyContentUiModel.NowSchedule( + content = KidJourneyContentUiModel.FirstSchedule( scheduleDetailId = 1, scheduleName = "피아노 학원 가기", stoneType = StoneUiType.WISDOM, diff --git a/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyHeader.kt b/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyHeader.kt index 23ed41a0..910999c5 100644 --- a/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyHeader.kt +++ b/app/src/main/java/com/kiero/presentation/kid/journey/component/KidJourneyHeader.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -24,30 +25,40 @@ fun KidJourneyHeader( modifier: Modifier = Modifier, isFireLit: Boolean = false ) { - Row( - modifier = modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically + Column( + modifier = modifier.fillMaxWidth() ) { - Column { + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.Top + ) { KidProfileChip(kidName = header.kidName) - Text( - text = header.currentDate, - style = KieroTheme.typography.regular.body3, - color = KieroTheme.colors.gray500 - ) - } - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) - Column(horizontalAlignment = Alignment.End) { KieroChip( action = KieroCoinAction( coinCount = header.coinCount, onClick = {} - ) + ), + modifier = Modifier.padding(top = 5.dp), + isEnabled = true + ) + } + + Spacer(modifier = Modifier.height(4.dp)) + + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.Top + ) { + Text( + text = header.currentDate, + style = KieroTheme.typography.regular.body3, + color = KieroTheme.colors.gray500 ) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.weight(1f)) KieroChip( action = KieroStoneAction( diff --git a/app/src/main/java/com/kiero/presentation/kid/mission/KidMissionScreen.kt b/app/src/main/java/com/kiero/presentation/kid/mission/KidMissionScreen.kt index 53cd01b9..a002f940 100644 --- a/app/src/main/java/com/kiero/presentation/kid/mission/KidMissionScreen.kt +++ b/app/src/main/java/com/kiero/presentation/kid/mission/KidMissionScreen.kt @@ -106,7 +106,8 @@ private fun KidMissionScreen( stickyHeader { Row( modifier = Modifier - .fillMaxWidth(), + .fillMaxWidth() + .background(color = KieroTheme.colors.black), verticalAlignment = Alignment.CenterVertically ) { KidProfileChip( @@ -120,7 +121,8 @@ private fun KidMissionScreen( coinCount = 150, isEnabled = true, onClick = {} - ) + ), + isEnabled = true ) } } diff --git a/app/src/main/java/com/kiero/presentation/kid/onboarding/KidOnboardingScreen.kt b/app/src/main/java/com/kiero/presentation/kid/onboarding/KidOnboardingScreen.kt index 3e561148..72478b2f 100644 --- a/app/src/main/java/com/kiero/presentation/kid/onboarding/KidOnboardingScreen.kt +++ b/app/src/main/java/com/kiero/presentation/kid/onboarding/KidOnboardingScreen.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable @@ -19,10 +20,13 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.kiero.core.common.extension.collectSideEffect import com.kiero.core.common.extension.noRippleClickable import com.kiero.core.designsystem.component.button.KieroButtonMedium +import com.kiero.core.designsystem.component.indicator.KieroLoadingIndicator import com.kiero.core.designsystem.theme.KieroTheme +import com.kiero.core.model.UiState import com.kiero.presentation.kid.component.KidSpeechField import com.kiero.presentation.kid.onboarding.component.KidOnboardingMessage import com.kiero.presentation.kid.onboarding.model.OnboardingUiModel @@ -36,23 +40,36 @@ fun KidOnboardingRoute( navigateToKid: () -> Unit, viewModel: KidOnboardingViewModel = hiltViewModel() ) { + val state by viewModel.state.collectAsStateWithLifecycle() + viewModel.sideEffect.collectSideEffect { when (it) { KidOnboardingSideEffect.NavigateToKid -> navigateToKid() } } - KidOnboardingScreen( - paddingValues = paddingValues, - navigateToKid = viewModel::startJourney, - onSkipClick = {}, - onNextClick = {} - ) + when (val uiState = state) { + is UiState.Loading -> { + KieroLoadingIndicator() + } + is UiState.Success -> { + KidOnboardingScreen( + paddingValues = paddingValues, + kidName = uiState.data.kidName, + navigateToKid = viewModel::startJourney, + onSkipClick = {}, + onNextClick = {} + ) + } + is UiState.Failure -> {} + UiState.Empty -> {} + } } @Composable fun KidOnboardingScreen( paddingValues: PaddingValues, + kidName: String, navigateToKid: () -> Unit, onNextClick: () -> Unit, onSkipClick: () -> Unit, @@ -77,7 +94,6 @@ fun KidOnboardingScreen( modifier = modifier .fillMaxSize() .background(color = KieroTheme.colors.black) - .padding(paddingValues), ) { Image( painter = painterResource(id = currentStep.backImage), @@ -89,8 +105,10 @@ fun KidOnboardingScreen( Column( modifier = Modifier .fillMaxSize() - .padding(top = 527.dp) + .padding(paddingValues), ) { + Spacer(modifier = Modifier.weight(1f)) + if (currentStep == OnboardingUiModel.STORY5) { KidSpeechField( name = "꾸비", @@ -111,13 +129,14 @@ fun KidOnboardingScreen( buttonText = "다음", isVisibleButton = true, nextButtonColor = KieroTheme.colors.main, + onClick = moveToNextStep ) { - KidOnboardingMessage(step = currentStep) + KidOnboardingMessage(step = currentStep, kidName = kidName) } } KieroButtonMedium( - text = "여정 시작하기", + text = "시작해보자!", onClick = navigateToKid, modifier = Modifier .alpha(if (currentStep == OnboardingUiModel.STORY5) 1f else 0f) @@ -128,13 +147,13 @@ fun KidOnboardingScreen( } } - @Preview @Composable private fun KidOnboardingStoryScreenPreview() { KieroTheme { KidOnboardingScreen( paddingValues = PaddingValues(), + kidName = "", navigateToKid = {}, onSkipClick = {}, onNextClick = {} diff --git a/app/src/main/java/com/kiero/presentation/kid/onboarding/component/KidOnboardingMessage.kt b/app/src/main/java/com/kiero/presentation/kid/onboarding/component/KidOnboardingMessage.kt index e24325b7..077d3b07 100644 --- a/app/src/main/java/com/kiero/presentation/kid/onboarding/component/KidOnboardingMessage.kt +++ b/app/src/main/java/com/kiero/presentation/kid/onboarding/component/KidOnboardingMessage.kt @@ -11,7 +11,8 @@ import com.kiero.presentation.kid.onboarding.model.OnboardingUiModel @Composable fun KidOnboardingMessage( - step: OnboardingUiModel + step: OnboardingUiModel, + kidName: String = "" ) { val mainColor = KieroTheme.colors.main val defaultColor = KieroTheme.colors.gray300 @@ -20,7 +21,7 @@ fun KidOnboardingMessage( when (step) { OnboardingUiModel.STORY1 -> { Text( - text = "드디어 만났다! 나의 짝궁 근영", + text = "드디어 만났다! 나의 짝궁 $kidName", color = defaultColor, style = textStyle ) diff --git a/app/src/main/java/com/kiero/presentation/kid/onboarding/state/KidOnboardingContract.kt b/app/src/main/java/com/kiero/presentation/kid/onboarding/state/KidOnboardingContract.kt index d7764874..6f251e68 100644 --- a/app/src/main/java/com/kiero/presentation/kid/onboarding/state/KidOnboardingContract.kt +++ b/app/src/main/java/com/kiero/presentation/kid/onboarding/state/KidOnboardingContract.kt @@ -1,5 +1,12 @@ package com.kiero.presentation.kid.onboarding.state +import androidx.compose.runtime.Immutable + +@Immutable +data class KidOnboardingState( + val kidName: String +) + sealed interface KidOnboardingSideEffect { data object NavigateToKid : KidOnboardingSideEffect } \ No newline at end of file diff --git a/app/src/main/java/com/kiero/presentation/kid/onboarding/viewmodel/KidOnboardingViewModel.kt b/app/src/main/java/com/kiero/presentation/kid/onboarding/viewmodel/KidOnboardingViewModel.kt index 4062aa90..4687975d 100644 --- a/app/src/main/java/com/kiero/presentation/kid/onboarding/viewmodel/KidOnboardingViewModel.kt +++ b/app/src/main/java/com/kiero/presentation/kid/onboarding/viewmodel/KidOnboardingViewModel.kt @@ -3,26 +3,63 @@ package com.kiero.presentation.kid.onboarding.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.kiero.core.localstorage.onboarding.OnboardingManager +import com.kiero.core.model.UiState +import com.kiero.data.kid.coin.repository.CoinRepository import com.kiero.presentation.kid.onboarding.state.KidOnboardingSideEffect +import com.kiero.presentation.kid.onboarding.state.KidOnboardingState import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.launch +import timber.log.Timber import javax.inject.Inject @HiltViewModel class KidOnboardingViewModel @Inject constructor( - private val onboardingManager: OnboardingManager + private val onboardingManager: OnboardingManager, + private val coinRepository: CoinRepository ) : ViewModel() { + private val coin = coinRepository.myCoin + + private val _state = MutableStateFlow>(UiState.Loading) + val state = _state.asStateFlow() + private val _sideEffect = MutableSharedFlow() val sideEffect = _sideEffect.asSharedFlow() + init { + fetchCoin() + } + fun startJourney() { viewModelScope.launch { - onboardingManager.saveIsSawOnboarding(isSaw = true) + _state.value = UiState.Loading + + delay(2000) + onboardingManager.saveIsSawOnboarding(isSaw = true) _sideEffect.emit(KidOnboardingSideEffect.NavigateToKid) } } + fun fetchCoin() { + viewModelScope.launch { + _state.value = UiState.Loading + + coinRepository.getCurrentCoin() + .onSuccess { + Timber.d("fetchCoin: $it") + _state.value = UiState.Success( + KidOnboardingState(kidName = coin.value.firstName) + ) + } + .onFailure { + Timber.e("fetchCoin fail: $it") + _state.value = UiState.Failure(it.message.toString()) + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/kiero/presentation/kid/wish/KidWishScreen.kt b/app/src/main/java/com/kiero/presentation/kid/wish/KidWishScreen.kt index 1b1e1a3b..d336b05d 100644 --- a/app/src/main/java/com/kiero/presentation/kid/wish/KidWishScreen.kt +++ b/app/src/main/java/com/kiero/presentation/kid/wish/KidWishScreen.kt @@ -117,7 +117,7 @@ fun KidWishRoute( Row( verticalAlignment = Alignment.CenterVertically ) { - val coinImage = painterResource(R.drawable.img_kid_coin) + val coinImage = painterResource(R.drawable.img_coin) Image( painter = coinImage, @@ -176,7 +176,8 @@ private fun KidWishScreen( ) { Row( modifier = Modifier - .fillMaxWidth(), + .fillMaxWidth() + .background(color = KieroTheme.colors.black), verticalAlignment = Alignment.CenterVertically ) { KidProfileChip( @@ -190,7 +191,8 @@ private fun KidWishScreen( coinCount = state.coinUiModel.coinAmount, isEnabled = true, onClick = {} - ) + ), + isEnabled = true ) } diff --git a/app/src/main/java/com/kiero/presentation/signup/parent/screen/ParentSignUpAddChildScreen.kt b/app/src/main/java/com/kiero/presentation/signup/parent/screen/ParentSignUpAddChildScreen.kt index 61903e3a..2f8a4f91 100644 --- a/app/src/main/java/com/kiero/presentation/signup/parent/screen/ParentSignUpAddChildScreen.kt +++ b/app/src/main/java/com/kiero/presentation/signup/parent/screen/ParentSignUpAddChildScreen.kt @@ -1,10 +1,16 @@ package com.kiero.presentation.signup.parent.screen +import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -21,7 +27,20 @@ fun ParentSignUpAddChildScreen( nextFocus: () -> Unit, doneFocus: () -> Unit ) { - Column { + val focusManager = LocalFocusManager.current + val keyboardController = LocalSoftwareKeyboardController.current + + Column ( + modifier = Modifier + .fillMaxSize() + .background(color = KieroTheme.colors.black) + .pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + keyboardController?.hide() + }) + } + ){ Spacer(modifier = Modifier.height(17.dp)) ParentSignUpForm( diff --git a/app/src/main/java/com/kiero/presentation/splash/SplashScreen.kt b/app/src/main/java/com/kiero/presentation/splash/SplashScreen.kt index 65644f0e..894b3fcd 100644 --- a/app/src/main/java/com/kiero/presentation/splash/SplashScreen.kt +++ b/app/src/main/java/com/kiero/presentation/splash/SplashScreen.kt @@ -58,7 +58,7 @@ fun SplashRoute( @Composable fun SplashScreen() { - val logoPainter = painterResource(R.drawable.img_app_logo) + val logoPainter = painterResource(R.drawable.ic_logo) val goblinPainter = painterResource(R.drawable.img_splash_goblin) val configuration = LocalConfiguration.current.screenWidthDp.dp diff --git a/app/src/main/res/drawable/ic_logo.xml b/app/src/main/res/drawable/ic_logo.xml new file mode 100644 index 00000000..7dc7fc3f --- /dev/null +++ b/app/src/main/res/drawable/ic_logo.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/app/src/main/res/drawable/img_app_logo.png b/app/src/main/res/drawable/img_app_logo.png deleted file mode 100644 index e8493e83..00000000 Binary files a/app/src/main/res/drawable/img_app_logo.png and /dev/null differ diff --git a/app/src/main/res/drawable/img_auth_app_logo.png b/app/src/main/res/drawable/img_auth_app_logo.png deleted file mode 100644 index b4bcc6af..00000000 Binary files a/app/src/main/res/drawable/img_auth_app_logo.png and /dev/null differ diff --git a/app/src/main/res/drawable/img_auth_kid_goblin_small.png b/app/src/main/res/drawable/img_auth_kid_goblin_small.png index c56b94f2..e3b4e882 100644 Binary files a/app/src/main/res/drawable/img_auth_kid_goblin_small.png and b/app/src/main/res/drawable/img_auth_kid_goblin_small.png differ diff --git a/app/src/main/res/drawable/img_auth_parent_goblin_small.png b/app/src/main/res/drawable/img_auth_parent_goblin_small.png index 6b53e15b..7d2a5f0f 100644 Binary files a/app/src/main/res/drawable/img_auth_parent_goblin_small.png and b/app/src/main/res/drawable/img_auth_parent_goblin_small.png differ diff --git a/app/src/main/res/drawable/img_coin.png b/app/src/main/res/drawable/img_coin.png new file mode 100644 index 00000000..1c215aa7 Binary files /dev/null and b/app/src/main/res/drawable/img_coin.png differ