From 2fa1cd6c0a187924a7cf653f3a4297033507a973 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Thu, 2 May 2024 21:21:32 +0900 Subject: [PATCH 01/41] #82 chore : add feature:setting --- feature/setting/build.gradle.kts | 10 +++++++++ .../setting/ExampleInstrumentedTest.kt | 22 +++++++++++++++++++ feature/setting/src/main/AndroidManifest.xml | 4 ++++ .../app/feature/setting/ExampleUnitTest.kt | 16 ++++++++++++++ settings.gradle.kts | 1 + 5 files changed, 53 insertions(+) create mode 100644 feature/setting/build.gradle.kts create mode 100644 feature/setting/src/androidTest/kotlin/com/titi/app/feature/setting/ExampleInstrumentedTest.kt create mode 100644 feature/setting/src/main/AndroidManifest.xml create mode 100644 feature/setting/src/test/kotlin/com/titi/app/feature/setting/ExampleUnitTest.kt diff --git a/feature/setting/build.gradle.kts b/feature/setting/build.gradle.kts new file mode 100644 index 00000000..63109244 --- /dev/null +++ b/feature/setting/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("titi.android.feature") +} + +android { + namespace = "com.titi.app.feature.setting" +} + +dependencies { +} diff --git a/feature/setting/src/androidTest/kotlin/com/titi/app/feature/setting/ExampleInstrumentedTest.kt b/feature/setting/src/androidTest/kotlin/com/titi/app/feature/setting/ExampleInstrumentedTest.kt new file mode 100644 index 00000000..1f19630a --- /dev/null +++ b/feature/setting/src/androidTest/kotlin/com/titi/app/feature/setting/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package com.titi.app.feature.setting + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.platform.app.InstrumentationRegistry +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.titi.app.feature.setting.test", appContext.packageName) + } +} diff --git a/feature/setting/src/main/AndroidManifest.xml b/feature/setting/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/feature/setting/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/feature/setting/src/test/kotlin/com/titi/app/feature/setting/ExampleUnitTest.kt b/feature/setting/src/test/kotlin/com/titi/app/feature/setting/ExampleUnitTest.kt new file mode 100644 index 00000000..ef0f6baa --- /dev/null +++ b/feature/setting/src/test/kotlin/com/titi/app/feature/setting/ExampleUnitTest.kt @@ -0,0 +1,16 @@ +package com.titi.app.feature.setting + +import org.junit.Assert.assertEquals +import org.junit.Test + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 93be0a03..d196e10d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -46,3 +46,4 @@ include(":feature:popup") include(":feature:log") include(":data:graph:impl") include(":data:graph:api") +include(":feature:setting") From 4494e579eb91a472ca064a1b76d0498857abbe51 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Thu, 2 May 2024 22:35:44 +0900 Subject: [PATCH 02/41] #82 feat : add grouped color --- .../kotlin/com/titi/app/core/designsystem/theme/Color.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/theme/Color.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/theme/Color.kt index ae959416..233ccfa1 100644 --- a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/theme/Color.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/theme/Color.kt @@ -21,6 +21,7 @@ data class TdsColorsPalette( val textColor: Color = Color.Unspecified, val backgroundColor: Color = Color.Unspecified, val secondaryBackgroundColor: Color = Color.Unspecified, + val groupedBackgroundColor: Color = Color.Unspecified, val switchBackgroundColor: Color = Color.Unspecified, val alertBackgroundColor: Color = Color.Unspecified, val tertiaryBackgroundColor: Color = Color.Unspecified, @@ -52,7 +53,8 @@ val TdsLightColorsPalette = TdsColorsPalette( d12 = Color(0xFF928AEA), textColor = Color(0xFF000000), backgroundColor = Color(0xFFFFFFFF), - secondaryBackgroundColor = Color(0xFFF2F2F7), + secondaryBackgroundColor = Color(0xFFFFFFFF), + groupedBackgroundColor = Color(0xFFF2F2F7), switchBackgroundColor = Color(0xFFE9E9EB), alertBackgroundColor = Color(0xD1EEEEEE), tertiaryBackgroundColor = Color(0xFFFFFFFF), @@ -85,6 +87,7 @@ val TdsDarkColorsPalette = TdsColorsPalette( textColor = Color(0xFFFFFFFF), backgroundColor = Color(0xFF000000), secondaryBackgroundColor = Color(0xFF1C1C1E), + groupedBackgroundColor = Color(0xFF000000), switchBackgroundColor = Color(0xFF39393D), alertBackgroundColor = Color(0xD12B2B2B), tertiaryBackgroundColor = Color(0xFF2C2C2E), @@ -118,6 +121,7 @@ enum class TdsColor { TEXT, BACKGROUND, SECONDARY_BACKGROUND, + GROUPED_BACKGROUND, SWITCH_BACKGROUND, ALERT_BACKGROUND, TERTIARY_BACKGROUND, @@ -154,6 +158,7 @@ enum class TdsColor { TEXT -> TiTiTheme.colors.textColor BACKGROUND -> TiTiTheme.colors.backgroundColor SECONDARY_BACKGROUND -> TiTiTheme.colors.secondaryBackgroundColor + GROUPED_BACKGROUND -> TiTiTheme.colors.groupedBackgroundColor SWITCH_BACKGROUND -> TiTiTheme.colors.switchBackgroundColor ALERT_BACKGROUND -> TiTiTheme.colors.alertBackgroundColor TERTIARY_BACKGROUND -> TiTiTheme.colors.tertiaryBackgroundColor From bbc252ed9d4822a2ca5454efaeaf7f66accbe7a5 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Thu, 2 May 2024 22:37:22 +0900 Subject: [PATCH 03/41] #82 feat : SettingScreen --- .../titi/app/feature/setting/SettingScreen.kt | 235 ++++++++++++++++++ 1 file changed, 235 insertions(+) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/SettingScreen.kt diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/SettingScreen.kt new file mode 100644 index 00000000..779e7600 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/SettingScreen.kt @@ -0,0 +1,235 @@ +package com.titi.app.feature.setting + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Icon +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Switch +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.PreviewLightDark +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.titi.app.core.designsystem.R +import com.titi.app.core.designsystem.component.TdsText +import com.titi.app.core.designsystem.theme.TdsColor +import com.titi.app.core.designsystem.theme.TdsTextStyle +import com.titi.app.core.designsystem.theme.TiTiTheme + +@Composable +fun SettingScreen() { + val scrollState = rememberScrollState() + + Scaffold(containerColor = Color.Transparent) { + Column( + modifier = Modifier + .fillMaxSize() + .background(color = TdsColor.GROUPED_BACKGROUND.getColor()) + .padding(it) + .verticalScroll(scrollState), + ) { + Spacer(modifier = Modifier.height(64.dp)) + + TdsText( + modifier = Modifier.padding(start = 16.dp), + text = "Setting", + textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, + fontSize = 34.sp, + color = TdsColor.TEXT, + ) + + Spacer(modifier = Modifier.height(35.dp)) + + SettingServiceSection() + + Spacer(modifier = Modifier.height(35.dp)) + + SettingNotificationSection() + + Spacer(modifier = Modifier.height(35.dp)) + + SettingVersionSection() + + Spacer(modifier = Modifier.height(35.dp)) + } + } +} + +@Composable +private fun SettingServiceSection() { + TdsText( + modifier = Modifier.padding(start = 16.dp), + text = "서비스", + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + fontSize = 14.sp, + color = TdsColor.TEXT, + ) + + Spacer(modifier = Modifier.height(4.dp)) + + SettingRowContent( + title = "TiTi 기능들", + rightAreaContent = { + Icon( + painter = painterResource(id = R.drawable.arrow_right_icon), + contentDescription = "", + tint = TdsColor.LIGHT_GRAY.getColor(), + ) + }, + onClick = {}, + ) +} + +@Composable +private fun SettingNotificationSection() { + TdsText( + modifier = Modifier.padding(start = 16.dp), + text = "알림", + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + fontSize = 14.sp, + color = TdsColor.TEXT, + ) + + Spacer(modifier = Modifier.height(4.dp)) + + SettingRowContent( + title = "타이머", + description = "종료 5분전 알림", + rightAreaContent = { + Switch( + checked = true, + onCheckedChange = {}, + ) + }, + onClick = {}, + ) + + Spacer(modifier = Modifier.height(1.dp)) + + SettingRowContent( + title = "타이머", + description = "종료 알림", + rightAreaContent = { + Switch( + checked = true, + onCheckedChange = {}, + ) + }, + onClick = {}, + ) + + Spacer(modifier = Modifier.height(1.dp)) + + SettingRowContent( + title = "스톱워치", + description = "1시간단위 경과시 알림", + rightAreaContent = { + Switch( + checked = true, + onCheckedChange = {}, + ) + }, + onClick = {}, + ) +} + +@Composable +private fun SettingVersionSection() { + TdsText( + modifier = Modifier.padding(start = 16.dp), + text = "버전 및 업데이트 내역", + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + fontSize = 14.sp, + color = TdsColor.TEXT, + ) + + Spacer(modifier = Modifier.height(4.dp)) + + SettingRowContent( + title = "버전 정보", + description = "최신버전: 7.17.1", + rightAreaContent = { + Icon( + painter = painterResource(id = R.drawable.arrow_right_icon), + contentDescription = "", + tint = TdsColor.LIGHT_GRAY.getColor(), + ) + }, + onClick = {}, + ) + + Spacer(modifier = Modifier.height(1.dp)) + + SettingRowContent( + title = "업데이트 내역", + rightAreaContent = { + Icon( + painter = painterResource(id = R.drawable.arrow_right_icon), + contentDescription = "", + tint = TdsColor.LIGHT_GRAY.getColor(), + ) + }, + onClick = {}, + ) +} + +@Composable +private fun SettingRowContent( + title: String, + description: String? = null, + rightAreaContent: @Composable () -> Unit, + onClick: () -> Unit, +) { + Row( + modifier = Modifier + .fillMaxSize() + .background(TdsColor.SECONDARY_BACKGROUND.getColor()) + .clickable { onClick() } + .padding( + horizontal = 16.dp, + vertical = 14.dp, + ), + verticalAlignment = Alignment.CenterVertically, + ) { + Column(modifier = Modifier.weight(1f)) { + TdsText( + text = title, + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + fontSize = 17.sp, + color = TdsColor.TEXT, + ) + + Spacer(modifier = Modifier.height(4.dp)) + + description?.let { + TdsText( + text = it, + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + fontSize = 11.sp, + color = TdsColor.LIGHT_GRAY, + ) + } + } + + rightAreaContent() + } +} + +@PreviewLightDark +@Composable +private fun SettingScreenPreview() { + TiTiTheme { + SettingScreen() + } +} From adf833b8faf32f5f17a9bb5f2b722b6e675bc7aa Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Thu, 2 May 2024 22:57:03 +0900 Subject: [PATCH 04/41] #82 feat : navigate setting --- .../src/main/res/values/strings.xml | 1 + feature/main/build.gradle.kts | 1 + .../feature/main/navigation/TiTiNavHost.kt | 3 +++ .../main/navigation/TopLevelDestination.kt | 4 ++++ .../titi/app/feature/main/ui/TiTiAppState.kt | 5 +++++ .../setting/navigation/SettingNavigation.kt | 20 +++++++++++++++++++ .../feature/setting/{ => ui}/SettingScreen.kt | 4 +--- 7 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt rename feature/setting/src/main/kotlin/com/titi/app/feature/setting/{ => ui}/SettingScreen.kt (98%) diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml index c62fe299..4293cc48 100644 --- a/core/designsystem/src/main/res/values/strings.xml +++ b/core/designsystem/src/main/res/values/strings.xml @@ -3,6 +3,7 @@ Timer Stopwatch Log + Setting 누적 시간 타이머 diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts index d6b9fd69..de53ea5a 100644 --- a/feature/main/build.gradle.kts +++ b/feature/main/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { implementation(project(":feature:time")) implementation(project(":feature:log")) implementation(project(":feature:popup")) + implementation(project(":feature:setting")) implementation(libs.androidx.splashscreen) implementation(libs.androidx.material3.window.size) diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt index cda2d56f..5a5c0d49 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt @@ -14,6 +14,7 @@ import com.titi.app.feature.main.ui.TiTiAppState import com.titi.app.feature.popup.PopUpActivity import com.titi.app.feature.popup.PopUpActivity.Companion.COLOR_RECORDING_MODE_KEY import com.titi.app.feature.popup.PopUpActivity.Companion.MEASURE_SPLASH_RESULT_KEY +import com.titi.app.feature.setting.navigation.settingGraph import com.titi.app.feature.time.navigation.STOPWATCH_SCREEN import com.titi.app.feature.time.navigation.TIMER_SCREEN import com.titi.app.feature.time.navigation.timeGraph @@ -61,5 +62,7 @@ fun TiTiNavHost( ) logGraph() + + settingGraph() } } diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TopLevelDestination.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TopLevelDestination.kt index 9ebcf6fe..436574a3 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TopLevelDestination.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TopLevelDestination.kt @@ -20,4 +20,8 @@ enum class TopLevelDestination( titleTextId = R.string.bottom_log_text, iconResourceId = R.drawable.log_icon, ), + SETTING( + titleTextId = R.string.bottom_setting_text, + iconResourceId = R.drawable.setting_icon, + ), } diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt index bceb18f0..5ab4e70f 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt @@ -15,6 +15,8 @@ import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.feature.log.navigation.LOG_ROUTE import com.titi.app.feature.log.navigation.navigateToLog import com.titi.app.feature.main.navigation.TopLevelDestination +import com.titi.app.feature.setting.navigation.SETTING_ROUTE +import com.titi.app.feature.setting.navigation.navigateToSetting import com.titi.app.feature.time.navigation.STOPWATCH_ROUTE import com.titi.app.feature.time.navigation.TIMER_ROUTE import com.titi.app.feature.time.navigation.navigateToStopWatch @@ -64,6 +66,7 @@ class TiTiAppState( TIMER_ROUTE -> TopLevelDestination.TIMER STOPWATCH_ROUTE -> TopLevelDestination.STOPWATCH LOG_ROUTE -> TopLevelDestination.LOG + SETTING_ROUTE -> TopLevelDestination.SETTING else -> null } @@ -82,6 +85,7 @@ class TiTiAppState( TIMER_ROUTE -> timeColor.timerBackgroundColor STOPWATCH_ROUTE -> timeColor.stopwatchBackgroundColor LOG_ROUTE -> if (isSystemDarkTheme) 0xFF000000 else 0xFFFFFFFF + SETTING_ROUTE -> if (isSystemDarkTheme) 0xFF000000 else 0xFFFFFFFF else -> 0xFF000000 } } @@ -106,6 +110,7 @@ class TiTiAppState( TopLevelDestination.TIMER -> navController.navigateToTimer(topLevelNavOptions) TopLevelDestination.STOPWATCH -> navController.navigateToStopWatch(topLevelNavOptions) TopLevelDestination.LOG -> navController.navigateToLog(topLevelNavOptions) + TopLevelDestination.SETTING -> navController.navigateToSetting(topLevelNavOptions) } } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt new file mode 100644 index 00000000..ecdf66dc --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt @@ -0,0 +1,20 @@ +package com.titi.app.feature.setting.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.titi.app.feature.setting.ui.SettingScreen + +private const val SETTING_SCREEN = "setting" +const val SETTING_ROUTE = SETTING_SCREEN + +fun NavController.navigateToSetting(navOptions: NavOptions) { + navigate(SETTING_ROUTE, navOptions) +} + +fun NavGraphBuilder.settingGraph() { + composable(route = SETTING_ROUTE) { + SettingScreen() + } +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt similarity index 98% rename from feature/setting/src/main/kotlin/com/titi/app/feature/setting/SettingScreen.kt rename to feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index 779e7600..509d37e5 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.setting +package com.titi.app.feature.setting.ui import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -39,8 +39,6 @@ fun SettingScreen() { .padding(it) .verticalScroll(scrollState), ) { - Spacer(modifier = Modifier.height(64.dp)) - TdsText( modifier = Modifier.padding(start = 16.dp), text = "Setting", From b4c417e174bca51d13a641385e6406899e4bae8a Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Fri, 3 May 2024 15:40:34 +0900 Subject: [PATCH 05/41] #82 feat : SettingUiState --- .../app/feature/setting/di/ViewModelModule.kt | 19 +++ .../feature/setting/model/SettingUiState.kt | 19 +++ .../app/feature/setting/ui/SettingScreen.kt | 112 +++++++++++------- .../feature/setting/ui/SettingViewModel.kt | 24 ++++ 4 files changed, 133 insertions(+), 41 deletions(-) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingUiState.kt create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt new file mode 100644 index 00000000..df833131 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt @@ -0,0 +1,19 @@ +package com.titi.app.feature.setting.di + +import com.airbnb.mvrx.hilt.AssistedViewModelFactory +import com.airbnb.mvrx.hilt.MavericksViewModelComponent +import com.airbnb.mvrx.hilt.ViewModelKey +import com.titi.app.feature.setting.ui.SettingViewModel +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.multibindings.IntoMap + +@Module +@InstallIn(MavericksViewModelComponent::class) +internal interface ViewModelModule { + @Binds + @IntoMap + @ViewModelKey(SettingViewModel::class) + fun settingViewModelFactory(factory: SettingViewModel.Factory): AssistedViewModelFactory<*, *> +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingUiState.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingUiState.kt new file mode 100644 index 00000000..2885ca44 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingUiState.kt @@ -0,0 +1,19 @@ +package com.titi.app.feature.setting.model + +import com.airbnb.mvrx.MavericksState + +data class SettingUiState( + val switchState: SwitchState = SwitchState(), + val versionState: VersionState = VersionState(), +) : MavericksState { + data class SwitchState( + val timerFiveMinutesBeforeTheEnd: Boolean = true, + val timerBeforeTheEnd: Boolean = true, + val stopwatch: Boolean = true, + ) + + data class VersionState( + val currentVersion: String = "", + val newVersion: String = "", + ) +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index 509d37e5..fd665e67 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -8,12 +8,14 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Icon import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -21,46 +23,63 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import com.airbnb.mvrx.compose.collectAsState +import com.airbnb.mvrx.compose.mavericksViewModel import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsText import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TdsTextStyle import com.titi.app.core.designsystem.theme.TiTiTheme +import com.titi.app.feature.setting.model.SettingUiState @Composable -fun SettingScreen() { - val scrollState = rememberScrollState() +fun SettingScreen(viewModel: SettingViewModel = mavericksViewModel()) { + val uiState by viewModel.collectAsState() Scaffold(containerColor = Color.Transparent) { - Column( - modifier = Modifier - .fillMaxSize() - .background(color = TdsColor.GROUPED_BACKGROUND.getColor()) - .padding(it) - .verticalScroll(scrollState), - ) { - TdsText( - modifier = Modifier.padding(start = 16.dp), - text = "Setting", - textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, - fontSize = 34.sp, - color = TdsColor.TEXT, - ) + SettingScreen( + modifier = Modifier.padding(it), + uiState = uiState, + ) + } +} - Spacer(modifier = Modifier.height(35.dp)) +@Composable +private fun SettingScreen(modifier: Modifier, uiState: SettingUiState) { + val scrollState = rememberScrollState() - SettingServiceSection() + Column( + modifier = Modifier + .fillMaxSize() + .background(color = TdsColor.GROUPED_BACKGROUND.getColor()) + .then(modifier) + .verticalScroll(scrollState), + ) { + TdsText( + modifier = Modifier.padding(start = 16.dp), + text = "Setting", + textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, + fontSize = 34.sp, + color = TdsColor.TEXT, + ) - Spacer(modifier = Modifier.height(35.dp)) + Spacer(modifier = Modifier.height(35.dp)) - SettingNotificationSection() + SettingServiceSection() - Spacer(modifier = Modifier.height(35.dp)) + Spacer(modifier = Modifier.height(35.dp)) - SettingVersionSection() + SettingNotificationSection( + switchState = uiState.switchState, + ) - Spacer(modifier = Modifier.height(35.dp)) - } + Spacer(modifier = Modifier.height(35.dp)) + + SettingVersionSection( + versionState = uiState.versionState, + ) + + Spacer(modifier = Modifier.height(35.dp)) } } @@ -90,7 +109,7 @@ private fun SettingServiceSection() { } @Composable -private fun SettingNotificationSection() { +private fun SettingNotificationSection(switchState: SettingUiState.SwitchState) { TdsText( modifier = Modifier.padding(start = 16.dp), text = "알림", @@ -106,11 +125,10 @@ private fun SettingNotificationSection() { description = "종료 5분전 알림", rightAreaContent = { Switch( - checked = true, + checked = switchState.timerFiveMinutesBeforeTheEnd, onCheckedChange = {}, ) }, - onClick = {}, ) Spacer(modifier = Modifier.height(1.dp)) @@ -120,11 +138,10 @@ private fun SettingNotificationSection() { description = "종료 알림", rightAreaContent = { Switch( - checked = true, + checked = switchState.timerBeforeTheEnd, onCheckedChange = {}, ) }, - onClick = {}, ) Spacer(modifier = Modifier.height(1.dp)) @@ -134,16 +151,15 @@ private fun SettingNotificationSection() { description = "1시간단위 경과시 알림", rightAreaContent = { Switch( - checked = true, + checked = switchState.stopwatch, onCheckedChange = {}, ) }, - onClick = {}, ) } @Composable -private fun SettingVersionSection() { +private fun SettingVersionSection(versionState: SettingUiState.VersionState) { TdsText( modifier = Modifier.padding(start = 16.dp), text = "버전 및 업데이트 내역", @@ -156,7 +172,7 @@ private fun SettingVersionSection() { SettingRowContent( title = "버전 정보", - description = "최신버전: 7.17.1", + description = "최신버전: ${versionState.newVersion}", rightAreaContent = { Icon( painter = painterResource(id = R.drawable.arrow_right_icon), @@ -172,11 +188,22 @@ private fun SettingVersionSection() { SettingRowContent( title = "업데이트 내역", rightAreaContent = { - Icon( - painter = painterResource(id = R.drawable.arrow_right_icon), - contentDescription = "", - tint = TdsColor.LIGHT_GRAY.getColor(), - ) + Row(verticalAlignment = Alignment.CenterVertically) { + TdsText( + text = versionState.currentVersion, + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + color = TdsColor.LIGHT_GRAY, + fontSize = 14.sp, + ) + + Spacer(modifier = Modifier.width(4.dp)) + + Icon( + painter = painterResource(id = R.drawable.arrow_right_icon), + contentDescription = "", + tint = TdsColor.LIGHT_GRAY.getColor(), + ) + } }, onClick = {}, ) @@ -187,13 +214,13 @@ private fun SettingRowContent( title: String, description: String? = null, rightAreaContent: @Composable () -> Unit, - onClick: () -> Unit, + onClick: (() -> Unit)? = null, ) { Row( modifier = Modifier .fillMaxSize() .background(TdsColor.SECONDARY_BACKGROUND.getColor()) - .clickable { onClick() } + .clickable { onClick?.invoke() } .padding( horizontal = 16.dp, vertical = 14.dp, @@ -228,6 +255,9 @@ private fun SettingRowContent( @Composable private fun SettingScreenPreview() { TiTiTheme { - SettingScreen() + SettingScreen( + modifier = Modifier, + uiState = SettingUiState(), + ) } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt new file mode 100644 index 00000000..4e069f81 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt @@ -0,0 +1,24 @@ +package com.titi.app.feature.setting.ui + +import com.airbnb.mvrx.MavericksViewModel +import com.airbnb.mvrx.MavericksViewModelFactory +import com.airbnb.mvrx.hilt.AssistedViewModelFactory +import com.airbnb.mvrx.hilt.hiltMavericksViewModelFactory +import com.titi.app.feature.setting.model.SettingUiState +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +class SettingViewModel @AssistedInject constructor( + @Assisted initialState: SettingUiState, +) : MavericksViewModel(initialState) { + + @AssistedFactory + interface Factory : AssistedViewModelFactory { + override fun create(state: SettingUiState): SettingViewModel + } + + companion object : + MavericksViewModelFactory + by hiltMavericksViewModelFactory() +} From ae297619e02e2b396b58ac6ef49376f9e2b617c6 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Fri, 3 May 2024 15:57:22 +0900 Subject: [PATCH 06/41] #82 feat : SettingActions --- .../feature/setting/model/SettingActions.kt | 18 ++++ .../app/feature/setting/ui/SettingScreen.kt | 90 ++++++++++++++++--- 2 files changed, 97 insertions(+), 11 deletions(-) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingActions.kt diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingActions.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingActions.kt new file mode 100644 index 00000000..9e4a8890 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/SettingActions.kt @@ -0,0 +1,18 @@ +package com.titi.app.feature.setting.model + +sealed interface SettingActions { + + sealed interface Navigates : SettingActions { + data object FeaturesList : Navigates + data object PlayStore : Navigates + data object UpdatesList : Navigates + } + + sealed interface Updates : SettingActions { + @JvmInline + value class Switch(val switchState: SettingUiState.SwitchState) : Updates + + @JvmInline + value class Version(val versionState: SettingUiState.VersionState) : Updates + } +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index fd665e67..c7f96f90 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -1,5 +1,6 @@ package com.titi.app.feature.setting.ui +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column @@ -30,6 +31,7 @@ import com.titi.app.core.designsystem.component.TdsText import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TdsTextStyle import com.titi.app.core.designsystem.theme.TiTiTheme +import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState @Composable @@ -40,12 +42,38 @@ fun SettingScreen(viewModel: SettingViewModel = mavericksViewModel()) { SettingScreen( modifier = Modifier.padding(it), uiState = uiState, + onSettingActions = { settingActions -> + when (settingActions) { + is SettingActions.Navigates -> { + when (settingActions) { + is SettingActions.Navigates.FeaturesList -> { + Log.e("ABC", settingActions.toString()) + } + + is SettingActions.Navigates.UpdatesList -> { + Log.e("ABC", settingActions.toString()) + } + + is SettingActions.Navigates.PlayStore -> { + Log.e("ABC", settingActions.toString()) + } + } + } + + is SettingActions.Updates -> { + } + } + }, ) } } @Composable -private fun SettingScreen(modifier: Modifier, uiState: SettingUiState) { +private fun SettingScreen( + modifier: Modifier, + uiState: SettingUiState, + onSettingActions: (SettingActions) -> Unit, +) { val scrollState = rememberScrollState() Column( @@ -65,18 +93,20 @@ private fun SettingScreen(modifier: Modifier, uiState: SettingUiState) { Spacer(modifier = Modifier.height(35.dp)) - SettingServiceSection() + SettingServiceSection(onSettingActions = onSettingActions) Spacer(modifier = Modifier.height(35.dp)) SettingNotificationSection( switchState = uiState.switchState, + onSettingActions = onSettingActions, ) Spacer(modifier = Modifier.height(35.dp)) SettingVersionSection( versionState = uiState.versionState, + onSettingActions = onSettingActions, ) Spacer(modifier = Modifier.height(35.dp)) @@ -84,7 +114,7 @@ private fun SettingScreen(modifier: Modifier, uiState: SettingUiState) { } @Composable -private fun SettingServiceSection() { +private fun SettingServiceSection(onSettingActions: (SettingActions) -> Unit) { TdsText( modifier = Modifier.padding(start = 16.dp), text = "서비스", @@ -104,12 +134,17 @@ private fun SettingServiceSection() { tint = TdsColor.LIGHT_GRAY.getColor(), ) }, - onClick = {}, + onClick = { + onSettingActions(SettingActions.Navigates.FeaturesList) + }, ) } @Composable -private fun SettingNotificationSection(switchState: SettingUiState.SwitchState) { +private fun SettingNotificationSection( + switchState: SettingUiState.SwitchState, + onSettingActions: (SettingActions) -> Unit, +) { TdsText( modifier = Modifier.padding(start = 16.dp), text = "알림", @@ -126,7 +161,16 @@ private fun SettingNotificationSection(switchState: SettingUiState.SwitchState) rightAreaContent = { Switch( checked = switchState.timerFiveMinutesBeforeTheEnd, - onCheckedChange = {}, + onCheckedChange = { + onSettingActions( + SettingActions.Updates.Switch( + switchState = switchState.copy( + timerFiveMinutesBeforeTheEnd = + !switchState.timerFiveMinutesBeforeTheEnd, + ), + ), + ) + }, ) }, ) @@ -139,7 +183,15 @@ private fun SettingNotificationSection(switchState: SettingUiState.SwitchState) rightAreaContent = { Switch( checked = switchState.timerBeforeTheEnd, - onCheckedChange = {}, + onCheckedChange = { + onSettingActions( + SettingActions.Updates.Switch( + switchState = switchState.copy( + timerBeforeTheEnd = !switchState.timerBeforeTheEnd, + ), + ), + ) + }, ) }, ) @@ -152,14 +204,25 @@ private fun SettingNotificationSection(switchState: SettingUiState.SwitchState) rightAreaContent = { Switch( checked = switchState.stopwatch, - onCheckedChange = {}, + onCheckedChange = { + onSettingActions( + SettingActions.Updates.Switch( + switchState = switchState.copy( + stopwatch = !switchState.stopwatch, + ), + ), + ) + }, ) }, ) } @Composable -private fun SettingVersionSection(versionState: SettingUiState.VersionState) { +private fun SettingVersionSection( + versionState: SettingUiState.VersionState, + onSettingActions: (SettingActions) -> Unit, +) { TdsText( modifier = Modifier.padding(start = 16.dp), text = "버전 및 업데이트 내역", @@ -180,7 +243,9 @@ private fun SettingVersionSection(versionState: SettingUiState.VersionState) { tint = TdsColor.LIGHT_GRAY.getColor(), ) }, - onClick = {}, + onClick = { + onSettingActions(SettingActions.Navigates.PlayStore) + }, ) Spacer(modifier = Modifier.height(1.dp)) @@ -205,7 +270,9 @@ private fun SettingVersionSection(versionState: SettingUiState.VersionState) { ) } }, - onClick = {}, + onClick = { + onSettingActions(SettingActions.Navigates.UpdatesList) + }, ) } @@ -258,6 +325,7 @@ private fun SettingScreenPreview() { SettingScreen( modifier = Modifier, uiState = SettingUiState(), + onSettingActions = {}, ) } } From a74fc43c3928bb47e3bb334a25ee550ad44d7689 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Fri, 3 May 2024 16:01:10 +0900 Subject: [PATCH 07/41] #82 feat : handleUpdateActions --- .../app/feature/setting/ui/SettingScreen.kt | 3 +-- .../feature/setting/ui/SettingViewModel.kt | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index c7f96f90..a887a23c 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -60,8 +60,7 @@ fun SettingScreen(viewModel: SettingViewModel = mavericksViewModel()) { } } - is SettingActions.Updates -> { - } + is SettingActions.Updates -> viewModel.handleUpdateActions(settingActions) } }, ) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt index 4e069f81..f83136e2 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt @@ -4,6 +4,7 @@ import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.hilt.AssistedViewModelFactory import com.airbnb.mvrx.hilt.hiltMavericksViewModelFactory +import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState import dagger.assisted.Assisted import dagger.assisted.AssistedFactory @@ -13,6 +14,25 @@ class SettingViewModel @AssistedInject constructor( @Assisted initialState: SettingUiState, ) : MavericksViewModel(initialState) { + fun handleUpdateActions(updateActions: SettingActions.Updates) { + when (updateActions) { + is SettingActions.Updates.Switch -> updateSwitch(updateActions.switchState) + is SettingActions.Updates.Version -> updateVersion(updateActions.versionState) + } + } + + private fun updateSwitch(switchState: SettingUiState.SwitchState) { + setState { + copy(switchState = switchState) + } + } + + private fun updateVersion(versionState: SettingUiState.VersionState) { + setState { + copy(versionState = versionState) + } + } + @AssistedFactory interface Factory : AssistedViewModelFactory { override fun create(state: SettingUiState): SettingViewModel From 2e5f8f0e2cda45e7e83b65c72a4739f3a50bc324 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Fri, 3 May 2024 16:36:55 +0900 Subject: [PATCH 08/41] =?UTF-8?q?#82=20feat=20:=20handleUpdateActions=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/main/navigation/TiTiNavHost.kt | 16 +++++++- .../setting/navigation/SettingNavigation.kt | 41 ++++++++++++++++++- .../feature/setting/ui/FeaturesListScreen.kt | 22 ++++++++++ .../app/feature/setting/ui/SettingScreen.kt | 22 +++------- .../feature/setting/ui/UpdatesListScreen.kt | 22 ++++++++++ 5 files changed, 103 insertions(+), 20 deletions(-) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt index 5a5c0d49..00a3c6c3 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt @@ -6,6 +6,7 @@ import androidx.activity.result.ActivityResult import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.core.net.toUri import androidx.navigation.compose.NavHost import com.titi.app.feature.log.navigation.logGraph import com.titi.app.feature.main.model.SplashResultState @@ -14,6 +15,8 @@ import com.titi.app.feature.main.ui.TiTiAppState import com.titi.app.feature.popup.PopUpActivity import com.titi.app.feature.popup.PopUpActivity.Companion.COLOR_RECORDING_MODE_KEY import com.titi.app.feature.popup.PopUpActivity.Companion.MEASURE_SPLASH_RESULT_KEY +import com.titi.app.feature.setting.navigation.navigateToFeatures +import com.titi.app.feature.setting.navigation.navigateToUpdates import com.titi.app.feature.setting.navigation.settingGraph import com.titi.app.feature.time.navigation.STOPWATCH_SCREEN import com.titi.app.feature.time.navigation.TIMER_SCREEN @@ -63,6 +66,17 @@ fun TiTiNavHost( logGraph() - settingGraph() + settingGraph( + onNavigateToFeatures = { navController.navigateToFeatures() }, + onNavigateToUpdates = { navController.navigateToUpdates() }, + onNavigateToPlayStore = { + val intent = Intent( + Intent.ACTION_VIEW, + "https://play.google.com/store/apps/details?id=com.titi.app".toUri(), + ) + + context.startActivity(intent) + }, + ) } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt index ecdf66dc..f56a4264 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt @@ -4,17 +4,54 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import com.titi.app.feature.setting.model.SettingActions +import com.titi.app.feature.setting.ui.FeaturesListScreen import com.titi.app.feature.setting.ui.SettingScreen +import com.titi.app.feature.setting.ui.UpdatesListScreen private const val SETTING_SCREEN = "setting" const val SETTING_ROUTE = SETTING_SCREEN +private const val FEATURES_SCREEN = "features" +const val FEATURES_ROUTE = FEATURES_SCREEN + +private const val UPDATES_SCREEN = "updates" +const val UPDATES_ROUTE = UPDATES_SCREEN + fun NavController.navigateToSetting(navOptions: NavOptions) { navigate(SETTING_ROUTE, navOptions) } -fun NavGraphBuilder.settingGraph() { +fun NavController.navigateToFeatures() { + navigate(FEATURES_ROUTE) +} + +fun NavController.navigateToUpdates() { + navigate(UPDATES_ROUTE) +} + +fun NavGraphBuilder.settingGraph( + onNavigateToFeatures: () -> Unit, + onNavigateToUpdates: () -> Unit, + onNavigateToPlayStore: () -> Unit, +) { composable(route = SETTING_ROUTE) { - SettingScreen() + SettingScreen( + handleNavigateActions = { + when (it) { + SettingActions.Navigates.FeaturesList -> onNavigateToFeatures() + SettingActions.Navigates.PlayStore -> onNavigateToPlayStore() + SettingActions.Navigates.UpdatesList -> onNavigateToUpdates() + } + }, + ) + } + + composable(route = FEATURES_ROUTE) { + FeaturesListScreen() + } + + composable(route = UPDATES_ROUTE) { + UpdatesListScreen() } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt new file mode 100644 index 00000000..d660399e --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt @@ -0,0 +1,22 @@ +package com.titi.app.feature.setting.ui + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.sp +import com.titi.app.core.designsystem.component.TdsText +import com.titi.app.core.designsystem.theme.TdsColor +import com.titi.app.core.designsystem.theme.TdsTextStyle + +@Composable +fun FeaturesListScreen() { + Column(modifier = Modifier.fillMaxSize()) { + TdsText( + text = "Features", + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + color = TdsColor.TEXT, + fontSize = 24.sp, + ) + } +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index a887a23c..db6f7f5a 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -1,6 +1,5 @@ package com.titi.app.feature.setting.ui -import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column @@ -35,7 +34,10 @@ import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState @Composable -fun SettingScreen(viewModel: SettingViewModel = mavericksViewModel()) { +fun SettingScreen( + viewModel: SettingViewModel = mavericksViewModel(), + handleNavigateActions: (SettingActions.Navigates) -> Unit, +) { val uiState by viewModel.collectAsState() Scaffold(containerColor = Color.Transparent) { @@ -44,21 +46,7 @@ fun SettingScreen(viewModel: SettingViewModel = mavericksViewModel()) { uiState = uiState, onSettingActions = { settingActions -> when (settingActions) { - is SettingActions.Navigates -> { - when (settingActions) { - is SettingActions.Navigates.FeaturesList -> { - Log.e("ABC", settingActions.toString()) - } - - is SettingActions.Navigates.UpdatesList -> { - Log.e("ABC", settingActions.toString()) - } - - is SettingActions.Navigates.PlayStore -> { - Log.e("ABC", settingActions.toString()) - } - } - } + is SettingActions.Navigates -> handleNavigateActions(settingActions) is SettingActions.Updates -> viewModel.handleUpdateActions(settingActions) } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt new file mode 100644 index 00000000..30aab799 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt @@ -0,0 +1,22 @@ +package com.titi.app.feature.setting.ui + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.sp +import com.titi.app.core.designsystem.component.TdsText +import com.titi.app.core.designsystem.theme.TdsColor +import com.titi.app.core.designsystem.theme.TdsTextStyle + +@Composable +fun UpdatesListScreen() { + Column(modifier = Modifier.fillMaxSize()) { + TdsText( + text = "Updates", + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + color = TdsColor.TEXT, + fontSize = 24.sp, + ) + } +} From 460b388103895f5ba5d64498d82c1b1f45f79ed8 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 14:47:14 +0900 Subject: [PATCH 09/41] #82 update : setting topbar --- .../app/feature/setting/ui/SettingScreen.kt | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index db6f7f5a..ff04be12 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -11,9 +11,12 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.Scaffold import androidx.compose.material3.Switch +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -33,6 +36,7 @@ import com.titi.app.core.designsystem.theme.TiTiTheme import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SettingScreen( viewModel: SettingViewModel = mavericksViewModel(), @@ -40,7 +44,24 @@ fun SettingScreen( ) { val uiState by viewModel.collectAsState() - Scaffold(containerColor = Color.Transparent) { + Scaffold( + containerColor = Color.Transparent, + topBar = { + TopAppBar( + colors = TopAppBarDefaults.topAppBarColors( + containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + ), + title = { + TdsText( + text = "Setting", + textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, + fontSize = 24.sp, + color = TdsColor.TEXT, + ) + }, + ) + }, + ) { SettingScreen( modifier = Modifier.padding(it), uiState = uiState, @@ -70,16 +91,6 @@ private fun SettingScreen( .then(modifier) .verticalScroll(scrollState), ) { - TdsText( - modifier = Modifier.padding(start = 16.dp), - text = "Setting", - textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, - fontSize = 34.sp, - color = TdsColor.TEXT, - ) - - Spacer(modifier = Modifier.height(35.dp)) - SettingServiceSection(onSettingActions = onSettingActions) Spacer(modifier = Modifier.height(35.dp)) From 437e595999813aa32f4a06f74a56badb99ba8918 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 15:15:31 +0900 Subject: [PATCH 10/41] =?UTF-8?q?#82=20feat=20:=20=ED=8B=B0=ED=8B=B0=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=EB=93=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../feature/main/navigation/TiTiNavHost.kt | 4 + .../app/feature/setting/di/ViewModelModule.kt | 8 ++ .../feature/setting/model/FeaturesUiState.kt | 42 +++++++ .../setting/navigation/SettingNavigation.kt | 7 +- .../feature/setting/ui/FeaturesListScreen.kt | 106 ++++++++++++++++-- .../setting/ui/FeaturesListViewModel.kt | 24 ++++ .../app/feature/setting/ui/SettingScreen.kt | 17 +-- 7 files changed, 192 insertions(+), 16 deletions(-) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/FeaturesUiState.kt create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListViewModel.kt diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt index 00a3c6c3..2e2e1c1f 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt @@ -77,6 +77,10 @@ fun TiTiNavHost( context.startActivity(intent) }, + onNavigateUp = { navController.navigateUp() }, + onNavigateToWebView = { + // TODO WebView 연결 + }, ) } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt index df833131..1631bc74 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/di/ViewModelModule.kt @@ -3,6 +3,7 @@ package com.titi.app.feature.setting.di import com.airbnb.mvrx.hilt.AssistedViewModelFactory import com.airbnb.mvrx.hilt.MavericksViewModelComponent import com.airbnb.mvrx.hilt.ViewModelKey +import com.titi.app.feature.setting.ui.FeaturesListViewModel import com.titi.app.feature.setting.ui.SettingViewModel import dagger.Binds import dagger.Module @@ -16,4 +17,11 @@ internal interface ViewModelModule { @IntoMap @ViewModelKey(SettingViewModel::class) fun settingViewModelFactory(factory: SettingViewModel.Factory): AssistedViewModelFactory<*, *> + + @Binds + @IntoMap + @ViewModelKey(FeaturesListViewModel::class) + fun featuresViewModelFactory( + factory: FeaturesListViewModel.Factory, + ): AssistedViewModelFactory<*, *> } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/FeaturesUiState.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/FeaturesUiState.kt new file mode 100644 index 00000000..6c6d2429 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/FeaturesUiState.kt @@ -0,0 +1,42 @@ +package com.titi.app.feature.setting.model + +import com.airbnb.mvrx.MavericksState + +data class FeaturesUiState( + val features: List = makeFeatures(), +) : MavericksState { + data class Feature( + val title: String, + val url: String, + ) +} + +internal fun makeFeatures(): List { + return listOf( + FeaturesUiState.Feature( + title = "새로운 기록 설정", + url = "https://www.notion.so/timertiti/2501881bb0ef49c29a1c2cee29b7f48e?pvs=4", + ), + FeaturesUiState.Feature( + title = "Task", + url = "https://www.notion.so/timertiti/Task-5fbd947fe3994ce09dd3d87051861005?pvs=4", + ), + FeaturesUiState.Feature( + title = "Timer", + url = "https://www.notion.so/timertiti/Timer-0083c63a3a464fc69b6c255930690ae8?pvs=4", + ), + FeaturesUiState.Feature( + title = "Stopwatch", + url = + "https://www.notion.so/timertiti/Stopwatch-41984a8ab11444cba79fb94984f799bb?pvs=4", + ), + FeaturesUiState.Feature( + title = "Log", + url = "https://www.notion.so/timertiti/Log-362d4cffb3e74f1686dd4e603fba8496?pvs=4", + ), + FeaturesUiState.Feature( + title = "Daily", + url = "https://www.notion.so/timertiti/Daily-d60dc90f3c104744a74985ea221e5691?pvs=4", + ), + ) +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt index f56a4264..27d1dbf3 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt @@ -34,6 +34,8 @@ fun NavGraphBuilder.settingGraph( onNavigateToFeatures: () -> Unit, onNavigateToUpdates: () -> Unit, onNavigateToPlayStore: () -> Unit, + onNavigateUp: () -> Unit, + onNavigateToWebView: (String) -> Unit, ) { composable(route = SETTING_ROUTE) { SettingScreen( @@ -48,7 +50,10 @@ fun NavGraphBuilder.settingGraph( } composable(route = FEATURES_ROUTE) { - FeaturesListScreen() + FeaturesListScreen( + onNavigateUp = onNavigateUp, + onNavigateWebView = onNavigateToWebView, + ) } composable(route = UPDATES_ROUTE) { diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt index d660399e..2222efc9 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt @@ -1,22 +1,114 @@ package com.titi.app.feature.setting.ui 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.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.Scaffold +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue 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 androidx.compose.ui.unit.sp +import com.airbnb.mvrx.compose.collectAsState +import com.airbnb.mvrx.compose.mavericksViewModel +import com.titi.app.core.designsystem.R +import com.titi.app.core.designsystem.component.TdsIconButton import com.titi.app.core.designsystem.component.TdsText import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TdsTextStyle +import com.titi.app.core.designsystem.theme.TiTiTheme +import com.titi.app.feature.setting.model.FeaturesUiState +import com.titi.app.feature.setting.model.makeFeatures +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun FeaturesListScreen() { - Column(modifier = Modifier.fillMaxSize()) { - TdsText( - text = "Features", - textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, - color = TdsColor.TEXT, - fontSize = 24.sp, +fun FeaturesListScreen( + viewModel: FeaturesListViewModel = mavericksViewModel(), + onNavigateUp: () -> Unit, + onNavigateWebView: (String) -> Unit, +) { + val uiState by viewModel.collectAsState() + + Scaffold( + containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + topBar = { + TopAppBar( + colors = TopAppBarDefaults.topAppBarColors( + containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + ), + navigationIcon = { + TdsIconButton(onClick = onNavigateUp) { + Icon( + painter = painterResource(id = R.drawable.arrow_left_icon), + contentDescription = "back", + tint = TdsColor.TEXT.getColor(), + ) + } + }, + title = { + TdsText( + text = "Setting", + textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, + fontSize = 24.sp, + color = TdsColor.TEXT, + ) + }, + ) + }, + ) { + FeaturesListScreen( + modifier = Modifier + .fillMaxSize() + .padding(it), + uiState = uiState, + onClick = onNavigateWebView, + ) + } +} + +@Composable +fun FeaturesListScreen( + modifier: Modifier = Modifier, + uiState: FeaturesUiState, + onClick: (String) -> Unit, +) { + Column(modifier = modifier) { + uiState.features.forEachIndexed { index, feature -> + ListContent( + title = feature.title, + rightAreaContent = { + Icon( + painter = painterResource(id = R.drawable.arrow_right_icon), + contentDescription = "", + tint = TdsColor.LIGHT_GRAY.getColor(), + ) + }, + onClick = { onClick(feature.url) }, + ) + + if (index != uiState.features.size - 1) { + Spacer(modifier = Modifier.height(1.dp)) + } + } + } +} + +@Composable +@Preview +private fun FeaturesListScreenPreview() { + TiTiTheme { + FeaturesListScreen( + modifier = Modifier.fillMaxSize(), + uiState = FeaturesUiState(features = makeFeatures()), + onClick = {}, ) } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListViewModel.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListViewModel.kt new file mode 100644 index 00000000..b3ccf8eb --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListViewModel.kt @@ -0,0 +1,24 @@ +package com.titi.app.feature.setting.ui + +import com.airbnb.mvrx.MavericksViewModel +import com.airbnb.mvrx.MavericksViewModelFactory +import com.airbnb.mvrx.hilt.AssistedViewModelFactory +import com.airbnb.mvrx.hilt.hiltMavericksViewModelFactory +import com.titi.app.feature.setting.model.FeaturesUiState +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +class FeaturesListViewModel @AssistedInject constructor( + @Assisted initialState: FeaturesUiState, +) : MavericksViewModel(initialState) { + + @AssistedFactory + interface Factory : AssistedViewModelFactory { + override fun create(state: FeaturesUiState): FeaturesListViewModel + } + + companion object : + MavericksViewModelFactory + by hiltMavericksViewModelFactory() +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index ff04be12..e6ccb31e 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row 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.width @@ -123,7 +124,7 @@ private fun SettingServiceSection(onSettingActions: (SettingActions) -> Unit) { Spacer(modifier = Modifier.height(4.dp)) - SettingRowContent( + ListContent( title = "TiTi 기능들", rightAreaContent = { Icon( @@ -153,7 +154,7 @@ private fun SettingNotificationSection( Spacer(modifier = Modifier.height(4.dp)) - SettingRowContent( + ListContent( title = "타이머", description = "종료 5분전 알림", rightAreaContent = { @@ -175,7 +176,7 @@ private fun SettingNotificationSection( Spacer(modifier = Modifier.height(1.dp)) - SettingRowContent( + ListContent( title = "타이머", description = "종료 알림", rightAreaContent = { @@ -196,7 +197,7 @@ private fun SettingNotificationSection( Spacer(modifier = Modifier.height(1.dp)) - SettingRowContent( + ListContent( title = "스톱워치", description = "1시간단위 경과시 알림", rightAreaContent = { @@ -231,7 +232,7 @@ private fun SettingVersionSection( Spacer(modifier = Modifier.height(4.dp)) - SettingRowContent( + ListContent( title = "버전 정보", description = "최신버전: ${versionState.newVersion}", rightAreaContent = { @@ -248,7 +249,7 @@ private fun SettingVersionSection( Spacer(modifier = Modifier.height(1.dp)) - SettingRowContent( + ListContent( title = "업데이트 내역", rightAreaContent = { Row(verticalAlignment = Alignment.CenterVertically) { @@ -275,7 +276,7 @@ private fun SettingVersionSection( } @Composable -private fun SettingRowContent( +internal fun ListContent( title: String, description: String? = null, rightAreaContent: @Composable () -> Unit, @@ -283,7 +284,7 @@ private fun SettingRowContent( ) { Row( modifier = Modifier - .fillMaxSize() + .fillMaxWidth() .background(TdsColor.SECONDARY_BACKGROUND.getColor()) .clickable { onClick?.invoke() } .padding( From f92dfc96937ec2b6592181219129a703dd996ea2 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 15:21:46 +0900 Subject: [PATCH 11/41] #82 chore : data notification module setting --- data/notification/api/build.gradle.kts | 7 +++++++ data/notification/api/src/main/AndroidManifest.xml | 4 ++++ data/notification/impl/build.gradle.kts | 11 +++++++++++ data/notification/impl/src/main/AndroidManifest.xml | 4 ++++ settings.gradle.kts | 2 ++ 5 files changed, 28 insertions(+) create mode 100644 data/notification/api/build.gradle.kts create mode 100644 data/notification/api/src/main/AndroidManifest.xml create mode 100644 data/notification/impl/build.gradle.kts create mode 100644 data/notification/impl/src/main/AndroidManifest.xml diff --git a/data/notification/api/build.gradle.kts b/data/notification/api/build.gradle.kts new file mode 100644 index 00000000..c1dd973b --- /dev/null +++ b/data/notification/api/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("titi.android.library-no-hilt") +} + +android { + namespace = "com.titi.app.data.notification.api" +} diff --git a/data/notification/api/src/main/AndroidManifest.xml b/data/notification/api/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/data/notification/api/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/data/notification/impl/build.gradle.kts b/data/notification/impl/build.gradle.kts new file mode 100644 index 00000000..c249701a --- /dev/null +++ b/data/notification/impl/build.gradle.kts @@ -0,0 +1,11 @@ +plugins { + id("titi.android.data.local") +} + +android { + namespace = "com.titi.app.data.notification.impl" +} + +dependencies { + implementation(project(":data:notification:api")) +} diff --git a/data/notification/impl/src/main/AndroidManifest.xml b/data/notification/impl/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/data/notification/impl/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index d196e10d..e9a06e60 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -47,3 +47,5 @@ include(":feature:log") include(":data:graph:impl") include(":data:graph:api") include(":feature:setting") +include(":data:notification:api") +include(":data:notification:impl") From b249782bd13e8607af2d61cfd2780b6b429b83bf Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 15:31:26 +0900 Subject: [PATCH 12/41] #82 feat : NotificationDataStore --- .../notification/impl/di/DataStoreModule.kt | 19 +++++++++++ .../impl/local/NotificationDataStore.kt | 33 +++++++++++++++++++ .../impl/local/model/NotificationEntity.kt | 10 ++++++ 3 files changed, 62 insertions(+) create mode 100644 data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/DataStoreModule.kt create mode 100644 data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt create mode 100644 data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/model/NotificationEntity.kt diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/DataStoreModule.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/DataStoreModule.kt new file mode 100644 index 00000000..cdd567a0 --- /dev/null +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/DataStoreModule.kt @@ -0,0 +1,19 @@ +package com.titi.app.data.notification.impl.di + +import android.content.Context +import com.titi.app.data.notification.impl.local.NotificationDataStore +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal object DataStoreModule { + @Provides + @Singleton + fun provideNotificationDataStore(@ApplicationContext context: Context) = + NotificationDataStore(context) +} diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt new file mode 100644 index 00000000..6eed21be --- /dev/null +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt @@ -0,0 +1,33 @@ +package com.titi.app.data.notification.impl.local + +import android.content.Context +import androidx.datastore.core.DataStore +import androidx.datastore.preferences.core.Preferences +import androidx.datastore.preferences.core.stringPreferencesKey +import androidx.datastore.preferences.preferencesDataStore +import com.titi.app.core.util.fromJson +import com.titi.app.core.util.readFlowValue +import com.titi.app.core.util.storeValue +import com.titi.app.core.util.toJson +import com.titi.app.data.notification.impl.local.model.NotificationEntity +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +internal class NotificationDataStore(context: Context) { + private val dataStore: DataStore = context.dataStore + + suspend fun setNotification(notificationEntity: NotificationEntity) { + dataStore.storeValue(NOTIFICATION_KEY, notificationEntity.toJson()) + } + + fun getNotificationFlow(): Flow = + dataStore.readFlowValue(NOTIFICATION_KEY).map { it?.fromJson() } + + companion object { + private const val NOTIFICATION_PREF_NAME = "notificationPrefName" + private val NOTIFICATION_KEY = stringPreferencesKey("notificationKey") + + private val Context.dataStore: DataStore + by preferencesDataStore(NOTIFICATION_PREF_NAME) + } +} diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/model/NotificationEntity.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/model/NotificationEntity.kt new file mode 100644 index 00000000..4a34a759 --- /dev/null +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/model/NotificationEntity.kt @@ -0,0 +1,10 @@ +package com.titi.app.data.notification.impl.local.model + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +internal data class NotificationEntity( + val timerFiveMinutesBeforeTheEnd: Boolean, + val timerBeforeTheEnd: Boolean, + val stopwatch: Boolean, +) From 3d3321e6701a0574fac4bee88d6216e915be832a Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 15:34:43 +0900 Subject: [PATCH 13/41] #82 feat : NotificationRepositoryModel --- .../api/model/NotificationRepositoryModel.kt | 7 +++++++ .../impl/mapper/LocalToRepositoryMapper.kt | 10 ++++++++++ .../impl/mapper/RepositoryToLocalMapper.kt | 10 ++++++++++ 3 files changed, 27 insertions(+) create mode 100644 data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt create mode 100644 data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/LocalToRepositoryMapper.kt create mode 100644 data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/RepositoryToLocalMapper.kt diff --git a/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt new file mode 100644 index 00000000..d048899a --- /dev/null +++ b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt @@ -0,0 +1,7 @@ +package com.titi.app.data.notification.api.model + +data class NotificationRepositoryModel( + val timerFiveMinutesBeforeTheEnd: Boolean, + val timerBeforeTheEnd: Boolean, + val stopwatch: Boolean, +) diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/LocalToRepositoryMapper.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/LocalToRepositoryMapper.kt new file mode 100644 index 00000000..54e4680e --- /dev/null +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/LocalToRepositoryMapper.kt @@ -0,0 +1,10 @@ +package com.titi.app.data.notification.impl.mapper + +import com.titi.app.data.notification.api.model.NotificationRepositoryModel +import com.titi.app.data.notification.impl.local.model.NotificationEntity + +internal fun NotificationEntity.toRepositoryModel() = NotificationRepositoryModel( + timerFiveMinutesBeforeTheEnd = timerFiveMinutesBeforeTheEnd, + timerBeforeTheEnd = timerBeforeTheEnd, + stopwatch = stopwatch, +) diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/RepositoryToLocalMapper.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/RepositoryToLocalMapper.kt new file mode 100644 index 00000000..7c4902e2 --- /dev/null +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/mapper/RepositoryToLocalMapper.kt @@ -0,0 +1,10 @@ +package com.titi.app.data.notification.impl.mapper + +import com.titi.app.data.notification.api.model.NotificationRepositoryModel +import com.titi.app.data.notification.impl.local.model.NotificationEntity + +internal fun NotificationRepositoryModel.toLocalModel() = NotificationEntity( + timerFiveMinutesBeforeTheEnd = timerFiveMinutesBeforeTheEnd, + timerBeforeTheEnd = timerBeforeTheEnd, + stopwatch = stopwatch, +) From 9e1c5c3b76ed625e381cc4b833adb39170dd0e10 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 15:39:15 +0900 Subject: [PATCH 14/41] #82 feat : NotificationRepository --- .../api/NotificationRepository.kt | 11 ++++++++++ .../api/model/NotificationRepositoryModel.kt | 6 ++--- .../notification/impl/di/RepositoryModule.kt | 19 ++++++++++++++++ .../repository/NotificationRepositoryImpl.kt | 22 +++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt create mode 100644 data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/RepositoryModule.kt create mode 100644 data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt diff --git a/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt new file mode 100644 index 00000000..015e2d1c --- /dev/null +++ b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt @@ -0,0 +1,11 @@ +package com.titi.app.data.notification.api + +import com.titi.app.data.notification.api.model.NotificationRepositoryModel +import kotlinx.coroutines.flow.Flow + +interface NotificationRepository { + + suspend fun setNotification(notificationRepositoryModel: NotificationRepositoryModel) + + fun getNotificationFlow(): Flow +} diff --git a/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt index d048899a..40eca73f 100644 --- a/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt +++ b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/model/NotificationRepositoryModel.kt @@ -1,7 +1,7 @@ package com.titi.app.data.notification.api.model data class NotificationRepositoryModel( - val timerFiveMinutesBeforeTheEnd: Boolean, - val timerBeforeTheEnd: Boolean, - val stopwatch: Boolean, + val timerFiveMinutesBeforeTheEnd: Boolean = true, + val timerBeforeTheEnd: Boolean = true, + val stopwatch: Boolean = true, ) diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/RepositoryModule.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/RepositoryModule.kt new file mode 100644 index 00000000..2ec2b335 --- /dev/null +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/di/RepositoryModule.kt @@ -0,0 +1,19 @@ +package com.titi.app.data.notification.impl.di + +import com.titi.app.data.notification.api.NotificationRepository +import com.titi.app.data.notification.impl.repository.NotificationRepositoryImpl +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal interface RepositoryModule { + @Binds + @Singleton + fun provideNotificationRepository( + notificationRepositoryImpl: NotificationRepositoryImpl, + ): NotificationRepository +} diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt new file mode 100644 index 00000000..2f5cc819 --- /dev/null +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt @@ -0,0 +1,22 @@ +package com.titi.app.data.notification.impl.repository + +import com.titi.app.data.notification.api.NotificationRepository +import com.titi.app.data.notification.api.model.NotificationRepositoryModel +import com.titi.app.data.notification.impl.local.NotificationDataStore +import com.titi.app.data.notification.impl.mapper.toLocalModel +import com.titi.app.data.notification.impl.mapper.toRepositoryModel +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +internal class NotificationRepositoryImpl @Inject constructor( + private val notificationDataStore: NotificationDataStore, +) : NotificationRepository { + override suspend fun setNotification(notificationRepositoryModel: NotificationRepositoryModel) { + notificationDataStore.setNotification(notificationRepositoryModel.toLocalModel()) + } + + override fun getNotificationFlow(): Flow = + notificationDataStore.getNotificationFlow() + .map { it?.toRepositoryModel() ?: NotificationRepositoryModel() } +} From 7cffd4a98508face4c9190d4618f8b71ec4307c2 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 15:50:16 +0900 Subject: [PATCH 15/41] =?UTF-8?q?#82=20feat=20:=20Notification=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85=20=ED=99=94=EB=A9=B4=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 1 + feature/setting/build.gradle.kts | 1 + .../mapper/FeatureToRepositoryMapper.kt | 10 ++++++++ .../mapper/RepositoryToFeatureMapper.kt | 10 ++++++++ .../feature/setting/ui/SettingViewModel.kt | 23 ++++++++++++++++++- 5 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/FeatureToRepositoryMapper.kt create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/RepositoryToFeatureMapper.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e8217229..f23126a4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -72,6 +72,7 @@ dependencies { implementation(project(":data:sleep:impl")) implementation(project(":data:alarm:impl")) implementation(project(":data:graph:impl")) + implementation(project(":data:notification:impl")) implementation(platform(libs.firebase.bom)) implementation(libs.firebase.analytics) diff --git a/feature/setting/build.gradle.kts b/feature/setting/build.gradle.kts index 63109244..3f7168ba 100644 --- a/feature/setting/build.gradle.kts +++ b/feature/setting/build.gradle.kts @@ -7,4 +7,5 @@ android { } dependencies { + implementation(project(":data:notification:api")) } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/FeatureToRepositoryMapper.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/FeatureToRepositoryMapper.kt new file mode 100644 index 00000000..393b9d85 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/FeatureToRepositoryMapper.kt @@ -0,0 +1,10 @@ +package com.titi.app.feature.setting.mapper + +import com.titi.app.data.notification.api.model.NotificationRepositoryModel +import com.titi.app.feature.setting.model.SettingUiState + +fun SettingUiState.SwitchState.toRepositoryModel() = NotificationRepositoryModel( + timerFiveMinutesBeforeTheEnd = timerFiveMinutesBeforeTheEnd, + timerBeforeTheEnd = timerBeforeTheEnd, + stopwatch = stopwatch, +) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/RepositoryToFeatureMapper.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/RepositoryToFeatureMapper.kt new file mode 100644 index 00000000..c261b703 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/mapper/RepositoryToFeatureMapper.kt @@ -0,0 +1,10 @@ +package com.titi.app.feature.setting.mapper + +import com.titi.app.data.notification.api.model.NotificationRepositoryModel +import com.titi.app.feature.setting.model.SettingUiState + +fun NotificationRepositoryModel.toFeatureModel() = SettingUiState.SwitchState( + timerFiveMinutesBeforeTheEnd = timerFiveMinutesBeforeTheEnd, + timerBeforeTheEnd = timerBeforeTheEnd, + stopwatch = stopwatch, +) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt index f83136e2..d0b399f1 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingViewModel.kt @@ -4,19 +4,40 @@ import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.hilt.AssistedViewModelFactory import com.airbnb.mvrx.hilt.hiltMavericksViewModelFactory +import com.titi.app.data.notification.api.NotificationRepository +import com.titi.app.feature.setting.mapper.toFeatureModel +import com.titi.app.feature.setting.mapper.toRepositoryModel import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import kotlinx.coroutines.flow.collectLatest +import kotlinx.coroutines.launch class SettingViewModel @AssistedInject constructor( @Assisted initialState: SettingUiState, + private val notificationRepository: NotificationRepository, ) : MavericksViewModel(initialState) { + init { + viewModelScope.launch { + notificationRepository.getNotificationFlow() + .collectLatest { + updateSwitch(it.toFeatureModel()) + } + } + } + fun handleUpdateActions(updateActions: SettingActions.Updates) { when (updateActions) { - is SettingActions.Updates.Switch -> updateSwitch(updateActions.switchState) + is SettingActions.Updates.Switch -> { + viewModelScope.launch { + notificationRepository + .setNotification(updateActions.switchState.toRepositoryModel()) + } + } + is SettingActions.Updates.Version -> updateVersion(updateActions.versionState) } } From 8af00d9add5202ea5f51b1c659f99ffa6dd335bb Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 16:36:24 +0900 Subject: [PATCH 16/41] #82 feat : getNotification --- .../titi/app/data/notification/api/NotificationRepository.kt | 3 ++- .../data/notification/impl/local/NotificationDataStore.kt | 4 ++++ .../impl/repository/NotificationRepositoryImpl.kt | 5 +++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt index 015e2d1c..e41edeb5 100644 --- a/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt +++ b/data/notification/api/src/main/kotlin/com/titi/app/data/notification/api/NotificationRepository.kt @@ -4,8 +4,9 @@ import com.titi.app.data.notification.api.model.NotificationRepositoryModel import kotlinx.coroutines.flow.Flow interface NotificationRepository { - suspend fun setNotification(notificationRepositoryModel: NotificationRepositoryModel) fun getNotificationFlow(): Flow + + suspend fun getNotification(): NotificationRepositoryModel } diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt index 6eed21be..c620857f 100644 --- a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/local/NotificationDataStore.kt @@ -7,6 +7,7 @@ import androidx.datastore.preferences.core.stringPreferencesKey import androidx.datastore.preferences.preferencesDataStore import com.titi.app.core.util.fromJson import com.titi.app.core.util.readFlowValue +import com.titi.app.core.util.readValue import com.titi.app.core.util.storeValue import com.titi.app.core.util.toJson import com.titi.app.data.notification.impl.local.model.NotificationEntity @@ -23,6 +24,9 @@ internal class NotificationDataStore(context: Context) { fun getNotificationFlow(): Flow = dataStore.readFlowValue(NOTIFICATION_KEY).map { it?.fromJson() } + suspend fun getNotification(): NotificationEntity? = + dataStore.readValue(NOTIFICATION_KEY)?.fromJson() + companion object { private const val NOTIFICATION_PREF_NAME = "notificationPrefName" private val NOTIFICATION_KEY = stringPreferencesKey("notificationKey") diff --git a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt index 2f5cc819..bc1852d7 100644 --- a/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt +++ b/data/notification/impl/src/main/kotlin/com/titi/app/data/notification/impl/repository/NotificationRepositoryImpl.kt @@ -19,4 +19,9 @@ internal class NotificationRepositoryImpl @Inject constructor( override fun getNotificationFlow(): Flow = notificationDataStore.getNotificationFlow() .map { it?.toRepositoryModel() ?: NotificationRepositoryModel() } + + override suspend fun getNotification(): NotificationRepositoryModel { + return notificationDataStore.getNotification()?.toRepositoryModel() + ?: NotificationRepositoryModel() + } } From 455003338e0ea8c7162a404a2e3d0643fbeec9c1 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 16:45:25 +0900 Subject: [PATCH 17/41] =?UTF-8?q?#82=20feat=20:=20notification=20=EC=83=81?= =?UTF-8?q?=ED=83=9C=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=95=8C=EB=9E=8C=20?= =?UTF-8?q?=EB=B3=B4=EB=82=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domain/alarm/build.gradle.kts | 1 + .../alarm/usecase/SetStopWatchAlarmUseCase.kt | 37 +++++++++++-------- .../alarm/usecase/SetTimerAlarmUseCase.kt | 24 ++++++++---- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/domain/alarm/build.gradle.kts b/domain/alarm/build.gradle.kts index 2cb7b4b4..02e1e7e3 100644 --- a/domain/alarm/build.gradle.kts +++ b/domain/alarm/build.gradle.kts @@ -8,6 +8,7 @@ android { dependencies { implementation(project(":data:alarm:api")) + implementation(project(":data:notification:api")) implementation(libs.threetenabp) } diff --git a/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetStopWatchAlarmUseCase.kt b/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetStopWatchAlarmUseCase.kt index 2ae28ec3..b00e41d7 100644 --- a/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetStopWatchAlarmUseCase.kt +++ b/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetStopWatchAlarmUseCase.kt @@ -1,6 +1,7 @@ package com.titi.app.domain.alarm.usecase import com.titi.app.data.alarm.api.AlarmRepository +import com.titi.app.data.notification.api.NotificationRepository import com.titi.app.domain.alarm.mapper.toRepositoryModel import com.titi.app.domain.alarm.model.Alarm import com.titi.app.domain.alarm.model.Alarms @@ -9,29 +10,33 @@ import org.threeten.bp.ZonedDateTime class SetStopWatchAlarmUseCase @Inject constructor( private val alarmRepository: AlarmRepository, + private val notificationRepository: NotificationRepository, ) { suspend operator fun invoke(title: String, finishMessage: String, measureTime: Long) { alarmRepository.cancelAlarms() val now = ZonedDateTime.now() val finishTimeRange = (measureTime / ONE_HOUR_SECONDS) + 1..TWENTY_FOUR_HOURS - val alarms = - Alarms( - alarms = finishTimeRange.map { - Alarm( - title = title, - message = "$it$finishMessage", - finishTime = now.plusSeconds( - it * ONE_HOUR_SECONDS - measureTime, - ).toString(), - ) - }, - ) + val alarms = Alarms( + alarms = finishTimeRange.map { + Alarm( + title = title, + message = "$it$finishMessage", + finishTime = now.plusSeconds( + it * ONE_HOUR_SECONDS - measureTime, + ).toString(), + ) + }, + ) - if (alarmRepository.canScheduleExactAlarms()) { - alarmRepository.setExactAlarms(alarms.toRepositoryModel()) - } else { - alarmRepository.addExactAlarms(alarms.toRepositoryModel()) + val notification = notificationRepository.getNotification() + + if (notification.stopwatch) { + if (alarmRepository.canScheduleExactAlarms()) { + alarmRepository.setExactAlarms(alarms.toRepositoryModel()) + } else { + alarmRepository.addExactAlarms(alarms.toRepositoryModel()) + } } } diff --git a/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetTimerAlarmUseCase.kt b/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetTimerAlarmUseCase.kt index 2dffac3c..f27497dc 100644 --- a/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetTimerAlarmUseCase.kt +++ b/domain/alarm/src/main/kotlin/com/titi/app/domain/alarm/usecase/SetTimerAlarmUseCase.kt @@ -1,6 +1,7 @@ package com.titi.app.domain.alarm.usecase import com.titi.app.data.alarm.api.AlarmRepository +import com.titi.app.data.notification.api.NotificationRepository import com.titi.app.domain.alarm.mapper.toRepositoryModel import com.titi.app.domain.alarm.model.Alarm import com.titi.app.domain.alarm.model.Alarms @@ -9,6 +10,7 @@ import org.threeten.bp.ZonedDateTime class SetTimerAlarmUseCase @Inject constructor( private val alarmRepository: AlarmRepository, + private val notificationRepository: NotificationRepository, ) { suspend operator fun invoke( title: String, @@ -26,17 +28,23 @@ class SetTimerAlarmUseCase @Inject constructor( null } + val notification = notificationRepository.getNotification() val alarms = Alarms( alarms = mutableListOf().apply { - add( - Alarm( - title = title, - message = finishMessage, - finishTime = finishTime, - ), - ) + if (notification.timerBeforeTheEnd) { + add( + Alarm( + title = title, + message = finishMessage, + finishTime = finishTime, + ), + ) + } - if (fiveMinutesBeforeFinishTime != null) { + if ( + fiveMinutesBeforeFinishTime != null && + notification.timerFiveMinutesBeforeTheEnd + ) { add( Alarm( title = title, From 4283d9a54fc1d2017ce52858b94538628f35f9ab Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 18:57:22 +0900 Subject: [PATCH 18/41] =?UTF-8?q?#82=20feat=20:=20firebase=20=EC=9D=B4?= =?UTF-8?q?=EC=9A=A9=ED=95=9C=20=ED=98=84=EC=9E=AC=20=EC=B5=9C=EC=8B=A0=20?= =?UTF-8?q?=EB=B2=84=EC=A0=84=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/setting/build.gradle.kts | 7 ++++ .../app/feature/setting/model/Versions.kt | 15 +++++++++ .../app/feature/setting/ui/SettingScreen.kt | 32 +++++++++++++++++++ gradle/libs.versions.toml | 1 + 4 files changed, 55 insertions(+) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Versions.kt diff --git a/feature/setting/build.gradle.kts b/feature/setting/build.gradle.kts index 3f7168ba..1e260fa8 100644 --- a/feature/setting/build.gradle.kts +++ b/feature/setting/build.gradle.kts @@ -8,4 +8,11 @@ android { dependencies { implementation(project(":data:notification:api")) + + implementation(platform(libs.firebase.bom)) + implementation(libs.firebase.database) + + implementation(libs.moshi) + implementation(libs.moshi.kotlin) + ksp(libs.moshi.codegen) } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Versions.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Versions.kt new file mode 100644 index 00000000..2357f9e1 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Versions.kt @@ -0,0 +1,15 @@ +package com.titi.app.feature.setting.model + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class Versions( + val versions: List = emptyList(), +) { + @JsonClass(generateAdapter = true) + data class Version( + val currentVersion: String = "", + val date: String = "", + val description: String = "", + ) +} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index e6ccb31e..cf0a1a2b 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -1,5 +1,6 @@ package com.titi.app.feature.setting.ui +import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column @@ -29,6 +30,11 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel +import com.google.firebase.database.DataSnapshot +import com.google.firebase.database.DatabaseError +import com.google.firebase.database.FirebaseDatabase +import com.google.firebase.database.ValueEventListener +import com.google.firebase.database.getValue import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsText import com.titi.app.core.designsystem.theme.TdsColor @@ -36,6 +42,7 @@ import com.titi.app.core.designsystem.theme.TdsTextStyle import com.titi.app.core.designsystem.theme.TiTiTheme import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState +import com.titi.app.feature.setting.model.Versions @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -45,6 +52,31 @@ fun SettingScreen( ) { val uiState by viewModel.collectAsState() + val firebaseDatabase = FirebaseDatabase.getInstance() + val databaseReference = firebaseDatabase.getReference("versions") + + databaseReference.addValueEventListener( + object : ValueEventListener { + override fun onDataChange(snapshot: DataSnapshot) { + val latestVersion = snapshot + .children + .lastOrNull() + ?.getValue() + ?.currentVersion + + latestVersion?.let { + viewModel.handleUpdateActions( + SettingActions.Updates.Version(uiState.versionState.copy(newVersion = it)), + ) + } + } + + override fun onCancelled(error: DatabaseError) { + Log.e("SettingScreen", error.message) + } + }, + ) + Scaffold( containerColor = Color.Transparent, topBar = { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8c89aab3..1370c2b6 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -117,6 +117,7 @@ androidx-junit-ktx = { group = "androidx.test.ext", name = "junit-ktx", version. firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebaseBom" } firebase-analytics = { group = "com.google.firebase", name = "firebase-analytics" } firebase-crashlytics = { group = "com.google.firebase", name = "firebase-crashlytics" } +firebase-database = { group = "com.google.firebase", name = "firebase-database-ktx" } calendar = { group = "com.kizitonwose.calendar", name = "compose", version.ref = "calendar" } From 07f1b57a634502ca672248555036c709e93bad56 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 19:01:45 +0900 Subject: [PATCH 19/41] =?UTF-8?q?#82=20feat=20:=20=ED=98=84=EC=9E=AC=20?= =?UTF-8?q?=EB=B2=84=EC=A0=BC=20=EA=B0=80=EC=A0=B8=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/feature/setting/ui/SettingScreen.kt | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index cf0a1a2b..0c8823fa 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.unit.dp @@ -55,6 +56,8 @@ fun SettingScreen( val firebaseDatabase = FirebaseDatabase.getInstance() val databaseReference = firebaseDatabase.getReference("versions") + val context = LocalContext.current + databaseReference.addValueEventListener( object : ValueEventListener { override fun onDataChange(snapshot: DataSnapshot) { @@ -64,9 +67,19 @@ fun SettingScreen( ?.getValue() ?.currentVersion - latestVersion?.let { + val currentVersion = context + .packageManager + .getPackageInfo(context.packageName, 0) + .versionName + + latestVersion?.let { safeLatestVersion -> viewModel.handleUpdateActions( - SettingActions.Updates.Version(uiState.versionState.copy(newVersion = it)), + SettingActions.Updates.Version( + uiState.versionState.copy( + newVersion = safeLatestVersion, + currentVersion = currentVersion, + ), + ), ) } } @@ -268,6 +281,15 @@ private fun SettingVersionSection( title = "버전 정보", description = "최신버전: ${versionState.newVersion}", rightAreaContent = { + TdsText( + text = versionState.currentVersion, + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + color = TdsColor.LIGHT_GRAY, + fontSize = 14.sp, + ) + + Spacer(modifier = Modifier.width(4.dp)) + Icon( painter = painterResource(id = R.drawable.arrow_right_icon), contentDescription = "", @@ -285,15 +307,6 @@ private fun SettingVersionSection( title = "업데이트 내역", rightAreaContent = { Row(verticalAlignment = Alignment.CenterVertically) { - TdsText( - text = versionState.currentVersion, - textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, - color = TdsColor.LIGHT_GRAY, - fontSize = 14.sp, - ) - - Spacer(modifier = Modifier.width(4.dp)) - Icon( painter = painterResource(id = R.drawable.arrow_right_icon), contentDescription = "", From e3e0b61bea2b3d33274da2d86bdaa459a2d3f301 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 19:03:44 +0900 Subject: [PATCH 20/41] =?UTF-8?q?#82=20feat=20:=20=ED=8C=8C=EC=9D=B4?= =?UTF-8?q?=EC=96=B4=EB=B2=A0=EC=9D=B4=EC=8A=A4=EC=9A=A9=20model=20proguar?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/proguard-rules.pro | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 28c16c03..141b1628 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -69,4 +69,7 @@ -keepclassmembers class * { @com.squareup.moshi.FromJson ; @com.squareup.moshi.ToJson ; -} \ No newline at end of file +} + +-keepattributes Signature +-keepclassmembers class com.titi.app.feature.setting.model.** {*;} \ No newline at end of file From e5c89a5f84747980c4a2ca06f55eb466765656f1 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 20:01:28 +0900 Subject: [PATCH 21/41] #82 update : versions -> versionuistate --- .../feature/setting/model/{Versions.kt => VersionUiState.kt} | 2 +- .../kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/{Versions.kt => VersionUiState.kt} (92%) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Versions.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/VersionUiState.kt similarity index 92% rename from feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Versions.kt rename to feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/VersionUiState.kt index 2357f9e1..4897091c 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Versions.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/VersionUiState.kt @@ -3,7 +3,7 @@ package com.titi.app.feature.setting.model import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class Versions( +data class VersionUiState( val versions: List = emptyList(), ) { @JsonClass(generateAdapter = true) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index 0c8823fa..fe30ae9b 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -43,7 +43,7 @@ import com.titi.app.core.designsystem.theme.TdsTextStyle import com.titi.app.core.designsystem.theme.TiTiTheme import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState -import com.titi.app.feature.setting.model.Versions +import com.titi.app.feature.setting.model.VersionUiState @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -64,7 +64,7 @@ fun SettingScreen( val latestVersion = snapshot .children .lastOrNull() - ?.getValue() + ?.getValue() ?.currentVersion val currentVersion = context From fbb0ef433a9a78b5773dc021b8d4e1683a1a7790 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sat, 4 May 2024 21:37:09 +0900 Subject: [PATCH 22/41] #82 feat : UpdateListScreen --- .../titi/app/feature/setting/model/Version.kt | 10 ++ .../feature/setting/model/VersionUiState.kt | 15 -- .../setting/navigation/SettingNavigation.kt | 2 +- .../feature/setting/ui/FeaturesListScreen.kt | 2 +- .../app/feature/setting/ui/SettingScreen.kt | 61 ++++--- .../feature/setting/ui/UpdatesListScreen.kt | 167 +++++++++++++++++- 6 files changed, 205 insertions(+), 52 deletions(-) create mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Version.kt delete mode 100644 feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/VersionUiState.kt diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Version.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Version.kt new file mode 100644 index 00000000..0d0edba2 --- /dev/null +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/Version.kt @@ -0,0 +1,10 @@ +package com.titi.app.feature.setting.model + +import com.squareup.moshi.JsonClass + +@JsonClass(generateAdapter = true) +data class Version( + val currentVersion: String = "", + val date: String = "", + val description: String = "", +) diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/VersionUiState.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/VersionUiState.kt deleted file mode 100644 index 4897091c..00000000 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/model/VersionUiState.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.titi.app.feature.setting.model - -import com.squareup.moshi.JsonClass - -@JsonClass(generateAdapter = true) -data class VersionUiState( - val versions: List = emptyList(), -) { - @JsonClass(generateAdapter = true) - data class Version( - val currentVersion: String = "", - val date: String = "", - val description: String = "", - ) -} diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt index 27d1dbf3..71f0a026 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt @@ -57,6 +57,6 @@ fun NavGraphBuilder.settingGraph( } composable(route = UPDATES_ROUTE) { - UpdatesListScreen() + UpdatesListScreen(onNavigateUp = onNavigateUp) } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt index 2222efc9..5264a10f 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt @@ -55,7 +55,7 @@ fun FeaturesListScreen( }, title = { TdsText( - text = "Setting", + text = "TiTi 기능들", textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, fontSize = 24.sp, color = TdsColor.TEXT, diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index fe30ae9b..5d7435b9 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.material3.Switch import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -43,7 +44,7 @@ import com.titi.app.core.designsystem.theme.TdsTextStyle import com.titi.app.core.designsystem.theme.TiTiTheme import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.model.SettingUiState -import com.titi.app.feature.setting.model.VersionUiState +import com.titi.app.feature.setting.model.Version @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -58,37 +59,39 @@ fun SettingScreen( val context = LocalContext.current - databaseReference.addValueEventListener( - object : ValueEventListener { - override fun onDataChange(snapshot: DataSnapshot) { - val latestVersion = snapshot - .children - .lastOrNull() - ?.getValue() - ?.currentVersion - - val currentVersion = context - .packageManager - .getPackageInfo(context.packageName, 0) - .versionName - - latestVersion?.let { safeLatestVersion -> - viewModel.handleUpdateActions( - SettingActions.Updates.Version( - uiState.versionState.copy( - newVersion = safeLatestVersion, - currentVersion = currentVersion, + LaunchedEffect(Unit) { + databaseReference.addValueEventListener( + object : ValueEventListener { + override fun onDataChange(snapshot: DataSnapshot) { + val latestVersion = snapshot + .children + .lastOrNull() + ?.getValue() + ?.currentVersion + + val currentVersion = context + .packageManager + .getPackageInfo(context.packageName, 0) + .versionName + + latestVersion?.let { safeLatestVersion -> + viewModel.handleUpdateActions( + SettingActions.Updates.Version( + uiState.versionState.copy( + newVersion = safeLatestVersion, + currentVersion = currentVersion, + ), ), - ), - ) + ) + } } - } - override fun onCancelled(error: DatabaseError) { - Log.e("SettingScreen", error.message) - } - }, - ) + override fun onCancelled(error: DatabaseError) { + Log.e("SettingScreen", error.message) + } + }, + ) + } Scaffold( containerColor = Color.Transparent, diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt index 30aab799..82ed1cc3 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt @@ -1,22 +1,177 @@ package com.titi.app.feature.setting.ui +import android.util.Log +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +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.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.Scaffold +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.remember 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 androidx.compose.ui.unit.sp +import com.google.firebase.database.DataSnapshot +import com.google.firebase.database.DatabaseError +import com.google.firebase.database.FirebaseDatabase +import com.google.firebase.database.ValueEventListener +import com.google.firebase.database.getValue +import com.titi.app.core.designsystem.R +import com.titi.app.core.designsystem.component.TdsIconButton import com.titi.app.core.designsystem.component.TdsText import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TdsTextStyle +import com.titi.app.feature.setting.model.Version +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun UpdatesListScreen() { - Column(modifier = Modifier.fillMaxSize()) { +fun UpdatesListScreen(onNavigateUp: () -> Unit) { + val firebaseDatabase = FirebaseDatabase.getInstance() + val databaseReference = firebaseDatabase.getReference("versions") + + val updates = remember { mutableStateListOf() } + + LaunchedEffect(Unit) { + databaseReference.addValueEventListener( + object : ValueEventListener { + override fun onDataChange(snapshot: DataSnapshot) { + for (data in snapshot.children) { + data.getValue()?.let { + updates.add(it) + } + } + } + + override fun onCancelled(error: DatabaseError) { + Log.e("UpdateListScreen", error.message) + } + }, + ) + } + + Scaffold( + containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + topBar = { + TopAppBar( + colors = TopAppBarDefaults.topAppBarColors( + containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + ), + navigationIcon = { + TdsIconButton(onClick = onNavigateUp) { + Icon( + painter = painterResource(id = R.drawable.arrow_left_icon), + contentDescription = "back", + tint = TdsColor.TEXT.getColor(), + ) + } + }, + title = { + TdsText( + text = "업데이트 내역", + textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, + fontSize = 24.sp, + color = TdsColor.TEXT, + ) + }, + ) + }, + ) { + UpdateListScreen( + modifier = Modifier + .fillMaxSize() + .padding(it), + updates = updates.reversed(), + ) + } +} + +@Composable +private fun UpdateListScreen(modifier: Modifier = Modifier, updates: List) { + LazyColumn(modifier) { + items(updates) { + VersionContent(version = it) + } + } +} + +@Composable +private fun VersionContent(version: Version) { + Column { + Row( + modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + TdsText( + text = "ver ${version.currentVersion}", + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + color = TdsColor.TEXT, + fontSize = 16.sp, + ) + + TdsText( + text = version.date, + textStyle = TdsTextStyle.NORMAL_TEXT_STYLE, + color = TdsColor.LIGHT_GRAY, + fontSize = 16.sp, + ) + } + + Spacer(modifier = Modifier.height(8.dp)) + TdsText( - text = "Updates", - textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, - color = TdsColor.TEXT, - fontSize = 24.sp, + modifier = Modifier + .fillMaxWidth() + .background(color = TdsColor.SECONDARY_BACKGROUND.getColor()) + .padding( + horizontal = 8.dp, + vertical = 12.dp, + ), + text = version.description, + textStyle = TdsTextStyle.NORMAL_TEXT_STYLE, + color = TdsColor.LIGHT_GRAY, + fontSize = 16.sp, ) + + Spacer(modifier = Modifier.height(8.dp)) } } + +@Preview +@Composable +private fun UpdatesListScreenPreview() { + UpdateListScreen( + modifier = Modifier.fillMaxSize(), + updates = listOf( + Version( + currentVersion = "repudiandae", + date = "utinam", + description = "magnis", + ), + Version( + currentVersion = "repudiandae", + date = "utinam", + description = "magnis", + ), + Version( + currentVersion = "repudiandae", + date = "utinam", + description = "magnis", + ), + ), + ) +} From 6972f4070b475686d147565bbbaf7dba929e7610 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 5 May 2024 12:37:39 +0900 Subject: [PATCH 23/41] #82 chore : feature:webview --- feature/webview/build.gradle.kts | 10 ++++++++++ feature/webview/src/main/AndroidManifest.xml | 4 ++++ settings.gradle.kts | 1 + 3 files changed, 15 insertions(+) create mode 100644 feature/webview/build.gradle.kts create mode 100644 feature/webview/src/main/AndroidManifest.xml diff --git a/feature/webview/build.gradle.kts b/feature/webview/build.gradle.kts new file mode 100644 index 00000000..6f8ab32b --- /dev/null +++ b/feature/webview/build.gradle.kts @@ -0,0 +1,10 @@ +plugins { + id("titi.android.feature") +} + +android { + namespace = "com.titi.app.feature.webview" +} + +dependencies { +} diff --git a/feature/webview/src/main/AndroidManifest.xml b/feature/webview/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/feature/webview/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index e9a06e60..7911b62d 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -49,3 +49,4 @@ include(":data:graph:api") include(":feature:setting") include(":data:notification:api") include(":data:notification:impl") +include(":feature:webview") From a2e23611d50e89dda395468970c1ebabe975d30d Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 5 May 2024 13:18:15 +0900 Subject: [PATCH 24/41] #82 feat : webview --- app/src/main/AndroidManifest.xml | 1 + feature/main/build.gradle.kts | 1 + .../feature/main/navigation/TiTiNavHost.kt | 11 ++- .../setting/navigation/SettingNavigation.kt | 2 +- .../feature/setting/ui/FeaturesListScreen.kt | 8 +- .../app/feature/webview/WebViewNavigation.kt | 37 ++++++++ .../titi/app/feature/webview/WebViewScreen.kt | 90 +++++++++++++++++++ 7 files changed, 143 insertions(+), 7 deletions(-) create mode 100644 feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewNavigation.kt create mode 100644 feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a78ba903..257b2b88 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -14,6 +14,7 @@ android:label="${appName}" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" + android:usesCleartextTraffic="true" android:theme="@style/Theme.TiTi" tools:targetApi="31"> diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts index de53ea5a..a5eb135b 100644 --- a/feature/main/build.gradle.kts +++ b/feature/main/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { implementation(project(":feature:log")) implementation(project(":feature:popup")) implementation(project(":feature:setting")) + implementation(project(":feature:webview")) implementation(libs.androidx.splashscreen) implementation(libs.androidx.material3.window.size) diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt index 2e2e1c1f..3b9ea0dc 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt @@ -21,6 +21,8 @@ import com.titi.app.feature.setting.navigation.settingGraph import com.titi.app.feature.time.navigation.STOPWATCH_SCREEN import com.titi.app.feature.time.navigation.TIMER_SCREEN import com.titi.app.feature.time.navigation.timeGraph +import com.titi.app.feature.webview.navigateToWebView +import com.titi.app.feature.webview.webViewGraph @Composable fun TiTiNavHost( @@ -78,9 +80,14 @@ fun TiTiNavHost( context.startActivity(intent) }, onNavigateUp = { navController.navigateUp() }, - onNavigateToWebView = { - // TODO WebView 연결 + onNavigateToWebView = { title, url -> + navController.navigateToWebView( + title = title, + url = url, + ) }, ) + + webViewGraph(onNavigateUp = { navController.navigateUp() }) } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt index 71f0a026..dc0f0d73 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt @@ -35,7 +35,7 @@ fun NavGraphBuilder.settingGraph( onNavigateToUpdates: () -> Unit, onNavigateToPlayStore: () -> Unit, onNavigateUp: () -> Unit, - onNavigateToWebView: (String) -> Unit, + onNavigateToWebView: (title: String, url: String) -> Unit, ) { composable(route = SETTING_ROUTE) { SettingScreen( diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt index 5264a10f..243d52ca 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt @@ -33,7 +33,7 @@ import com.titi.app.feature.setting.model.makeFeatures fun FeaturesListScreen( viewModel: FeaturesListViewModel = mavericksViewModel(), onNavigateUp: () -> Unit, - onNavigateWebView: (String) -> Unit, + onNavigateWebView: (title: String, url: String) -> Unit, ) { val uiState by viewModel.collectAsState() @@ -78,7 +78,7 @@ fun FeaturesListScreen( fun FeaturesListScreen( modifier: Modifier = Modifier, uiState: FeaturesUiState, - onClick: (String) -> Unit, + onClick: (title: String, url: String) -> Unit, ) { Column(modifier = modifier) { uiState.features.forEachIndexed { index, feature -> @@ -91,7 +91,7 @@ fun FeaturesListScreen( tint = TdsColor.LIGHT_GRAY.getColor(), ) }, - onClick = { onClick(feature.url) }, + onClick = { onClick(feature.title, feature.url) }, ) if (index != uiState.features.size - 1) { @@ -108,7 +108,7 @@ private fun FeaturesListScreenPreview() { FeaturesListScreen( modifier = Modifier.fillMaxSize(), uiState = FeaturesUiState(features = makeFeatures()), - onClick = {}, + onClick = { title, url -> }, ) } } diff --git a/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewNavigation.kt b/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewNavigation.kt new file mode 100644 index 00000000..477bcd39 --- /dev/null +++ b/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewNavigation.kt @@ -0,0 +1,37 @@ +package com.titi.app.feature.webview + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavType +import androidx.navigation.compose.composable +import androidx.navigation.navArgument + +private const val WEBVIEW_SCREEN = "webview" +const val WEBVIEW_TITLE_ARG = "title" +const val WEBVIEW_URL_ARG = "url" +const val WEBVIEW_ROUTE = + "$WEBVIEW_SCREEN?$WEBVIEW_TITLE_ARG={$WEBVIEW_TITLE_ARG}&$WEBVIEW_URL_ARG={$WEBVIEW_URL_ARG}" + +fun NavController.navigateToWebView(title: String, url: String) { + navigate("$WEBVIEW_SCREEN?$WEBVIEW_TITLE_ARG=$title&$WEBVIEW_URL_ARG=$url") +} + +fun NavGraphBuilder.webViewGraph(onNavigateUp: () -> Unit) { + composable( + route = WEBVIEW_ROUTE, + arguments = listOf( + navArgument(WEBVIEW_TITLE_ARG) { + type = NavType.StringType + }, + navArgument(WEBVIEW_URL_ARG) { + type = NavType.StringType + }, + ), + ) { + WebViewScreen( + title = it.arguments?.getString(WEBVIEW_TITLE_ARG) ?: "", + url = it.arguments?.getString(WEBVIEW_URL_ARG) ?: "", + onNavigateUp = onNavigateUp, + ) + } +} diff --git a/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt b/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt new file mode 100644 index 00000000..2b28535a --- /dev/null +++ b/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt @@ -0,0 +1,90 @@ +package com.titi.app.feature.webview + +import android.view.ViewGroup +import android.webkit.WebChromeClient +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.Scaffold +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.sp +import androidx.compose.ui.viewinterop.AndroidView +import com.titi.app.core.designsystem.R +import com.titi.app.core.designsystem.component.TdsIconButton +import com.titi.app.core.designsystem.component.TdsText +import com.titi.app.core.designsystem.theme.TdsColor +import com.titi.app.core.designsystem.theme.TdsTextStyle + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun WebViewScreen(title: String, url: String, onNavigateUp: () -> Unit) { + Scaffold( + containerColor = Color.White, + modifier = Modifier.fillMaxSize(), + topBar = { + TopAppBar( + colors = TopAppBarDefaults.topAppBarColors( + containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + ), + navigationIcon = { + TdsIconButton(onClick = onNavigateUp) { + Icon( + painter = painterResource(id = R.drawable.arrow_left_icon), + contentDescription = "back", + tint = TdsColor.TEXT.getColor(), + ) + } + }, + title = { + TdsText( + text = title, + textStyle = TdsTextStyle.EXTRA_BOLD_TEXT_STYLE, + fontSize = 24.sp, + color = TdsColor.TEXT, + ) + }, + ) + }, + ) { + WebViewScreen( + modifier = Modifier + .fillMaxSize() + .padding(it), + url = url, + ) + } +} + +@Composable +private fun WebViewScreen(modifier: Modifier, url: String) { + AndroidView( + modifier = modifier, + factory = { context -> + WebView(context).apply { + layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + ) + webViewClient = WebViewClient() + webChromeClient = WebChromeClient() + settings.apply { + javaScriptEnabled = true + domStorageEnabled = true + loadWithOverviewMode = true + useWideViewPort = true + } + } + }, + update = { webView -> + webView.loadUrl(url) + }, + ) +} From 2f4bc3641327121432d2b046dfaee04261763d48 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 5 May 2024 13:31:00 +0900 Subject: [PATCH 25/41] =?UTF-8?q?#82=20feat=20:=20color=20=EB=A7=9E?= =?UTF-8?q?=EC=B6=94=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/titi/app/feature/main/ui/TiTiAppState.kt | 13 ++++++++++--- .../app/feature/setting/ui/FeaturesListScreen.kt | 3 ++- .../app/feature/setting/ui/UpdatesListScreen.kt | 3 ++- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt index 5ab4e70f..7efc322d 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt @@ -15,12 +15,15 @@ import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.feature.log.navigation.LOG_ROUTE import com.titi.app.feature.log.navigation.navigateToLog import com.titi.app.feature.main.navigation.TopLevelDestination +import com.titi.app.feature.setting.navigation.FEATURES_ROUTE import com.titi.app.feature.setting.navigation.SETTING_ROUTE +import com.titi.app.feature.setting.navigation.UPDATES_ROUTE import com.titi.app.feature.setting.navigation.navigateToSetting import com.titi.app.feature.time.navigation.STOPWATCH_ROUTE import com.titi.app.feature.time.navigation.TIMER_ROUTE import com.titi.app.feature.time.navigation.navigateToStopWatch import com.titi.app.feature.time.navigation.navigateToTimer +import com.titi.app.feature.webview.WEBVIEW_ROUTE import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -84,9 +87,13 @@ class TiTiAppState( when (route) { TIMER_ROUTE -> timeColor.timerBackgroundColor STOPWATCH_ROUTE -> timeColor.stopwatchBackgroundColor - LOG_ROUTE -> if (isSystemDarkTheme) 0xFF000000 else 0xFFFFFFFF - SETTING_ROUTE -> if (isSystemDarkTheme) 0xFF000000 else 0xFFFFFFFF - else -> 0xFF000000 + SETTING_ROUTE, + FEATURES_ROUTE, + UPDATES_ROUTE, + WEBVIEW_ROUTE, + -> if (isSystemDarkTheme) 0xFF000000 else 0xFFF2F2F7 + + else -> if (isSystemDarkTheme) 0xFF000000 else 0xFFFFFFFF } } .stateIn( diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt index 243d52ca..4bd8639e 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt @@ -13,6 +13,7 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -38,7 +39,7 @@ fun FeaturesListScreen( val uiState by viewModel.collectAsState() Scaffold( - containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + containerColor = Color.Transparent, topBar = { TopAppBar( colors = TopAppBarDefaults.topAppBarColors( diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt index 82ed1cc3..6ee051f5 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt @@ -22,6 +22,7 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -65,7 +66,7 @@ fun UpdatesListScreen(onNavigateUp: () -> Unit) { } Scaffold( - containerColor = TdsColor.GROUPED_BACKGROUND.getColor(), + containerColor = Color.Transparent, topBar = { TopAppBar( colors = TopAppBarDefaults.topAppBarColors( From 62571f7806f52958a314d515c21d7190923dd485 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 5 May 2024 13:37:44 +0900 Subject: [PATCH 26/41] update : version --- build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt b/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt index 5335002e..06cd8a76 100644 --- a/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt +++ b/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt @@ -9,7 +9,7 @@ object BuildType { object AppConfig { const val APP_ID = "com.titi.app" - const val APP_VERSION_NAME = "1.0.2" - const val APP_VERSION_CODE = 23 + const val APP_VERSION_NAME = "1.0.3" + const val APP_VERSION_CODE = 24 const val APP_NAME = "TiTi" } \ No newline at end of file From b071a91c4915bed6c9b62d1e71eafc160a1fdcdd Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 5 May 2024 13:38:08 +0900 Subject: [PATCH 27/41] docs : release-note --- release-note.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/release-note.txt b/release-note.txt index 527e29ed..c1422a1e 100644 --- a/release-note.txt +++ b/release-note.txt @@ -1,3 +1,2 @@ -TiTi android dev 1.0.2(23) -- 타이머, 스탑워치 디자인 수정 -- 그래프 디자인 수정 \ No newline at end of file +TiTi android dev 1.0.3(24) +- 세팅 화면 구현 완료 \ No newline at end of file From a1d520c55b343fb37a76583848870a1a771a59e9 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 14:42:09 +0900 Subject: [PATCH 28/41] =?UTF-8?q?#122=20Update=20timer=20screen=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/res/drawable/edit_record_icon.xml | 14 +++ .../src/main/res/values/strings.xml | 2 + .../doamin/daily/usecase/AddDailyUseCase.kt | 34 +----- ...ilyDialog.kt => TimeAddEditDailyDialog.kt} | 15 ++- .../feature/time/content/TimeButtonContent.kt | 19 ++-- ...kDailyDialog.kt => TimeCheckTaskDialog.kt} | 4 +- .../feature/time/content/TimeHeaderContent.kt | 10 +- .../app/feature/time/model/TimerUiState.kt | 4 +- .../app/feature/time/ui/timer/TimerScreen.kt | 103 +++++++----------- .../feature/time/ui/timer/TimerViewModel.kt | 45 +++++++- 10 files changed, 120 insertions(+), 130 deletions(-) create mode 100644 core/designsystem/src/main/res/drawable/edit_record_icon.xml rename feature/time/src/main/kotlin/com/titi/app/feature/time/content/{TimeDailyDialog.kt => TimeAddEditDailyDialog.kt} (79%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/content/{TimeCheckDailyDialog.kt => TimeCheckTaskDialog.kt} (84%) diff --git a/core/designsystem/src/main/res/drawable/edit_record_icon.xml b/core/designsystem/src/main/res/drawable/edit_record_icon.xml new file mode 100644 index 00000000..3de4b7c6 --- /dev/null +++ b/core/designsystem/src/main/res/drawable/edit_record_icon.xml @@ -0,0 +1,14 @@ + + + + diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml index 4293cc48..d2afab37 100644 --- a/core/designsystem/src/main/res/values/strings.xml +++ b/core/designsystem/src/main/res/values/strings.xml @@ -27,6 +27,8 @@ 해당 색상을 배경색으로 설정하시겠습니까? 새로운 기록 설정 %1$s 목표시간 설정 + 목표시간 수정 + %1$s 목표시간 수정 타이머 시간 설정 종료예정 : %1$s Task와 Daily를 확인해주세요. diff --git a/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/AddDailyUseCase.kt b/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/AddDailyUseCase.kt index f1687d3b..835f92d9 100644 --- a/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/AddDailyUseCase.kt +++ b/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/AddDailyUseCase.kt @@ -4,41 +4,11 @@ import com.titi.app.data.daily.api.DailyRepository import com.titi.app.doamin.daily.mapper.toRepositoryModel import com.titi.app.doamin.daily.model.Daily import javax.inject.Inject -import org.threeten.bp.LocalDateTime -import org.threeten.bp.ZoneId -import org.threeten.bp.ZoneOffset -import org.threeten.bp.ZonedDateTime class AddDailyUseCase @Inject constructor( private val dailyRepository: DailyRepository, ) { - suspend operator fun invoke() { - val recentDaily = dailyRepository.getDateDaily() - - val currentDateTime = LocalDateTime.now() - val dailyDayOfMonth = recentDaily?.let { - ZonedDateTime - .parse(it.day) - .withZoneSameInstant(ZoneId.systemDefault()) - .dayOfMonth - } ?: currentDateTime.dayOfMonth - - if ( - recentDaily == null || - (currentDateTime.dayOfMonth != dailyDayOfMonth && currentDateTime.hour >= 6) - ) { - dailyRepository.upsert(Daily().toRepositoryModel()) - } else { - dailyRepository.upsert( - recentDaily.copy( - status = null, - day = ZonedDateTime.now(ZoneOffset.UTC).toString(), - timeline = LongArray(24) { 0 }.toList(), - maxTime = 0, - tasks = null, - taskHistories = null, - ), - ) - } + suspend operator fun invoke(daily: Daily) { + dailyRepository.upsert(daily.toRepositoryModel()) } } diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeDailyDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeAddEditDailyDialog.kt similarity index 79% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeDailyDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeAddEditDailyDialog.kt index f98b81dc..6e7e6571 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeDailyDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeAddEditDailyDialog.kt @@ -17,7 +17,8 @@ import com.titi.app.core.designsystem.model.TdsTime import com.titi.app.core.util.getTimeToLong @Composable -fun TimeDailyDialog( +fun TimeAddEditDailyDialog( + isFirstDaily: Boolean, todayDate: String, currentTime: TdsTime, onPositive: (Long) -> Unit, @@ -29,8 +30,16 @@ fun TimeDailyDialog( TdsDialog( tdsDialogInfo = TdsDialogInfo.Confirm( - title = stringResource(R.string.add_daily_title), - message = stringResource(R.string.add_daily_message, todayDate), + title = if (isFirstDaily) { + stringResource(R.string.add_daily_title) + } else { + stringResource(id = R.string.edit_daily_title) + }, + message = if (isFirstDaily) { + stringResource(R.string.add_daily_message, todayDate) + } else { + stringResource(R.string.edit_daily_message, todayDate) + }, positiveText = stringResource(id = R.string.Ok), negativeText = stringResource(id = R.string.Cancel), onPositive = { diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt index 6bc7b032..f3680400 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt @@ -14,14 +14,13 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsIconButton -import com.titi.app.core.designsystem.theme.TdsColor @Composable fun TimeButtonContent( recordingMode: Int, - isDailyAfter6AM: Boolean, tintColor: Color, - onClickAddDaily: () -> Unit, + isFirstDaily: Boolean, + onClickAddEditDaily: () -> Unit, onClickStartRecord: () -> Unit, onClickSettingTimer: (() -> Unit)? = null, onClickResetStopwatch: (() -> Unit)? = null, @@ -32,17 +31,13 @@ fun TimeButtonContent( horizontalArrangement = Arrangement.Center, ) { TdsIconButton( - onClick = onClickAddDaily, + onClick = onClickAddEditDaily, size = 50.dp, ) { Icon( painter = painterResource(id = R.drawable.add_record_icon), contentDescription = "addRecord", - tint = if (isDailyAfter6AM) { - tintColor - } else { - TdsColor.RED.getColor() - }, + tint = tintColor, ) } @@ -53,7 +48,11 @@ fun TimeButtonContent( size = 70.dp, ) { Icon( - painter = painterResource(id = R.drawable.start_record_icon), + painter = if (isFirstDaily) { + painterResource(id = R.drawable.start_record_icon) + } else { + painterResource(id = R.drawable.edit_record_icon) + }, contentDescription = "startRecord", tint = Color.Unspecified, ) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckDailyDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckTaskDialog.kt similarity index 84% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckDailyDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckTaskDialog.kt index f3390513..0ca32fac 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckDailyDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckTaskDialog.kt @@ -11,10 +11,10 @@ import com.titi.app.core.designsystem.component.TdsDialog import com.titi.app.core.designsystem.model.TdsDialogInfo @Composable -fun TimeCheckDailyDialog(title: String, onShowDialog: (Boolean) -> Unit) { +fun TimeCheckTaskDialog(onShowDialog: (Boolean) -> Unit) { TdsDialog( tdsDialogInfo = TdsDialogInfo.Alert( - title = title, + title = stringResource(id = R.string.task_check_title), confirmText = stringResource(id = R.string.Ok), ), onShowDialog = onShowDialog, diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeHeaderContent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeHeaderContent.kt index a1334748..b0faeb63 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeHeaderContent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeHeaderContent.kt @@ -14,16 +14,10 @@ import androidx.compose.ui.unit.sp import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsIconButton import com.titi.app.core.designsystem.component.TdsText -import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TdsTextStyle @Composable -fun TimeHeaderContent( - todayDate: String, - isDailyAfter6AM: Boolean, - textColor: Color, - onClickColor: () -> Unit, -) { +fun TimeHeaderContent(todayDate: String, textColor: Color, onClickColor: () -> Unit) { Box( modifier = Modifier .fillMaxWidth() @@ -34,7 +28,7 @@ fun TimeHeaderContent( text = todayDate, textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, fontSize = 16.sp, - color = if (isDailyAfter6AM) textColor else TdsColor.RED.getColor(), + color = textColor, ) TdsIconButton( diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt index 07f84864..dd094659 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt @@ -6,7 +6,6 @@ import com.airbnb.mvrx.Mavericks import com.airbnb.mvrx.MavericksState import com.titi.app.core.util.addTimeToNow import com.titi.app.core.util.getTodayDate -import com.titi.app.core.util.isAfterSixAM import com.titi.app.doamin.daily.model.Daily import com.titi.app.domain.color.model.TimeColor import com.titi.app.domain.time.model.RecordTimes @@ -23,12 +22,11 @@ data class TimerUiState( daily = getSplashResultStateFromArgs(args).daily, ) - val isDailyAfter6AM: Boolean = isAfterSixAM(daily?.day) + val isFirstDaily: Boolean = daily == null val isSetTask: Boolean = recordTimes.currentTask != null val taskName: String = recordTimes.currentTask?.taskName ?: "" val timerColor = timeColor.toUiModel() val timerRecordTimes = recordTimes.toUiModel(daily) - val isEnableStartRecording: Boolean = isDailyAfter6AM && isSetTask } fun getSplashResultStateFromArgs(args: Bundle): SplashResultState = diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt index 2a6361bc..6359fcd0 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt @@ -19,27 +19,23 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.airbnb.mvrx.asMavericksArgs import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel -import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime -import com.titi.app.core.util.toJson +import com.titi.app.doamin.daily.model.Daily +import com.titi.app.feature.time.content.TimeAddEditDailyDialog import com.titi.app.feature.time.content.TimeButtonContent -import com.titi.app.feature.time.content.TimeCheckDailyDialog +import com.titi.app.feature.time.content.TimeCheckTaskDialog import com.titi.app.feature.time.content.TimeColorDialog -import com.titi.app.feature.time.content.TimeDailyDialog import com.titi.app.feature.time.content.TimeHeaderContent import com.titi.app.feature.time.content.TimeTaskContent import com.titi.app.feature.time.content.TimeTimerDialog import com.titi.app.feature.time.model.SplashResultState import com.titi.app.feature.time.model.TimerUiState import com.titi.app.feature.time.ui.task.TaskBottomSheet -import org.threeten.bp.ZoneOffset -import org.threeten.bp.ZonedDateTime @Composable fun TimerScreen( @@ -63,8 +59,8 @@ fun TimerScreen( var showTaskBottomSheet by remember { mutableStateOf(false) } var showSelectColorDialog by remember { mutableStateOf(false) } - var showAddDailyDialog by remember { mutableStateOf(false) } - var showCheckTaskDailyDialog by remember { mutableStateOf(false) } + var showAddEditDailyDialog by remember { mutableStateOf(false) } + var showCheckTaskDialog by remember { mutableStateOf(false) } var showUpdateTimerDialog by remember { mutableStateOf(false) } if (showTaskBottomSheet) { @@ -97,39 +93,35 @@ fun TimerScreen( ) } - if (showAddDailyDialog) { - TimeDailyDialog( + if (showAddEditDailyDialog) { + TimeAddEditDailyDialog( + isFirstDaily = uiState.isFirstDaily, todayDate = uiState.todayDate, currentTime = uiState.recordTimes.setGoalTime.getTdsTime(), - onPositive = { - if (it > 0) { - viewModel.updateSetGoalTime( - uiState.recordTimes, - it, - ) - viewModel.addDaily() - onChangeFinishStateFalse() + onPositive = { goalTime -> + if (goalTime > 0) { + if (uiState.isFirstDaily) { + viewModel.addDaily() + } else { + viewModel.updateSetGoalTime( + uiState.recordTimes, + goalTime, + ) + + onChangeFinishStateFalse() + } } }, onShowDialog = { - showAddDailyDialog = it + showAddEditDailyDialog = it }, ) } - if (showCheckTaskDailyDialog) { - TimeCheckDailyDialog( - title = if (!uiState.isSetTask && !uiState.isDailyAfter6AM) { - stringResource(id = R.string.daily_task_check_title) - } else if (!uiState.isSetTask) { - stringResource(id = R.string.task_check_title) - } else { - stringResource(id = R.string.daily_check_title) - }, - onShowDialog = { - showCheckTaskDailyDialog = it - }, - ) + if (showCheckTaskDialog) { + TimeCheckTaskDialog { + showCheckTaskDialog = it + } } if (showUpdateTimerDialog) { @@ -164,39 +156,19 @@ fun TimerScreen( onClickTask = { showTaskBottomSheet = true }, - onClickAddDaily = { - showAddDailyDialog = true + onClickAddEditDaily = { + showAddEditDailyDialog = true }, onClickStartRecord = { - if (uiState.isEnableStartRecording) { - val updateRecordTimes = - with(uiState.recordTimes) { - if (savedTimerTime <= 0) { - copy( - recording = true, - recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), - savedTimerTime = setTimerTime, - ) - } else { - copy( - recording = true, - recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), - ) - } - } - - viewModel.updateMeasuringState(updateRecordTimes) - - val splashResultStateString = - SplashResultState( - recordTimes = updateRecordTimes, - timeColor = uiState.timeColor, - daily = uiState.daily, - ).toJson() - + if (uiState.isSetTask) { + val splashResultStateString = viewModel.startRecording( + recordTimes = uiState.recordTimes, + daily = uiState.daily ?: Daily(), + timeColor = uiState.timeColor, + ) onNavigateToMeasure(splashResultStateString) } else { - showCheckTaskDailyDialog = true + showCheckTaskDialog = true } }, onClickSettingTimer = { @@ -212,7 +184,7 @@ private fun TimerScreen( textColor: Color, onClickColor: () -> Unit, onClickTask: () -> Unit, - onClickAddDaily: () -> Unit, + onClickAddEditDaily: () -> Unit, onClickStartRecord: () -> Unit, onClickSettingTimer: () -> Unit, ) { @@ -229,7 +201,6 @@ private fun TimerScreen( ) { TimeHeaderContent( todayDate = uiState.todayDate, - isDailyAfter6AM = uiState.isDailyAfter6AM, textColor = textColor, onClickColor = onClickColor, ) @@ -273,9 +244,9 @@ private fun TimerScreen( TimeButtonContent( recordingMode = 1, - isDailyAfter6AM = uiState.isDailyAfter6AM, tintColor = textColor, - onClickAddDaily = onClickAddDaily, + isFirstDaily = uiState.isFirstDaily, + onClickAddEditDaily = onClickAddEditDaily, onClickStartRecord = onClickStartRecord, onClickSettingTimer = onClickSettingTimer, ) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt index e5c0c097..8da0a1ec 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt @@ -5,8 +5,12 @@ import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.hilt.AssistedViewModelFactory import com.airbnb.mvrx.hilt.hiltMavericksViewModelFactory +import com.titi.app.core.util.isAfterSixAM +import com.titi.app.core.util.toJson +import com.titi.app.doamin.daily.model.Daily import com.titi.app.doamin.daily.usecase.AddDailyUseCase import com.titi.app.doamin.daily.usecase.GetCurrentDailyFlowUseCase +import com.titi.app.domain.color.model.TimeColor import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.domain.color.usecase.UpdateColorUseCase import com.titi.app.domain.time.model.RecordTimes @@ -15,6 +19,7 @@ import com.titi.app.domain.time.usecase.UpdateMeasuringStateUseCase import com.titi.app.domain.time.usecase.UpdateRecordingModeUseCase import com.titi.app.domain.time.usecase.UpdateSetGoalTimeUseCase import com.titi.app.domain.time.usecase.UpdateSetTimerTimeUseCase +import com.titi.app.feature.time.model.SplashResultState import com.titi.app.feature.time.model.TimerColor import com.titi.app.feature.time.model.TimerUiState import dagger.assisted.Assisted @@ -22,6 +27,8 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch +import org.threeten.bp.ZoneOffset +import org.threeten.bp.ZonedDateTime class TimerViewModel @AssistedInject constructor( @Assisted initialState: TimerUiState, @@ -88,6 +95,12 @@ class TimerViewModel @AssistedInject constructor( prevTimerColor = timerColor } + fun addDaily() { + viewModelScope.launch { + addDailyUseCase(Daily()) + } + } + fun updateSetGoalTime(recordTimes: RecordTimes, setGoalTime: Long) { viewModelScope.launch { updateSetGoalTimeUseCase( @@ -97,16 +110,36 @@ class TimerViewModel @AssistedInject constructor( } } - fun addDaily() { - viewModelScope.launch { - addDailyUseCase() + fun startRecording(recordTimes: RecordTimes, daily: Daily, timeColor: TimeColor): String { + val updateRecordTimes = if (recordTimes.savedTimerTime <= 0) { + recordTimes.copy( + recording = true, + recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + savedTimerTime = recordTimes.setTimerTime, + ) + } else { + recordTimes.copy( + recording = true, + recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + ) + } + + val updateDaily = if (isAfterSixAM(daily.day)) { + daily + } else { + Daily() } - } - fun updateMeasuringState(recordTimes: RecordTimes) { viewModelScope.launch { - updateMeasuringStateUseCase(recordTimes) + updateMeasuringStateUseCase(updateRecordTimes) + addDailyUseCase(updateDaily) } + + return SplashResultState( + recordTimes = updateRecordTimes, + daily = updateDaily, + timeColor = timeColor, + ).toJson() } fun updateSetTimerTime(recordTimes: RecordTimes, timerTime: Long) { From 7eddfbad2759577be29a9f4c3467274878b35d99 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 15:21:40 +0900 Subject: [PATCH 29/41] =?UTF-8?q?#122=20Update=20stopwatch=20screen=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../titi/app/domain/time/model/RecordTimes.kt | 2 +- .../time/usecase/UpdateSetGoalTimeUseCase.kt | 6 +- .../feature/time/content/TimeButtonContent.kt | 12 +-- .../feature/time/model/StopWatchUiState.kt | 4 +- .../time/ui/stopwatch/StopWatchScreen.kt | 89 +++++++------------ .../time/ui/stopwatch/StopWatchViewModel.kt | 55 ++++++++++-- .../app/feature/time/ui/timer/TimerScreen.kt | 3 +- .../feature/time/ui/timer/TimerViewModel.kt | 27 ++++-- 8 files changed, 113 insertions(+), 85 deletions(-) diff --git a/domain/time/src/main/kotlin/com/titi/app/domain/time/model/RecordTimes.kt b/domain/time/src/main/kotlin/com/titi/app/domain/time/model/RecordTimes.kt index 9aacab77..15c9b3d0 100644 --- a/domain/time/src/main/kotlin/com/titi/app/domain/time/model/RecordTimes.kt +++ b/domain/time/src/main/kotlin/com/titi/app/domain/time/model/RecordTimes.kt @@ -13,6 +13,6 @@ data class RecordTimes( val savedSumTime: Long = 0, val savedTimerTime: Long = 3600, val savedStopWatchTime: Long = 0, - val savedGoalTime: Long = 7200, + val savedGoalTime: Long = 21600, val currentTask: CurrentTask? = null, ) : Parcelable diff --git a/domain/time/src/main/kotlin/com/titi/app/domain/time/usecase/UpdateSetGoalTimeUseCase.kt b/domain/time/src/main/kotlin/com/titi/app/domain/time/usecase/UpdateSetGoalTimeUseCase.kt index a0790cd9..2acb4743 100644 --- a/domain/time/src/main/kotlin/com/titi/app/domain/time/usecase/UpdateSetGoalTimeUseCase.kt +++ b/domain/time/src/main/kotlin/com/titi/app/domain/time/usecase/UpdateSetGoalTimeUseCase.kt @@ -14,10 +14,8 @@ class UpdateSetGoalTimeUseCase @Inject constructor( .toRepositoryModel() .copy( setGoalTime = setGoalTime, - savedSumTime = 0, - savedTimerTime = recordTimes.setTimerTime, - savedStopWatchTime = 0, - savedGoalTime = setGoalTime, + savedGoalTime = setGoalTime - + (recordTimes.setGoalTime - recordTimes.savedGoalTime), ), ) } diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt index f3680400..ed62bb1f 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt @@ -35,7 +35,11 @@ fun TimeButtonContent( size = 50.dp, ) { Icon( - painter = painterResource(id = R.drawable.add_record_icon), + painter = if (isFirstDaily) { + painterResource(id = R.drawable.add_record_icon) + } else { + painterResource(id = R.drawable.edit_record_icon) + }, contentDescription = "addRecord", tint = tintColor, ) @@ -48,11 +52,7 @@ fun TimeButtonContent( size = 70.dp, ) { Icon( - painter = if (isFirstDaily) { - painterResource(id = R.drawable.start_record_icon) - } else { - painterResource(id = R.drawable.edit_record_icon) - }, + painter = painterResource(id = R.drawable.start_record_icon), contentDescription = "startRecord", tint = Color.Unspecified, ) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt index 9ecff11e..bc2692db 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt @@ -4,7 +4,6 @@ import android.os.Bundle import com.airbnb.mvrx.MavericksState import com.titi.app.core.util.addTimeToNow import com.titi.app.core.util.getTodayDate -import com.titi.app.core.util.isAfterSixAM import com.titi.app.doamin.daily.model.Daily import com.titi.app.domain.color.model.TimeColor import com.titi.app.domain.time.model.RecordTimes @@ -21,12 +20,11 @@ data class StopWatchUiState( daily = getSplashResultStateFromArgs(args).daily, ) - val isDailyAfter6AM: Boolean = isAfterSixAM(daily?.day) + val isFirstDaily: Boolean = daily == null val isSetTask: Boolean = recordTimes.currentTask != null val taskName: String = recordTimes.currentTask?.taskName ?: "" val stopWatchColor = timeColor.toUiModel() val stopWatchRecordTimes = recordTimes.toUiModel(daily) - val isEnableStartRecording: Boolean = isDailyAfter6AM && isSetTask } data class StopWatchColor( diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt index 6c6daed7..bddcdde9 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt @@ -18,26 +18,21 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.airbnb.mvrx.asMavericksArgs import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel -import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime -import com.titi.app.core.util.toJson +import com.titi.app.feature.time.content.TimeAddEditDailyDialog import com.titi.app.feature.time.content.TimeButtonContent -import com.titi.app.feature.time.content.TimeCheckDailyDialog +import com.titi.app.feature.time.content.TimeCheckTaskDialog import com.titi.app.feature.time.content.TimeColorDialog -import com.titi.app.feature.time.content.TimeDailyDialog import com.titi.app.feature.time.content.TimeHeaderContent import com.titi.app.feature.time.content.TimeTaskContent import com.titi.app.feature.time.model.SplashResultState import com.titi.app.feature.time.model.StopWatchUiState import com.titi.app.feature.time.ui.task.TaskBottomSheet -import org.threeten.bp.ZoneOffset -import org.threeten.bp.ZonedDateTime @Composable fun StopWatchScreen( @@ -59,8 +54,8 @@ fun StopWatchScreen( var showTaskBottomSheet by remember { mutableStateOf(false) } var showSelectColorDialog by remember { mutableStateOf(false) } - var showAddDailyDialog by remember { mutableStateOf(false) } - var showCheckTaskDailyDialog by remember { mutableStateOf(false) } + var showAddEditDailyDialog by remember { mutableStateOf(false) } + var showCheckTaskDialog by remember { mutableStateOf(false) } if (showTaskBottomSheet) { TaskBottomSheet( @@ -90,38 +85,33 @@ fun StopWatchScreen( ) } - if (showAddDailyDialog) { - TimeDailyDialog( + if (showAddEditDailyDialog) { + TimeAddEditDailyDialog( + isFirstDaily = uiState.isFirstDaily, todayDate = uiState.todayDate, currentTime = uiState.recordTimes.setGoalTime.getTdsTime(), - onPositive = { - if (it > 0) { - viewModel.updateSetGoalTime( - uiState.recordTimes, - it, - ) - viewModel.addDaily() + onPositive = { goalTime -> + if (goalTime > 0) { + if (uiState.isFirstDaily) { + viewModel.addDaily() + } else { + viewModel.updateSetGoalTime( + uiState.recordTimes, + goalTime, + ) + } } }, onShowDialog = { - showAddDailyDialog = it + showAddEditDailyDialog = it }, ) } - if (showCheckTaskDailyDialog) { - TimeCheckDailyDialog( - title = if (!uiState.isSetTask && !uiState.isDailyAfter6AM) { - stringResource(id = R.string.daily_task_check_title) - } else if (!uiState.isSetTask) { - stringResource(id = R.string.task_check_title) - } else { - stringResource(id = R.string.daily_check_title) - }, - onShowDialog = { - showCheckTaskDailyDialog = it - }, - ) + if (showCheckTaskDialog) { + TimeCheckTaskDialog { + showCheckTaskDialog = it + } } StopWatchScreen( @@ -138,29 +128,19 @@ fun StopWatchScreen( onClickTask = { showTaskBottomSheet = true }, - onClickAddDaily = { - showAddDailyDialog = true + onClickAddEditDaily = { + showAddEditDailyDialog = true }, onClickStartRecord = { - if (uiState.isEnableStartRecording) { - val updateRecordTimes = - uiState.recordTimes.copy( - recording = true, - recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), - ) - - viewModel.updateMeasuringState(updateRecordTimes) - - val splashResultStateString = - SplashResultState( - recordTimes = updateRecordTimes, - timeColor = uiState.timeColor, - daily = uiState.daily, - ).toJson() - + if (uiState.isSetTask) { + val splashResultStateString = viewModel.startRecording( + recordTimes = uiState.recordTimes, + daily = uiState.daily, + timeColor = uiState.timeColor, + ) onNavigateToMeasure(splashResultStateString) } else { - showCheckTaskDailyDialog = true + showCheckTaskDialog = true } }, onClickResetStopWatch = { @@ -175,7 +155,7 @@ private fun StopWatchScreen( textColor: Color, onClickColor: () -> Unit, onClickTask: () -> Unit, - onClickAddDaily: () -> Unit, + onClickAddEditDaily: () -> Unit, onClickStartRecord: () -> Unit, onClickResetStopWatch: () -> Unit, ) { @@ -191,7 +171,6 @@ private fun StopWatchScreen( ) { TimeHeaderContent( todayDate = uiState.todayDate, - isDailyAfter6AM = uiState.isDailyAfter6AM, textColor = textColor, onClickColor = onClickColor, ) @@ -234,9 +213,9 @@ private fun StopWatchScreen( TimeButtonContent( recordingMode = 2, - isDailyAfter6AM = uiState.isDailyAfter6AM, tintColor = textColor, - onClickAddDaily = onClickAddDaily, + isFirstDaily = uiState.isFirstDaily, + onClickAddEditDaily = onClickAddEditDaily, onClickStartRecord = onClickStartRecord, onClickResetStopwatch = onClickResetStopWatch, ) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt index 405f626a..edafb4df 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt @@ -5,8 +5,12 @@ import com.airbnb.mvrx.MavericksViewModel import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.hilt.AssistedViewModelFactory import com.airbnb.mvrx.hilt.hiltMavericksViewModelFactory +import com.titi.app.core.util.isAfterSixAM +import com.titi.app.core.util.toJson +import com.titi.app.doamin.daily.model.Daily import com.titi.app.doamin.daily.usecase.AddDailyUseCase import com.titi.app.doamin.daily.usecase.GetCurrentDailyFlowUseCase +import com.titi.app.domain.color.model.TimeColor import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.domain.color.usecase.UpdateColorUseCase import com.titi.app.domain.time.model.RecordTimes @@ -15,6 +19,7 @@ import com.titi.app.domain.time.usecase.UpdateMeasuringStateUseCase import com.titi.app.domain.time.usecase.UpdateRecordingModeUseCase import com.titi.app.domain.time.usecase.UpdateSavedStopWatchTimeUseCase import com.titi.app.domain.time.usecase.UpdateSetGoalTimeUseCase +import com.titi.app.feature.time.model.SplashResultState import com.titi.app.feature.time.model.StopWatchColor import com.titi.app.feature.time.model.StopWatchUiState import dagger.assisted.Assisted @@ -22,6 +27,8 @@ import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch +import org.threeten.bp.ZoneOffset +import org.threeten.bp.ZonedDateTime class StopWatchViewModel @AssistedInject constructor( @Assisted initialState: StopWatchUiState, @@ -88,6 +95,12 @@ class StopWatchViewModel @AssistedInject constructor( prevStopWatchColor = stopWatchColor } + fun addDaily() { + viewModelScope.launch { + addDailyUseCase(Daily()) + } + } + fun updateSetGoalTime(recordTimes: RecordTimes, setGoalTime: Long) { viewModelScope.launch { updateSetGoalTimeUseCase( @@ -97,16 +110,46 @@ class StopWatchViewModel @AssistedInject constructor( } } - fun addDaily() { - viewModelScope.launch { - addDailyUseCase() + fun startRecording(recordTimes: RecordTimes, daily: Daily?, timeColor: TimeColor): String { + val updateRecordTimes = if (isAfterSixAM(daily?.day)) { + if (recordTimes.savedTimerTime <= 0) { + recordTimes.copy( + recording = true, + recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + savedTimerTime = recordTimes.setTimerTime, + ) + } else { + recordTimes.copy( + recording = true, + recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + ) + } + } else { + recordTimes.copy( + recording = true, + recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + savedSumTime = 0, + savedTimerTime = recordTimes.setTimerTime, + savedStopWatchTime = 0, + ) + } + + val updateDaily = if (daily != null && isAfterSixAM(daily.day)) { + daily + } else { + Daily() } - } - fun updateMeasuringState(recordTimes: RecordTimes) { viewModelScope.launch { - updateMeasuringStateUseCase(recordTimes) + updateMeasuringStateUseCase(updateRecordTimes) + addDailyUseCase(updateDaily) } + + return SplashResultState( + recordTimes = updateRecordTimes, + daily = updateDaily, + timeColor = timeColor, + ).toJson() } fun updateSavedStopWatchTime(recordTimes: RecordTimes) { diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt index 6359fcd0..0d1c4eaa 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt @@ -25,7 +25,6 @@ import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime -import com.titi.app.doamin.daily.model.Daily import com.titi.app.feature.time.content.TimeAddEditDailyDialog import com.titi.app.feature.time.content.TimeButtonContent import com.titi.app.feature.time.content.TimeCheckTaskDialog @@ -163,7 +162,7 @@ fun TimerScreen( if (uiState.isSetTask) { val splashResultStateString = viewModel.startRecording( recordTimes = uiState.recordTimes, - daily = uiState.daily ?: Daily(), + daily = uiState.daily, timeColor = uiState.timeColor, ) onNavigateToMeasure(splashResultStateString) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt index 8da0a1ec..1eb943b8 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt @@ -110,21 +110,32 @@ class TimerViewModel @AssistedInject constructor( } } - fun startRecording(recordTimes: RecordTimes, daily: Daily, timeColor: TimeColor): String { - val updateRecordTimes = if (recordTimes.savedTimerTime <= 0) { - recordTimes.copy( - recording = true, - recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), - savedTimerTime = recordTimes.setTimerTime, - ) + fun startRecording(recordTimes: RecordTimes, daily: Daily?, timeColor: TimeColor): String { + val updateRecordTimes = if (isAfterSixAM(daily?.day)) { + if (recordTimes.savedTimerTime <= 0) { + recordTimes.copy( + recording = true, + recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + savedTimerTime = recordTimes.setTimerTime, + ) + } else { + recordTimes.copy( + recording = true, + recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + ) + } } else { recordTimes.copy( recording = true, recordStartAt = ZonedDateTime.now(ZoneOffset.UTC).toString(), + savedSumTime = 0, + savedTimerTime = recordTimes.setTimerTime, + savedStopWatchTime = 0, + savedGoalTime = recordTimes.setGoalTime, ) } - val updateDaily = if (isAfterSixAM(daily.day)) { + val updateDaily = if (daily != null && isAfterSixAM(daily.day)) { daily } else { Daily() From aa0a8a1dc53b3720631f3cd6a97be5a3584e7688 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 15:31:17 +0900 Subject: [PATCH 30/41] #122 Update : GetLastDailyFlowUseCase --- .../titi/app/data/daily/api/DailyRepository.kt | 15 +-------------- .../app/data/daily/impl/local/dao/DailyDao.kt | 8 ++------ .../daily/impl/repository/DailyRepositoryImpl.kt | 10 ++-------- ...yFlowUseCase.kt => GetLastDailyFlowUseCase.kt} | 4 ++-- .../app/feature/main/ui/main/MainViewModel.kt | 6 +++--- .../time/ui/stopwatch/StopWatchViewModel.kt | 6 +++--- .../app/feature/time/ui/timer/TimerViewModel.kt | 6 +++--- 7 files changed, 16 insertions(+), 39 deletions(-) rename domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/{GetCurrentDailyFlowUseCase.kt => GetLastDailyFlowUseCase.kt} (73%) diff --git a/data/daily/api/src/main/kotlin/com/titi/app/data/daily/api/DailyRepository.kt b/data/daily/api/src/main/kotlin/com/titi/app/data/daily/api/DailyRepository.kt index e5bd3f46..1d783623 100644 --- a/data/daily/api/src/main/kotlin/com/titi/app/data/daily/api/DailyRepository.kt +++ b/data/daily/api/src/main/kotlin/com/titi/app/data/daily/api/DailyRepository.kt @@ -24,20 +24,7 @@ interface DailyRepository { suspend fun getDailies(startDateTime: String, endDateTime: String): List? - fun getDateDailyFlow( - startDateTime: String = LocalDate - .now() - .minusDays(1) - .atStartOfDay(ZoneOffset.systemDefault()) - .withZoneSameInstant(ZoneOffset.UTC) - .toString(), - endDateTime: String = LocalDate - .now() - .atTime(23, 59, 59) - .atZone(ZoneId.systemDefault()) - .withZoneSameInstant(ZoneOffset.UTC) - .toString(), - ): Flow + fun getLastDailyFlow(): Flow suspend fun getAllDailies(): List? diff --git a/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/local/dao/DailyDao.kt b/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/local/dao/DailyDao.kt index 6f460ea0..599fdfe6 100644 --- a/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/local/dao/DailyDao.kt +++ b/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/local/dao/DailyDao.kt @@ -23,12 +23,8 @@ internal interface DailyDao { ) suspend fun getWeekDaily(startDateTime: String, endDateTime: String): List? - @Query( - "SELECT * FROM dailies " + - " WHERE datetime(day) " + - "BETWEEN datetime(:startDateTime) AND datetime(:endDateTime) ORDER BY id desc LIMIT 1", - ) - fun getDateDailyFlow(startDateTime: String, endDateTime: String): Flow + @Query("SELECT * FROM dailies ORDER BY id desc LIMIT 1") + fun getLastDailyFlow(): Flow @Query("SELECT * FROM dailies") suspend fun getAllDailies(): List? diff --git a/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/repository/DailyRepositoryImpl.kt b/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/repository/DailyRepositoryImpl.kt index 81ca83dc..0ec8d3d1 100644 --- a/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/repository/DailyRepositoryImpl.kt +++ b/data/daily/impl/src/main/kotlin/com/titi/app/data/daily/impl/repository/DailyRepositoryImpl.kt @@ -32,14 +32,8 @@ internal class DailyRepositoryImpl @Inject constructor( )?.map { it.toRepositoryModel() } } - override fun getDateDailyFlow( - startDateTime: String, - endDateTime: String, - ): Flow { - return dailyDao.getDateDailyFlow( - startDateTime = startDateTime, - endDateTime = endDateTime, - ).map { it?.toRepositoryModel() } + override fun getLastDailyFlow(): Flow { + return dailyDao.getLastDailyFlow().map { it?.toRepositoryModel() } } override suspend fun getAllDailies(): List? { diff --git a/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/GetCurrentDailyFlowUseCase.kt b/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/GetLastDailyFlowUseCase.kt similarity index 73% rename from domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/GetCurrentDailyFlowUseCase.kt rename to domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/GetLastDailyFlowUseCase.kt index f0b62f1d..def45b69 100644 --- a/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/GetCurrentDailyFlowUseCase.kt +++ b/domain/daily/src/main/kotlin/com/titi/app/doamin/daily/usecase/GetLastDailyFlowUseCase.kt @@ -7,10 +7,10 @@ import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map -class GetCurrentDailyFlowUseCase @Inject constructor( +class GetLastDailyFlowUseCase @Inject constructor( private val dailyRepository: DailyRepository, ) { - operator fun invoke(): Flow = dailyRepository.getDateDailyFlow().map { + operator fun invoke(): Flow = dailyRepository.getLastDailyFlow().map { it?.toDomainModel() } } diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainViewModel.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainViewModel.kt index cda736c4..90ddfb61 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainViewModel.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainViewModel.kt @@ -2,7 +2,7 @@ package com.titi.app.feature.main.ui.main import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.titi.app.doamin.daily.usecase.GetCurrentDailyFlowUseCase +import com.titi.app.doamin.daily.usecase.GetLastDailyFlowUseCase import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.domain.time.usecase.GetRecordTimesFlowUseCase import com.titi.app.feature.main.model.SplashResultState @@ -17,13 +17,13 @@ import kotlinx.coroutines.flow.shareIn class MainViewModel @Inject constructor( getRecordTimesFlowUseCase: GetRecordTimesFlowUseCase, getTimeColorFlowUseCase: GetTimeColorFlowUseCase, - getCurrentDailyFlowUseCase: GetCurrentDailyFlowUseCase, + getLastDailyFlowUseCase: GetLastDailyFlowUseCase, ) : ViewModel() { val splashResultState: SharedFlow = combine( getRecordTimesFlowUseCase(), getTimeColorFlowUseCase(), - getCurrentDailyFlowUseCase(), + getLastDailyFlowUseCase(), ) { recordTimes, timeColor, daily -> SplashResultState( recordTimes = recordTimes, diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt index edafb4df..a835707a 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt @@ -9,7 +9,7 @@ import com.titi.app.core.util.isAfterSixAM import com.titi.app.core.util.toJson import com.titi.app.doamin.daily.model.Daily import com.titi.app.doamin.daily.usecase.AddDailyUseCase -import com.titi.app.doamin.daily.usecase.GetCurrentDailyFlowUseCase +import com.titi.app.doamin.daily.usecase.GetLastDailyFlowUseCase import com.titi.app.domain.color.model.TimeColor import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.domain.color.usecase.UpdateColorUseCase @@ -34,7 +34,7 @@ class StopWatchViewModel @AssistedInject constructor( @Assisted initialState: StopWatchUiState, getRecordTimesFlowUseCase: GetRecordTimesFlowUseCase, getTimeColorFlowUseCase: GetTimeColorFlowUseCase, - getCurrentDailyFlowUseCase: GetCurrentDailyFlowUseCase, + getLastDailyFlowUseCase: GetLastDailyFlowUseCase, private val updateRecordingModeUseCase: UpdateRecordingModeUseCase, private val updateColorUseCase: UpdateColorUseCase, private val updateSetGoalTimeUseCase: UpdateSetGoalTimeUseCase, @@ -57,7 +57,7 @@ class StopWatchViewModel @AssistedInject constructor( copy(timeColor = it) } - getCurrentDailyFlowUseCase().catch { + getLastDailyFlowUseCase().catch { Log.e("TimeViewModel", it.message.toString()) }.setOnEach { copy(daily = it) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt index 1eb943b8..6d12d790 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt @@ -9,7 +9,7 @@ import com.titi.app.core.util.isAfterSixAM import com.titi.app.core.util.toJson import com.titi.app.doamin.daily.model.Daily import com.titi.app.doamin.daily.usecase.AddDailyUseCase -import com.titi.app.doamin.daily.usecase.GetCurrentDailyFlowUseCase +import com.titi.app.doamin.daily.usecase.GetLastDailyFlowUseCase import com.titi.app.domain.color.model.TimeColor import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.domain.color.usecase.UpdateColorUseCase @@ -34,7 +34,7 @@ class TimerViewModel @AssistedInject constructor( @Assisted initialState: TimerUiState, getRecordTimesFlowUseCase: GetRecordTimesFlowUseCase, getTimeColorFlowUseCase: GetTimeColorFlowUseCase, - getCurrentDailyFlowUseCase: GetCurrentDailyFlowUseCase, + getLastDailyFlowUseCase: GetLastDailyFlowUseCase, private val updateRecordingModeUseCase: UpdateRecordingModeUseCase, private val updateColorUseCase: UpdateColorUseCase, private val updateSetGoalTimeUseCase: UpdateSetGoalTimeUseCase, @@ -55,7 +55,7 @@ class TimerViewModel @AssistedInject constructor( copy(timeColor = it) } - getCurrentDailyFlowUseCase().catch { + getLastDailyFlowUseCase().catch { Log.e("TimeViewModel", it.message.toString()) }.setOnEach { copy(daily = it) From 8ece6da85f1978d7d46da832c609b1bc73f109ae Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 15:42:53 +0900 Subject: [PATCH 31/41] #122 Update : Add Edit view logic --- .../ColorSelectComponent.kt} | 8 ++-- .../TimeAddEditDailyDialog.kt | 2 +- .../TimeButtonComponent.kt} | 11 +++-- .../TimeCheckDailyDialog.kt} | 6 +-- .../{content => component}/TimeColorDialog.kt | 4 +- .../TimeHeaderComponent.kt} | 4 +- .../TimeTaskComponent.kt} | 4 +- .../{content => component}/TimeTimerDialog.kt | 2 +- .../time/ui/stopwatch/StopWatchScreen.kt | 43 +++++++++++------- .../app/feature/time/ui/timer/TimerScreen.kt | 45 ++++++++++++------- 10 files changed, 78 insertions(+), 51 deletions(-) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content/ColorSelectContent.kt => component/ColorSelectComponent.kt} (97%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content => component}/TimeAddEditDailyDialog.kt (98%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content/TimeButtonContent.kt => component/TimeButtonComponent.kt} (90%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content/TimeCheckTaskDialog.kt => component/TimeCheckDailyDialog.kt} (79%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content => component}/TimeColorDialog.kt (94%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content/TimeHeaderContent.kt => component/TimeHeaderComponent.kt} (91%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content/TimeTaskContent.kt => component/TimeTaskComponent.kt} (96%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/{content => component}/TimeTimerDialog.kt (98%) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/ColorSelectContent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/ColorSelectComponent.kt similarity index 97% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/ColorSelectContent.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/ColorSelectComponent.kt index 0078814b..bdb84ede 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/ColorSelectContent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/ColorSelectComponent.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -32,7 +32,7 @@ import com.titi.app.core.designsystem.theme.TdsTextStyle import com.titi.app.core.designsystem.theme.TiTiTheme @Composable -fun ColorSelectContent( +fun ColorSelectComponent( backgroundColor: Color, textColor: Color, onClickBackgroundColor: () -> Unit, @@ -129,9 +129,9 @@ fun ColorSelectContent( @Preview @Composable -private fun ColorSelectContentPreview() { +private fun ColorSelectComponentPreview() { TiTiTheme { - ColorSelectContent( + ColorSelectComponent( backgroundColor = Color.Blue, textColor = Color.Black, onClickBackgroundColor = {}, diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeAddEditDailyDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeAddEditDailyDialog.kt similarity index 98% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeAddEditDailyDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeAddEditDailyDialog.kt index 6e7e6571..cce1ec5d 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeAddEditDailyDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeAddEditDailyDialog.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeButtonComponent.kt similarity index 90% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeButtonComponent.kt index ed62bb1f..b17ba696 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeButtonContent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeButtonComponent.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row @@ -14,9 +14,10 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsIconButton +import com.titi.app.core.designsystem.theme.TdsColor @Composable -fun TimeButtonContent( +fun TimeButtonComponent( recordingMode: Int, tintColor: Color, isFirstDaily: Boolean, @@ -41,7 +42,11 @@ fun TimeButtonContent( painterResource(id = R.drawable.edit_record_icon) }, contentDescription = "addRecord", - tint = tintColor, + tint = if (isFirstDaily) { + TdsColor.RED.getColor() + } else { + tintColor + }, ) } diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckTaskDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckDailyDialog.kt similarity index 79% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckTaskDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckDailyDialog.kt index 0ca32fac..a1acbee0 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeCheckTaskDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckDailyDialog.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height @@ -11,10 +11,10 @@ import com.titi.app.core.designsystem.component.TdsDialog import com.titi.app.core.designsystem.model.TdsDialogInfo @Composable -fun TimeCheckTaskDialog(onShowDialog: (Boolean) -> Unit) { +fun TimeCheckDailyDialog(title: String, onShowDialog: (Boolean) -> Unit) { TdsDialog( tdsDialogInfo = TdsDialogInfo.Alert( - title = stringResource(id = R.string.task_check_title), + title = title, confirmText = stringResource(id = R.string.Ok), ), onShowDialog = onShowDialog, diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeColorDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeColorDialog.kt similarity index 94% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeColorDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeColorDialog.kt index 49af82b2..475fe06f 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeColorDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeColorDialog.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.height @@ -32,7 +32,7 @@ fun TimeColorDialog( ), onShowDialog = onShowDialog, ) { - ColorSelectContent( + ColorSelectComponent( backgroundColor = backgroundColor, textColor = textColor, onClickBackgroundColor = { diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeHeaderContent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeHeaderComponent.kt similarity index 91% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeHeaderContent.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeHeaderComponent.kt index b0faeb63..f990ff75 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeHeaderContent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeHeaderComponent.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth @@ -17,7 +17,7 @@ import com.titi.app.core.designsystem.component.TdsText import com.titi.app.core.designsystem.theme.TdsTextStyle @Composable -fun TimeHeaderContent(todayDate: String, textColor: Color, onClickColor: () -> Unit) { +fun TimeHeaderComponent(todayDate: String, textColor: Color, onClickColor: () -> Unit) { Box( modifier = Modifier .fillMaxWidth() diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeTaskContent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeTaskComponent.kt similarity index 96% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeTaskContent.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeTaskComponent.kt index 5590438b..da22b2b6 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeTaskContent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeTaskComponent.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.layout.PaddingValues @@ -15,7 +15,7 @@ import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TdsTextStyle @Composable -fun TimeTaskContent( +fun TimeTaskComponent( isSetTask: Boolean, textColor: Color, taskName: String, diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeTimerDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeTimerDialog.kt similarity index 98% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeTimerDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeTimerDialog.kt index f481bce6..2eb2f4e4 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/content/TimeTimerDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeTimerDialog.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.time.content +package com.titi.app.feature.time.component import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt index bddcdde9..5f6da6cc 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt @@ -18,18 +18,20 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.airbnb.mvrx.asMavericksArgs import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel +import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime -import com.titi.app.feature.time.content.TimeAddEditDailyDialog -import com.titi.app.feature.time.content.TimeButtonContent -import com.titi.app.feature.time.content.TimeCheckTaskDialog -import com.titi.app.feature.time.content.TimeColorDialog -import com.titi.app.feature.time.content.TimeHeaderContent -import com.titi.app.feature.time.content.TimeTaskContent +import com.titi.app.feature.time.component.TimeAddEditDailyDialog +import com.titi.app.feature.time.component.TimeButtonComponent +import com.titi.app.feature.time.component.TimeCheckDailyDialog +import com.titi.app.feature.time.component.TimeColorDialog +import com.titi.app.feature.time.component.TimeHeaderComponent +import com.titi.app.feature.time.component.TimeTaskComponent import com.titi.app.feature.time.model.SplashResultState import com.titi.app.feature.time.model.StopWatchUiState import com.titi.app.feature.time.ui.task.TaskBottomSheet @@ -55,7 +57,7 @@ fun StopWatchScreen( var showTaskBottomSheet by remember { mutableStateOf(false) } var showSelectColorDialog by remember { mutableStateOf(false) } var showAddEditDailyDialog by remember { mutableStateOf(false) } - var showCheckTaskDialog by remember { mutableStateOf(false) } + var showCheckTaskDailyDialog by remember { mutableStateOf(false) } if (showTaskBottomSheet) { TaskBottomSheet( @@ -108,10 +110,19 @@ fun StopWatchScreen( ) } - if (showCheckTaskDialog) { - TimeCheckTaskDialog { - showCheckTaskDialog = it - } + if (showCheckTaskDailyDialog) { + TimeCheckDailyDialog( + title = if (!uiState.isSetTask && uiState.isFirstDaily) { + stringResource(id = R.string.daily_task_check_title) + } else if (!uiState.isSetTask) { + stringResource(id = R.string.task_check_title) + } else { + stringResource(id = R.string.daily_check_title) + }, + onShowDialog = { + showCheckTaskDailyDialog = it + }, + ) } StopWatchScreen( @@ -132,7 +143,7 @@ fun StopWatchScreen( showAddEditDailyDialog = true }, onClickStartRecord = { - if (uiState.isSetTask) { + if (uiState.isSetTask && !uiState.isFirstDaily) { val splashResultStateString = viewModel.startRecording( recordTimes = uiState.recordTimes, daily = uiState.daily, @@ -140,7 +151,7 @@ fun StopWatchScreen( ) onNavigateToMeasure(splashResultStateString) } else { - showCheckTaskDialog = true + showCheckTaskDailyDialog = true } }, onClickResetStopWatch = { @@ -169,7 +180,7 @@ private fun StopWatchScreen( .padding(top = 16.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { - TimeHeaderContent( + TimeHeaderComponent( todayDate = uiState.todayDate, textColor = textColor, onClickColor = onClickColor, @@ -177,7 +188,7 @@ private fun StopWatchScreen( Spacer(modifier = Modifier.weight(1f)) - TimeTaskContent( + TimeTaskComponent( isSetTask = uiState.isSetTask, textColor = textColor, taskName = uiState.taskName, @@ -211,7 +222,7 @@ private fun StopWatchScreen( Spacer(modifier = Modifier.height(50.dp)) - TimeButtonContent( + TimeButtonComponent( recordingMode = 2, tintColor = textColor, isFirstDaily = uiState.isFirstDaily, diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt index 0d1c4eaa..1d196fce 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt @@ -19,19 +19,21 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.airbnb.mvrx.asMavericksArgs import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel +import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime -import com.titi.app.feature.time.content.TimeAddEditDailyDialog -import com.titi.app.feature.time.content.TimeButtonContent -import com.titi.app.feature.time.content.TimeCheckTaskDialog -import com.titi.app.feature.time.content.TimeColorDialog -import com.titi.app.feature.time.content.TimeHeaderContent -import com.titi.app.feature.time.content.TimeTaskContent -import com.titi.app.feature.time.content.TimeTimerDialog +import com.titi.app.feature.time.component.TimeAddEditDailyDialog +import com.titi.app.feature.time.component.TimeButtonComponent +import com.titi.app.feature.time.component.TimeCheckDailyDialog +import com.titi.app.feature.time.component.TimeColorDialog +import com.titi.app.feature.time.component.TimeHeaderComponent +import com.titi.app.feature.time.component.TimeTaskComponent +import com.titi.app.feature.time.component.TimeTimerDialog import com.titi.app.feature.time.model.SplashResultState import com.titi.app.feature.time.model.TimerUiState import com.titi.app.feature.time.ui.task.TaskBottomSheet @@ -59,7 +61,7 @@ fun TimerScreen( var showTaskBottomSheet by remember { mutableStateOf(false) } var showSelectColorDialog by remember { mutableStateOf(false) } var showAddEditDailyDialog by remember { mutableStateOf(false) } - var showCheckTaskDialog by remember { mutableStateOf(false) } + var showCheckTaskDailyDialog by remember { mutableStateOf(false) } var showUpdateTimerDialog by remember { mutableStateOf(false) } if (showTaskBottomSheet) { @@ -117,10 +119,19 @@ fun TimerScreen( ) } - if (showCheckTaskDialog) { - TimeCheckTaskDialog { - showCheckTaskDialog = it - } + if (showCheckTaskDailyDialog) { + TimeCheckDailyDialog( + title = if (!uiState.isSetTask && uiState.isFirstDaily) { + stringResource(id = R.string.daily_task_check_title) + } else if (!uiState.isSetTask) { + stringResource(id = R.string.task_check_title) + } else { + stringResource(id = R.string.daily_check_title) + }, + onShowDialog = { + showCheckTaskDailyDialog = it + }, + ) } if (showUpdateTimerDialog) { @@ -159,7 +170,7 @@ fun TimerScreen( showAddEditDailyDialog = true }, onClickStartRecord = { - if (uiState.isSetTask) { + if (uiState.isSetTask && !uiState.isFirstDaily) { val splashResultStateString = viewModel.startRecording( recordTimes = uiState.recordTimes, daily = uiState.daily, @@ -167,7 +178,7 @@ fun TimerScreen( ) onNavigateToMeasure(splashResultStateString) } else { - showCheckTaskDialog = true + showCheckTaskDailyDialog = true } }, onClickSettingTimer = { @@ -198,7 +209,7 @@ private fun TimerScreen( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { - TimeHeaderContent( + TimeHeaderComponent( todayDate = uiState.todayDate, textColor = textColor, onClickColor = onClickColor, @@ -206,7 +217,7 @@ private fun TimerScreen( Spacer(modifier = Modifier.weight(1f)) - TimeTaskContent( + TimeTaskComponent( isSetTask = uiState.isSetTask, textColor = textColor, taskName = uiState.taskName, @@ -241,7 +252,7 @@ private fun TimerScreen( Spacer(modifier = Modifier.height(50.dp)) - TimeButtonContent( + TimeButtonComponent( recordingMode = 1, tintColor = textColor, isFirstDaily = uiState.isFirstDaily, From 5d3ca423bd22c112632f1e8c56584af884cb56a7 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 16:19:34 +0900 Subject: [PATCH 32/41] #123 Update : Mesaure activity -> screen --- feature/main/build.gradle.kts | 1 + .../feature/main/navigation/TiTiNavHost.kt | 31 ++++++++++------ .../com/titi/app/feature/main/ui/TiTiApp.kt | 10 +---- .../titi/app/feature/main/ui/TiTiAppState.kt | 3 +- .../app/feature/main/ui/main/MainActivity.kt | 37 ------------------- .../measure/navigation/MeasureNavigation.kt | 32 ++++++++++++++++ .../titi/app/feature/popup/PopUpActivity.kt | 27 ++------------ 7 files changed, 60 insertions(+), 81 deletions(-) create mode 100644 feature/measure/src/main/kotlin/com/titi/app/feature/measure/navigation/MeasureNavigation.kt diff --git a/feature/main/build.gradle.kts b/feature/main/build.gradle.kts index a5eb135b..a7a565cf 100644 --- a/feature/main/build.gradle.kts +++ b/feature/main/build.gradle.kts @@ -12,6 +12,7 @@ dependencies { implementation(project(":domain:daily")) implementation(project(":feature:time")) + implementation(project(":feature:measure")) implementation(project(":feature:log")) implementation(project(":feature:popup")) implementation(project(":feature:setting")) diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt index 3b9ea0dc..9ddc1d28 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt @@ -1,24 +1,26 @@ package com.titi.app.feature.main.navigation import android.content.Intent -import androidx.activity.compose.ManagedActivityResultLauncher -import androidx.activity.result.ActivityResult import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.core.net.toUri import androidx.navigation.compose.NavHost +import com.titi.app.core.util.toJson import com.titi.app.feature.log.navigation.logGraph import com.titi.app.feature.main.model.SplashResultState import com.titi.app.feature.main.model.toFeatureTimeModel import com.titi.app.feature.main.ui.TiTiAppState +import com.titi.app.feature.measure.navigation.measureGraph +import com.titi.app.feature.measure.navigation.navigateToMeasure import com.titi.app.feature.popup.PopUpActivity import com.titi.app.feature.popup.PopUpActivity.Companion.COLOR_RECORDING_MODE_KEY -import com.titi.app.feature.popup.PopUpActivity.Companion.MEASURE_SPLASH_RESULT_KEY import com.titi.app.feature.setting.navigation.navigateToFeatures import com.titi.app.feature.setting.navigation.navigateToUpdates import com.titi.app.feature.setting.navigation.settingGraph import com.titi.app.feature.time.navigation.STOPWATCH_SCREEN +import com.titi.app.feature.time.navigation.TIMER_FINISH_KEY import com.titi.app.feature.time.navigation.TIMER_SCREEN import com.titi.app.feature.time.navigation.timeGraph import com.titi.app.feature.webview.navigateToWebView @@ -28,12 +30,17 @@ import com.titi.app.feature.webview.webViewGraph fun TiTiNavHost( splashResultState: SplashResultState, appState: TiTiAppState, - measuringResult: ManagedActivityResultLauncher, modifier: Modifier = Modifier, ) { val navController = appState.navController val context = LocalContext.current + LaunchedEffect(Unit) { + if (splashResultState.recordTimes.recording) { + navController.navigateToMeasure(splashResultState.toJson()) + } + } + NavHost( modifier = modifier, navController = navController, @@ -55,14 +62,16 @@ fun TiTiNavHost( context.startActivity(intent) }, onNavigateToMeasure = { - val intent = Intent(context, PopUpActivity::class.java).apply { - putExtra( - MEASURE_SPLASH_RESULT_KEY, - it, - ) - } + navController.navigateToMeasure(it) + }, + ) - measuringResult.launch(intent) + measureGraph( + onFinish = { isFinish -> + navController.previousBackStackEntry + ?.savedStateHandle + ?.set(TIMER_FINISH_KEY, isFinish) + navController.popBackStack() }, ) diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt index 68814bc4..0e2f5fd0 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt @@ -2,12 +2,9 @@ package com.titi.app.feature.main.ui import android.Manifest import android.annotation.SuppressLint -import android.content.Intent import android.os.Build import android.util.Log -import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement @@ -51,11 +48,7 @@ import com.titi.app.feature.main.navigation.TopLevelDestination @SuppressLint("UnusedContentLambdaTargetStateParameter") @Composable -fun TiTiApp( - splashResultState: SplashResultState, - appState: TiTiAppState, - measuringResult: ManagedActivityResultLauncher, -) { +fun TiTiApp(splashResultState: SplashResultState, appState: TiTiAppState) { val requestPermissionLauncher = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission(), @@ -101,7 +94,6 @@ fun TiTiApp( modifier = Modifier.fillMaxSize(), appState = appState, splashResultState = splashResultState, - measuringResult = measuringResult, ) } } diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt index 7efc322d..a581d5ac 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt @@ -15,6 +15,7 @@ import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.feature.log.navigation.LOG_ROUTE import com.titi.app.feature.log.navigation.navigateToLog import com.titi.app.feature.main.navigation.TopLevelDestination +import com.titi.app.feature.measure.navigation.MEASURE_ROUTE import com.titi.app.feature.setting.navigation.FEATURES_ROUTE import com.titi.app.feature.setting.navigation.SETTING_ROUTE import com.titi.app.feature.setting.navigation.UPDATES_ROUTE @@ -92,7 +93,7 @@ class TiTiAppState( UPDATES_ROUTE, WEBVIEW_ROUTE, -> if (isSystemDarkTheme) 0xFF000000 else 0xFFF2F2F7 - + MEASURE_ROUTE -> 0xFF000000 else -> if (isSystemDarkTheme) 0xFF000000 else 0xFFFFFFFF } } diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt index d75fb949..d33ab66f 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt @@ -1,16 +1,12 @@ package com.titi.app.feature.main.ui.main -import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.SystemBarStyle -import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge -import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -19,14 +15,10 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle import com.titi.app.core.designsystem.theme.TiTiTheme -import com.titi.app.core.util.toJson import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.feature.main.model.SplashResultState import com.titi.app.feature.main.ui.TiTiApp import com.titi.app.feature.main.ui.rememberNiaAppState -import com.titi.app.feature.popup.PopUpActivity -import com.titi.app.feature.popup.PopUpActivity.Companion.MEASURE_SPLASH_RESULT_KEY -import com.titi.app.feature.time.navigation.TIMER_FINISH_KEY import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.filterNotNull @@ -73,40 +65,11 @@ class MainActivity : ComponentActivity() { isSystemDarkTheme = isSystemInDarkTheme(), ) - val measuringResult = - rememberLauncherForActivityResult( - ActivityResultContracts.StartActivityForResult(), - ) { result -> - if (result.resultCode == RESULT_OK) { - result.data?.let { data -> - val isFinish = data.getBooleanExtra(TIMER_FINISH_KEY, false) - - appState.navController - .currentBackStackEntry - ?.savedStateHandle - ?.set(TIMER_FINISH_KEY, isFinish) - } - } - } - TiTiTheme { splashResultState?.let { - if (it.recordTimes.recording) { - SideEffect { - val intent = Intent(this, PopUpActivity::class.java).apply { - putExtra( - MEASURE_SPLASH_RESULT_KEY, - it.toJson(), - ) - } - - measuringResult.launch(intent) - } - } TiTiApp( splashResultState = it, appState = appState, - measuringResult = measuringResult, ) } } diff --git a/feature/measure/src/main/kotlin/com/titi/app/feature/measure/navigation/MeasureNavigation.kt b/feature/measure/src/main/kotlin/com/titi/app/feature/measure/navigation/MeasureNavigation.kt new file mode 100644 index 00000000..42715b0b --- /dev/null +++ b/feature/measure/src/main/kotlin/com/titi/app/feature/measure/navigation/MeasureNavigation.kt @@ -0,0 +1,32 @@ +package com.titi.app.feature.measure.navigation + +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavType +import androidx.navigation.compose.composable +import androidx.navigation.navArgument +import com.titi.app.feature.measure.ui.MeasuringScreen + +private const val MEASURE_SCREEN = "measure" +const val MEASURE_ARG = "splashResultState" +const val MEASURE_ROUTE = "$MEASURE_SCREEN?$MEASURE_ARG={$MEASURE_ARG}" + +fun NavController.navigateToMeasure(splashResultState: String) { + navigate("$MEASURE_SCREEN?$MEASURE_ARG=$splashResultState") +} + +fun NavGraphBuilder.measureGraph(onFinish: (isFinish: Boolean) -> Unit) { + composable( + route = MEASURE_ROUTE, + arguments = listOf( + navArgument(MEASURE_ARG) { + type = NavType.StringType + }, + ), + ) { + MeasuringScreen( + splashResultState = it.arguments?.getString(MEASURE_ARG, "") ?: "", + onFinish = onFinish, + ) + } +} diff --git a/feature/popup/src/main/kotlin/com/titi/app/feature/popup/PopUpActivity.kt b/feature/popup/src/main/kotlin/com/titi/app/feature/popup/PopUpActivity.kt index 69e65bdc..4699a654 100644 --- a/feature/popup/src/main/kotlin/com/titi/app/feature/popup/PopUpActivity.kt +++ b/feature/popup/src/main/kotlin/com/titi/app/feature/popup/PopUpActivity.kt @@ -1,47 +1,28 @@ package com.titi.app.feature.popup -import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import com.titi.app.core.designsystem.theme.TiTiTheme import com.titi.app.feature.color.ui.ColorScreen -import com.titi.app.feature.measure.ui.MeasuringScreen class PopUpActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val recordingMode = intent.getIntExtra(COLOR_RECORDING_MODE_KEY, 0) - val splashResultState = intent.getStringExtra(MEASURE_SPLASH_RESULT_KEY) setContent { TiTiTheme { - when { - recordingMode != 0 -> { - ColorScreen(recordingMode = recordingMode) { - finish() - } - } - - splashResultState != null -> { - MeasuringScreen(splashResultState = splashResultState) { - val resultIntent = Intent().apply { - putExtra("isFinish", it) - } - setResult(RESULT_OK, resultIntent) - finish() - } - } - - else -> finish() - } + ColorScreen( + recordingMode = recordingMode, + onFinish = { finish() }, + ) } } } companion object { const val COLOR_RECORDING_MODE_KEY = "colorRecordingModeKey" - const val MEASURE_SPLASH_RESULT_KEY = "measureSplashResultKey" } } From 0c28b9a2011823b6a1dbe92143c94a6f6ba11f50 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 17:27:08 +0900 Subject: [PATCH 33/41] =?UTF-8?q?#123=20Update=20:=20navgation=20bar=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navigation/TdsBottomNavigationBar.kt | 78 ++++++ .../TdsBottomNavigationBarItem.kt} | 4 +- .../navigation/TopLevelDestination.kt | 2 +- .../feature/log/navigation/LogNavigation.kt | 5 +- .../com/titi/app/feature/log/ui/LogScreen.kt | 228 ++++++++++-------- .../app/feature/main/navigation/TiTiApp.kt | 39 +++ .../feature/main/navigation/TiTiNavHost.kt | 49 +++- .../com/titi/app/feature/main/ui/TiTiApp.kt | 159 ------------ .../titi/app/feature/main/ui/TiTiAppState.kt | 124 ---------- .../app/feature/main/ui/main/MainActivity.kt | 14 +- .../setting/navigation/SettingNavigation.kt | 3 + .../feature/setting/ui/FeaturesListScreen.kt | 9 +- .../app/feature/setting/ui/SettingScreen.kt | 19 +- .../feature/setting/ui/UpdatesListScreen.kt | 9 +- .../feature/time/navigation/TimeNavigation.kt | 4 + .../time/ui/stopwatch/StopWatchScreen.kt | 121 ++++++---- .../app/feature/time/ui/timer/TimerScreen.kt | 124 ++++++---- 17 files changed, 475 insertions(+), 516 deletions(-) create mode 100644 core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TdsBottomNavigationBar.kt rename core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/{component/TdsNavigationBarItem.kt => navigation/TdsBottomNavigationBarItem.kt} (93%) rename {feature/main/src/main/kotlin/com/titi/app/feature/main => core/designsystem/src/main/kotlin/com/titi/app/core/designsystem}/navigation/TopLevelDestination.kt (93%) create mode 100644 feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiApp.kt delete mode 100644 feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt delete mode 100644 feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TdsBottomNavigationBar.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TdsBottomNavigationBar.kt new file mode 100644 index 00000000..dbedcf05 --- /dev/null +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TdsBottomNavigationBar.kt @@ -0,0 +1,78 @@ +package com.titi.app.core.designsystem.navigation + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.WindowInsetsSides +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.only +import androidx.compose.foundation.layout.systemBarsIgnoringVisibility +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.foundation.selection.selectableGroup +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.titi.app.core.designsystem.component.TdsText +import com.titi.app.core.designsystem.theme.TdsColor +import com.titi.app.core.designsystem.theme.TdsTextStyle + +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun TdsBottomNavigationBar( + currentTopLevelDestination: TopLevelDestination, + bottomNavigationColor: Long, + onNavigateToDestination: (TopLevelDestination) -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .windowInsetsPadding( + WindowInsets.systemBarsIgnoringVisibility.only( + WindowInsetsSides.Bottom + WindowInsetsSides.Horizontal, + ), + ) + .selectableGroup() + .background(Color(bottomNavigationColor)), + horizontalArrangement = Arrangement.spacedBy(8.dp), + ) { + TopLevelDestination.entries.forEach { destination -> + val selected = currentTopLevelDestination == destination + TdsBottomNavigationBarItem( + selected = selected, + onClick = { onNavigateToDestination(destination) }, + icon = { + Icon( + painter = painterResource(id = destination.iconResourceId), + contentDescription = stringResource(id = destination.titleTextId), + tint = if (selected) { + TdsColor.TEXT.getColor() + } else { + TdsColor.LIGHT_GRAY.getColor() + }, + ) + }, + label = { + TdsText( + text = stringResource(id = destination.titleTextId), + textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, + fontSize = 16.sp, + color = if (selected) { + TdsColor.TEXT.getColor() + } else { + TdsColor.LIGHT_GRAY.getColor() + }, + ) + }, + ) + } + } +} diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsNavigationBarItem.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TdsBottomNavigationBarItem.kt similarity index 93% rename from core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsNavigationBarItem.kt rename to core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TdsBottomNavigationBarItem.kt index 95e2adcb..2a5f7a06 100644 --- a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsNavigationBarItem.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TdsBottomNavigationBarItem.kt @@ -1,4 +1,4 @@ -package com.titi.app.core.designsystem.component +package com.titi.app.core.designsystem.navigation import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Column @@ -16,7 +16,7 @@ import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp @Composable -fun RowScope.TdsNavigationBarItem( +fun RowScope.TdsBottomNavigationBarItem( selected: Boolean, onClick: () -> Unit, icon: @Composable () -> Unit, diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TopLevelDestination.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TopLevelDestination.kt similarity index 93% rename from feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TopLevelDestination.kt rename to core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TopLevelDestination.kt index 436574a3..57618a8d 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TopLevelDestination.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/navigation/TopLevelDestination.kt @@ -1,4 +1,4 @@ -package com.titi.app.feature.main.navigation +package com.titi.app.core.designsystem.navigation import androidx.annotation.DrawableRes import androidx.annotation.StringRes diff --git a/feature/log/src/main/kotlin/com/titi/app/feature/log/navigation/LogNavigation.kt b/feature/log/src/main/kotlin/com/titi/app/feature/log/navigation/LogNavigation.kt index a5abeaaa..e70d2fb0 100644 --- a/feature/log/src/main/kotlin/com/titi/app/feature/log/navigation/LogNavigation.kt +++ b/feature/log/src/main/kotlin/com/titi/app/feature/log/navigation/LogNavigation.kt @@ -4,6 +4,7 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.feature.log.ui.LogScreen private const val LOG_SCREEN = "log" @@ -13,8 +14,8 @@ fun NavController.navigateToLog(navOptions: NavOptions) { navigate(LOG_ROUTE, navOptions) } -fun NavGraphBuilder.logGraph() { +fun NavGraphBuilder.logGraph(onNavigateToDestination: (TopLevelDestination) -> Unit) { composable(route = LOG_ROUTE) { - LogScreen() + LogScreen(onNavigateToDestination = onNavigateToDestination) } } diff --git a/feature/log/src/main/kotlin/com/titi/app/feature/log/ui/LogScreen.kt b/feature/log/src/main/kotlin/com/titi/app/feature/log/ui/LogScreen.kt index 057402dc..d00df635 100644 --- a/feature/log/src/main/kotlin/com/titi/app/feature/log/ui/LogScreen.kt +++ b/feature/log/src/main/kotlin/com/titi/app/feature/log/ui/LogScreen.kt @@ -2,6 +2,7 @@ package com.titi.app.feature.log.ui import android.content.res.Configuration import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -13,6 +14,7 @@ import androidx.compose.foundation.layout.width import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.material3.Icon +import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.derivedStateOf @@ -23,6 +25,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview @@ -32,6 +35,8 @@ import com.airbnb.mvrx.compose.mavericksViewModel import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsIconButton import com.titi.app.core.designsystem.component.TdsTabRow +import com.titi.app.core.designsystem.navigation.TdsBottomNavigationBar +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TiTiTheme import com.titi.app.feature.log.ui.component.SettingBottomSheet @@ -40,7 +45,10 @@ import kotlinx.coroutines.launch @OptIn(ExperimentalFoundationApi::class) @Composable -fun LogScreen(viewModel: LogViewModel = mavericksViewModel()) { +fun LogScreen( + viewModel: LogViewModel = mavericksViewModel(), + onNavigateToDestination: (TopLevelDestination) -> Unit, +) { val scope = rememberCoroutineScope() val orientation = LocalConfiguration.current.orientation @@ -86,116 +94,134 @@ fun LogScreen(viewModel: LogViewModel = mavericksViewModel()) { } } - Column( - modifier = Modifier - .fillMaxSize() - .padding(vertical = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, + val containerColor = if (isSystemInDarkTheme()) { + 0xFF000000 + } else { + 0xFFFFFFFF + } + + Scaffold( + containerColor = Color(containerColor), + bottomBar = { + TdsBottomNavigationBar( + currentTopLevelDestination = TopLevelDestination.LOG, + bottomNavigationColor = containerColor, + onNavigateToDestination = onNavigateToDestination, + ) + }, ) { - Box( + Column( modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), + .fillMaxSize() + .padding(it) + .padding(vertical = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, ) { - TdsTabRow( + Box( modifier = Modifier - .width(174.dp) - .height(32.dp) - .align(Alignment.Center), - selectedItemIndex = uiState.tabSelectedIndex, - items = listOf("Home", "Daily", "Week"), - onClick = { - viewModel.updateTabSelectedIndex(it) - }, - ) - - if (showSettingButton && orientation == Configuration.ORIENTATION_PORTRAIT) { - TdsIconButton( - modifier = Modifier.align(Alignment.CenterEnd), + .fillMaxWidth() + .padding(horizontal = 16.dp), + ) { + TdsTabRow( + modifier = Modifier + .width(174.dp) + .height(32.dp) + .align(Alignment.Center), + selectedItemIndex = uiState.tabSelectedIndex, + items = listOf("Home", "Daily", "Week"), onClick = { - showSettingBottomSheet = true + viewModel.updateTabSelectedIndex(it) }, - ) { - Icon( - painter = painterResource(id = R.drawable.setting_icon), - contentDescription = "setting", - tint = TdsColor.TEXT.getColor(), - ) + ) + + if (showSettingButton && orientation == Configuration.ORIENTATION_PORTRAIT) { + TdsIconButton( + modifier = Modifier.align(Alignment.CenterEnd), + onClick = { + showSettingBottomSheet = true + }, + ) { + Icon( + painter = painterResource(id = R.drawable.setting_icon), + contentDescription = "setting", + tint = TdsColor.TEXT.getColor(), + ) + } } } - } - Spacer(modifier = Modifier.height(16.dp)) - - HorizontalPager( - modifier = Modifier.fillMaxSize(), - state = pagerState, - userScrollEnabled = false, - ) { page -> - when (page % 3) { - 0 -> HomeScreen( - tdsColors = uiState.graphColorUiState.graphColors, - totalData = uiState.homeUiState.totalData, - graphGoalTimeUiState = uiState.graphGoalTimeUiState, - homeMonthGraphData = uiState.homeUiState.homeGraphData.homeMonthGraphData, - homeWeekGraphData = uiState.homeUiState.homeGraphData.homeWeekGraphData, - homeDailyGraphData = uiState.homeUiState.homeGraphData.homeDailyGraphData, - ) + Spacer(modifier = Modifier.height(16.dp)) + + HorizontalPager( + modifier = Modifier.fillMaxSize(), + state = pagerState, + userScrollEnabled = false, + ) { page -> + when (page % 3) { + 0 -> HomeScreen( + tdsColors = uiState.graphColorUiState.graphColors, + totalData = uiState.homeUiState.totalData, + graphGoalTimeUiState = uiState.graphGoalTimeUiState, + homeMonthGraphData = uiState.homeUiState.homeGraphData.homeMonthGraphData, + homeWeekGraphData = uiState.homeUiState.homeGraphData.homeWeekGraphData, + homeDailyGraphData = uiState.homeUiState.homeGraphData.homeDailyGraphData, + ) - 1 -> DailyScreen( - currentDate = uiState.dailyUiState.currentDate, - hasDailies = uiState.dailyUiState.hasDailies, - totalTime = uiState.dailyUiState.dailyGraphData.totalTime, - maxTime = uiState.dailyUiState.dailyGraphData.maxTime, - taskData = uiState.dailyUiState.dailyGraphData.taskData, - tdsColors = uiState.graphColorUiState.graphColors, - timeLines = uiState.dailyUiState.dailyGraphData.timeLine, - timeTableData = uiState.dailyUiState.dailyGraphData.tdsTimeTableData, - checkedButtonStates = uiState.dailyUiState.checkedButtonStates, - onClickDate = { - viewModel.updateCurrentDateDaily(it) - }, - onClickGraphColor = { - viewModel.updateGraphColors( - selectedIndex = it, - graphColorUiState = uiState.graphColorUiState, - ) - }, - onCalendarLocalDateChanged = { - viewModel.updateHasDailyAtDailyTab(it) - }, - onCheckedChange = { graph, checked -> - viewModel.updateCheckedState( - page = graph, - checked = checked, - checkedButtonStates = uiState.dailyUiState.checkedButtonStates, - ) - }, - ) + 1 -> DailyScreen( + currentDate = uiState.dailyUiState.currentDate, + hasDailies = uiState.dailyUiState.hasDailies, + totalTime = uiState.dailyUiState.dailyGraphData.totalTime, + maxTime = uiState.dailyUiState.dailyGraphData.maxTime, + taskData = uiState.dailyUiState.dailyGraphData.taskData, + tdsColors = uiState.graphColorUiState.graphColors, + timeLines = uiState.dailyUiState.dailyGraphData.timeLine, + timeTableData = uiState.dailyUiState.dailyGraphData.tdsTimeTableData, + checkedButtonStates = uiState.dailyUiState.checkedButtonStates, + onClickDate = { + viewModel.updateCurrentDateDaily(it) + }, + onClickGraphColor = { + viewModel.updateGraphColors( + selectedIndex = it, + graphColorUiState = uiState.graphColorUiState, + ) + }, + onCalendarLocalDateChanged = { + viewModel.updateHasDailyAtDailyTab(it) + }, + onCheckedChange = { graph, checked -> + viewModel.updateCheckedState( + page = graph, + checked = checked, + checkedButtonStates = uiState.dailyUiState.checkedButtonStates, + ) + }, + ) - 2 -> WeekScreen( - weekInformation = uiState.weekUiState.weekGraphData.weekInformation, - hasDailies = uiState.weekUiState.hasDailies, - totalTime = uiState.weekUiState.weekGraphData.totalWeekTime, - averageTime = uiState.weekUiState.weekGraphData.averageWeekTime, - weekLineChartData = uiState.weekUiState.weekGraphData.weekLineChartData, - tdsColors = uiState.graphColorUiState.graphColors, - topLevelTaskTotal = uiState.weekUiState.weekGraphData.topLevelTaskTotal, - topLevelTaskData = uiState.weekUiState.weekGraphData.topLevelTdsTaskData, - currentDate = uiState.weekUiState.currentDate, - onClickDate = { - viewModel.updateCurrentDateWeek(it) - }, - onClickGraphColor = { - viewModel.updateGraphColors( - selectedIndex = it, - graphColorUiState = uiState.graphColorUiState, - ) - }, - onCalendarLocalDateChanged = { - viewModel.updateHasDailyAtWeekTab(it) - }, - ) + 2 -> WeekScreen( + weekInformation = uiState.weekUiState.weekGraphData.weekInformation, + hasDailies = uiState.weekUiState.hasDailies, + totalTime = uiState.weekUiState.weekGraphData.totalWeekTime, + averageTime = uiState.weekUiState.weekGraphData.averageWeekTime, + weekLineChartData = uiState.weekUiState.weekGraphData.weekLineChartData, + tdsColors = uiState.graphColorUiState.graphColors, + topLevelTaskTotal = uiState.weekUiState.weekGraphData.topLevelTaskTotal, + topLevelTaskData = uiState.weekUiState.weekGraphData.topLevelTdsTaskData, + currentDate = uiState.weekUiState.currentDate, + onClickDate = { + viewModel.updateCurrentDateWeek(it) + }, + onClickGraphColor = { + viewModel.updateGraphColors( + selectedIndex = it, + graphColorUiState = uiState.graphColorUiState, + ) + }, + onCalendarLocalDateChanged = { + viewModel.updateHasDailyAtWeekTab(it) + }, + ) + } } } } @@ -205,6 +231,6 @@ fun LogScreen(viewModel: LogViewModel = mavericksViewModel()) { @Composable private fun LogScreenPreview() { TiTiTheme { - LogScreen() + LogScreen(onNavigateToDestination = {}) } } diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiApp.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiApp.kt new file mode 100644 index 00000000..4cb4b77f --- /dev/null +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiApp.kt @@ -0,0 +1,39 @@ +package com.titi.app.feature.main.navigation + +import android.Manifest +import android.annotation.SuppressLint +import android.os.Build +import android.util.Log +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Modifier +import com.titi.app.feature.main.model.SplashResultState + +@SuppressLint("UnusedContentLambdaTargetStateParameter") +@Composable +fun TiTiApp(splashResultState: SplashResultState) { + val requestPermissionLauncher = + rememberLauncherForActivityResult( + ActivityResultContracts.RequestPermission(), + ) { isGranted: Boolean -> + Log.e("MainActivity", isGranted.toString()) + } + + fun askNotificationPermission() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) + } + } + + LaunchedEffect(Unit) { + askNotificationPermission() + } + + TiTiNavHost( + modifier = Modifier.fillMaxSize(), + splashResultState = splashResultState, + ) +} diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt index 9ddc1d28..86bc50b3 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt @@ -6,33 +6,37 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.core.net.toUri +import androidx.navigation.NavController +import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.compose.NavHost +import androidx.navigation.compose.rememberNavController +import androidx.navigation.navOptions +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.core.util.toJson import com.titi.app.feature.log.navigation.logGraph +import com.titi.app.feature.log.navigation.navigateToLog import com.titi.app.feature.main.model.SplashResultState import com.titi.app.feature.main.model.toFeatureTimeModel -import com.titi.app.feature.main.ui.TiTiAppState import com.titi.app.feature.measure.navigation.measureGraph import com.titi.app.feature.measure.navigation.navigateToMeasure import com.titi.app.feature.popup.PopUpActivity import com.titi.app.feature.popup.PopUpActivity.Companion.COLOR_RECORDING_MODE_KEY import com.titi.app.feature.setting.navigation.navigateToFeatures +import com.titi.app.feature.setting.navigation.navigateToSetting import com.titi.app.feature.setting.navigation.navigateToUpdates import com.titi.app.feature.setting.navigation.settingGraph import com.titi.app.feature.time.navigation.STOPWATCH_SCREEN import com.titi.app.feature.time.navigation.TIMER_FINISH_KEY import com.titi.app.feature.time.navigation.TIMER_SCREEN +import com.titi.app.feature.time.navigation.navigateToStopWatch +import com.titi.app.feature.time.navigation.navigateToTimer import com.titi.app.feature.time.navigation.timeGraph import com.titi.app.feature.webview.navigateToWebView import com.titi.app.feature.webview.webViewGraph @Composable -fun TiTiNavHost( - splashResultState: SplashResultState, - appState: TiTiAppState, - modifier: Modifier = Modifier, -) { - val navController = appState.navController +fun TiTiNavHost(splashResultState: SplashResultState, modifier: Modifier = Modifier) { + val navController = rememberNavController() val context = LocalContext.current LaunchedEffect(Unit) { @@ -64,6 +68,9 @@ fun TiTiNavHost( onNavigateToMeasure = { navController.navigateToMeasure(it) }, + onNavigateToDestination = { + navController.navigateToTopLevelDestination(it) + }, ) measureGraph( @@ -75,7 +82,11 @@ fun TiTiNavHost( }, ) - logGraph() + logGraph( + onNavigateToDestination = { + navController.navigateToTopLevelDestination(it) + }, + ) settingGraph( onNavigateToFeatures = { navController.navigateToFeatures() }, @@ -95,8 +106,30 @@ fun TiTiNavHost( url = url, ) }, + onNavigateToDestination = { + navController.navigateToTopLevelDestination(it) + }, ) webViewGraph(onNavigateUp = { navController.navigateUp() }) } } + +fun NavController.navigateToTopLevelDestination(topLevelDestination: TopLevelDestination) { + val topLevelNavOptions = + navOptions { + popUpTo(graph.findStartDestination().id) { + saveState = true + } + + launchSingleTop = true + restoreState = true + } + + when (topLevelDestination) { + TopLevelDestination.TIMER -> navigateToTimer(topLevelNavOptions) + TopLevelDestination.STOPWATCH -> navigateToStopWatch(topLevelNavOptions) + TopLevelDestination.LOG -> navigateToLog(topLevelNavOptions) + TopLevelDestination.SETTING -> navigateToSetting(topLevelNavOptions) + } +} diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt deleted file mode 100644 index 0e2f5fd0..00000000 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiApp.kt +++ /dev/null @@ -1,159 +0,0 @@ -package com.titi.app.feature.main.ui - -import android.Manifest -import android.annotation.SuppressLint -import android.os.Build -import android.util.Log -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.ExperimentalLayoutApi -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.foundation.layout.WindowInsetsSides -import androidx.compose.foundation.layout.consumeWindowInsets -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.navigationBarsPadding -import androidx.compose.foundation.layout.only -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.statusBarsPadding -import androidx.compose.foundation.layout.systemBarsIgnoringVisibility -import androidx.compose.foundation.layout.windowInsetsPadding -import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.selection.selectableGroup -import androidx.compose.material3.Icon -import androidx.compose.material3.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.navigation.NavDestination -import androidx.navigation.NavDestination.Companion.hierarchy -import com.titi.app.core.designsystem.component.TdsNavigationBarItem -import com.titi.app.core.designsystem.component.TdsText -import com.titi.app.core.designsystem.theme.TdsColor -import com.titi.app.core.designsystem.theme.TdsTextStyle -import com.titi.app.feature.main.model.SplashResultState -import com.titi.app.feature.main.navigation.TiTiNavHost -import com.titi.app.feature.main.navigation.TopLevelDestination - -@SuppressLint("UnusedContentLambdaTargetStateParameter") -@Composable -fun TiTiApp(splashResultState: SplashResultState, appState: TiTiAppState) { - val requestPermissionLauncher = - rememberLauncherForActivityResult( - ActivityResultContracts.RequestPermission(), - ) { isGranted: Boolean -> - Log.e("MainActivity", isGranted.toString()) - } - - fun askNotificationPermission() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - requestPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) - } - } - - LaunchedEffect(Unit) { - askNotificationPermission() - } - - val bottomNavigationColor by appState.bottomNavigationColor.collectAsStateWithLifecycle() - - Scaffold( - contentWindowInsets = WindowInsets(0, 0, 0, 0), - containerColor = Color(bottomNavigationColor), - bottomBar = { - if (appState.shouldShowBottomBar) { - TiTiBottomBar( - bottomNavigationColor = bottomNavigationColor, - destinations = appState.topLevelDestinations, - onNavigateToDestination = appState::navigateToTopLevelDestination, - currentDestination = appState.currentDestination, - ) - } - }, - ) { padding -> - Column( - modifier = Modifier - .fillMaxSize() - .padding(padding) - .consumeWindowInsets(padding) - .navigationBarsPadding() - .statusBarsPadding(), - ) { - TiTiNavHost( - modifier = Modifier.fillMaxSize(), - appState = appState, - splashResultState = splashResultState, - ) - } - } -} - -@OptIn(ExperimentalLayoutApi::class) -@Composable -private fun TiTiBottomBar( - bottomNavigationColor: Long, - destinations: List, - onNavigateToDestination: (TopLevelDestination) -> Unit, - currentDestination: NavDestination?, -) { - Row( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .windowInsetsPadding( - WindowInsets.systemBarsIgnoringVisibility.only( - WindowInsetsSides.Bottom + WindowInsetsSides.Horizontal, - ), - ) - .selectableGroup() - .background(Color(bottomNavigationColor)), - horizontalArrangement = Arrangement.spacedBy(8.dp), - ) { - destinations.forEach { destination -> - val selected = currentDestination.isTopLevelDestinationInHierarchy(destination) - TdsNavigationBarItem( - selected = selected, - onClick = { onNavigateToDestination(destination) }, - icon = { - Icon( - painter = painterResource(id = destination.iconResourceId), - contentDescription = stringResource(id = destination.titleTextId), - tint = if (selected) { - TdsColor.TEXT.getColor() - } else { - TdsColor.LIGHT_GRAY.getColor() - }, - ) - }, - label = { - TdsText( - text = stringResource(id = destination.titleTextId), - textStyle = TdsTextStyle.SEMI_BOLD_TEXT_STYLE, - fontSize = 16.sp, - color = if (selected) { - TdsColor.TEXT.getColor() - } else { - TdsColor.LIGHT_GRAY.getColor() - }, - ) - }, - ) - } - } -} - -private fun NavDestination?.isTopLevelDestinationInHierarchy(destination: TopLevelDestination) = - this?.hierarchy?.any { - it.route?.contains(destination.name, true) ?: false - } ?: false diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt deleted file mode 100644 index a581d5ac..00000000 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/TiTiAppState.kt +++ /dev/null @@ -1,124 +0,0 @@ -package com.titi.app.feature.main.ui - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.Stable -import androidx.compose.runtime.remember -import androidx.compose.runtime.rememberCoroutineScope -import androidx.navigation.NavDestination -import androidx.navigation.NavGraph.Companion.findStartDestination -import androidx.navigation.NavHostController -import androidx.navigation.compose.currentBackStackEntryAsState -import androidx.navigation.compose.rememberNavController -import androidx.navigation.navOptions -import com.titi.app.domain.color.model.TimeColor -import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase -import com.titi.app.feature.log.navigation.LOG_ROUTE -import com.titi.app.feature.log.navigation.navigateToLog -import com.titi.app.feature.main.navigation.TopLevelDestination -import com.titi.app.feature.measure.navigation.MEASURE_ROUTE -import com.titi.app.feature.setting.navigation.FEATURES_ROUTE -import com.titi.app.feature.setting.navigation.SETTING_ROUTE -import com.titi.app.feature.setting.navigation.UPDATES_ROUTE -import com.titi.app.feature.setting.navigation.navigateToSetting -import com.titi.app.feature.time.navigation.STOPWATCH_ROUTE -import com.titi.app.feature.time.navigation.TIMER_ROUTE -import com.titi.app.feature.time.navigation.navigateToStopWatch -import com.titi.app.feature.time.navigation.navigateToTimer -import com.titi.app.feature.webview.WEBVIEW_ROUTE -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.combine -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.stateIn - -@Composable -fun rememberNiaAppState( - navController: NavHostController = rememberNavController(), - coroutineScope: CoroutineScope = rememberCoroutineScope(), - isSystemDarkTheme: Boolean, - getTimeColorFlowUseCase: GetTimeColorFlowUseCase, -): TiTiAppState { - return remember(navController) { - TiTiAppState( - navController, - isSystemDarkTheme, - coroutineScope, - getTimeColorFlowUseCase, - ) - } -} - -@Stable -class TiTiAppState( - val navController: NavHostController, - isSystemDarkTheme: Boolean, - coroutineScope: CoroutineScope, - getTimeColorFlowUseCase: GetTimeColorFlowUseCase, -) { - val currentDestination: NavDestination? - @Composable get() = - navController - .currentBackStackEntryAsState().value?.destination - - private val currentDestinationRouteFlow = - navController.currentBackStackEntryFlow.map { it.destination.route } - - private val currentTopLevelDestination: TopLevelDestination? - @Composable get() = - when (currentDestination?.route) { - TIMER_ROUTE -> TopLevelDestination.TIMER - STOPWATCH_ROUTE -> TopLevelDestination.STOPWATCH - LOG_ROUTE -> TopLevelDestination.LOG - SETTING_ROUTE -> TopLevelDestination.SETTING - else -> null - } - - val topLevelDestinations: List = TopLevelDestination.entries - - private val isTopLevelDestination: Boolean - @Composable get() = currentTopLevelDestination != null - - val shouldShowBottomBar: Boolean - @Composable get() = isTopLevelDestination - - val bottomNavigationColor: StateFlow = - getTimeColorFlowUseCase() - .combine(currentDestinationRouteFlow) { timeColor: TimeColor, route: String? -> - when (route) { - TIMER_ROUTE -> timeColor.timerBackgroundColor - STOPWATCH_ROUTE -> timeColor.stopwatchBackgroundColor - SETTING_ROUTE, - FEATURES_ROUTE, - UPDATES_ROUTE, - WEBVIEW_ROUTE, - -> if (isSystemDarkTheme) 0xFF000000 else 0xFFF2F2F7 - MEASURE_ROUTE -> 0xFF000000 - else -> if (isSystemDarkTheme) 0xFF000000 else 0xFFFFFFFF - } - } - .stateIn( - scope = coroutineScope, - SharingStarted.WhileSubscribed(), - initialValue = 0xFF000000, - ) - - fun navigateToTopLevelDestination(topLevelDestination: TopLevelDestination) { - val topLevelNavOptions = - navOptions { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true - } - - launchSingleTop = true - restoreState = true - } - - when (topLevelDestination) { - TopLevelDestination.TIMER -> navController.navigateToTimer(topLevelNavOptions) - TopLevelDestination.STOPWATCH -> navController.navigateToStopWatch(topLevelNavOptions) - TopLevelDestination.LOG -> navController.navigateToLog(topLevelNavOptions) - TopLevelDestination.SETTING -> navController.navigateToSetting(topLevelNavOptions) - } - } -} diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt index d33ab66f..b753b160 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/ui/main/MainActivity.kt @@ -6,7 +6,6 @@ import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels -import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -17,8 +16,7 @@ import androidx.lifecycle.repeatOnLifecycle import com.titi.app.core.designsystem.theme.TiTiTheme import com.titi.app.domain.color.usecase.GetTimeColorFlowUseCase import com.titi.app.feature.main.model.SplashResultState -import com.titi.app.feature.main.ui.TiTiApp -import com.titi.app.feature.main.ui.rememberNiaAppState +import com.titi.app.feature.main.navigation.TiTiApp import dagger.hilt.android.AndroidEntryPoint import javax.inject.Inject import kotlinx.coroutines.flow.filterNotNull @@ -60,17 +58,9 @@ class MainActivity : ComponentActivity() { ) setContent { - val appState = rememberNiaAppState( - getTimeColorFlowUseCase = getTimeColorFlowUseCase, - isSystemDarkTheme = isSystemInDarkTheme(), - ) - TiTiTheme { splashResultState?.let { - TiTiApp( - splashResultState = it, - appState = appState, - ) + TiTiApp(splashResultState = it) } } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt index dc0f0d73..cee22fd4 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/navigation/SettingNavigation.kt @@ -4,6 +4,7 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.feature.setting.model.SettingActions import com.titi.app.feature.setting.ui.FeaturesListScreen import com.titi.app.feature.setting.ui.SettingScreen @@ -36,6 +37,7 @@ fun NavGraphBuilder.settingGraph( onNavigateToPlayStore: () -> Unit, onNavigateUp: () -> Unit, onNavigateToWebView: (title: String, url: String) -> Unit, + onNavigateToDestination: (TopLevelDestination) -> Unit, ) { composable(route = SETTING_ROUTE) { SettingScreen( @@ -46,6 +48,7 @@ fun NavGraphBuilder.settingGraph( SettingActions.Navigates.UpdatesList -> onNavigateToUpdates() } }, + onNavigateToDestination = onNavigateToDestination, ) } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt index 4bd8639e..c4337680 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt @@ -1,5 +1,6 @@ package com.titi.app.feature.setting.ui +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize @@ -38,8 +39,14 @@ fun FeaturesListScreen( ) { val uiState by viewModel.collectAsState() + val containerColor = if (isSystemInDarkTheme()) { + 0xFF000000 + } else { + 0xFFF2F2F7 + } + Scaffold( - containerColor = Color.Transparent, + containerColor = Color(containerColor), topBar = { TopAppBar( colors = TopAppBarDefaults.topAppBarColors( diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index 5d7435b9..2a9ed4aa 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -3,6 +3,7 @@ package com.titi.app.feature.setting.ui import android.util.Log import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -39,6 +40,8 @@ import com.google.firebase.database.ValueEventListener import com.google.firebase.database.getValue import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsText +import com.titi.app.core.designsystem.navigation.TdsBottomNavigationBar +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.core.designsystem.theme.TdsColor import com.titi.app.core.designsystem.theme.TdsTextStyle import com.titi.app.core.designsystem.theme.TiTiTheme @@ -51,6 +54,7 @@ import com.titi.app.feature.setting.model.Version fun SettingScreen( viewModel: SettingViewModel = mavericksViewModel(), handleNavigateActions: (SettingActions.Navigates) -> Unit, + onNavigateToDestination: (TopLevelDestination) -> Unit, ) { val uiState by viewModel.collectAsState() @@ -93,8 +97,14 @@ fun SettingScreen( ) } + val containerColor = if (isSystemInDarkTheme()) { + 0xFF000000 + } else { + 0xFFF2F2F7 + } + Scaffold( - containerColor = Color.Transparent, + containerColor = Color(containerColor), topBar = { TopAppBar( colors = TopAppBarDefaults.topAppBarColors( @@ -110,6 +120,13 @@ fun SettingScreen( }, ) }, + bottomBar = { + TdsBottomNavigationBar( + currentTopLevelDestination = TopLevelDestination.SETTING, + bottomNavigationColor = containerColor, + onNavigateToDestination = onNavigateToDestination, + ) + }, ) { SettingScreen( modifier = Modifier.padding(it), diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt index 6ee051f5..2cb2b6df 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt @@ -2,6 +2,7 @@ package com.titi.app.feature.setting.ui import android.util.Log import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row @@ -65,8 +66,14 @@ fun UpdatesListScreen(onNavigateUp: () -> Unit) { ) } + val containerColor = if (isSystemInDarkTheme()) { + 0xFF000000 + } else { + 0xFFF2F2F7 + } + Scaffold( - containerColor = Color.Transparent, + containerColor = Color(containerColor), topBar = { TopAppBar( colors = TopAppBarDefaults.topAppBarColors( diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/navigation/TimeNavigation.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/navigation/TimeNavigation.kt index 9399a0c8..04b6bcce 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/navigation/TimeNavigation.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/navigation/TimeNavigation.kt @@ -6,6 +6,7 @@ import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.feature.time.model.SplashResultState import com.titi.app.feature.time.ui.stopwatch.StopWatchScreen import com.titi.app.feature.time.ui.timer.TimerScreen @@ -29,6 +30,7 @@ fun NavGraphBuilder.timeGraph( splashResultState: SplashResultState, onNavigateToColor: (Int) -> Unit, onNavigateToMeasure: (String) -> Unit, + onNavigateToDestination: (TopLevelDestination) -> Unit, ) { composable(route = TIMER_ROUTE) { backStackEntry -> val isFinish by backStackEntry @@ -44,6 +46,7 @@ fun NavGraphBuilder.timeGraph( }, onNavigateToColor = { onNavigateToColor(1) }, onNavigateToMeasure = onNavigateToMeasure, + onNavigateToDestination = onNavigateToDestination, ) } @@ -52,6 +55,7 @@ fun NavGraphBuilder.timeGraph( splashResultState = splashResultState, onNavigateToColor = { onNavigateToColor(2) }, onNavigateToMeasure = onNavigateToMeasure, + onNavigateToDestination = onNavigateToDestination, ) } } diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt index 6c6daed7..8ff8250c 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -26,6 +27,8 @@ import com.airbnb.mvrx.compose.mavericksViewModel import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime +import com.titi.app.core.designsystem.navigation.TdsBottomNavigationBar +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.core.util.toJson import com.titi.app.feature.time.content.TimeButtonContent import com.titi.app.feature.time.content.TimeCheckDailyDialog @@ -44,6 +47,7 @@ fun StopWatchScreen( splashResultState: SplashResultState, onNavigateToColor: () -> Unit, onNavigateToMeasure: (String) -> Unit, + onNavigateToDestination: (TopLevelDestination) -> Unit, ) { val viewModel: StopWatchViewModel = mavericksViewModel( argsFactory = { @@ -166,6 +170,7 @@ fun StopWatchScreen( onClickResetStopWatch = { viewModel.updateSavedStopWatchTime(uiState.recordTimes) }, + onNavigateToDestination = onNavigateToDestination, ) } @@ -178,70 +183,84 @@ private fun StopWatchScreen( onClickAddDaily: () -> Unit, onClickStartRecord: () -> Unit, onClickResetStopWatch: () -> Unit, + onNavigateToDestination: (TopLevelDestination) -> Unit, ) { val configuration = LocalConfiguration.current when (configuration.orientation) { Configuration.ORIENTATION_PORTRAIT -> { - Column( - modifier = Modifier - .fillMaxSize() - .padding(top = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, + Scaffold( + containerColor = Color(uiState.timeColor.stopwatchBackgroundColor), + bottomBar = { + TdsBottomNavigationBar( + currentTopLevelDestination = TopLevelDestination.STOPWATCH, + bottomNavigationColor = uiState.timeColor.stopwatchBackgroundColor, + onNavigateToDestination = onNavigateToDestination, + ) + }, ) { - TimeHeaderContent( - todayDate = uiState.todayDate, - isDailyAfter6AM = uiState.isDailyAfter6AM, - textColor = textColor, - onClickColor = onClickColor, - ) + Column( + modifier = Modifier + .fillMaxSize() + .padding(it) + .padding(top = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + TimeHeaderContent( + todayDate = uiState.todayDate, + isDailyAfter6AM = uiState.isDailyAfter6AM, + textColor = textColor, + onClickColor = onClickColor, + ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) - TimeTaskContent( - isSetTask = uiState.isSetTask, - textColor = textColor, - taskName = uiState.taskName, - onClickTask = onClickTask, - ) + TimeTaskContent( + isSetTask = uiState.isSetTask, + textColor = textColor, + taskName = uiState.taskName, + onClickTask = onClickTask, + ) - Spacer(modifier = Modifier.height(50.dp)) + Spacer(modifier = Modifier.height(50.dp)) - with(uiState.stopWatchRecordTimes) { - TdsTimer( - outCircularLineColor = textColor, - outCircularProgress = outCircularProgress, - inCircularLineTrackColor = if (uiState.stopWatchColor.isTextColorBlack) { - Color.White - } else { - Color(0x8C000000) - }, - inCircularProgress = inCircularProgress, - fontColor = textColor, - recordingMode = 2, - savedSumTime = savedSumTime, - savedTime = savedTime, - savedGoalTime = savedGoalTime, - finishGoalTime = finishGoalTime, - isTaskTargetTimeOn = isTaskTargetTimeOn, - onClickStopStart = { - onClickStartRecord() - }, - ) - } + with(uiState.stopWatchRecordTimes) { + TdsTimer( + outCircularLineColor = textColor, + outCircularProgress = outCircularProgress, + inCircularLineTrackColor = + if (uiState.stopWatchColor.isTextColorBlack) { + Color.White + } else { + Color(0x8C000000) + }, + inCircularProgress = inCircularProgress, + fontColor = textColor, + recordingMode = 2, + savedSumTime = savedSumTime, + savedTime = savedTime, + savedGoalTime = savedGoalTime, + finishGoalTime = finishGoalTime, + isTaskTargetTimeOn = isTaskTargetTimeOn, + onClickStopStart = { + onClickStartRecord() + }, + ) + } - Spacer(modifier = Modifier.height(50.dp)) + Spacer(modifier = Modifier.height(50.dp)) - TimeButtonContent( - recordingMode = 2, - isDailyAfter6AM = uiState.isDailyAfter6AM, - tintColor = textColor, - onClickAddDaily = onClickAddDaily, - onClickStartRecord = onClickStartRecord, - onClickResetStopwatch = onClickResetStopWatch, - ) + TimeButtonContent( + recordingMode = 2, + isDailyAfter6AM = uiState.isDailyAfter6AM, + tintColor = textColor, + onClickAddDaily = onClickAddDaily, + onClickStartRecord = onClickStartRecord, + onClickResetStopwatch = onClickResetStopWatch, + ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) + } } } diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt index 2a6361bc..2e90f23c 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawingPadding +import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -27,6 +28,8 @@ import com.airbnb.mvrx.compose.mavericksViewModel import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime +import com.titi.app.core.designsystem.navigation.TdsBottomNavigationBar +import com.titi.app.core.designsystem.navigation.TopLevelDestination import com.titi.app.core.util.toJson import com.titi.app.feature.time.content.TimeButtonContent import com.titi.app.feature.time.content.TimeCheckDailyDialog @@ -48,6 +51,7 @@ fun TimerScreen( onChangeFinishStateFalse: () -> Unit, onNavigateToColor: () -> Unit, onNavigateToMeasure: (String) -> Unit, + onNavigateToDestination: (TopLevelDestination) -> Unit, ) { val viewModel: TimerViewModel = mavericksViewModel( argsFactory = { @@ -202,6 +206,7 @@ fun TimerScreen( onClickSettingTimer = { showUpdateTimerDialog = true }, + onNavigateToDestination = onNavigateToDestination, ) } @@ -215,72 +220,85 @@ private fun TimerScreen( onClickAddDaily: () -> Unit, onClickStartRecord: () -> Unit, onClickSettingTimer: () -> Unit, + onNavigateToDestination: (TopLevelDestination) -> Unit, ) { val configuration = LocalConfiguration.current when (configuration.orientation) { Configuration.ORIENTATION_PORTRAIT -> { - Column( - modifier = Modifier - .fillMaxSize() - .padding(top = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, + Scaffold( + containerColor = Color(uiState.timeColor.timerBackgroundColor), + bottomBar = { + TdsBottomNavigationBar( + currentTopLevelDestination = TopLevelDestination.TIMER, + bottomNavigationColor = uiState.timeColor.timerBackgroundColor, + onNavigateToDestination = onNavigateToDestination, + ) + }, ) { - TimeHeaderContent( - todayDate = uiState.todayDate, - isDailyAfter6AM = uiState.isDailyAfter6AM, - textColor = textColor, - onClickColor = onClickColor, - ) + Column( + modifier = Modifier + .fillMaxSize() + .padding(it) + .padding(top = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + TimeHeaderContent( + todayDate = uiState.todayDate, + isDailyAfter6AM = uiState.isDailyAfter6AM, + textColor = textColor, + onClickColor = onClickColor, + ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) - TimeTaskContent( - isSetTask = uiState.isSetTask, - textColor = textColor, - taskName = uiState.taskName, - onClickTask = onClickTask, - ) + TimeTaskContent( + isSetTask = uiState.isSetTask, + textColor = textColor, + taskName = uiState.taskName, + onClickTask = onClickTask, + ) - Spacer(modifier = Modifier.height(50.dp)) + Spacer(modifier = Modifier.height(50.dp)) - with(uiState.timerRecordTimes) { - TdsTimer( - isFinish = isFinish, - outCircularLineColor = textColor, - outCircularProgress = outCircularProgress, - inCircularLineTrackColor = if (uiState.timerColor.isTextColorBlack) { - Color.White - } else { - Color(0x8C000000) - }, - inCircularProgress = inCircularProgress, - fontColor = textColor, - recordingMode = 1, - savedSumTime = savedSumTime, - savedTime = savedTime, - savedGoalTime = savedGoalTime, - finishGoalTime = finishGoalTime, - isTaskTargetTimeOn = isTaskTargetTimeOn, - onClickStopStart = { - onClickStartRecord() - }, - ) - } + with(uiState.timerRecordTimes) { + TdsTimer( + isFinish = isFinish, + outCircularLineColor = textColor, + outCircularProgress = outCircularProgress, + inCircularLineTrackColor = if (uiState.timerColor.isTextColorBlack) { + Color.White + } else { + Color(0x8C000000) + }, + inCircularProgress = inCircularProgress, + fontColor = textColor, + recordingMode = 1, + savedSumTime = savedSumTime, + savedTime = savedTime, + savedGoalTime = savedGoalTime, + finishGoalTime = finishGoalTime, + isTaskTargetTimeOn = isTaskTargetTimeOn, + onClickStopStart = { + onClickStartRecord() + }, + ) + } - Spacer(modifier = Modifier.height(50.dp)) + Spacer(modifier = Modifier.height(50.dp)) - TimeButtonContent( - recordingMode = 1, - isDailyAfter6AM = uiState.isDailyAfter6AM, - tintColor = textColor, - onClickAddDaily = onClickAddDaily, - onClickStartRecord = onClickStartRecord, - onClickSettingTimer = onClickSettingTimer, - ) + TimeButtonContent( + recordingMode = 1, + isDailyAfter6AM = uiState.isDailyAfter6AM, + tintColor = textColor, + onClickAddDaily = onClickAddDaily, + onClickStartRecord = onClickStartRecord, + onClickSettingTimer = onClickSettingTimer, + ) - Spacer(modifier = Modifier.weight(1f)) + Spacer(modifier = Modifier.weight(1f)) + } } } From 5b9b08f40d00c2eccdcc62c96159c7dc16ae60b8 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 17:47:14 +0900 Subject: [PATCH 34/41] =?UTF-8?q?#123=20feat=20:=20=EA=B0=80=EB=A1=9C=20?= =?UTF-8?q?=EC=84=B8=EB=A1=9C=20=EB=8C=80=EC=9D=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/feature/measure/ui/MeasuringScreen.kt | 212 ++++++++++-------- .../feature/setting/ui/FeaturesListScreen.kt | 2 + .../app/feature/setting/ui/SettingScreen.kt | 5 +- .../feature/setting/ui/UpdatesListScreen.kt | 2 + .../time/ui/stopwatch/StopWatchScreen.kt | 86 +++---- .../app/feature/time/ui/timer/TimerScreen.kt | 87 +++---- .../titi/app/feature/webview/WebViewScreen.kt | 2 + 7 files changed, 216 insertions(+), 180 deletions(-) diff --git a/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt b/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt index f6d59375..55d84b35 100644 --- a/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt +++ b/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt @@ -14,10 +14,12 @@ import androidx.compose.foundation.layout.Box 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.safeDrawingPadding import androidx.compose.material3.Icon +import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.DisposableEffect import androidx.compose.runtime.LaunchedEffect @@ -204,112 +206,130 @@ private fun MeasuringScreen( ) { val configuration = LocalConfiguration.current - when (configuration.orientation) { - Configuration.ORIENTATION_PORTRAIT -> { - Column( + Scaffold( + containerColor = Color.Black, + bottomBar = { + Box( modifier = Modifier - .fillMaxSize() - .background(Color.Black) - .padding(top = 16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - TdsIconButton( - modifier = - Modifier - .padding(start = 16.dp) - .align(Alignment.Start), - size = 32.dp, - onClick = onSleepClick, + .fillMaxWidth() + .height(58.dp) + .background(Color.Transparent), + ) + }, + ) { + when (configuration.orientation) { + Configuration.ORIENTATION_PORTRAIT -> { + Column( + modifier = Modifier + .fillMaxSize() + .background(Color.Black) + .padding(it) + .padding(top = 16.dp), + horizontalAlignment = Alignment.CenterHorizontally, ) { - Icon( - painter = - if (uiState.isSleepMode) { - painterResource(id = R.drawable.sleep_icon) - } else { - painterResource(id = R.drawable.non_sleep_icon) - }, - contentDescription = "sleepIcon", - tint = Color.White, - ) - } + TdsIconButton( + modifier = + Modifier + .padding(start = 16.dp) + .align(Alignment.Start), + size = 32.dp, + onClick = onSleepClick, + ) { + Icon( + painter = + if (uiState.isSleepMode) { + painterResource(id = R.drawable.sleep_icon) + } else { + painterResource(id = R.drawable.non_sleep_icon) + }, + contentDescription = "sleepIcon", + tint = Color.White, + ) + } + + Spacer(modifier = Modifier.weight(1f)) - Spacer(modifier = Modifier.weight(1f)) - - TdsText( - modifier = Modifier.padding(vertical = 12.dp), - text = uiState.recordTimes.currentTask?.taskName, - textStyle = TdsTextStyle.NORMAL_TEXT_STYLE, - fontSize = 18.sp, - color = Color.White, - ) - - Spacer(modifier = Modifier.height(50.dp)) - - with(uiState.measuringRecordTimes) { - TdsTimer( - outCircularLineColor = Color(uiState.measuringTimeColor.backgroundColor), - outCircularProgress = outCircularProgress, - inCircularLineTrackColor = Color.White, - inCircularProgress = inCircularProgress, - fontColor = Color.White, - themeColor = Color(uiState.measuringTimeColor.backgroundColor), - recordingMode = uiState.recordTimes.recordingMode, - savedSumTime = savedSumTime, - savedTime = savedTime, - savedGoalTime = savedGoalTime, - finishGoalTime = finishGoalTime, - isTaskTargetTimeOn = isTaskTargetTimeOn, - onClickStopStart = { - onFinishClick() - }, + TdsText( + modifier = Modifier.padding(vertical = 12.dp), + text = uiState.recordTimes.currentTask?.taskName, + textStyle = TdsTextStyle.NORMAL_TEXT_STYLE, + fontSize = 18.sp, + color = Color.White, ) - } - Spacer(modifier = Modifier.height(50.dp)) + Spacer(modifier = Modifier.height(50.dp)) + + with(uiState.measuringRecordTimes) { + TdsTimer( + outCircularLineColor = Color( + uiState.measuringTimeColor.backgroundColor, + ), + outCircularProgress = outCircularProgress, + inCircularLineTrackColor = Color.White, + inCircularProgress = inCircularProgress, + fontColor = Color.White, + themeColor = Color(uiState.measuringTimeColor.backgroundColor), + recordingMode = uiState.recordTimes.recordingMode, + savedSumTime = savedSumTime, + savedTime = savedTime, + savedGoalTime = savedGoalTime, + finishGoalTime = finishGoalTime, + isTaskTargetTimeOn = isTaskTargetTimeOn, + onClickStopStart = { + onFinishClick() + }, + ) + } - TdsIconButton( - onClick = onFinishClick, - size = 70.dp, - ) { - Icon( - painter = painterResource(id = R.drawable.stop_record_icon), - contentDescription = "startRecord", - tint = TdsColor.RED.getColor(), - ) - } + Spacer(modifier = Modifier.height(50.dp)) - Spacer(modifier = Modifier.weight(1f)) + TdsIconButton( + onClick = onFinishClick, + size = 70.dp, + ) { + Icon( + painter = painterResource(id = R.drawable.stop_record_icon), + contentDescription = "startRecord", + tint = TdsColor.RED.getColor(), + ) + } - Spacer(modifier = Modifier.height(80.dp)) + Spacer(modifier = Modifier.weight(1f)) + + Spacer(modifier = Modifier.height(80.dp)) + } } - } - else -> { - Box( - Modifier - .fillMaxSize() - .safeDrawingPadding() - .background(Color.Black), - contentAlignment = Alignment.Center, - ) { - with(uiState.measuringRecordTimes) { - TdsTimer( - outCircularLineColor = Color(uiState.measuringTimeColor.backgroundColor), - outCircularProgress = outCircularProgress, - inCircularLineTrackColor = Color.White, - inCircularProgress = inCircularProgress, - fontColor = Color.White, - themeColor = Color(uiState.measuringTimeColor.backgroundColor), - recordingMode = uiState.recordTimes.recordingMode, - savedSumTime = savedSumTime, - savedTime = savedTime, - savedGoalTime = savedGoalTime, - finishGoalTime = finishGoalTime, - isTaskTargetTimeOn = isTaskTargetTimeOn, - onClickStopStart = { - onFinishClick() - }, - ) + else -> { + Box( + Modifier + .fillMaxSize() + .safeDrawingPadding() + .padding(it) + .background(Color.Black), + contentAlignment = Alignment.Center, + ) { + with(uiState.measuringRecordTimes) { + TdsTimer( + outCircularLineColor = Color( + uiState.measuringTimeColor.backgroundColor, + ), + outCircularProgress = outCircularProgress, + inCircularLineTrackColor = Color.White, + inCircularProgress = inCircularProgress, + fontColor = Color.White, + themeColor = Color(uiState.measuringTimeColor.backgroundColor), + recordingMode = uiState.recordTimes.recordingMode, + savedSumTime = savedSumTime, + savedTime = savedTime, + savedGoalTime = savedGoalTime, + finishGoalTime = finishGoalTime, + isTaskTargetTimeOn = isTaskTargetTimeOn, + onClickStopStart = { + onFinishClick() + }, + ) + } } } } diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt index c4337680..52b26591 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/FeaturesListScreen.kt @@ -6,6 +6,7 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.Scaffold @@ -75,6 +76,7 @@ fun FeaturesListScreen( FeaturesListScreen( modifier = Modifier .fillMaxSize() + .safeDrawingPadding() .padding(it), uiState = uiState, onClick = onNavigateWebView, diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt index 2a9ed4aa..e3d4276d 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/SettingScreen.kt @@ -11,6 +11,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.safeDrawingPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll @@ -129,7 +130,9 @@ fun SettingScreen( }, ) { SettingScreen( - modifier = Modifier.padding(it), + modifier = Modifier + .padding(it) + .safeDrawingPadding(), uiState = uiState, onSettingActions = { settingActions -> when (settingActions) { diff --git a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt index 2cb2b6df..278da84e 100644 --- a/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt +++ b/feature/setting/src/main/kotlin/com/titi/app/feature/setting/ui/UpdatesListScreen.kt @@ -11,6 +11,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.safeDrawingPadding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.ExperimentalMaterial3Api @@ -102,6 +103,7 @@ fun UpdatesListScreen(onNavigateUp: () -> Unit) { UpdateListScreen( modifier = Modifier .fillMaxSize() + .safeDrawingPadding() .padding(it), updates = updates.reversed(), ) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt index 8ff8250c..3cee085d 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt @@ -187,18 +187,20 @@ private fun StopWatchScreen( ) { val configuration = LocalConfiguration.current - when (configuration.orientation) { - Configuration.ORIENTATION_PORTRAIT -> { - Scaffold( - containerColor = Color(uiState.timeColor.stopwatchBackgroundColor), - bottomBar = { - TdsBottomNavigationBar( - currentTopLevelDestination = TopLevelDestination.STOPWATCH, - bottomNavigationColor = uiState.timeColor.stopwatchBackgroundColor, - onNavigateToDestination = onNavigateToDestination, - ) - }, - ) { + Scaffold( + containerColor = Color(uiState.timeColor.stopwatchBackgroundColor), + bottomBar = { + if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { + TdsBottomNavigationBar( + currentTopLevelDestination = TopLevelDestination.STOPWATCH, + bottomNavigationColor = uiState.timeColor.stopwatchBackgroundColor, + onNavigateToDestination = onNavigateToDestination, + ) + } + }, + ) { + when (configuration.orientation) { + Configuration.ORIENTATION_PORTRAIT -> { Column( modifier = Modifier .fillMaxSize() @@ -262,36 +264,38 @@ private fun StopWatchScreen( Spacer(modifier = Modifier.weight(1f)) } } - } - else -> { - Box( - Modifier - .fillMaxSize() - .safeDrawingPadding(), - contentAlignment = Alignment.Center, - ) { - with(uiState.stopWatchRecordTimes) { - TdsTimer( - outCircularLineColor = textColor, - outCircularProgress = outCircularProgress, - inCircularLineTrackColor = if (uiState.stopWatchColor.isTextColorBlack) { - Color.White - } else { - Color(0x8C000000) - }, - inCircularProgress = inCircularProgress, - fontColor = textColor, - recordingMode = 2, - savedSumTime = savedSumTime, - savedTime = savedTime, - savedGoalTime = savedGoalTime, - finishGoalTime = finishGoalTime, - isTaskTargetTimeOn = isTaskTargetTimeOn, - onClickStopStart = { - onClickStartRecord() - }, - ) + else -> { + Box( + Modifier + .fillMaxSize() + .safeDrawingPadding() + .padding(it), + contentAlignment = Alignment.Center, + ) { + with(uiState.stopWatchRecordTimes) { + TdsTimer( + outCircularLineColor = textColor, + outCircularProgress = outCircularProgress, + inCircularLineTrackColor = + if (uiState.stopWatchColor.isTextColorBlack) { + Color.White + } else { + Color(0x8C000000) + }, + inCircularProgress = inCircularProgress, + fontColor = textColor, + recordingMode = 2, + savedSumTime = savedSumTime, + savedTime = savedTime, + savedGoalTime = savedGoalTime, + finishGoalTime = finishGoalTime, + isTaskTargetTimeOn = isTaskTargetTimeOn, + onClickStopStart = { + onClickStartRecord() + }, + ) + } } } } diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt index 2e90f23c..4ed19f96 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt @@ -224,18 +224,20 @@ private fun TimerScreen( ) { val configuration = LocalConfiguration.current - when (configuration.orientation) { - Configuration.ORIENTATION_PORTRAIT -> { - Scaffold( - containerColor = Color(uiState.timeColor.timerBackgroundColor), - bottomBar = { - TdsBottomNavigationBar( - currentTopLevelDestination = TopLevelDestination.TIMER, - bottomNavigationColor = uiState.timeColor.timerBackgroundColor, - onNavigateToDestination = onNavigateToDestination, - ) - }, - ) { + Scaffold( + containerColor = Color(uiState.timeColor.timerBackgroundColor), + bottomBar = { + if (configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { + TdsBottomNavigationBar( + currentTopLevelDestination = TopLevelDestination.TIMER, + bottomNavigationColor = uiState.timeColor.timerBackgroundColor, + onNavigateToDestination = onNavigateToDestination, + ) + } + }, + ) { + when (configuration.orientation) { + Configuration.ORIENTATION_PORTRAIT -> { Column( modifier = Modifier .fillMaxSize() @@ -300,37 +302,38 @@ private fun TimerScreen( Spacer(modifier = Modifier.weight(1f)) } } - } - else -> { - Box( - Modifier - .fillMaxSize() - .safeDrawingPadding(), - contentAlignment = Alignment.Center, - ) { - with(uiState.timerRecordTimes) { - TdsTimer( - isFinish = isFinish, - outCircularLineColor = textColor, - outCircularProgress = outCircularProgress, - inCircularLineTrackColor = if (uiState.timerColor.isTextColorBlack) { - Color.White - } else { - Color(0x8C000000) - }, - inCircularProgress = inCircularProgress, - fontColor = textColor, - recordingMode = 1, - savedSumTime = savedSumTime, - savedTime = savedTime, - savedGoalTime = savedGoalTime, - finishGoalTime = finishGoalTime, - isTaskTargetTimeOn = isTaskTargetTimeOn, - onClickStopStart = { - onClickStartRecord() - }, - ) + else -> { + Box( + Modifier + .fillMaxSize() + .safeDrawingPadding() + .padding(it), + contentAlignment = Alignment.Center, + ) { + with(uiState.timerRecordTimes) { + TdsTimer( + isFinish = isFinish, + outCircularLineColor = textColor, + outCircularProgress = outCircularProgress, + inCircularLineTrackColor = if (uiState.timerColor.isTextColorBlack) { + Color.White + } else { + Color(0x8C000000) + }, + inCircularProgress = inCircularProgress, + fontColor = textColor, + recordingMode = 1, + savedSumTime = savedSumTime, + savedTime = savedTime, + savedGoalTime = savedGoalTime, + finishGoalTime = finishGoalTime, + isTaskTargetTimeOn = isTaskTargetTimeOn, + onClickStopStart = { + onClickStartRecord() + }, + ) + } } } } diff --git a/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt b/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt index 2b28535a..861f502a 100644 --- a/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt +++ b/feature/webview/src/main/kotlin/com/titi/app/feature/webview/WebViewScreen.kt @@ -6,6 +6,7 @@ import android.webkit.WebView import android.webkit.WebViewClient import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawingPadding import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.Scaffold @@ -57,6 +58,7 @@ fun WebViewScreen(title: String, url: String, onNavigateUp: () -> Unit) { WebViewScreen( modifier = Modifier .fillMaxSize() + .safeDrawingPadding() .padding(it), url = url, ) From 3ffc1bae4d5540a07d5d9beff58c08cfe9033e07 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 18:18:02 +0900 Subject: [PATCH 35/41] #123 update : measure padding --- .../app/feature/measure/ui/MeasuringScreen.kt | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt b/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt index 55d84b35..99f6a15a 100644 --- a/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt +++ b/feature/measure/src/main/kotlin/com/titi/app/feature/measure/ui/MeasuringScreen.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.Box 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.safeDrawingPadding @@ -206,17 +205,7 @@ private fun MeasuringScreen( ) { val configuration = LocalConfiguration.current - Scaffold( - containerColor = Color.Black, - bottomBar = { - Box( - modifier = Modifier - .fillMaxWidth() - .height(58.dp) - .background(Color.Transparent), - ) - }, - ) { + Scaffold(containerColor = Color.Black) { when (configuration.orientation) { Configuration.ORIENTATION_PORTRAIT -> { Column( @@ -228,16 +217,14 @@ private fun MeasuringScreen( horizontalAlignment = Alignment.CenterHorizontally, ) { TdsIconButton( - modifier = - Modifier + modifier = Modifier .padding(start = 16.dp) .align(Alignment.Start), size = 32.dp, onClick = onSleepClick, ) { Icon( - painter = - if (uiState.isSleepMode) { + painter = if (uiState.isSleepMode) { painterResource(id = R.drawable.sleep_icon) } else { painterResource(id = R.drawable.non_sleep_icon) @@ -250,7 +237,7 @@ private fun MeasuringScreen( Spacer(modifier = Modifier.weight(1f)) TdsText( - modifier = Modifier.padding(vertical = 12.dp), + modifier = Modifier.padding(vertical = 24.dp), text = uiState.recordTimes.currentTask?.taskName, textStyle = TdsTextStyle.NORMAL_TEXT_STYLE, fontSize = 18.sp, From d06bc85b072b1040fbc5aad60f5530a3556e435f Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 18:22:50 +0900 Subject: [PATCH 36/41] #126 update : version code --- build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt b/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt index 06cd8a76..0812cfb8 100644 --- a/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt +++ b/build-logic/src/main/kotlin/com/titi/common/BuildInfo.kt @@ -10,6 +10,6 @@ object BuildType { object AppConfig { const val APP_ID = "com.titi.app" const val APP_VERSION_NAME = "1.0.3" - const val APP_VERSION_CODE = 24 + const val APP_VERSION_CODE = 25 const val APP_NAME = "TiTi" } \ No newline at end of file From 8264c2c6261220340bd6173d545cdeb287adb320 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 18:24:47 +0900 Subject: [PATCH 37/41] #126 docs : release-note --- release-note.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/release-note.txt b/release-note.txt index c1422a1e..7eec99f6 100644 --- a/release-note.txt +++ b/release-note.txt @@ -1,2 +1,4 @@ -TiTi android dev 1.0.3(24) -- 세팅 화면 구현 완료 \ No newline at end of file +TiTi android dev 1.0.3(25) +- 세팅 화면 +- 데일리 추가, 수정 로직 변경 +- 측정화면 activity -> screen \ No newline at end of file From b054d0108dbe9e0686cfb8d715f7f5080a2071e6 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 19:46:17 +0900 Subject: [PATCH 38/41] #126 update : graph padding --- .../core/designsystem/component/TdsStandardDailyGraph.kt | 9 +++++---- .../designsystem/component/TdsTaskProgressDailyGraph.kt | 9 +++++---- .../core/designsystem/component/TdsTimeLineDailyGraph.kt | 9 +++++---- .../titi/app/core/designsystem/component/TdsTimeTable.kt | 2 +- .../designsystem/component/TdsTimeTableDailyGraph.kt | 9 +++++---- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsStandardDailyGraph.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsStandardDailyGraph.kt index 6d8e8adc..6c1a75e7 100644 --- a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsStandardDailyGraph.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsStandardDailyGraph.kt @@ -51,12 +51,13 @@ fun TdsStandardDailyGraph( modifier = modifier, contentAlignment = Alignment.Center, ) { - val size = maxWidth.coerceAtMost(345.dp) + val size = maxWidth.coerceAtMost(365.dp) OutlinedCard( modifier = Modifier .createCaptureImageModifier(picture = picture) - .size(size), + .size(size) + .padding(10.dp), shape = RoundedCornerShape(size * 0.07), colors = CardDefaults.cardColors(containerColor = TdsColor.BACKGROUND.getColor()), border = BorderStroke( @@ -203,8 +204,8 @@ fun TdsStandardDailyGraph( Box( modifier = Modifier .offset( - x = -size / 2 + 26.dp, - y = -size * 0.38 + 33.dp, + x = -size / 2 + 36.dp, + y = -size * 0.38 + 43.dp, ), ) { TdsToggleIconButton( diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTaskProgressDailyGraph.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTaskProgressDailyGraph.kt index 0a56261d..5901e66a 100644 --- a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTaskProgressDailyGraph.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTaskProgressDailyGraph.kt @@ -42,12 +42,13 @@ fun TdsTaskProgressDailyGraph( modifier = modifier, contentAlignment = Alignment.Center, ) { - val size = maxWidth.coerceAtMost(345.dp) + val size = maxWidth.coerceAtMost(365.dp) OutlinedCard( modifier = Modifier .createCaptureImageModifier(picture = picture) - .size(size), + .size(size) + .padding(10.dp), shape = RoundedCornerShape(size * 0.07), colors = CardDefaults.cardColors(containerColor = TdsColor.BACKGROUND.getColor()), border = BorderStroke( @@ -84,8 +85,8 @@ fun TdsTaskProgressDailyGraph( Box( modifier = Modifier .offset( - x = -size / 2 + 26.dp, - y = -size * 0.49 + 26.dp, + x = -size / 2 + 36.dp, + y = -size * 0.49 + 36.dp, ), ) { TdsToggleIconButton( diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeLineDailyGraph.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeLineDailyGraph.kt index e2d62064..c95fddf2 100644 --- a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeLineDailyGraph.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeLineDailyGraph.kt @@ -48,12 +48,13 @@ fun TdsTimeLineDailyGraph( modifier = modifier, contentAlignment = Alignment.Center, ) { - val size = maxWidth.coerceAtMost(345.dp) + val size = maxWidth.coerceAtMost(365.dp) OutlinedCard( modifier = Modifier .createCaptureImageModifier(picture = picture) - .size(size), + .size(size) + .padding(10.dp), shape = RoundedCornerShape(size * 0.07), colors = CardDefaults.cardColors(containerColor = TdsColor.BACKGROUND.getColor()), border = BorderStroke( @@ -147,8 +148,8 @@ fun TdsTimeLineDailyGraph( Box( modifier = Modifier .offset( - x = -size / 2 + 26.dp, - y = -size * 0.49 + 26.dp, + x = -size / 2 + 36.dp, + y = -size * 0.49 + 36.dp, ), ) { TdsToggleIconButton( diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTable.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTable.kt index cf32d15f..2991953d 100644 --- a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTable.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTable.kt @@ -35,7 +35,7 @@ fun TdsTimeTable( mutableStateOf("0") } var fontSize by remember { - mutableStateOf(14.sp) + mutableStateOf(7.sp) } val textStyle = TdsTextStyle .SEMI_BOLD_TEXT_STYLE diff --git a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTableDailyGraph.kt b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTableDailyGraph.kt index 7a554fc5..471b7dad 100644 --- a/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTableDailyGraph.kt +++ b/core/designsystem/src/main/kotlin/com/titi/app/core/designsystem/component/TdsTimeTableDailyGraph.kt @@ -53,12 +53,13 @@ fun TdsTimeTableDailyGraph( modifier = modifier, contentAlignment = Alignment.Center, ) { - val size = maxWidth.coerceAtMost(345.dp) + val size = maxWidth.coerceAtMost(365.dp) OutlinedCard( modifier = Modifier .createCaptureImageModifier(picture = picture) - .size(size), + .size(size) + .padding(10.dp), shape = RoundedCornerShape(size * 0.07), colors = CardDefaults.cardColors(containerColor = TdsColor.BACKGROUND.getColor()), border = BorderStroke( @@ -216,8 +217,8 @@ fun TdsTimeTableDailyGraph( Box( modifier = Modifier .offset( - x = -size / 2 + 26.dp, - y = -size * 0.38 + 33.dp, + x = -size / 2 + 36.dp, + y = -size * 0.38 + 43.dp, ), ) { TdsToggleIconButton( From 7ba9723d344aef215133f9a781103fa3b0a8c32a Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 22:53:16 +0900 Subject: [PATCH 39/41] =?UTF-8?q?#126=20update=20:=20=EB=8D=B0=EC=9D=BC?= =?UTF-8?q?=EB=A6=AC=20=EC=B6=94=EA=B0=80=20->=20=EB=AA=A9=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/add_record_icon.xml | 13 ----- .../time/component/TimeButtonComponent.kt | 19 ++----- ...kDailyDialog.kt => TimeCheckTaskDialog.kt} | 4 +- ...ilyDialog.kt => TimeGoalTimeEditDialog.kt} | 15 +---- .../feature/time/model/StopWatchUiState.kt | 1 - .../app/feature/time/model/TimerUiState.kt | 1 - .../time/ui/stopwatch/StopWatchScreen.kt | 55 +++++++----------- .../time/ui/stopwatch/StopWatchViewModel.kt | 6 -- .../app/feature/time/ui/timer/TimerScreen.kt | 57 +++++++------------ .../feature/time/ui/timer/TimerViewModel.kt | 6 -- 10 files changed, 51 insertions(+), 126 deletions(-) delete mode 100644 core/designsystem/src/main/res/drawable/add_record_icon.xml rename feature/time/src/main/kotlin/com/titi/app/feature/time/component/{TimeCheckDailyDialog.kt => TimeCheckTaskDialog.kt} (84%) rename feature/time/src/main/kotlin/com/titi/app/feature/time/component/{TimeAddEditDailyDialog.kt => TimeGoalTimeEditDialog.kt} (79%) diff --git a/core/designsystem/src/main/res/drawable/add_record_icon.xml b/core/designsystem/src/main/res/drawable/add_record_icon.xml deleted file mode 100644 index caaf5309..00000000 --- a/core/designsystem/src/main/res/drawable/add_record_icon.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeButtonComponent.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeButtonComponent.kt index b17ba696..9969d389 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeButtonComponent.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeButtonComponent.kt @@ -14,14 +14,12 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsIconButton -import com.titi.app.core.designsystem.theme.TdsColor @Composable fun TimeButtonComponent( recordingMode: Int, tintColor: Color, - isFirstDaily: Boolean, - onClickAddEditDaily: () -> Unit, + onClickGoalTimeEdit: () -> Unit, onClickStartRecord: () -> Unit, onClickSettingTimer: (() -> Unit)? = null, onClickResetStopwatch: (() -> Unit)? = null, @@ -32,21 +30,14 @@ fun TimeButtonComponent( horizontalArrangement = Arrangement.Center, ) { TdsIconButton( - onClick = onClickAddEditDaily, + onClick = onClickGoalTimeEdit, size = 50.dp, ) { Icon( - painter = if (isFirstDaily) { - painterResource(id = R.drawable.add_record_icon) - } else { - painterResource(id = R.drawable.edit_record_icon) - }, + painter = + painterResource(id = R.drawable.edit_record_icon), contentDescription = "addRecord", - tint = if (isFirstDaily) { - TdsColor.RED.getColor() - } else { - tintColor - }, + tint = tintColor, ) } diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckDailyDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckTaskDialog.kt similarity index 84% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckDailyDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckTaskDialog.kt index a1acbee0..88fd5bd0 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckDailyDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeCheckTaskDialog.kt @@ -11,10 +11,10 @@ import com.titi.app.core.designsystem.component.TdsDialog import com.titi.app.core.designsystem.model.TdsDialogInfo @Composable -fun TimeCheckDailyDialog(title: String, onShowDialog: (Boolean) -> Unit) { +fun TimeCheckTaskDialog(onShowDialog: (Boolean) -> Unit) { TdsDialog( tdsDialogInfo = TdsDialogInfo.Alert( - title = title, + title = stringResource(id = R.string.task_check_title), confirmText = stringResource(id = R.string.Ok), ), onShowDialog = onShowDialog, diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeAddEditDailyDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeGoalTimeEditDialog.kt similarity index 79% rename from feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeAddEditDailyDialog.kt rename to feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeGoalTimeEditDialog.kt index cce1ec5d..899b1d85 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeAddEditDailyDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeGoalTimeEditDialog.kt @@ -17,8 +17,7 @@ import com.titi.app.core.designsystem.model.TdsTime import com.titi.app.core.util.getTimeToLong @Composable -fun TimeAddEditDailyDialog( - isFirstDaily: Boolean, +fun TimeGoalTimeEditDialog( todayDate: String, currentTime: TdsTime, onPositive: (Long) -> Unit, @@ -30,16 +29,8 @@ fun TimeAddEditDailyDialog( TdsDialog( tdsDialogInfo = TdsDialogInfo.Confirm( - title = if (isFirstDaily) { - stringResource(R.string.add_daily_title) - } else { - stringResource(id = R.string.edit_daily_title) - }, - message = if (isFirstDaily) { - stringResource(R.string.add_daily_message, todayDate) - } else { - stringResource(R.string.edit_daily_message, todayDate) - }, + title = stringResource(R.string.add_daily_title), + message = stringResource(R.string.edit_daily_message, todayDate), positiveText = stringResource(id = R.string.Ok), negativeText = stringResource(id = R.string.Cancel), onPositive = { diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt index bc2692db..91713512 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/StopWatchUiState.kt @@ -20,7 +20,6 @@ data class StopWatchUiState( daily = getSplashResultStateFromArgs(args).daily, ) - val isFirstDaily: Boolean = daily == null val isSetTask: Boolean = recordTimes.currentTask != null val taskName: String = recordTimes.currentTask?.taskName ?: "" val stopWatchColor = timeColor.toUiModel() diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt index dd094659..2b796ebe 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/model/TimerUiState.kt @@ -22,7 +22,6 @@ data class TimerUiState( daily = getSplashResultStateFromArgs(args).daily, ) - val isFirstDaily: Boolean = daily == null val isSetTask: Boolean = recordTimes.currentTask != null val taskName: String = recordTimes.currentTask?.taskName ?: "" val timerColor = timeColor.toUiModel() diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt index f851c3bf..cae72517 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchScreen.kt @@ -19,20 +19,18 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.airbnb.mvrx.asMavericksArgs import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel -import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime import com.titi.app.core.designsystem.navigation.TdsBottomNavigationBar import com.titi.app.core.designsystem.navigation.TopLevelDestination -import com.titi.app.feature.time.component.TimeAddEditDailyDialog import com.titi.app.feature.time.component.TimeButtonComponent -import com.titi.app.feature.time.component.TimeCheckDailyDialog +import com.titi.app.feature.time.component.TimeCheckTaskDialog import com.titi.app.feature.time.component.TimeColorDialog +import com.titi.app.feature.time.component.TimeGoalTimeEditDialog import com.titi.app.feature.time.component.TimeHeaderComponent import com.titi.app.feature.time.component.TimeTaskComponent import com.titi.app.feature.time.model.SplashResultState @@ -60,8 +58,8 @@ fun StopWatchScreen( var showTaskBottomSheet by remember { mutableStateOf(false) } var showSelectColorDialog by remember { mutableStateOf(false) } - var showAddEditDailyDialog by remember { mutableStateOf(false) } - var showCheckTaskDailyDialog by remember { mutableStateOf(false) } + var showGoalTimeEditDialog by remember { mutableStateOf(false) } + var showCheckTaskDialog by remember { mutableStateOf(false) } if (showTaskBottomSheet) { TaskBottomSheet( @@ -91,40 +89,28 @@ fun StopWatchScreen( ) } - if (showAddEditDailyDialog) { - TimeAddEditDailyDialog( - isFirstDaily = uiState.isFirstDaily, + if (showGoalTimeEditDialog) { + TimeGoalTimeEditDialog( todayDate = uiState.todayDate, currentTime = uiState.recordTimes.setGoalTime.getTdsTime(), onPositive = { goalTime -> if (goalTime > 0) { - if (uiState.isFirstDaily) { - viewModel.addDaily() - } else { - viewModel.updateSetGoalTime( - uiState.recordTimes, - goalTime, - ) - } + viewModel.updateSetGoalTime( + uiState.recordTimes, + goalTime, + ) } }, onShowDialog = { - showAddEditDailyDialog = it + showGoalTimeEditDialog = it }, ) } - if (showCheckTaskDailyDialog) { - TimeCheckDailyDialog( - title = if (!uiState.isSetTask && uiState.isFirstDaily) { - stringResource(id = R.string.daily_task_check_title) - } else if (!uiState.isSetTask) { - stringResource(id = R.string.task_check_title) - } else { - stringResource(id = R.string.daily_check_title) - }, + if (showCheckTaskDialog) { + TimeCheckTaskDialog( onShowDialog = { - showCheckTaskDailyDialog = it + showCheckTaskDialog = it }, ) } @@ -143,11 +129,11 @@ fun StopWatchScreen( onClickTask = { showTaskBottomSheet = true }, - onClickAddEditDaily = { - showAddEditDailyDialog = true + onClickGoalTimeEdit = { + showGoalTimeEditDialog = true }, onClickStartRecord = { - if (uiState.isSetTask && !uiState.isFirstDaily) { + if (uiState.isSetTask) { val splashResultStateString = viewModel.startRecording( recordTimes = uiState.recordTimes, daily = uiState.daily, @@ -155,7 +141,7 @@ fun StopWatchScreen( ) onNavigateToMeasure(splashResultStateString) } else { - showCheckTaskDailyDialog = true + showGoalTimeEditDialog = true } }, onClickResetStopWatch = { @@ -171,7 +157,7 @@ private fun StopWatchScreen( textColor: Color, onClickColor: () -> Unit, onClickTask: () -> Unit, - onClickAddEditDaily: () -> Unit, + onClickGoalTimeEdit: () -> Unit, onClickStartRecord: () -> Unit, onClickResetStopWatch: () -> Unit, onNavigateToDestination: (TopLevelDestination) -> Unit, @@ -245,8 +231,7 @@ private fun StopWatchScreen( TimeButtonComponent( recordingMode = 2, tintColor = textColor, - isFirstDaily = uiState.isFirstDaily, - onClickAddEditDaily = onClickAddEditDaily, + onClickGoalTimeEdit = onClickGoalTimeEdit, onClickStartRecord = onClickStartRecord, onClickResetStopwatch = onClickResetStopWatch, ) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt index a835707a..778fb796 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/stopwatch/StopWatchViewModel.kt @@ -95,12 +95,6 @@ class StopWatchViewModel @AssistedInject constructor( prevStopWatchColor = stopWatchColor } - fun addDaily() { - viewModelScope.launch { - addDailyUseCase(Daily()) - } - } - fun updateSetGoalTime(recordTimes: RecordTimes, setGoalTime: Long) { viewModelScope.launch { updateSetGoalTimeUseCase( diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt index 297381f2..01967a49 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerScreen.kt @@ -20,20 +20,18 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalConfiguration -import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.airbnb.mvrx.asMavericksArgs import com.airbnb.mvrx.compose.collectAsState import com.airbnb.mvrx.compose.mavericksViewModel -import com.titi.app.core.designsystem.R import com.titi.app.core.designsystem.component.TdsTimer import com.titi.app.core.designsystem.extension.getTdsTime import com.titi.app.core.designsystem.navigation.TdsBottomNavigationBar import com.titi.app.core.designsystem.navigation.TopLevelDestination -import com.titi.app.feature.time.component.TimeAddEditDailyDialog import com.titi.app.feature.time.component.TimeButtonComponent -import com.titi.app.feature.time.component.TimeCheckDailyDialog +import com.titi.app.feature.time.component.TimeCheckTaskDialog import com.titi.app.feature.time.component.TimeColorDialog +import com.titi.app.feature.time.component.TimeGoalTimeEditDialog import com.titi.app.feature.time.component.TimeHeaderComponent import com.titi.app.feature.time.component.TimeTaskComponent import com.titi.app.feature.time.component.TimeTimerDialog @@ -64,8 +62,8 @@ fun TimerScreen( var showTaskBottomSheet by remember { mutableStateOf(false) } var showSelectColorDialog by remember { mutableStateOf(false) } - var showAddEditDailyDialog by remember { mutableStateOf(false) } - var showCheckTaskDailyDialog by remember { mutableStateOf(false) } + var showGoalTimeEditDialog by remember { mutableStateOf(false) } + var showCheckTaskDialog by remember { mutableStateOf(false) } var showUpdateTimerDialog by remember { mutableStateOf(false) } if (showTaskBottomSheet) { @@ -98,42 +96,30 @@ fun TimerScreen( ) } - if (showAddEditDailyDialog) { - TimeAddEditDailyDialog( - isFirstDaily = uiState.isFirstDaily, + if (showGoalTimeEditDialog) { + TimeGoalTimeEditDialog( todayDate = uiState.todayDate, currentTime = uiState.recordTimes.setGoalTime.getTdsTime(), onPositive = { goalTime -> if (goalTime > 0) { - if (uiState.isFirstDaily) { - viewModel.addDaily() - } else { - viewModel.updateSetGoalTime( - uiState.recordTimes, - goalTime, - ) + viewModel.updateSetGoalTime( + uiState.recordTimes, + goalTime, + ) - onChangeFinishStateFalse() - } + onChangeFinishStateFalse() } }, onShowDialog = { - showAddEditDailyDialog = it + showGoalTimeEditDialog = it }, ) } - if (showCheckTaskDailyDialog) { - TimeCheckDailyDialog( - title = if (!uiState.isSetTask && uiState.isFirstDaily) { - stringResource(id = R.string.daily_task_check_title) - } else if (!uiState.isSetTask) { - stringResource(id = R.string.task_check_title) - } else { - stringResource(id = R.string.daily_check_title) - }, + if (showCheckTaskDialog) { + TimeCheckTaskDialog( onShowDialog = { - showCheckTaskDailyDialog = it + showCheckTaskDialog = it }, ) } @@ -170,11 +156,11 @@ fun TimerScreen( onClickTask = { showTaskBottomSheet = true }, - onClickAddEditDaily = { - showAddEditDailyDialog = true + onClickGoalTimeEdit = { + showGoalTimeEditDialog = true }, onClickStartRecord = { - if (uiState.isSetTask && !uiState.isFirstDaily) { + if (uiState.isSetTask) { val splashResultStateString = viewModel.startRecording( recordTimes = uiState.recordTimes, daily = uiState.daily, @@ -182,7 +168,7 @@ fun TimerScreen( ) onNavigateToMeasure(splashResultStateString) } else { - showCheckTaskDailyDialog = true + showCheckTaskDialog = true } }, onClickSettingTimer = { @@ -199,7 +185,7 @@ private fun TimerScreen( textColor: Color, onClickColor: () -> Unit, onClickTask: () -> Unit, - onClickAddEditDaily: () -> Unit, + onClickGoalTimeEdit: () -> Unit, onClickStartRecord: () -> Unit, onClickSettingTimer: () -> Unit, onNavigateToDestination: (TopLevelDestination) -> Unit, @@ -274,8 +260,7 @@ private fun TimerScreen( TimeButtonComponent( recordingMode = 1, tintColor = textColor, - isFirstDaily = uiState.isFirstDaily, - onClickAddEditDaily = onClickAddEditDaily, + onClickGoalTimeEdit = onClickGoalTimeEdit, onClickStartRecord = onClickStartRecord, onClickSettingTimer = onClickSettingTimer, ) diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt index 6d12d790..9c4e7aed 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/ui/timer/TimerViewModel.kt @@ -95,12 +95,6 @@ class TimerViewModel @AssistedInject constructor( prevTimerColor = timerColor } - fun addDaily() { - viewModelScope.launch { - addDailyUseCase(Daily()) - } - } - fun updateSetGoalTime(recordTimes: RecordTimes, setGoalTime: Long) { viewModelScope.launch { updateSetGoalTimeUseCase( From 6c15e250c267a884f4c6c5d63732b02d42f3e0b7 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 22:56:07 +0900 Subject: [PATCH 40/41] =?UTF-8?q?#126=20update=20:=20=EB=AA=A9=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=EA=B0=84=20=EC=88=98=EC=A0=95=20stringResource?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/designsystem/src/main/res/values/strings.xml | 4 +--- .../titi/app/feature/time/component/TimeGoalTimeEditDialog.kt | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/core/designsystem/src/main/res/values/strings.xml b/core/designsystem/src/main/res/values/strings.xml index d2afab37..92efa1ff 100644 --- a/core/designsystem/src/main/res/values/strings.xml +++ b/core/designsystem/src/main/res/values/strings.xml @@ -25,10 +25,8 @@ 배경 텍스트 해당 색상을 배경색으로 설정하시겠습니까? - 새로운 기록 설정 - %1$s 목표시간 설정 목표시간 수정 - %1$s 목표시간 수정 + %1$s의 목표시간을 수정해요! 타이머 시간 설정 종료예정 : %1$s Task와 Daily를 확인해주세요. diff --git a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeGoalTimeEditDialog.kt b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeGoalTimeEditDialog.kt index 899b1d85..28734f50 100644 --- a/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeGoalTimeEditDialog.kt +++ b/feature/time/src/main/kotlin/com/titi/app/feature/time/component/TimeGoalTimeEditDialog.kt @@ -29,7 +29,7 @@ fun TimeGoalTimeEditDialog( TdsDialog( tdsDialogInfo = TdsDialogInfo.Confirm( - title = stringResource(R.string.add_daily_title), + title = stringResource(R.string.edit_daily_title), message = stringResource(R.string.edit_daily_message, todayDate), positiveText = stringResource(id = R.string.Ok), negativeText = stringResource(id = R.string.Cancel), From b7604f43c7a33419020342487d8d874dac032954 Mon Sep 17 00:00:00 2001 From: koreatlwls Date: Sun, 19 May 2024 23:01:40 +0900 Subject: [PATCH 41/41] #126 update : popbackstack -> navigateup --- .../kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt index 86bc50b3..241c2760 100644 --- a/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt +++ b/feature/main/src/main/kotlin/com/titi/app/feature/main/navigation/TiTiNavHost.kt @@ -78,7 +78,7 @@ fun TiTiNavHost(splashResultState: SplashResultState, modifier: Modifier = Modif navController.previousBackStackEntry ?.savedStateHandle ?.set(TIMER_FINISH_KEY, isFinish) - navController.popBackStack() + navController.navigateUp() }, )