From 3040f61115bec327e3595b107d1bcccaa2d031ef Mon Sep 17 00:00:00 2001 From: HaeTi Date: Thu, 4 Apr 2024 18:20:38 +0900 Subject: [PATCH 001/184] =?UTF-8?q?compose=20navigation=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 7 +++++-- gradle/libs.versions.toml | 2 ++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index cb19186b..cc32a28e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -201,8 +201,11 @@ dependencies { // Compose Material Design 3 implementation(libs.androidx.compose.material3) - // lifecycle - implementation(libs.androidx.lifecycle.runtime.compose) + // Compose navigation + implementation(libs.androidx.navigation.compose) + + // hilt navigation compose + implementation(libs.androidx.hilt.navigation.compose) // Compose navigation implementation(libs.androidx.navigation.compose) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9c8d69df..a3a66f0f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -20,6 +20,7 @@ gson = "2.10.1" hiltAndroid = "2.44.2" hiltAndroidGradlePlugin = "2.48" hiltCompiler = "2.48" +hiltNavigationCompose = "1.2.0" junit = "4.13.2" junitVersion = "1.1.5" kotlinxCoroutines = "1.8.0" @@ -70,6 +71,7 @@ androidx-material-icons-extended = { module = "androidx.compose.material:materia androidx-navigation-fragment-ktx = { module = "androidx.navigation:navigation-fragment-ktx", version.ref = "navigationUiKtx" } androidx-navigation-ui-ktx = { module = "androidx.navigation:navigation-ui-ktx", version.ref = "navigationUiKtx" } androidx-navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigationUiKtx" } +androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" } androidx-recyclerview = { module = "androidx.recyclerview:recyclerview", version.ref = "recyclerview" } androidx-security-crypto-ktx = { module = "androidx.security:security-crypto-ktx", version.ref = "securityCryptoKtx" } balloon = { module = "com.github.skydoves:balloon", version.ref = "balloon" } From e26cdde5a1576e42be22f9a04a31ea6d9851bbd0 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 5 Apr 2024 02:28:04 +0900 Subject: [PATCH 002/184] add Spacer Ext --- .../main/java/com/sopt/smeem/util/SpacerExt.kt | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/util/SpacerExt.kt diff --git a/app/src/main/java/com/sopt/smeem/util/SpacerExt.kt b/app/src/main/java/com/sopt/smeem/util/SpacerExt.kt new file mode 100644 index 00000000..47184030 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/util/SpacerExt.kt @@ -0,0 +1,18 @@ +package com.sopt.smeem.util + +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp + +@Composable +fun VerticalSpacer(height: Dp) { + Spacer(modifier = Modifier.height(height)) +} + +@Composable +fun HorizontalSpacer(width: Dp) { + Spacer(modifier = Modifier.width(width)) +} \ No newline at end of file From 9baf9218b640aa14c40ffff22cab57b2635051b2 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 5 Apr 2024 02:37:19 +0900 Subject: [PATCH 003/184] feature MyPagNavHost --- .../sopt/smeem/presentation/mypage/Const.kt | 4 ++ .../mypage/mysummary/MySummaryScreen.kt | 37 +++++++++++++ .../mypage/navigation/MyPageNavHost.kt | 52 +++++++++++++++++++ .../mypage/navigation/MyPageScreen.kt | 9 ++++ .../mypage/setting/SettingScreen.kt | 41 +++++++++++++++ 5 files changed, 143 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt new file mode 100644 index 00000000..5bbdf965 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt @@ -0,0 +1,4 @@ +package com.sopt.smeem.presentation.mypage + +const val MY_SUMMARY = "MyPage" +const val SETTING = "Setting" diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt new file mode 100644 index 00000000..75e29361 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt @@ -0,0 +1,37 @@ +package com.sopt.smeem.presentation.mypage.mysummary + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.sopt.smeem.presentation.mypage.SETTING +import com.sopt.smeem.util.VerticalSpacer + +@Composable +fun MySummaryScreen( + navController: NavController, + modifier: Modifier +) { + Column( + modifier = modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text(text = "성과요약 화면이다") + VerticalSpacer(height = 50.dp) + Button(onClick = { + navController.navigate(SETTING) { + launchSingleTop = true + restoreState = true + } + }) { + Text(text = "설정 화면으로 이동한다") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt new file mode 100644 index 00000000..a0011314 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt @@ -0,0 +1,52 @@ +package com.sopt.smeem.presentation.mypage.navigation + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavHostController +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.currentBackStackEntryAsState +import com.sopt.smeem.presentation.mypage.mysummary.MySummaryScreen +import com.sopt.smeem.presentation.mypage.setting.SettingScreen + +@Composable +fun MyPageNavHost( + navController: NavHostController +) { + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentRoute = navBackStackEntry?.destination?.route + + Scaffold( + topBar = { + // TopAppBar + } + ) { + NavHost(navController = navController, startDestination = MyPageScreen.MySummary.route) { + addMySummary(navController = navController, modifier = Modifier.padding(it)) + addSetting(navController = navController, modifier = Modifier.padding(it)) + } + } +} + +private fun NavGraphBuilder.addMySummary(navController: NavController, modifier: Modifier) { + composable(route = MyPageScreen.MySummary.route) { + MySummaryScreen( + navController = navController, + modifier = modifier + ) + } +} + +private fun NavGraphBuilder.addSetting(navController: NavController, modifier: Modifier) { + composable(route = MyPageScreen.Setting.route) { + SettingScreen( + navController = navController, + modifier = modifier + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt new file mode 100644 index 00000000..3e895674 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt @@ -0,0 +1,9 @@ +package com.sopt.smeem.presentation.mypage.navigation + +import com.sopt.smeem.presentation.mypage.MY_SUMMARY +import com.sopt.smeem.presentation.mypage.SETTING + +sealed class MyPageScreen(val route: String) { + data object MySummary : MyPageScreen(MY_SUMMARY) + data object Setting : MyPageScreen(SETTING) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt new file mode 100644 index 00000000..096b1b0d --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt @@ -0,0 +1,41 @@ +package com.sopt.smeem.presentation.mypage.setting + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.sopt.smeem.presentation.mypage.MY_SUMMARY +import com.sopt.smeem.presentation.mypage.SETTING +import com.sopt.smeem.util.VerticalSpacer + +@Composable +fun SettingScreen( + navController: NavController, + modifier: Modifier +) { + Column( + modifier = modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text(text = "설정 화면이다") + VerticalSpacer(height = 50.dp) + Button(onClick = { + navController.navigate(MY_SUMMARY) { + popUpTo(SETTING) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + }) { + Text(text = "다시 성과 요약 화면으로 이동한다") + } + } +} \ No newline at end of file From 8996f7a5d082b179dba650ccc0d4da9c298f61d6 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 5 Apr 2024 02:37:36 +0900 Subject: [PATCH 004/184] add TempMyPageActivity --- app/src/main/AndroidManifest.xml | 9 ++++++-- .../smeem/presentation/home/HomeActivity.kt | 4 ++-- .../presentation/mypage/TempMyPageActivity.kt | 22 +++++++++++++++++++ 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 604d6d95..30c501de 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,7 +13,6 @@ android:value="false" /> + android:screenOrientation="portrait" /> + + diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt index 90caeca9..ef131a7c 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt @@ -25,7 +25,7 @@ import com.sopt.smeem.presentation.home.calendar.SmeemCalendar import com.sopt.smeem.presentation.home.calendar.core.CalendarIntent import com.sopt.smeem.presentation.home.calendar.core.Period import com.sopt.smeem.presentation.home.calendar.ui.theme.SmeemTheme -import com.sopt.smeem.presentation.mypage.MyPageActivity +import com.sopt.smeem.presentation.mypage.TempMyPageActivity import com.sopt.smeem.util.DateUtil import com.sopt.smeem.util.getWeekStartDate import com.sopt.smeem.util.setOnSingleClickListener @@ -91,7 +91,7 @@ class HomeActivity : BindingActivity(R.layout.activity_home private fun moveToMyPage() { binding.ivMyPage.setOnClickListener { - startActivity(Intent(this, MyPageActivity::class.java)) + startActivity(Intent(this, TempMyPageActivity::class.java)) } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt new file mode 100644 index 00000000..fa9a1940 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt @@ -0,0 +1,22 @@ +package com.sopt.smeem.presentation.mypage + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.navigation.compose.rememberNavController +import com.sopt.smeem.presentation.home.calendar.ui.theme.SmeemTheme +import com.sopt.smeem.presentation.mypage.navigation.MyPageNavHost +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class TempMyPageActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + SmeemTheme { + val navController = rememberNavController() + MyPageNavHost(navController = navController) + } + } + } +} \ No newline at end of file From b527422df8452c573ed9eacc1d3c73167fb4e24c Mon Sep 17 00:00:00 2001 From: taeheeL Date: Sun, 14 Apr 2024 21:18:19 +0900 Subject: [PATCH 005/184] =?UTF-8?q?build.gradle=20=EC=97=90=EB=9F=AC=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index cc32a28e..8af0dff3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -201,6 +201,9 @@ dependencies { // Compose Material Design 3 implementation(libs.androidx.compose.material3) + // lifecycle + implementation(libs.androidx.lifecycle.runtime.compose) + // Compose navigation implementation(libs.androidx.navigation.compose) From ac7169094ac7c7367b27876d4ffd6be1b552a7ac Mon Sep 17 00:00:00 2001 From: HaeTi Date: Thu, 4 Apr 2024 18:20:38 +0900 Subject: [PATCH 006/184] =?UTF-8?q?compose=20navigation=20=EC=9D=98?= =?UTF-8?q?=EC=A1=B4=EC=84=B1=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8af0dff3..cb2f85fc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -210,9 +210,6 @@ dependencies { // hilt navigation compose implementation(libs.androidx.hilt.navigation.compose) - // Compose navigation - implementation(libs.androidx.navigation.compose) - // Optional - Integration with activities implementation(libs.androidx.activity.compose) // Optional - Integration with ViewModels From 9df5ef246bb2020c97052a030975301d6893f132 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 16 Apr 2024 00:22:31 +0900 Subject: [PATCH 007/184] =?UTF-8?q?=EC=84=B1=EA=B3=BC=EC=9A=94=EC=95=BD=20?= =?UTF-8?q?TopAppBar=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/MyPageTopAppBars.kt | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt new file mode 100644 index 00000000..33df2f7d --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt @@ -0,0 +1,73 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.CenterAlignedTopAppBar +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +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.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.R +import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.presentation.home.calendar.ui.theme.gray500 + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MySummaryTopAppBar( + onNavigationIconClick: () -> Unit = {}, + onSettingClick: () -> Unit = {} +) { + CenterAlignedTopAppBar( + modifier = Modifier + .fillMaxWidth(), + colors = TopAppBarDefaults.centerAlignedTopAppBarColors().copy( + containerColor = Color.White + ), + title = { + Text( + text = "성과 요약", + style = Typography.titleMedium + ) + }, + navigationIcon = { + IconButton( + modifier = Modifier.padding(start = 6.dp), + onClick = onNavigationIconClick + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + contentDescription = "Back" + ) + } + }, + actions = { + IconButton( + modifier = Modifier.padding(end = 16.dp), + onClick = onSettingClick + ) { + Text( + text = "설정", + style = Typography.bodyMedium.copy( + color = gray500, + fontWeight = FontWeight.SemiBold + ), + ) + } + } + ) +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun MySummaryTopAppBarPreview() { + MySummaryTopAppBar() +} \ No newline at end of file From 0a78fff988a1f9476ccbc937470fabda4c9082a1 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 16 Apr 2024 00:27:39 +0900 Subject: [PATCH 008/184] =?UTF-8?q?=EB=A7=88=EC=9D=B4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=84=A4=EC=A0=95=20=EB=B7=B0=20TopAppBar=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/MyPageTopAppBars.kt | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt index 33df2f7d..c2a85181 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt @@ -66,8 +66,58 @@ fun MySummaryTopAppBar( ) } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun SettingTopAppBar( + onNavigationIconClick: () -> Unit = {}, + onSettingClick: () -> Unit = {} +) { + CenterAlignedTopAppBar( + modifier = Modifier + .fillMaxWidth(), + colors = TopAppBarDefaults.centerAlignedTopAppBarColors().copy( + containerColor = Color.White + ), + title = { + Text( + text = "설정", + style = Typography.titleMedium + ) + }, + navigationIcon = { + IconButton( + modifier = Modifier.padding(start = 6.dp), + onClick = onNavigationIconClick + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + contentDescription = "Back" + ) + } + }, + actions = { + IconButton( + modifier = Modifier.padding(end = 6.dp), + onClick = onSettingClick + ) { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_menu_more), + contentDescription = "More" + ) + } + } + ) +} + + @Preview(showBackground = true, showSystemUi = true) @Composable fun MySummaryTopAppBarPreview() { MySummaryTopAppBar() +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun SettingTopAppBarPreview() { + SettingTopAppBar() } \ No newline at end of file From 62ca3dfe3d07dd92782133b2063a3d42d3856e01 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 16 Apr 2024 00:30:00 +0900 Subject: [PATCH 009/184] =?UTF-8?q?=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20?= =?UTF-8?q?TopAppBar=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/MyPageTopAppBars.kt | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt index c2a85181..8cbb0300 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt @@ -70,7 +70,7 @@ fun MySummaryTopAppBar( @Composable fun SettingTopAppBar( onNavigationIconClick: () -> Unit = {}, - onSettingClick: () -> Unit = {} + onMoreClick: () -> Unit = {} ) { CenterAlignedTopAppBar( modifier = Modifier @@ -98,7 +98,7 @@ fun SettingTopAppBar( actions = { IconButton( modifier = Modifier.padding(end = 6.dp), - onClick = onSettingClick + onClick = onMoreClick ) { Icon( imageVector = ImageVector.vectorResource(R.drawable.ic_menu_more), @@ -109,6 +109,32 @@ fun SettingTopAppBar( ) } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun OnlyBackArrowTopAppBar( + onNavigationIconClick: () -> Unit = {}, +) { + CenterAlignedTopAppBar( + modifier = Modifier + .fillMaxWidth(), + colors = TopAppBarDefaults.centerAlignedTopAppBarColors().copy( + containerColor = Color.White + ), + title = {}, + navigationIcon = { + IconButton( + modifier = Modifier.padding(start = 6.dp), + onClick = onNavigationIconClick + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + contentDescription = "Back" + ) + } + }, + ) +} + @Preview(showBackground = true, showSystemUi = true) @Composable @@ -120,4 +146,10 @@ fun MySummaryTopAppBarPreview() { @Composable fun SettingTopAppBarPreview() { SettingTopAppBar() +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun OnlyBackArrowTopAppBarPreview() { + OnlyBackArrowTopAppBar() } \ No newline at end of file From 9f0d4c8e8885acf40930779ca31c244b12cf5b3e Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 16 Apr 2024 02:21:19 +0900 Subject: [PATCH 010/184] =?UTF-8?q?=EB=8D=94=EB=B3=B4=EA=B8=B0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/smeem/presentation/mypage/Const.kt | 1 + .../presentation/mypage/more/MoreScreen.kt | 25 +++++++++++++++++++ .../mypage/navigation/MyPageScreen.kt | 2 ++ 3 files changed, 28 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt index 5bbdf965..bd0448ff 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt @@ -2,3 +2,4 @@ package com.sopt.smeem.presentation.mypage const val MY_SUMMARY = "MyPage" const val SETTING = "Setting" +const val MORE = "More" diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt new file mode 100644 index 00000000..666c7509 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt @@ -0,0 +1,25 @@ +package com.sopt.smeem.presentation.mypage.more + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.navigation.NavController + +@Composable +fun MoreScreen( + navController: NavController, + modifier: Modifier +) { + Column( + modifier = modifier.fillMaxSize(), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Text(text = "더보기 화면이다") + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt index 3e895674..40f856be 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt @@ -1,9 +1,11 @@ package com.sopt.smeem.presentation.mypage.navigation +import com.sopt.smeem.presentation.mypage.MORE import com.sopt.smeem.presentation.mypage.MY_SUMMARY import com.sopt.smeem.presentation.mypage.SETTING sealed class MyPageScreen(val route: String) { data object MySummary : MyPageScreen(MY_SUMMARY) data object Setting : MyPageScreen(SETTING) + data object More : MyPageScreen(MORE) } \ No newline at end of file From 4f594b1b519bc4fefd2e63a12956fce94a595bba Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 16 Apr 2024 02:21:39 +0900 Subject: [PATCH 011/184] =?UTF-8?q?=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 --- .../mypage/navigation/MyPageNavHost.kt | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt index a0011314..9279d150 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt @@ -5,12 +5,18 @@ import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState +import com.sopt.smeem.presentation.mypage.TempMyPageActivity +import com.sopt.smeem.presentation.mypage.components.MySummaryTopAppBar +import com.sopt.smeem.presentation.mypage.components.OnlyBackArrowTopAppBar +import com.sopt.smeem.presentation.mypage.components.SettingTopAppBar +import com.sopt.smeem.presentation.mypage.more.MoreScreen import com.sopt.smeem.presentation.mypage.mysummary.MySummaryScreen import com.sopt.smeem.presentation.mypage.setting.SettingScreen @@ -20,15 +26,41 @@ fun MyPageNavHost( ) { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentRoute = navBackStackEntry?.destination?.route + val context = LocalContext.current Scaffold( topBar = { - // TopAppBar + when (currentRoute) { + MyPageScreen.MySummary.route -> MySummaryTopAppBar( + onNavigationIconClick = { if (context is TempMyPageActivity) context.finish() }, + onSettingClick = { + navController.navigate(MyPageScreen.Setting.route) { + launchSingleTop = true + restoreState = true + } + } + ) + + MyPageScreen.Setting.route -> SettingTopAppBar( + onNavigationIconClick = { navController.popBackStack() }, + onMoreClick = { + navController.navigate(MyPageScreen.More.route) { + launchSingleTop = true + restoreState = true + } + } + ) + + MyPageScreen.More.route -> OnlyBackArrowTopAppBar( + onNavigationIconClick = { navController.popBackStack() } + ) + } } ) { NavHost(navController = navController, startDestination = MyPageScreen.MySummary.route) { addMySummary(navController = navController, modifier = Modifier.padding(it)) addSetting(navController = navController, modifier = Modifier.padding(it)) + addMore(navController = navController, modifier = Modifier.padding(it)) } } } @@ -49,4 +81,13 @@ private fun NavGraphBuilder.addSetting(navController: NavController, modifier: M modifier = modifier ) } +} + +private fun NavGraphBuilder.addMore(navController: NavController, modifier: Modifier) { + composable(route = MyPageScreen.More.route) { + MoreScreen( + navController = navController, + modifier = modifier + ) + } } \ No newline at end of file From e38930ca639a082f4e0998f0007d7e0a9895f5f0 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 01:23:35 +0900 Subject: [PATCH 012/184] =?UTF-8?q?SmeemContents=20=EA=B5=AC=ED=98=84=20(T?= =?UTF-8?q?itle=20+=20content)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/SmeemContents.kt | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt new file mode 100644 index 00000000..552cc7ff --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt @@ -0,0 +1,30 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.util.VerticalSpacer + +@Composable +fun SmeemContents( + modifier: Modifier = Modifier, + title: String, + content: @Composable () -> Unit +) { + Column( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 18.dp) + ) { + Text(text = title, style = Typography.titleLarge) + + VerticalSpacer(height = 12.dp) + + content() + } +} \ No newline at end of file From be181b51a783a254c530b98be557e817333fba11 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 01:23:51 +0900 Subject: [PATCH 013/184] =?UTF-8?q?=EB=82=98=EC=9D=98=20=EC=8A=A4=EB=B0=88?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/smeem/domain/model/mypage/MySmeem.kt | 8 ++ .../presentation/mypage/components/MySmeem.kt | 104 ++++++++++++++++++ .../mypage/mysummary/MySummaryScreen.kt | 35 +++--- app/src/main/res/values/strings.xml | 3 + 4 files changed, 133 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/domain/model/mypage/MySmeem.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeem.kt diff --git a/app/src/main/java/com/sopt/smeem/domain/model/mypage/MySmeem.kt b/app/src/main/java/com/sopt/smeem/domain/model/mypage/MySmeem.kt new file mode 100644 index 00000000..c557e246 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/model/mypage/MySmeem.kt @@ -0,0 +1,8 @@ +package com.sopt.smeem.domain.model.mypage + +data class MySmeem( + val visitDays: Int, + val diaryCount: Int, + val diaryComboCount: Int, + val badgeCount: Int +) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeem.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeem.kt new file mode 100644 index 00000000..fbdcab98 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeem.kt @@ -0,0 +1,104 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +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.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.R +import com.sopt.smeem.domain.model.mypage.MySmeem +import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 +import com.sopt.smeem.util.VerticalSpacer + +@Composable +fun MySmeem( + modifier: Modifier = Modifier, + mySmeem: MySmeem +) { + SmeemContents( + modifier = modifier.padding(vertical = 18.dp), + title = stringResource(R.string.my_smeem) + ) { + Card( + modifier = modifier.fillMaxWidth(), + colors = CardDefaults.cardColors().copy( + containerColor = Color.White + ), + shape = RoundedCornerShape(12.dp), + border = BorderStroke(1.dp, gray100) + ) { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly + ) { + MySmeemContent( + count = mySmeem.visitDays, + title = "방문일" + ) + MySmeemContent( + count = mySmeem.diaryCount, + title = "총 일기" + ) + MySmeemContent( + count = mySmeem.diaryComboCount, + title = "연속일기" + ) + MySmeemContent( + count = mySmeem.badgeCount, + title = "배지" + ) + } + + } + } +} + +@Composable +fun MySmeemContent( + count: Int, + title: String +) { + Column( + modifier = Modifier.padding(horizontal = 10.dp, vertical = 18.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Text(text = count.toString(), style = Typography.titleMedium) + VerticalSpacer(height = 6.dp) + Text(text = title, style = Typography.labelLarge) + } +} + +@Preview(showBackground = true) +@Composable +fun MySmeemContentPreview() { + MySmeemContent( + count = 23, + title = "방문일" + ) +} + +@Preview(showBackground = true, showSystemUi = true, widthDp = 360, heightDp = 800) +@Composable +fun MySmeemPreview() { + MySmeem( + mySmeem = MySmeem( + visitDays = 23, + diaryCount = 19, + diaryComboCount = 3, + badgeCount = 10 + ) + ) +} diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt index 75e29361..32eaab41 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt @@ -1,37 +1,38 @@ package com.sopt.smeem.presentation.mypage.mysummary -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.Button -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp +import androidx.compose.ui.tooling.preview.Preview import androidx.navigation.NavController -import com.sopt.smeem.presentation.mypage.SETTING -import com.sopt.smeem.util.VerticalSpacer +import androidx.navigation.compose.rememberNavController +import com.sopt.smeem.domain.model.mypage.MySmeem +import com.sopt.smeem.presentation.mypage.components.MySmeem @Composable fun MySummaryScreen( navController: NavController, modifier: Modifier ) { + val mockMySmeem = MySmeem( + visitDays = 23, + diaryCount = 19, + diaryComboCount = 3, + badgeCount = 10 + ) + Column( modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center ) { - Text(text = "성과요약 화면이다") - VerticalSpacer(height = 50.dp) - Button(onClick = { - navController.navigate(SETTING) { - launchSingleTop = true - restoreState = true - } - }) { - Text(text = "설정 화면으로 이동한다") - } + MySmeem(mySmeem = mockMySmeem) } +} + +@Preview(showSystemUi = true, showBackground = true) +@Composable +fun MySummaryScreenPreview() { + MySummaryScreen(navController = rememberNavController(), modifier = Modifier) } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index efa38147..f09ad856 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -71,4 +71,7 @@ https://smeem.notion.site/793bae40ccd14654828b68ee41ac51b6?pvs=4 https://smeem.notion.site/334e225bb69b45c28f31fe363ca9f25e?pvs=4 SmeemCalendar + + + 나의 스밈 \ No newline at end of file From a686d1ee5b06be480a93db89ad4c18f4f6a6d8de Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 01:33:46 +0900 Subject: [PATCH 014/184] =?UTF-8?q?MySmeem=20=EB=84=A4=EC=9D=B4=EB=B0=8D?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/{MySmeem.kt => MySmeemCard.kt} | 4 ++-- .../smeem/presentation/mypage/mysummary/MySummaryScreen.kt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename app/src/main/java/com/sopt/smeem/presentation/mypage/components/{MySmeem.kt => MySmeemCard.kt} (98%) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeem.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt similarity index 98% rename from app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeem.kt rename to app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt index fbdcab98..fd98ac4f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeem.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt @@ -24,7 +24,7 @@ import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 import com.sopt.smeem.util.VerticalSpacer @Composable -fun MySmeem( +fun MySmeemCard( modifier: Modifier = Modifier, mySmeem: MySmeem ) { @@ -93,7 +93,7 @@ fun MySmeemContentPreview() { @Preview(showBackground = true, showSystemUi = true, widthDp = 360, heightDp = 800) @Composable fun MySmeemPreview() { - MySmeem( + MySmeemCard( mySmeem = MySmeem( visitDays = 23, diaryCount = 19, diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt index 32eaab41..de69897b 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.sopt.smeem.domain.model.mypage.MySmeem -import com.sopt.smeem.presentation.mypage.components.MySmeem +import com.sopt.smeem.presentation.mypage.components.MySmeemCard @Composable fun MySummaryScreen( @@ -27,7 +27,7 @@ fun MySummaryScreen( modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { - MySmeem(mySmeem = mockMySmeem) + MySmeemCard(mySmeem = mockMySmeem) } } From 6314de95b55e04a16fb897a6133c3392a479f992 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 01:53:04 +0900 Subject: [PATCH 015/184] =?UTF-8?q?MySmeemContent=20=EA=B8=80=EC=9E=90?= =?UTF-8?q?=EC=83=89=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/mypage/components/MySmeemCard.kt | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt index fd98ac4f..1b61329c 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt @@ -33,11 +33,11 @@ fun MySmeemCard( title = stringResource(R.string.my_smeem) ) { Card( - modifier = modifier.fillMaxWidth(), + modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors().copy( containerColor = Color.White ), - shape = RoundedCornerShape(12.dp), + shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, gray100) ) { Row( @@ -75,9 +75,14 @@ fun MySmeemContent( modifier = Modifier.padding(horizontal = 10.dp, vertical = 18.dp), horizontalAlignment = Alignment.CenterHorizontally ) { - Text(text = count.toString(), style = Typography.titleMedium) + Text( + text = count.toString(), + style = Typography.titleMedium, color = Color.Black + ) VerticalSpacer(height = 6.dp) - Text(text = title, style = Typography.labelLarge) + Text( + text = title, style = Typography.labelLarge, color = Color.Black + ) } } From a49b79138e48a639c946ce72977718df2ec9cabb Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 03:07:07 +0900 Subject: [PATCH 016/184] =?UTF-8?q?dash=20border=20=ED=99=95=EC=9E=A5?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/sopt/smeem/util/ModifierExt.kt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/util/ModifierExt.kt diff --git a/app/src/main/java/com/sopt/smeem/util/ModifierExt.kt b/app/src/main/java/com/sopt/smeem/util/ModifierExt.kt new file mode 100644 index 00000000..b7e73be9 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/util/ModifierExt.kt @@ -0,0 +1,26 @@ +package com.sopt.smeem.util + +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.PathEffect +import androidx.compose.ui.graphics.drawscope.Stroke + +fun Modifier.dashedBorder( + borderWidth: Float, + color: Color, + dashLength: Float, + spaceLength: Float +): Modifier { + return this.drawWithContent { + drawContent() + + val pathEffect = PathEffect.dashPathEffect(floatArrayOf(dashLength, spaceLength), 0f) + + drawCircle( + color = color, + radius = size.minDimension / 2 - borderWidth / 2, + style = Stroke(width = borderWidth, pathEffect = pathEffect) + ) + } +} From cf62d6d2566806a198785a754b1002a6e7f8911d Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 03:07:33 +0900 Subject: [PATCH 017/184] =?UTF-8?q?MySmeemCard=20string=20=EC=B6=94?= =?UTF-8?q?=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../smeem/presentation/mypage/components/MySmeemCard.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt index 1b61329c..a6300c9d 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt @@ -46,19 +46,19 @@ fun MySmeemCard( ) { MySmeemContent( count = mySmeem.visitDays, - title = "방문일" + title = stringResource(R.string.my_plan_visit_days) ) MySmeemContent( count = mySmeem.diaryCount, - title = "총 일기" + title = stringResource(R.string.my_plan_entire_diary) ) MySmeemContent( count = mySmeem.diaryComboCount, - title = "연속일기" + title = stringResource(R.string.my_plan_continuity_diary) ) MySmeemContent( count = mySmeem.badgeCount, - title = "배지" + title = stringResource(R.string.my_plan_badge) ) } From 1972132d4d82bebbb2bbcdc5f75915d7d4938549 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 03:13:53 +0900 Subject: [PATCH 018/184] =?UTF-8?q?MyPlanCard=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/smeem/domain/model/mypage/MyPlan.kt | 8 + .../mypage/components/MyPlanCard.kt | 162 ++++++++++++++++++ .../mypage/mysummary/MySummaryScreen.kt | 11 ++ app/src/main/res/values/strings.xml | 6 + 4 files changed, 187 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/domain/model/mypage/MyPlan.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt diff --git a/app/src/main/java/com/sopt/smeem/domain/model/mypage/MyPlan.kt b/app/src/main/java/com/sopt/smeem/domain/model/mypage/MyPlan.kt new file mode 100644 index 00000000..733d69e0 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/model/mypage/MyPlan.kt @@ -0,0 +1,8 @@ +package com.sopt.smeem.domain.model.mypage + +data class MyPlan( + val plan: String, + val goal: String, + val clearedCount: Int, + val clearCount: Int +) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt new file mode 100644 index 00000000..e12e3b27 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt @@ -0,0 +1,162 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +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.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.R +import com.sopt.smeem.domain.model.mypage.MyPlan +import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 +import com.sopt.smeem.presentation.home.calendar.ui.theme.gray600 +import com.sopt.smeem.presentation.home.calendar.ui.theme.point +import com.sopt.smeem.util.VerticalSpacer +import com.sopt.smeem.util.dashedBorder + +@Composable +fun MyPlanCard( + modifier: Modifier = Modifier, + myPlan: MyPlan? +) { + SmeemContents( + modifier = modifier.padding(top = 26.dp), + title = stringResource(R.string.my_plan) + ) { + Card( + modifier = Modifier.fillMaxWidth(), + colors = CardDefaults.cardColors().copy( + containerColor = Color.White + ), + shape = RoundedCornerShape(16.dp), + border = BorderStroke(1.dp, gray100) + ) { + if (myPlan == null) { + // TODO : 노 플랜 카드 + } else { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 18.dp, horizontal = 20.dp) + ) { + Text( + text = myPlan.plan, + style = Typography.titleMedium, + color = Color.Black + ) + + VerticalSpacer(height = 4.dp) + + Text( + text = myPlan.goal, + style = Typography.labelLarge, + color = Color.Black + ) + + VerticalSpacer(height = 16.dp) + + MyPlanClearedDots( + clearedCount = myPlan.clearedCount, + clearCount = myPlan.clearCount + ) + } + } + } + } + +} + +@Composable +fun MyPlanDot( + number: Int, + isCleared: Boolean +) { + + Card( + colors = CardDefaults.cardColors().copy( + containerColor = if (isCleared) point else Color.White + ), + shape = RoundedCornerShape(50), + modifier = Modifier + .size(20.dp) + .then( + if (!isCleared) Modifier.dashedBorder(1f, gray600, 5f, 5f) else Modifier + ) + ) { + Box( + contentAlignment = Alignment.Center, + modifier = Modifier.fillMaxSize() + ) { + Text( + modifier = Modifier.padding(top = 3.dp, bottom = 3.dp, start = 5.dp, end = 6.dp), + text = number.toString(), + style = Typography.labelSmall.copy(fontWeight = FontWeight.SemiBold), + color = if (isCleared) Color.White else gray600, + ) + } + } +} + +@Composable +fun MyPlanClearedDots( + clearedCount: Int, + clearCount: Int +) { + LazyRow(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { + itemsIndexed(List(clearCount) { it }) { index, _ -> + MyPlanDot( + number = index + 1, + isCleared = index < clearedCount + ) + } + } +} + +@Preview(showBackground = true) +@Composable +fun MyPlanClearedDotPreview() { + MyPlanDot( + number = 1, + isCleared = true + ) +} + +@Preview(showBackground = true) +@Composable +fun MyPlanNotClearedDotPreview() { + MyPlanDot( + number = 3, + isCleared = false + ) +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun MyPlanCardPreview() { + MyPlanCard( + myPlan = MyPlan( + plan = "매일 일기 작성하기", + goal = "유창한 비즈니스 영어", + clearedCount = 3, + clearCount = 7 + ) + ) +} + diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt index de69897b..38bdaa37 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt @@ -8,7 +8,9 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController +import com.sopt.smeem.domain.model.mypage.MyPlan import com.sopt.smeem.domain.model.mypage.MySmeem +import com.sopt.smeem.presentation.mypage.components.MyPlanCard import com.sopt.smeem.presentation.mypage.components.MySmeemCard @Composable @@ -23,11 +25,20 @@ fun MySummaryScreen( badgeCount = 10 ) + val mockMyPlan = MyPlan( + plan = "매일 일기 작성하기", + goal = "유창한 비즈니스 영어", + clearedCount = 2, + clearCount = 7 + ) + Column( modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { MySmeemCard(mySmeem = mockMySmeem) + + MyPlanCard(myPlan = mockMyPlan) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f09ad856..295d9949 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -74,4 +74,10 @@ 나의 스밈 + 나의 플랜 + + 방문일 + 총 일기 + 연속일기 + 배지 \ No newline at end of file From 0b4c4cedc9e75e952fc32bf1c45b6f21510a6096 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Wed, 17 Apr 2024 03:17:14 +0900 Subject: [PATCH 019/184] padding -> Spacer --- .../sopt/smeem/presentation/mypage/components/MyPlanCard.kt | 2 +- .../smeem/presentation/mypage/components/MySmeemCard.kt | 2 +- .../smeem/presentation/mypage/mysummary/MySummaryScreen.kt | 6 ++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt index e12e3b27..506b99e9 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt @@ -37,7 +37,7 @@ fun MyPlanCard( myPlan: MyPlan? ) { SmeemContents( - modifier = modifier.padding(top = 26.dp), + modifier = modifier, title = stringResource(R.string.my_plan) ) { Card( diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt index a6300c9d..04be5fea 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt @@ -29,7 +29,7 @@ fun MySmeemCard( mySmeem: MySmeem ) { SmeemContents( - modifier = modifier.padding(vertical = 18.dp), + modifier = modifier, title = stringResource(R.string.my_smeem) ) { Card( diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt index 38bdaa37..48638731 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/mysummary/MySummaryScreen.kt @@ -6,12 +6,14 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.sopt.smeem.domain.model.mypage.MyPlan import com.sopt.smeem.domain.model.mypage.MySmeem import com.sopt.smeem.presentation.mypage.components.MyPlanCard import com.sopt.smeem.presentation.mypage.components.MySmeemCard +import com.sopt.smeem.util.VerticalSpacer @Composable fun MySummaryScreen( @@ -36,8 +38,12 @@ fun MySummaryScreen( modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { + VerticalSpacer(height = 18.dp) + MySmeemCard(mySmeem = mockMySmeem) + VerticalSpacer(height = 44.dp) + MyPlanCard(myPlan = mockMyPlan) } } From b0bb59b076481cc366d55cc6ec4531dfb5cba3f1 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 19 Apr 2024 03:57:06 +0900 Subject: [PATCH 020/184] =?UTF-8?q?SmeemCard,=20EditButton=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/SmeemCard.kt | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt new file mode 100644 index 00000000..759de2b7 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt @@ -0,0 +1,86 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Card +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.R +import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.presentation.home.calendar.ui.theme.black +import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 +import com.sopt.smeem.presentation.home.calendar.ui.theme.point + +@Composable +fun SmeemCard( + modifier: Modifier = Modifier, + text: String, + content: @Composable () -> Unit, +) { + Card( + modifier = modifier.fillMaxWidth(), + colors = CardDefaults.cardColors().copy( + containerColor = Color.White + ), + shape = RoundedCornerShape(10.dp), + border = BorderStroke(1.dp, gray100) + ) { + Row( + modifier = Modifier.padding(start = 20.dp), + ) { + Text( + text = text, + style = Typography.bodySmall, + color = black, + modifier = Modifier.padding(top = 17.dp, bottom = 18.dp) + ) + + Spacer(modifier = Modifier.weight(1f)) + + content() + } + } +} + +@Composable +fun EditButton( + action: () -> Unit +) { + Button( + onClick = action, + colors = ButtonDefaults.buttonColors().copy( + containerColor = Color.White + ), + contentPadding = PaddingValues(0.dp), + ) { + Text( + text = stringResource(R.string.smeem_card_edit), + style = Typography.labelMedium, + color = point, + modifier = Modifier.padding(start = 20.dp, end = 20.dp, top = 18.dp, bottom = 19.dp) + ) + } +} + +@Composable +@Preview(showBackground = true, showSystemUi = true) +fun SmeemCardPreview() { + SmeemCard( + text = "닉네임", + ) { + EditButton(action = {}) + } +} \ No newline at end of file From dd2fcd6ec4e74118e87904c4bdc085503787c24b Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 19 Apr 2024 03:57:22 +0900 Subject: [PATCH 021/184] =?UTF-8?q?=EB=8B=89=EB=84=A4=EC=9E=84=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20=EC=B9=B4=EB=93=9C=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/ChangeNickNameCard.kt | 31 +++++++++++++++++++ app/src/main/res/values/strings.xml | 3 ++ 2 files changed, 34 insertions(+) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeNickNameCard.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeNickNameCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeNickNameCard.kt new file mode 100644 index 00000000..e3de2709 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeNickNameCard.kt @@ -0,0 +1,31 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import com.sopt.smeem.R + +@Composable +fun ChangeNicknameCard( + nickname: String, + onEditClick: () -> Unit, +) { + SmeemContents(title = stringResource(R.string.change_nickname_card)) { + SmeemCard( + text = nickname, + ) { + EditButton { + onEditClick() + } + } + } +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun ChangeNickNameCardPreview() { + ChangeNicknameCard( + nickname = "닉네임", + onEditClick = {} + ) +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 295d9949..1cc1bd9a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -80,4 +80,7 @@ 총 일기 연속일기 배지 + + 수정하기 + 닉네임 변경 \ No newline at end of file From e284b94d7a0c05b20ae5fcb2410d483c9390cb6a Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 19 Apr 2024 04:18:13 +0900 Subject: [PATCH 022/184] =?UTF-8?q?=EB=82=98=EC=9D=98=20=ED=94=8C=EB=9E=9C?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EC=B9=B4=EB=93=9C=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/ChangeMyPlanCard.kt | 32 ++++++++++++++ .../mypage/setting/SettingScreen.kt | 43 +++++++++++-------- 2 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeMyPlanCard.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeMyPlanCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeMyPlanCard.kt new file mode 100644 index 00000000..3d34f842 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/ChangeMyPlanCard.kt @@ -0,0 +1,32 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import com.sopt.smeem.R + +@Composable +fun ChangeMyPlanCard( + myPlan: String, + onEditClick: () -> Unit, +) { + SmeemContents(title = stringResource(R.string.my_plan)) { + SmeemCard( + // TODO : arg로 받아온 값 넣어주기 + text = myPlan, + ) { + EditButton { + onEditClick() + } + } + } +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun ChangeMyPlanCardPreview() { + ChangeMyPlanCard( + myPlan = "주 3회 일기 작성하기", + onEditClick = {} + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt index 096b1b0d..5fa50b4e 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt @@ -1,17 +1,16 @@ package com.sopt.smeem.presentation.mypage.setting -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.Button -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController -import com.sopt.smeem.presentation.mypage.MY_SUMMARY -import com.sopt.smeem.presentation.mypage.SETTING +import androidx.navigation.compose.rememberNavController +import com.sopt.smeem.presentation.mypage.components.ChangeMyPlanCard +import com.sopt.smeem.presentation.mypage.components.ChangeNicknameCard import com.sopt.smeem.util.VerticalSpacer @Composable @@ -19,23 +18,29 @@ fun SettingScreen( navController: NavController, modifier: Modifier ) { + val mockNickname = "이태하이" + val mockMyPlan = "주 3회 일기 작성하기" + Column( modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center ) { - Text(text = "설정 화면이다") VerticalSpacer(height = 50.dp) - Button(onClick = { - navController.navigate(MY_SUMMARY) { - popUpTo(SETTING) { - saveState = true - } - launchSingleTop = true - restoreState = true - } - }) { - Text(text = "다시 성과 요약 화면으로 이동한다") - } + + ChangeNicknameCard(nickname = mockNickname, onEditClick = {}) + + VerticalSpacer(height = 28.dp) + + ChangeMyPlanCard(myPlan = mockMyPlan, onEditClick = {}) + + VerticalSpacer(height = 28.dp) + + } -} \ No newline at end of file +} + +@Preview(showSystemUi = true, showBackground = true) +@Composable +fun SettingScreenPreview() { + SettingScreen(navController = rememberNavController(), modifier = Modifier) +} From 3a33ddb2936ae039fef9727c57a7cb7aee592cb3 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 19 Apr 2024 04:33:56 +0900 Subject: [PATCH 023/184] =?UTF-8?q?=ED=95=99=EC=8A=B5=20=EC=96=B8=EC=96=B4?= =?UTF-8?q?=20=EC=B9=B4=EB=93=9C=20=EC=A0=9C=EC=9E=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/TargetLanguageCard.kt | 42 +++++++++++++++++++ .../mypage/setting/SettingScreen.kt | 3 +- app/src/main/res/values/strings.xml | 7 ++-- 3 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt new file mode 100644 index 00000000..0f046ac1 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt @@ -0,0 +1,42 @@ +package com.sopt.smeem.presentation.mypage.components + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.R +import com.sopt.smeem.presentation.home.calendar.ui.theme.point + +@Composable +fun TargetLanguageCard( + targetLanguage: String = stringResource(R.string.language_english), + onEditClick: () -> Unit, +) { + SmeemContents(title = stringResource(R.string.my_page_languages)) { + SmeemCard( + text = targetLanguage, + ) { + Icon( + painter = painterResource(id = R.drawable.ic_checked), + contentDescription = stringResource(R.string.edit_target_language), + tint = point, + modifier = Modifier + .padding(top = 7.dp, bottom = 7.dp, end = 14.dp) + .clickable { onEditClick() } + ) + } + } +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun TargetLanguageCardPreview() { + TargetLanguageCard( + onEditClick = {} + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt index 5fa50b4e..0a96ccc9 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt @@ -11,6 +11,7 @@ import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.sopt.smeem.presentation.mypage.components.ChangeMyPlanCard import com.sopt.smeem.presentation.mypage.components.ChangeNicknameCard +import com.sopt.smeem.presentation.mypage.components.TargetLanguageCard import com.sopt.smeem.util.VerticalSpacer @Composable @@ -35,7 +36,7 @@ fun SettingScreen( VerticalSpacer(height = 28.dp) - + TargetLanguageCard(onEditClick = {}) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1cc1bd9a..a2426a69 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -41,8 +41,6 @@ [필수] 위치기반 서비스 이용약관 동의 [선택] 마케팅 정보 활용 동의 내 배지 - 학습 언어 - 학습 알림 트레이닝 푸시알림 변경 완료 다음 @@ -54,7 +52,6 @@ 일기를 작성해주세요 :) 완전한 문장으로 한국어 일기를 작성하면, 더욱 정확한 힌트를 받을 수 있어요. 수정 완료 - English 한국어 오늘은 OPR을 공개한 날이었다. 안 떨릴 줄 알았는데 겁나 떨렸당. 사실 카페가 추웠어서 추워서 떠는 건지 긴장 돼서 떠는 건지 구분이 잘 안 갔다. 근데 사실 나는 다리 떠는 것도 습관이라 다리를 떨어서 몸이 떨린 걸 수도 있다. 오늘은 OPR을 공개한 날이었다. 안 떨릴 줄 알았는데 겁나 떨렸당. 사실 카페가 추웠어서 추워서 떠는 건지 긴장 돼서 떠는 건지 구분이 잘 안 갔다. 근데 사실 나는 다리 떠는 것도 습관이라 다리를 떨어서 몸이 떨린 걸 수도 있다. My Page @@ -83,4 +80,8 @@ 수정하기 닉네임 변경 + 학습 언어 + 학습 알림 + English + edit target language \ No newline at end of file From 865cf7a7b58a75ca901dc6662185c1d307bdd15d Mon Sep 17 00:00:00 2001 From: HaeTi Date: Fri, 19 Apr 2024 04:42:56 +0900 Subject: [PATCH 024/184] =?UTF-8?q?=ED=95=99=EC=8A=B5=20=EC=96=B8=EC=96=B4?= =?UTF-8?q?=EC=97=90=20noRippleClickable=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/mypage/components/TargetLanguageCard.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt index 0f046ac1..e1e73c0d 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt @@ -1,6 +1,5 @@ package com.sopt.smeem.presentation.mypage.components -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.padding import androidx.compose.material3.Icon import androidx.compose.runtime.Composable @@ -11,6 +10,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.presentation.home.calendar.ui.theme.point +import com.sopt.smeem.util.noRippleClickable @Composable fun TargetLanguageCard( @@ -27,7 +27,7 @@ fun TargetLanguageCard( tint = point, modifier = Modifier .padding(top = 7.dp, bottom = 7.dp, end = 14.dp) - .clickable { onEditClick() } + .noRippleClickable { onEditClick() } ) } } From da595699b5fc5e4fa2676cd2e37119aebca9d2e0 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Sat, 20 Apr 2024 12:15:13 +0900 Subject: [PATCH 025/184] =?UTF-8?q?theme=EC=9D=98=20color=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/MyPageTopAppBars.kt | 8 ++++---- .../presentation/mypage/components/MyPlanCard.kt | 13 +++++++------ .../presentation/mypage/components/MySmeemCard.kt | 12 ++++++++---- .../presentation/mypage/components/SmeemCard.kt | 6 +++--- .../presentation/mypage/components/SmeemContents.kt | 7 ++++++- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt index 8cbb0300..78637fc9 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt @@ -10,7 +10,6 @@ import androidx.compose.material3.Text 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.graphics.vector.ImageVector import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.font.FontWeight @@ -19,6 +18,7 @@ import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography import com.sopt.smeem.presentation.home.calendar.ui.theme.gray500 +import com.sopt.smeem.presentation.home.calendar.ui.theme.white @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -30,7 +30,7 @@ fun MySummaryTopAppBar( modifier = Modifier .fillMaxWidth(), colors = TopAppBarDefaults.centerAlignedTopAppBarColors().copy( - containerColor = Color.White + containerColor = white ), title = { Text( @@ -76,7 +76,7 @@ fun SettingTopAppBar( modifier = Modifier .fillMaxWidth(), colors = TopAppBarDefaults.centerAlignedTopAppBarColors().copy( - containerColor = Color.White + containerColor = white ), title = { Text( @@ -118,7 +118,7 @@ fun OnlyBackArrowTopAppBar( modifier = Modifier .fillMaxWidth(), colors = TopAppBarDefaults.centerAlignedTopAppBarColors().copy( - containerColor = Color.White + containerColor = white ), title = {}, navigationIcon = { diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt index 506b99e9..24c63097 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt @@ -17,7 +17,6 @@ import androidx.compose.material3.Text 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.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview @@ -25,9 +24,11 @@ import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.domain.model.mypage.MyPlan import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.presentation.home.calendar.ui.theme.black import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 import com.sopt.smeem.presentation.home.calendar.ui.theme.gray600 import com.sopt.smeem.presentation.home.calendar.ui.theme.point +import com.sopt.smeem.presentation.home.calendar.ui.theme.white import com.sopt.smeem.util.VerticalSpacer import com.sopt.smeem.util.dashedBorder @@ -43,7 +44,7 @@ fun MyPlanCard( Card( modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors().copy( - containerColor = Color.White + containerColor = white ), shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, gray100) @@ -59,7 +60,7 @@ fun MyPlanCard( Text( text = myPlan.plan, style = Typography.titleMedium, - color = Color.Black + color = black ) VerticalSpacer(height = 4.dp) @@ -67,7 +68,7 @@ fun MyPlanCard( Text( text = myPlan.goal, style = Typography.labelLarge, - color = Color.Black + color = black ) VerticalSpacer(height = 16.dp) @@ -91,7 +92,7 @@ fun MyPlanDot( Card( colors = CardDefaults.cardColors().copy( - containerColor = if (isCleared) point else Color.White + containerColor = if (isCleared) point else white ), shape = RoundedCornerShape(50), modifier = Modifier @@ -108,7 +109,7 @@ fun MyPlanDot( modifier = Modifier.padding(top = 3.dp, bottom = 3.dp, start = 5.dp, end = 6.dp), text = number.toString(), style = Typography.labelSmall.copy(fontWeight = FontWeight.SemiBold), - color = if (isCleared) Color.White else gray600, + color = if (isCleared) white else gray600, ) } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt index 04be5fea..e23644ff 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt @@ -13,14 +13,15 @@ import androidx.compose.material3.Text 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.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.domain.model.mypage.MySmeem import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.presentation.home.calendar.ui.theme.black import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 +import com.sopt.smeem.presentation.home.calendar.ui.theme.white import com.sopt.smeem.util.VerticalSpacer @Composable @@ -35,7 +36,7 @@ fun MySmeemCard( Card( modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors().copy( - containerColor = Color.White + containerColor = white ), shape = RoundedCornerShape(16.dp), border = BorderStroke(1.dp, gray100) @@ -77,11 +78,14 @@ fun MySmeemContent( ) { Text( text = count.toString(), - style = Typography.titleMedium, color = Color.Black + style = Typography.titleMedium, + color = black ) VerticalSpacer(height = 6.dp) Text( - text = title, style = Typography.labelLarge, color = Color.Black + text = title, + style = Typography.labelLarge, + color = black ) } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt index 759de2b7..1860a6fd 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt @@ -14,7 +14,6 @@ import androidx.compose.material3.CardDefaults import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -23,6 +22,7 @@ import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography import com.sopt.smeem.presentation.home.calendar.ui.theme.black import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 import com.sopt.smeem.presentation.home.calendar.ui.theme.point +import com.sopt.smeem.presentation.home.calendar.ui.theme.white @Composable fun SmeemCard( @@ -33,7 +33,7 @@ fun SmeemCard( Card( modifier = modifier.fillMaxWidth(), colors = CardDefaults.cardColors().copy( - containerColor = Color.White + containerColor = white ), shape = RoundedCornerShape(10.dp), border = BorderStroke(1.dp, gray100) @@ -62,7 +62,7 @@ fun EditButton( Button( onClick = action, colors = ButtonDefaults.buttonColors().copy( - containerColor = Color.White + containerColor = white ), contentPadding = PaddingValues(0.dp), ) { diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt index 552cc7ff..3c76e1c2 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography +import com.sopt.smeem.presentation.home.calendar.ui.theme.black import com.sopt.smeem.util.VerticalSpacer @Composable @@ -21,7 +22,11 @@ fun SmeemContents( .fillMaxWidth() .padding(horizontal = 18.dp) ) { - Text(text = title, style = Typography.titleLarge) + Text( + text = title, + style = Typography.titleLarge, + color = black + ) VerticalSpacer(height = 12.dp) From 0bdc1e1c2fe0bec6b4c23edd47570e877dac7340 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Sat, 20 Apr 2024 12:16:46 +0900 Subject: [PATCH 026/184] =?UTF-8?q?ui.theme=20presentation=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=ED=8F=B4=EB=8D=94=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/sopt/smeem/presentation/home/HomeActivity.kt | 2 +- .../presentation/home/calendar/SmeemCalendar.kt | 2 +- .../home/calendar/component/CalendarTitle.kt | 2 +- .../home/calendar/component/CalendarToggleSlider.kt | 2 +- .../presentation/home/calendar/component/DayItem.kt | 4 ++-- .../home/calendar/component/WeekLabel.kt | 2 +- .../smeem/presentation/mypage/TempMyPageActivity.kt | 2 +- .../mypage/components/MyPageTopAppBars.kt | 6 +++--- .../presentation/mypage/components/MyPlanCard.kt | 12 ++++++------ .../presentation/mypage/components/MySmeemCard.kt | 8 ++++---- .../presentation/mypage/components/SmeemCard.kt | 10 +++++----- .../presentation/mypage/components/SmeemContents.kt | 4 ++-- .../mypage/components/TargetLanguageCard.kt | 2 +- .../{home/calendar/ui => }/theme/Color.kt | 2 +- .../{home/calendar/ui => }/theme/Theme.kt | 2 +- .../{home/calendar/ui => }/theme/Type.kt | 2 +- 16 files changed, 32 insertions(+), 32 deletions(-) rename app/src/main/java/com/sopt/smeem/presentation/{home/calendar/ui => }/theme/Color.kt (87%) rename app/src/main/java/com/sopt/smeem/presentation/{home/calendar/ui => }/theme/Theme.kt (96%) rename app/src/main/java/com/sopt/smeem/presentation/{home/calendar/ui => }/theme/Type.kt (97%) diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt index ef131a7c..96fa7746 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt @@ -24,8 +24,8 @@ import com.sopt.smeem.presentation.home.WritingBottomSheet.Companion.TAG import com.sopt.smeem.presentation.home.calendar.SmeemCalendar import com.sopt.smeem.presentation.home.calendar.core.CalendarIntent import com.sopt.smeem.presentation.home.calendar.core.Period -import com.sopt.smeem.presentation.home.calendar.ui.theme.SmeemTheme import com.sopt.smeem.presentation.mypage.TempMyPageActivity +import com.sopt.smeem.presentation.theme.SmeemTheme import com.sopt.smeem.util.DateUtil import com.sopt.smeem.util.getWeekStartDate import com.sopt.smeem.util.setOnSingleClickListener diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt index 4d0feef6..afd35224 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt @@ -25,7 +25,7 @@ import com.sopt.smeem.presentation.home.calendar.component.WeekLabel import com.sopt.smeem.presentation.home.calendar.component.WeeklyCalendar import com.sopt.smeem.presentation.home.calendar.core.CalendarIntent import com.sopt.smeem.presentation.home.calendar.core.Period -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 +import com.sopt.smeem.presentation.theme.gray100 import com.sopt.smeem.util.getWeekStartDate import java.time.LocalDate import java.time.YearMonth diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt index d7c3a88d..69a80719 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt @@ -8,7 +8,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.home.calendar.ui.theme.SmeemTheme +import com.sopt.smeem.presentation.theme.SmeemTheme import java.time.YearMonth import java.time.format.DateTimeFormatter diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt index d4e91204..1129a620 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt @@ -10,7 +10,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray300 +import com.sopt.smeem.presentation.theme.gray300 @Composable fun CalendarToggleSlider( diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt index bdf0c282..358f21c6 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt @@ -20,8 +20,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.sopt.smeem.presentation.home.calendar.ui.theme.SmeemTheme -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray400 +import com.sopt.smeem.presentation.theme.SmeemTheme +import com.sopt.smeem.presentation.theme.gray400 import com.sopt.smeem.util.noRippleClickable import java.time.LocalDate diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt index 4626ede4..8085c434 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.home.calendar.ui.theme.SmeemTheme +import com.sopt.smeem.presentation.theme.SmeemTheme import java.time.DayOfWeek @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt index fa9a1940..78835918 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt @@ -4,8 +4,8 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.navigation.compose.rememberNavController -import com.sopt.smeem.presentation.home.calendar.ui.theme.SmeemTheme import com.sopt.smeem.presentation.mypage.navigation.MyPageNavHost +import com.sopt.smeem.presentation.theme.SmeemTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt index 78637fc9..38a457d8 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt @@ -16,9 +16,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R -import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray500 -import com.sopt.smeem.presentation.home.calendar.ui.theme.white +import com.sopt.smeem.presentation.theme.Typography +import com.sopt.smeem.presentation.theme.gray500 +import com.sopt.smeem.presentation.theme.white @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt index 24c63097..f4c85cf2 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt @@ -23,12 +23,12 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.domain.model.mypage.MyPlan -import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography -import com.sopt.smeem.presentation.home.calendar.ui.theme.black -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray600 -import com.sopt.smeem.presentation.home.calendar.ui.theme.point -import com.sopt.smeem.presentation.home.calendar.ui.theme.white +import com.sopt.smeem.presentation.theme.Typography +import com.sopt.smeem.presentation.theme.black +import com.sopt.smeem.presentation.theme.gray100 +import com.sopt.smeem.presentation.theme.gray600 +import com.sopt.smeem.presentation.theme.point +import com.sopt.smeem.presentation.theme.white import com.sopt.smeem.util.VerticalSpacer import com.sopt.smeem.util.dashedBorder diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt index e23644ff..d8f96212 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt @@ -18,10 +18,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.domain.model.mypage.MySmeem -import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography -import com.sopt.smeem.presentation.home.calendar.ui.theme.black -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 -import com.sopt.smeem.presentation.home.calendar.ui.theme.white +import com.sopt.smeem.presentation.theme.Typography +import com.sopt.smeem.presentation.theme.black +import com.sopt.smeem.presentation.theme.gray100 +import com.sopt.smeem.presentation.theme.white import com.sopt.smeem.util.VerticalSpacer @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt index 1860a6fd..b36933b7 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt @@ -18,11 +18,11 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R -import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography -import com.sopt.smeem.presentation.home.calendar.ui.theme.black -import com.sopt.smeem.presentation.home.calendar.ui.theme.gray100 -import com.sopt.smeem.presentation.home.calendar.ui.theme.point -import com.sopt.smeem.presentation.home.calendar.ui.theme.white +import com.sopt.smeem.presentation.theme.Typography +import com.sopt.smeem.presentation.theme.black +import com.sopt.smeem.presentation.theme.gray100 +import com.sopt.smeem.presentation.theme.point +import com.sopt.smeem.presentation.theme.white @Composable fun SmeemCard( diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt index 3c76e1c2..794817e3 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt @@ -7,8 +7,8 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.home.calendar.ui.theme.Typography -import com.sopt.smeem.presentation.home.calendar.ui.theme.black +import com.sopt.smeem.presentation.theme.Typography +import com.sopt.smeem.presentation.theme.black import com.sopt.smeem.util.VerticalSpacer @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt index e1e73c0d..8cb1eb2d 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R -import com.sopt.smeem.presentation.home.calendar.ui.theme.point +import com.sopt.smeem.presentation.theme.point import com.sopt.smeem.util.noRippleClickable @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Color.kt b/app/src/main/java/com/sopt/smeem/presentation/theme/Color.kt similarity index 87% rename from app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Color.kt rename to app/src/main/java/com/sopt/smeem/presentation/theme/Color.kt index 68fe32a8..4dfe4e13 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Color.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/theme/Color.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.presentation.home.calendar.ui.theme +package com.sopt.smeem.presentation.theme import androidx.compose.ui.graphics.Color diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Theme.kt b/app/src/main/java/com/sopt/smeem/presentation/theme/Theme.kt similarity index 96% rename from app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Theme.kt rename to app/src/main/java/com/sopt/smeem/presentation/theme/Theme.kt index 06f9cabe..867ad35f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Theme.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/theme/Theme.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.presentation.home.calendar.ui.theme +package com.sopt.smeem.presentation.theme import android.app.Activity import androidx.compose.foundation.isSystemInDarkTheme diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Type.kt b/app/src/main/java/com/sopt/smeem/presentation/theme/Type.kt similarity index 97% rename from app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Type.kt rename to app/src/main/java/com/sopt/smeem/presentation/theme/Type.kt index c0ff7337..32ca199a 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/ui/theme/Type.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/theme/Type.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.presentation.home.calendar.ui.theme +package com.sopt.smeem.presentation.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle From adef8f00019ea65ca05b2283dca362d5a8a4516b Mon Sep 17 00:00:00 2001 From: wateralsie Date: Sun, 14 Apr 2024 15:47:32 +0900 Subject: [PATCH 027/184] CalendarIntent -> CalendarState --- .../smeem/presentation/home/HomeActivity.kt | 8 ++++---- .../smeem/presentation/home/HomeViewModel.kt | 20 +++++++++---------- .../home/calendar/SmeemCalendar.kt | 20 +++++++++---------- .../home/calendar/core/CalendarIntent.kt | 15 -------------- .../home/calendar/core/CalendarState.kt | 15 ++++++++++++++ 5 files changed, 39 insertions(+), 39 deletions(-) delete mode 100644 app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarIntent.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarState.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt index 96fa7746..2375bb90 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt @@ -22,7 +22,7 @@ import com.sopt.smeem.presentation.EventVM import com.sopt.smeem.presentation.detail.DiaryDetailActivity import com.sopt.smeem.presentation.home.WritingBottomSheet.Companion.TAG import com.sopt.smeem.presentation.home.calendar.SmeemCalendar -import com.sopt.smeem.presentation.home.calendar.core.CalendarIntent +import com.sopt.smeem.presentation.home.calendar.core.CalendarState import com.sopt.smeem.presentation.home.calendar.core.Period import com.sopt.smeem.presentation.mypage.TempMyPageActivity import com.sopt.smeem.presentation.theme.SmeemTheme @@ -98,13 +98,13 @@ class HomeActivity : BindingActivity(R.layout.activity_home private fun initView(day: LocalDate) { lifecycleScope.launch { with(homeViewModel) { - onIntent( - CalendarIntent.LoadNextDates( + onStateChange( + CalendarState.LoadNextDates( startDate = day.minusWeeks(1).getWeekStartDate(), period = Period.WEEK, ), ) - onIntent(CalendarIntent.SelectDate(date = day)) + onStateChange(CalendarState.SelectDate(date = day)) updateWriteDiaryButtonVisibility() } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt index 455d4a13..df7abd4a 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt @@ -9,7 +9,7 @@ import com.sopt.smeem.domain.model.Date import com.sopt.smeem.domain.model.DiarySummary import com.sopt.smeem.domain.repository.DiaryRepository import com.sopt.smeem.event.AmplitudeEventType -import com.sopt.smeem.presentation.home.calendar.core.CalendarIntent +import com.sopt.smeem.presentation.home.calendar.core.CalendarState import com.sopt.smeem.presentation.home.calendar.core.Period import com.sopt.smeem.util.DateUtil import com.sopt.smeem.util.getNextDates @@ -119,9 +119,9 @@ class HomeViewModel @Inject constructor( } // calendar - fun onIntent(intent: CalendarIntent) { - when (intent) { - CalendarIntent.ExpandCalendar -> { + fun onStateChange(state: CalendarState) { + when (state) { + CalendarState.ExpandCalendar -> { calculateCalendarDates( startDate = currentMonth.value.minusMonths(1).atDay(FIRST), period = Period.MONTH, @@ -130,7 +130,7 @@ class HomeViewModel @Inject constructor( sendEvent(AmplitudeEventType.FULL_CALENDAR_APPEAR) } - CalendarIntent.CollapseCalendar -> { + CalendarState.CollapseCalendar -> { calculateCalendarDates( startDate = calculateWeeklyCalendarVisibleStartDay() .getWeekStartDate() @@ -140,14 +140,14 @@ class HomeViewModel @Inject constructor( _isCalendarExpanded.value = false } - is CalendarIntent.LoadNextDates -> { - calculateCalendarDates(intent.startDate, intent.period) + is CalendarState.LoadNextDates -> { + calculateCalendarDates(state.startDate, state.period) } - is CalendarIntent.SelectDate -> { + is CalendarState.SelectDate -> { viewModelScope.launch { - getDateDiary(intent.date) - _selectedDate.emit(intent.date) + getDateDiary(state.date) + _selectedDate.emit(state.date) } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt index afd35224..223761f1 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt @@ -23,7 +23,7 @@ import com.sopt.smeem.presentation.home.calendar.component.CalendarToggleSlider import com.sopt.smeem.presentation.home.calendar.component.MonthlyCalendar import com.sopt.smeem.presentation.home.calendar.component.WeekLabel import com.sopt.smeem.presentation.home.calendar.component.WeeklyCalendar -import com.sopt.smeem.presentation.home.calendar.core.CalendarIntent +import com.sopt.smeem.presentation.home.calendar.core.CalendarState import com.sopt.smeem.presentation.home.calendar.core.Period import com.sopt.smeem.presentation.theme.gray100 import com.sopt.smeem.util.getWeekStartDate @@ -46,7 +46,7 @@ fun SmeemCalendar( dateList = dateList.value, selectedDate = selectedDate.value, currentMonth = currentMonth.value, - onIntent = viewModel::onIntent, + onIntent = viewModel::onStateChange, isCalendarExpanded = isCalendarExpanded.value, onDayClick = {}, ) @@ -58,7 +58,7 @@ private fun SmeemCalendarImpl( dateList: Array>, selectedDate: LocalDate, currentMonth: YearMonth, - onIntent: (CalendarIntent) -> Unit, + onIntent: (CalendarState) -> Unit, isCalendarExpanded: Boolean, onDayClick: (LocalDate) -> Unit, ) { @@ -70,9 +70,9 @@ private fun SmeemCalendarImpl( detectDragGestures { change, dragAmount -> change.consume() if (dragAmount.y < 0) { - onIntent(CalendarIntent.CollapseCalendar) + onIntent(CalendarState.CollapseCalendar) } else if (dragAmount.y > 0) { - onIntent(CalendarIntent.ExpandCalendar) + onIntent(CalendarState.ExpandCalendar) } } }, @@ -89,14 +89,14 @@ private fun SmeemCalendarImpl( currentMonth = currentMonth, loadDatesForMonth = { yearMonth -> onIntent( - CalendarIntent.LoadNextDates( + CalendarState.LoadNextDates( startDate = yearMonth.atDay(1), period = Period.MONTH, ), ) }, onDayClick = { - onIntent(CalendarIntent.SelectDate(it)) + onIntent(CalendarState.SelectDate(it)) onDayClick(it) }, ) @@ -106,7 +106,7 @@ private fun SmeemCalendarImpl( selectedDate = selectedDate, loadNextWeek = { nextWeekDate -> onIntent( - CalendarIntent.LoadNextDates( + CalendarState.LoadNextDates( startDate = nextWeekDate, period = Period.WEEK, ), @@ -114,7 +114,7 @@ private fun SmeemCalendarImpl( }, loadPrevWeek = { endWeekDate -> onIntent( - CalendarIntent.LoadNextDates( + CalendarState.LoadNextDates( startDate = endWeekDate.minusDays( 1, ).getWeekStartDate(), @@ -123,7 +123,7 @@ private fun SmeemCalendarImpl( ) }, onDayClick = { - onIntent(CalendarIntent.SelectDate(it)) + onIntent(CalendarState.SelectDate(it)) onDayClick(it) }, ) diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarIntent.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarIntent.kt deleted file mode 100644 index da3ff07f..00000000 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarIntent.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.sopt.smeem.presentation.home.calendar.core - -import java.time.LocalDate - -sealed class CalendarIntent { - class LoadNextDates( - val startDate: LocalDate, - val period: Period = Period.WEEK - ) : CalendarIntent() - - class SelectDate(val date: LocalDate) : CalendarIntent() - - object ExpandCalendar : CalendarIntent() - object CollapseCalendar : CalendarIntent() -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarState.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarState.kt new file mode 100644 index 00000000..280f2605 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/core/CalendarState.kt @@ -0,0 +1,15 @@ +package com.sopt.smeem.presentation.home.calendar.core + +import java.time.LocalDate + +sealed class CalendarState { + class LoadNextDates( + val startDate: LocalDate, + val period: Period = Period.WEEK + ) : CalendarState() + + class SelectDate(val date: LocalDate) : CalendarState() + + object ExpandCalendar : CalendarState() + object CollapseCalendar : CalendarState() +} \ No newline at end of file From 976f8e712352e4943c53c529542098fea4d02b35 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Sun, 14 Apr 2024 16:46:20 +0900 Subject: [PATCH 028/184] =?UTF-8?q?HorizontalPager=EC=9D=98=20page=20count?= =?UTF-8?q?=20=EC=A6=9D=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/calendar/CalendarConstant.kt | 5 +++ .../home/calendar/component/CalendarPager.kt | 42 ++++++++++++------- .../calendar/component/MonthlyCalendar.kt | 2 + .../home/calendar/component/WeeklyCalendar.kt | 2 + .../main/java/com/sopt/smeem/util/DateUtil.kt | 28 ++++++++++++- 5 files changed, 62 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/home/calendar/CalendarConstant.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/CalendarConstant.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/CalendarConstant.kt new file mode 100644 index 00000000..06da1ab7 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/CalendarConstant.kt @@ -0,0 +1,5 @@ +package com.sopt.smeem.presentation.home.calendar + +object CalendarConstant { + val yearRange = IntRange(2000, 2050) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarPager.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarPager.kt index 68c67052..297b56ed 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarPager.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarPager.kt @@ -5,43 +5,53 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import com.sopt.smeem.domain.model.Date +import com.sopt.smeem.presentation.home.calendar.core.Period +import com.sopt.smeem.util.DateUtil import java.time.LocalDate @OptIn(ExperimentalFoundationApi::class) @Composable internal fun CalendarPager( + weekOrMonth: Period, dateList: Array>, loadNextDates: (date: LocalDate) -> Unit, loadPrevDates: (date: LocalDate) -> Unit, content: @Composable (currentPage: Int) -> Unit, ) { - val initialized = rememberSaveable { mutableStateOf(false) } - val pagerState = rememberPagerState(initialPage = 1) { /*page count*/ 3 } + val isInitialized = rememberSaveable { mutableStateOf(false) } - LaunchedEffect(pagerState.currentPage) { - if (pagerState.currentPage == 0 && initialized.value) { - loadPrevDates(dateList[0][0].day) - pagerState.scrollToPage(1) - } + val initialPage = DateUtil.getCurrentDateIndex(weekOrMonth) - 1 + var currentPage by rememberSaveable { mutableStateOf(initialPage) } + val pagerState = rememberPagerState( + initialPage = initialPage + ) { /*page count*/ DateUtil.getBetweenCount(weekOrMonth) } - if (pagerState.currentPage == 2) { - loadNextDates(dateList[1][0].day) - pagerState.scrollToPage(1) + LaunchedEffect(pagerState.currentPage) { + if (isInitialized.value) { + if (currentPage > pagerState.currentPage) { + loadPrevDates(dateList[0][0].day) + } else if (currentPage < pagerState.currentPage) { + loadNextDates(dateList[1][0].day) + } + currentPage = pagerState.currentPage } } - LaunchedEffect(Unit) { - initialized.value = true + isInitialized.value = true } - HorizontalPager( state = pagerState, verticalAlignment = Alignment.Top, - ) { currentPage -> - content(currentPage) + ) { page -> + if (page in pagerState.currentPage - 1..pagerState.currentPage + 1) { + val calendarPage = page - pagerState.currentPage + 1 + content(calendarPage) + } } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/MonthlyCalendar.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/MonthlyCalendar.kt index 56d286f8..8fa8ea00 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/MonthlyCalendar.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/MonthlyCalendar.kt @@ -13,6 +13,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.dp import com.sopt.smeem.domain.model.Date +import com.sopt.smeem.presentation.home.calendar.core.Period import java.time.LocalDate import java.time.YearMonth @@ -29,6 +30,7 @@ internal fun MonthlyCalendar( Box { CalendarPager( + weekOrMonth = Period.MONTH, dateList = dateList, loadNextDates = { loadDatesForMonth(currentMonth) }, loadPrevDates = { loadDatesForMonth(currentMonth.minusMonths(2)) }, diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeeklyCalendar.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeeklyCalendar.kt index 28a7fad1..557b0f4e 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeeklyCalendar.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeeklyCalendar.kt @@ -12,6 +12,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.dp import com.sopt.smeem.domain.model.Date +import com.sopt.smeem.presentation.home.calendar.core.Period import java.time.LocalDate @Composable @@ -26,6 +27,7 @@ internal fun WeeklyCalendar( Box { // 전체를 감싸는 Box 추가 CalendarPager( + weekOrMonth = Period.WEEK, dateList = dateList, loadNextDates = loadNextWeek, loadPrevDates = loadPrevWeek, diff --git a/app/src/main/java/com/sopt/smeem/util/DateUtil.kt b/app/src/main/java/com/sopt/smeem/util/DateUtil.kt index 5f3eba9f..644a7a60 100644 --- a/app/src/main/java/com/sopt/smeem/util/DateUtil.kt +++ b/app/src/main/java/com/sopt/smeem/util/DateUtil.kt @@ -1,7 +1,10 @@ package com.sopt.smeem.util +import com.sopt.smeem.presentation.home.calendar.CalendarConstant.yearRange +import com.sopt.smeem.presentation.home.calendar.core.Period import java.time.LocalDate import java.time.LocalDateTime +import java.time.temporal.ChronoUnit import java.util.regex.Pattern object DateUtil { @@ -72,11 +75,34 @@ object DateUtil { fun gap(start: String, end: String): Int = asLocalDate(end).compareTo(asLocalDate(start)) + fun getBetweenCount( + weekOrMonth: Period, + startYear: Int = yearRange.first, + endYear: Int = yearRange.last + ): Int { + val start = LocalDate.of(startYear, 1, 1) + val end = LocalDate.of(endYear, 12, 31) + return when (weekOrMonth) { + Period.WEEK -> ChronoUnit.WEEKS.between(start, end).toInt() + Period.MONTH -> ChronoUnit.MONTHS.between(start, end).toInt() + } + } + + fun getCurrentDateIndex(weekOrMonth: Period, startYear: Int = yearRange.first): Int { + val start = LocalDate.of(startYear, 1, 1) + val today = LocalDate.now() + return when (weekOrMonth) { + Period.WEEK -> ChronoUnit.WEEKS.between(start, today).toInt() + Period.MONTH -> ChronoUnit.MONTHS.between(start, today).toInt() + } + } + object WithServer { fun asStringOnlyDate(now: LocalDate): String { val monthValue = if (now.monthValue < 10) "0${now.monthValue}" else now.monthValue.toString() - val dayValue = if(now.dayOfMonth < 10) "0${now.dayOfMonth}" else now.dayOfMonth.toString() + val dayValue = + if (now.dayOfMonth < 10) "0${now.dayOfMonth}" else now.dayOfMonth.toString() return "${now.year}-${monthValue}-${dayValue}" } From 791d97ec72679eee8570157cf2a6e23ac12b77d6 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 15:27:10 +0900 Subject: [PATCH 029/184] =?UTF-8?q?=EC=A0=9C=EB=AA=A9=EA=B3=BC=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B2=84=ED=8A=BC=EB=A7=8C=20?= =?UTF-8?q?=EC=9E=88=EB=8A=94=20TopBar=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../{ => topbar}/MyPageTopAppBars.kt | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) rename app/src/main/java/com/sopt/smeem/presentation/mypage/components/{ => topbar}/MyPageTopAppBars.kt (79%) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt similarity index 79% rename from app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt rename to app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt index 38a457d8..94cd6421 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPageTopAppBars.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.presentation.mypage.components +package com.sopt.smeem.presentation.mypage.components.topbar import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -11,6 +11,7 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview @@ -135,6 +136,38 @@ fun OnlyBackArrowTopAppBar( ) } +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun TitleTopAppbar( + onNavigationIconClick: () -> Unit = {}, + title: String +) { + CenterAlignedTopAppBar( + modifier = Modifier + .fillMaxWidth(), + colors = TopAppBarDefaults.centerAlignedTopAppBarColors().copy( + containerColor = white + ), + title = { + Text( + text = title, + style = Typography.titleMedium + ) + }, + navigationIcon = { + IconButton( + modifier = Modifier.padding(start = 6.dp), + onClick = onNavigationIconClick + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + contentDescription = "Back" + ) + } + }, + ) +} + @Preview(showBackground = true, showSystemUi = true) @Composable @@ -152,4 +185,10 @@ fun SettingTopAppBarPreview() { @Composable fun OnlyBackArrowTopAppBarPreview() { OnlyBackArrowTopAppBar() +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun TitleTopAppbarPreview() { + TitleTopAppbar(title = stringResource(R.string.my_page_change_nickname)) } \ No newline at end of file From 79fa7536d916b628888b67fbbea569dfa5041164 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 15:27:33 +0900 Subject: [PATCH 030/184] =?UTF-8?q?ChangeNicknameScreen=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=8F=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sopt/smeem/presentation/mypage/Const.kt | 1 + .../mypage/navigation/MyPageNavHost.kt | 32 +++++++++++++++++-- .../mypage/navigation/MyPageScreen.kt | 5 +++ .../mypage/setting/ChangeNicknameScreen.kt | 14 ++++++++ .../mypage/setting/SettingScreen.kt | 8 ++++- app/src/main/res/values/strings.xml | 1 + 6 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt index bd0448ff..7dac43ab 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt @@ -3,3 +3,4 @@ package com.sopt.smeem.presentation.mypage const val MY_SUMMARY = "MyPage" const val SETTING = "Setting" const val MORE = "More" +const val CHANGE_NICKNAME = "ChangeNickname" diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt index 9279d150..06fae072 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageNavHost.kt @@ -6,18 +6,24 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavHostController +import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.navArgument +import com.sopt.smeem.R import com.sopt.smeem.presentation.mypage.TempMyPageActivity -import com.sopt.smeem.presentation.mypage.components.MySummaryTopAppBar -import com.sopt.smeem.presentation.mypage.components.OnlyBackArrowTopAppBar -import com.sopt.smeem.presentation.mypage.components.SettingTopAppBar +import com.sopt.smeem.presentation.mypage.components.topbar.MySummaryTopAppBar +import com.sopt.smeem.presentation.mypage.components.topbar.OnlyBackArrowTopAppBar +import com.sopt.smeem.presentation.mypage.components.topbar.SettingTopAppBar +import com.sopt.smeem.presentation.mypage.components.topbar.TitleTopAppbar import com.sopt.smeem.presentation.mypage.more.MoreScreen import com.sopt.smeem.presentation.mypage.mysummary.MySummaryScreen +import com.sopt.smeem.presentation.mypage.setting.ChangeNicknameScreen import com.sopt.smeem.presentation.mypage.setting.SettingScreen @Composable @@ -54,6 +60,11 @@ fun MyPageNavHost( MyPageScreen.More.route -> OnlyBackArrowTopAppBar( onNavigationIconClick = { navController.popBackStack() } ) + + MyPageScreen.ChangeNickname.route -> TitleTopAppbar( + onNavigationIconClick = { navController.popBackStack() }, + title = stringResource(R.string.my_page_change_nickname) + ) } } ) { @@ -61,6 +72,7 @@ fun MyPageNavHost( addMySummary(navController = navController, modifier = Modifier.padding(it)) addSetting(navController = navController, modifier = Modifier.padding(it)) addMore(navController = navController, modifier = Modifier.padding(it)) + addChangeNickname(modifier = Modifier.padding(it)) } } } @@ -90,4 +102,18 @@ private fun NavGraphBuilder.addMore(navController: NavController, modifier: Modi modifier = modifier ) } +} + +private fun NavGraphBuilder.addChangeNickname(modifier: Modifier) { + composable( + route = MyPageScreen.ChangeNickname.route, + arguments = listOf(navArgument("nickname") { type = NavType.StringType }) + ) { backStackEntry -> + val nickname = backStackEntry.arguments?.getString("nickname") ?: "" + + ChangeNicknameScreen( + modifier = modifier, + nickname = nickname + ) + } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt index 40f856be..8a3c97e9 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/navigation/MyPageScreen.kt @@ -1,5 +1,6 @@ package com.sopt.smeem.presentation.mypage.navigation +import com.sopt.smeem.presentation.mypage.CHANGE_NICKNAME import com.sopt.smeem.presentation.mypage.MORE import com.sopt.smeem.presentation.mypage.MY_SUMMARY import com.sopt.smeem.presentation.mypage.SETTING @@ -8,4 +9,8 @@ sealed class MyPageScreen(val route: String) { data object MySummary : MyPageScreen(MY_SUMMARY) data object Setting : MyPageScreen(SETTING) data object More : MyPageScreen(MORE) + + data object ChangeNickname : MyPageScreen("$CHANGE_NICKNAME/{nickname}") { + fun createRoute(nickname: String): String = "$CHANGE_NICKNAME/$nickname" + } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt new file mode 100644 index 00000000..10dcfef0 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt @@ -0,0 +1,14 @@ +package com.sopt.smeem.presentation.mypage.setting + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +fun ChangeNicknameScreen( + modifier: Modifier = Modifier, + nickname: String +) { + Text(text = "ChangeNicknameScreen: $nickname", modifier = modifier) + +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt index 0a96ccc9..bf71bd6f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/SettingScreen.kt @@ -12,6 +12,7 @@ import androidx.navigation.compose.rememberNavController import com.sopt.smeem.presentation.mypage.components.ChangeMyPlanCard import com.sopt.smeem.presentation.mypage.components.ChangeNicknameCard import com.sopt.smeem.presentation.mypage.components.TargetLanguageCard +import com.sopt.smeem.presentation.mypage.navigation.MyPageScreen import com.sopt.smeem.util.VerticalSpacer @Composable @@ -28,7 +29,12 @@ fun SettingScreen( ) { VerticalSpacer(height = 50.dp) - ChangeNicknameCard(nickname = mockNickname, onEditClick = {}) + ChangeNicknameCard( + nickname = mockNickname, + onEditClick = { + navController.navigate(MyPageScreen.ChangeNickname.createRoute(mockNickname)) + } + ) VerticalSpacer(height = 28.dp) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a2426a69..38b0b16b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -84,4 +84,5 @@ 학습 알림 English edit target language + 닉네임 변경 \ No newline at end of file From 92401936d3f8f553fa4b2315289f942280717fc5 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 22:12:59 +0900 Subject: [PATCH 031/184] =?UTF-8?q?ui.theme=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=20=EC=9D=B4=EB=8F=99=20->=20compose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../smeem/presentation/{ => compose}/theme/Color.kt | 2 +- .../smeem/presentation/{ => compose}/theme/Theme.kt | 2 +- .../smeem/presentation/{ => compose}/theme/Type.kt | 2 +- .../com/sopt/smeem/presentation/home/HomeActivity.kt | 2 +- .../presentation/home/calendar/SmeemCalendar.kt | 2 +- .../home/calendar/component/CalendarTitle.kt | 2 +- .../home/calendar/component/CalendarToggleSlider.kt | 2 +- .../presentation/home/calendar/component/DayItem.kt | 4 ++-- .../home/calendar/component/WeekLabel.kt | 2 +- .../smeem/presentation/mypage/TempMyPageActivity.kt | 2 +- .../presentation/mypage/components/MyPlanCard.kt | 12 ++++++------ .../presentation/mypage/components/MySmeemCard.kt | 8 ++++---- .../presentation/mypage/components/SmeemCard.kt | 10 +++++----- .../presentation/mypage/components/SmeemContents.kt | 4 ++-- .../mypage/components/TargetLanguageCard.kt | 2 +- .../mypage/components/topbar/MyPageTopAppBars.kt | 6 +++--- 16 files changed, 32 insertions(+), 32 deletions(-) rename app/src/main/java/com/sopt/smeem/presentation/{ => compose}/theme/Color.kt (89%) rename app/src/main/java/com/sopt/smeem/presentation/{ => compose}/theme/Theme.kt (96%) rename app/src/main/java/com/sopt/smeem/presentation/{ => compose}/theme/Type.kt (98%) diff --git a/app/src/main/java/com/sopt/smeem/presentation/theme/Color.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/theme/Color.kt similarity index 89% rename from app/src/main/java/com/sopt/smeem/presentation/theme/Color.kt rename to app/src/main/java/com/sopt/smeem/presentation/compose/theme/Color.kt index 4dfe4e13..3388d333 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/theme/Color.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/theme/Color.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.presentation.theme +package com.sopt.smeem.presentation.compose.theme import androidx.compose.ui.graphics.Color diff --git a/app/src/main/java/com/sopt/smeem/presentation/theme/Theme.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/theme/Theme.kt similarity index 96% rename from app/src/main/java/com/sopt/smeem/presentation/theme/Theme.kt rename to app/src/main/java/com/sopt/smeem/presentation/compose/theme/Theme.kt index 867ad35f..095b1167 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/theme/Theme.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/theme/Theme.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.presentation.theme +package com.sopt.smeem.presentation.compose.theme import android.app.Activity import androidx.compose.foundation.isSystemInDarkTheme diff --git a/app/src/main/java/com/sopt/smeem/presentation/theme/Type.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/theme/Type.kt similarity index 98% rename from app/src/main/java/com/sopt/smeem/presentation/theme/Type.kt rename to app/src/main/java/com/sopt/smeem/presentation/compose/theme/Type.kt index 32ca199a..9b5c7b70 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/theme/Type.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/theme/Type.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.presentation.theme +package com.sopt.smeem.presentation.compose.theme import androidx.compose.material3.Typography import androidx.compose.ui.text.TextStyle diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt index 2375bb90..01ff27b8 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/HomeActivity.kt @@ -19,13 +19,13 @@ import com.sopt.smeem.domain.model.RetrievedBadge import com.sopt.smeem.event.AmplitudeEventType import com.sopt.smeem.presentation.BindingActivity import com.sopt.smeem.presentation.EventVM +import com.sopt.smeem.presentation.compose.theme.SmeemTheme import com.sopt.smeem.presentation.detail.DiaryDetailActivity import com.sopt.smeem.presentation.home.WritingBottomSheet.Companion.TAG import com.sopt.smeem.presentation.home.calendar.SmeemCalendar import com.sopt.smeem.presentation.home.calendar.core.CalendarState import com.sopt.smeem.presentation.home.calendar.core.Period import com.sopt.smeem.presentation.mypage.TempMyPageActivity -import com.sopt.smeem.presentation.theme.SmeemTheme import com.sopt.smeem.util.DateUtil import com.sopt.smeem.util.getWeekStartDate import com.sopt.smeem.util.setOnSingleClickListener diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt index 223761f1..7f20e828 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/SmeemCalendar.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.sopt.smeem.domain.model.Date +import com.sopt.smeem.presentation.compose.theme.gray100 import com.sopt.smeem.presentation.home.HomeViewModel import com.sopt.smeem.presentation.home.calendar.component.CalendarTitle import com.sopt.smeem.presentation.home.calendar.component.CalendarToggleSlider @@ -25,7 +26,6 @@ import com.sopt.smeem.presentation.home.calendar.component.WeekLabel import com.sopt.smeem.presentation.home.calendar.component.WeeklyCalendar import com.sopt.smeem.presentation.home.calendar.core.CalendarState import com.sopt.smeem.presentation.home.calendar.core.Period -import com.sopt.smeem.presentation.theme.gray100 import com.sopt.smeem.util.getWeekStartDate import java.time.LocalDate import java.time.YearMonth diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt index 69a80719..3a6616f1 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarTitle.kt @@ -8,7 +8,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.theme.SmeemTheme +import com.sopt.smeem.presentation.compose.theme.SmeemTheme import java.time.YearMonth import java.time.format.DateTimeFormatter diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt index 1129a620..873578af 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/CalendarToggleSlider.kt @@ -10,7 +10,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.theme.gray300 +import com.sopt.smeem.presentation.compose.theme.gray300 @Composable fun CalendarToggleSlider( diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt index 358f21c6..b769d07f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/DayItem.kt @@ -20,8 +20,8 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import com.sopt.smeem.presentation.theme.SmeemTheme -import com.sopt.smeem.presentation.theme.gray400 +import com.sopt.smeem.presentation.compose.theme.SmeemTheme +import com.sopt.smeem.presentation.compose.theme.gray400 import com.sopt.smeem.util.noRippleClickable import java.time.LocalDate diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt index 8085c434..3cc64579 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/calendar/component/WeekLabel.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.theme.SmeemTheme +import com.sopt.smeem.presentation.compose.theme.SmeemTheme import java.time.DayOfWeek @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt index 78835918..dd60d908 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/TempMyPageActivity.kt @@ -4,8 +4,8 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.navigation.compose.rememberNavController +import com.sopt.smeem.presentation.compose.theme.SmeemTheme import com.sopt.smeem.presentation.mypage.navigation.MyPageNavHost -import com.sopt.smeem.presentation.theme.SmeemTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt index f4c85cf2..148cb79d 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MyPlanCard.kt @@ -23,12 +23,12 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.domain.model.mypage.MyPlan -import com.sopt.smeem.presentation.theme.Typography -import com.sopt.smeem.presentation.theme.black -import com.sopt.smeem.presentation.theme.gray100 -import com.sopt.smeem.presentation.theme.gray600 -import com.sopt.smeem.presentation.theme.point -import com.sopt.smeem.presentation.theme.white +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.black +import com.sopt.smeem.presentation.compose.theme.gray100 +import com.sopt.smeem.presentation.compose.theme.gray600 +import com.sopt.smeem.presentation.compose.theme.point +import com.sopt.smeem.presentation.compose.theme.white import com.sopt.smeem.util.VerticalSpacer import com.sopt.smeem.util.dashedBorder diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt index d8f96212..22c4ea2b 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/MySmeemCard.kt @@ -18,10 +18,10 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R import com.sopt.smeem.domain.model.mypage.MySmeem -import com.sopt.smeem.presentation.theme.Typography -import com.sopt.smeem.presentation.theme.black -import com.sopt.smeem.presentation.theme.gray100 -import com.sopt.smeem.presentation.theme.white +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.black +import com.sopt.smeem.presentation.compose.theme.gray100 +import com.sopt.smeem.presentation.compose.theme.white import com.sopt.smeem.util.VerticalSpacer @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt index b36933b7..dbd52de1 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemCard.kt @@ -18,11 +18,11 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R -import com.sopt.smeem.presentation.theme.Typography -import com.sopt.smeem.presentation.theme.black -import com.sopt.smeem.presentation.theme.gray100 -import com.sopt.smeem.presentation.theme.point -import com.sopt.smeem.presentation.theme.white +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.black +import com.sopt.smeem.presentation.compose.theme.gray100 +import com.sopt.smeem.presentation.compose.theme.point +import com.sopt.smeem.presentation.compose.theme.white @Composable fun SmeemCard( diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt index 794817e3..74f36094 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/SmeemContents.kt @@ -7,8 +7,8 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.sopt.smeem.presentation.theme.Typography -import com.sopt.smeem.presentation.theme.black +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.black import com.sopt.smeem.util.VerticalSpacer @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt index 8cb1eb2d..941ad428 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/TargetLanguageCard.kt @@ -9,7 +9,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R -import com.sopt.smeem.presentation.theme.point +import com.sopt.smeem.presentation.compose.theme.point import com.sopt.smeem.util.noRippleClickable @Composable diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt index 94cd6421..89d23975 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt @@ -17,9 +17,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R -import com.sopt.smeem.presentation.theme.Typography -import com.sopt.smeem.presentation.theme.gray500 -import com.sopt.smeem.presentation.theme.white +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.gray500 +import com.sopt.smeem.presentation.compose.theme.white @OptIn(ExperimentalMaterial3Api::class) @Composable From 02587ff132fd88ac31f21b6d5c7a009e742a9619 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 23:10:21 +0900 Subject: [PATCH 032/184] =?UTF-8?q?SmeemTextField=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compose/components/SmeemTextField.kt | 52 +++++++++++++++++++ .../mypage/setting/ChangeNicknameScreen.kt | 35 ++++++++++++- 2 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt new file mode 100644 index 00000000..b62528b7 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt @@ -0,0 +1,52 @@ +package com.sopt.smeem.presentation.compose.components + +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.gray100 +import com.sopt.smeem.presentation.compose.theme.point + +// 공백이나 11자 초과시 버튼 비활성화 + +@Composable +fun SmeemTextField( + modifier: Modifier = Modifier, + text: String, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + onValueChange: (String) -> Unit +) { + BasicTextField( + value = text, + onValueChange = onValueChange, + singleLine = true, + keyboardOptions = KeyboardOptions( + keyboardType = keyboardOptions.keyboardType, + imeAction = ImeAction.Done + ), + modifier = modifier + .fillMaxWidth() + .border(width = 1.dp, color = gray100) + .padding(vertical = 19.dp, horizontal = 20.dp), + textStyle = Typography.headlineSmall.copy( + color = point + ) + + ) +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun SmeemTextFieldPreview() { + SmeemTextField( + text = "텍스트", + onValueChange = {} + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt index 10dcfef0..0c86c851 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt @@ -1,14 +1,45 @@ package com.sopt.smeem.presentation.mypage.setting -import androidx.compose.material3.Text +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.presentation.compose.components.SmeemTextField +import com.sopt.smeem.util.VerticalSpacer @Composable fun ChangeNicknameScreen( modifier: Modifier = Modifier, nickname: String ) { - Text(text = "ChangeNicknameScreen: $nickname", modifier = modifier) + var newNickName by rememberSaveable { mutableStateOf(nickname) } + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally + ) { + + VerticalSpacer(height = 14.dp) + + SmeemTextField( + text = newNickName, + onValueChange = { newNickName = it }, + modifier = Modifier.padding(horizontal = 18.dp) + ) + + } + +} + +@Composable +@Preview(showBackground = true, showSystemUi = true) +fun ChangeNicknameScreenPreview() { + ChangeNicknameScreen(nickname = "이태하이") } \ No newline at end of file From 3c2898e4c4a16c4bb19629f1947c59c591330631 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 23:14:32 +0900 Subject: [PATCH 033/184] =?UTF-8?q?=EA=B8=80=EC=9E=90=EC=88=98=20=EC=A0=9C?= =?UTF-8?q?=ED=95=9C=20caption=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/setting/ChangeNicknameScreen.kt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt index 0c86c851..0076e10f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt @@ -1,7 +1,11 @@ package com.sopt.smeem.presentation.mypage.setting import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -9,9 +13,14 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.sopt.smeem.R import com.sopt.smeem.presentation.compose.components.SmeemTextField +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.gray400 +import com.sopt.smeem.util.HorizontalSpacer import com.sopt.smeem.util.VerticalSpacer @Composable @@ -34,6 +43,21 @@ fun ChangeNicknameScreen( modifier = Modifier.padding(horizontal = 18.dp) ) + VerticalSpacer(height = 10.dp) + + Row(modifier = Modifier.fillMaxWidth()) { + Spacer(modifier = Modifier.weight(1f)) + + Text( + text = stringResource(id = R.string.entrance_nickname_caption), + style = Typography.labelSmall, + color = gray400, + ) + + HorizontalSpacer(width = 18.dp) + } + + } } From 6bf89cd1cf2a636d0c3b829787c51ecad45bd0c0 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 23:18:59 +0900 Subject: [PATCH 034/184] =?UTF-8?q?SmeemTextField=EC=97=90=20RoundCornerSh?= =?UTF-8?q?ape=20=EB=B6=80=EC=97=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../smeem/presentation/compose/components/SmeemTextField.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt index b62528b7..3816f248 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt @@ -3,6 +3,7 @@ package com.sopt.smeem.presentation.compose.components import androidx.compose.foundation.border import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Composable @@ -33,7 +34,7 @@ fun SmeemTextField( ), modifier = modifier .fillMaxWidth() - .border(width = 1.dp, color = gray100) + .border(width = 1.dp, color = gray100, shape = RoundedCornerShape(6.dp)) .padding(vertical = 19.dp, horizontal = 20.dp), textStyle = Typography.headlineSmall.copy( color = point From 969bca3f171786bd24c03ce8037f401ede0cae16 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 23:39:36 +0900 Subject: [PATCH 035/184] adjustResize --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 30c501de..2350c2d1 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -132,7 +132,8 @@ + android:screenOrientation="portrait" + android:windowSoftInputMode="adjustResize" /> Date: Mon, 22 Apr 2024 23:39:53 +0900 Subject: [PATCH 036/184] =?UTF-8?q?SmeemButton=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compose/components/SmeemButton.kt | 56 +++++++++++++++++++ .../mypage/setting/ChangeNicknameScreen.kt | 11 +++- app/src/main/res/values/strings.xml | 1 + 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemButton.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemButton.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemButton.kt new file mode 100644 index 00000000..b00665d2 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemButton.kt @@ -0,0 +1,56 @@ +package com.sopt.smeem.presentation.compose.components + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.point +import com.sopt.smeem.presentation.compose.theme.pointInactive +import com.sopt.smeem.presentation.compose.theme.white + +@Composable +fun SmeemButton( + modifier: Modifier = Modifier, + text: String, + onClick: () -> Unit, + isButtonEnabled: Boolean = true +) { + Button( + onClick = onClick, + modifier = modifier.fillMaxWidth(), + enabled = isButtonEnabled, + shape = RoundedCornerShape(6.dp), + contentPadding = PaddingValues(vertical = 19.dp), + colors = ButtonDefaults.buttonColors( + containerColor = point, + contentColor = white, + disabledContainerColor = pointInactive, + disabledContentColor = white + ) + ) { + Text( + text = text, + style = Typography.titleLarge, + color = white + ) + } +} + +@Composable +@Preview(showBackground = true, showSystemUi = true) +fun SmeemActiveButtonPreview() { + SmeemButton(text = "버튼", onClick = {}) +} + +@Composable +@Preview(showBackground = true, showSystemUi = true) +fun SmeemNonActiveButtonPreview() { + SmeemButton(text = "버튼", onClick = {}, isButtonEnabled = false) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt index 0076e10f..08edd1af 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R +import com.sopt.smeem.presentation.compose.components.SmeemButton import com.sopt.smeem.presentation.compose.components.SmeemTextField import com.sopt.smeem.presentation.compose.theme.Typography import com.sopt.smeem.presentation.compose.theme.gray400 @@ -57,9 +58,17 @@ fun ChangeNicknameScreen( HorizontalSpacer(width = 18.dp) } + Spacer(modifier = Modifier.weight(1f)) - } + SmeemButton( + text = stringResource(id = R.string.my_page_change_nickname_button), + onClick = { /*TODO*/ }, + modifier = Modifier.padding(horizontal = 18.dp) + ) + + VerticalSpacer(height = 10.dp) + } } @Composable diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 38b0b16b..3dcc5a7f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,4 +85,5 @@ English edit target language 닉네임 변경 + 완료 \ No newline at end of file From abda55c334cc23e5985395a74e9f91174c64d405 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Mon, 22 Apr 2024 23:45:18 +0900 Subject: [PATCH 037/184] =?UTF-8?q?=EB=B9=88=20=EA=B3=B5=EA=B0=84=20?= =?UTF-8?q?=ED=84=B0=EC=B9=98=20=EC=8B=9C=20=ED=82=A4=EB=B3=B4=EB=93=9C=20?= =?UTF-8?q?=EB=82=B4=EB=A6=AC=EB=8A=94=20=ED=99=95=EC=9E=A5=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EA=B5=AC=ED=98=84=20=EB=B0=8F=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/setting/ChangeNicknameScreen.kt | 4 +++- app/src/main/java/com/sopt/smeem/util/ModifierExt.kt | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt index 08edd1af..0813e242 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt @@ -13,6 +13,7 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -23,6 +24,7 @@ import com.sopt.smeem.presentation.compose.theme.Typography import com.sopt.smeem.presentation.compose.theme.gray400 import com.sopt.smeem.util.HorizontalSpacer import com.sopt.smeem.util.VerticalSpacer +import com.sopt.smeem.util.addFocusCleaner @Composable fun ChangeNicknameScreen( @@ -32,7 +34,7 @@ fun ChangeNicknameScreen( var newNickName by rememberSaveable { mutableStateOf(nickname) } Column( - modifier = modifier, + modifier = modifier.addFocusCleaner(LocalFocusManager.current), horizontalAlignment = Alignment.CenterHorizontally ) { diff --git a/app/src/main/java/com/sopt/smeem/util/ModifierExt.kt b/app/src/main/java/com/sopt/smeem/util/ModifierExt.kt index b7e73be9..328b36a0 100644 --- a/app/src/main/java/com/sopt/smeem/util/ModifierExt.kt +++ b/app/src/main/java/com/sopt/smeem/util/ModifierExt.kt @@ -1,10 +1,13 @@ package com.sopt.smeem.util +import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.PathEffect import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.input.pointer.pointerInput fun Modifier.dashedBorder( borderWidth: Float, @@ -24,3 +27,11 @@ fun Modifier.dashedBorder( ) } } + +fun Modifier.addFocusCleaner(focusManager: FocusManager): Modifier { + return this.pointerInput(Unit) { + detectTapGestures(onTap = { + focusManager.clearFocus() + }) + } +} From 3d8ffce4d1403c570d5bcfcd5f54021d000da715 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 00:05:23 +0900 Subject: [PATCH 038/184] =?UTF-8?q?brush=20=EC=83=89=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../smeem/presentation/compose/components/SmeemTextField.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt index 3816f248..21797bc6 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -38,8 +39,8 @@ fun SmeemTextField( .padding(vertical = 19.dp, horizontal = 20.dp), textStyle = Typography.headlineSmall.copy( color = point - ) - + ), + cursorBrush = SolidColor(point) ) } From fad9fde1d5daf8854a2671be22f9bee82c122300 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 00:27:12 +0900 Subject: [PATCH 039/184] =?UTF-8?q?=EC=B4=88=EA=B8=B0=20=EC=A7=84=EC=9E=85?= =?UTF-8?q?=20=EC=8B=9C=20=EC=BB=A4=EC=84=9C=20=EB=A7=A8=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C=20=EC=98=AE=EA=B8=B0=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compose/components/SmeemTextField.kt | 11 +++-- .../mypage/setting/ChangeNicknameScreen.kt | 41 ++++++++++++++++--- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt index 21797bc6..40954988 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemTextField.kt @@ -10,23 +10,22 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.presentation.compose.theme.Typography import com.sopt.smeem.presentation.compose.theme.gray100 import com.sopt.smeem.presentation.compose.theme.point -// 공백이나 11자 초과시 버튼 비활성화 - @Composable fun SmeemTextField( modifier: Modifier = Modifier, - text: String, + value: TextFieldValue, keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - onValueChange: (String) -> Unit + onValueChange: (TextFieldValue) -> Unit ) { BasicTextField( - value = text, + value = value, onValueChange = onValueChange, singleLine = true, keyboardOptions = KeyboardOptions( @@ -48,7 +47,7 @@ fun SmeemTextField( @Composable fun SmeemTextFieldPreview() { SmeemTextField( - text = "텍스트", + value = TextFieldValue("텍스트"), onValueChange = {} ) } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt index 0813e242..e072fe83 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt @@ -3,18 +3,25 @@ package com.sopt.smeem.presentation.mypage.setting 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.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R @@ -31,19 +38,41 @@ fun ChangeNicknameScreen( modifier: Modifier = Modifier, nickname: String ) { - var newNickName by rememberSaveable { mutableStateOf(nickname) } + val focusManager = LocalFocusManager.current + val focusRequester = remember { FocusRequester() } + var textFieldState by remember { mutableStateOf(TextFieldValue(text = nickname)) } + + + LaunchedEffect(key1 = Unit) { + focusRequester.requestFocus() + } Column( - modifier = modifier.addFocusCleaner(LocalFocusManager.current), + modifier = modifier + .fillMaxSize() + .addFocusCleaner(focusManager), horizontalAlignment = Alignment.CenterHorizontally ) { VerticalSpacer(height = 14.dp) SmeemTextField( - text = newNickName, - onValueChange = { newNickName = it }, - modifier = Modifier.padding(horizontal = 18.dp) + value = textFieldState, + onValueChange = { newValue -> + textFieldState = newValue + }, + modifier = Modifier + .padding(horizontal = 18.dp) + .focusRequester(focusRequester) + .onFocusChanged { focusState -> + if (focusState.isFocused) { + textFieldState = textFieldState.copy( + selection = TextRange( + textFieldState.text.length + ) + ) + } + } ) VerticalSpacer(height = 10.dp) From aeca7929a9b18cc17b1d3f1611628310b63f5ed8 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 00:30:53 +0900 Subject: [PATCH 040/184] =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=ED=99=9C=EC=84=B1?= =?UTF-8?q?=ED=99=94=20=EC=A1=B0=EC=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/sopt/smeem/presentation/mypage/Const.kt | 3 +++ .../presentation/mypage/setting/ChangeNicknameScreen.kt | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt index 7dac43ab..cfc6614e 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/Const.kt @@ -4,3 +4,6 @@ const val MY_SUMMARY = "MyPage" const val SETTING = "Setting" const val MORE = "More" const val CHANGE_NICKNAME = "ChangeNickname" + +const val NICKNAME_MIN_LENGTH = 1 +const val NICKNAME_MAX_LENGTH = 10 diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt index e072fe83..84d43e00 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/setting/ChangeNicknameScreen.kt @@ -29,6 +29,8 @@ import com.sopt.smeem.presentation.compose.components.SmeemButton import com.sopt.smeem.presentation.compose.components.SmeemTextField import com.sopt.smeem.presentation.compose.theme.Typography import com.sopt.smeem.presentation.compose.theme.gray400 +import com.sopt.smeem.presentation.mypage.NICKNAME_MAX_LENGTH +import com.sopt.smeem.presentation.mypage.NICKNAME_MIN_LENGTH import com.sopt.smeem.util.HorizontalSpacer import com.sopt.smeem.util.VerticalSpacer import com.sopt.smeem.util.addFocusCleaner @@ -95,7 +97,9 @@ fun ChangeNicknameScreen( SmeemButton( text = stringResource(id = R.string.my_page_change_nickname_button), onClick = { /*TODO*/ }, - modifier = Modifier.padding(horizontal = 18.dp) + modifier = Modifier.padding(horizontal = 18.dp), + isButtonEnabled = textFieldState.text.length + in NICKNAME_MIN_LENGTH..NICKNAME_MAX_LENGTH ) VerticalSpacer(height = 10.dp) From bb35d8d8b33244baea3b88f034681e3f493049e0 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 00:40:25 +0900 Subject: [PATCH 041/184] =?UTF-8?q?TopBar=20=EB=92=A4=EB=A1=9C=EA=B0=80?= =?UTF-8?q?=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mypage/components/topbar/MyPageTopAppBars.kt | 8 ++++---- app/src/main/res/drawable/ic_arrow_left.xml | 10 ++++++++++ 2 files changed, 14 insertions(+), 4 deletions(-) create mode 100644 app/src/main/res/drawable/ic_arrow_left.xml diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt index 89d23975..1a76b5df 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/components/topbar/MyPageTopAppBars.kt @@ -45,7 +45,7 @@ fun MySummaryTopAppBar( onClick = onNavigationIconClick ) { Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_left), contentDescription = "Back" ) } @@ -91,7 +91,7 @@ fun SettingTopAppBar( onClick = onNavigationIconClick ) { Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_left), contentDescription = "Back" ) } @@ -128,7 +128,7 @@ fun OnlyBackArrowTopAppBar( onClick = onNavigationIconClick ) { Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_left), contentDescription = "Back" ) } @@ -160,7 +160,7 @@ fun TitleTopAppbar( onClick = onNavigationIconClick ) { Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_back), + imageVector = ImageVector.vectorResource(id = R.drawable.ic_arrow_left), contentDescription = "Back" ) } diff --git a/app/src/main/res/drawable/ic_arrow_left.xml b/app/src/main/res/drawable/ic_arrow_left.xml new file mode 100644 index 00000000..63ae7494 --- /dev/null +++ b/app/src/main/res/drawable/ic_arrow_left.xml @@ -0,0 +1,10 @@ + + + From d17f0ab987229e779eec2882ab2409f337a06d44 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 01:19:25 +0900 Subject: [PATCH 042/184] =?UTF-8?q?=EB=8D=94=EB=B3=B4=EA=B8=B0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/mypage/more/MoreScreen.kt | 85 +++++++++++++++++-- app/src/main/res/values/strings.xml | 8 ++ 2 files changed, 87 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt index 666c7509..94d93dfc 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt @@ -1,13 +1,23 @@ package com.sopt.smeem.presentation.mypage.more -import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp import androidx.navigation.NavController +import androidx.navigation.compose.rememberNavController +import com.sopt.smeem.R +import com.sopt.smeem.presentation.theme.Typography +import com.sopt.smeem.presentation.theme.black +import com.sopt.smeem.presentation.theme.gray600 +import com.sopt.smeem.util.VerticalSpacer @Composable fun MoreScreen( @@ -15,11 +25,74 @@ fun MoreScreen( modifier: Modifier ) { Column( - modifier = modifier.fillMaxSize(), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center + modifier = modifier + .fillMaxSize() + .padding(horizontal = 24.dp), ) { - Text(text = "더보기 화면이다") + + VerticalSpacer(height = 30.dp) + + Text( + text = stringResource(R.string.my_page_more_information), + style = Typography.titleMedium, + color = black + ) + + VerticalSpacer(height = 9.dp) + + Box( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 12.dp, horizontal = 8.dp) + ) { + Text( + text = stringResource(R.string.my_page_more_instructions), + style = Typography.bodyMedium, + color = gray600 + ) + } + + VerticalSpacer(height = 60.dp) + + Text( + text = stringResource(R.string.my_page_more_account_management), + style = Typography.titleMedium, + color = black + ) + + VerticalSpacer(height = 10.dp) + + Box( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 12.dp, horizontal = 8.dp) + ) { + Text( + text = stringResource(R.string.my_page_more_logout), + style = Typography.bodyMedium, + color = gray600 + ) + } + + VerticalSpacer(height = 6.dp) + + Box( + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 12.dp, horizontal = 8.dp) + ) { + Text( + text = stringResource(R.string.my_page_more_delete_account), + style = Typography.bodyMedium, + color = gray600 + ) + } } +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun MoreScreenPreview() { + MoreScreen(navController = rememberNavController(), modifier = Modifier) } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3dcc5a7f..5626cb14 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -84,6 +84,14 @@ 학습 알림 English edit target language + 닉네임 변경 완료 + + + 정보 + 이용 안내 + 계정 관리 + 로그아웃 + 계정 삭제 \ No newline at end of file From bab03b89b02d7385ffbcdc8514e1306222acc9d6 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 01:33:19 +0900 Subject: [PATCH 043/184] =?UTF-8?q?=EC=BB=A4=EC=8A=A4=ED=85=80=20=ED=83=AD?= =?UTF-8?q?=20=EB=A7=81=ED=81=AC=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 ++ .../presentation/mypage/more/MoreScreen.kt | 22 ++++++++++++++++++- app/src/main/res/values/strings.xml | 5 +++-- gradle/libs.versions.toml | 2 ++ 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index cb2f85fc..de3e8fca 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -189,6 +189,8 @@ dependencies { implementation(libs.glide) // Amplitude implementation(libs.analytics.android) + // Browser + implementation(libs.androidx.browser) // Compose implementation(platform(libs.androidx.compose.bom)) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt index 94d93dfc..ea67da66 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt @@ -1,5 +1,7 @@ package com.sopt.smeem.presentation.mypage.more +import android.net.Uri +import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize @@ -8,9 +10,11 @@ import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.sopt.smeem.R @@ -18,12 +22,16 @@ import com.sopt.smeem.presentation.theme.Typography import com.sopt.smeem.presentation.theme.black import com.sopt.smeem.presentation.theme.gray600 import com.sopt.smeem.util.VerticalSpacer +import com.sopt.smeem.util.noRippleClickable @Composable fun MoreScreen( navController: NavController, modifier: Modifier ) { + val viewModel: MoreViewModel = hiltViewModel() + val context = LocalContext.current + Column( modifier = modifier .fillMaxSize() @@ -43,10 +51,22 @@ fun MoreScreen( Box( modifier = Modifier .fillMaxWidth() + .noRippleClickable { + CustomTabsIntent + .Builder() + .build() + .run { + launchUrl( + context, Uri.parse( + context.getString(R.string.my_page_more_manual_link) + ) + ) + } + } .padding(vertical = 12.dp, horizontal = 8.dp) ) { Text( - text = stringResource(R.string.my_page_more_instructions), + text = stringResource(R.string.my_page_more_manual), style = Typography.bodyMedium, color = gray600 ) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5626cb14..1a81ed6f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -88,10 +88,11 @@ 닉네임 변경 완료 - + 정보 - 이용 안내 + 이용 안내 계정 관리 로그아웃 계정 삭제 + \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index a3a66f0f..a7bea8ef 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -39,6 +39,7 @@ securityCryptoKtx = "1.1.0-alpha05" timber = "5.0.1" v2User = "2.13.0" kotlin = "1.9.22" +browser = "1.8.0" [libraries] analytics-android = { module = "com.amplitude:analytics-android", version.ref = "analyticsAndroid" } @@ -99,6 +100,7 @@ retrofit2-kotlinx-serialization-converter = { module = "com.jakewharton.retrofit secrets-gradle-plugin = { module = "com.google.android.libraries.mapsplatform.secrets-gradle-plugin:secrets-gradle-plugin", version.ref = "secretsGradlePlugin" } timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" } v2-user = { module = "com.kakao.sdk:v2-user", version.ref = "v2User" } +androidx-browser = { module = "androidx.browser:browser", version.ref = "browser" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" } From 8c48321dd1cf49cd22ae06b48897df9d222d3057 Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 12:33:23 +0900 Subject: [PATCH 044/184] =?UTF-8?q?SmeemDialog=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compose/components/SmeemDialog.kt | 81 +++++++++++++++++++ .../presentation/mypage/more/MoreScreen.kt | 39 ++++++++- .../presentation/mypage/more/MoreViewModel.kt | 30 +++++++ app/src/main/res/values/strings.xml | 9 ++- 4 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreViewModel.kt diff --git a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt new file mode 100644 index 00000000..bfbd2cd0 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt @@ -0,0 +1,81 @@ +package com.sopt.smeem.presentation.compose.components + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.sopt.smeem.R +import com.sopt.smeem.presentation.theme.Typography +import com.sopt.smeem.presentation.theme.black +import com.sopt.smeem.presentation.theme.gray600 +import com.sopt.smeem.presentation.theme.point +import com.sopt.smeem.presentation.theme.white + +@Composable +fun SmeemDialog( + setShowDialog: (Boolean) -> Unit, + title: String, + content: String, + onConfirmButtonClick: () -> Unit, + modifier: Modifier = Modifier, +) { + AlertDialog( + onDismissRequest = { setShowDialog(false) }, + title = { + Text( + text = title, + style = Typography.titleSmall, + color = black + ) + }, + text = { + Text( + text = content, + style = Typography.labelMedium, + color = gray600 + ) + }, + shape = RoundedCornerShape(10.dp), + containerColor = white, + confirmButton = { + TextButton( + onClick = onConfirmButtonClick + ) { + Text( + text = stringResource(R.string.smeem_dialog_yes), + style = Typography.bodyLarge.copy(fontWeight = FontWeight.SemiBold), + color = point + ) + } + }, + dismissButton = { + TextButton(onClick = { setShowDialog(false) }) { + Text( + text = stringResource(R.string.smeem_dialog_no), + style = Typography.bodyLarge.copy(fontWeight = FontWeight.SemiBold), + color = point + ) + } + }, + modifier = modifier.fillMaxWidth() + ) + +} + +@Preview(showBackground = true, showSystemUi = true) +@Composable +fun SmeemDialogPreview() { + SmeemDialog( + setShowDialog = {}, + title = "Title", + content = "Content Content Content Content", + onConfirmButtonClick = {}, + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt index ea67da66..42802c3d 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt @@ -1,5 +1,7 @@ package com.sopt.smeem.presentation.mypage.more +import android.app.Activity +import android.content.Intent import android.net.Uri import androidx.browser.customtabs.CustomTabsIntent import androidx.compose.foundation.layout.Box @@ -9,6 +11,8 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -18,6 +22,8 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import androidx.navigation.compose.rememberNavController import com.sopt.smeem.R +import com.sopt.smeem.presentation.compose.components.SmeemDialog +import com.sopt.smeem.presentation.splash.SplashLoginActivity import com.sopt.smeem.presentation.theme.Typography import com.sopt.smeem.presentation.theme.black import com.sopt.smeem.presentation.theme.gray600 @@ -32,6 +38,35 @@ fun MoreScreen( val viewModel: MoreViewModel = hiltViewModel() val context = LocalContext.current + val (showLogoutDialog, setShowLogoutDialog) = rememberSaveable { mutableStateOf(false) } + val (showDeleteDialog, setShowDeleteDialog) = rememberSaveable { mutableStateOf(false) } + + if (showLogoutDialog) { + SmeemDialog( + setShowDialog = setShowLogoutDialog, + title = stringResource(R.string.smeem_dialog_logout_title), + content = stringResource(R.string.smeem_dialog_logout_content), + onConfirmButtonClick = { + viewModel.clearLocal() + context.startActivity(Intent(context, SplashLoginActivity::class.java)) + (context as? Activity)?.finishAffinity() + }) + } + + // 계정 삭제 대화상자 + if (showDeleteDialog) { + SmeemDialog( + setShowDialog = setShowDeleteDialog, + title = stringResource(R.string.smeem_dialog_delete_account_title), + content = stringResource(R.string.smeem_dialog_delete_dialog_content), + onConfirmButtonClick = { + viewModel.withdrawal() + context.startActivity(Intent(context, SplashLoginActivity::class.java)) + (context as? Activity)?.finishAffinity() + }) + } + + Column( modifier = modifier .fillMaxSize() @@ -58,7 +93,7 @@ fun MoreScreen( .run { launchUrl( context, Uri.parse( - context.getString(R.string.my_page_more_manual_link) + context.getString(R.string.manual_url) ) ) } @@ -85,6 +120,7 @@ fun MoreScreen( Box( modifier = Modifier .fillMaxWidth() + .noRippleClickable { setShowLogoutDialog(true) } .padding(vertical = 12.dp, horizontal = 8.dp) ) { Text( @@ -99,6 +135,7 @@ fun MoreScreen( Box( modifier = Modifier .fillMaxWidth() + .noRippleClickable { setShowDeleteDialog(true) } .padding(vertical = 12.dp, horizontal = 8.dp) ) { Text( diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreViewModel.kt new file mode 100644 index 00000000..f3197e4e --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreViewModel.kt @@ -0,0 +1,30 @@ +package com.sopt.smeem.presentation.mypage.more + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.kakao.sdk.user.UserApiClient +import com.sopt.smeem.domain.repository.LocalRepository +import com.sopt.smeem.domain.repository.UserRepository +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class MoreViewModel @Inject constructor( + private val localRepository: LocalRepository, + private val userRepository: UserRepository +) : ViewModel() { + fun clearLocal() { + viewModelScope.launch { + localRepository.clear() + } + } + + fun withdrawal() { + viewModelScope.launch { + userRepository.deleteUser() + UserApiClient.instance.unlink {} + localRepository.clear() + } + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1a81ed6f..9d241ce2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -94,5 +94,12 @@ 계정 관리 로그아웃 계정 삭제 - + + + + 아니요 + 로그아웃 + 로그아웃 하시겠습니까? + 계정을 삭제하시겠습니까? + 이전에 작성했던 일기는 모두 사라집니다. \ No newline at end of file From e8712a08b1e43132e5e1f8b418ac634ab856518e Mon Sep 17 00:00:00 2001 From: HaeTi Date: Tue, 23 Apr 2024 21:37:53 +0900 Subject: [PATCH 045/184] =?UTF-8?q?TextButton=20=ED=84=B0=EC=B9=98?= =?UTF-8?q?=EC=98=81=EC=97=AD=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/mypage/more/MoreScreen.kt | 47 +++++++++---------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt index 42802c3d..dc959927 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt @@ -4,10 +4,10 @@ import android.app.Activity import android.content.Intent import android.net.Uri import androidx.browser.customtabs.CustomTabsIntent +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -28,7 +28,6 @@ import com.sopt.smeem.presentation.theme.Typography import com.sopt.smeem.presentation.theme.black import com.sopt.smeem.presentation.theme.gray600 import com.sopt.smeem.util.VerticalSpacer -import com.sopt.smeem.util.noRippleClickable @Composable fun MoreScreen( @@ -83,27 +82,26 @@ fun MoreScreen( VerticalSpacer(height = 9.dp) - Box( - modifier = Modifier - .fillMaxWidth() - .noRippleClickable { - CustomTabsIntent - .Builder() - .build() - .run { - launchUrl( - context, Uri.parse( - context.getString(R.string.manual_url) - ) + + Box(modifier = Modifier + .clickable { + CustomTabsIntent + .Builder() + .build() + .run { + launchUrl( + context, Uri.parse( + context.getString(R.string.manual_url) ) - } - } - .padding(vertical = 12.dp, horizontal = 8.dp) + ) + } + } + .padding(vertical = 12.dp, horizontal = 8.dp) ) { Text( text = stringResource(R.string.my_page_more_manual), style = Typography.bodyMedium, - color = gray600 + color = gray600, ) } @@ -112,21 +110,20 @@ fun MoreScreen( Text( text = stringResource(R.string.my_page_more_account_management), style = Typography.titleMedium, - color = black + color = black, ) VerticalSpacer(height = 10.dp) Box( modifier = Modifier - .fillMaxWidth() - .noRippleClickable { setShowLogoutDialog(true) } + .clickable { setShowLogoutDialog(true) } .padding(vertical = 12.dp, horizontal = 8.dp) ) { Text( text = stringResource(R.string.my_page_more_logout), style = Typography.bodyMedium, - color = gray600 + color = gray600, ) } @@ -134,17 +131,15 @@ fun MoreScreen( Box( modifier = Modifier - .fillMaxWidth() - .noRippleClickable { setShowDeleteDialog(true) } + .clickable { setShowDeleteDialog(true) } .padding(vertical = 12.dp, horizontal = 8.dp) ) { Text( text = stringResource(R.string.my_page_more_delete_account), style = Typography.bodyMedium, - color = gray600 + color = gray600, ) } - } } From fe56fe82e88c613390400b3111faa8155cc54a69 Mon Sep 17 00:00:00 2001 From: wateralsie Date: Wed, 24 Apr 2024 00:11:05 +0900 Subject: [PATCH 046/184] =?UTF-8?q?theme=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/compose/components/SmeemDialog.kt | 10 +++++----- .../sopt/smeem/presentation/mypage/more/MoreScreen.kt | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt index bfbd2cd0..755be517 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/compose/components/SmeemDialog.kt @@ -12,11 +12,11 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.smeem.R -import com.sopt.smeem.presentation.theme.Typography -import com.sopt.smeem.presentation.theme.black -import com.sopt.smeem.presentation.theme.gray600 -import com.sopt.smeem.presentation.theme.point -import com.sopt.smeem.presentation.theme.white +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.black +import com.sopt.smeem.presentation.compose.theme.gray600 +import com.sopt.smeem.presentation.compose.theme.point +import com.sopt.smeem.presentation.compose.theme.white @Composable fun SmeemDialog( diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt index dc959927..de2dc18b 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/more/MoreScreen.kt @@ -24,9 +24,9 @@ import androidx.navigation.compose.rememberNavController import com.sopt.smeem.R import com.sopt.smeem.presentation.compose.components.SmeemDialog import com.sopt.smeem.presentation.splash.SplashLoginActivity -import com.sopt.smeem.presentation.theme.Typography -import com.sopt.smeem.presentation.theme.black -import com.sopt.smeem.presentation.theme.gray600 +import com.sopt.smeem.presentation.compose.theme.Typography +import com.sopt.smeem.presentation.compose.theme.black +import com.sopt.smeem.presentation.compose.theme.gray600 import com.sopt.smeem.util.VerticalSpacer @Composable From 874acd8f5e16064bd5a12c5c3693569f76cda858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EB=A8=B8=ED=99=98=EC=9E=84?= Date: Wed, 24 Apr 2024 00:10:23 +0900 Subject: [PATCH 047/184] Refactor Server Call R --- .../java/com/sopt/smeem/SmeemException.kt | 8 +- .../main/java/com/sopt/smeem/data/ApiPool.kt | 6 +- .../smeem/data/datasource/DiaryCommander.kt | 30 -- .../sopt/smeem/data/datasource/DiaryReader.kt | 38 +-- .../sopt/smeem/data/datasource/DummyDate.kt | 37 --- .../smeem/data/datasource/HealthChecker.kt | 10 - .../smeem/data/datasource/LoginExecutor.kt | 23 -- .../smeem/data/datasource/MyPageRetriever.kt | 11 - .../smeem/data/datasource/TrainingManager.kt | 74 ----- .../smeem/data/datasource/UserModifier.kt | 34 --- .../model/request/UserInfoModifyingRequest.kt | 2 +- .../smeem/data/model/response/ApiResponse.kt | 4 +- .../data/model/response/MyInfoResponse.kt | 16 ++ .../data/model/response/MyPlanDataResponse.kt | 8 + .../model/response/MySmeemDataResponse.kt | 8 + .../data/repository/DiaryRepositoryImpl.kt | 159 +++++++---- .../data/repository/HealthRepositoryImpl.kt | 16 +- .../data/repository/LocalRepositoryImpl.kt | 26 +- .../data/repository/LoginRepositoryImpl.kt | 45 ++- .../smeem/data/repository/StatusCodeUtils.kt | 16 ++ .../data/repository/TrainingRepositoryImpl.kt | 66 ++--- .../data/repository/UserRepositoryImpl.kt | 259 +++++++++++++----- .../sopt/smeem/data/service/DiaryService.kt | 13 +- .../sopt/smeem/data/service/HealthService.kt | 4 +- .../sopt/smeem/data/service/LoginService.kt | 6 +- .../sopt/smeem/data/service/MyPageService.kt | 10 - .../smeem/data/service/TrainingService.kt | 6 +- .../sopt/smeem/data/service/UserService.kt | 32 ++- .../java/com/sopt/smeem/domain/ApiResult.kt | 11 + .../smeem/domain/dto/DeleteDiaryRequestDto.kt | 5 + .../smeem/domain/dto/GetDiaryResponseDto.kt | 11 + .../smeem/domain/dto/GetDiarySummariesDto.kt | 15 + .../com/sopt/smeem/domain/dto/GetTopicDto.kt | 6 + .../sopt/smeem/domain/dto/HealthStatusDto.kt | 5 + .../LoginResult.kt => dto/LoginResultDto.kt} | 8 +- .../com/sopt/smeem/domain/dto/MyInfoDto.kt | 18 ++ .../com/sopt/smeem/domain/dto/MyPlanDto.kt | 8 + .../sopt/smeem/domain/dto/MySmeemDataDto.kt | 8 + .../smeem/domain/dto/PatchDiaryRequestDto.kt | 6 + .../smeem/domain/dto/PostOnBoardingDto.kt | 25 ++ .../smeem/domain/dto/RetrievedBadgeDto.kt | 8 + .../TrainingGoalDto.kt} | 4 +- .../TrainingGoalSimpleDto.kt} | 4 +- .../smeem/domain/dto/WriteDiaryRequestDto.kt | 6 + .../smeem/domain/dto/WriteDiaryResponseDto.kt | 6 + .../com/sopt/smeem/domain/model/MyPage.kt | 4 +- .../domain/repository/DiaryRepository.kt | 46 ++-- .../domain/repository/HealthRepository.kt | 4 +- .../domain/repository/LocalRepository.kt | 3 + .../domain/repository/LoginRepository.kt | 11 +- .../domain/repository/TrainingRepository.kt | 9 +- .../smeem/domain/repository/UserRepository.kt | 53 ++-- .../com/sopt/smeem/module/AnonymousModule.kt | 32 +-- .../sopt/smeem/module/HealthCheckModule.kt | 5 +- .../java/com/sopt/smeem/module/UserModule.kt | 35 +-- .../smeem/presentation/IntentConstants.kt | 18 ++ .../smeem/presentation/auth/OAuthProcessor.kt | 4 - .../smeem/presentation/detail/DiaryDetail.kt | 9 + .../detail/DiaryDetailActivity.kt | 19 +- .../detail/DiaryDetailBottomSheet.kt | 37 +-- .../detail/DiaryDetailViewModel.kt | 97 +++++-- .../presentation/detail/DiaryEditActivity.kt | 18 +- .../presentation/detail/DiaryEditViewModel.kt | 36 ++- .../smeem/presentation/health/HealthStatus.kt | 5 + .../smeem/presentation/health/ViewModel.kt | 9 +- .../home}/DiarySummaries.kt | 2 +- .../smeem/presentation/home/HomeViewModel.kt | 39 +-- .../smeem/presentation/join/JoinNicknameVM.kt | 11 +- .../sopt/smeem/presentation/join/JoinVM.kt | 14 +- .../join/JoinWithAgreementActivity.kt | 6 +- .../mypage/ChangingNicknameActivity.kt | 25 +- .../mypage/DisplayTrainingGoalActivity.kt | 12 +- .../mypage/EditTrainingTimeActivity.kt | 7 +- .../mypage/EditTrainingTimeViewModel.kt | 22 +- .../presentation/mypage/EditTrainingVM.kt | 33 ++- .../presentation/mypage/MyPageActivity.kt | 8 +- .../smeem/presentation/mypage/MyPageVM.kt | 24 +- .../onboarding/DisplayGoalFragment.kt | 2 +- .../onboarding/OnBoardingActivity.kt | 15 +- .../presentation/onboarding/OnBoardingVM.kt | 112 ++++---- .../onboarding/SignUpBottomSheet.kt | 5 +- .../presentation/splash/LoginBottomSheet.kt | 6 +- .../sopt/smeem/presentation/splash/LoginVM.kt | 24 +- .../splash/SplashLoginActivity.kt | 8 +- .../write/foreign/ForeignWriteActivity.kt | 32 +-- .../write/foreign/ForeignWriteViewModel.kt | 90 +++--- .../write/natiive/NativeWriteStep1Activity.kt | 2 +- .../natiive/NativeWriteStep1ViewModel.kt | 20 +- .../write/natiive/NativeWriteStep2Activity.kt | 28 +- .../natiive/NativeWriteStep2ViewModel.kt | 68 ++--- .../main/res/layout/activity_diary_detail.xml | 20 +- .../layout/activity_display_training_goal.xml | 2 +- .../main/res/layout/activity_health_check.xml | 29 +- app/src/main/res/layout/activity_my_page.xml | 2 +- .../layout/fragment_setting_encouraging.xml | 2 +- 95 files changed, 1219 insertions(+), 1026 deletions(-) delete mode 100644 app/src/main/java/com/sopt/smeem/data/datasource/DiaryCommander.kt delete mode 100644 app/src/main/java/com/sopt/smeem/data/datasource/DummyDate.kt delete mode 100644 app/src/main/java/com/sopt/smeem/data/datasource/HealthChecker.kt delete mode 100644 app/src/main/java/com/sopt/smeem/data/datasource/LoginExecutor.kt delete mode 100644 app/src/main/java/com/sopt/smeem/data/datasource/MyPageRetriever.kt delete mode 100644 app/src/main/java/com/sopt/smeem/data/datasource/TrainingManager.kt delete mode 100644 app/src/main/java/com/sopt/smeem/data/datasource/UserModifier.kt create mode 100644 app/src/main/java/com/sopt/smeem/data/model/response/MyInfoResponse.kt create mode 100644 app/src/main/java/com/sopt/smeem/data/model/response/MyPlanDataResponse.kt create mode 100644 app/src/main/java/com/sopt/smeem/data/model/response/MySmeemDataResponse.kt create mode 100644 app/src/main/java/com/sopt/smeem/data/repository/StatusCodeUtils.kt delete mode 100644 app/src/main/java/com/sopt/smeem/data/service/MyPageService.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/ApiResult.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/DeleteDiaryRequestDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/GetDiaryResponseDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/GetDiarySummariesDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/GetTopicDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/HealthStatusDto.kt rename app/src/main/java/com/sopt/smeem/domain/{model/LoginResult.kt => dto/LoginResultDto.kt} (75%) create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/MyInfoDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/MyPlanDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/MySmeemDataDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/PatchDiaryRequestDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/PostOnBoardingDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/RetrievedBadgeDto.kt rename app/src/main/java/com/sopt/smeem/domain/{model/TrainingGoal.kt => dto/TrainingGoalDto.kt} (59%) rename app/src/main/java/com/sopt/smeem/domain/{model/TrainingGoalSimple.kt => dto/TrainingGoalSimpleDto.kt} (59%) create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryRequestDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryResponseDto.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/IntentConstants.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetail.kt create mode 100644 app/src/main/java/com/sopt/smeem/presentation/health/HealthStatus.kt rename app/src/main/java/com/sopt/smeem/{domain/model => presentation/home}/DiarySummaries.kt (86%) diff --git a/app/src/main/java/com/sopt/smeem/SmeemException.kt b/app/src/main/java/com/sopt/smeem/SmeemException.kt index 1edef984..693d57a8 100644 --- a/app/src/main/java/com/sopt/smeem/SmeemException.kt +++ b/app/src/main/java/com/sopt/smeem/SmeemException.kt @@ -5,9 +5,7 @@ import android.util.Log class SmeemException( val errorCode: SmeemErrorCode, val logMessage: String? = null, - val throwable: Throwable -) : RuntimeException(if (logMessage.isNullOrEmpty()) errorCode.message else logMessage) { -} +) : RuntimeException(if (logMessage.isNullOrEmpty()) errorCode.message else logMessage) enum class SmeemErrorCode( val code: Int, @@ -24,6 +22,4 @@ enum class SmeemErrorCode( } fun SmeemException.description() = this.errorCode.message -fun SmeemException.tip() = this.errorCode.tip -fun SmeemException.logging(tag: String) = - Log.e(tag, this.logMessage ?: this.description(), this.throwable) \ No newline at end of file +fun SmeemException.logging(tag: String) = Log.e(tag, this.logMessage ?: this.description()) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/ApiPool.kt b/app/src/main/java/com/sopt/smeem/data/ApiPool.kt index 1801725c..ceaf473f 100644 --- a/app/src/main/java/com/sopt/smeem/data/ApiPool.kt +++ b/app/src/main/java/com/sopt/smeem/data/ApiPool.kt @@ -5,6 +5,7 @@ import com.sopt.smeem.SmeemException import retrofit2.HttpException object ApiPool { + @Deprecated("not used") fun Result.onHttpFailure(action: (SmeemException) -> Unit) { exceptionOrNull()?.let { exception -> when (exception) { @@ -13,22 +14,18 @@ object ApiPool { when (exception.code()) { 400 -> throw SmeemException( errorCode = SmeemErrorCode.SYSTEM_ERROR, - throwable = exception, ) 401 -> throw SmeemException( errorCode = SmeemErrorCode.UNAUTHORIZED, - throwable = exception, ) 403 -> throw SmeemException( errorCode = SmeemErrorCode.FORBIDDEN, - throwable = exception, ) else -> throw SmeemException( errorCode = SmeemErrorCode.UNKNOWN_ERROR, - throwable = exception, ) } } catch (e: SmeemException) { @@ -39,7 +36,6 @@ object ApiPool { else -> action( SmeemException( errorCode = SmeemErrorCode.NETWORK_ERROR, - throwable = exception, logMessage = "서버 통신에 실패했습니다.", ), ) diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/DiaryCommander.kt b/app/src/main/java/com/sopt/smeem/data/datasource/DiaryCommander.kt deleted file mode 100644 index 0de2f347..00000000 --- a/app/src/main/java/com/sopt/smeem/data/datasource/DiaryCommander.kt +++ /dev/null @@ -1,30 +0,0 @@ -package com.sopt.smeem.data.datasource - -import com.sopt.smeem.data.model.request.DiaryRequest -import com.sopt.smeem.data.model.response.ApiResponse -import com.sopt.smeem.data.model.response.DiaryWritingResponse -import com.sopt.smeem.data.service.DiaryService -import com.sopt.smeem.domain.model.Diary - -class DiaryCommander( - private val diaryService: DiaryService -) { - suspend fun writeDiary(diary: Diary): ApiResponse = diaryService.post( - request = DiaryRequest.Writing( - content = diary.content, - topicId = diary.topicId - ) - ) - - suspend fun editDiary(diary: Diary): ApiResponse = diaryService.patch( - request = DiaryRequest.Editing( - content = diary.content - ), - diaryId = diary.id!! - ) - - suspend fun removeDiary(diaryId: Long) = diaryService.delete( - diaryId = diaryId - ) - -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/DiaryReader.kt b/app/src/main/java/com/sopt/smeem/data/datasource/DiaryReader.kt index 39e76540..4bd2727d 100644 --- a/app/src/main/java/com/sopt/smeem/data/datasource/DiaryReader.kt +++ b/app/src/main/java/com/sopt/smeem/data/datasource/DiaryReader.kt @@ -6,46 +6,32 @@ import com.sopt.smeem.data.model.response.ApiResponse import com.sopt.smeem.data.model.response.DiaryResponse import com.sopt.smeem.data.service.DiaryService import com.sopt.smeem.util.DateUtil -import com.sopt.smeem.util.DateUtil.YYYY_MM_DD +import retrofit2.Response import java.time.LocalDateTime -import java.util.regex.Pattern class DiaryReader( private val diaryService: DiaryService, ) { - suspend fun getDetail(diaryId: Long): ApiResponse = - diaryService.getDetail(diaryId = diaryId) - // calendar related suspend fun getList( start: String?, end: String?, - ): ApiResponse { + ): Response> { val now = LocalDateTime.now() - try { - if (start == null || end == null) { - return diaryService.getList( - startDate = DateUtil.yyyy_mm_dd(now), - endDate = DateUtil.yyyy_mm_dd(now), - ) - } - - if ((DateUtil.gap(start, end) >= 50) || (DateUtil.gap(start, end) < 0)) { - throw SmeemException( - errorCode = SmeemErrorCode.CLIENT_ERROR, - throwable = IllegalArgumentException("날짜에 유호하지 않은 값이 입력되었습니다."), - ) - } + if (start == null || end == null) { + return diaryService.getList( + startDate = DateUtil.yyyy_mm_dd(now), + endDate = DateUtil.yyyy_mm_dd(now), + ) + } - return diaryService.getList(startDate = start, endDate = end) - } catch (t: IllegalArgumentException) { + if ((DateUtil.gap(start, end) >= 50) || (DateUtil.gap(start, end) < 0)) { throw SmeemException( - errorCode = SmeemErrorCode.UNKNOWN_ERROR, - throwable = t, + errorCode = SmeemErrorCode.CLIENT_ERROR, ) } - } - suspend fun getTopic(): ApiResponse = diaryService.getTopic() + return diaryService.getList(startDate = start, endDate = end) + } } diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/DummyDate.kt b/app/src/main/java/com/sopt/smeem/data/datasource/DummyDate.kt deleted file mode 100644 index 4dfa193a..00000000 --- a/app/src/main/java/com/sopt/smeem/data/datasource/DummyDate.kt +++ /dev/null @@ -1,37 +0,0 @@ -package com.sopt.smeem.data.datasource - -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import java.time.LocalDate - -object DummyDate { - private val _diaryDateList = MutableStateFlow>( - listOf( - LocalDate.of(2023, 10, 9), - LocalDate.of(2023, 10, 19), - LocalDate.of(2023, 10, 20), - LocalDate.of(2023, 10, 21), - LocalDate.of(2023, 10, 26), - LocalDate.of(2023, 10, 28), - LocalDate.of(2023, 11, 2), - LocalDate.of(2023, 11, 10), - LocalDate.of(2023, 11, 12), - LocalDate.of(2023, 11, 22), - LocalDate.of(2023, 12, 5), - LocalDate.of(2023, 12, 17), - LocalDate.of(2023, 12, 22), - LocalDate.of(2023, 12, 25), - LocalDate.of(2023, 12, 29), - LocalDate.of(2023, 12, 31), - LocalDate.of(2024, 1, 1), - LocalDate.of(2024, 1, 8), - LocalDate.of(2024, 1, 12), - LocalDate.of(2024, 1, 13), - LocalDate.of(2024, 1, 19), - LocalDate.of(2024, 1, 20), - LocalDate.of(2024, 1, 21), - LocalDate.of(2024, 1, 22), - ) - ) - val diaryDateList: StateFlow> = _diaryDateList -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/HealthChecker.kt b/app/src/main/java/com/sopt/smeem/data/datasource/HealthChecker.kt deleted file mode 100644 index 130f9503..00000000 --- a/app/src/main/java/com/sopt/smeem/data/datasource/HealthChecker.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.sopt.smeem.data.datasource - -import com.sopt.smeem.data.model.response.ApiResponse -import com.sopt.smeem.data.service.HealthService - -class HealthChecker( - private val healthService: HealthService -) { - suspend fun getHealth(): ApiResponse = healthService.getStatus() -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/LoginExecutor.kt b/app/src/main/java/com/sopt/smeem/data/datasource/LoginExecutor.kt deleted file mode 100644 index ac4a8858..00000000 --- a/app/src/main/java/com/sopt/smeem/data/datasource/LoginExecutor.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.sopt.smeem.data.datasource - -import com.sopt.smeem.SocialType -import com.sopt.smeem.data.model.request.LoginRequest -import com.sopt.smeem.data.model.response.ApiResponse -import com.sopt.smeem.data.model.response.LoginResponse -import com.sopt.smeem.data.model.response.NicknameCheckResponse -import com.sopt.smeem.data.service.LoginService - -class LoginExecutor( - private val loginService: LoginService -) { - suspend fun execute( - accessToken: String, - socialType: SocialType, - fcmToken: String, - ): ApiResponse = - loginService.login(accessToken = "Bearer $accessToken", LoginRequest(socialType, fcmToken)) - - suspend fun checkNicknameDuplicated( - nickname: String - ): ApiResponse = loginService.checkDuplicated(nickname) -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/MyPageRetriever.kt b/app/src/main/java/com/sopt/smeem/data/datasource/MyPageRetriever.kt deleted file mode 100644 index 6ec80268..00000000 --- a/app/src/main/java/com/sopt/smeem/data/datasource/MyPageRetriever.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.sopt.smeem.data.datasource - -import com.sopt.smeem.data.model.response.ApiResponse -import com.sopt.smeem.data.model.response.MyPageResponse -import com.sopt.smeem.data.service.MyPageService - -class MyPageRetriever( - private val myPageService: MyPageService -) { - suspend fun getResponse(): ApiResponse = myPageService.getMyInfo() -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/TrainingManager.kt b/app/src/main/java/com/sopt/smeem/data/datasource/TrainingManager.kt deleted file mode 100644 index f5bb67de..00000000 --- a/app/src/main/java/com/sopt/smeem/data/datasource/TrainingManager.kt +++ /dev/null @@ -1,74 +0,0 @@ -package com.sopt.smeem.data.datasource - -import com.sopt.smeem.TrainingGoalType -import com.sopt.smeem.data.model.request.PushRequest -import com.sopt.smeem.data.model.request.TrainingRequest -import com.sopt.smeem.data.model.response.ApiResponse -import com.sopt.smeem.data.model.response.TrainingGoalResponse -import com.sopt.smeem.data.model.response.TrainingGoalSimpleResponse -import com.sopt.smeem.data.service.TrainingService -import com.sopt.smeem.data.service.UserService -import com.sopt.smeem.domain.model.LoginResult -import com.sopt.smeem.domain.model.OnBoarding -import com.sopt.smeem.domain.model.PushAlarm -import com.sopt.smeem.domain.model.Training - -class TrainingManager( - private val userService: UserService? = null, - private val trainingService: TrainingService -) { - suspend fun registerOnBoarding( - onBoarding: OnBoarding, - loginResult: LoginResult - ): ApiResponse { - return userService!!.patchPlanOnAnonymous( - request = TrainingRequest( - target = onBoarding.trainingGoalType, - trainingTime = onBoarding.extractTime(), - hasAlarm = onBoarding.hasAlarm - ), - token = "Bearer ${loginResult.apiAccessToken}" - ) - } - - suspend fun patchTraining(accessToken: String?, training: Training): ApiResponse { - if (accessToken.isNullOrBlank()) { - return userService!!.patchPlan( - request = TrainingRequest( - target = training.type, - trainingTime = training.extractTime(), - hasAlarm = training.hasAlarm - ) - ) - } else { - return userService!!.patchPlanWithFixedToken( - token = "Bearer $accessToken", - request = TrainingRequest( - target = training.type, - trainingTime = training.extractTime(), - hasAlarm = training.hasAlarm - ) - ) - } - } - - suspend fun patchPushAlarm(accessToken: String?, push: PushAlarm): ApiResponse { - if (accessToken.isNullOrBlank()) { - return userService!!.patchPush( - request = PushRequest(push.hasAlarm) - ) - } else { - return userService!!.patchPushWithFixedToken( - token = "Bearer $accessToken", - request = PushRequest(push.hasAlarm) - ) - } - } - - - suspend fun getDetail(goal: TrainingGoalType): ApiResponse = - trainingService.getDetail(goal) - - suspend fun getAll(): ApiResponse = - trainingService.getAll() -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/datasource/UserModifier.kt b/app/src/main/java/com/sopt/smeem/data/datasource/UserModifier.kt deleted file mode 100644 index a11d3c36..00000000 --- a/app/src/main/java/com/sopt/smeem/data/datasource/UserModifier.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.sopt.smeem.data.datasource - -import com.sopt.smeem.data.model.request.UserInfoModifyingRequest -import com.sopt.smeem.data.model.response.ApiResponse -import com.sopt.smeem.data.service.UserService - -class UserModifier( - private val userService: UserService -) { - suspend fun patch( - accessToken: String?, - username: String, - marketingAcceptance: Boolean? - ): ApiResponse { - if (accessToken != null) { - return userService.patchUserInfoWithTokenFixed( - token = "Bearer $accessToken", - UserInfoModifyingRequest( - username = username, - termAccepted = marketingAcceptance ?: false - ) - ) - } else { - return userService.patchUserInfo( - UserInfoModifyingRequest( - username = username, - termAccepted = marketingAcceptance ?: false - ) - ) - } - } - - suspend fun delete(): ApiResponse = userService.delete() -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/model/request/UserInfoModifyingRequest.kt b/app/src/main/java/com/sopt/smeem/data/model/request/UserInfoModifyingRequest.kt index a69091d4..a8173e42 100644 --- a/app/src/main/java/com/sopt/smeem/data/model/request/UserInfoModifyingRequest.kt +++ b/app/src/main/java/com/sopt/smeem/data/model/request/UserInfoModifyingRequest.kt @@ -2,5 +2,5 @@ package com.sopt.smeem.data.model.request data class UserInfoModifyingRequest( val username: String, - val termAccepted: Boolean, + val termAccepted: Boolean? = null, ) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/model/response/ApiResponse.kt b/app/src/main/java/com/sopt/smeem/data/model/response/ApiResponse.kt index 7d426a3b..e1064e0e 100644 --- a/app/src/main/java/com/sopt/smeem/data/model/response/ApiResponse.kt +++ b/app/src/main/java/com/sopt/smeem/data/model/response/ApiResponse.kt @@ -1,8 +1,8 @@ package com.sopt.smeem.data.model.response -data class ApiResponse( +data class ApiResponse( val status: Int?, val success: Boolean, val message: String?, - val data: RESULT?, + val data: DATA, ) diff --git a/app/src/main/java/com/sopt/smeem/data/model/response/MyInfoResponse.kt b/app/src/main/java/com/sopt/smeem/data/model/response/MyInfoResponse.kt new file mode 100644 index 00000000..08e4f651 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/data/model/response/MyInfoResponse.kt @@ -0,0 +1,16 @@ +package com.sopt.smeem.data.model.response + +data class MyInfoResponse( + val username: String, + val way: String, + val detail: String, + val targetLang: String, + val hasPushAlarm: Boolean, + val trainingTime: MyTrainingTimeResponse?, +) { + data class MyTrainingTimeResponse( + val day: String, + val hour: Int, + val minute: Int + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/model/response/MyPlanDataResponse.kt b/app/src/main/java/com/sopt/smeem/data/model/response/MyPlanDataResponse.kt new file mode 100644 index 00000000..ff312b60 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/data/model/response/MyPlanDataResponse.kt @@ -0,0 +1,8 @@ +package com.sopt.smeem.data.model.response + +data class MyPlanDataResponse( + val plan: String, + val goal: String, + val clearedCount: Int, + val clearCount: Int, +) diff --git a/app/src/main/java/com/sopt/smeem/data/model/response/MySmeemDataResponse.kt b/app/src/main/java/com/sopt/smeem/data/model/response/MySmeemDataResponse.kt new file mode 100644 index 00000000..5a20e2fe --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/data/model/response/MySmeemDataResponse.kt @@ -0,0 +1,8 @@ +package com.sopt.smeem.data.model.response + +data class MySmeemDataResponse( + val visitDays: Int, + val diaryCount: Int, + val diaryComboCount: Int, + val badgeCount: Int, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/repository/DiaryRepositoryImpl.kt b/app/src/main/java/com/sopt/smeem/data/repository/DiaryRepositoryImpl.kt index 4f67fa42..9d1dcf69 100644 --- a/app/src/main/java/com/sopt/smeem/data/repository/DiaryRepositoryImpl.kt +++ b/app/src/main/java/com/sopt/smeem/data/repository/DiaryRepositoryImpl.kt @@ -1,86 +1,125 @@ package com.sopt.smeem.data.repository -import com.sopt.smeem.data.datasource.DiaryCommander import com.sopt.smeem.data.datasource.DiaryReader -import com.sopt.smeem.domain.model.Diary -import com.sopt.smeem.domain.model.DiarySummaries -import com.sopt.smeem.domain.model.DiarySummary -import com.sopt.smeem.domain.model.RetrievedBadge -import com.sopt.smeem.domain.model.Topic +import com.sopt.smeem.data.model.request.DiaryRequest +import com.sopt.smeem.data.service.DiaryService +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.DeleteDiaryRequestDto +import com.sopt.smeem.domain.dto.GetDiaryResponseDto +import com.sopt.smeem.domain.dto.GetDiarySummariesDto +import com.sopt.smeem.domain.dto.GetDiarySummaryDto +import com.sopt.smeem.domain.dto.GetTopicDto +import com.sopt.smeem.domain.dto.PatchDiaryRequestDto +import com.sopt.smeem.domain.dto.RetrievedBadgeDto +import com.sopt.smeem.domain.dto.WriteDiaryRequestDto +import com.sopt.smeem.domain.dto.WriteDiaryResponseDto import com.sopt.smeem.domain.repository.DiaryRepository import com.sopt.smeem.util.DateUtil class DiaryRepositoryImpl( - private val diaryCommander: DiaryCommander, + private val diaryService: DiaryService, private val diaryReader: DiaryReader, ) : DiaryRepository { - override suspend fun postDiary(diary: Diary): Result> = - kotlin.runCatching { diaryCommander.writeDiary(diary).data!!.badges } - .map { badges -> - badges.map { badge -> - RetrievedBadge( - name = badge.name, - imageUrl = badge.imageUrl, + override suspend fun postDiary(diary: WriteDiaryRequestDto): ApiResult = + diaryService.post(DiaryRequest.Writing(diary.content, diary.topicId)).let { response -> + if (response.isSuccessful) { + response.body()!!.let { + ApiResult( + response.code(), + WriteDiaryResponseDto( + diaryId = it.data.diaryId, + retrievedBadgeList = it.data.badges.map { badge -> + RetrievedBadgeDto( + badge.name, + badge.imageUrl + ) + } + ) ) } + } else { + throw response.code().handleStatusCode() } + } - override suspend fun patchDiary(diary: Diary): Result = - kotlin.runCatching { diaryCommander.editDiary(diary) } + override suspend fun patchDiary(dto: PatchDiaryRequestDto): ApiResult = + diaryService.patch(DiaryRequest.Editing(dto.content), dto.id).let { response -> + if (response.isSuccessful) { + response.body()!!.let { ApiResult(response.code(), Unit) } + } else { + throw response.code().handleStatusCode() + } + } - override suspend fun removeDiary(diaryId: Long): Result = - kotlin.runCatching { diaryCommander.removeDiary(diaryId) } + override suspend fun deleteDiary(dto: DeleteDiaryRequestDto): ApiResult = + diaryService.delete(dto.id).let { response -> + if (response.isSuccessful) { + response.body()!!.let { ApiResult(response.code(), Unit) } + } else { + throw response.code().handleStatusCode() + } + } - override suspend fun getDiaryDetail(diaryId: Long): Result = - kotlin.runCatching { diaryReader.getDetail(diaryId) } - .map { response -> - Diary( - id = response.data!!.diaryId, - content = response.data.content, - topic = response.data.topic, - createdAt = response.data.createdAt, - username = response.data.username, - corrections = response.data.corrections?.map { - Diary.Correction( - id = it.correctionId, - before = it.before, - after = it.after, + override suspend fun getDiaryDetail(diaryId: Long): ApiResult = + diaryService.getDetail(diaryId).let { response -> + if (response.isSuccessful) { + response.body()!!.let { body -> + ApiResult( + response.code(), GetDiaryResponseDto( + id = body.data.diaryId, + content = body.data.content, + createdAt = DateUtil.asLocalDateTime(body.data.createdAt), + username = body.data.username, + topic = body.data.topic, ) - } ?: emptyList(), - ) + ) + } + } else { + throw response.code().handleStatusCode() } + } // calendar related override suspend fun getDiaries( start: String?, end: String? - ): Result = - kotlin.runCatching { diaryReader.getList(start, end) } - .map { response -> - DiarySummaries( - diaries = response.data!!.diaries.associateBy( - keySelector = { diary -> - DateUtil.asLocalDateTime(diary.createdAt).toLocalDate() - }, - valueTransform = { diary -> - DiarySummary( - id = diary.diaryId, - content = diary.content, - createdAt = DateUtil.asLocalDateTime(diary.createdAt).toLocalTime() - ) - } - ), - has30Past = response.data.has30Past, - ) + ): ApiResult = + diaryReader.getList(start, end).let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), GetDiarySummariesDto( + diaries = data.diaries.associate { + DateUtil.asLocalDateTime(it.createdAt) + .toLocalDate() to GetDiarySummaryDto( + id = it.diaryId, + content = it.content, + createdAt = DateUtil.asLocalDateTime(it.createdAt) + .toLocalTime() + ) + }, + has30Past = data.has30Past, + ) + ) + } + } else { + throw response.code().handleStatusCode() } + } - override suspend fun getTopic(): Result = - kotlin.runCatching { - diaryReader.getTopic() - }.map { response -> - Topic( - id = response.data!!.topicId, - content = response.data.content, - ) + override suspend fun getTopic(): ApiResult = + diaryService.getTopic().let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), GetTopicDto( + id = data.topicId, + content = data.content + ) + ) + } + } else { + throw response.code().handleStatusCode() + } } } diff --git a/app/src/main/java/com/sopt/smeem/data/repository/HealthRepositoryImpl.kt b/app/src/main/java/com/sopt/smeem/data/repository/HealthRepositoryImpl.kt index 187c2e7e..87d1be4b 100644 --- a/app/src/main/java/com/sopt/smeem/data/repository/HealthRepositoryImpl.kt +++ b/app/src/main/java/com/sopt/smeem/data/repository/HealthRepositoryImpl.kt @@ -1,14 +1,18 @@ package com.sopt.smeem.data.repository -import com.sopt.smeem.data.datasource.HealthChecker -import com.sopt.smeem.domain.model.health.HealthStatus +import com.sopt.smeem.data.service.HealthService +import com.sopt.smeem.domain.ApiResult import com.sopt.smeem.domain.repository.HealthRepository class HealthRepositoryImpl( - private val healthChecker: HealthChecker + private val healthService: HealthService ) : HealthRepository { - override suspend fun getHealth(): Result = - kotlin.runCatching { healthChecker.getHealth() }.map { - response -> HealthStatus.init(response) + override suspend fun getHealth(): ApiResult = + healthService.getStatus().let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), Unit) + } else { + throw response.code().handleStatusCode() + } } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/repository/LocalRepositoryImpl.kt b/app/src/main/java/com/sopt/smeem/data/repository/LocalRepositoryImpl.kt index f2265d5e..361ce72c 100644 --- a/app/src/main/java/com/sopt/smeem/data/repository/LocalRepositoryImpl.kt +++ b/app/src/main/java/com/sopt/smeem/data/repository/LocalRepositoryImpl.kt @@ -25,6 +25,14 @@ class LocalRepositoryImpl @Inject constructor( private val context: Context ) : LocalRepository { + override suspend fun setStringValue(key: Preferences.Key, value: String) { + context.dataStore.edit { storage -> storage[key] = value } + } + + override suspend fun remove(key: Preferences.Key) { + context.dataStore.edit { storage -> storage.remove(key) } + } + /** * LocalStorage 로 부터 Authentication 추출 * 없을 경우, null 응답 @@ -43,13 +51,11 @@ class LocalRepositoryImpl @Inject constructor( Authentication( accessToken = preferences[API_ACCESS_TOKEN] ?: throw SmeemException( SmeemErrorCode.UNAUTHORIZED, - "인증이 필요합니다.", - IllegalStateException() + "인증이 필요합니다." ), refreshToken = preferences[API_REFRESH_TOKEN] ?: throw SmeemException( SmeemErrorCode.UNAUTHORIZED, - "인증이 필요합니다.", - IllegalStateException() + "인증이 필요합니다." ) ) }.first() @@ -64,12 +70,11 @@ class LocalRepositoryImpl @Inject constructor( requireNotNull(authentication.accessToken) { "NPE when register authentication with refreshToken" } } } catch (e: IOException) { - throw SmeemException(errorCode = SmeemErrorCode.SYSTEM_ERROR, throwable = e) + throw SmeemException(errorCode = SmeemErrorCode.SYSTEM_ERROR) } catch (e: IllegalArgumentException) { throw SmeemException( errorCode = SmeemErrorCode.SYSTEM_ERROR, - logMessage = "token 값 저장 중, null 로 접근하였습니다. (authentication = $authentication)", - throwable = e + logMessage = "token 값 저장 중, null 로 접근하였습니다. (authentication = $authentication)" ) } } @@ -94,7 +99,7 @@ class LocalRepositoryImpl @Inject constructor( } } } catch (t: Throwable) { - throw SmeemException(errorCode = SmeemErrorCode.SYSTEM_ERROR, throwable = t) + throw SmeemException(errorCode = SmeemErrorCode.SYSTEM_ERROR) } } @@ -102,7 +107,8 @@ class LocalRepositoryImpl @Inject constructor( .catch { emit(emptyPreferences()) } .map { preferences: Preferences -> when (localStatus) { - LocalStatus.RANDOM_TOPIC_TOOL_TIP -> preferences[RANDOM_TOPIC_TOOL_TIP_SWITCH] ?: true // 최초에는 킨 상태 + LocalStatus.RANDOM_TOPIC_TOOL_TIP -> preferences[RANDOM_TOPIC_TOOL_TIP_SWITCH] + ?: true // 최초에는 킨 상태 } } .first() @@ -111,7 +117,7 @@ class LocalRepositoryImpl @Inject constructor( try { context.dataStore.edit { preferences -> preferences.clear() } } catch (t: Throwable) { - throw SmeemException(errorCode = SmeemErrorCode.SYSTEM_ERROR, throwable = t) + throw SmeemException(errorCode = SmeemErrorCode.SYSTEM_ERROR) } } diff --git a/app/src/main/java/com/sopt/smeem/data/repository/LoginRepositoryImpl.kt b/app/src/main/java/com/sopt/smeem/data/repository/LoginRepositoryImpl.kt index 6ec47fda..f6a7ae37 100644 --- a/app/src/main/java/com/sopt/smeem/data/repository/LoginRepositoryImpl.kt +++ b/app/src/main/java/com/sopt/smeem/data/repository/LoginRepositoryImpl.kt @@ -1,20 +1,45 @@ package com.sopt.smeem.data.repository import com.sopt.smeem.SocialType -import com.sopt.smeem.data.datasource.LoginExecutor -import com.sopt.smeem.domain.model.LoginResult +import com.sopt.smeem.data.model.request.LoginRequest +import com.sopt.smeem.data.service.LoginService +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.LoginResultDto import com.sopt.smeem.domain.repository.LoginRepository class LoginRepositoryImpl( - private val loginExecutor: LoginExecutor + private val loginService: LoginService, ) : LoginRepository { - override suspend fun execute(accessToken: String, socialType: SocialType, fcmToken: String): Result = - kotlin.runCatching { loginExecutor.execute(accessToken, socialType, fcmToken) }.map { response -> - LoginResult.from(response.data!!) - } + override suspend fun execute( + accessToken: String, + socialType: SocialType, + fcmToken: String + ): ApiResult = + loginService.login("Bearer $accessToken", LoginRequest(socialType, fcmToken)).let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), + LoginResultDto( + apiAccessToken = data.accessToken, + apiRefreshToken = data.refreshToken, + isRegistered = data.isRegistered, + isPlanRegistered = data.hasPlan, + ) + ) + } + } else { + throw response.code().handleStatusCode() + } - override suspend fun checkNicknameDuplicated(nickname: String): Result = - kotlin.runCatching { loginExecutor.checkNicknameDuplicated(nickname) } - .map { response -> response.data!!.isExist } + } + override suspend fun checkNicknameDuplicated(nickname: String): ApiResult = + loginService.checkDuplicated(nickname).let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), response.body()!!.data.isExist) + } else { + throw response.code().handleStatusCode() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/repository/StatusCodeUtils.kt b/app/src/main/java/com/sopt/smeem/data/repository/StatusCodeUtils.kt new file mode 100644 index 00000000..0f8b5849 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/data/repository/StatusCodeUtils.kt @@ -0,0 +1,16 @@ +package com.sopt.smeem.data.repository + +import com.sopt.smeem.SmeemErrorCode +import com.sopt.smeem.SmeemException + +fun Int.handleStatusCode(specificAction: (() -> Throwable)? = null): Throwable = + specificAction?.invoke() + ?: if (this in 500..599) { + throw SmeemException(SmeemErrorCode.NETWORK_ERROR) + } else if (this == 401) { + throw SmeemException(SmeemErrorCode.UNAUTHORIZED) + } else if (this == 403) { + throw SmeemException(SmeemErrorCode.FORBIDDEN) + } else { + throw SmeemException(SmeemErrorCode.CLIENT_ERROR) + } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/repository/TrainingRepositoryImpl.kt b/app/src/main/java/com/sopt/smeem/data/repository/TrainingRepositoryImpl.kt index 6830c755..1e27eb19 100644 --- a/app/src/main/java/com/sopt/smeem/data/repository/TrainingRepositoryImpl.kt +++ b/app/src/main/java/com/sopt/smeem/data/repository/TrainingRepositoryImpl.kt @@ -1,42 +1,46 @@ package com.sopt.smeem.data.repository -import com.sopt.smeem.SmeemErrorCode -import com.sopt.smeem.SmeemException import com.sopt.smeem.TrainingGoalType -import com.sopt.smeem.data.datasource.TrainingManager -import com.sopt.smeem.domain.model.TrainingGoal -import com.sopt.smeem.domain.model.TrainingGoalSimple +import com.sopt.smeem.data.service.TrainingService +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.TrainingGoalDto +import com.sopt.smeem.domain.dto.TrainingGoalSimpleDto import com.sopt.smeem.domain.repository.TrainingRepository class TrainingRepositoryImpl( - private val trainingManager: TrainingManager + private val trainingService: TrainingService, ) : TrainingRepository { - override suspend fun getDetail(goal: TrainingGoalType?): Result = - kotlin.runCatching { - trainingManager.getDetail( - goal ?: throw SmeemException( - errorCode = SmeemErrorCode.SYSTEM_ERROR, - logMessage = "없는 트레이닝 목표에 대한 접근이 발생했습니다.", - throwable = IllegalArgumentException() - ) - ) - } - .map { - TrainingGoal( - title = it.data!!.title, - goal = it.data.name, - way = it.data.way, - detail = it.data.detail - ) + override suspend fun getDetail(goal: TrainingGoalType): ApiResult = + trainingService.getDetail(goal).let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), TrainingGoalDto( + title = data.title, + goal = data.name, + way = data.way, + detail = data.detail, + ) + ) + } + } else { + throw response.code().handleStatusCode() } + } - override suspend fun getAll(): Result = - kotlin.runCatching { - trainingManager.getAll() - }.map { - TrainingGoalSimple( - goalType = TrainingGoalType.valueOf(it.data!!.goalType), - name = it.data.name - ) + override suspend fun getAll(): ApiResult = + trainingService.getAll().let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), TrainingGoalSimpleDto( + goalType = TrainingGoalType.valueOf(data.goalType), + name = data.name, + ) + ) + } + } else { + throw response.code().handleStatusCode() + } } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/repository/UserRepositoryImpl.kt b/app/src/main/java/com/sopt/smeem/data/repository/UserRepositoryImpl.kt index 12e00deb..8a50211a 100644 --- a/app/src/main/java/com/sopt/smeem/data/repository/UserRepositoryImpl.kt +++ b/app/src/main/java/com/sopt/smeem/data/repository/UserRepositoryImpl.kt @@ -1,76 +1,212 @@ package com.sopt.smeem.data.repository -import com.sopt.smeem.LanguageCode import com.sopt.smeem.data.datasource.MyBadgeRetriever -import com.sopt.smeem.data.datasource.MyPageRetriever -import com.sopt.smeem.data.datasource.TrainingManager -import com.sopt.smeem.data.datasource.UserModifier +import com.sopt.smeem.data.model.request.PushRequest +import com.sopt.smeem.data.model.request.TrainingRequest +import com.sopt.smeem.data.model.request.UserInfoModifyingRequest +import com.sopt.smeem.data.service.UserService +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.LoginResultDto +import com.sopt.smeem.domain.dto.MyInfoDto +import com.sopt.smeem.domain.dto.MyPlanDto +import com.sopt.smeem.domain.dto.MySmeemDataDto +import com.sopt.smeem.domain.dto.PostOnBoardingDto import com.sopt.smeem.domain.model.Badge import com.sopt.smeem.domain.model.Day -import com.sopt.smeem.domain.model.LoginResult -import com.sopt.smeem.domain.model.MyPage -import com.sopt.smeem.domain.model.MyPageBadge -import com.sopt.smeem.domain.model.OnBoarding import com.sopt.smeem.domain.model.PushAlarm import com.sopt.smeem.domain.model.Training -import com.sopt.smeem.domain.model.TrainingGoal -import com.sopt.smeem.domain.model.TrainingTime import com.sopt.smeem.domain.repository.UserRepository class UserRepositoryImpl( - private val trainingManager: TrainingManager, - private val userModifier: UserModifier, - private val myPageRetriever: MyPageRetriever, + private val userService: UserService, + private val myBadgeRetriever: MyBadgeRetriever, ) : UserRepository { override suspend fun registerOnBoarding( - onBoarding: OnBoarding, - loginResult: LoginResult - ): Result = - kotlin.runCatching { trainingManager.registerOnBoarding(onBoarding, loginResult) } - - override suspend fun modifyUserInfo( - accessToken: String?, - username: String, - marketingAcceptance: Boolean? - ): Result = - kotlin.runCatching { - userModifier.patch( - accessToken = accessToken, - username = username, - marketingAcceptance = marketingAcceptance + onBoardingDto: PostOnBoardingDto, + loginResult: LoginResultDto + ): ApiResult = + userService.patchPlanOnAnonymous( + request = TrainingRequest( + target = onBoardingDto.trainingGoalType, + trainingTime = onBoardingDto.extractTime(), + hasAlarm = onBoardingDto.hasAlarm, + ), + token = "Bearer ${loginResult.apiAccessToken}", + ).let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), Unit) + } else { + throw response.code().handleStatusCode() + } + } + + override suspend fun modifyUsername(nickname: String): ApiResult = + userService.patchUserInfo( + UserInfoModifyingRequest(username = nickname) + ).let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), true) + } else { + throw response.code().handleStatusCode() + } + } + + override suspend fun registerUserInfo( + accessToken: String, + nickname: String, + marketingAcceptance: Boolean + ): ApiResult = + userService.patchUserInfoWithTokenFixed( + token = "Bearer $accessToken", + UserInfoModifyingRequest( + username = nickname, termAccepted = marketingAcceptance ) - }.map { true } + ).let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), true) + } else { + throw response.code().handleStatusCode() + } + } - override suspend fun getMyPage(): Result = - kotlin.runCatching { - myPageRetriever.getResponse() - }.map { response -> - MyPage( - username = response.data!!.username, - myPageBadge = MyPageBadge.from(response.data.badge), - hasPushAlarm = response.data.hasPushAlarm, - goal = TrainingGoal( - title = response.data.title, - goal = response.data.target, - detail = response.data.detail ?: "", - way = response.data.way ?: "" - ), - language = LanguageCode.en.language, - trainingTime = TrainingTime( - days = response.data.trainingTime!!.day.let { - if (it.isNotBlank()) { - it.split(",") - .map { Day.valueOf(it) } - .toSet() - } else emptySet() - } ?: emptySet(), - hour = response.data.trainingTime.hour, - minute = response.data.trainingTime.minute - ) + override suspend fun getMySmeemData(): ApiResult = + userService.getMySmeemData().let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), MySmeemDataDto( + visitDays = data.visitDays, + diaryCount = data.diaryCount, + diaryComboCount = data.diaryComboCount, + badgeCount = data.badgeCount, + ) + ) + } + } else { + throw response.code().handleStatusCode() + } + } + + + override suspend fun getMyPlanData(): ApiResult = + userService.getMyPlanData() + .let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), MyPlanDto( + plan = data.plan, + goal = data.goal, + clearedCount = data.clearedCount, + clearCount = data.clearCount, + ) + ) + } + } else { + throw response.code().handleStatusCode() + } + } + + + override suspend fun getMyInfo(): ApiResult = + userService.getMyInfo().let { response -> + if (response.isSuccessful) { + response.body()!!.data.let { data -> + ApiResult( + response.code(), MyInfoDto( + username = data.username, + way = data.way, + detail = data.detail, + targetLang = data.targetLang, + hasPushAlarm = data.hasPushAlarm, + trainingTime = data.trainingTime?.let { + MyInfoDto.MyTrainingTime( + day = it.day.split(",").map { Day.valueOf(it) } + .toSet(), + hour = it.hour, + minute = it.minute + ) + } + ) + ) + } + } else { + throw response.code().handleStatusCode() + } + } + + override suspend fun registerTraining( + accessToken: String, + training: Training + ): ApiResult = + userService.patchPlanWithFixedToken( + token = "Bearer $accessToken", + request = TrainingRequest( + target = training.type, + trainingTime = training.extractTime(), + hasAlarm = training.hasAlarm + ) + ).let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), Unit) + } else { + throw response.code().handleStatusCode() + } + + } + + override suspend fun editTraining(training: Training): ApiResult = + userService.patchPlan( + request = TrainingRequest( + target = training.type, + trainingTime = training.extractTime(), + hasAlarm = training.hasAlarm ) + ).let { resposne -> + if (resposne.isSuccessful) { + ApiResult(resposne.code(), Unit) + } else { + throw resposne.code().handleStatusCode() + } } + override suspend fun registerPushAlarm( + accessToken: String, + push: PushAlarm + ): ApiResult = + userService.patchPushWithFixedToken( + token = "Bearer $accessToken", + request = PushRequest(push.hasAlarm) + ).let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), Unit) + } else { + throw response.code().handleStatusCode() + } + } + + override suspend fun editPushAlarm(push: PushAlarm): ApiResult = + userService.patchPush( + request = PushRequest(push.hasAlarm) + ).let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), Unit) + } else { + throw response.code().handleStatusCode() + } + } + + override suspend fun deleteUser(): ApiResult = + userService.delete().let { response -> + if (response.isSuccessful) { + ApiResult(response.code(), Unit) + } else { + throw response.code().handleStatusCode() + } + } + + override suspend fun getMyBadges(): Result> = kotlin.runCatching { myBadgeRetriever.getResponse() @@ -87,18 +223,5 @@ class UserRepositoryImpl( ?: throw IllegalArgumentException("내부 로직 구현 오류") } - override suspend fun editTraining(accessToken: String?, training: Training): Result = - kotlin.runCatching { - trainingManager.patchTraining(accessToken, training) - } - override suspend fun editPushAlarm(accessToken: String?, push: PushAlarm): Result = - kotlin.runCatching { - trainingManager.patchPushAlarm(accessToken, push) - } - - override suspend fun deleteUser(): Result = - kotlin.runCatching { - userModifier.delete() - } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/service/DiaryService.kt b/app/src/main/java/com/sopt/smeem/data/service/DiaryService.kt index e38f9a0c..a29e9d64 100644 --- a/app/src/main/java/com/sopt/smeem/data/service/DiaryService.kt +++ b/app/src/main/java/com/sopt/smeem/data/service/DiaryService.kt @@ -4,6 +4,7 @@ import com.sopt.smeem.data.model.request.DiaryRequest import com.sopt.smeem.data.model.response.ApiResponse import com.sopt.smeem.data.model.response.DiaryResponse import com.sopt.smeem.data.model.response.DiaryWritingResponse +import retrofit2.Response import retrofit2.http.Body import retrofit2.http.DELETE import retrofit2.http.GET @@ -16,31 +17,31 @@ interface DiaryService { @POST("/api/v2/diaries") suspend fun post( @Body request: DiaryRequest.Writing - ): ApiResponse + ): Response> @PATCH("/api/v2/diaries/{diaryId}") suspend fun patch( @Body request: DiaryRequest.Editing, @Path("diaryId") diaryId: Long - ): ApiResponse + ): Response> @DELETE("/api/v2/diaries/{diaryId}") suspend fun delete( @Path("diaryId") diaryId: Long - ): ApiResponse + ): Response> @GET("/api/v2/diaries/{diaryId}") suspend fun getDetail( @Path("diaryId") diaryId: Long - ): ApiResponse + ): Response> // calendar related @GET("/api/v2/diaries") suspend fun getList( @Query("start") startDate: String, // yyyy-mm-dd @Query("end") endDate: String, // yyyy-mm-dd - ): ApiResponse + ): Response> @GET("/api/v2/topics/random") - suspend fun getTopic(): ApiResponse + suspend fun getTopic(): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/service/HealthService.kt b/app/src/main/java/com/sopt/smeem/data/service/HealthService.kt index e9cd267e..ea1c622f 100644 --- a/app/src/main/java/com/sopt/smeem/data/service/HealthService.kt +++ b/app/src/main/java/com/sopt/smeem/data/service/HealthService.kt @@ -1,9 +1,11 @@ package com.sopt.smeem.data.service import com.sopt.smeem.data.model.response.ApiResponse +import kotlinx.coroutines.flow.Flow +import retrofit2.Response import retrofit2.http.GET interface HealthService { @GET("/api/v2/test") - suspend fun getStatus(): ApiResponse + suspend fun getStatus(): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/service/LoginService.kt b/app/src/main/java/com/sopt/smeem/data/service/LoginService.kt index a4f2da0c..34b1b572 100644 --- a/app/src/main/java/com/sopt/smeem/data/service/LoginService.kt +++ b/app/src/main/java/com/sopt/smeem/data/service/LoginService.kt @@ -4,6 +4,8 @@ import com.sopt.smeem.data.model.request.LoginRequest import com.sopt.smeem.data.model.response.ApiResponse import com.sopt.smeem.data.model.response.LoginResponse import com.sopt.smeem.data.model.response.NicknameCheckResponse +import kotlinx.coroutines.flow.Flow +import retrofit2.Response import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.Header @@ -15,10 +17,10 @@ interface LoginService { suspend fun login( @Header(value = "Authorization") accessToken: String, @Body request: LoginRequest - ): ApiResponse + ): Response> @GET("/api/v2/members/nickname/check") suspend fun checkDuplicated( @Query("name") nickname: String - ): ApiResponse + ): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/service/MyPageService.kt b/app/src/main/java/com/sopt/smeem/data/service/MyPageService.kt deleted file mode 100644 index 757e4801..00000000 --- a/app/src/main/java/com/sopt/smeem/data/service/MyPageService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.sopt.smeem.data.service - -import com.sopt.smeem.data.model.response.ApiResponse -import com.sopt.smeem.data.model.response.MyPageResponse -import retrofit2.http.GET - -interface MyPageService { - @GET("/api/v2/members/me") - suspend fun getMyInfo(): ApiResponse -} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/service/TrainingService.kt b/app/src/main/java/com/sopt/smeem/data/service/TrainingService.kt index 305dec79..cb17fd6b 100644 --- a/app/src/main/java/com/sopt/smeem/data/service/TrainingService.kt +++ b/app/src/main/java/com/sopt/smeem/data/service/TrainingService.kt @@ -4,6 +4,8 @@ import com.sopt.smeem.TrainingGoalType import com.sopt.smeem.data.model.response.ApiResponse import com.sopt.smeem.data.model.response.TrainingGoalResponse import com.sopt.smeem.data.model.response.TrainingGoalSimpleResponse +import kotlinx.coroutines.flow.Flow +import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Path @@ -11,8 +13,8 @@ interface TrainingService { @GET("/api/v2/goals/{type}") suspend fun getDetail( @Path("type") path: TrainingGoalType - ): ApiResponse + ): Response> @GET("/api/v2/goals") - suspend fun getAll(): ApiResponse + suspend fun getAll(): Response> } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/data/service/UserService.kt b/app/src/main/java/com/sopt/smeem/data/service/UserService.kt index 66a47380..1cfa1236 100644 --- a/app/src/main/java/com/sopt/smeem/data/service/UserService.kt +++ b/app/src/main/java/com/sopt/smeem/data/service/UserService.kt @@ -4,8 +4,14 @@ import com.sopt.smeem.data.model.request.PushRequest import com.sopt.smeem.data.model.request.TrainingRequest import com.sopt.smeem.data.model.request.UserInfoModifyingRequest import com.sopt.smeem.data.model.response.ApiResponse +import com.sopt.smeem.data.model.response.MyInfoResponse +import com.sopt.smeem.data.model.response.MyPlanDataResponse +import com.sopt.smeem.data.model.response.MySmeemDataResponse +import kotlinx.coroutines.flow.Flow +import retrofit2.Response import retrofit2.http.Body import retrofit2.http.DELETE +import retrofit2.http.GET import retrofit2.http.Header import retrofit2.http.PATCH @@ -13,42 +19,52 @@ interface UserService { @PATCH("/api/v2/members/plan") suspend fun patchPlan( @Body request: TrainingRequest - ): ApiResponse + ): Response> @PATCH("/api/v2/members/plan") suspend fun patchPlanWithFixedToken( @Header("Authorization") token: String, @Body request: TrainingRequest, - ): ApiResponse + ): Response> @PATCH("/api/v2/members/plan") suspend fun patchPlanOnAnonymous( @Body request: TrainingRequest, @Header("Authorization") token: String - ): ApiResponse + ): Response> @PATCH("/api/v2/members") suspend fun patchUserInfo( @Body request: UserInfoModifyingRequest - ): ApiResponse + ): Response> @PATCH("/api/v2/members") suspend fun patchUserInfoWithTokenFixed( @Header("Authorization") token: String, @Body request: UserInfoModifyingRequest, - ): ApiResponse + ): Response> @PATCH("/api/v2/members/push") suspend fun patchPush( @Body request: PushRequest - ): ApiResponse + ): Response> @PATCH("/api/v2/members/push") suspend fun patchPushWithFixedToken( @Header("Authorization") token: String, @Body request: PushRequest - ): ApiResponse + ): Response> @DELETE("/api/v2/auth") - suspend fun delete(): ApiResponse + suspend fun delete(): Response> + + @GET("/api/v2/members/summary") + suspend fun getMySmeemData(): Response> + + @GET("/api/v2/members/plan") + suspend fun getMyPlanData(): Response> + + @GET("/api/v2/members/me") + suspend fun getMyInfo(): Response> + } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/ApiResult.kt b/app/src/main/java/com/sopt/smeem/domain/ApiResult.kt new file mode 100644 index 00000000..4402c946 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/ApiResult.kt @@ -0,0 +1,11 @@ +package com.sopt.smeem.domain + +import com.sopt.smeem.SmeemErrorCode +import com.sopt.smeem.SmeemException + +data class ApiResult( + val statusCode: Int, + private val data: DATA, +) { + fun data(): DATA = data ?: throw SmeemException(SmeemErrorCode.NETWORK_LOAD_ERROR) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/DeleteDiaryRequestDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/DeleteDiaryRequestDto.kt new file mode 100644 index 00000000..a9280f37 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/DeleteDiaryRequestDto.kt @@ -0,0 +1,5 @@ +package com.sopt.smeem.domain.dto + +data class DeleteDiaryRequestDto( + val id: Long, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/GetDiaryResponseDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/GetDiaryResponseDto.kt new file mode 100644 index 00000000..64c2644b --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/GetDiaryResponseDto.kt @@ -0,0 +1,11 @@ +package com.sopt.smeem.domain.dto + +import java.time.LocalDateTime + +data class GetDiaryResponseDto( + val id: Long, + val content: String, + val createdAt: LocalDateTime, + val username: String, + val topic: String? = null, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/GetDiarySummariesDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/GetDiarySummariesDto.kt new file mode 100644 index 00000000..af48394d --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/GetDiarySummariesDto.kt @@ -0,0 +1,15 @@ +package com.sopt.smeem.domain.dto + +import java.time.LocalDate +import java.time.LocalTime + +data class GetDiarySummariesDto( + val diaries: Map, + val has30Past: Boolean +) + +data class GetDiarySummaryDto( + val id: Long, + val content: String, + val createdAt: LocalTime, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/GetTopicDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/GetTopicDto.kt new file mode 100644 index 00000000..9f01b37f --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/GetTopicDto.kt @@ -0,0 +1,6 @@ +package com.sopt.smeem.domain.dto + +data class GetTopicDto( + val id: Long, + val content: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/HealthStatusDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/HealthStatusDto.kt new file mode 100644 index 00000000..4681fae1 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/HealthStatusDto.kt @@ -0,0 +1,5 @@ +package com.sopt.smeem.domain.dto + +data class HealthStatusDto( + val lived: Boolean, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/model/LoginResult.kt b/app/src/main/java/com/sopt/smeem/domain/dto/LoginResultDto.kt similarity index 75% rename from app/src/main/java/com/sopt/smeem/domain/model/LoginResult.kt rename to app/src/main/java/com/sopt/smeem/domain/dto/LoginResultDto.kt index 4f5b461b..029ca8e3 100644 --- a/app/src/main/java/com/sopt/smeem/domain/model/LoginResult.kt +++ b/app/src/main/java/com/sopt/smeem/domain/dto/LoginResultDto.kt @@ -1,16 +1,16 @@ -package com.sopt.smeem.domain.model +package com.sopt.smeem.domain.dto import com.sopt.smeem.data.model.response.LoginResponse -data class LoginResult( +data class LoginResultDto( val apiAccessToken: String, val apiRefreshToken: String, val isRegistered: Boolean, val isPlanRegistered: Boolean ) { companion object { - fun from(response: LoginResponse): LoginResult = - LoginResult( + fun from(response: LoginResponse): LoginResultDto = + LoginResultDto( apiAccessToken = response.accessToken, apiRefreshToken = response.refreshToken, isRegistered = response.isRegistered, diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/MyInfoDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/MyInfoDto.kt new file mode 100644 index 00000000..66143462 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/MyInfoDto.kt @@ -0,0 +1,18 @@ +package com.sopt.smeem.domain.dto + +import com.sopt.smeem.domain.model.Day + +data class MyInfoDto( + val username: String, + val way: String, + val detail: String, + val targetLang: String, + val hasPushAlarm: Boolean, + val trainingTime: MyTrainingTime?, +) { + data class MyTrainingTime( + val day: Set, + val hour: Int, + val minute: Int, + ) +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/MyPlanDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/MyPlanDto.kt new file mode 100644 index 00000000..ce6ac6af --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/MyPlanDto.kt @@ -0,0 +1,8 @@ +package com.sopt.smeem.domain.dto + +data class MyPlanDto( + val plan: String, + val goal: String, + val clearedCount: Int, + val clearCount: Int, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/MySmeemDataDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/MySmeemDataDto.kt new file mode 100644 index 00000000..0d22ed7a --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/MySmeemDataDto.kt @@ -0,0 +1,8 @@ +package com.sopt.smeem.domain.dto + +data class MySmeemDataDto( + val visitDays: Int, + val diaryCount: Int, + val diaryComboCount: Int, + val badgeCount: Int, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/PatchDiaryRequestDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/PatchDiaryRequestDto.kt new file mode 100644 index 00000000..7267d62a --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/PatchDiaryRequestDto.kt @@ -0,0 +1,6 @@ +package com.sopt.smeem.domain.dto + +data class PatchDiaryRequestDto( + val id: Long, + val content: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/PostOnBoardingDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/PostOnBoardingDto.kt new file mode 100644 index 00000000..96a8953b --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/PostOnBoardingDto.kt @@ -0,0 +1,25 @@ +package com.sopt.smeem.domain.dto + +import com.sopt.smeem.TrainingGoalType +import com.sopt.smeem.data.model.request.TrainingRequest +import com.sopt.smeem.domain.model.Day + +data class PostOnBoardingDto( + val trainingGoalType: TrainingGoalType, + val hasAlarm: Boolean, + val day: List = emptyList(), + val hour: Int?, + val minute: Int? +) { + fun extractTime(): TrainingRequest.TrainingTime? { + if (day.isEmpty()) { + return null + } + + return TrainingRequest.TrainingTime.of( + day = day, + hour = hour, + minute = minute + ) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/RetrievedBadgeDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/RetrievedBadgeDto.kt new file mode 100644 index 00000000..413d9fa1 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/RetrievedBadgeDto.kt @@ -0,0 +1,8 @@ +package com.sopt.smeem.domain.dto + +import java.io.Serializable + +data class RetrievedBadgeDto( + val name: String, + val imageUrl: String, +) : Serializable \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/model/TrainingGoal.kt b/app/src/main/java/com/sopt/smeem/domain/dto/TrainingGoalDto.kt similarity index 59% rename from app/src/main/java/com/sopt/smeem/domain/model/TrainingGoal.kt rename to app/src/main/java/com/sopt/smeem/domain/dto/TrainingGoalDto.kt index 24fd67d0..c725391a 100644 --- a/app/src/main/java/com/sopt/smeem/domain/model/TrainingGoal.kt +++ b/app/src/main/java/com/sopt/smeem/domain/dto/TrainingGoalDto.kt @@ -1,6 +1,6 @@ -package com.sopt.smeem.domain.model +package com.sopt.smeem.domain.dto -data class TrainingGoal( +data class TrainingGoalDto( val title: String, val goal: String, val way: String, diff --git a/app/src/main/java/com/sopt/smeem/domain/model/TrainingGoalSimple.kt b/app/src/main/java/com/sopt/smeem/domain/dto/TrainingGoalSimpleDto.kt similarity index 59% rename from app/src/main/java/com/sopt/smeem/domain/model/TrainingGoalSimple.kt rename to app/src/main/java/com/sopt/smeem/domain/dto/TrainingGoalSimpleDto.kt index 5e5b3d8a..f296482d 100644 --- a/app/src/main/java/com/sopt/smeem/domain/model/TrainingGoalSimple.kt +++ b/app/src/main/java/com/sopt/smeem/domain/dto/TrainingGoalSimpleDto.kt @@ -1,8 +1,8 @@ -package com.sopt.smeem.domain.model +package com.sopt.smeem.domain.dto import com.sopt.smeem.TrainingGoalType -data class TrainingGoalSimple( +data class TrainingGoalSimpleDto( val goalType: TrainingGoalType, val name: String ) diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryRequestDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryRequestDto.kt new file mode 100644 index 00000000..561a30a0 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryRequestDto.kt @@ -0,0 +1,6 @@ +package com.sopt.smeem.domain.dto + +data class WriteDiaryRequestDto( + val content: String, + val topicId: Long? = null, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryResponseDto.kt b/app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryResponseDto.kt new file mode 100644 index 00000000..7e056024 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/domain/dto/WriteDiaryResponseDto.kt @@ -0,0 +1,6 @@ +package com.sopt.smeem.domain.dto + +data class WriteDiaryResponseDto( + val diaryId: Long, + val retrievedBadgeList: List, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/model/MyPage.kt b/app/src/main/java/com/sopt/smeem/domain/model/MyPage.kt index e3852364..0efb9b8a 100644 --- a/app/src/main/java/com/sopt/smeem/domain/model/MyPage.kt +++ b/app/src/main/java/com/sopt/smeem/domain/model/MyPage.kt @@ -1,10 +1,12 @@ package com.sopt.smeem.domain.model +import com.sopt.smeem.domain.dto.TrainingGoalDto + data class MyPage( val username: String, val myPageBadge: MyPageBadge, val hasPushAlarm: Boolean, - val goal: TrainingGoal, + val goal: TrainingGoalDto, val language: Language, val trainingTime: TrainingTime ) diff --git a/app/src/main/java/com/sopt/smeem/domain/repository/DiaryRepository.kt b/app/src/main/java/com/sopt/smeem/domain/repository/DiaryRepository.kt index f2fe3657..8615a8c9 100644 --- a/app/src/main/java/com/sopt/smeem/domain/repository/DiaryRepository.kt +++ b/app/src/main/java/com/sopt/smeem/domain/repository/DiaryRepository.kt @@ -1,30 +1,20 @@ package com.sopt.smeem.domain.repository -import com.sopt.smeem.domain.model.Diary -import com.sopt.smeem.domain.model.DiarySummaries -import com.sopt.smeem.domain.model.RetrievedBadge -import com.sopt.smeem.domain.model.Topic +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.DeleteDiaryRequestDto +import com.sopt.smeem.domain.dto.GetDiaryResponseDto +import com.sopt.smeem.domain.dto.GetDiarySummariesDto +import com.sopt.smeem.domain.dto.GetTopicDto +import com.sopt.smeem.domain.dto.PatchDiaryRequestDto +import com.sopt.smeem.domain.dto.WriteDiaryRequestDto +import com.sopt.smeem.domain.dto.WriteDiaryResponseDto interface DiaryRepository { - /** - * 일기 내용을 서버로 전송합니다. - */ - suspend fun postDiary(diary: Diary): Result> - - /** - * 일기 내용을 수정합니다. - */ - suspend fun patchDiary(diary: Diary): Result - - /** - * 일기를 제거한다. - */ - suspend fun removeDiary(diaryId: Long): Result - - /** - * 일기를 상세 조회한다. - */ - suspend fun getDiaryDetail(diaryId: Long): Result + suspend fun postDiary(dto: WriteDiaryRequestDto): ApiResult + suspend fun patchDiary(dto: PatchDiaryRequestDto): ApiResult + suspend fun deleteDiary(dto: DeleteDiaryRequestDto): ApiResult + suspend fun getDiaryDetail(diaryId: Long): ApiResult + suspend fun getTopic(): ApiResult // calendar related /** @@ -53,10 +43,8 @@ interface DiaryRepository { * - Ex) * start : 2023-04-10, end : 2023-10-20 => 예외 발생 */ - suspend fun getDiaries(start: String? = null, end: String? = null): Result - - /** - * 일기 랜덤 주제를 조회합니다. - */ - suspend fun getTopic(): Result + suspend fun getDiaries( + start: String? = null, + end: String? = null + ): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/repository/HealthRepository.kt b/app/src/main/java/com/sopt/smeem/domain/repository/HealthRepository.kt index 5d7c7308..302e49bb 100644 --- a/app/src/main/java/com/sopt/smeem/domain/repository/HealthRepository.kt +++ b/app/src/main/java/com/sopt/smeem/domain/repository/HealthRepository.kt @@ -1,7 +1,7 @@ package com.sopt.smeem.domain.repository -import com.sopt.smeem.domain.model.health.HealthStatus +import com.sopt.smeem.domain.ApiResult interface HealthRepository { - suspend fun getHealth(): Result + suspend fun getHealth(): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/repository/LocalRepository.kt b/app/src/main/java/com/sopt/smeem/domain/repository/LocalRepository.kt index d6009015..fed87f6f 100644 --- a/app/src/main/java/com/sopt/smeem/domain/repository/LocalRepository.kt +++ b/app/src/main/java/com/sopt/smeem/domain/repository/LocalRepository.kt @@ -1,9 +1,12 @@ package com.sopt.smeem.domain.repository +import androidx.datastore.preferences.core.Preferences import com.sopt.smeem.LocalStatus import com.sopt.smeem.domain.model.Authentication interface LocalRepository { + suspend fun setStringValue(key: Preferences.Key, value: String) + suspend fun remove(key: Preferences.Key) suspend fun getAuthentication(): Authentication suspend fun setAuthentication(authentication: Authentication) suspend fun isAuthenticated(): Boolean diff --git a/app/src/main/java/com/sopt/smeem/domain/repository/LoginRepository.kt b/app/src/main/java/com/sopt/smeem/domain/repository/LoginRepository.kt index f41d4c72..c7506045 100644 --- a/app/src/main/java/com/sopt/smeem/domain/repository/LoginRepository.kt +++ b/app/src/main/java/com/sopt/smeem/domain/repository/LoginRepository.kt @@ -1,10 +1,15 @@ package com.sopt.smeem.domain.repository import com.sopt.smeem.SocialType -import com.sopt.smeem.domain.model.LoginResult +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.LoginResultDto interface LoginRepository { - suspend fun execute(accessToken: String, socialType: SocialType, fcmToken: String): Result + suspend fun execute( + accessToken: String, + socialType: SocialType, + fcmToken: String + ): ApiResult - suspend fun checkNicknameDuplicated(nickname: String): Result + suspend fun checkNicknameDuplicated(nickname: String): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/repository/TrainingRepository.kt b/app/src/main/java/com/sopt/smeem/domain/repository/TrainingRepository.kt index 6840f46e..c61b4b82 100644 --- a/app/src/main/java/com/sopt/smeem/domain/repository/TrainingRepository.kt +++ b/app/src/main/java/com/sopt/smeem/domain/repository/TrainingRepository.kt @@ -1,11 +1,12 @@ package com.sopt.smeem.domain.repository import com.sopt.smeem.TrainingGoalType -import com.sopt.smeem.domain.model.TrainingGoal -import com.sopt.smeem.domain.model.TrainingGoalSimple +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.TrainingGoalDto +import com.sopt.smeem.domain.dto.TrainingGoalSimpleDto interface TrainingRepository { - suspend fun getDetail(goal: TrainingGoalType?): Result + suspend fun getDetail(goal: TrainingGoalType): ApiResult - suspend fun getAll(): Result + suspend fun getAll(): ApiResult } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/domain/repository/UserRepository.kt b/app/src/main/java/com/sopt/smeem/domain/repository/UserRepository.kt index 9b447d32..1ad9c0d8 100644 --- a/app/src/main/java/com/sopt/smeem/domain/repository/UserRepository.kt +++ b/app/src/main/java/com/sopt/smeem/domain/repository/UserRepository.kt @@ -1,40 +1,45 @@ package com.sopt.smeem.domain.repository +import com.sopt.smeem.domain.ApiResult +import com.sopt.smeem.domain.dto.LoginResultDto +import com.sopt.smeem.domain.dto.MyInfoDto +import com.sopt.smeem.domain.dto.MyPlanDto +import com.sopt.smeem.domain.dto.MySmeemDataDto +import com.sopt.smeem.domain.dto.PostOnBoardingDto import com.sopt.smeem.domain.model.Badge -import com.sopt.smeem.domain.model.LoginResult -import com.sopt.smeem.domain.model.MyPage -import com.sopt.smeem.domain.model.OnBoarding import com.sopt.smeem.domain.model.PushAlarm import com.sopt.smeem.domain.model.Training interface UserRepository { - /** - * OnBoarding 결과 (학습 목표, 알람 여부, 알람 시간) 를 서버로 전송합니다. (사전에 로그인 없이 진입한 상태) - */ - suspend fun registerOnBoarding(onBoarding: OnBoarding, loginResult: LoginResult): Result - /** - * 닉네임 및 이용약관 정보를 서버로 전송합니다. - */ - suspend fun modifyUserInfo( - accessToken: String? = null, + suspend fun registerOnBoarding( + onBoardingDto: PostOnBoardingDto, + loginResult: LoginResultDto + ): ApiResult + + suspend fun modifyUsername(nickname: String): ApiResult + + suspend fun registerUserInfo( + accessToken: String, nickname: String, - marketingAcceptance: Boolean? = null - ): Result + marketingAcceptance: Boolean + ): ApiResult + + suspend fun getMySmeemData(): ApiResult + + suspend fun getMyPlanData(): ApiResult + + suspend fun getMyInfo(): ApiResult + + suspend fun registerTraining(accessToken: String, training: Training): ApiResult + suspend fun editTraining(training: Training): ApiResult + suspend fun registerPushAlarm(accessToken: String, push: PushAlarm): ApiResult + suspend fun editPushAlarm(push: PushAlarm): ApiResult + suspend fun deleteUser(): ApiResult - suspend fun getMyPage(): Result /** * 나의 뱃지 정보를 조회합니다. */ suspend fun getMyBadges(): Result> - - /** - * 트레이닝 정보를 수정합니다. - */ - suspend fun editTraining(accessToken: String? = null, training: Training): Result - - suspend fun editPushAlarm(accessToken: String? = null, push: PushAlarm): Result - - suspend fun deleteUser(): Result } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/module/AnonymousModule.kt b/app/src/main/java/com/sopt/smeem/module/AnonymousModule.kt index 31641768..b84202f8 100644 --- a/app/src/main/java/com/sopt/smeem/module/AnonymousModule.kt +++ b/app/src/main/java/com/sopt/smeem/module/AnonymousModule.kt @@ -1,17 +1,12 @@ package com.sopt.smeem.module import com.sopt.smeem.Anonymous -import com.sopt.smeem.data.datasource.LoginExecutor import com.sopt.smeem.data.datasource.MyBadgeRetriever -import com.sopt.smeem.data.datasource.MyPageRetriever -import com.sopt.smeem.data.datasource.TrainingManager -import com.sopt.smeem.data.datasource.UserModifier import com.sopt.smeem.data.repository.LoginRepositoryImpl import com.sopt.smeem.data.repository.TrainingRepositoryImpl import com.sopt.smeem.data.repository.UserRepositoryImpl import com.sopt.smeem.data.service.LoginService import com.sopt.smeem.data.service.MyBadgeService -import com.sopt.smeem.data.service.MyPageService import com.sopt.smeem.data.service.TrainingService import com.sopt.smeem.data.service.UserService import com.sopt.smeem.domain.repository.LoginRepository @@ -31,26 +26,19 @@ object AnonymousModule { @Anonymous fun anonymousMemberRepository(networkModule: NetworkModule): UserRepository = UserRepositoryImpl( - trainingManager = TrainingManager( - userService = networkModule.apiServerRetrofitForAnonymous.create(UserService::class.java), - trainingService = networkModule.apiServerRetrofitForAnonymous.create(TrainingService::class.java) + userService = networkModule.apiServerRetrofitForAnonymous.create(UserService::class.java), + myBadgeRetriever = MyBadgeRetriever( + networkModule.apiServerRetrofitForAnonymous.create( + MyBadgeService::class.java + ) ), - userModifier = UserModifier(networkModule.apiServerRetrofitForAnonymous.create(UserService::class.java)), - myPageRetriever = MyPageRetriever(networkModule.apiServerRetrofitForAnonymous.create(MyPageService::class.java)), - myBadgeRetriever = MyBadgeRetriever(networkModule.apiServerRetrofitForAnonymous.create(MyBadgeService::class.java)), ) @Provides @ViewModelScoped @Anonymous fun loginRepository(networkModule: NetworkModule): LoginRepository = - LoginRepositoryImpl( - LoginExecutor( - networkModule.apiServerRetrofitForAnonymous.create( - LoginService::class.java - ) - ) - ) + LoginRepositoryImpl(networkModule.apiServerRetrofitForAnonymous.create(LoginService::class.java)) @Provides @ViewModelScoped @@ -58,10 +46,10 @@ object AnonymousModule { fun trainingRepository( networkModule: NetworkModule ): TrainingRepository { - val trainingService = networkModule.apiServerRetrofitForAnonymous.create( - TrainingService::class.java + return TrainingRepositoryImpl( + networkModule.apiServerRetrofitForAnonymous.create( + TrainingService::class.java + ) ) - - return TrainingRepositoryImpl(TrainingManager(trainingService = trainingService)) } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/module/HealthCheckModule.kt b/app/src/main/java/com/sopt/smeem/module/HealthCheckModule.kt index 4ea1f8e2..4623e259 100644 --- a/app/src/main/java/com/sopt/smeem/module/HealthCheckModule.kt +++ b/app/src/main/java/com/sopt/smeem/module/HealthCheckModule.kt @@ -1,6 +1,5 @@ package com.sopt.smeem.module -import com.sopt.smeem.data.datasource.HealthChecker import com.sopt.smeem.data.repository.HealthRepositoryImpl import com.sopt.smeem.data.service.HealthService import com.sopt.smeem.domain.repository.HealthRepository @@ -18,8 +17,6 @@ object HealthCheckModule { fun healthRepository( networkModule: NetworkModule ): HealthRepository = HealthRepositoryImpl( - HealthChecker( - networkModule.apiServerRetrofitForAnonymous.create(HealthService::class.java) - ) + networkModule.apiServerRetrofitForAnonymous.create(HealthService::class.java) ) } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/module/UserModule.kt b/app/src/main/java/com/sopt/smeem/module/UserModule.kt index 0f11a35c..70a0b56d 100644 --- a/app/src/main/java/com/sopt/smeem/module/UserModule.kt +++ b/app/src/main/java/com/sopt/smeem/module/UserModule.kt @@ -1,17 +1,11 @@ package com.sopt.smeem.module -import com.sopt.smeem.data.datasource.DiaryCommander import com.sopt.smeem.data.datasource.DiaryReader import com.sopt.smeem.data.datasource.MyBadgeRetriever -import com.sopt.smeem.data.datasource.MyPageRetriever -import com.sopt.smeem.data.datasource.UserModifier -import com.sopt.smeem.data.datasource.TrainingManager import com.sopt.smeem.data.repository.DiaryRepositoryImpl import com.sopt.smeem.data.repository.UserRepositoryImpl import com.sopt.smeem.data.service.DiaryService import com.sopt.smeem.data.service.MyBadgeService -import com.sopt.smeem.data.service.MyPageService -import com.sopt.smeem.data.service.TrainingService import com.sopt.smeem.data.service.UserService import com.sopt.smeem.domain.repository.DiaryRepository import com.sopt.smeem.domain.repository.UserRepository @@ -27,24 +21,15 @@ object UserModule { @Provides @ViewModelScoped fun userRepository(networkModule: NetworkModule): UserRepository { - val userService = networkModule.apiServerRetrofitForAuthentication.create( - UserService::class.java - ) - val trainingService = networkModule.apiServerRetrofitForAuthentication.create( - TrainingService::class.java - ) - val myPageService = networkModule.apiServerRetrofitForAuthentication.create( - MyPageService::class.java - ) - val myBadgeRetriever = networkModule.apiServerRetrofitForAuthentication.create( - MyBadgeService::class.java - ) - return UserRepositoryImpl( - trainingManager = TrainingManager(userService, trainingService), - userModifier = UserModifier(userService), - myPageRetriever = MyPageRetriever(myPageService), - myBadgeRetriever = MyBadgeRetriever(myBadgeRetriever) + userService = networkModule.apiServerRetrofitForAuthentication.create( + UserService::class.java + ), + myBadgeRetriever = MyBadgeRetriever( + networkModule.apiServerRetrofitForAuthentication.create( + MyBadgeService::class.java + ) + ) ) } @@ -52,9 +37,7 @@ object UserModule { @ViewModelScoped fun diaryRepository(networkModule: NetworkModule): DiaryRepository { return DiaryRepositoryImpl( - diaryCommander = DiaryCommander( - networkModule.apiServerRetrofitForAuthentication.create(DiaryService::class.java) - ), + networkModule.apiServerRetrofitForAuthentication.create(DiaryService::class.java), diaryReader = DiaryReader( networkModule.apiServerRetrofitForAuthentication.create(DiaryService::class.java) ) diff --git a/app/src/main/java/com/sopt/smeem/presentation/IntentConstants.kt b/app/src/main/java/com/sopt/smeem/presentation/IntentConstants.kt new file mode 100644 index 00000000..57f74e6e --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/IntentConstants.kt @@ -0,0 +1,18 @@ +package com.sopt.smeem.presentation + +object IntentConstants { + const val RETRIEVED_BADGE_DTO = "retrievedBadgeDto" + const val SNACKBAR_TEXT = "snackbarText" + + // diary + const val DIARY_ID = "diaryId" + const val ORIGINAL_CONTENT = "originalContent" + const val RANDOM_TOPIC = "randomTopic" + + // goal + const val SELECTED_GOAL = "selectedGoal" + + // auth + const val ACCESS_TOKEN = "accessToken" + const val REFRESH_TOKEN = "refreshToken" +} \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/auth/OAuthProcessor.kt b/app/src/main/java/com/sopt/smeem/presentation/auth/OAuthProcessor.kt index ac405367..aefded4c 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/auth/OAuthProcessor.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/auth/OAuthProcessor.kt @@ -52,7 +52,6 @@ object KakaoHandler : OAuthHandler { throw SmeemException( errorCode = SmeemErrorCode.CLIENT_ERROR, logMessage = "카카오 로그인 중 client 에서 발생시킨 에러 ${error.reason}", - throwable = error ) } @@ -60,7 +59,6 @@ object KakaoHandler : OAuthHandler { throw SmeemException( errorCode = SmeemErrorCode.CLIENT_ERROR, logMessage = "카카오 로그인 중 인증 과정에서 발생된 에러 (${error.reason})", - throwable = error ) } @@ -68,7 +66,6 @@ object KakaoHandler : OAuthHandler { throw SmeemException( errorCode = SmeemErrorCode.CLIENT_ERROR, logMessage = "KAKAO API 호출 중 발생된 에러 (${error.reason})", - throwable = error ) } @@ -76,7 +73,6 @@ object KakaoHandler : OAuthHandler { throw SmeemException( errorCode = SmeemErrorCode.SYSTEM_ERROR, logMessage = "카카오 로그인 중 비정상적으로 발생된 에러", - throwable = error ) } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetail.kt b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetail.kt new file mode 100644 index 00000000..e6b9be58 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetail.kt @@ -0,0 +1,9 @@ +package com.sopt.smeem.presentation.detail + +data class DiaryDetail( + val diaryId: Long, + val topic: String?, + val content: String, + val createdAt: String, + val writerUsername: String, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailActivity.kt index 670e5865..837c5173 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailActivity.kt @@ -6,10 +6,10 @@ import android.widget.Toast import androidx.activity.viewModels import com.sopt.smeem.R import com.sopt.smeem.databinding.ActivityDiaryDetailBinding -import com.sopt.smeem.description import com.sopt.smeem.event.AmplitudeEventType import com.sopt.smeem.presentation.BindingActivity import com.sopt.smeem.presentation.EventVM +import com.sopt.smeem.presentation.IntentConstants.DIARY_ID import com.sopt.smeem.presentation.home.HomeActivity import com.sopt.smeem.util.setOnSingleClickListener import dagger.hilt.android.AndroidEntryPoint @@ -23,13 +23,13 @@ class DiaryDetailActivity : override fun constructLayout() { // databinding - binding.vm = viewModel binding.lifecycleOwner = this // data - viewModel.diaryId = intent.getLongExtra("diaryId", -1) - viewModel.getDiaryDetail { e-> - Toast.makeText(this, e.description(), Toast.LENGTH_SHORT).show() + viewModel.setDiaryId(intent.getLongExtra(DIARY_ID, -1)) + viewModel.getDiaryDetail { t -> + Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show() } + eventVm.sendEvent(AmplitudeEventType.MY_DIARY_CLICK) } @@ -38,11 +38,18 @@ class DiaryDetailActivity : finish() } binding.btnDiaryDetailMenu.setOnSingleClickListener { - DiaryDetailBottomSheet(viewModel, eventVm).show(supportFragmentManager, DiaryDetailBottomSheet.TAG) + DiaryDetailBottomSheet(viewModel, eventVm).show( + supportFragmentManager, + DiaryDetailBottomSheet.TAG + ) } } override fun addObservers() { + viewModel.diaryDetailResult.observe(this) { + binding.diaryDetail = it + } + viewModel.isTopicExist.observe(this) { if (!it) binding.layoutDiaryDetailRandomTopic.layoutSection.visibility = View.GONE } diff --git a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailBottomSheet.kt b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailBottomSheet.kt index 8430530b..f40157b6 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailBottomSheet.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailBottomSheet.kt @@ -7,19 +7,15 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.Toast -import androidx.datastore.preferences.core.edit -import androidx.lifecycle.lifecycleScope import com.google.android.material.bottomsheet.BottomSheetDialogFragment import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.sopt.smeem.R -import com.sopt.smeem.data.SmeemDataStore.RECENT_DIARY_DATE -import com.sopt.smeem.data.SmeemDataStore.dataStore import com.sopt.smeem.databinding.BottomSheetDiaryDetailBinding -import com.sopt.smeem.description import com.sopt.smeem.event.AmplitudeEventType import com.sopt.smeem.presentation.EventVM -import kotlinx.coroutines.launch -import java.time.LocalDate +import com.sopt.smeem.presentation.IntentConstants.DIARY_ID +import com.sopt.smeem.presentation.IntentConstants.ORIGINAL_CONTENT +import com.sopt.smeem.presentation.IntentConstants.RANDOM_TOPIC class DiaryDetailBottomSheet( private val viewModel: DiaryDetailViewModel, @@ -27,8 +23,6 @@ class DiaryDetailBottomSheet( ) : BottomSheetDialogFragment() { private var _binding: BottomSheetDiaryDetailBinding? = null private val binding get() = requireNotNull(_binding) - - private lateinit var viewModelDate: LocalDate private lateinit var fragmentContext: Context override fun onAttach(context: Context) { @@ -43,8 +37,6 @@ class DiaryDetailBottomSheet( ): View { _binding = BottomSheetDiaryDetailBinding.inflate(inflater, container, false) - viewModelDate = viewModel.date.value?.toLocalDate()!! - return binding.root } @@ -66,9 +58,9 @@ class DiaryDetailBottomSheet( private fun moveToEdit() { Intent(requireContext(), DiaryEditActivity::class.java).apply { - putExtra("diaryId", viewModel.diaryId) - putExtra("originalContent", viewModel.diary.value) - putExtra("randomTopic", viewModel.topic.value) + putExtra(DIARY_ID, viewModel.getDiaryId()) + putExtra(ORIGINAL_CONTENT, viewModel.getContent()) + putExtra(RANDOM_TOPIC, viewModel.getTopic()) }.run(::startActivity) eventViewModel.sendEvent(AmplitudeEventType.MY_DIARY_EDIT) } @@ -79,20 +71,9 @@ class DiaryDetailBottomSheet( .setNegativeButton("아니요") { dialog, which -> } .setPositiveButton("예") { dialog, which -> viewModel.deleteDiary( - onSuccess = { - // 오늘 작성한 일기일 때만 일기 삭제 시 datastore의 최근 일기 날짜 삭제 - if (viewModelDate.isEqual(LocalDate.now())) { - lifecycleScope.launch { - fragmentContext.dataStore.edit { storage -> - storage.remove(RECENT_DIARY_DATE) - } - } - } - viewModel.isDiaryDeleted.value = true - dismiss() - }, - onError = { e -> - Toast.makeText(requireContext(), e.description(), Toast.LENGTH_SHORT).show() + onSuccess = { dismiss() }, + onError = { t -> + Toast.makeText(requireContext(), t.message, Toast.LENGTH_SHORT).show() }, ) } diff --git a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailViewModel.kt index 1c71820f..1e0d634c 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryDetailViewModel.kt @@ -5,56 +5,95 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.map import androidx.lifecycle.viewModelScope +import com.sopt.smeem.SmeemErrorCode import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure +import com.sopt.smeem.data.SmeemDataStore +import com.sopt.smeem.domain.dto.DeleteDiaryRequestDto import com.sopt.smeem.domain.repository.DiaryRepository -import com.sopt.smeem.util.TextUtil.toLocalDateTime +import com.sopt.smeem.domain.repository.LocalRepository +import com.sopt.smeem.util.DateUtil import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch +import java.time.LocalDate import java.time.LocalDateTime import javax.inject.Inject @HiltViewModel class DiaryDetailViewModel @Inject constructor( private val diaryRepository: DiaryRepository, + private val localRepository: LocalRepository, ) : ViewModel() { - var diaryId: Long? = -1 + private var diaryId: Long = -1L + private lateinit var diaryCreatedAt: LocalDateTime - val topic = MutableLiveData() - val diary = MutableLiveData() - private val _date = MutableLiveData() - val date: LiveData = _date - val dateForUI = MutableLiveData() - val writer = MutableLiveData() - - val isTopicExist: LiveData = topic.map { it != "" } + private val _diaryDetailResult: MutableLiveData = MutableLiveData() + val diaryDetailResult: LiveData + get() = _diaryDetailResult + val isTopicExist: LiveData = _diaryDetailResult.map { !it.topic.isNullOrBlank() } val isDiaryDeleted = MutableLiveData(false) - fun getDiaryDetail(onError: (SmeemException) -> Unit) { + fun getDiaryId() = diaryDetailResult.value!!.diaryId + fun getContent() = diaryDetailResult.value!!.content + fun getTopic() = diaryDetailResult.value!!.topic + + fun setDiaryId(diaryId: Long) { + if (diaryId < 0) { + throw SmeemException(SmeemErrorCode.SYSTEM_ERROR, "잘못된 diaryId ($diaryId) 입니다.") + } + this.diaryId = diaryId + } + + fun getDiaryDetail(onError: (Throwable) -> Unit) { viewModelScope.launch { - diaryRepository.getDiaryDetail(diaryId!!) - .onSuccess { - diaryId = it.id - topic.value = it.topic - diary.value = it.content - _date.value = it.createdAt?.toLocalDateTime() - writer.value = it.username - dateForUI.value = - it.createdAt?.toLocalDateTime() - ?.let { date -> com.sopt.smeem.util.DateUtil.asString(date) } + try { + diaryRepository.getDiaryDetail(diaryId).run { + data().let { dto -> + _diaryDetailResult.value = DiaryDetail( + diaryId = dto.id, + topic = dto.topic, + content = dto.content, + createdAt = DateUtil.asString(dto.createdAt), + writerUsername = dto.username + ) + diaryCreatedAt = dto.createdAt + + } } - .onHttpFailure { e -> onError(e) } + } catch (t: Throwable) { + onError(t) + } } } - fun deleteDiary(onSuccess: (Unit) -> Unit, onError: (SmeemException) -> Unit) { + fun deleteDiary( + onSuccess: (Unit) -> Unit, + onError: (Throwable) -> Unit + ) { viewModelScope.launch { - diaryId?.let { - diaryRepository.removeDiary(it) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } - } + launch { requestToServer(diaryId, onSuccess, onError) } + // 오늘 작성한 일기일 때만 일기 삭제 시 datastore의 최근 일기 날짜 삭제 + launch { updateRecentDiaryDateOnLocal() } + } + } + + private suspend fun requestToServer( + diaryId: Long, + onSuccess: (Unit) -> Unit, + onError: (Throwable) -> Unit + ) = coroutineScope { + try { + diaryRepository.deleteDiary(DeleteDiaryRequestDto(diaryId)).run { onSuccess(Unit) } + } catch (t: Throwable) { + onError(t) + } + } + + private suspend fun updateRecentDiaryDateOnLocal() = coroutineScope { + if (diaryCreatedAt.toLocalDate().isEqual(LocalDate.now())) { + localRepository.remove(SmeemDataStore.RECENT_DIARY_DATE) + isDiaryDeleted.value = true } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditActivity.kt index cb14425d..b4cc74d4 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditActivity.kt @@ -7,11 +7,11 @@ import androidx.activity.viewModels import com.sopt.smeem.DefaultSnackBar import com.sopt.smeem.R import com.sopt.smeem.databinding.ActivityDiaryEditBinding -import com.sopt.smeem.description import com.sopt.smeem.presentation.BindingActivity +import com.sopt.smeem.presentation.IntentConstants.SNACKBAR_TEXT import com.sopt.smeem.presentation.home.HomeActivity -import com.sopt.smeem.util.showSnackbar import dagger.hilt.android.AndroidEntryPoint +import timber.log.Timber @AndroidEntryPoint class DiaryEditActivity : BindingActivity(R.layout.activity_diary_edit) { @@ -23,7 +23,7 @@ class DiaryEditActivity : BindingActivity(R.layout.act binding.lifecycleOwner = this // ui viewModel.diaryId = intent.getLongExtra("diaryId", -1) - with (binding.etDiaryEditContent) { + with(binding.etDiaryEditContent) { requestFocus() viewModel.diary.value = intent.getStringExtra("originalContent") postDelayed( @@ -62,15 +62,20 @@ class DiaryEditActivity : BindingActivity(R.layout.act viewModel.editDiary( onSuccess = { Intent(this, HomeActivity::class.java).apply { - putExtra("snackbarText", resources.getString(R.string.diary_edit_done_message)) + putExtra( + SNACKBAR_TEXT, + resources.getString(R.string.diary_edit_done_message) + ) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP }.run(::startActivity) }, - onError = { e -> - Toast.makeText(this, e.description(), Toast.LENGTH_SHORT).show() + onError = { t -> + Timber.e(t) + Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show() } ) } + else -> { DefaultSnackBar.make(binding.root, "외국어를 포함해 일기를 작성해 주세요 :(").show() } @@ -85,6 +90,7 @@ class DiaryEditActivity : BindingActivity(R.layout.act resources.getColor(R.color.point, null) ) } + false -> { binding.btnDiaryEditDone.setTextColor( resources.getColor(R.color.gray_300, null) diff --git a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditViewModel.kt index 38c00cc7..b5048396 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/detail/DiaryEditViewModel.kt @@ -1,14 +1,11 @@ package com.sopt.smeem.presentation.detail -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.map import androidx.lifecycle.viewModelScope -import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure -import com.sopt.smeem.domain.model.Diary +import com.sopt.smeem.domain.dto.PatchDiaryRequestDto import com.sopt.smeem.domain.repository.DiaryRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -18,21 +15,32 @@ import javax.inject.Inject class DiaryEditViewModel @Inject constructor( private val diaryRepository: DiaryRepository ) : ViewModel() { - var diaryId: Long? = -1 + var diaryId: Long = -1 val diary = MutableLiveData() val isValidDiary: LiveData = diary.map { isValidDiaryFormat(it) } - fun editDiary(onSuccess: (Unit) -> Unit, onError: (SmeemException) -> Unit) { - viewModelScope.launch { - diaryRepository.patchDiary( - Diary( - id = diaryId, - content = diary.value!! + fun editDiary(onSuccess: (Unit) -> Unit, onError: (Throwable) -> Unit) { + diary.value?.let { content -> + viewModelScope.launch { + requestToServer( + PatchDiaryRequestDto(diaryId, content), + onSuccess, + onError ) - ) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } + } + } + } + + private suspend fun requestToServer( + dto: PatchDiaryRequestDto, + onSuccess: (Unit) -> Unit, + onError: (Throwable) -> Unit + ) { + try { + diaryRepository.patchDiary(dto).run { onSuccess(Unit) } + } catch (t: Throwable) { + onError(t) } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/health/HealthStatus.kt b/app/src/main/java/com/sopt/smeem/presentation/health/HealthStatus.kt new file mode 100644 index 00000000..aebd17f5 --- /dev/null +++ b/app/src/main/java/com/sopt/smeem/presentation/health/HealthStatus.kt @@ -0,0 +1,5 @@ +package com.sopt.smeem.presentation.health + +data class HealthStatus( + val lived: Boolean, +) \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/health/ViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/health/ViewModel.kt index a37c43e6..000006f5 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/health/ViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/health/ViewModel.kt @@ -3,8 +3,6 @@ package com.sopt.smeem.presentation.health import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope -import com.sopt.smeem.data.ApiPool.onHttpFailure -import com.sopt.smeem.domain.model.health.HealthStatus import com.sopt.smeem.domain.repository.HealthRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -22,9 +20,10 @@ internal open class ViewModel @Inject constructor() : androidx.lifecycle.ViewMod fun connect(onError: (Throwable) -> Unit) { viewModelScope.launch { - healthRepository.getHealth().apply { - this.onSuccess { _result.value = it } - this.onHttpFailure { e -> onError(e) } + try { + _result.value = healthRepository.getHealth().run { HealthStatus(true) } + } catch (t: Throwable) { + onError(t) } } } diff --git a/app/src/main/java/com/sopt/smeem/domain/model/DiarySummaries.kt b/app/src/main/java/com/sopt/smeem/presentation/home/DiarySummaries.kt similarity index 86% rename from app/src/main/java/com/sopt/smeem/domain/model/DiarySummaries.kt rename to app/src/main/java/com/sopt/smeem/presentation/home/DiarySummaries.kt index 086f2235..df8b3664 100644 --- a/app/src/main/java/com/sopt/smeem/domain/model/DiarySummaries.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/DiarySummaries.kt @@ -1,4 +1,4 @@ -package com.sopt.smeem.domain.model +package com.sopt.smeem.presentation.home import java.time.LocalDate import java.time.LocalTime diff --git a/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt index df7abd4a..2b2ffa57 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/home/HomeViewModel.kt @@ -6,10 +6,8 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sopt.smeem.Smeem import com.sopt.smeem.domain.model.Date -import com.sopt.smeem.domain.model.DiarySummary import com.sopt.smeem.domain.repository.DiaryRepository import com.sopt.smeem.event.AmplitudeEventType -import com.sopt.smeem.presentation.home.calendar.core.CalendarState import com.sopt.smeem.presentation.home.calendar.core.Period import com.sopt.smeem.util.DateUtil import com.sopt.smeem.util.getNextDates @@ -27,7 +25,6 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.zip import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import timber.log.Timber import java.time.LocalDate import java.time.YearMonth @@ -80,6 +77,7 @@ class HomeViewModel @Inject constructor( // diary private suspend fun getDates(startDate: LocalDate, period: Period): List { + var diaryDates: List = emptyList() val endDate = when (period) { Period.WEEK -> startDate.plusDays(END_DATE_AFTER_THREE_WEEKS) Period.MONTH -> startDate.plusMonths(START_DATE_AFTER_THREE_MONTHS).minusDays(1) @@ -88,28 +86,33 @@ class HomeViewModel @Inject constructor( val endAsString = DateUtil.WithServer.asStringOnlyDate(endDate) return viewModelScope.async { - kotlin.runCatching { + try { diaryRepository.getDiaries(startAsString, endAsString) - }.fold({ - it.getOrNull()?.diaries?.keys?.toList() ?: emptyList() - }, { - Timber.e(it.message.toString()) - emptyList() - }) + .run { diaryDates = data().diaries.keys.toList() } + } catch (t: Throwable) { + Timber.e(t) + } + diaryDates }.await() } private suspend fun getDateDiary(date: LocalDate) { val dateAsString = DateUtil.WithServer.asStringOnlyDate(date) - kotlin.runCatching { + + try { diaryRepository.getDiaries(start = dateAsString, end = dateAsString) - }.fold({ - _diaryList.postValue( - it.getOrNull()?.diaries?.values?.firstOrNull(), - ) - }, { - Timber.e(it.message.toString()) - }) + .run { + _diaryList.postValue(data().diaries.values.first().let { dto -> + DiarySummary( + id = dto.id, + content = dto.content, + createdAt = dto.createdAt + ) + }) + } + } catch (t: Throwable) { + Timber.e(t) + } } fun setBadgeInfo(name: String, imageUrl: String, isFirst: Boolean) { diff --git a/app/src/main/java/com/sopt/smeem/presentation/join/JoinNicknameVM.kt b/app/src/main/java/com/sopt/smeem/presentation/join/JoinNicknameVM.kt index a797cedf..52407148 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/join/JoinNicknameVM.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/join/JoinNicknameVM.kt @@ -5,7 +5,6 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sopt.smeem.Anonymous -import com.sopt.smeem.data.ApiPool.onHttpFailure import com.sopt.smeem.domain.repository.LoginRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch @@ -24,11 +23,13 @@ class JoinNicknameVM @Inject constructor( fun callApiNicknameDuplicated(onError: (Throwable) -> Unit) { viewModelScope.launch { - loginRepository.checkNicknameDuplicated(content) - .onSuccess { result -> - _nicknameDuplicated.value = result + try { + loginRepository.checkNicknameDuplicated(content).run { + _nicknameDuplicated.value = data() } - .onHttpFailure { onError(it) } + } catch (t: Throwable) { + onError(t) + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/join/JoinVM.kt b/app/src/main/java/com/sopt/smeem/presentation/join/JoinVM.kt index b43fc179..bb41be99 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/join/JoinVM.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/join/JoinVM.kt @@ -1,13 +1,10 @@ package com.sopt.smeem.presentation.join -import android.widget.Button import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sopt.smeem.Anonymous -import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure import com.sopt.smeem.domain.model.Authentication import com.sopt.smeem.domain.repository.LocalRepository import com.sopt.smeem.domain.repository.UserRepository @@ -52,12 +49,15 @@ class JoinVM @Inject constructor( nickname: String, selected: Set, accessToken: String, - onError: (SmeemException) -> Unit + onError: (Throwable) -> Unit ) { viewModelScope.launch { - userRepository.modifyUserInfo(accessToken, nickname, selected.contains(MARKETING)) - .onSuccess { _joinSucceed.value = true } - .onHttpFailure { e -> onError(e) } + try { + userRepository.registerUserInfo(accessToken, nickname, selected.contains(MARKETING)) + .run { _joinSucceed.value = true } + } catch (t: Throwable) { + onError(t) + } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/join/JoinWithAgreementActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/join/JoinWithAgreementActivity.kt index 7d9e8916..12e762c0 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/join/JoinWithAgreementActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/join/JoinWithAgreementActivity.kt @@ -33,8 +33,8 @@ class JoinWithAgreementActivity : private lateinit var refreshToken: String override fun constructLayout() { - accessToken = intent.getStringExtra(ACCESS_TOKEN) ?: throw SmeemException(SmeemErrorCode.SYSTEM_ERROR, "토큰이 정상적으로 전달되지 않았습니다.", IllegalStateException()) - refreshToken = intent.getStringExtra(REFRESH_TOKEN) ?: throw SmeemException(SmeemErrorCode.SYSTEM_ERROR, "토큰이 정상적으로 전달되지 않았습니다.", IllegalStateException()) + accessToken = intent.getStringExtra(ACCESS_TOKEN) ?: throw SmeemException(SmeemErrorCode.SYSTEM_ERROR, "토큰이 정상적으로 전달되지 않았습니다.") + refreshToken = intent.getStringExtra(REFRESH_TOKEN) ?: throw SmeemException(SmeemErrorCode.SYSTEM_ERROR, "토큰이 정상적으로 전달되지 않았습니다.") EntranceSelection.SERVICE.id = binding.btnEntranceAgreementService.id @@ -150,7 +150,7 @@ class JoinWithAgreementActivity : selected, accessToken, onError = { e -> - Toast.makeText(this@JoinWithAgreementActivity, e.description(), Toast.LENGTH_SHORT) + Toast.makeText(this@JoinWithAgreementActivity, e.message, Toast.LENGTH_SHORT) .show() } ) diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/ChangingNicknameActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/ChangingNicknameActivity.kt index 3752b0d9..b7fcf2b4 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/ChangingNicknameActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/ChangingNicknameActivity.kt @@ -11,7 +11,6 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sopt.smeem.Anonymous import com.sopt.smeem.R -import com.sopt.smeem.data.ApiPool.onHttpFailure import com.sopt.smeem.databinding.ActivityChangingNicknameBinding import com.sopt.smeem.domain.repository.LoginRepository import com.sopt.smeem.domain.repository.UserRepository @@ -38,7 +37,7 @@ class ChangingNicknameActivity : } private fun setUpData() { - with (binding.etChangeNickname) { + with(binding.etChangeNickname) { setText(intent.getStringExtra("originalNickname")) requestFocus() } @@ -47,7 +46,10 @@ class ChangingNicknameActivity : private fun onTextWrite() { binding.etChangeNickname.addTextChangedListener( onTextChanged = { name, _, _, _ -> - if (name.isNullOrBlank() || name.length > 10 || name.toString() == intent.getStringExtra("originalNickname")) { + if (name.isNullOrBlank() || name.length > 10 || name.toString() == intent.getStringExtra( + "originalNickname" + ) + ) { nextButtonOff() } else { nextButtonOn() @@ -125,22 +127,21 @@ class ChangingNicknameVM @Inject constructor( val nicknameDuplicated: LiveData get() = _nicknameDuplicated - fun send(name: String): Unit // TODO : nickname 변경 api call + fun send(name: String) // TODO : nickname 변경 api call { viewModelScope.launch { - userRepository.modifyUserInfo( - nickname = name - ) + userRepository.modifyUsername(nickname = name) } } fun callApiNicknameDuplicated(onError: (Throwable) -> Unit) { viewModelScope.launch { - loginRepository.checkNicknameDuplicated(content) - .onSuccess { result -> - _nicknameDuplicated.value = result - } - .onHttpFailure { onError(it) } + try { + loginRepository.checkNicknameDuplicated(content) + .run { _nicknameDuplicated.value = data() } + } catch (t: Throwable) { + onError(t) + } } } } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/DisplayTrainingGoalActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/DisplayTrainingGoalActivity.kt index 4f51c0a2..54ceef4d 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/DisplayTrainingGoalActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/DisplayTrainingGoalActivity.kt @@ -11,6 +11,8 @@ import com.sopt.smeem.TrainingGoalType import com.sopt.smeem.databinding.ActivityDisplayTrainingGoalBinding import com.sopt.smeem.description import com.sopt.smeem.presentation.BindingActivity +import com.sopt.smeem.presentation.IntentConstants.SELECTED_GOAL +import com.sopt.smeem.presentation.IntentConstants.SNACKBAR_TEXT import com.sopt.smeem.util.setOnSingleClickListener import dagger.hilt.android.AndroidEntryPoint @@ -32,9 +34,9 @@ class DisplayTrainingGoalActivity : BindingActivity - Toast.makeText(applicationContext, e.description(), Toast.LENGTH_SHORT).show() + viewModel.setSelectedGoal(intent.getSerializableExtra(SELECTED_GOAL) as TrainingGoalType) + viewModel.getGoalDetail { t -> + Toast.makeText(applicationContext, t.message, Toast.LENGTH_SHORT).show() } } @@ -48,11 +50,11 @@ class DisplayTrainingGoalActivity : BindingActivity - Toast.makeText(this, e.errorCode.message, Toast.LENGTH_SHORT).show() + Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show() } ) Intent(this, MyPageActivity::class.java).apply { - putExtra("snackbarText", resources.getString(R.string.my_page_edit_done_message)) + putExtra(SNACKBAR_TEXT, resources.getString(R.string.my_page_edit_done_message)) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP }.run(::startActivity) } diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeActivity.kt index 83218c4f..b311ccca 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeActivity.kt @@ -10,6 +10,7 @@ import com.sopt.smeem.databinding.ActivityEditTrainingTimeBinding import com.sopt.smeem.description import com.sopt.smeem.domain.model.TrainingTime import com.sopt.smeem.presentation.BindingActivity +import com.sopt.smeem.presentation.IntentConstants.SNACKBAR_TEXT import com.sopt.smeem.util.ButtonUtil.switchOff import com.sopt.smeem.util.ButtonUtil.switchOn import com.sopt.smeem.util.DateUtil @@ -100,11 +101,11 @@ class EditTrainingTimeActivity : private fun onTouchComplete() { binding.btnMyPageEditTime.setOnSingleClickListener { - viewModel.sendServer { e -> - Toast.makeText(applicationContext, e.description(), Toast.LENGTH_SHORT).show() + viewModel.sendServer { t -> + Toast.makeText(applicationContext, t.message, Toast.LENGTH_SHORT).show() } Intent(this, MyPageActivity::class.java).apply { - putExtra("snackbarText", resources.getString(R.string.my_page_edit_done_message)) + putExtra(SNACKBAR_TEXT, resources.getString(R.string.my_page_edit_done_message)) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP }.run(::startActivity) } diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeViewModel.kt index cd906ec0..91d8bc5a 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingTimeViewModel.kt @@ -3,13 +3,13 @@ package com.sopt.smeem.presentation.mypage import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope -import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure import com.sopt.smeem.domain.model.Day import com.sopt.smeem.domain.model.Training import com.sopt.smeem.domain.model.TrainingTime import com.sopt.smeem.domain.repository.UserRepository import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch import javax.inject.Inject @@ -35,11 +35,21 @@ class EditTrainingTimeViewModel @Inject constructor( fun canConfirmEdit() = days.isNotEmpty() && (TrainingTime(days, hour.value!!, minute.value!!) != originalTime) - fun sendServer(onError: (SmeemException) -> Unit) { + fun sendServer(onError: (Throwable) -> Unit) { viewModelScope.launch { - userRepository.editTraining( - training = Training(trainingTime = TrainingTime(days, hour.value!!, minute.value!!)) - ).onHttpFailure { e -> onError(e) } + try { + userRepository.editTraining( + Training( + trainingTime = TrainingTime( + days, + hour.value!!, + minute.value!! + ) + ) + ) + } catch (t: Throwable) { + onError(t) + } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingVM.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingVM.kt index c5565972..4d7aed05 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingVM.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/EditTrainingVM.kt @@ -5,11 +5,9 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.sopt.smeem.Anonymous -import com.sopt.smeem.SmeemException import com.sopt.smeem.TrainingGoalType -import com.sopt.smeem.data.ApiPool.onHttpFailure +import com.sopt.smeem.domain.dto.TrainingGoalDto import com.sopt.smeem.domain.model.Training -import com.sopt.smeem.domain.model.TrainingGoal import com.sopt.smeem.domain.repository.TrainingRepository import com.sopt.smeem.domain.repository.UserRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -25,8 +23,8 @@ class EditTrainingVM @Inject constructor( val selectedGoal: LiveData get() = _selectedGoal - private val _trainingGoal = MutableLiveData() - val trainingGoal: LiveData + private val _trainingGoal = MutableLiveData() + val trainingGoal: LiveData get() = _trainingGoal fun upsert(target: TrainingGoalType) { @@ -47,20 +45,25 @@ class EditTrainingVM @Inject constructor( _selectedGoal.value = goal } - fun getGoalDetail(onError: (SmeemException) -> Unit) { - viewModelScope.launch { - trainingRepository.getDetail(_selectedGoal.value) - .onSuccess { _trainingGoal.value = it } - .onHttpFailure { e -> onError(e) } + fun getGoalDetail(onError: (Throwable) -> Unit) { + selectedGoal.value?.let { goal -> + viewModelScope.launch { + try { + trainingRepository.getDetail(goal) + } catch (t: Throwable) { + onError(t) + } + } } } - fun sendServer(onError: (SmeemException) -> Unit) { + fun sendServer(onError: (Throwable) -> Unit) { viewModelScope.launch { - userRepository.editTraining( - training = Training(type = selectedGoal.value!!) - ).onHttpFailure { e -> onError(e) } + try { + userRepository.editTraining(Training(type = selectedGoal.value!!)) + } catch (t: Throwable) { + onError(t) + } } } - } \ No newline at end of file diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageActivity.kt index 93fc3e04..43fca8d3 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageActivity.kt @@ -159,16 +159,16 @@ class MyPageActivity : BindingActivity(R.layout.activity_ if (isChecked) { vm.changePushAlarm( hasAlarm = true, - onError = { e -> - Toast.makeText(this, e.errorCode.message, Toast.LENGTH_SHORT).show() + onError = { t -> + Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show() } ) unFreezeTimeTable() } else { vm.changePushAlarm( hasAlarm = false, - onError = { e -> - Toast.makeText(this, e.errorCode.message, Toast.LENGTH_SHORT).show() + onError = { t -> + Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show() } ) freezeTimeTable() diff --git a/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageVM.kt b/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageVM.kt index c09c2bbf..5682b018 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageVM.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/mypage/MyPageVM.kt @@ -5,16 +5,14 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.kakao.sdk.user.UserApiClient -import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure import com.sopt.smeem.domain.model.Day import com.sopt.smeem.domain.model.MyPage import com.sopt.smeem.domain.model.PushAlarm import com.sopt.smeem.domain.repository.LocalRepository import com.sopt.smeem.domain.repository.UserRepository import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.collect import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking import javax.inject.Inject @HiltViewModel @@ -30,22 +28,16 @@ internal class MyPageVM @Inject constructor( var days: MutableSet = mutableSetOf() fun getData(onError: (Throwable) -> Unit) { - viewModelScope.launch { - userRepository.getMyPage().apply { - this.onSuccess { - _response.value = it - isTimeSet = it.hasPushAlarm && it.trainingTime.isSet() - } - this.onHttpFailure { onError(it) } - } - } + } - fun changePushAlarm(hasAlarm: Boolean, onError: (SmeemException) -> Unit) { + fun changePushAlarm(hasAlarm: Boolean, onError: (Throwable) -> Unit) { viewModelScope.launch { - userRepository.editPushAlarm( - push = PushAlarm(hasAlarm = hasAlarm) - ).onHttpFailure { e -> onError(e) } + try { + userRepository.editPushAlarm(PushAlarm(hasAlarm = hasAlarm)) + } catch (t: Throwable) { + onError(t) + } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/onboarding/DisplayGoalFragment.kt b/app/src/main/java/com/sopt/smeem/presentation/onboarding/DisplayGoalFragment.kt index 75d419b6..7524ea55 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/onboarding/DisplayGoalFragment.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/onboarding/DisplayGoalFragment.kt @@ -14,7 +14,7 @@ class DisplayGoalFragment : private val vm: OnBoardingVM by activityViewModels() override fun constructLayout() { vm.getGoalDetail { e -> - Toast.makeText(context, e.description(), Toast.LENGTH_SHORT).show() + Toast.makeText(context, e.message, Toast.LENGTH_SHORT).show() } vm.trainingGoal.observe(this) { diff --git a/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingActivity.kt index 59f44af5..ecd57606 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingActivity.kt @@ -214,7 +214,7 @@ class OnBoardingActivity : if (!isFinishing) finish() }, onError = { e -> - Toast.makeText(this, e.description(), Toast.LENGTH_SHORT).show() + Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show() } ) } else { @@ -283,22 +283,19 @@ class OnBoardingActivity : false -> { vm.sendPlanDataOnAnonymous( onSuccess = { - vm.loadingEnd() val toJoin = Intent( this@OnBoardingActivity, JoinWithNicknameActivity::class.java ) - toJoin.putExtra("accessToken", result.apiAccessToken) - toJoin.putExtra("refreshToken", result.apiRefreshToken) + toJoin.putExtra(ACCESS_TOKEN, result.apiAccessToken) + toJoin.putExtra(REFRESH_TOKEN, result.apiRefreshToken) startActivity(toJoin) if (!isFinishing) finish() }, - onError = { e -> + onError = { t -> Toast.makeText( - this@OnBoardingActivity, - e.description(), - Toast.LENGTH_SHORT + this@OnBoardingActivity, t.message, Toast.LENGTH_SHORT ).show() } ) @@ -373,7 +370,7 @@ class OnBoardingActivity : startActivity(toJoin) if (!isFinishing) finish() }, - onError = { e -> Toast.makeText(this, e.description(), Toast.LENGTH_SHORT).show() } + onError = { e -> Toast.makeText(this, e.message, Toast.LENGTH_SHORT).show() } ) } // 사전 로그인이 없었으면 login 동작하도록 diff --git a/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingVM.kt b/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingVM.kt index 8be56aaf..c4dda37e 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingVM.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/onboarding/OnBoardingVM.kt @@ -6,16 +6,14 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.firebase.messaging.FirebaseMessaging import com.sopt.smeem.Anonymous -import com.sopt.smeem.SmeemException import com.sopt.smeem.SocialType import com.sopt.smeem.TrainingGoalType -import com.sopt.smeem.data.ApiPool.onHttpFailure +import com.sopt.smeem.domain.dto.LoginResultDto +import com.sopt.smeem.domain.dto.PostOnBoardingDto +import com.sopt.smeem.domain.dto.TrainingGoalDto import com.sopt.smeem.domain.model.Authentication import com.sopt.smeem.domain.model.Day -import com.sopt.smeem.domain.model.LoginResult -import com.sopt.smeem.domain.model.OnBoarding import com.sopt.smeem.domain.model.Training -import com.sopt.smeem.domain.model.TrainingGoal import com.sopt.smeem.domain.model.TrainingTime import com.sopt.smeem.domain.repository.LocalRepository import com.sopt.smeem.domain.repository.LoginRepository @@ -33,16 +31,16 @@ class OnBoardingVM @Inject constructor( private val localRepository: LocalRepository, ) : ViewModel() { - private val _loginResult = MutableLiveData() - val loginResult: LiveData + private val _loginResult = MutableLiveData() + val loginResult: LiveData get() = _loginResult private val _selectedGoal = MutableLiveData(TrainingGoalType.NO_SELECTED) val selectedGoal: LiveData get() = _selectedGoal - private val _trainingGoal = MutableLiveData() - val trainingGoal: LiveData + private val _trainingGoal = MutableLiveData() + val trainingGoal: LiveData get() = _trainingGoal private val _setTimeLater = MutableLiveData() @@ -142,16 +140,22 @@ class OnBoardingVM @Inject constructor( kakaoAccessToken: String, kakaoRefreshToken: String, socialType: SocialType, - onError: (SmeemException) -> Unit + onError: (Throwable) -> Unit ) { - FirebaseMessaging.getInstance().token.addOnCompleteListener { - if (it.isSuccessful) { + FirebaseMessaging.getInstance().token.addOnCompleteListener { fcmTask -> + if (fcmTask.isSuccessful) { viewModelScope.launch { - loginRepository.execute(accessToken = kakaoAccessToken, socialType, it.result) - .onSuccess { - _loginResult.value = it + try { + loginRepository.execute( + accessToken = kakaoAccessToken, + socialType, + fcmTask.result + ).run { + _loginResult.value = data() } - .onHttpFailure { e -> onError(e) } + } catch (t: Throwable) { + onError(t) + } } } } @@ -165,48 +169,64 @@ class OnBoardingVM @Inject constructor( // TODO : Room 에 보관하기 } - fun sendPlanDataOnAnonymous(onSuccess: (Unit) -> Unit, onError: (SmeemException) -> Unit) { - viewModelScope.launch { - userRepositoryWithAnonymous.registerOnBoarding( - OnBoarding( - trainingGoalType = selectedGoal.value ?: TrainingGoalType.NO_SELECTED, - hasAlarm = isNotiGranted.value ?: false, - day = days, - hour = selectedHour.value, - minute = selectedMinute.value - ), - loginResult.value!! - ) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } - loadingEnd() + fun sendPlanDataOnAnonymous(onSuccess: (Unit) -> Unit, onError: (Throwable) -> Unit) { + loginResult.value?.let { loginResult -> + viewModelScope.launch { + try { + userRepositoryWithAnonymous.registerOnBoarding( + PostOnBoardingDto( + trainingGoalType = selectedGoal.value ?: TrainingGoalType.NO_SELECTED, + hasAlarm = isNotiGranted.value ?: false, + day = days, + hour = selectedHour.value, + minute = selectedMinute.value + ), loginResult + ).run { onSuccess(Unit) } + } catch (t: Throwable) { + onError(t) + } finally { + loadingEnd() + } + } } } fun sendPlanDataWithAuth( token: String, onSuccess: (Unit) -> Unit, - onError: (SmeemException) -> Unit + onError: (Throwable) -> Unit ) { viewModelScope.launch { - userRepositoryWithAnonymous.editTraining( - accessToken = token, - training = Training( - type = selectedGoal.value ?: TrainingGoalType.NO_SELECTED, - trainingTime = TrainingTime(days = days.toSet(), hour = hour, minute = minute), - hasAlarm = isNotiGranted.value ?: false, + try { + userRepositoryWithAnonymous.registerTraining( + accessToken = token, + training = Training( + type = selectedGoal.value ?: TrainingGoalType.NO_SELECTED, + trainingTime = TrainingTime( + days = days.toSet(), + hour = hour, + minute = minute + ), + hasAlarm = isNotiGranted.value ?: false, + ) ) - ) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } + } catch (t: Throwable) { + onError(t) + } } } - fun getGoalDetail(onError: (SmeemException) -> Unit) { - viewModelScope.launch { - trainingRepository.getDetail(selectedGoal.value) - .onSuccess { _trainingGoal.value = it } - .onHttpFailure { e -> onError(e) } + fun getGoalDetail(onError: (Throwable) -> Unit) { + selectedGoal.value?.let { goal -> + viewModelScope.launch { + try { + trainingRepository.getDetail(goal).run { + _trainingGoal.value = data() + } + } catch (t: Throwable) { + onError(t) + } + } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/onboarding/SignUpBottomSheet.kt b/app/src/main/java/com/sopt/smeem/presentation/onboarding/SignUpBottomSheet.kt index 8cbc4cb1..9595e97f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/onboarding/SignUpBottomSheet.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/onboarding/SignUpBottomSheet.kt @@ -13,6 +13,7 @@ import com.sopt.smeem.logging import com.sopt.smeem.presentation.auth.LoginProcess import com.sopt.smeem.presentation.auth.KakaoHandler import com.sopt.smeem.util.setOnSingleClickListener +import timber.log.Timber class SignUpBottomSheet() : BottomSheetDialogFragment(), LoginProcess { var _binding: BottomSheetSignUpBinding? = null @@ -43,7 +44,7 @@ class SignUpBottomSheet() : BottomSheetDialogFragment(), LoginProcess { kakaoAccessToken = kakaoAccessToken, kakaoRefreshToken = kakaoRefreshToken, socialType = SocialType.KAKAO, - onError = { e -> e.logging("LOGIN_FAILED") } + onError = { e -> Timber.e("LOGIN_FAILED") } ) }, onFailed = { exception -> exception.logging("KAKAO_LOGIN") }) @@ -57,7 +58,7 @@ class SignUpBottomSheet() : BottomSheetDialogFragment(), LoginProcess { kakaoAccessToken = kakaoAccessToken, kakaoRefreshToken = kakaoRefreshToken, socialType = SocialType.KAKAO, - onError = { e -> e.logging("LOGIN_FAILED") } + onError = { e -> Timber.e("LOGIN_FAILED") } ) }, onFailed = { exception -> exception.logging("KAKAO_LOGIN") }) diff --git a/app/src/main/java/com/sopt/smeem/presentation/splash/LoginBottomSheet.kt b/app/src/main/java/com/sopt/smeem/presentation/splash/LoginBottomSheet.kt index 7e8322d0..7e8186c9 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/splash/LoginBottomSheet.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/splash/LoginBottomSheet.kt @@ -46,8 +46,7 @@ class LoginBottomSheet : BottomSheetDialogFragment(), LoginProcess { kakaoAccessToken = kakaoAccessToken, socialType = SocialType.KAKAO, onError = { exception -> - exception.logging("LOGIN_FAILED") - Toast.makeText(context, exception.description(), Toast.LENGTH_SHORT) + Toast.makeText(context, exception.message, Toast.LENGTH_SHORT) .show() } ) @@ -63,8 +62,7 @@ class LoginBottomSheet : BottomSheetDialogFragment(), LoginProcess { kakaoAccessToken = kakaoAccessToken, socialType = SocialType.KAKAO, onError = { exception -> - exception.logging("LOGIN_FAILED") - Toast.makeText(context, exception.description(), Toast.LENGTH_SHORT) + Toast.makeText(context, exception.message, Toast.LENGTH_SHORT) .show() } ) diff --git a/app/src/main/java/com/sopt/smeem/presentation/splash/LoginVM.kt b/app/src/main/java/com/sopt/smeem/presentation/splash/LoginVM.kt index a8e534b4..aeb2509f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/splash/LoginVM.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/splash/LoginVM.kt @@ -6,11 +6,9 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.google.firebase.messaging.FirebaseMessaging import com.sopt.smeem.Anonymous -import com.sopt.smeem.SmeemException import com.sopt.smeem.SocialType -import com.sopt.smeem.data.ApiPool.onHttpFailure +import com.sopt.smeem.domain.dto.LoginResultDto import com.sopt.smeem.domain.model.Authentication -import com.sopt.smeem.domain.model.LoginResult import com.sopt.smeem.domain.repository.LocalRepository import com.sopt.smeem.domain.repository.LoginRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -22,23 +20,25 @@ internal class LoginVM @Inject constructor( private val localRepository: LocalRepository, @Anonymous private val loginRepository: LoginRepository ) : ViewModel() { - private val _loginResult = MutableLiveData() - val loginResult: LiveData + private val _loginResult = MutableLiveData() + val loginResult: LiveData get() = _loginResult fun login( kakaoAccessToken: String, socialType: SocialType, - onError: (SmeemException) -> Unit + onError: (Throwable) -> Unit ) { - FirebaseMessaging.getInstance().token.addOnCompleteListener { - if (it.isSuccessful) { + FirebaseMessaging.getInstance().token.addOnCompleteListener { fcmTask -> + if (fcmTask.isSuccessful) { viewModelScope.launch { - loginRepository.execute(kakaoAccessToken, socialType, it.result) - .onSuccess { - _loginResult.value = it + try { + loginRepository.execute(kakaoAccessToken, socialType, fcmTask.result).run { + _loginResult.value = data() } - .onHttpFailure { e -> onError(e) } + } catch (t: Throwable) { + onError(t) + } } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/splash/SplashLoginActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/splash/SplashLoginActivity.kt index c42a415c..975552bb 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/splash/SplashLoginActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/splash/SplashLoginActivity.kt @@ -4,13 +4,9 @@ import android.content.Intent import android.content.res.ColorStateList import androidx.activity.viewModels import com.sopt.smeem.R -import com.sopt.smeem.Smeem.Companion.AMPLITUDE import com.sopt.smeem.databinding.ActivitySplashLoginBinding -import com.sopt.smeem.domain.model.LoginResult -import com.sopt.smeem.event.AmplitudeEventType.BADGE_MORE_CLICK +import com.sopt.smeem.domain.dto.LoginResultDto import com.sopt.smeem.event.AmplitudeEventType.FIRST_VIEW -import com.sopt.smeem.event.AmplitudeEventType.ON_BOARDING_ALARM_VIEW -import com.sopt.smeem.event.AmplitudeEventType.ON_BOARDING_GOAL_VIEW import com.sopt.smeem.event.AmplitudeEventType.SIGN_UP_SUCCESS import com.sopt.smeem.presentation.BindingActivity import com.sopt.smeem.presentation.EventVM @@ -83,7 +79,7 @@ class SplashLoginActivity : finish() } - private fun gotoNext(loginResult: LoginResult) { + private fun gotoNext(loginResult: LoginResultDto) { when (loginResult.isPlanRegistered) { true -> gotoJoin( loginResult.apiAccessToken, diff --git a/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteActivity.kt b/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteActivity.kt index 9c12cd2b..cc9f8855 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteActivity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteActivity.kt @@ -4,28 +4,23 @@ import android.content.Intent import android.view.View import android.widget.Toast import androidx.activity.viewModels -import androidx.datastore.preferences.core.edit import androidx.lifecycle.LifecycleOwner -import androidx.lifecycle.lifecycleScope import com.sopt.smeem.DefaultSnackBar import com.sopt.smeem.R -import com.sopt.smeem.data.SmeemDataStore.RECENT_DIARY_DATE -import com.sopt.smeem.data.SmeemDataStore.dataStore import com.sopt.smeem.databinding.ActivityForeignWriteBinding -import com.sopt.smeem.description import com.sopt.smeem.event.AmplitudeEventType import com.sopt.smeem.presentation.BindingActivity import com.sopt.smeem.presentation.EventVM +import com.sopt.smeem.presentation.IntentConstants.RETRIEVED_BADGE_DTO +import com.sopt.smeem.presentation.IntentConstants.SNACKBAR_TEXT import com.sopt.smeem.presentation.home.HomeActivity import com.sopt.smeem.presentation.write.Constant.tooltipHasNeverChecked import com.sopt.smeem.util.TooltipUtil.createTopicTooltip import com.sopt.smeem.util.hideKeyboard import com.sopt.smeem.util.setOnSingleClickListener import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch +import timber.log.Timber import java.io.Serializable -import java.time.LocalDate -import java.time.format.DateTimeFormatter @AndroidEntryPoint class ForeignWriteActivity : @@ -99,8 +94,8 @@ class ForeignWriteActivity : } private fun setRandomTopic() { - viewModel.getRandomTopic { e -> - Toast.makeText(this@ForeignWriteActivity, e.description(), Toast.LENGTH_SHORT).show() + viewModel.getRandomTopic { t -> + Toast.makeText(this@ForeignWriteActivity, t.message, Toast.LENGTH_SHORT).show() } } @@ -112,26 +107,19 @@ class ForeignWriteActivity : hideKeyboard(currentFocus ?: View(this)) viewModel.uploadDiary( onSuccess = { - // recent_diary_date 값 변경 - lifecycleScope.launch { - dataStore.edit { storage -> - storage[RECENT_DIARY_DATE] = - LocalDate.now() - .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) - } - } Intent(this, HomeActivity::class.java).apply { - putExtra("retrievedBadge", it as Serializable) + putExtra(RETRIEVED_BADGE_DTO, it as Serializable) putExtra( - "snackbarText", + SNACKBAR_TEXT, resources.getString(R.string.diary_write_done_message) ) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP }.run(::startActivity) }, - onError = { e -> - Toast.makeText(this, e.description(), Toast.LENGTH_SHORT).show() + onError = { t -> + Timber.e(t) + Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show() } ) eventVm.sendEvent(AmplitudeEventType.DIARY_COMPLETE) diff --git a/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteViewModel.kt index a5c9e735..a1e9d16f 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/write/foreign/ForeignWriteViewModel.kt @@ -6,15 +6,17 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.map import androidx.lifecycle.viewModelScope import com.sopt.smeem.LocalStatus -import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure -import com.sopt.smeem.domain.model.Diary -import com.sopt.smeem.domain.model.RetrievedBadge +import com.sopt.smeem.data.SmeemDataStore.RECENT_DIARY_DATE +import com.sopt.smeem.domain.dto.RetrievedBadgeDto +import com.sopt.smeem.domain.dto.WriteDiaryRequestDto import com.sopt.smeem.domain.repository.DiaryRepository import com.sopt.smeem.domain.repository.LocalRepository import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import java.time.LocalDate +import java.time.format.DateTimeFormatter import javax.inject.Inject @HiltViewModel @@ -28,63 +30,61 @@ class ForeignWriteViewModel @Inject constructor( val diary = MutableLiveData("") val isValidDiary: LiveData = diary.map { isValidDiaryFormat(it) } - fun getRandomTopic(onError: (SmeemException) -> Unit) { + fun getRandomTopic(onError: (Throwable) -> Unit) { viewModelScope.launch { - diaryRepository.getTopic() - .onSuccess { - topicId = it.id - topic.value = it.content + try { + diaryRepository.getTopic().run { + topic.value = data().content + topicId = data().id } - .onHttpFailure { e -> onError(e) } + } catch (t: Throwable) { + onError(t) + } } } - fun uploadDiary(onSuccess: (List) -> Unit, onError: (SmeemException) -> Unit) { - if (topicId != (-1).toLong()) { - diaryWithTopic(onSuccess, onError) - } else { - diaryWithoutTopic(onSuccess, onError) - } - } + fun uploadDiary(onSuccess: (List) -> Unit, onError: (Throwable) -> Unit) { + val selectedTopicId = if (topicId < 0) null else topicId - fun neverClickedRandomToolTip(): Boolean = runBlocking { - return@runBlocking localRepository.checkStatus(LocalStatus.RANDOM_TOPIC_TOOL_TIP) + diary.value?.let { + viewModelScope.launch { + requestToServer(WriteDiaryRequestDto(it, selectedTopicId), onSuccess, onError) + updateRecentDiaryDateOnLocal() + } + } } - fun randomTopicTooltipOff() { - viewModelScope.launch { - localRepository.saveStatus(LocalStatus.RANDOM_TOPIC_TOOL_TIP) + private suspend fun requestToServer( + dto: WriteDiaryRequestDto, + onSuccess: (List) -> Unit, + onError: (Throwable) -> Unit + ) = coroutineScope { + launch { + try { + diaryRepository.postDiary(dto).run { onSuccess(data().retrievedBadgeList) } + } catch (t: Throwable) { + onError(t) + } } } - private fun diaryWithTopic( - onSuccess: (List) -> Unit, - onError: (SmeemException) -> Unit - ) { - viewModelScope.launch { - diaryRepository.postDiary( - Diary( - topicId = topicId, - content = diary.value!! - ) + private suspend fun updateRecentDiaryDateOnLocal() = coroutineScope { + // recent_diary_date 값 변경 + launch { + localRepository.setStringValue( + RECENT_DIARY_DATE, LocalDate.now() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) ) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } } } - private fun diaryWithoutTopic( - onSuccess: (List) -> Unit, - onError: (SmeemException) -> Unit - ) { + fun neverClickedRandomToolTip(): Boolean = runBlocking { + return@runBlocking localRepository.checkStatus(LocalStatus.RANDOM_TOPIC_TOOL_TIP) + } + + fun randomTopicTooltipOff() { viewModelScope.launch { - diaryRepository.postDiary( - Diary( - content = diary.value!! - ) - ) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } + localRepository.saveStatus(LocalStatus.RANDOM_TOPIC_TOOL_TIP) } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1Activity.kt b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1Activity.kt index 24dcea4a..150eae5b 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1Activity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1Activity.kt @@ -110,7 +110,7 @@ class NativeWriteStep1Activity : private fun setRandomTopic() { viewModel.getRandomTopic { e -> - Toast.makeText(this@NativeWriteStep1Activity, e.description(), Toast.LENGTH_SHORT) + Toast.makeText(this@NativeWriteStep1Activity, e.message, Toast.LENGTH_SHORT) .show() } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1ViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1ViewModel.kt index 8d6957e2..c168e89a 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1ViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep1ViewModel.kt @@ -7,12 +7,11 @@ import androidx.lifecycle.map import androidx.lifecycle.viewModelScope import com.sopt.smeem.Anonymous import com.sopt.smeem.LocalStatus -import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure import com.sopt.smeem.domain.repository.DiaryRepository import com.sopt.smeem.domain.repository.LocalRepository import com.sopt.smeem.domain.repository.TranslateRepository import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.catch import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import javax.inject.Inject @@ -31,14 +30,17 @@ class NativeWriteStep1ViewModel @Inject constructor( val translateResult = MutableLiveData() - fun getRandomTopic(onError: (SmeemException) -> Unit) { + fun getRandomTopic(onError: (Throwable) -> Unit) { viewModelScope.launch { - diaryRepository.getTopic() - .onSuccess { - topicId = it.id - topic.value = it.content - } - .onHttpFailure { e -> onError(e) } + try { + diaryRepository.getTopic() + .run { + topicId = data().id + topic.value = data().content + } + } catch (t:Throwable) { + onError(t) + } } } diff --git a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2Activity.kt b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2Activity.kt index e7dba641..2e1a1295 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2Activity.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2Activity.kt @@ -5,25 +5,20 @@ import android.text.method.ScrollingMovementMethod import android.view.View import android.widget.Toast import androidx.activity.viewModels -import androidx.datastore.preferences.core.edit -import androidx.lifecycle.lifecycleScope import com.sopt.smeem.DefaultSnackBar import com.sopt.smeem.R -import com.sopt.smeem.data.SmeemDataStore -import com.sopt.smeem.data.SmeemDataStore.dataStore import com.sopt.smeem.databinding.ActivityNativeWriteStep2Binding -import com.sopt.smeem.description import com.sopt.smeem.event.AmplitudeEventType import com.sopt.smeem.presentation.BindingActivity import com.sopt.smeem.presentation.EventVM +import com.sopt.smeem.presentation.IntentConstants.RETRIEVED_BADGE_DTO +import com.sopt.smeem.presentation.IntentConstants.SNACKBAR_TEXT import com.sopt.smeem.presentation.home.HomeActivity import com.sopt.smeem.util.hideKeyboard import com.sopt.smeem.util.setOnSingleClickListener import dagger.hilt.android.AndroidEntryPoint -import kotlinx.coroutines.launch +import timber.log.Timber import java.io.Serializable -import java.time.LocalDate -import java.time.format.DateTimeFormatter @AndroidEntryPoint class NativeWriteStep2Activity : @@ -89,26 +84,19 @@ class NativeWriteStep2Activity : hideKeyboard(currentFocus ?: View(this)) viewModel.uploadDiary( onSuccess = { - // recent_diary_date 값 변경 - lifecycleScope.launch { - dataStore.edit { storage -> - storage[SmeemDataStore.RECENT_DIARY_DATE] = - LocalDate.now() - .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) - } - } Intent(this, HomeActivity::class.java).apply { - putExtra("retrievedBadge", it as Serializable) + putExtra(RETRIEVED_BADGE_DTO, it as Serializable) putExtra( - "snackbarText", + SNACKBAR_TEXT, resources.getString(R.string.diary_write_done_message) ) flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK }.run(::startActivity) }, - onError = { e -> - Toast.makeText(this, e.description(), Toast.LENGTH_SHORT).show() + onError = { t -> + Timber.e(t) + Toast.makeText(this, t.message, Toast.LENGTH_SHORT).show() } ) eventVm.sendEvent(AmplitudeEventType.SECOND_STEP_COMPLETE) diff --git a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2ViewModel.kt b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2ViewModel.kt index c67d6d56..138e8362 100644 --- a/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2ViewModel.kt +++ b/app/src/main/java/com/sopt/smeem/presentation/write/natiive/NativeWriteStep2ViewModel.kt @@ -1,60 +1,66 @@ package com.sopt.smeem.presentation.write.natiive -import android.util.Log import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.map import androidx.lifecycle.viewModelScope -import com.sopt.smeem.SmeemException -import com.sopt.smeem.data.ApiPool.onHttpFailure -import com.sopt.smeem.domain.model.Diary -import com.sopt.smeem.domain.model.RetrievedBadge +import com.sopt.smeem.data.SmeemDataStore +import com.sopt.smeem.domain.dto.RetrievedBadgeDto +import com.sopt.smeem.domain.dto.WriteDiaryRequestDto import com.sopt.smeem.domain.repository.DiaryRepository +import com.sopt.smeem.domain.repository.LocalRepository import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch +import java.time.LocalDate +import java.time.format.DateTimeFormatter import javax.inject.Inject @HiltViewModel class NativeWriteStep2ViewModel @Inject constructor( - private val diaryRepository: DiaryRepository + private val diaryRepository: DiaryRepository, + private val localRepository: LocalRepository, ) : ViewModel() { var topicId: Long = -1 val diary = MutableLiveData("") val isValidDiary: LiveData = diary.map { isValidDiaryFormat(it) } - fun uploadDiary(onSuccess: (List) -> Unit, onError: (SmeemException) -> Unit) { - if (topicId != (-1).toLong()) { - diaryWithTopic(onSuccess, onError) - } else { - diaryWithoutTopic(onSuccess, onError) + fun uploadDiary(onSuccess: (List) -> Unit, onError: (Throwable) -> Unit) { + val selectedTopicId = if (topicId < 0) null else topicId + + diary.value?.let { content -> + viewModelScope.launch { + launch { + requestToServer( + WriteDiaryRequestDto(content, selectedTopicId), + onSuccess, + onError + ) + } + launch { updateRecentDiaryDateOnLocal() } + } } } - private fun diaryWithTopic(onSuccess: (List) -> Unit, onError: (SmeemException) -> Unit) { - viewModelScope.launch { - diaryRepository.postDiary( - Diary( - topicId = topicId, - content = diary.value!! - ) - ) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } + private suspend fun requestToServer( + dto: WriteDiaryRequestDto, + onSuccess: (List) -> Unit, + onError: (Throwable) -> Unit + ) { + try { + diaryRepository.postDiary(dto).run { onSuccess(data().retrievedBadgeList) } + } catch (t: Throwable) { + onError(t) } } - private fun diaryWithoutTopic(onSuccess: (List) -> Unit, onError: (SmeemException) -> Unit) { - viewModelScope.launch { - diaryRepository.postDiary( - Diary( - content = diary.value!! - ) - ) - .onSuccess(onSuccess) - .onHttpFailure { e -> onError(e) } - } + private suspend fun updateRecentDiaryDateOnLocal() { + // recent_diary_date 값 변경 + localRepository.setStringValue( + SmeemDataStore.RECENT_DIARY_DATE, LocalDate.now() + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + ) } private fun isValidDiaryFormat(diary: String): Boolean { diff --git a/app/src/main/res/layout/activity_diary_detail.xml b/app/src/main/res/layout/activity_diary_detail.xml index 7e167885..bfb35371 100644 --- a/app/src/main/res/layout/activity_diary_detail.xml +++ b/app/src/main/res/layout/activity_diary_detail.xml @@ -8,8 +8,8 @@ + name="diaryDetail" + type="com.sopt.smeem.presentation.detail.DiaryDetail" /> @@ -59,19 +59,19 @@ + android:layout_height="wrap_content" + android:paddingBottom="16dp"> + type="com.sopt.smeem.domain.dto.TrainingGoalDto" /> diff --git a/app/src/main/res/layout/activity_health_check.xml b/app/src/main/res/layout/activity_health_check.xml index 76a6f9b4..b16c1572 100644 --- a/app/src/main/res/layout/activity_health_check.xml +++ b/app/src/main/res/layout/activity_health_check.xml @@ -4,17 +4,17 @@ xmlns:tools="http://schemas.android.com/tools"> + + type="com.sopt.smeem.presentation.health.HealthStatus" /> + tools:context=".presentation.health.HealthCheckActivity">