diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index f158156f..908a39ef 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -8,6 +8,7 @@ import androidx.navigation.compose.composable import androidx.navigation.toRoute import com.threegap.bitnagil.navigation.home.HomeNavHost import com.threegap.bitnagil.presentation.emotion.EmotionScreenContainer +import com.threegap.bitnagil.presentation.guide.GuideScreenContainer import com.threegap.bitnagil.presentation.login.LoginScreenContainer import com.threegap.bitnagil.presentation.onboarding.OnBoardingScreenContainer import com.threegap.bitnagil.presentation.onboarding.OnBoardingViewModel @@ -112,6 +113,11 @@ fun MainNavHost( ), ) }, + navigateToGuide = { + navigator.navController.navigate(Route.Guide) { + launchSingleTop = true + } + }, navigateToRegisterRoutine = { routineId -> navigator.navController.navigate(Route.WriteRoutine(routineId = routineId)) }, @@ -241,5 +247,15 @@ fun MainNavHost( }, ) } + + composable { + GuideScreenContainer( + navigateToBack = { + if (navigator.navController.previousBackStackEntry != null) { + navigator.navController.popBackStack() + } + }, + ) + } } } diff --git a/app/src/main/java/com/threegap/bitnagil/Route.kt b/app/src/main/java/com/threegap/bitnagil/Route.kt index cb9eacde..9ae850d4 100644 --- a/app/src/main/java/com/threegap/bitnagil/Route.kt +++ b/app/src/main/java/com/threegap/bitnagil/Route.kt @@ -41,4 +41,7 @@ sealed interface Route { @Serializable data object Withdrawal : Route + + @Serializable + data object Guide : Route } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt index 41633372..4d21389f 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt @@ -39,6 +39,7 @@ fun HomeNavHost( navigateToOnBoarding: () -> Unit, navigateToNotice: () -> Unit, navigateToQnA: () -> Unit, + navigateToGuide: () -> Unit, navigateToRegisterRoutine: (String?) -> Unit, navigateToEmotion: () -> Unit, ) { @@ -62,6 +63,7 @@ fun HomeNavHost( ) { composable(HomeRoute.Home.route) { HomeScreenContainer( + navigateToGuide = navigateToGuide, navigateToRegisterRoutine = { navigateToRegisterRoutine(null) }, diff --git a/core/designsystem/src/main/res/drawable-hdpi/img_edit_guide.png b/core/designsystem/src/main/res/drawable-hdpi/img_edit_guide.png new file mode 100644 index 00000000..9dc6c45b Binary files /dev/null and b/core/designsystem/src/main/res/drawable-hdpi/img_edit_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-hdpi/img_recommend_guide.png b/core/designsystem/src/main/res/drawable-hdpi/img_recommend_guide.png new file mode 100644 index 00000000..4f8ffd00 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-hdpi/img_recommend_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-hdpi/img_register_guide.png b/core/designsystem/src/main/res/drawable-hdpi/img_register_guide.png new file mode 100644 index 00000000..9f117056 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-hdpi/img_register_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-mdpi/img_edit_guide.png b/core/designsystem/src/main/res/drawable-mdpi/img_edit_guide.png new file mode 100644 index 00000000..e8441cc3 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-mdpi/img_edit_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-mdpi/img_recommend_guide.png b/core/designsystem/src/main/res/drawable-mdpi/img_recommend_guide.png new file mode 100644 index 00000000..077c1080 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-mdpi/img_recommend_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-mdpi/img_register_guide.png b/core/designsystem/src/main/res/drawable-mdpi/img_register_guide.png new file mode 100644 index 00000000..8ca697ea Binary files /dev/null and b/core/designsystem/src/main/res/drawable-mdpi/img_register_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xhdpi/img_edit_guide.png b/core/designsystem/src/main/res/drawable-xhdpi/img_edit_guide.png new file mode 100644 index 00000000..b1a89dc8 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xhdpi/img_edit_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xhdpi/img_recommend_guide.png b/core/designsystem/src/main/res/drawable-xhdpi/img_recommend_guide.png new file mode 100644 index 00000000..f5775192 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xhdpi/img_recommend_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xhdpi/img_register_guide.png b/core/designsystem/src/main/res/drawable-xhdpi/img_register_guide.png new file mode 100644 index 00000000..b37d3fc5 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xhdpi/img_register_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xxhdpi/img_edit_guide.png b/core/designsystem/src/main/res/drawable-xxhdpi/img_edit_guide.png new file mode 100644 index 00000000..e8403da0 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xxhdpi/img_edit_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xxhdpi/img_recommend_guide.png b/core/designsystem/src/main/res/drawable-xxhdpi/img_recommend_guide.png new file mode 100644 index 00000000..bd0b3e64 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xxhdpi/img_recommend_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xxhdpi/img_register_guide.png b/core/designsystem/src/main/res/drawable-xxhdpi/img_register_guide.png new file mode 100644 index 00000000..949cc70d Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xxhdpi/img_register_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xxxhdpi/img_edit_guide.png b/core/designsystem/src/main/res/drawable-xxxhdpi/img_edit_guide.png new file mode 100644 index 00000000..f8e3a57d Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xxxhdpi/img_edit_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xxxhdpi/img_recommend_guide.png b/core/designsystem/src/main/res/drawable-xxxhdpi/img_recommend_guide.png new file mode 100644 index 00000000..2b31ee08 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xxxhdpi/img_recommend_guide.png differ diff --git a/core/designsystem/src/main/res/drawable-xxxhdpi/img_register_guide.png b/core/designsystem/src/main/res/drawable-xxxhdpi/img_register_guide.png new file mode 100644 index 00000000..5e54d053 Binary files /dev/null and b/core/designsystem/src/main/res/drawable-xxxhdpi/img_register_guide.png differ diff --git a/core/designsystem/src/main/res/drawable/ic_help_circle.xml b/core/designsystem/src/main/res/drawable/ic_help_circle.xml new file mode 100644 index 00000000..6142c01e --- /dev/null +++ b/core/designsystem/src/main/res/drawable/ic_help_circle.xml @@ -0,0 +1,16 @@ + + + + diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/GuideScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/GuideScreen.kt new file mode 100644 index 00000000..cba2e1cf --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/GuideScreen.kt @@ -0,0 +1,95 @@ +package com.threegap.bitnagil.presentation.guide + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +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.statusBarsPadding +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +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 com.threegap.bitnagil.designsystem.BitnagilTheme +import com.threegap.bitnagil.designsystem.component.block.BitnagilTopBar +import com.threegap.bitnagil.presentation.common.flow.collectAsEffect +import com.threegap.bitnagil.presentation.guide.component.atom.GuideButton +import com.threegap.bitnagil.presentation.guide.component.template.GuideBottomSheet +import com.threegap.bitnagil.presentation.guide.model.GuideIntent +import com.threegap.bitnagil.presentation.guide.model.GuideSideEffect +import com.threegap.bitnagil.presentation.guide.model.GuideType + +@Composable +fun GuideScreenContainer( + navigateToBack: () -> Unit, + viewModel: GuideViewModel = hiltViewModel(), +) { + val uiState by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + viewModel.sideEffectFlow.collectAsEffect { sideEffect -> + when (sideEffect) { + is GuideSideEffect.NavigateToBack -> navigateToBack() + } + } + + if (uiState.guideBottomSheetVisible) { + uiState.guideType?.let { guideType -> + GuideBottomSheet( + guideType = guideType, + onDismissRequest = { viewModel.sendIntent(GuideIntent.OnHideGuideBottomSheet) }, + ) + } + } + + GuideScreen( + onClickGuideButton = { viewModel.sendIntent(GuideIntent.OnClickGuideButton(it)) }, + onBackClick = { viewModel.sendIntent(GuideIntent.OnBackClick) }, + ) +} + +@Composable +private fun GuideScreen( + onClickGuideButton: (GuideType) -> Unit, + onBackClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .fillMaxSize() + .background(BitnagilTheme.colors.white) + .statusBarsPadding(), + ) { + BitnagilTopBar( + title = "설명서", + showBackButton = true, + onBackClick = onBackClick, + modifier = Modifier.fillMaxWidth(), + ) + + Spacer(modifier = Modifier.height(46.dp)) + + GuideType.entries.forEach { guideType -> + GuideButton( + title = guideType.title, + onClick = { onClickGuideButton(guideType) }, + modifier = Modifier + .padding(horizontal = 16.dp) + .padding(bottom = 12.dp), + ) + } + } +} + +@Preview +@Composable +private fun GuideScreenPreview() { + GuideScreen( + onClickGuideButton = {}, + onBackClick = {}, + ) +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/GuideViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/GuideViewModel.kt new file mode 100644 index 00000000..30accb7b --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/GuideViewModel.kt @@ -0,0 +1,46 @@ +package com.threegap.bitnagil.presentation.guide + +import androidx.lifecycle.SavedStateHandle +import com.threegap.bitnagil.presentation.common.mviviewmodel.MviViewModel +import com.threegap.bitnagil.presentation.guide.model.GuideIntent +import com.threegap.bitnagil.presentation.guide.model.GuideSideEffect +import com.threegap.bitnagil.presentation.guide.model.GuideState +import dagger.hilt.android.lifecycle.HiltViewModel +import org.orbitmvi.orbit.syntax.simple.SimpleSyntax +import javax.inject.Inject + +@HiltViewModel +class GuideViewModel @Inject constructor( + savedStateHandle: SavedStateHandle, +) : MviViewModel( + initState = GuideState(), + savedStateHandle = savedStateHandle, +) { + override suspend fun SimpleSyntax.reduceState( + intent: GuideIntent, + state: GuideState, + ): GuideState? { + val newState = when (intent) { + is GuideIntent.OnClickGuideButton -> { + state.copy( + guideType = intent.guideType, + guideBottomSheetVisible = true, + ) + } + + is GuideIntent.OnHideGuideBottomSheet -> { + state.copy( + guideType = null, + guideBottomSheetVisible = false, + ) + } + + is GuideIntent.OnBackClick -> { + sendSideEffect(GuideSideEffect.NavigateToBack) + null + } + } + + return newState + } +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/component/atom/GuideButton.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/component/atom/GuideButton.kt new file mode 100644 index 00000000..ab239a25 --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/component/atom/GuideButton.kt @@ -0,0 +1,60 @@ +package com.threegap.bitnagil.presentation.guide.component.atom + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.threegap.bitnagil.designsystem.BitnagilTheme +import com.threegap.bitnagil.designsystem.R +import com.threegap.bitnagil.designsystem.component.atom.BitnagilIcon +import com.threegap.bitnagil.designsystem.modifier.clickableWithoutRipple + +@Composable +fun GuideButton( + title: String, + onClick: () -> Unit, + modifier: Modifier = Modifier, +) { + Row( + modifier = modifier + .background( + color = BitnagilTheme.colors.coolGray99, + shape = RoundedCornerShape(12.dp), + ) + .fillMaxWidth() + .height(56.dp) + .clickableWithoutRipple { onClick() } + .padding(vertical = 14.dp, horizontal = 20.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = title, + color = BitnagilTheme.colors.coolGray10, + style = BitnagilTheme.typography.body2Medium, + ) + + BitnagilIcon( + id = R.drawable.ic_chevron_right_md, + tint = BitnagilTheme.colors.coolGray10, + ) + } +} + +@Preview +@Composable +private fun GuideButtonPreview() { + GuideButton( + title = "루틴 수정하기란?", + onClick = {}, + ) +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/component/template/GuideBottomSheet.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/component/template/GuideBottomSheet.kt new file mode 100644 index 00000000..fefefa47 --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/component/template/GuideBottomSheet.kt @@ -0,0 +1,82 @@ +package com.threegap.bitnagil.presentation.guide.component.template + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.threegap.bitnagil.designsystem.BitnagilTheme +import com.threegap.bitnagil.presentation.guide.model.GuideType + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun GuideBottomSheet( + guideType: GuideType, + onDismissRequest: () -> Unit, + modifier: Modifier = Modifier, +) { + ModalBottomSheet( + onDismissRequest = onDismissRequest, + containerColor = BitnagilTheme.colors.coolGray99, + contentColor = BitnagilTheme.colors.coolGray99, + modifier = modifier, + ) { + GuideBottomSheetContent( + guideType = guideType, + modifier = Modifier + .padding(horizontal = 24.dp) + .padding(bottom = 26.dp), + ) + } +} + +@Composable +private fun GuideBottomSheetContent( + guideType: GuideType, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier, + ) { + Text( + text = guideType.title, + color = BitnagilTheme.colors.coolGray10, + style = BitnagilTheme.typography.title3SemiBold, + modifier = Modifier.padding(bottom = 10.dp), + ) + + Text( + text = guideType.description, + color = BitnagilTheme.colors.coolGray40, + style = BitnagilTheme.typography.body2Medium, + ) + + Spacer(modifier = Modifier.height(24.dp)) + + Image( + painter = painterResource(guideType.image), + contentDescription = null, + modifier = Modifier + .fillMaxWidth() + .aspectRatio(312f / 198f), + ) + } +} + +@Preview(showBackground = true) +@Composable +private fun GuideBottomSheetContentPreview() { + GuideBottomSheetContent( + guideType = GuideType.REGISTER, + ) +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideIntent.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideIntent.kt new file mode 100644 index 00000000..b28b34ca --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideIntent.kt @@ -0,0 +1,9 @@ +package com.threegap.bitnagil.presentation.guide.model + +import com.threegap.bitnagil.presentation.common.mviviewmodel.MviIntent + +sealed class GuideIntent : MviIntent { + data object OnHideGuideBottomSheet : GuideIntent() + data object OnBackClick : GuideIntent() + data class OnClickGuideButton(val guideType: GuideType) : GuideIntent() +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideSideEffect.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideSideEffect.kt new file mode 100644 index 00000000..0cffdc52 --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideSideEffect.kt @@ -0,0 +1,7 @@ +package com.threegap.bitnagil.presentation.guide.model + +import com.threegap.bitnagil.presentation.common.mviviewmodel.MviSideEffect + +sealed interface GuideSideEffect : MviSideEffect { + data object NavigateToBack : GuideSideEffect +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideState.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideState.kt new file mode 100644 index 00000000..4223c533 --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideState.kt @@ -0,0 +1,10 @@ +package com.threegap.bitnagil.presentation.guide.model + +import com.threegap.bitnagil.presentation.common.mviviewmodel.MviState +import kotlinx.parcelize.Parcelize + +@Parcelize +data class GuideState( + val guideType: GuideType? = null, + val guideBottomSheetVisible: Boolean = false, +) : MviState diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideType.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideType.kt new file mode 100644 index 00000000..40bec3b6 --- /dev/null +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/guide/model/GuideType.kt @@ -0,0 +1,26 @@ +package com.threegap.bitnagil.presentation.guide.model + +import androidx.annotation.DrawableRes +import com.threegap.bitnagil.designsystem.R + +enum class GuideType( + val title: String, + val description: String, + @DrawableRes val image: Int, +) { + REGISTER( + title = "오늘 감정 등록하기란?", + description = "오늘 느끼는 감정을 선택하면, 그 기분에 맞춰 추천 루틴을 확인할 수 있어요.", + image = R.drawable.img_register_guide, + ), + RECOMMEND( + title = "맞춤 추천 루틴이란?", + description = "처음 설정한 목표에 맞춰 루틴을 추천받을 수 있으며,\n필요할 때 언제든 수정할 수 있어요.", + image = R.drawable.img_recommend_guide, + ), + EDIT( + title = "루틴 수정하기란?", + description = "등록한 루틴은 수정할 수 있으며, 변경 내용을 당일부터 또는 다음 날부터 적용하도록 선택할 수 있어요.", + image = R.drawable.img_edit_guide, + ), +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt index 6be6a6cb..c0cde108 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt @@ -40,6 +40,7 @@ import java.time.LocalDate @Composable fun HomeScreenContainer( viewModel: HomeViewModel = hiltViewModel(), + navigateToGuide: () -> Unit, navigateToRegisterRoutine: () -> Unit, navigateToEmotion: () -> Unit, ) { @@ -47,6 +48,10 @@ fun HomeScreenContainer( viewModel.sideEffectFlow.collectAsEffect { sideEffect -> when (sideEffect) { + is HomeSideEffect.NavigateToGuide -> { + navigateToGuide() + } + is HomeSideEffect.NavigateToRegisterRoutine -> { navigateToRegisterRoutine() } @@ -82,6 +87,9 @@ fun HomeScreenContainer( onSubRoutineCompletionToggle = { routineId, subRoutineIndex, isCompleted -> viewModel.toggleSubRoutineCompletion(routineId, subRoutineIndex, isCompleted) }, + onHelpClick = { + viewModel.sendIntent(HomeIntent.OnHelpClick) + }, onRegisterRoutineClick = { viewModel.sendIntent(HomeIntent.OnRegisterRoutineClick) }, @@ -102,6 +110,7 @@ private fun HomeScreen( onNextWeekClick: () -> Unit, onRoutineCompletionToggle: (String, Boolean) -> Unit, onSubRoutineCompletionToggle: (String, Int, Boolean) -> Unit, + onHelpClick: () -> Unit, onRegisterRoutineClick: () -> Unit, onRegisterEmotionClick: () -> Unit, onShowMoreRoutinesClick: () -> Unit, @@ -198,6 +207,7 @@ private fun HomeScreen( userName = uiState.userNickname, todayEmotion = uiState.todayEmotion, collapsibleHeaderState = collapsibleHeaderState, + onHelpClick = onHelpClick, onRegisterEmotion = onRegisterEmotionClick, ) } @@ -213,6 +223,7 @@ private fun HomeScreenPreview() { onNextWeekClick = {}, onRoutineCompletionToggle = { _, _ -> }, onSubRoutineCompletionToggle = { _, _, _ -> }, + onHelpClick = {}, onRegisterRoutineClick = {}, onRegisterEmotionClick = {}, onShowMoreRoutinesClick = {}, diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeViewModel.kt index cf6a796c..b31a92fa 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeViewModel.kt @@ -110,6 +110,11 @@ class HomeViewModel @Inject constructor( state.copy(todayEmotion = intent.emotion) } + is HomeIntent.OnHelpClick -> { + sendSideEffect(HomeSideEffect.NavigateToGuide) + null + } + is HomeIntent.OnRegisterEmotionClick -> { sendSideEffect(HomeSideEffect.NavigateToEmotion) null diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/component/template/CollapsibleHomeHeader.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/component/template/CollapsibleHomeHeader.kt index 1be0dd03..f15b8e12 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/component/template/CollapsibleHomeHeader.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/component/template/CollapsibleHomeHeader.kt @@ -5,7 +5,9 @@ import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -30,6 +32,7 @@ import coil3.request.crossfade import com.threegap.bitnagil.designsystem.BitnagilTheme import com.threegap.bitnagil.designsystem.R import com.threegap.bitnagil.designsystem.component.atom.BitnagilIcon +import com.threegap.bitnagil.designsystem.component.atom.BitnagilIconButton import com.threegap.bitnagil.presentation.home.component.atom.EmotionRegisterButton import com.threegap.bitnagil.presentation.home.model.TodayEmotionUiModel import com.threegap.bitnagil.presentation.home.util.CollapsibleHeaderState @@ -40,6 +43,7 @@ fun CollapsibleHomeHeader( userName: String, todayEmotion: TodayEmotionUiModel?, collapsibleHeaderState: CollapsibleHeaderState, + onHelpClick: () -> Unit, onRegisterEmotion: () -> Unit, modifier: Modifier = Modifier, ) { @@ -64,13 +68,22 @@ fun CollapsibleHomeHeader( modifier = Modifier .fillMaxWidth() .height(collapsibleHeaderState.collapsedHeaderHeight) - .statusBarsPadding(), + .statusBarsPadding() + .padding(start = 16.dp, end = 4.dp), verticalAlignment = Alignment.CenterVertically, ) { BitnagilIcon( id = R.drawable.ic_logo, tint = BitnagilTheme.colors.coolGray50, - modifier = Modifier.padding(start = 16.dp), + ) + + Spacer(modifier = Modifier.weight(1f)) + + BitnagilIconButton( + id = R.drawable.ic_help_circle, + onClick = onHelpClick, + paddingValues = PaddingValues(12.dp), + tint = null, ) } @@ -129,6 +142,7 @@ private fun CollapsibleHomeHeaderPreview() { userName = "대현", todayEmotion = null, collapsibleHeaderState = rememberCollapsibleHeaderState(), + onHelpClick = {}, onRegisterEmotion = {}, ) } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeIntent.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeIntent.kt index a15b8f77..05684d1f 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeIntent.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeIntent.kt @@ -12,6 +12,7 @@ sealed class HomeIntent : MviIntent { data class OnRoutineCompletionToggle(val routineId: String, val isCompleted: Boolean) : HomeIntent() data class OnSubRoutineCompletionToggle(val routineId: String, val subRoutineIndex: Int, val isCompleted: Boolean) : HomeIntent() data object RoutineToggleCompletionFailure : HomeIntent() + data object OnHelpClick : HomeIntent() data object OnRegisterEmotionClick : HomeIntent() data object OnRegisterRoutineClick : HomeIntent() data object OnPreviousWeekClick : HomeIntent() diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeSideEffect.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeSideEffect.kt index 72ab2d75..a26b9ffe 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeSideEffect.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/model/HomeSideEffect.kt @@ -5,6 +5,7 @@ import com.threegap.bitnagil.presentation.common.mviviewmodel.MviSideEffect sealed interface HomeSideEffect : MviSideEffect { data class ShowToast(val message: String) : HomeSideEffect data class ShowToastWithIcon(val message: String) : HomeSideEffect + data object NavigateToGuide : HomeSideEffect data object NavigateToRegisterRoutine : HomeSideEffect data object NavigateToEmotion : HomeSideEffect }