From 603990a6cd76258275ababa2a272eca79b0da7f8 Mon Sep 17 00:00:00 2001 From: Junhyeok Date: Sat, 15 Feb 2025 01:00:20 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=BA=90=EB=A6=AD=ED=84=B0=20=EC=84=A0?= =?UTF-8?q?=ED=83=9D=20ui=EB=A5=BC=20=EC=9E=AC=EC=82=AC=EC=9A=A9=EC=9D=84?= =?UTF-8?q?=20=EC=9C=84=ED=95=9C=20core:ui=20module=20=EC=9E=91=EC=97=85?= =?UTF-8?q?=20(#69)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore : add core:ui module * refactor : move character selection to core:ui * feat : add preview --- app/build.gradle.kts | 1 + .../OnboardingSelectCharacterScreen.kt | 69 +-------------- app/src/main/res/values-en/strings.xml | 5 -- app/src/main/res/values/strings.xml | 5 -- .../src/main/kotlin/AndroidFeaturePlugin.kt | 1 + core/ui/.gitignore | 1 + core/ui/build.gradle.kts | 16 ++++ core/ui/src/main/AndroidManifest.xml | 4 + .../dobedobe/core/ui/CharacterCard.kt | 15 ++-- .../dobedobe/core/ui/SelectCharacterScreen.kt | 80 ++++++++++++++++++ .../src/main/res/drawable/bird_character.png | Bin .../ui}/src/main/res/drawable/bubble_bird.png | Bin .../src/main/res/drawable/bubble_rabbit.png | Bin .../main/res/drawable/rabbit_character.png | Bin core/ui/src/main/res/values-en/strings.xml | 7 ++ core/ui/src/main/res/values/strings.xml | 7 ++ settings.gradle.kts | 1 + 17 files changed, 128 insertions(+), 84 deletions(-) create mode 100644 core/ui/.gitignore create mode 100644 core/ui/build.gradle.kts create mode 100644 core/ui/src/main/AndroidManifest.xml rename app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingCharacterCard.kt => core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/CharacterCard.kt (90%) create mode 100644 core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt rename app/src/main/res/drawable/onboarding_bird.png => core/ui/src/main/res/drawable/bird_character.png (100%) rename {app => core/ui}/src/main/res/drawable/bubble_bird.png (100%) rename {app => core/ui}/src/main/res/drawable/bubble_rabbit.png (100%) rename app/src/main/res/drawable/onboarding_rabbit.png => core/ui/src/main/res/drawable/rabbit_character.png (100%) create mode 100644 core/ui/src/main/res/values-en/strings.xml create mode 100644 core/ui/src/main/res/values/strings.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 60ac5672..da4f8e4c 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -58,6 +58,7 @@ dependencies { implementation(projects.core.designsystem) implementation(projects.core.model) implementation(projects.core.notifications) + implementation(projects.core.ui) implementation(libs.androidx.core.ktx) implementation(libs.androidx.activity.compose) diff --git a/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt b/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt index 451b8bc2..ca8bcbe3 100644 --- a/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt +++ b/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt @@ -1,23 +1,10 @@ package com.chipichipi.dobedobe.onboarding -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.heightIn -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle -import com.chipichipi.dobedobe.R -import com.chipichipi.dobedobe.core.designsystem.component.DobeDobeTextButton -import com.chipichipi.dobedobe.core.designsystem.theme.DobeDobeTheme -import com.chipichipi.dobedobe.core.model.CharacterType +import com.chipichipi.dobedobe.core.ui.SelectCharacterScreen import org.koin.androidx.compose.koinViewModel @Composable @@ -27,60 +14,10 @@ internal fun OnboardingSelectCharacterRoute( ) { val selectedCharacter by viewModel.selectedCharacter.collectAsStateWithLifecycle() - OnboardingSelectCharacterScreen( + SelectCharacterScreen( modifier = modifier, selectedCharacter = selectedCharacter, onCharacterToggled = viewModel::toggleCharacter, - onOnboardingCompleted = viewModel::completeOnboarding, + onCompleted = viewModel::completeOnboarding, ) } - -@Composable -private fun OnboardingSelectCharacterScreen( - selectedCharacter: CharacterType, - onCharacterToggled: () -> Unit, - onOnboardingCompleted: () -> Unit, - modifier: Modifier = Modifier, -) { - Column( - modifier = modifier - .fillMaxSize() - .padding(horizontal = 24.dp) - .padding( - top = 48.dp, - bottom = 32.dp, - ), - ) { - Text( - text = stringResource(R.string.onboarding_select_character_title), - style = DobeDobeTheme.typography.heading1, - color = DobeDobeTheme.colors.black, - ) - Spacer(modifier = Modifier.height(48.dp)) - - OnboardingBirdCard( - selected = selectedCharacter == CharacterType.Bird, - onClick = onCharacterToggled, - ) - Spacer(modifier = Modifier.height(32.dp)) - - OnboardingRabbitCard( - selected = selectedCharacter == CharacterType.Rabbit, - onClick = onCharacterToggled, - ) - Spacer(modifier = Modifier.weight(1f)) - - DobeDobeTextButton( - modifier = Modifier - .fillMaxWidth() - .heightIn(56.dp), - onClick = onOnboardingCompleted, - ) { - Text( - text = stringResource(R.string.onboarding_all_complete), - style = DobeDobeTheme.typography.heading2, - color = DobeDobeTheme.colors.white, - ) - } - } -} diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index f042b827..f8d28921 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -6,9 +6,4 @@ ex) Read 1 book per day The simpler the goal, the better the focus. Complete - - 함께 할 러닝메이트를\n선택해 주세요 - 시작하기 - 마구 쪼는 잔소리무새 - 공감 만점 럭키 토끼 \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a208e3d9..8f38036b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,9 +5,4 @@ ex) 1일 1책 읽기 목표가 간결할수록 집중력이 높아져요. 작성 완료 - - 함께 할 러닝메이트를\n선택해 주세요 - 시작하기 - 마구 쪼는 잔소리무새 - 공감 만점 럭키 토끼 \ No newline at end of file diff --git a/build-logic/convention/src/main/kotlin/AndroidFeaturePlugin.kt b/build-logic/convention/src/main/kotlin/AndroidFeaturePlugin.kt index 3296b59f..c2ae3556 100644 --- a/build-logic/convention/src/main/kotlin/AndroidFeaturePlugin.kt +++ b/build-logic/convention/src/main/kotlin/AndroidFeaturePlugin.kt @@ -12,6 +12,7 @@ class AndroidFeaturePlugin : Plugin { dependencies { "implementation"(project(":core:designsystem")) + "implementation"(project(":core:ui")) "implementation"(libs.findLibrary("androidx.lifecycle.runtimeCompose").get()) "implementation"(libs.findLibrary("androidx.lifecycle.viewModelCompose").get()) diff --git a/core/ui/.gitignore b/core/ui/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/core/ui/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/ui/build.gradle.kts b/core/ui/build.gradle.kts new file mode 100644 index 00000000..43940705 --- /dev/null +++ b/core/ui/build.gradle.kts @@ -0,0 +1,16 @@ +plugins { + alias(libs.plugins.dobedobe.android.library) + alias(libs.plugins.dobedobe.android.compose) +} + +android { + namespace = "com.chipichipi.dobedobe.core.ui" +} + +dependencies { + api(projects.core.designsystem) + api(projects.core.model) + + implementation(libs.coil.kt) + implementation(libs.coil.kt.compose) +} diff --git a/core/ui/src/main/AndroidManifest.xml b/core/ui/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/core/ui/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingCharacterCard.kt b/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/CharacterCard.kt similarity index 90% rename from app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingCharacterCard.kt rename to core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/CharacterCard.kt index 12c172cd..90567539 100644 --- a/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingCharacterCard.kt +++ b/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/CharacterCard.kt @@ -1,4 +1,4 @@ -package com.chipichipi.dobedobe.onboarding +package com.chipichipi.dobedobe.core.ui import androidx.annotation.DrawableRes import androidx.compose.foundation.BorderStroke @@ -23,21 +23,20 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import com.chipichipi.dobedobe.R import com.chipichipi.dobedobe.core.designsystem.theme.DobeDobeTheme @Composable -internal fun OnboardingBirdCard( +internal fun BirdCard( selected: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier, ) { CharacterCard( modifier = modifier, - title = stringResource(R.string.onboarding_bird_character_description), + title = stringResource(R.string.bird_character_description), characterAlignment = Alignment.BottomStart, bubbleAlignment = Alignment.TopEnd, - characterRes = R.drawable.onboarding_bird, + characterRes = R.drawable.bird_character, bubbleRes = R.drawable.bubble_bird, selected = selected, onClick = onClick, @@ -45,17 +44,17 @@ internal fun OnboardingBirdCard( } @Composable -internal fun OnboardingRabbitCard( +internal fun RabbitCard( selected: Boolean, onClick: () -> Unit, modifier: Modifier = Modifier, ) { CharacterCard( modifier = modifier, - title = stringResource(R.string.onboarding_rabbit_character_description), + title = stringResource(R.string.rabbit_character_description), characterAlignment = Alignment.BottomEnd, bubbleAlignment = Alignment.TopStart, - characterRes = R.drawable.onboarding_rabbit, + characterRes = R.drawable.rabbit_character, bubbleRes = R.drawable.bubble_rabbit, selected = selected, onClick = onClick, diff --git a/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt b/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt new file mode 100644 index 00000000..d9708e3e --- /dev/null +++ b/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt @@ -0,0 +1,80 @@ +package com.chipichipi.dobedobe.core.ui + +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.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.chipichipi.dobedobe.core.designsystem.component.DobeDobeTextButton +import com.chipichipi.dobedobe.core.designsystem.component.ThemePreviews +import com.chipichipi.dobedobe.core.designsystem.theme.DobeDobeTheme +import com.chipichipi.dobedobe.core.model.CharacterType + +@Composable +fun SelectCharacterScreen( + selectedCharacter: CharacterType, + onCharacterToggled: () -> Unit, + onCompleted: () -> Unit, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .fillMaxSize() + .padding(horizontal = 24.dp) + .padding( + top = 48.dp, + bottom = 32.dp, + ), + ) { + Text( + text = stringResource(R.string.select_character_title), + style = DobeDobeTheme.typography.heading1, + color = DobeDobeTheme.colors.black, + ) + Spacer(modifier = Modifier.height(48.dp)) + + BirdCard( + selected = selectedCharacter == CharacterType.Bird, + onClick = onCharacterToggled, + ) + Spacer(modifier = Modifier.height(32.dp)) + + RabbitCard( + selected = selectedCharacter == CharacterType.Rabbit, + onClick = onCharacterToggled, + ) + Spacer(modifier = Modifier.weight(1f)) + + DobeDobeTextButton( + modifier = Modifier + .fillMaxWidth() + .heightIn(56.dp), + onClick = onCompleted, + ) { + Text( + text = stringResource(R.string.all_complete), + style = DobeDobeTheme.typography.heading2, + color = DobeDobeTheme.colors.white, + ) + } + } +} + +@ThemePreviews +@Composable +private fun SelectCharacterScreenPreview() { + DobeDobeTheme { + SelectCharacterScreen( + selectedCharacter = CharacterType.Rabbit, + onCharacterToggled = {}, + onCompleted = {}, + ) + } +} diff --git a/app/src/main/res/drawable/onboarding_bird.png b/core/ui/src/main/res/drawable/bird_character.png similarity index 100% rename from app/src/main/res/drawable/onboarding_bird.png rename to core/ui/src/main/res/drawable/bird_character.png diff --git a/app/src/main/res/drawable/bubble_bird.png b/core/ui/src/main/res/drawable/bubble_bird.png similarity index 100% rename from app/src/main/res/drawable/bubble_bird.png rename to core/ui/src/main/res/drawable/bubble_bird.png diff --git a/app/src/main/res/drawable/bubble_rabbit.png b/core/ui/src/main/res/drawable/bubble_rabbit.png similarity index 100% rename from app/src/main/res/drawable/bubble_rabbit.png rename to core/ui/src/main/res/drawable/bubble_rabbit.png diff --git a/app/src/main/res/drawable/onboarding_rabbit.png b/core/ui/src/main/res/drawable/rabbit_character.png similarity index 100% rename from app/src/main/res/drawable/onboarding_rabbit.png rename to core/ui/src/main/res/drawable/rabbit_character.png diff --git a/core/ui/src/main/res/values-en/strings.xml b/core/ui/src/main/res/values-en/strings.xml new file mode 100644 index 00000000..ad83f168 --- /dev/null +++ b/core/ui/src/main/res/values-en/strings.xml @@ -0,0 +1,7 @@ + + + Please select your running mate + Start + Nagging Bird + Empathetic Lucky Rabbit + diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml new file mode 100644 index 00000000..9424f02b --- /dev/null +++ b/core/ui/src/main/res/values/strings.xml @@ -0,0 +1,7 @@ + + + 함께 할 러닝메이트를\n선택해 주세요 + 시작하기 + 마구 쪼는 잔소리무새 + 공감 만점 럭키 토끼 + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 860295ba..d44e6eea 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -32,6 +32,7 @@ include(":core:database") include(":core:datastore") include(":core:datastore-proto") include(":core:notifications") +include(":core:ui") include(":feature:dashboard") include(":feature:goal") From ed28e3adb04d95969c7eb64856614fcaecc1febc Mon Sep 17 00:00:00 2001 From: Junhyeok Date: Sat, 15 Feb 2025 01:10:25 +0900 Subject: [PATCH 2/4] =?UTF-8?q?=EC=BA=90=EB=A6=AD=ED=84=B0=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80=20(#70)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor : pass modifier * feat : add SelectCharacterDialog * feat : Add character change to settings * refactor : use string resources for button text * refactor : lint * feat : review * feat : contentDesc * refactor : en res --- .../OnboardingSelectCharacterScreen.kt | 13 ++- app/src/main/res/values-en/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + .../dobedobe/core/ui/SelectCharacterScreen.kt | 15 +-- core/ui/src/main/res/values-en/strings.xml | 1 - core/ui/src/main/res/values/strings.xml | 1 - .../dobedobe/feature/setting/SettingScreen.kt | 29 ++++++ .../feature/setting/SettingUiState.kt | 3 + .../feature/setting/SettingViewModel.kt | 14 ++- .../component/SelectCharacterDialog.kt | 97 +++++++++++++++++++ .../src/main/res/values-en/strings.xml | 2 + .../setting/src/main/res/values/strings.xml | 2 + 12 files changed, 165 insertions(+), 14 deletions(-) create mode 100644 feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/component/SelectCharacterDialog.kt diff --git a/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt b/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt index ca8bcbe3..2562afd0 100644 --- a/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt +++ b/app/src/main/kotlin/com/chipichipi/dobedobe/onboarding/OnboardingSelectCharacterScreen.kt @@ -1,9 +1,13 @@ package com.chipichipi.dobedobe.onboarding +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.chipichipi.dobedobe.R import com.chipichipi.dobedobe.core.ui.SelectCharacterScreen import org.koin.androidx.compose.koinViewModel @@ -15,9 +19,16 @@ internal fun OnboardingSelectCharacterRoute( val selectedCharacter by viewModel.selectedCharacter.collectAsStateWithLifecycle() SelectCharacterScreen( - modifier = modifier, selectedCharacter = selectedCharacter, onCharacterToggled = viewModel::toggleCharacter, onCompleted = viewModel::completeOnboarding, + buttonText = R.string.onboarding_all_completed, + modifier = modifier + .fillMaxSize() + .padding(horizontal = 24.dp) + .padding( + top = 48.dp, + bottom = 32.dp, + ), ) } diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml index f8d28921..d4f7778f 100644 --- a/app/src/main/res/values-en/strings.xml +++ b/app/src/main/res/values-en/strings.xml @@ -6,4 +6,5 @@ ex) Read 1 book per day The simpler the goal, the better the focus. Complete + Start \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8f38036b..08bfc032 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -5,4 +5,5 @@ ex) 1일 1책 읽기 목표가 간결할수록 집중력이 높아져요. 작성 완료 + 시작하기 \ No newline at end of file diff --git a/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt b/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt index d9708e3e..1ba49541 100644 --- a/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt +++ b/core/ui/src/main/kotlin/com/chipichipi/dobedobe/core/ui/SelectCharacterScreen.kt @@ -1,12 +1,11 @@ package com.chipichipi.dobedobe.core.ui +import androidx.annotation.StringRes 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.heightIn -import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -22,16 +21,11 @@ fun SelectCharacterScreen( selectedCharacter: CharacterType, onCharacterToggled: () -> Unit, onCompleted: () -> Unit, + @StringRes buttonText: Int, modifier: Modifier = Modifier, ) { Column( - modifier = modifier - .fillMaxSize() - .padding(horizontal = 24.dp) - .padding( - top = 48.dp, - bottom = 32.dp, - ), + modifier = modifier, ) { Text( text = stringResource(R.string.select_character_title), @@ -59,7 +53,7 @@ fun SelectCharacterScreen( onClick = onCompleted, ) { Text( - text = stringResource(R.string.all_complete), + text = stringResource(buttonText), style = DobeDobeTheme.typography.heading2, color = DobeDobeTheme.colors.white, ) @@ -75,6 +69,7 @@ private fun SelectCharacterScreenPreview() { selectedCharacter = CharacterType.Rabbit, onCharacterToggled = {}, onCompleted = {}, + buttonText = R.string.select_character_title, ) } } diff --git a/core/ui/src/main/res/values-en/strings.xml b/core/ui/src/main/res/values-en/strings.xml index ad83f168..a91eac67 100644 --- a/core/ui/src/main/res/values-en/strings.xml +++ b/core/ui/src/main/res/values-en/strings.xml @@ -1,7 +1,6 @@ Please select your running mate - Start Nagging Bird Empathetic Lucky Rabbit diff --git a/core/ui/src/main/res/values/strings.xml b/core/ui/src/main/res/values/strings.xml index 9424f02b..28f0f4dd 100644 --- a/core/ui/src/main/res/values/strings.xml +++ b/core/ui/src/main/res/values/strings.xml @@ -1,7 +1,6 @@ 함께 할 러닝메이트를\n선택해 주세요 - 시작하기 마구 쪼는 잔소리무새 공감 만점 럭키 토끼 \ No newline at end of file diff --git a/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingScreen.kt b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingScreen.kt index d2797798..bd341782 100644 --- a/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -25,8 +26,10 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.chipichipi.dobedobe.core.designsystem.component.DobeDobeSwitch import com.chipichipi.dobedobe.core.designsystem.icon.DobeDobeIcons import com.chipichipi.dobedobe.core.designsystem.theme.DobeDobeTheme +import com.chipichipi.dobedobe.core.model.CharacterType import com.chipichipi.dobedobe.core.notifications.NotificationUtil import com.chipichipi.dobedobe.core.notifications.NotificationUtil.areNotificationsEnabled +import com.chipichipi.dobedobe.feature.setting.component.SelectCharacterDialog import com.chipichipi.dobedobe.feature.setting.component.SettingRow import com.chipichipi.dobedobe.feature.setting.component.SettingTopAppBar import com.chipichipi.dobedobe.feature.setting.util.openPlayStore @@ -46,6 +49,7 @@ internal fun SettingRoute( uiState = settingUiState, navigateToBack = navigateToBack, onNotificationToggled = viewModel::setGoalNotificationEnabled, + onCharacterChangeCompleted = viewModel::changeCharacterCompleted, ) } @@ -54,6 +58,7 @@ private fun SettingScreen( uiState: SettingUiState, navigateToBack: () -> Unit, onNotificationToggled: (Boolean) -> Unit, + onCharacterChangeCompleted: (CharacterType) -> Unit, modifier: Modifier = Modifier, ) { Scaffold( @@ -81,6 +86,8 @@ private fun SettingScreen( SettingBody( isGoalNotificationEnabled = uiState.isGoalNotificationEnabled, onNotificationToggled = onNotificationToggled, + characterType = uiState.characterType, + onCharacterChangeCompleted = onCharacterChangeCompleted, ) } } @@ -96,9 +103,12 @@ private fun SettingScreen( private fun SettingBody( isGoalNotificationEnabled: Boolean, onNotificationToggled: (Boolean) -> Unit, + characterType: CharacterType, + onCharacterChangeCompleted: (CharacterType) -> Unit, modifier: Modifier = Modifier, ) { val context = LocalContext.current + var showSelectCharacterDialog by rememberSaveable { mutableStateOf(false) } val handleNotificationToggle: (Boolean) -> Unit = { enabled -> NotificationUtil.handleNotificationToggle( @@ -108,6 +118,14 @@ private fun SettingBody( ) } + if (showSelectCharacterDialog) { + SelectCharacterDialog( + onDismissRequest = { showSelectCharacterDialog = false }, + characterType = characterType, + onCharacterChangeCompleted = onCharacterChangeCompleted, + ) + } + Column( modifier = modifier .fillMaxSize(), @@ -137,6 +155,17 @@ private fun SettingBody( tint = Color.Unspecified, ) } + + SettingRow( + label = stringResource(R.string.feature_setting_change_character), + onClick = { showSelectCharacterDialog = true }, + ) { + Icon( + painter = painterResource(DobeDobeIcons.ArrowForward), + contentDescription = null, + tint = Color.Unspecified, + ) + } } } diff --git a/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingUiState.kt b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingUiState.kt index 3183fb71..81463d31 100644 --- a/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingUiState.kt +++ b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingUiState.kt @@ -1,9 +1,12 @@ package com.chipichipi.dobedobe.feature.setting +import com.chipichipi.dobedobe.core.model.CharacterType + sealed interface SettingUiState { data object Loading : SettingUiState data class Success( val isGoalNotificationEnabled: Boolean, + val characterType: CharacterType, ) : SettingUiState } diff --git a/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingViewModel.kt b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingViewModel.kt index 220f0046..d8e4227b 100644 --- a/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingViewModel.kt +++ b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/SettingViewModel.kt @@ -3,6 +3,7 @@ package com.chipichipi.dobedobe.feature.setting import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.chipichipi.dobedobe.core.data.repository.UserRepository +import com.chipichipi.dobedobe.core.model.CharacterType import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.stateIn @@ -12,7 +13,12 @@ internal class SettingViewModel( private val userRepository: UserRepository, ) : ViewModel() { val settingUiState = userRepository.userData - .map { SettingUiState.Success(it.isGoalNotificationEnabled) } + .map { user -> + SettingUiState.Success( + isGoalNotificationEnabled = user.isGoalNotificationEnabled, + characterType = user.characterType, + ) + } .stateIn( scope = viewModelScope, started = SharingStarted.WhileSubscribed(5_000), @@ -24,4 +30,10 @@ internal class SettingViewModel( userRepository.setGoalNotificationEnabled(checked) } } + + fun changeCharacterCompleted(type: CharacterType) { + viewModelScope.launch { + userRepository.saveCharacter(type) + } + } } diff --git a/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/component/SelectCharacterDialog.kt b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/component/SelectCharacterDialog.kt new file mode 100644 index 00000000..2dda9c0e --- /dev/null +++ b/feature/setting/src/main/kotlin/com/chipichipi/dobedobe/feature/setting/component/SelectCharacterDialog.kt @@ -0,0 +1,97 @@ +package com.chipichipi.dobedobe.feature.setting.component + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Cancel +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.chipichipi.dobedobe.core.designsystem.component.ThemePreviews +import com.chipichipi.dobedobe.core.designsystem.theme.DobeDobeTheme +import com.chipichipi.dobedobe.core.model.CharacterType +import com.chipichipi.dobedobe.core.ui.SelectCharacterScreen +import com.chipichipi.dobedobe.feature.setting.R + +@Composable +internal fun SelectCharacterDialog( + onDismissRequest: () -> Unit, + characterType: CharacterType, + onCharacterChangeCompleted: (CharacterType) -> Unit, +) { + var selectedCharacterType by rememberSaveable { mutableStateOf(characterType) } + + Dialog( + onDismissRequest = onDismissRequest, + properties = DialogProperties( + usePlatformDefaultWidth = false, + ), + ) { + Surface( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp), + shape = RoundedCornerShape(16.dp), + color = DobeDobeTheme.colors.white, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(top = 10.dp, bottom = 32.dp), + ) { + IconButton( + modifier = Modifier.align(Alignment.End), + onClick = onDismissRequest, + ) { + Icon( + imageVector = Icons.Filled.Cancel, + contentDescription = "close", + ) + } + + SelectCharacterScreen( + selectedCharacter = selectedCharacterType, + onCompleted = { + onCharacterChangeCompleted(selectedCharacterType) + onDismissRequest() + }, + onCharacterToggled = { + selectedCharacterType = if (selectedCharacterType == CharacterType.Rabbit) { + CharacterType.Bird + } else { + CharacterType.Rabbit + } + }, + buttonText = R.string.feature_setting_change_character_completed, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 24.dp), + ) + } + } + } +} + +@ThemePreviews +@Composable +private fun SelectCharacterDialogPreview() { + DobeDobeTheme { + SelectCharacterDialog( + onDismissRequest = {}, + characterType = CharacterType.Rabbit, + onCharacterChangeCompleted = {}, + ) + } +} diff --git a/feature/setting/src/main/res/values-en/strings.xml b/feature/setting/src/main/res/values-en/strings.xml index a99607a2..14a90cab 100644 --- a/feature/setting/src/main/res/values-en/strings.xml +++ b/feature/setting/src/main/res/values-en/strings.xml @@ -3,4 +3,6 @@ Setting Leave App Feedback Notification + Change Character + Confirm Change \ No newline at end of file diff --git a/feature/setting/src/main/res/values/strings.xml b/feature/setting/src/main/res/values/strings.xml index 2206ae42..2c2a5a52 100644 --- a/feature/setting/src/main/res/values/strings.xml +++ b/feature/setting/src/main/res/values/strings.xml @@ -3,4 +3,6 @@ 설정 앱 피드백 남기기 알림 + 캐릭터 변경하기 + 변경하기 \ No newline at end of file From fccc4ee01b99fb39ed280552824637332fee9763 Mon Sep 17 00:00:00 2001 From: JUNWON LEE Date: Sat, 15 Feb 2025 01:55:54 +0900 Subject: [PATCH 3/4] =?UTF-8?q?Status=20Bar=20=EB=9D=BC=EC=9D=B4=ED=8A=B8?= =?UTF-8?q?=20=EB=AA=A8=EB=93=9C=EB=A1=9C=20=EA=B0=95=EC=A0=9C=ED=99=94=20?= =?UTF-8?q?(#68)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: enforce light status bar * feat: enforce status bar light mode --- .../kotlin/com/chipichipi/dobedobe/MainActivity.kt | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/com/chipichipi/dobedobe/MainActivity.kt b/app/src/main/kotlin/com/chipichipi/dobedobe/MainActivity.kt index bf1d83c5..a51d5a43 100644 --- a/app/src/main/kotlin/com/chipichipi/dobedobe/MainActivity.kt +++ b/app/src/main/kotlin/com/chipichipi/dobedobe/MainActivity.kt @@ -3,8 +3,11 @@ package com.chipichipi.dobedobe import android.content.pm.ActivityInfo import android.os.Bundle import androidx.activity.ComponentActivity +import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -26,7 +29,12 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) ActivityInfo.SCREEN_ORIENTATION_PORTRAIT.also { requestedOrientation = it } - enableEdgeToEdge() + enableEdgeToEdge( + statusBarStyle = SystemBarStyle.light( + Color.Transparent.toArgb(), + Color.Transparent.toArgb(), + ), + ) lifecycleScope.launch { lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) { From 15e478b572ccbf6b8d68b56dc43a15c2f7c5d8ff Mon Sep 17 00:00:00 2001 From: JUNWON LEE Date: Sat, 15 Feb 2025 01:56:11 +0900 Subject: [PATCH 4/4] =?UTF-8?q?=EB=A7=90=ED=92=8D=EC=84=A0=20=EB=94=94?= =?UTF-8?q?=ED=85=8C=EC=9D=BC=20=EC=9E=A1=EA=B8=B0=20(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: Bubble logic * feat: when bubble click, go to detail screen * chore: remove bubble logic comments --- .../feature/dashboard/DashboardScreen.kt | 4 +- .../feature/dashboard/DashboardUiState.kt | 3 +- .../feature/dashboard/DashboardViewModel.kt | 118 +++++++++++------- .../dashboard/component/DashboardCharacter.kt | 3 + .../dashboard/component/DashboardViewMode.kt | 13 +- .../feature/dashboard/model/BubbleGoal.kt | 18 +++ 6 files changed, 107 insertions(+), 52 deletions(-) create mode 100644 feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/model/BubbleGoal.kt diff --git a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardScreen.kt b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardScreen.kt index 2dbdcd00..2453a024 100644 --- a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardScreen.kt +++ b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardScreen.kt @@ -126,7 +126,6 @@ private fun DashboardScreen( navigateToSetting = navigateToSetting, navigateToSearchGoal = navigateToSearchGoal, onGoalToggled = onGoalToggled, - // TODO: 캐릭터 누르면 말풍선 바뀌는걸로 옮기기! onChangeBubble = onChangeBubble, onToggleMode = onToggleMode, onUpsertPhotos = onUpsertPhotos, @@ -217,11 +216,12 @@ private fun DashboardBody( DashboardViewMode( isViewMode = !isEditMode, photoState = uiState.photoState, - bubbleTitle = uiState.bubbleTitle, + bubbleGoal = uiState.bubbleGoal, photoFramesState = photoFramesState, onChangeBubble = onChangeBubble, onToggleExpansion = onToggleExpansion, onToggleMode = onToggleMode, + navigateToGoalDetail = navigateToGoalDetail, navigateToSetting = navigateToSetting, character = uiState.character, ) diff --git a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardUiState.kt b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardUiState.kt index 133f1acb..f0c165c2 100644 --- a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardUiState.kt +++ b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardUiState.kt @@ -2,6 +2,7 @@ package com.chipichipi.dobedobe.feature.dashboard import com.chipichipi.dobedobe.core.model.CharacterType import com.chipichipi.dobedobe.core.model.Goal +import com.chipichipi.dobedobe.feature.dashboard.model.BubbleGoal import com.chipichipi.dobedobe.feature.dashboard.model.DashboardPhotoState sealed interface DashboardUiState { @@ -11,7 +12,7 @@ sealed interface DashboardUiState { val photoState: List, val isSystemNotificationDialogDisabled: Boolean, val goals: List, - val bubbleTitle: String, + val bubbleGoal: BubbleGoal, val character: CharacterType, ) : DashboardUiState diff --git a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardViewModel.kt b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardViewModel.kt index 9c7970e1..c9e4eec0 100644 --- a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardViewModel.kt +++ b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/DashboardViewModel.kt @@ -9,6 +9,7 @@ import com.chipichipi.dobedobe.core.data.repository.GoalRepository import com.chipichipi.dobedobe.core.data.repository.UserRepository import com.chipichipi.dobedobe.core.model.DashboardPhoto import com.chipichipi.dobedobe.core.model.Goal +import com.chipichipi.dobedobe.feature.dashboard.model.BubbleGoal import com.chipichipi.dobedobe.feature.dashboard.model.DashboardModeState import com.chipichipi.dobedobe.feature.dashboard.model.DashboardPhotoConfig import com.chipichipi.dobedobe.feature.dashboard.model.DashboardPhotoState @@ -21,8 +22,9 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onStart +import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.runningFold import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -73,7 +75,7 @@ internal class DashboardViewModel( photoState = dashboardPhotoStates, isSystemNotificationDialogDisabled = isSystemNotificationDialogDisabled, goals = goals, - bubbleTitle = bubbleGoal.title, + bubbleGoal = bubbleGoal, character = character, ) } @@ -163,58 +165,82 @@ internal class DashboardViewModel( } } - /** - * bubbleGoal 을 random 으로 변경하는 로직 - * - * - todoGoals 가 empty 일 경우, Empty BubbleGoal 을 반환 - * - todoGoals 가 empty 가 아닌 경우 - * - * 1) goalRepository 에 있는 goal 이 변경될 경우 - * 1-1) old goals 와 new goals 가 다르면 변경 - * 1-2) 만약, bubbleGoal 의 id 가 todoGoals 에 포함되어 있으면 변경 - * - * 2) changeBubbleEvent 가 발생할 경우 - * - 무조건 random 하게 변경 - * */ private fun bubbleGoalFlow(): Flow { - val todoGoals: Flow> = goalRepository.getTodoGoals() - .distinctUntilChanged() - .distinctUntilChanged { _, new -> - val id = bubbleGoal.value.id - val isBubbleGoalCompleted = new.any { it.id == id } - isBubbleGoalCompleted - } + val events: Flow = merge( + goalRepository.getTodoGoals().map { goals -> BubbleGoalEvent.GoalsChanged(goals) }, + changeBubbleEvent.receiveAsFlow().map { BubbleGoalEvent.BubbleChanged }, + ) - return combine( - todoGoals, - changeBubbleEvent.receiveAsFlow().onStart { - emit(Unit) - }, - ) { goals, _ -> - goals.filter { it.id != bubbleGoal.value.id }.shuffled() - } - .map(List::firstOrNull) - .map { goal -> - if (goal != null) { - BubbleGoal.from(goal) - } else { - BubbleGoal.empty() + return events + .runningFold(BubbleGoal.empty() to emptyList()) { acc, event -> + val (currentBubble, latestGoals) = acc + + when (event) { + is BubbleGoalEvent.GoalsChanged -> handleGoalsChangedEvent( + event.goals, + currentBubble, + ) + + is BubbleGoalEvent.BubbleChanged -> handleBubbleChangedEvent( + latestGoals, + currentBubble, + ) } } + .map { it.first } } - private data class BubbleGoal( - val title: String, - val id: Long?, - ) { - companion object { - private val Empty = BubbleGoal(title = "", id = null) + /** + * goals 이 변경될 때(e. toggle, delete) BubbleGoal 을 업데이트하는 함수. + * + * 1) BubbleGoal 이 goals 에 포함되어 있으면 그대로 유지 + * 2) BubbleGoal 이 goals 에 포함 x + * - goals 이 비어있으면 empty 상태로 반환 + * - goals 이 존재하면 랜덤으로 선택하여 새로운 BubbleGoal 을 생성 + * */ + private fun handleGoalsChangedEvent( + goals: List, + currentBubble: BubbleGoal, + ): Pair> { + val containsCurrentBubble = goals.any { it.id == currentBubble.id } + + if (containsCurrentBubble) { + return currentBubble to goals + } - fun empty(): BubbleGoal = Empty + if (goals.isEmpty()) { + return BubbleGoal.empty() to goals + } - fun from(goal: Goal): BubbleGoal { - return BubbleGoal(goal.title, goal.id) - } + val newGoal = goals.random() + return BubbleGoal.from(newGoal) to goals + } + + /** + * 버블 변경 이벤트(BubbleChanged)가 발생했을 때 현재 BubbleGoal 을 업데이트하는 함수. + * + * candidates: 현재 BubbleGoal 을 제외한 후보 목록 + * + * 1) 후보 목록이 비어있으면 현재 BubbleGoal 을 그대로 반환 + * 2) 후보 목록이 존재하면 후보 목록 중 랜덤으로 선택하여 새로운 BubbleGoal 을 생성 + * */ + private fun handleBubbleChangedEvent( + goals: List, + currentBubble: BubbleGoal, + ): Pair> { + val candidates = goals.filter { it.id != currentBubble.id } + + return if (candidates.isEmpty()) { + currentBubble to goals + } else { + val newGoal = candidates.random() + BubbleGoal.from(newGoal) to goals } } + + private sealed class BubbleGoalEvent { + data class GoalsChanged(val goals: List) : BubbleGoalEvent() + + data object BubbleChanged : BubbleGoalEvent() + } } diff --git a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardCharacter.kt b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardCharacter.kt index 860a54c9..fefc2d00 100644 --- a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardCharacter.kt +++ b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardCharacter.kt @@ -31,6 +31,7 @@ internal fun DashboardCharacter( @RawRes defaultApngRes: Int, @RawRes reactionApngRes: Int, @DrawableRes placeholder: Int, + onChangeBubble: () -> Unit, modifier: Modifier = Modifier, ) { val context = LocalContext.current @@ -45,6 +46,7 @@ internal fun DashboardCharacter( LaunchedEffect(isResetTrigger) { if (isResetTrigger) { + onChangeBubble() delay(4000) currentRaw = defaultApngRes isResetTrigger = false @@ -81,6 +83,7 @@ private fun DashboardCharacterPreview() { defaultApngRes = R.raw.rabbit01, reactionApngRes = R.raw.rabbit02, placeholder = R.drawable.rabbit_placeholder, + onChangeBubble = {}, ) } } diff --git a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardViewMode.kt b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardViewMode.kt index 565f312c..dbf80a92 100644 --- a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardViewMode.kt +++ b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/component/DashboardViewMode.kt @@ -19,6 +19,7 @@ import androidx.compose.ui.zIndex import com.chipichipi.dobedobe.core.designsystem.theme.DobeDobeTheme import com.chipichipi.dobedobe.core.model.CharacterType import com.chipichipi.dobedobe.feature.dashboard.DashboardPhotoFramesState +import com.chipichipi.dobedobe.feature.dashboard.model.BubbleGoal import com.chipichipi.dobedobe.feature.dashboard.model.CharacterResources import com.chipichipi.dobedobe.feature.dashboard.model.DashboardPhotoState @@ -27,12 +28,13 @@ import com.chipichipi.dobedobe.feature.dashboard.model.DashboardPhotoState internal fun SharedTransitionScope.DashboardViewMode( isViewMode: Boolean, photoState: List, - bubbleTitle: String, + bubbleGoal: BubbleGoal, photoFramesState: DashboardPhotoFramesState, onChangeBubble: () -> Unit, onToggleExpansion: (Int) -> Unit, onToggleMode: () -> Unit, navigateToSetting: () -> Unit, + navigateToGoalDetail: (Long) -> Unit, character: CharacterType, modifier: Modifier = Modifier, ) { @@ -76,13 +78,17 @@ internal fun SharedTransitionScope.DashboardViewMode( ) { Spacer(Modifier.height(14.dp)) DashboardBubble( - title = bubbleTitle, + title = bubbleGoal.title, textStyle = DobeDobeTheme.typography.body2, modifier = Modifier .background( color = DobeDobeTheme.colors.white, ), - onClick = onChangeBubble, + onClick = { + if (bubbleGoal.id != null) { + navigateToGoalDetail(bubbleGoal.id) + } + }, ) DashboardCharacter( modifier = Modifier @@ -91,6 +97,7 @@ internal fun SharedTransitionScope.DashboardViewMode( defaultApngRes = resources.defaultApngRes, reactionApngRes = resources.reactionApngRes, placeholder = resources.placeholderRes, + onChangeBubble = onChangeBubble, ) } } diff --git a/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/model/BubbleGoal.kt b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/model/BubbleGoal.kt new file mode 100644 index 00000000..1f720ad5 --- /dev/null +++ b/feature/dashboard/src/main/kotlin/com/chipichipi/dobedobe/feature/dashboard/model/BubbleGoal.kt @@ -0,0 +1,18 @@ +package com.chipichipi.dobedobe.feature.dashboard.model + +import com.chipichipi.dobedobe.core.model.Goal + +data class BubbleGoal( + val title: String, + val id: Long?, +) { + companion object { + private val Empty = BubbleGoal(title = "", id = null) + + fun empty(): BubbleGoal = Empty + + fun from(goal: Goal): BubbleGoal { + return BubbleGoal(goal.title, goal.id) + } + } +}