From 70d9c1d5c69d30db29f9c84638ac47c1fb865948 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Fri, 1 Nov 2024 22:07:42 +0900 Subject: [PATCH 01/23] feat: Create Edit Member Info Screen --- feature/edit-member-info/.gitignore | 1 + feature/edit-member-info/build.gradle.kts | 32 +++++ .../editmemberinfo/EditMemberInfoScreen.kt | 115 ++++++++++++++++++ settings.gradle.kts | 1 + 4 files changed, 149 insertions(+) create mode 100644 feature/edit-member-info/.gitignore create mode 100644 feature/edit-member-info/build.gradle.kts create mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt diff --git a/feature/edit-member-info/.gitignore b/feature/edit-member-info/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/feature/edit-member-info/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/feature/edit-member-info/build.gradle.kts b/feature/edit-member-info/build.gradle.kts new file mode 100644 index 00000000..b6f293a5 --- /dev/null +++ b/feature/edit-member-info/build.gradle.kts @@ -0,0 +1,32 @@ +import com.b1nd.dodam.dsl.android +import com.b1nd.dodam.dsl.kotlin +import com.b1nd.dodam.dsl.setIOS + +plugins { + alias(libs.plugins.dodam.multiplatform.feature) + alias(libs.plugins.dodam.multiplatform.koin) + alias(libs.plugins.dodam.multiplatform.coil) +} + +kotlin { + + setIOS( + name = "edit_member_info", + bundleId = "com.b1nd.dodam.edit_member_info" + ) + + sourceSets.commonMain.dependencies { + implementation(libs.dodam.design.system.cmm) + implementation(projects.data.member) + implementation(projects.common) + implementation(projects.ui) + implementation(projects.logging) + } +} + +android { + namespace = "com.b1nd.dodam.setting" + defaultConfig { + consumerProguardFiles("consumer-rules.pro") + } +} \ No newline at end of file diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt new file mode 100644 index 00000000..79fa0f81 --- /dev/null +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -0,0 +1,115 @@ +package com.b1nd.dodam.editmemberinfo + +import androidx.compose.foundation.Image +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.layout.statusBarsPadding +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.dp +import coil3.compose.AsyncImage +import com.b1nd.dodam.designsystem.DodamTheme +import com.b1nd.dodam.designsystem.component.DodamButton +import com.b1nd.dodam.designsystem.component.DodamTextField +import com.b1nd.dodam.designsystem.component.DodamTopAppBar +import com.b1nd.dodam.ui.icons.ColoredPencil +import com.b1nd.dodam.ui.icons.DefaultProfile + +@Composable +internal fun EditMemberInfoScreen() { + + var name by remember { mutableStateOf("") } + var email by remember { mutableStateOf("") } + var pell by remember { mutableStateOf("") } + + + Scaffold( + topBar = { + DodamTopAppBar( + modifier = Modifier.statusBarsPadding(), + title = "정보수정", + onBackClick = {}, + ) + } + ) { + Column( + modifier = Modifier + .fillMaxSize() + .padding(it) + .padding(horizontal = 16.dp) + .padding(vertical = 12.dp) + ) { + Box { + if (true) { + AsyncImage( + modifier = Modifier + .clip(DodamTheme.shapes.medium) + .size(128.dp), + model = "uiState.profile", + contentDescription = null, + contentScale = ContentScale.Crop, + ) + } else { + Image( + modifier = Modifier + .clip(DodamTheme.shapes.medium) + .size(128.dp), + bitmap = DefaultProfile, + contentDescription = "프로필 이미지", + contentScale = ContentScale.Crop, + ) + } + Image( + imageVector = ColoredPencil, + contentDescription = "image", + modifier = Modifier.size(20.dp) + ) + + + } + Column( + modifier = Modifier + .fillMaxWidth() + .padding(top = 24.dp) + ) { + DodamTextField( + value = name, + onValueChange = { + name = it + }, + label = "이름", + onClickRemoveRequest = { + name = "" + }, + modifier = Modifier.padding(bottom = 24.dp), + ) + DodamTextField( + value = email, + onValueChange = { + email = it + }, + label = "이메일", + onClickRemoveRequest = { + email = "" + }, + modifier = Modifier.padding(bottom = 24.dp), + ) + } + DodamButton( + onClick = {}, + text = "수정 완료", + ) + } + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 2ff63236..2b5443ff 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -81,3 +81,4 @@ include(":feature-teacher:approve-outing") include(":feature-teacher:approve-nightstudy") include(":network:bundleid-info") include(":data:bundleid-info") +include(":feature:edit-member-info") From c8a35abb930dd63a97f51536a4f558997f0fdbb9 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Mon, 4 Nov 2024 09:10:09 +0900 Subject: [PATCH 02/23] feat: Create Navigation --- dodam-student/build.gradle.kts | 1 + .../kotlin/com/b1nd/dodam/student/DodamApp.kt | 6 ++++ .../dodam/student/util/DodamApplication.kt | 2 ++ dodam-teacher-android/build.gradle.kts | 1 + .../com/b1nd/dodam/teacher/DodamTeacherApp.kt | 7 +++++ .../kotlin/com/b1nd/dodam/teacher/Koin.kt | 2 ++ .../editmemberinfo/di/ViewModelModule.kt | 9 ++++++ .../navigation/EditMemberInfoNavigation.kt | 30 +++++++++++++++++++ .../viewmodel/EditmemberInfoViewModel.kt | 7 +++++ .../com/b1nd/dodam/setting/SettingScreen.kt | 4 +-- .../setting/navigation/SettingNavigation.kt | 3 +- 11 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt create mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt create mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt diff --git a/dodam-student/build.gradle.kts b/dodam-student/build.gradle.kts index 2c24f5ad..0ee5e8fc 100644 --- a/dodam-student/build.gradle.kts +++ b/dodam-student/build.gradle.kts @@ -88,4 +88,5 @@ dependencies { implementation(projects.network.login) implementation(projects.network.bundleidInfo) implementation(projects.data.bundleidInfo) + implementation(projects.feature.editMemberInfo) } diff --git a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt index 9ce3f1f6..f2117bcd 100644 --- a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt +++ b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt @@ -36,6 +36,8 @@ import com.b1nd.dodam.bus.navigation.navigateToBus import com.b1nd.dodam.dds.component.DodamErrorToast import com.b1nd.dodam.dds.component.DodamSuccessToast import com.b1nd.dodam.dds.component.DodamWarningToast +import com.b1nd.dodam.editmemberinfo.navigation.editMemberInfoScreen +import com.b1nd.dodam.editmemberinfo.navigation.navigationToEditMemberInfo import com.b1nd.dodam.login.navigation.loginScreen import com.b1nd.dodam.login.navigation.navigationToLogin import com.b1nd.dodam.onboarding.navigation.ONBOARDING_ROUTE @@ -236,6 +238,7 @@ fun DodamApp( versionInfo = "3.2.0", popBackStack = navController::popBackStack, logout = logout, + navigationToEditMemberInfo = navController::navigationToEditMemberInfo ) askWakeupSongScreen( popBackStack = navController::popBackStack, @@ -247,6 +250,9 @@ fun DodamApp( pointScreen( popBackStack = navController::popBackStack, ) + editMemberInfoScreen ( + popBackStack = navController::popBackStack + ) } } } diff --git a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt index 689ac8f2..ea1db4d5 100644 --- a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt +++ b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt @@ -18,6 +18,7 @@ import com.b1nd.dodam.data.outing.di.outingRepositoryModule import com.b1nd.dodam.data.point.di.pointRepositoryModule import com.b1nd.dodam.data.schedule.di.scheduleRepositoryModule import com.b1nd.dodam.datastore.di.dataStoreModule +import com.b1nd.dodam.editmemberinfo.di.editMemberInfoViewModelModule import com.b1nd.dodam.keystore.keystoreManagerModule import com.b1nd.dodam.login.di.loginViewModelModule import com.b1nd.dodam.member.di.memberDataSourceModule @@ -96,6 +97,7 @@ class DodamApplication : Application() { outingViewModelModule, bundleIdInfoRepositoryModule, bundleIdInfoDataSourceModule, + editMemberInfoViewModelModule ) + mainViewModelModules, ) } diff --git a/dodam-teacher-android/build.gradle.kts b/dodam-teacher-android/build.gradle.kts index c81ee1e2..9d33d1f7 100644 --- a/dodam-teacher-android/build.gradle.kts +++ b/dodam-teacher-android/build.gradle.kts @@ -56,6 +56,7 @@ kotlin { implementation(projects.network.point) implementation(projects.network.bundleidInfo) implementation(projects.data.bundleidInfo) + implementation(projects.feature.editMemberInfo) } androidMain.dependencies { diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt index 31f9d81b..8f3b2b2e 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt @@ -50,6 +50,8 @@ import com.b1nd.dodam.designsystem.component.DodamDialog import com.b1nd.dodam.designsystem.component.DodamNavigationBar import com.b1nd.dodam.designsystem.component.DodamNavigationBarItem import com.b1nd.dodam.designsystem.foundation.DodamIcons +import com.b1nd.dodam.editmemberinfo.navigation.editMemberInfoScreen +import com.b1nd.dodam.editmemberinfo.navigation.navigationToEditMemberInfo import com.b1nd.dodam.home.navigation.HOME_ROUTE import com.b1nd.dodam.home.navigation.homeScreen import com.b1nd.dodam.home.navigation.navigateToHome @@ -256,6 +258,11 @@ fun DodamTeacherApp(exit: () -> Unit, viewModel: DodamTeacherAppViewModel = koin popBackStack = navHostController::popBackStack, logout = exit, versionInfo = getPlatformName(), + navigationToEditMemberInfo = navHostController::navigationToEditMemberInfo + ) + + editMemberInfoScreen( + popBackStack = navHostController::popBackStack ) } diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt index 807d9ed2..f89334b7 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt @@ -14,6 +14,7 @@ import com.b1nd.dodam.data.outing.di.outingRepositoryModule import com.b1nd.dodam.data.point.di.pointRepositoryModule import com.b1nd.dodam.data.schedule.di.scheduleRepositoryModule import com.b1nd.dodam.datastore.di.dataStoreModule +import com.b1nd.dodam.editmemberinfo.di.editMemberInfoViewModelModule import com.b1nd.dodam.home.di.homeViewModelModule import com.b1nd.dodam.login.di.loginViewModelModule import com.b1nd.dodam.meal.di.mealViewModelModule @@ -78,6 +79,7 @@ fun initKoin(block: KoinApplication.() -> Unit = {}) { settingViewModelModule, bundleIdInfoRepositoryModule, bundleIdInfoDataSourceModule, + editMemberInfoViewModelModule ) block() } diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt new file mode 100644 index 00000000..5c6849f9 --- /dev/null +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt @@ -0,0 +1,9 @@ +package com.b1nd.dodam.editmemberinfo.di + +import com.b1nd.dodam.editmemberinfo.viewmodel.EditmemberInfoViewModel +import org.koin.compose.viewmodel.dsl.viewModel +import org.koin.dsl.module + +val editMemberInfoViewModelModule = module { + viewModel { EditmemberInfoViewModel() } +} diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt new file mode 100644 index 00000000..c7a38ff9 --- /dev/null +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt @@ -0,0 +1,30 @@ +package com.b1nd.dodam.editmemberinfo.navigation + +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.b1nd.dodam.editmemberinfo.EditMemberInfoScreen + +const val EDIT_MEMBER_INFO_ROUTE = "login" + +fun NavController.navigationToEditMemberInfo( + navOptions: NavOptions? = androidx.navigation.navOptions { + launchSingleTop = true + }, +) = navigate(EDIT_MEMBER_INFO_ROUTE, navOptions) + +@ExperimentalMaterial3Api +fun NavGraphBuilder.editMemberInfoScreen(popBackStack: () -> Unit) { + composable( + route = EDIT_MEMBER_INFO_ROUTE, + enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, + exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, + popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Down) }, + popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Down) }, + ) { + EditMemberInfoScreen() + } +} diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt new file mode 100644 index 00000000..d296016b --- /dev/null +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt @@ -0,0 +1,7 @@ +package com.b1nd.dodam.editmemberinfo.viewmodel + +import androidx.lifecycle.ViewModel +import org.koin.core.component.KoinComponent + +class EditmemberInfoViewModel : ViewModel(), KoinComponent { +} \ No newline at end of file diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index 5a61e9e2..60017e31 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -56,7 +56,7 @@ import org.koin.core.annotation.KoinExperimentalAPI @OptIn(KoinExperimentalAPI::class) @ExperimentalMaterial3Api @Composable -internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versionInfo: String = "3.2.0", popBackStack: () -> Unit, logout: () -> Unit) { +internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versionInfo: String = "3.2.0", popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: () -> Unit) { val uiState by viewModel.uiState.collectAsState() var showLogoutDialog by remember { mutableStateOf(false) } @@ -166,7 +166,7 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio .clickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberBounceIndication(), - onClick = { showDialog = true }, + onClick = navigationToEditMemberInfo , ), ) { if (uiState.isLoading) { diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt index bb964ae3..2285029b 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt @@ -18,7 +18,7 @@ fun NavController.navigateToSetting( ) = navigate(SETTING_ROUTE, navOptions) @ExperimentalMaterial3Api -fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, logout: () -> Unit) { +fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: () -> Unit) { composable( route = SETTING_ROUTE, enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, @@ -30,6 +30,7 @@ fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, versionInfo = versionInfo, popBackStack = popBackStack, logout = logout, + navigationToEditMemberInfo = navigationToEditMemberInfo ) } } From f51c689f931f5ae1727496df47f572fabc72624f Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 6 Nov 2024 17:23:56 +0900 Subject: [PATCH 03/23] feat: Finish Edit Member Info Screen --- .../editmemberinfo/EditMemberInfoScreen.kt | 143 +++++++++++------- .../navigation/EditMemberInfoNavigation.kt | 4 +- .../composeResources/drawable/ic_plus.xml | 12 ++ .../kotlin/com/b1nd/dodam/ui/icons/Icons.kt | 5 + 4 files changed, 108 insertions(+), 56 deletions(-) create mode 100644 ui/src/commonMain/composeResources/drawable/ic_plus.xml diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 79fa0f81..e0f6bd8a 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -1,10 +1,13 @@ package com.b1nd.dodam.editmemberinfo import androidx.compose.foundation.Image +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding @@ -14,9 +17,11 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme @@ -25,90 +30,118 @@ import com.b1nd.dodam.designsystem.component.DodamTextField import com.b1nd.dodam.designsystem.component.DodamTopAppBar import com.b1nd.dodam.ui.icons.ColoredPencil import com.b1nd.dodam.ui.icons.DefaultProfile +import com.b1nd.dodam.ui.icons.Plus +import com.b1nd.dodam.ui.util.addFocusCleaner @Composable -internal fun EditMemberInfoScreen() { +internal fun EditMemberInfoScreen( + popBackStack: () -> Unit +) { var name by remember { mutableStateOf("") } var email by remember { mutableStateOf("") } - var pell by remember { mutableStateOf("") } + var phone by remember { mutableStateOf("") } + val focusManager = LocalFocusManager.current Scaffold( + modifier = Modifier.addFocusCleaner(focusManager), topBar = { DodamTopAppBar( modifier = Modifier.statusBarsPadding(), title = "정보수정", - onBackClick = {}, + onBackClick = popBackStack, ) } ) { - Column( + Box( modifier = Modifier .fillMaxSize() + .background(DodamTheme.colors.backgroundNeutral) .padding(it) .padding(horizontal = 16.dp) .padding(vertical = 12.dp) ) { - Box { - if (true) { - AsyncImage( - modifier = Modifier - .clip(DodamTheme.shapes.medium) - .size(128.dp), - model = "uiState.profile", - contentDescription = null, - contentScale = ContentScale.Crop, - ) - } else { + Column( + modifier = Modifier.fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Box{ + if (!true) { + AsyncImage( + modifier = Modifier + .clip(DodamTheme.shapes.medium) + .size(128.dp), + model = "uiState.profile", + contentDescription = null, + contentScale = ContentScale.Crop, + ) + } else { + Image( + modifier = Modifier + .clip(DodamTheme.shapes.medium) + .size(128.dp), + bitmap = DefaultProfile, + contentDescription = "프로필 이미지", + contentScale = ContentScale.Crop, + ) + } Image( + imageVector = Plus, + contentDescription = "image", modifier = Modifier - .clip(DodamTheme.shapes.medium) - .size(128.dp), - bitmap = DefaultProfile, - contentDescription = "프로필 이미지", - contentScale = ContentScale.Crop, + .size(32.dp) + .align(Alignment.BottomEnd) ) } - Image( - imageVector = ColoredPencil, - contentDescription = "image", - modifier = Modifier.size(20.dp) - ) - - - } - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 24.dp) - ) { - DodamTextField( - value = name, - onValueChange = { - name = it - }, - label = "이름", - onClickRemoveRequest = { - name = "" - }, - modifier = Modifier.padding(bottom = 24.dp), - ) - DodamTextField( - value = email, - onValueChange = { - email = it - }, - label = "이메일", - onClickRemoveRequest = { - email = "" - }, - modifier = Modifier.padding(bottom = 24.dp), - ) + Column( + modifier = Modifier + .fillMaxWidth() + .padding(top = 24.dp) + ) { + DodamTextField( + value = name, + onValueChange = { + name = it + }, + label = "이름", + onClickRemoveRequest = { + name = "" + }, + ) + Spacer(Modifier.height(24.dp)) + DodamTextField( + value = email, + onValueChange = { + email = it + }, + label = "이메일", + onClickRemoveRequest = { + email = "" + }, + modifier = Modifier, + ) + Spacer(Modifier.height(24.dp)) + DodamTextField( + value = phone, + onValueChange = { + phone = it + }, + label = "전화번호", + onClickRemoveRequest = { + phone = "" + }, + modifier = Modifier, + ) + Spacer(Modifier.height(24.dp)) + } } DodamButton( onClick = {}, text = "수정 완료", + modifier = Modifier + .align(Alignment.BottomCenter) + .fillMaxWidth(), ) } } diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt index c7a38ff9..c8c11cae 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt @@ -25,6 +25,8 @@ fun NavGraphBuilder.editMemberInfoScreen(popBackStack: () -> Unit) { popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Down) }, popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Down) }, ) { - EditMemberInfoScreen() + EditMemberInfoScreen( + popBackStack = popBackStack + ) } } diff --git a/ui/src/commonMain/composeResources/drawable/ic_plus.xml b/ui/src/commonMain/composeResources/drawable/ic_plus.xml new file mode 100644 index 00000000..09e656d2 --- /dev/null +++ b/ui/src/commonMain/composeResources/drawable/ic_plus.xml @@ -0,0 +1,12 @@ + + + + diff --git a/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt b/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt index 2760b698..a3c5ab5d 100644 --- a/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt +++ b/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt @@ -20,6 +20,7 @@ import dodamdodam_android.ui.generated.resources.ic_colored_xmark_circle import dodamdodam_android.ui.generated.resources.ic_default_profile import dodamdodam_android.ui.generated.resources.ic_default_user import dodamdodam_android.ui.generated.resources.ic_dodamlogo +import dodamdodam_android.ui.generated.resources.ic_plus import org.jetbrains.compose.resources.imageResource import org.jetbrains.compose.resources.vectorResource @@ -94,3 +95,7 @@ val ColoredXMarkCircle val ColoredCookedRice @Composable get() = vectorResource(Res.drawable.ic_colored_cookedrice) + +val Plus + @Composable + get() = vectorResource(Res.drawable.ic_plus) From 6e30ad86169dac564a74e1ad6dcfba24ed70a44a Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 6 Nov 2024 19:32:05 +0900 Subject: [PATCH 04/23] feat: Change Profile Shape --- .../editmemberinfo/EditMemberInfoScreen.kt | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index e0f6bd8a..99678fcc 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -2,6 +2,7 @@ package com.b1nd.dodam.editmemberinfo import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -11,6 +12,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -25,9 +27,12 @@ import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme +import com.b1nd.dodam.designsystem.component.AvatarSize +import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamButton import com.b1nd.dodam.designsystem.component.DodamTextField import com.b1nd.dodam.designsystem.component.DodamTopAppBar +import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.icons.ColoredPencil import com.b1nd.dodam.ui.icons.DefaultProfile import com.b1nd.dodam.ui.icons.Plus @@ -66,26 +71,20 @@ internal fun EditMemberInfoScreen( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { - Box{ - if (!true) { - AsyncImage( - modifier = Modifier - .clip(DodamTheme.shapes.medium) - .size(128.dp), - model = "uiState.profile", - contentDescription = null, - contentScale = ContentScale.Crop, - ) - } else { - Image( - modifier = Modifier - .clip(DodamTheme.shapes.medium) - .size(128.dp), - bitmap = DefaultProfile, - contentDescription = "프로필 이미지", - contentScale = ContentScale.Crop, - ) - } + val borderColor = DodamTheme.colors.lineAlternative + Box { + DodamAvatar( + avatarSize = AvatarSize.XXL, + contentDescription = "프로필 이미지", + modifier = Modifier + .`if`(true) { + border( + width = 1.dp, + color = borderColor, + shape = CircleShape + ) + } + ) Image( imageVector = Plus, contentDescription = "image", From 77253f83e83455da7cdf974b893d2dedbb9461a8 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Thu, 7 Nov 2024 10:45:33 +0900 Subject: [PATCH 05/23] feat: Move Image Url --- .../kotlin/com/b1nd/dodam/student/DodamApp.kt | 6 ++++- .../com/b1nd/dodam/teacher/DodamTeacherApp.kt | 6 ++++- .../editmemberinfo/EditMemberInfoScreen.kt | 7 ++++-- .../navigation/EditMemberInfoNavigation.kt | 25 ++++++++++++++++--- .../com/b1nd/dodam/setting/SettingScreen.kt | 4 +-- .../setting/navigation/SettingNavigation.kt | 2 +- 6 files changed, 40 insertions(+), 10 deletions(-) diff --git a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt index f2117bcd..9be67ad2 100644 --- a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt +++ b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt @@ -238,7 +238,11 @@ fun DodamApp( versionInfo = "3.2.0", popBackStack = navController::popBackStack, logout = logout, - navigationToEditMemberInfo = navController::navigationToEditMemberInfo + navigationToEditMemberInfo = { profileImage -> + navController.navigationToEditMemberInfo( + profileImage + ) + } ) askWakeupSongScreen( popBackStack = navController::popBackStack, diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt index 8f3b2b2e..49ce0b9e 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt @@ -258,7 +258,11 @@ fun DodamTeacherApp(exit: () -> Unit, viewModel: DodamTeacherAppViewModel = koin popBackStack = navHostController::popBackStack, logout = exit, versionInfo = getPlatformName(), - navigationToEditMemberInfo = navHostController::navigationToEditMemberInfo + navigationToEditMemberInfo = {profileImage -> + navHostController.navigationToEditMemberInfo( + profileImage + ) + } ) editMemberInfoScreen( diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 99678fcc..ffc8415f 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -40,6 +40,7 @@ import com.b1nd.dodam.ui.util.addFocusCleaner @Composable internal fun EditMemberInfoScreen( + profileImage: String?, popBackStack: () -> Unit ) { @@ -76,14 +77,16 @@ internal fun EditMemberInfoScreen( DodamAvatar( avatarSize = AvatarSize.XXL, contentDescription = "프로필 이미지", + model = if (profileImage == "default") null else profileImage, modifier = Modifier - .`if`(true) { + .`if`(profileImage == "default") { border( width = 1.dp, color = borderColor, shape = CircleShape ) - } + }, + contentScale = ContentScale.Crop ) Image( imageVector = Plus, diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt index c8c11cae..f2c69472 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt @@ -5,28 +5,47 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions +import androidx.navigation.NavType import androidx.navigation.compose.composable +import androidx.navigation.navArgument import com.b1nd.dodam.editmemberinfo.EditMemberInfoScreen +import io.ktor.http.encodeURLPath +import io.ktor.util.decodeBase64String +import io.ktor.util.encodeBase64 +import io.ktor.utils.io.core.toByteArray +import kotlinx.io.bytestring.encodeToByteString +import kotlin.io.encoding.Base64 +import kotlin.io.encoding.ExperimentalEncodingApi const val EDIT_MEMBER_INFO_ROUTE = "login" fun NavController.navigationToEditMemberInfo( + profileImage: String?, navOptions: NavOptions? = androidx.navigation.navOptions { launchSingleTop = true }, -) = navigate(EDIT_MEMBER_INFO_ROUTE, navOptions) +) { + val image = (profileImage ?: "default").toByteArray().encodeBase64() + navigate("$EDIT_MEMBER_INFO_ROUTE/$image", navOptions) +} @ExperimentalMaterial3Api fun NavGraphBuilder.editMemberInfoScreen(popBackStack: () -> Unit) { composable( - route = EDIT_MEMBER_INFO_ROUTE, + route = "$EDIT_MEMBER_INFO_ROUTE/{image}", + arguments = listOf( + navArgument("image") { type = NavType.StringType } + ), enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, popEnterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Down) }, popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Down) }, ) { + val encodedImage = it.arguments?.getString("image") ?: "default" + val profileImage = encodedImage.decodeBase64String() EditMemberInfoScreen( + profileImage = profileImage, popBackStack = popBackStack ) } -} +} \ No newline at end of file diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index 60017e31..9f18daeb 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -56,7 +56,7 @@ import org.koin.core.annotation.KoinExperimentalAPI @OptIn(KoinExperimentalAPI::class) @ExperimentalMaterial3Api @Composable -internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versionInfo: String = "3.2.0", popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: () -> Unit) { +internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versionInfo: String = "3.2.0", popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?) -> Unit) { val uiState by viewModel.uiState.collectAsState() var showLogoutDialog by remember { mutableStateOf(false) } @@ -166,7 +166,7 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio .clickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberBounceIndication(), - onClick = navigationToEditMemberInfo , + onClick = { navigationToEditMemberInfo(uiState.profile) } , ), ) { if (uiState.isLoading) { diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt index 2285029b..96ae984a 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt @@ -18,7 +18,7 @@ fun NavController.navigateToSetting( ) = navigate(SETTING_ROUTE, navOptions) @ExperimentalMaterial3Api -fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: () -> Unit) { +fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?) -> Unit) { composable( route = SETTING_ROUTE, enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, From a1ecc8e7c2a0bff87f8ef45e82f88b9f01209649 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Thu, 7 Nov 2024 17:17:50 +0900 Subject: [PATCH 06/23] feat: Create Get Gallery Image --- feature/edit-member-info/build.gradle.kts | 5 +- .../editmemberinfo/EditMemberInfoScreen.kt | 47 ++++++++++++++++--- settings.gradle.kts | 1 + 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/feature/edit-member-info/build.gradle.kts b/feature/edit-member-info/build.gradle.kts index b6f293a5..0e9fa9a3 100644 --- a/feature/edit-member-info/build.gradle.kts +++ b/feature/edit-member-info/build.gradle.kts @@ -21,11 +21,12 @@ kotlin { implementation(projects.common) implementation(projects.ui) implementation(projects.logging) + implementation("com.mohamedrejeb.calf:calf-file-picker:0.5.5") + implementation("com.mohamedrejeb.calf:calf-permissions:0.5.5") } } - android { - namespace = "com.b1nd.dodam.setting" + namespace = "com.b1nd.dodam.edit_member_info" defaultConfig { consumerProguardFiles("consumer-rules.pro") } diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index ffc8415f..1828a6c1 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -3,6 +3,7 @@ package com.b1nd.dodam.editmemberinfo import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer @@ -14,18 +15,19 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Scaffold +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.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme import com.b1nd.dodam.designsystem.component.AvatarSize import com.b1nd.dodam.designsystem.component.DodamAvatar @@ -33,14 +35,19 @@ import com.b1nd.dodam.designsystem.component.DodamButton import com.b1nd.dodam.designsystem.component.DodamTextField import com.b1nd.dodam.designsystem.component.DodamTopAppBar import com.b1nd.dodam.ui.component.modifier.`if` -import com.b1nd.dodam.ui.icons.ColoredPencil -import com.b1nd.dodam.ui.icons.DefaultProfile import com.b1nd.dodam.ui.icons.Plus import com.b1nd.dodam.ui.util.addFocusCleaner +import com.mohamedrejeb.calf.core.LocalPlatformContext +import com.mohamedrejeb.calf.io.getPath +import com.mohamedrejeb.calf.io.readByteArray +import com.mohamedrejeb.calf.picker.FilePickerFileType +import com.mohamedrejeb.calf.picker.FilePickerSelectionMode +import com.mohamedrejeb.calf.picker.rememberFilePickerLauncher +import kotlinx.coroutines.launch @Composable internal fun EditMemberInfoScreen( - profileImage: String?, + profileImage: String, popBackStack: () -> Unit ) { @@ -49,6 +56,29 @@ internal fun EditMemberInfoScreen( var phone by remember { mutableStateOf("") } val focusManager = LocalFocusManager.current + val scope = rememberCoroutineScope() + val context = LocalPlatformContext.current + + + var byteArray by remember { mutableStateOf(ByteArray(0)) } + var platformSpecificFilePath by remember { mutableStateOf("") } + + val pickerLauncher = rememberFilePickerLauncher( + type = FilePickerFileType.Image, + selectionMode = FilePickerSelectionMode.Multiple, + onResult = { files -> + scope.launch { + files.firstOrNull()?.let { + byteArray = it.readByteArray(context) + platformSpecificFilePath = it.getPath(context) ?:"" + } + } + } + ) + + LaunchedEffect(true){ + platformSpecificFilePath = profileImage + } Scaffold( modifier = Modifier.addFocusCleaner(focusManager), @@ -77,9 +107,9 @@ internal fun EditMemberInfoScreen( DodamAvatar( avatarSize = AvatarSize.XXL, contentDescription = "프로필 이미지", - model = if (profileImage == "default") null else profileImage, + model = if (platformSpecificFilePath == "default") null else platformSpecificFilePath , modifier = Modifier - .`if`(profileImage == "default") { + .`if`(platformSpecificFilePath == "default") { border( width = 1.dp, color = borderColor, @@ -94,6 +124,9 @@ internal fun EditMemberInfoScreen( modifier = Modifier .size(32.dp) .align(Alignment.BottomEnd) + .clickable { + pickerLauncher.launch() + } ) } Column( diff --git a/settings.gradle.kts b/settings.gradle.kts index 2b5443ff..7819b945 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -15,6 +15,7 @@ dependencyResolutionManagement { mavenCentral() maven("https://jitpack.io") maven("https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental") + maven("https://s01.oss.sonatype.org/content/repositories/snapshots") } } From 97f0d0e9af8bb0cfe63182c7b8ea5c478c1f6f13 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Thu, 7 Nov 2024 17:39:35 +0900 Subject: [PATCH 07/23] feat: Change Profile Image Shape --- feature-student/all/build.gradle.kts | 1 + .../java/com/b1nd/dodam/member/AllScreen.kt | 53 ++++++++++--------- .../kotlin/com/b1nd/dodam/all/AllScreen.kt | 2 +- .../com/b1nd/dodam/setting/SettingScreen.kt | 42 +++++++-------- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/feature-student/all/build.gradle.kts b/feature-student/all/build.gradle.kts index 0239bbd3..7a33a061 100644 --- a/feature-student/all/build.gradle.kts +++ b/feature-student/all/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { implementation(projects.common) implementation(projects.datastore) implementation(libs.dodam.design.system) + implementation(libs.dodam.design.system.cmm) implementation(projects.data.member) implementation(projects.ui) implementation(libs.coil.compose) diff --git a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt index a3f862f4..f708bec8 100644 --- a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt +++ b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt @@ -2,6 +2,7 @@ package com.b1nd.dodam.member import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -13,6 +14,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider @@ -39,7 +41,10 @@ import com.b1nd.dodam.dds.foundation.DodamIcons import com.b1nd.dodam.dds.style.BodyLarge import com.b1nd.dodam.dds.style.GearIcon import com.b1nd.dodam.dds.style.LabelLarge -import com.b1nd.dodam.dds.theme.DodamTheme +import com.b1nd.dodam.designsystem.DodamTheme +import com.b1nd.dodam.designsystem.component.AvatarSize +import com.b1nd.dodam.designsystem.component.DodamAvatar +import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.effect.shimmerEffect import com.b1nd.dodam.ui.icons.BarChart import com.b1nd.dodam.ui.icons.ColoredBus @@ -80,15 +85,15 @@ fun AllScreen( } }, colors = TopAppBarColors( - containerColor = MaterialTheme.colorScheme.background, - scrolledContainerColor = MaterialTheme.colorScheme.background, - navigationIconContentColor = MaterialTheme.colorScheme.background, + containerColor = DodamTheme.colors.backgroundNeutral, + scrolledContainerColor = DodamTheme.colors.backgroundNeutral, + navigationIconContentColor = DodamTheme.colors.backgroundNeutral, titleContentColor = MaterialTheme.colorScheme.onBackground, actionIconContentColor = MaterialTheme.colorScheme.onSurfaceVariant, ), ) }, - containerColor = MaterialTheme.colorScheme.background, + containerColor = DodamTheme.colors.backgroundNeutral, ) { paddingValues -> Column( modifier = Modifier @@ -102,10 +107,10 @@ fun AllScreen( ) { Box( modifier = Modifier - .size(70.dp) + .size(64.dp) .background( shimmerEffect(), - RoundedCornerShape(12.dp), + CircleShape, ), ) Spacer(modifier = Modifier.width(16.dp)) @@ -132,25 +137,21 @@ fun AllScreen( ) { uiState.memberInfo?.let { myInfo -> Box { - if (myInfo.profileImage != null) { - AsyncImage( - model = myInfo.profileImage, - contentDescription = "profile", - modifier = Modifier - .clip(shape = RoundedCornerShape(12.dp)) - .size(70.dp), - contentScale = ContentScale.Crop, - ) - } else { - Image( - bitmap = DefaultProfile, - contentDescription = "profile", - modifier = Modifier - .clip(shape = RoundedCornerShape(12.dp)) - .size(70.dp), - contentScale = ContentScale.Crop, - ) - } + val borderColor = DodamTheme.colors.lineAlternative + DodamAvatar( + avatarSize = AvatarSize.ExtraLarge, + contentDescription = "프로필 이미지", + model = myInfo.profileImage , + modifier = Modifier + .`if`(myInfo.profileImage.isNullOrEmpty()) { + border( + width = 1.dp, + color = borderColor, + shape = CircleShape + ) + }, + contentScale = ContentScale.Crop + ) } Spacer(modifier = Modifier.width(16.dp)) val classInfo = myInfo.student diff --git a/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt b/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt index a3aa027d..5b9199e0 100644 --- a/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt +++ b/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt @@ -100,7 +100,7 @@ internal fun AllScreen( if (uiState.isLoading) { Box( modifier = Modifier - .size(70.dp) + .size(64.dp) .background( brush = shimmerEffect(), shape = DodamTheme.shapes.extraSmall, diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index 9f18daeb..b59a7de3 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -2,6 +2,7 @@ package com.b1nd.dodam.setting import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement @@ -15,6 +16,7 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold @@ -40,8 +42,10 @@ import androidx.compose.ui.window.Dialog import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme import com.b1nd.dodam.designsystem.animation.rememberBounceIndication +import com.b1nd.dodam.designsystem.component.AvatarSize import com.b1nd.dodam.designsystem.component.ButtonRole import com.b1nd.dodam.designsystem.component.DividerType +import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamButtonDialog import com.b1nd.dodam.designsystem.component.DodamDialog import com.b1nd.dodam.designsystem.component.DodamDivider @@ -176,10 +180,10 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio ) { Box( modifier = Modifier - .size(56.dp) + .size(64.dp) .background( brush = shimmerEffect(), - shape = DodamTheme.shapes.medium, + shape = CircleShape, ), ) @@ -208,25 +212,21 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(16.dp), ) { - if (uiState.profile != null && uiState.profile != "") { - AsyncImage( - modifier = Modifier - .clip(DodamTheme.shapes.medium) - .size(56.dp), - model = uiState.profile, - contentDescription = null, - contentScale = ContentScale.Crop, - ) - } else { - Image( - modifier = Modifier - .clip(DodamTheme.shapes.medium) - .size(56.dp), - bitmap = DefaultProfile, - contentDescription = "프로필 이미지", - contentScale = ContentScale.Crop, - ) - } + val borderColor = DodamTheme.colors.lineAlternative + DodamAvatar( + avatarSize = AvatarSize.ExtraLarge, + contentDescription = "프로필 이미지", + model = uiState.profile , + modifier = Modifier + .`if`(uiState.profile.isNullOrEmpty()) { + border( + width = 1.dp, + color = borderColor, + shape = CircleShape + ) + }, + contentScale = ContentScale.Crop + ) Column { Text( From c02c12dff52622da0e5439fdc038349af9ac75c7 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Thu, 7 Nov 2024 19:42:01 +0900 Subject: [PATCH 08/23] feat: Move User Data --- .../kotlin/com/b1nd/dodam/student/DodamApp.kt | 7 +++++-- .../com/b1nd/dodam/teacher/DodamTeacherApp.kt | 7 +++++-- .../editmemberinfo/EditMemberInfoScreen.kt | 11 ++++++---- .../editmemberinfo/di/ViewModelModule.kt | 4 ++-- .../navigation/EditMemberInfoNavigation.kt | 20 +++++++++++++++---- .../viewmodel/EditmemberInfoViewModel.kt | 7 ------- .../com/b1nd/dodam/setting/SettingScreen.kt | 9 +++++++-- .../b1nd/dodam/setting/SettingViewModel.kt | 2 ++ .../dodam/setting/model/SettingUiState.kt | 2 ++ .../setting/navigation/SettingNavigation.kt | 2 +- 10 files changed, 47 insertions(+), 24 deletions(-) delete mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt diff --git a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt index 9be67ad2..22ab20db 100644 --- a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt +++ b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt @@ -238,9 +238,12 @@ fun DodamApp( versionInfo = "3.2.0", popBackStack = navController::popBackStack, logout = logout, - navigationToEditMemberInfo = { profileImage -> + navigationToEditMemberInfo = { profileImage, name, email, phone -> navController.navigationToEditMemberInfo( - profileImage + profileImage = profileImage, + name = name, + email = email, + phone = phone ) } ) diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt index 49ce0b9e..5373c04b 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt @@ -258,9 +258,12 @@ fun DodamTeacherApp(exit: () -> Unit, viewModel: DodamTeacherAppViewModel = koin popBackStack = navHostController::popBackStack, logout = exit, versionInfo = getPlatformName(), - navigationToEditMemberInfo = {profileImage -> + navigationToEditMemberInfo = {profileImage, name, email, phone -> navHostController.navigationToEditMemberInfo( - profileImage + profileImage = profileImage, + name = name, + email = email, + phone = phone ) } ) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 1828a6c1..7f625e53 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -48,12 +48,15 @@ import kotlinx.coroutines.launch @Composable internal fun EditMemberInfoScreen( profileImage: String, - popBackStack: () -> Unit + popBackStack: () -> Unit, + name: String, + email: String, + phone: String ) { - var name by remember { mutableStateOf("") } - var email by remember { mutableStateOf("") } - var phone by remember { mutableStateOf("") } + var name by remember { mutableStateOf(name) } + var email by remember { mutableStateOf(email) } + var phone by remember { mutableStateOf(phone) } val focusManager = LocalFocusManager.current val scope = rememberCoroutineScope() diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt index 5c6849f9..21f62ac6 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/di/ViewModelModule.kt @@ -1,9 +1,9 @@ package com.b1nd.dodam.editmemberinfo.di -import com.b1nd.dodam.editmemberinfo.viewmodel.EditmemberInfoViewModel +import com.b1nd.dodam.editmemberinfo.viewmodel.EditMemberInfoViewModel import org.koin.compose.viewmodel.dsl.viewModel import org.koin.dsl.module val editMemberInfoViewModelModule = module { - viewModel { EditmemberInfoViewModel() } + viewModel { EditMemberInfoViewModel() } } diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt index f2c69472..f76479b4 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt @@ -21,20 +21,26 @@ const val EDIT_MEMBER_INFO_ROUTE = "login" fun NavController.navigationToEditMemberInfo( profileImage: String?, + name: String, + phone: String, + email: String, navOptions: NavOptions? = androidx.navigation.navOptions { launchSingleTop = true }, ) { val image = (profileImage ?: "default").toByteArray().encodeBase64() - navigate("$EDIT_MEMBER_INFO_ROUTE/$image", navOptions) + navigate("$EDIT_MEMBER_INFO_ROUTE/$image/$name/$email/$phone", navOptions) } @ExperimentalMaterial3Api fun NavGraphBuilder.editMemberInfoScreen(popBackStack: () -> Unit) { composable( - route = "$EDIT_MEMBER_INFO_ROUTE/{image}", + route = "$EDIT_MEMBER_INFO_ROUTE/{image}/{name}/{email}/{phone}", arguments = listOf( - navArgument("image") { type = NavType.StringType } + navArgument("image") { type = NavType.StringType }, + navArgument("name") { type = NavType.StringType }, + navArgument("email") { type = NavType.StringType }, + navArgument("phone") { type = NavType.StringType }, ), enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, exitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, @@ -43,9 +49,15 @@ fun NavGraphBuilder.editMemberInfoScreen(popBackStack: () -> Unit) { ) { val encodedImage = it.arguments?.getString("image") ?: "default" val profileImage = encodedImage.decodeBase64String() + val name = it.arguments?.getString("name") ?: "" + val email = it.arguments?.getString("email") ?: "" + val phone = it.arguments?.getString("phone") ?: "" EditMemberInfoScreen( profileImage = profileImage, - popBackStack = popBackStack + popBackStack = popBackStack, + name = name, + email = email, + phone = phone ) } } \ No newline at end of file diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt deleted file mode 100644 index d296016b..00000000 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditmemberInfoViewModel.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.b1nd.dodam.editmemberinfo.viewmodel - -import androidx.lifecycle.ViewModel -import org.koin.core.component.KoinComponent - -class EditmemberInfoViewModel : ViewModel(), KoinComponent { -} \ No newline at end of file diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index b59a7de3..93dca309 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -60,7 +60,7 @@ import org.koin.core.annotation.KoinExperimentalAPI @OptIn(KoinExperimentalAPI::class) @ExperimentalMaterial3Api @Composable -internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versionInfo: String = "3.2.0", popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?) -> Unit) { +internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versionInfo: String = "3.2.0", popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?, name: String, email: String, phone: String) -> Unit) { val uiState by viewModel.uiState.collectAsState() var showLogoutDialog by remember { mutableStateOf(false) } @@ -170,7 +170,12 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio .clickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberBounceIndication(), - onClick = { navigationToEditMemberInfo(uiState.profile) } , + onClick = { navigationToEditMemberInfo( + uiState.profile, + uiState.name, + uiState.email, + uiState.phone + ) } , ), ) { if (uiState.isLoading) { diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt index 565c7ce5..888b19d2 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt @@ -31,6 +31,8 @@ class SettingViewModel : ViewModel(), KoinComponent { isLoading = false, name = result.data.name, profile = result.data.profileImage, + email = result.data.email, + phone = result.data.phone ) } } diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt index 39f1e222..fac85e4e 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt @@ -4,4 +4,6 @@ data class SettingUiState( val isLoading: Boolean = false, val profile: String? = null, val name: String = "", + val email: String = "", + val phone: String = "" ) diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt index 96ae984a..27872eb5 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt @@ -18,7 +18,7 @@ fun NavController.navigateToSetting( ) = navigate(SETTING_ROUTE, navOptions) @ExperimentalMaterial3Api -fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?) -> Unit) { +fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?, name: String, email: String, phone: String) -> Unit) { composable( route = SETTING_ROUTE, enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, From d7cb0fbaaf35055c5af5620221ea683f4a8849d2 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Mon, 11 Nov 2024 17:57:52 +0900 Subject: [PATCH 09/23] feat: Change Profile Image --- .../com/b1nd/dodam/member/MemberRepository.kt | 2 + .../member/repository/MemberRepositoryImpl.kt | 14 +++ data/upload/.gitignore | 1 + data/upload/build.gradle.kts | 29 ++++++ .../dodam/data/upload/UploadRepository.kt | 10 ++ .../dodam/data/upload/di/RepositoryModule.kt | 17 ++++ .../dodam/data/upload/model/UploadModel.kt | 12 +++ .../upload/repository/UploadRepositoryImpl.kt | 37 ++++++++ dodam-student/build.gradle.kts | 2 + .../dodam/student/util/DodamApplication.kt | 6 +- dodam-teacher-android/build.gradle.kts | 2 + .../kotlin/com/b1nd/dodam/teacher/Koin.kt | 6 +- feature/edit-member-info/build.gradle.kts | 1 + .../editmemberinfo/EditMemberInfoScreen.kt | 36 ++++++-- .../editmemberinfo/model/ProfileModel.kt | 8 ++ .../viewmodel/EditMemberInfoViewModel.kt | 91 +++++++++++++++++++ .../com/b1nd/dodam/network/core/DodamUrl.kt | 2 + .../b1nd/dodam/member/api/MemberService.kt | 23 +++++ .../member/datasource/MemberDataSource.kt | 4 + .../member/model/EditMemberInfoRequest.kt | 11 +++ network/upload/.gitignore | 1 + network/upload/build.gradle.kts | 33 +++++++ .../dodam/network/upload/api/UploadService.kt | 44 +++++++++ .../upload/datasource/UploadDataSource.kt | 9 ++ .../upload/di/scheduleDatasourceModule.kt | 11 +++ .../network/upload/model/UploadResponse.kt | 10 ++ settings.gradle.kts | 2 + 27 files changed, 416 insertions(+), 8 deletions(-) create mode 100644 data/upload/.gitignore create mode 100644 data/upload/build.gradle.kts create mode 100644 data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt create mode 100644 data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt create mode 100644 data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt create mode 100644 data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt create mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt create mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt create mode 100644 network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt create mode 100644 network/upload/.gitignore create mode 100644 network/upload/build.gradle.kts create mode 100644 network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt create mode 100644 network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt create mode 100644 network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/scheduleDatasourceModule.kt create mode 100644 network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt diff --git a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt index b21a3838..f2206661 100644 --- a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt +++ b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt @@ -2,6 +2,7 @@ package com.b1nd.dodam.member import com.b1nd.dodam.common.result.Result import com.b1nd.dodam.member.model.MemberInfo +import com.b1nd.dodam.network.core.model.DefaultResponse import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.flow.Flow @@ -9,4 +10,5 @@ interface MemberRepository { suspend fun getMyInfo(): Flow> suspend fun deactivation(): Flow> suspend fun getMemberActiveAll(): Flow>> + suspend fun editMemberInfo(name: String, email: String, phone: String, profileImage: String?): Flow> } diff --git a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt index 8b2b9905..b349e342 100644 --- a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt +++ b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt @@ -9,6 +9,7 @@ import com.b1nd.dodam.member.datasource.MemberDataSource import com.b1nd.dodam.member.model.ActiveStatus import com.b1nd.dodam.member.model.MemberInfo import com.b1nd.dodam.member.model.toModel +import com.b1nd.dodam.network.core.model.DefaultResponse import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineDispatcher @@ -43,4 +44,17 @@ internal class MemberRepositoryImpl( .asResult() .flowOn(dispatcher) } + + override suspend fun editMemberInfo( + name: String, + email: String, + phone: String, + profileImage: String? + ): Flow> { + return flow{ + emit(network.editMemberInfo(name, email, phone, profileImage)) + } + .asResult() + .flowOn(dispatcher) + } } diff --git a/data/upload/.gitignore b/data/upload/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/data/upload/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/data/upload/build.gradle.kts b/data/upload/build.gradle.kts new file mode 100644 index 00000000..b7a21aab --- /dev/null +++ b/data/upload/build.gradle.kts @@ -0,0 +1,29 @@ +import com.b1nd.dodam.dsl.android +import com.b1nd.dodam.dsl.kotlin +import com.b1nd.dodam.dsl.setIOS + +plugins { + alias(libs.plugins.dodam.multiplatform) + alias(libs.plugins.dodam.multiplatform.kotlin) + alias(libs.plugins.dodam.multiplatform.koin) +} + +kotlin { + setIOS("data.upload") + + sourceSets.commonMain.dependencies { + api(projects.data.core) + implementation(projects.common) + implementation(projects.network.upload) + + } +} + + +android { + namespace = "com.b1nd.dodam.data.upload" + + defaultConfig { + consumerProguardFiles("consumer-rules.pro") + } +} \ No newline at end of file diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt new file mode 100644 index 00000000..44fb4897 --- /dev/null +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt @@ -0,0 +1,10 @@ +package com.b1nd.dodam.data.upload + +import com.b1nd.dodam.common.result.Result +import com.b1nd.dodam.data.upload.model.UploadModel +import kotlinx.coroutines.flow.Flow + +interface UploadRepository { + + suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): Flow> +} \ No newline at end of file diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt new file mode 100644 index 00000000..5fb3b89d --- /dev/null +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt @@ -0,0 +1,17 @@ +package com.b1nd.dodam.data.upload.di + +import com.b1nd.dodam.common.DispatcherType +import com.b1nd.dodam.data.upload.UploadRepository +import com.b1nd.dodam.data.upload.repository.UploadRepositoryImpl +import org.koin.core.qualifier.named +import org.koin.dsl.module + + +val uploadRepositoryModule = module { + single { + UploadRepositoryImpl( + network = get(), + dispatcher = get(named(DispatcherType.IO)), + ) + } +} \ No newline at end of file diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt new file mode 100644 index 00000000..7cb76dbe --- /dev/null +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt @@ -0,0 +1,12 @@ +package com.b1nd.dodam.data.upload.model + +import com.b1nd.dodam.network.core.model.Response +import com.b1nd.dodam.network.upload.model.UploadResponse + +data class UploadModel( + val profileImage: String +) + +fun String.toModel() = UploadModel( + profileImage = this +) \ No newline at end of file diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt new file mode 100644 index 00000000..42446c35 --- /dev/null +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt @@ -0,0 +1,37 @@ +package com.b1nd.dodam.data.upload.repository + +import androidx.compose.ui.input.nestedscroll.NestedScrollSource +import com.b1nd.dodam.common.Dispatcher +import com.b1nd.dodam.common.DispatcherType +import com.b1nd.dodam.common.result.Result +import com.b1nd.dodam.common.result.asResult +import com.b1nd.dodam.data.upload.UploadRepository +import com.b1nd.dodam.data.upload.model.UploadModel +import com.b1nd.dodam.data.upload.model.toModel +import com.b1nd.dodam.network.upload.datasource.UploadDataSource +import kotlinx.collections.immutable.toImmutableList +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.flowOn + +class UploadRepositoryImpl( + private val network: UploadDataSource, + @Dispatcher(DispatcherType.IO) private val dispatcher: CoroutineDispatcher +): UploadRepository { + override suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): Flow> { + return flow { + emit( + network.upload( + fileName = fileName, + fileMimeType = fileMimeType, + byteArray = byteArray + ).toModel() + ) + } + .asResult() + .flowOn(dispatcher) + + } + +} \ No newline at end of file diff --git a/dodam-student/build.gradle.kts b/dodam-student/build.gradle.kts index 0ee5e8fc..dba0daf9 100644 --- a/dodam-student/build.gradle.kts +++ b/dodam-student/build.gradle.kts @@ -89,4 +89,6 @@ dependencies { implementation(projects.network.bundleidInfo) implementation(projects.data.bundleidInfo) implementation(projects.feature.editMemberInfo) + implementation(projects.network.upload) + implementation(projects.data.upload) } diff --git a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt index ea1db4d5..f8e1759e 100644 --- a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt +++ b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt @@ -17,6 +17,7 @@ import com.b1nd.dodam.data.nightstudy.di.nightStudyRepositoryModule import com.b1nd.dodam.data.outing.di.outingRepositoryModule import com.b1nd.dodam.data.point.di.pointRepositoryModule import com.b1nd.dodam.data.schedule.di.scheduleRepositoryModule +import com.b1nd.dodam.data.upload.di.uploadRepositoryModule import com.b1nd.dodam.datastore.di.dataStoreModule import com.b1nd.dodam.editmemberinfo.di.editMemberInfoViewModelModule import com.b1nd.dodam.keystore.keystoreManagerModule @@ -31,6 +32,7 @@ import com.b1nd.dodam.network.nightstudy.di.nightStudyDataSourceModule import com.b1nd.dodam.network.outing.di.outingDataSourceModule import com.b1nd.dodam.network.point.di.pointDataSourceModule import com.b1nd.dodam.network.schedule.di.scheduleDatasourceModule +import com.b1nd.dodam.network.upload.di.uploadDatasourceModule import com.b1nd.dodam.nightstudy.di.nightStudyViewModelModule import com.b1nd.dodam.outing.di.outingViewModelModule import com.b1nd.dodam.register.di.registerDataSourceModule @@ -97,7 +99,9 @@ class DodamApplication : Application() { outingViewModelModule, bundleIdInfoRepositoryModule, bundleIdInfoDataSourceModule, - editMemberInfoViewModelModule + editMemberInfoViewModelModule, + uploadDatasourceModule, + uploadRepositoryModule ) + mainViewModelModules, ) } diff --git a/dodam-teacher-android/build.gradle.kts b/dodam-teacher-android/build.gradle.kts index 9d33d1f7..2a5d9a29 100644 --- a/dodam-teacher-android/build.gradle.kts +++ b/dodam-teacher-android/build.gradle.kts @@ -57,6 +57,8 @@ kotlin { implementation(projects.network.bundleidInfo) implementation(projects.data.bundleidInfo) implementation(projects.feature.editMemberInfo) + implementation(projects.network.upload) + implementation(projects.data.upload) } androidMain.dependencies { diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt index f89334b7..727c3548 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt @@ -13,6 +13,7 @@ import com.b1nd.dodam.data.nightstudy.di.nightStudyRepositoryModule import com.b1nd.dodam.data.outing.di.outingRepositoryModule import com.b1nd.dodam.data.point.di.pointRepositoryModule import com.b1nd.dodam.data.schedule.di.scheduleRepositoryModule +import com.b1nd.dodam.data.upload.di.uploadRepositoryModule import com.b1nd.dodam.datastore.di.dataStoreModule import com.b1nd.dodam.editmemberinfo.di.editMemberInfoViewModelModule import com.b1nd.dodam.home.di.homeViewModelModule @@ -28,6 +29,7 @@ import com.b1nd.dodam.network.nightstudy.di.nightStudyDataSourceModule import com.b1nd.dodam.network.outing.di.outingDataSourceModule import com.b1nd.dodam.network.point.di.pointDataSourceModule import com.b1nd.dodam.network.schedule.di.scheduleDatasourceModule +import com.b1nd.dodam.network.upload.di.uploadDatasourceModule import com.b1nd.dodam.nightstudy.di.nightStudyViewModelModule import com.b1nd.dodam.outing.di.outingViewModelModule import com.b1nd.dodam.point.di.pointViewModelModule @@ -79,7 +81,9 @@ fun initKoin(block: KoinApplication.() -> Unit = {}) { settingViewModelModule, bundleIdInfoRepositoryModule, bundleIdInfoDataSourceModule, - editMemberInfoViewModelModule + editMemberInfoViewModelModule, + uploadDatasourceModule, + uploadRepositoryModule ) block() } diff --git a/feature/edit-member-info/build.gradle.kts b/feature/edit-member-info/build.gradle.kts index 0e9fa9a3..efdfcee9 100644 --- a/feature/edit-member-info/build.gradle.kts +++ b/feature/edit-member-info/build.gradle.kts @@ -21,6 +21,7 @@ kotlin { implementation(projects.common) implementation(projects.ui) implementation(projects.logging) + implementation(projects.data.upload) implementation("com.mohamedrejeb.calf:calf-file-picker:0.5.5") implementation("com.mohamedrejeb.calf:calf-permissions:0.5.5") } diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 7f625e53..b523d5f1 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -18,6 +18,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -28,25 +29,30 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel import com.b1nd.dodam.designsystem.DodamTheme import com.b1nd.dodam.designsystem.component.AvatarSize import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamButton import com.b1nd.dodam.designsystem.component.DodamTextField import com.b1nd.dodam.designsystem.component.DodamTopAppBar +import com.b1nd.dodam.editmemberinfo.viewmodel.EditMemberInfoViewModel import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.icons.Plus import com.b1nd.dodam.ui.util.addFocusCleaner import com.mohamedrejeb.calf.core.LocalPlatformContext +import com.mohamedrejeb.calf.io.getName import com.mohamedrejeb.calf.io.getPath import com.mohamedrejeb.calf.io.readByteArray import com.mohamedrejeb.calf.picker.FilePickerFileType import com.mohamedrejeb.calf.picker.FilePickerSelectionMode import com.mohamedrejeb.calf.picker.rememberFilePickerLauncher import kotlinx.coroutines.launch +import org.koin.compose.viewmodel.koinViewModel @Composable internal fun EditMemberInfoScreen( + viewModel: EditMemberInfoViewModel = koinViewModel(), profileImage: String, popBackStack: () -> Unit, name: String, @@ -59,6 +65,8 @@ internal fun EditMemberInfoScreen( var phone by remember { mutableStateOf(phone) } val focusManager = LocalFocusManager.current + val uiState by viewModel.uiState.collectAsState() + val scope = rememberCoroutineScope() val context = LocalPlatformContext.current @@ -71,16 +79,25 @@ internal fun EditMemberInfoScreen( selectionMode = FilePickerSelectionMode.Multiple, onResult = { files -> scope.launch { - files.firstOrNull()?.let { - byteArray = it.readByteArray(context) - platformSpecificFilePath = it.getPath(context) ?:"" + files.firstOrNull()?.let { file -> + byteArray = file.readByteArray(context) + platformSpecificFilePath = file.getPath(context) ?: "" + file.getName(context) + viewModel.fileUpload( + fileByteArray = byteArray, + fileMimeType = file.getPath(context) ?: "", + fileName = file.getName(context) ?: "" + ) } } } ) - LaunchedEffect(true){ + LaunchedEffect(true) { platformSpecificFilePath = profileImage + viewModel.setProfile( + if (profileImage == "default") null else profileImage + ) } Scaffold( @@ -110,7 +127,7 @@ internal fun EditMemberInfoScreen( DodamAvatar( avatarSize = AvatarSize.XXL, contentDescription = "프로필 이미지", - model = if (platformSpecificFilePath == "default") null else platformSpecificFilePath , + model = if (uiState.image == "default") null else uiState.image, modifier = Modifier .`if`(platformSpecificFilePath == "default") { border( @@ -175,7 +192,14 @@ internal fun EditMemberInfoScreen( } } DodamButton( - onClick = {}, + onClick = { + viewModel.editMember( + email = email, + name = name, + phone = phone, + profileImage = uiState.image + ) + }, text = "수정 완료", modifier = Modifier .align(Alignment.BottomCenter) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt new file mode 100644 index 00000000..1db5277b --- /dev/null +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt @@ -0,0 +1,8 @@ +package com.b1nd.dodam.editmemberinfo.model + +data class ProfileModel( + val name: String = "", + val email: String = "", + val phone: String = "", + val image: String? = null +) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt new file mode 100644 index 00000000..44055260 --- /dev/null +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt @@ -0,0 +1,91 @@ +package com.b1nd.dodam.editmemberinfo.viewmodel + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.b1nd.dodam.common.result.Result +import com.b1nd.dodam.data.upload.UploadRepository +import com.b1nd.dodam.editmemberinfo.model.ProfileModel +import com.b1nd.dodam.member.MemberRepository +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject + +class EditMemberInfoViewModel : ViewModel(), KoinComponent { + private val memberRepository: MemberRepository by inject() + private val uploadRepository: UploadRepository by inject() + + private val _uiState = MutableStateFlow(ProfileModel()) + val uiState = _uiState.asStateFlow() + + fun setProfile( + profileImage: String? + ) { + viewModelScope.launch { + _uiState.value = _uiState.value.copy( + image = profileImage + ) + } + } + + fun editMember( + email: String, + name: String, + phone: String, + profileImage: String? + ) { + viewModelScope.launch { + memberRepository.editMemberInfo( + name = name, + email = email, + phone = phone, + profileImage = profileImage + ).collect { + when (it) { + is Result.Success -> { + println(it.data) + } + + is Result.Error -> { + it.error.printStackTrace() + } + + is Result.Loading -> {} + } + } + } + } + + fun fileUpload( + fileByteArray: ByteArray, + fileMimeType: String, + fileName: String + ) { + viewModelScope.launch { + uploadRepository.upload( + fileName = fileName, + fileMimeType = fileMimeType, + byteArray = fileByteArray + ).collect { + when (it) { + is Result.Error -> { + it.error.printStackTrace() + } + + is Result.Success -> { + _uiState.update { ui -> + println(it.data) + ui.copy( + image = it.data.profileImage + ) + } + } + + is Result.Loading -> {} + } + } + } + } +} \ No newline at end of file diff --git a/network/core/src/commonMain/kotlin/com/b1nd/dodam/network/core/DodamUrl.kt b/network/core/src/commonMain/kotlin/com/b1nd/dodam/network/core/DodamUrl.kt index 279ee572..70bd97be 100644 --- a/network/core/src/commonMain/kotlin/com/b1nd/dodam/network/core/DodamUrl.kt +++ b/network/core/src/commonMain/kotlin/com/b1nd/dodam/network/core/DodamUrl.kt @@ -15,6 +15,7 @@ object DodamUrl { const val BANNER = "$BASE_URL/banner" const val POINT = "$BASE_URL/point" const val GET_BUNDLE_ID = "https://itunes.apple.com/lookup?bundleId=com.b1nd.dodam.teacher&country=br" + const val UPLOAD = "$BASE_URL/upload" object Meal { const val MONTH = "$MEAL/month" @@ -34,6 +35,7 @@ object DodamUrl { const val MY = "$MEMBER/my" const val DEACTIVATION = "$MEMBER/deactivate" const val STATUS = "$MEMBER/status" + const val EDIT = "$MEMBER/info" } object WakeupSong { diff --git a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt index 6417a406..d5252ab5 100644 --- a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt +++ b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt @@ -1,8 +1,10 @@ package com.b1nd.dodam.member.api import com.b1nd.dodam.member.datasource.MemberDataSource +import com.b1nd.dodam.member.model.EditMemberInfoRequest import com.b1nd.dodam.member.model.MemberInfoResponse import com.b1nd.dodam.network.core.DodamUrl +import com.b1nd.dodam.network.core.model.DefaultResponse import com.b1nd.dodam.network.core.model.Response import com.b1nd.dodam.network.core.util.defaultSafeRequest import com.b1nd.dodam.network.core.util.safeRequest @@ -11,6 +13,7 @@ import io.ktor.client.call.body import io.ktor.client.request.get import io.ktor.client.request.parameter import io.ktor.client.request.patch +import io.ktor.client.request.setBody internal class MemberService( private val client: HttpClient, @@ -36,4 +39,24 @@ internal class MemberService( }.body() } } + + override suspend fun editMemberInfo( + name: String, + email: String, + phone: String, + profileImage: String? + ) { + return defaultSafeRequest { + client.patch(DodamUrl.Member.EDIT){ + setBody( + EditMemberInfoRequest( + name = name, + email = email, + phone = phone, + profileImage = profileImage + ) + ) + }.body() + } + } } diff --git a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt index 6349bdf3..c6a7b980 100644 --- a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt +++ b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt @@ -1,9 +1,13 @@ package com.b1nd.dodam.member.datasource +import com.b1nd.dodam.common.result.Result import com.b1nd.dodam.member.model.MemberInfoResponse +import com.b1nd.dodam.network.core.model.DefaultResponse +import kotlinx.coroutines.flow.Flow interface MemberDataSource { suspend fun getMyInfo(): MemberInfoResponse suspend fun deactivation() suspend fun getMemberAll(status: String): List + suspend fun editMemberInfo(name: String, email: String, phone: String, profileImage: String?) } diff --git a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt new file mode 100644 index 00000000..0e52f40c --- /dev/null +++ b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt @@ -0,0 +1,11 @@ +package com.b1nd.dodam.member.model + +import kotlinx.serialization.Serializable + +@Serializable +data class EditMemberInfoRequest( + val email: String, + val name: String, + val phone: String, + val profileImage: String? +) diff --git a/network/upload/.gitignore b/network/upload/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/network/upload/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/network/upload/build.gradle.kts b/network/upload/build.gradle.kts new file mode 100644 index 00000000..2b4553b3 --- /dev/null +++ b/network/upload/build.gradle.kts @@ -0,0 +1,33 @@ +import com.b1nd.dodam.dsl.android +import com.b1nd.dodam.dsl.kotlin +import com.b1nd.dodam.dsl.setIOS + +plugins { + alias(libs.plugins.dodam.multiplatform) + alias(libs.plugins.dodam.multiplatform.kotlin.serialization) + alias(libs.plugins.dodam.multiplatform.koin) +} + +kotlin { + setIOS("network.upload") + + sourceSets.commonMain.dependencies { + api(projects.network.core) + implementation(projects.common) + implementation(libs.kotlinx.collections.immutable) + } + + sourceSets.commonTest.dependencies { + implementation(libs.kotlin.test) + implementation(libs.ktor.client.mock) + implementation(libs.kotlinx.coroutines.test) + } +} + +android { + namespace = "com.b1nd.dodam.network.upload" + + defaultConfig { + consumerProguardFiles("consumer-rules.pro") + } +} \ No newline at end of file diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt new file mode 100644 index 00000000..ebc364fd --- /dev/null +++ b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt @@ -0,0 +1,44 @@ +package com.b1nd.dodam.network.upload.api + +import com.b1nd.dodam.network.core.DodamUrl +import com.b1nd.dodam.network.core.model.Response +import com.b1nd.dodam.network.core.util.safeRequest +import com.b1nd.dodam.network.upload.datasource.UploadDataSource +import com.b1nd.dodam.network.upload.model.UploadResponse +import io.ktor.client.HttpClient +import io.ktor.client.call.body +import io.ktor.client.plugins.onUpload +import io.ktor.client.request.forms.MultiPartFormDataContent +import io.ktor.client.request.forms.formData +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import io.ktor.http.Headers +import io.ktor.http.HttpHeaders + +class UploadService( + private val client: HttpClient +): UploadDataSource { + override suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): String { + return safeRequest { + client.post(DodamUrl.UPLOAD){ + setBody( + MultiPartFormDataContent( + formData { + append( + "file", + byteArray, + Headers.build { + append(HttpHeaders.ContentType, fileMimeType) + append(HttpHeaders.ContentDisposition, "filename=\"${fileName}\"") + }, + ) + }, + ), + ) + onUpload { bytesSentTotal, contentLength -> + println("Sent $bytesSentTotal bytes from $contentLength") + } + }.body>() + } + } +} \ No newline at end of file diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt new file mode 100644 index 00000000..0b86ba73 --- /dev/null +++ b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt @@ -0,0 +1,9 @@ +package com.b1nd.dodam.network.upload.datasource + +import com.b1nd.dodam.network.core.model.Response +import com.b1nd.dodam.network.upload.model.UploadResponse + +interface UploadDataSource { + + suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): String +} \ No newline at end of file diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/scheduleDatasourceModule.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/scheduleDatasourceModule.kt new file mode 100644 index 00000000..73d27ba0 --- /dev/null +++ b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/scheduleDatasourceModule.kt @@ -0,0 +1,11 @@ +package com.b1nd.dodam.network.upload.di + +import com.b1nd.dodam.network.upload.api.UploadService +import com.b1nd.dodam.network.upload.datasource.UploadDataSource +import org.koin.dsl.module + +val uploadDatasourceModule = module { + single { + UploadService(get()) + } +} diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt new file mode 100644 index 00000000..55d26201 --- /dev/null +++ b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt @@ -0,0 +1,10 @@ +package com.b1nd.dodam.network.upload.model + +import kotlinx.serialization.Serializable + +@Serializable +data class UploadResponse( + val status: Int, + val message: String, + val data: String +) diff --git a/settings.gradle.kts b/settings.gradle.kts index 7819b945..0d334aa4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -83,3 +83,5 @@ include(":feature-teacher:approve-nightstudy") include(":network:bundleid-info") include(":data:bundleid-info") include(":feature:edit-member-info") +include(":network:upload") +include(":data:upload") From 271a85dc8b808df25148d8795ccb3efd09a2ff45 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Mon, 11 Nov 2024 19:00:30 +0900 Subject: [PATCH 10/23] feat: Create Success Event --- .../all/src/main/java/com/b1nd/dodam/member/AllScreen.kt | 5 +++++ .../src/main/java/com/b1nd/dodam/member/AllViewModel.kt | 2 +- .../b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt | 9 +++++++++ .../editmemberinfo/model/EditMemberInfoSideEffect.kt | 6 ++++++ .../editmemberinfo/viewmodel/EditMemberInfoViewModel.kt | 7 +++++++ .../kotlin/com/b1nd/dodam/setting/SettingScreen.kt | 4 ++++ .../kotlin/com/b1nd/dodam/setting/SettingViewModel.kt | 2 +- 7 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt diff --git a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt index f708bec8..59c7141f 100644 --- a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt +++ b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBarColors import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment @@ -69,6 +70,10 @@ fun AllScreen( navigateToAddWakeUpSong: () -> Unit, ) { val uiState by viewModel.uiState.collectAsState() + + LaunchedEffect(key1 = true) { + viewModel.getMyInfo() + } Scaffold( modifier = Modifier .fillMaxSize(), diff --git a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt index 6d471c04..a39f827e 100644 --- a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt +++ b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt @@ -18,7 +18,7 @@ class AllViewModel : ViewModel(), KoinComponent { private val _uiState = MutableStateFlow(AllUiState()) val uiState = _uiState.asStateFlow() - init { + fun getMyInfo(){ viewModelScope.launch { memberRepository.getMyInfo().collect { result -> _uiState.update { uiState -> diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index b523d5f1..cea649ba 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -36,7 +36,9 @@ import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamButton import com.b1nd.dodam.designsystem.component.DodamTextField import com.b1nd.dodam.designsystem.component.DodamTopAppBar +import com.b1nd.dodam.editmemberinfo.model.EditMemberInfoSideEffect import com.b1nd.dodam.editmemberinfo.viewmodel.EditMemberInfoViewModel +import com.b1nd.dodam.ui.component.SnackbarState import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.icons.Plus import com.b1nd.dodam.ui.util.addFocusCleaner @@ -98,6 +100,13 @@ internal fun EditMemberInfoScreen( viewModel.setProfile( if (profileImage == "default") null else profileImage ) + viewModel.sideEffect.collect{ + when(it){ + EditMemberInfoSideEffect.SuccessEditMemberInfo -> { + popBackStack() + } + } + } } Scaffold( diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt new file mode 100644 index 00000000..14e2834b --- /dev/null +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt @@ -0,0 +1,6 @@ +package com.b1nd.dodam.editmemberinfo.model + + +sealed interface EditMemberInfoSideEffect { + data object SuccessEditMemberInfo : EditMemberInfoSideEffect +} \ No newline at end of file diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt index 44055260..fbeae244 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt @@ -4,9 +4,12 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.b1nd.dodam.common.result.Result import com.b1nd.dodam.data.upload.UploadRepository +import com.b1nd.dodam.editmemberinfo.model.EditMemberInfoSideEffect import com.b1nd.dodam.editmemberinfo.model.ProfileModel import com.b1nd.dodam.member.MemberRepository +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @@ -20,6 +23,9 @@ class EditMemberInfoViewModel : ViewModel(), KoinComponent { private val _uiState = MutableStateFlow(ProfileModel()) val uiState = _uiState.asStateFlow() + private val _sideEffect = MutableSharedFlow() + val sideEffect = _sideEffect.asSharedFlow() + fun setProfile( profileImage: String? ) { @@ -45,6 +51,7 @@ class EditMemberInfoViewModel : ViewModel(), KoinComponent { ).collect { when (it) { is Result.Success -> { + _sideEffect.emit(EditMemberInfoSideEffect.SuccessEditMemberInfo) println(it.data) } diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index 93dca309..08ef3b5f 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -72,6 +72,10 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio var count by remember { mutableIntStateOf(0) } + LaunchedEffect(key1 = true){ + viewModel.getMyInfo() + } + LaunchedEffect(count) { if (count == 10) { showEasterEggDialog = true diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt index 888b19d2..c19fa6be 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt @@ -21,7 +21,7 @@ class SettingViewModel : ViewModel(), KoinComponent { private val _uiState = MutableStateFlow(SettingUiState()) val uiState = _uiState.asStateFlow() - init { + fun getMyInfo(){ viewModelScope.launch { memberRepository.getMyInfo().collect { result -> when (result) { From e9c3a68a8b8d0adc318bc28482d96ce9df263fa4 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Mon, 11 Nov 2024 19:09:14 +0900 Subject: [PATCH 11/23] style: Apply Spotless Format --- .../com/b1nd/dodam/member/MemberRepository.kt | 1 - .../member/repository/MemberRepositoryImpl.kt | 10 ++---- .../dodam/data/upload/UploadRepository.kt | 2 +- .../dodam/data/upload/di/RepositoryModule.kt | 3 +- .../dodam/data/upload/model/UploadModel.kt | 9 ++--- .../upload/repository/UploadRepositoryImpl.kt | 14 +++----- .../kotlin/com/b1nd/dodam/student/DodamApp.kt | 8 ++--- .../dodam/student/util/DodamApplication.kt | 2 +- .../com/b1nd/dodam/teacher/DodamTeacherApp.kt | 8 ++--- .../kotlin/com/b1nd/dodam/teacher/Koin.kt | 2 +- .../java/com/b1nd/dodam/member/AllScreen.kt | 9 ++--- .../com/b1nd/dodam/member/AllViewModel.kt | 2 +- .../editmemberinfo/EditMemberInfoScreen.kt | 34 ++++++++----------- .../model/EditMemberInfoSideEffect.kt | 3 +- .../editmemberinfo/model/ProfileModel.kt | 2 +- .../navigation/EditMemberInfoNavigation.kt | 8 ++--- .../viewmodel/EditMemberInfoViewModel.kt | 27 +++++---------- .../com/b1nd/dodam/setting/SettingScreen.kt | 33 ++++++++++-------- .../b1nd/dodam/setting/SettingViewModel.kt | 4 +-- .../dodam/setting/model/SettingUiState.kt | 2 +- .../setting/navigation/SettingNavigation.kt | 9 +++-- .../b1nd/dodam/member/api/MemberService.kt | 15 +++----- .../member/datasource/MemberDataSource.kt | 3 -- .../member/model/EditMemberInfoRequest.kt | 2 +- ...atasourceModule.kt => DataSourceModule.kt} | 0 .../dodam/network/upload/api/UploadService.kt | 9 +++-- .../upload/datasource/UploadDataSource.kt | 5 +-- ...atasourceModule.kt => DataSourceModule.kt} | 0 .../network/upload/model/UploadResponse.kt | 2 +- 29 files changed, 94 insertions(+), 134 deletions(-) rename network/schedule/src/commonMain/kotlin/com/b1nd/dodam/network/schedule/di/{DatasourceModule.kt => DataSourceModule.kt} (100%) rename network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/{scheduleDatasourceModule.kt => DataSourceModule.kt} (100%) diff --git a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt index f2206661..6e9cc583 100644 --- a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt +++ b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/MemberRepository.kt @@ -2,7 +2,6 @@ package com.b1nd.dodam.member import com.b1nd.dodam.common.result.Result import com.b1nd.dodam.member.model.MemberInfo -import com.b1nd.dodam.network.core.model.DefaultResponse import kotlinx.collections.immutable.ImmutableList import kotlinx.coroutines.flow.Flow diff --git a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt index b349e342..ae30f6a7 100644 --- a/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt +++ b/data/member/src/commonMain/kotlin/com/b1nd/dodam/member/repository/MemberRepositoryImpl.kt @@ -9,7 +9,6 @@ import com.b1nd.dodam.member.datasource.MemberDataSource import com.b1nd.dodam.member.model.ActiveStatus import com.b1nd.dodam.member.model.MemberInfo import com.b1nd.dodam.member.model.toModel -import com.b1nd.dodam.network.core.model.DefaultResponse import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineDispatcher @@ -45,13 +44,8 @@ internal class MemberRepositoryImpl( .flowOn(dispatcher) } - override suspend fun editMemberInfo( - name: String, - email: String, - phone: String, - profileImage: String? - ): Flow> { - return flow{ + override suspend fun editMemberInfo(name: String, email: String, phone: String, profileImage: String?): Flow> { + return flow { emit(network.editMemberInfo(name, email, phone, profileImage)) } .asResult() diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt index 44fb4897..c28b252a 100644 --- a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/UploadRepository.kt @@ -7,4 +7,4 @@ import kotlinx.coroutines.flow.Flow interface UploadRepository { suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): Flow> -} \ No newline at end of file +} diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt index 5fb3b89d..dbf356a0 100644 --- a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/di/RepositoryModule.kt @@ -6,7 +6,6 @@ import com.b1nd.dodam.data.upload.repository.UploadRepositoryImpl import org.koin.core.qualifier.named import org.koin.dsl.module - val uploadRepositoryModule = module { single { UploadRepositoryImpl( @@ -14,4 +13,4 @@ val uploadRepositoryModule = module { dispatcher = get(named(DispatcherType.IO)), ) } -} \ No newline at end of file +} diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt index 7cb76dbe..ffac0ef7 100644 --- a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/model/UploadModel.kt @@ -1,12 +1,9 @@ package com.b1nd.dodam.data.upload.model -import com.b1nd.dodam.network.core.model.Response -import com.b1nd.dodam.network.upload.model.UploadResponse - data class UploadModel( - val profileImage: String + val profileImage: String, ) fun String.toModel() = UploadModel( - profileImage = this -) \ No newline at end of file + profileImage = this, +) diff --git a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt index 42446c35..77aeede3 100644 --- a/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt +++ b/data/upload/src/commonMain/kotlin/com/b1nd/dodam/data/upload/repository/UploadRepositoryImpl.kt @@ -1,6 +1,5 @@ package com.b1nd.dodam.data.upload.repository -import androidx.compose.ui.input.nestedscroll.NestedScrollSource import com.b1nd.dodam.common.Dispatcher import com.b1nd.dodam.common.DispatcherType import com.b1nd.dodam.common.result.Result @@ -9,7 +8,6 @@ import com.b1nd.dodam.data.upload.UploadRepository import com.b1nd.dodam.data.upload.model.UploadModel import com.b1nd.dodam.data.upload.model.toModel import com.b1nd.dodam.network.upload.datasource.UploadDataSource -import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow @@ -17,21 +15,19 @@ import kotlinx.coroutines.flow.flowOn class UploadRepositoryImpl( private val network: UploadDataSource, - @Dispatcher(DispatcherType.IO) private val dispatcher: CoroutineDispatcher -): UploadRepository { + @Dispatcher(DispatcherType.IO) private val dispatcher: CoroutineDispatcher, +) : UploadRepository { override suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): Flow> { return flow { emit( network.upload( fileName = fileName, fileMimeType = fileMimeType, - byteArray = byteArray - ).toModel() + byteArray = byteArray, + ).toModel(), ) } .asResult() .flowOn(dispatcher) - } - -} \ No newline at end of file +} diff --git a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt index 22ab20db..535dc640 100644 --- a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt +++ b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/DodamApp.kt @@ -243,9 +243,9 @@ fun DodamApp( profileImage = profileImage, name = name, email = email, - phone = phone + phone = phone, ) - } + }, ) askWakeupSongScreen( popBackStack = navController::popBackStack, @@ -257,8 +257,8 @@ fun DodamApp( pointScreen( popBackStack = navController::popBackStack, ) - editMemberInfoScreen ( - popBackStack = navController::popBackStack + editMemberInfoScreen( + popBackStack = navController::popBackStack, ) } } diff --git a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt index f8e1759e..4e8202ba 100644 --- a/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt +++ b/dodam-student/src/main/kotlin/com/b1nd/dodam/student/util/DodamApplication.kt @@ -101,7 +101,7 @@ class DodamApplication : Application() { bundleIdInfoDataSourceModule, editMemberInfoViewModelModule, uploadDatasourceModule, - uploadRepositoryModule + uploadRepositoryModule, ) + mainViewModelModules, ) } diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt index 5373c04b..1d3cab3e 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt @@ -258,18 +258,18 @@ fun DodamTeacherApp(exit: () -> Unit, viewModel: DodamTeacherAppViewModel = koin popBackStack = navHostController::popBackStack, logout = exit, versionInfo = getPlatformName(), - navigationToEditMemberInfo = {profileImage, name, email, phone -> + navigationToEditMemberInfo = { profileImage, name, email, phone -> navHostController.navigationToEditMemberInfo( profileImage = profileImage, name = name, email = email, - phone = phone + phone = phone, ) - } + }, ) editMemberInfoScreen( - popBackStack = navHostController::popBackStack + popBackStack = navHostController::popBackStack, ) } diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt index 727c3548..0d096514 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/Koin.kt @@ -83,7 +83,7 @@ fun initKoin(block: KoinApplication.() -> Unit = {}) { bundleIdInfoDataSourceModule, editMemberInfoViewModelModule, uploadDatasourceModule, - uploadRepositoryModule + uploadRepositoryModule, ) block() } diff --git a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt index 59c7141f..6322ae52 100644 --- a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt +++ b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt @@ -29,12 +29,10 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage import com.b1nd.dodam.dds.animation.bounceClick import com.b1nd.dodam.dds.component.DodamTopAppBar import com.b1nd.dodam.dds.component.button.DodamIconButton @@ -53,7 +51,6 @@ import com.b1nd.dodam.ui.icons.ColoredMegaphone import com.b1nd.dodam.ui.icons.ColoredMusicalNote import com.b1nd.dodam.ui.icons.ColoredPencil import com.b1nd.dodam.ui.icons.ColoredTent -import com.b1nd.dodam.ui.icons.DefaultProfile import org.koin.androidx.compose.koinViewModel @OptIn(ExperimentalMaterial3Api::class) @@ -146,16 +143,16 @@ fun AllScreen( DodamAvatar( avatarSize = AvatarSize.ExtraLarge, contentDescription = "프로필 이미지", - model = myInfo.profileImage , + model = myInfo.profileImage, modifier = Modifier .`if`(myInfo.profileImage.isNullOrEmpty()) { border( width = 1.dp, color = borderColor, - shape = CircleShape + shape = CircleShape, ) }, - contentScale = ContentScale.Crop + contentScale = ContentScale.Crop, ) } Spacer(modifier = Modifier.width(16.dp)) diff --git a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt index a39f827e..a7d14d40 100644 --- a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt +++ b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllViewModel.kt @@ -18,7 +18,7 @@ class AllViewModel : ViewModel(), KoinComponent { private val _uiState = MutableStateFlow(AllUiState()) val uiState = _uiState.asStateFlow() - fun getMyInfo(){ + fun getMyInfo() { viewModelScope.launch { memberRepository.getMyInfo().collect { result -> _uiState.update { uiState -> diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index cea649ba..7a449e36 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Scaffold -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -38,7 +37,6 @@ import com.b1nd.dodam.designsystem.component.DodamTextField import com.b1nd.dodam.designsystem.component.DodamTopAppBar import com.b1nd.dodam.editmemberinfo.model.EditMemberInfoSideEffect import com.b1nd.dodam.editmemberinfo.viewmodel.EditMemberInfoViewModel -import com.b1nd.dodam.ui.component.SnackbarState import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.icons.Plus import com.b1nd.dodam.ui.util.addFocusCleaner @@ -59,9 +57,8 @@ internal fun EditMemberInfoScreen( popBackStack: () -> Unit, name: String, email: String, - phone: String + phone: String, ) { - var name by remember { mutableStateOf(name) } var email by remember { mutableStateOf(email) } var phone by remember { mutableStateOf(phone) } @@ -72,7 +69,6 @@ internal fun EditMemberInfoScreen( val scope = rememberCoroutineScope() val context = LocalPlatformContext.current - var byteArray by remember { mutableStateOf(ByteArray(0)) } var platformSpecificFilePath by remember { mutableStateOf("") } @@ -88,20 +84,20 @@ internal fun EditMemberInfoScreen( viewModel.fileUpload( fileByteArray = byteArray, fileMimeType = file.getPath(context) ?: "", - fileName = file.getName(context) ?: "" + fileName = file.getName(context) ?: "", ) } } - } + }, ) LaunchedEffect(true) { platformSpecificFilePath = profileImage viewModel.setProfile( - if (profileImage == "default") null else profileImage + if (profileImage == "default") null else profileImage, ) - viewModel.sideEffect.collect{ - when(it){ + viewModel.sideEffect.collect { + when (it) { EditMemberInfoSideEffect.SuccessEditMemberInfo -> { popBackStack() } @@ -117,7 +113,7 @@ internal fun EditMemberInfoScreen( title = "정보수정", onBackClick = popBackStack, ) - } + }, ) { Box( modifier = Modifier @@ -125,11 +121,11 @@ internal fun EditMemberInfoScreen( .background(DodamTheme.colors.backgroundNeutral) .padding(it) .padding(horizontal = 16.dp) - .padding(vertical = 12.dp) + .padding(vertical = 12.dp), ) { Column( modifier = Modifier.fillMaxWidth(), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { val borderColor = DodamTheme.colors.lineAlternative Box { @@ -142,10 +138,10 @@ internal fun EditMemberInfoScreen( border( width = 1.dp, color = borderColor, - shape = CircleShape + shape = CircleShape, ) }, - contentScale = ContentScale.Crop + contentScale = ContentScale.Crop, ) Image( imageVector = Plus, @@ -155,13 +151,13 @@ internal fun EditMemberInfoScreen( .align(Alignment.BottomEnd) .clickable { pickerLauncher.launch() - } + }, ) } Column( modifier = Modifier .fillMaxWidth() - .padding(top = 24.dp) + .padding(top = 24.dp), ) { DodamTextField( value = name, @@ -206,7 +202,7 @@ internal fun EditMemberInfoScreen( email = email, name = name, phone = phone, - profileImage = uiState.image + profileImage = uiState.image, ) }, text = "수정 완료", @@ -216,4 +212,4 @@ internal fun EditMemberInfoScreen( ) } } -} \ No newline at end of file +} diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt index 14e2834b..6fe29972 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/EditMemberInfoSideEffect.kt @@ -1,6 +1,5 @@ package com.b1nd.dodam.editmemberinfo.model - sealed interface EditMemberInfoSideEffect { data object SuccessEditMemberInfo : EditMemberInfoSideEffect -} \ No newline at end of file +} diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt index 1db5277b..acae4ad3 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt @@ -4,5 +4,5 @@ data class ProfileModel( val name: String = "", val email: String = "", val phone: String = "", - val image: String? = null + val image: String? = null, ) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt index f76479b4..cbc2804c 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt @@ -9,13 +9,9 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.b1nd.dodam.editmemberinfo.EditMemberInfoScreen -import io.ktor.http.encodeURLPath import io.ktor.util.decodeBase64String import io.ktor.util.encodeBase64 import io.ktor.utils.io.core.toByteArray -import kotlinx.io.bytestring.encodeToByteString -import kotlin.io.encoding.Base64 -import kotlin.io.encoding.ExperimentalEncodingApi const val EDIT_MEMBER_INFO_ROUTE = "login" @@ -57,7 +53,7 @@ fun NavGraphBuilder.editMemberInfoScreen(popBackStack: () -> Unit) { popBackStack = popBackStack, name = name, email = email, - phone = phone + phone = phone, ) } -} \ No newline at end of file +} diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt index fbeae244..f62aab19 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt @@ -26,28 +26,21 @@ class EditMemberInfoViewModel : ViewModel(), KoinComponent { private val _sideEffect = MutableSharedFlow() val sideEffect = _sideEffect.asSharedFlow() - fun setProfile( - profileImage: String? - ) { + fun setProfile(profileImage: String?) { viewModelScope.launch { _uiState.value = _uiState.value.copy( - image = profileImage + image = profileImage, ) } } - fun editMember( - email: String, - name: String, - phone: String, - profileImage: String? - ) { + fun editMember(email: String, name: String, phone: String, profileImage: String?) { viewModelScope.launch { memberRepository.editMemberInfo( name = name, email = email, phone = phone, - profileImage = profileImage + profileImage = profileImage, ).collect { when (it) { is Result.Success -> { @@ -65,16 +58,12 @@ class EditMemberInfoViewModel : ViewModel(), KoinComponent { } } - fun fileUpload( - fileByteArray: ByteArray, - fileMimeType: String, - fileName: String - ) { + fun fileUpload(fileByteArray: ByteArray, fileMimeType: String, fileName: String) { viewModelScope.launch { uploadRepository.upload( fileName = fileName, fileMimeType = fileMimeType, - byteArray = fileByteArray + byteArray = fileByteArray, ).collect { when (it) { is Result.Error -> { @@ -85,7 +74,7 @@ class EditMemberInfoViewModel : ViewModel(), KoinComponent { _uiState.update { ui -> println(it.data) ui.copy( - image = it.data.profileImage + image = it.data.profileImage, ) } } @@ -95,4 +84,4 @@ class EditMemberInfoViewModel : ViewModel(), KoinComponent { } } } -} \ No newline at end of file +} diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index 08ef3b5f..b5bf89e5 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -31,7 +31,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale @@ -39,7 +38,6 @@ import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog -import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme import com.b1nd.dodam.designsystem.animation.rememberBounceIndication import com.b1nd.dodam.designsystem.component.AvatarSize @@ -53,14 +51,19 @@ import com.b1nd.dodam.designsystem.component.DodamTopAppBar import com.b1nd.dodam.designsystem.foundation.DodamIcons import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.effect.shimmerEffect -import com.b1nd.dodam.ui.icons.DefaultProfile import org.koin.compose.viewmodel.koinViewModel import org.koin.core.annotation.KoinExperimentalAPI @OptIn(KoinExperimentalAPI::class) @ExperimentalMaterial3Api @Composable -internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versionInfo: String = "3.2.0", popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?, name: String, email: String, phone: String) -> Unit) { +internal fun SettingScreen( + viewModel: SettingViewModel = koinViewModel(), + versionInfo: String = "3.2.0", + popBackStack: () -> Unit, + logout: () -> Unit, + navigationToEditMemberInfo: (profileImage: String?, name: String, email: String, phone: String) -> Unit, +) { val uiState by viewModel.uiState.collectAsState() var showLogoutDialog by remember { mutableStateOf(false) } @@ -72,7 +75,7 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio var count by remember { mutableIntStateOf(0) } - LaunchedEffect(key1 = true){ + LaunchedEffect(key1 = true) { viewModel.getMyInfo() } @@ -174,12 +177,14 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio .clickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberBounceIndication(), - onClick = { navigationToEditMemberInfo( - uiState.profile, - uiState.name, - uiState.email, - uiState.phone - ) } , + onClick = { + navigationToEditMemberInfo( + uiState.profile, + uiState.name, + uiState.email, + uiState.phone, + ) + }, ), ) { if (uiState.isLoading) { @@ -225,16 +230,16 @@ internal fun SettingScreen(viewModel: SettingViewModel = koinViewModel(), versio DodamAvatar( avatarSize = AvatarSize.ExtraLarge, contentDescription = "프로필 이미지", - model = uiState.profile , + model = uiState.profile, modifier = Modifier .`if`(uiState.profile.isNullOrEmpty()) { border( width = 1.dp, color = borderColor, - shape = CircleShape + shape = CircleShape, ) }, - contentScale = ContentScale.Crop + contentScale = ContentScale.Crop, ) Column { diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt index c19fa6be..c02e635f 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingViewModel.kt @@ -21,7 +21,7 @@ class SettingViewModel : ViewModel(), KoinComponent { private val _uiState = MutableStateFlow(SettingUiState()) val uiState = _uiState.asStateFlow() - fun getMyInfo(){ + fun getMyInfo() { viewModelScope.launch { memberRepository.getMyInfo().collect { result -> when (result) { @@ -32,7 +32,7 @@ class SettingViewModel : ViewModel(), KoinComponent { name = result.data.name, profile = result.data.profileImage, email = result.data.email, - phone = result.data.phone + phone = result.data.phone, ) } } diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt index fac85e4e..c21eef83 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/model/SettingUiState.kt @@ -5,5 +5,5 @@ data class SettingUiState( val profile: String? = null, val name: String = "", val email: String = "", - val phone: String = "" + val phone: String = "", ) diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt index 27872eb5..7ae59a71 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/navigation/SettingNavigation.kt @@ -18,7 +18,12 @@ fun NavController.navigateToSetting( ) = navigate(SETTING_ROUTE, navOptions) @ExperimentalMaterial3Api -fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, logout: () -> Unit, navigationToEditMemberInfo: (profileImage: String?, name: String, email: String, phone: String) -> Unit) { +fun NavGraphBuilder.settingScreen( + versionInfo: String, + popBackStack: () -> Unit, + logout: () -> Unit, + navigationToEditMemberInfo: (profileImage: String?, name: String, email: String, phone: String) -> Unit, +) { composable( route = SETTING_ROUTE, enterTransition = { slideIntoContainer(AnimatedContentTransitionScope.SlideDirection.Up) }, @@ -30,7 +35,7 @@ fun NavGraphBuilder.settingScreen(versionInfo: String, popBackStack: () -> Unit, versionInfo = versionInfo, popBackStack = popBackStack, logout = logout, - navigationToEditMemberInfo = navigationToEditMemberInfo + navigationToEditMemberInfo = navigationToEditMemberInfo, ) } } diff --git a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt index d5252ab5..a0643567 100644 --- a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt +++ b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/api/MemberService.kt @@ -40,21 +40,16 @@ internal class MemberService( } } - override suspend fun editMemberInfo( - name: String, - email: String, - phone: String, - profileImage: String? - ) { + override suspend fun editMemberInfo(name: String, email: String, phone: String, profileImage: String?) { return defaultSafeRequest { - client.patch(DodamUrl.Member.EDIT){ + client.patch(DodamUrl.Member.EDIT) { setBody( EditMemberInfoRequest( name = name, - email = email, + email = email, phone = phone, - profileImage = profileImage - ) + profileImage = profileImage, + ), ) }.body() } diff --git a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt index c6a7b980..013424ad 100644 --- a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt +++ b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/datasource/MemberDataSource.kt @@ -1,9 +1,6 @@ package com.b1nd.dodam.member.datasource -import com.b1nd.dodam.common.result.Result import com.b1nd.dodam.member.model.MemberInfoResponse -import com.b1nd.dodam.network.core.model.DefaultResponse -import kotlinx.coroutines.flow.Flow interface MemberDataSource { suspend fun getMyInfo(): MemberInfoResponse diff --git a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt index 0e52f40c..aca44114 100644 --- a/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt +++ b/network/member/src/commonMain/kotlin/com/b1nd/dodam/member/model/EditMemberInfoRequest.kt @@ -7,5 +7,5 @@ data class EditMemberInfoRequest( val email: String, val name: String, val phone: String, - val profileImage: String? + val profileImage: String?, ) diff --git a/network/schedule/src/commonMain/kotlin/com/b1nd/dodam/network/schedule/di/DatasourceModule.kt b/network/schedule/src/commonMain/kotlin/com/b1nd/dodam/network/schedule/di/DataSourceModule.kt similarity index 100% rename from network/schedule/src/commonMain/kotlin/com/b1nd/dodam/network/schedule/di/DatasourceModule.kt rename to network/schedule/src/commonMain/kotlin/com/b1nd/dodam/network/schedule/di/DataSourceModule.kt diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt index ebc364fd..8d2c3695 100644 --- a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt +++ b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/api/UploadService.kt @@ -4,7 +4,6 @@ import com.b1nd.dodam.network.core.DodamUrl import com.b1nd.dodam.network.core.model.Response import com.b1nd.dodam.network.core.util.safeRequest import com.b1nd.dodam.network.upload.datasource.UploadDataSource -import com.b1nd.dodam.network.upload.model.UploadResponse import io.ktor.client.HttpClient import io.ktor.client.call.body import io.ktor.client.plugins.onUpload @@ -16,11 +15,11 @@ import io.ktor.http.Headers import io.ktor.http.HttpHeaders class UploadService( - private val client: HttpClient -): UploadDataSource { + private val client: HttpClient, +) : UploadDataSource { override suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): String { return safeRequest { - client.post(DodamUrl.UPLOAD){ + client.post(DodamUrl.UPLOAD) { setBody( MultiPartFormDataContent( formData { @@ -41,4 +40,4 @@ class UploadService( }.body>() } } -} \ No newline at end of file +} diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt index 0b86ba73..798b1406 100644 --- a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt +++ b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/datasource/UploadDataSource.kt @@ -1,9 +1,6 @@ package com.b1nd.dodam.network.upload.datasource -import com.b1nd.dodam.network.core.model.Response -import com.b1nd.dodam.network.upload.model.UploadResponse - interface UploadDataSource { suspend fun upload(fileName: String, fileMimeType: String, byteArray: ByteArray): String -} \ No newline at end of file +} diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/scheduleDatasourceModule.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/DataSourceModule.kt similarity index 100% rename from network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/scheduleDatasourceModule.kt rename to network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/di/DataSourceModule.kt diff --git a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt index 55d26201..94a652ca 100644 --- a/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt +++ b/network/upload/src/commonMain/kotlin/com/b1nd/dodam/network/upload/model/UploadResponse.kt @@ -6,5 +6,5 @@ import kotlinx.serialization.Serializable data class UploadResponse( val status: Int, val message: String, - val data: String + val data: String, ) From dbb0a3f8bb3df893616cba8082d6428d5a1ccff0 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Tue, 12 Nov 2024 10:13:52 +0900 Subject: [PATCH 12/23] fix: Image Navigation Bug --- %25%23ok%C3%A9k%C3%89%C8%A2 | 0 a%20test%20%26 | 0 feature/edit-member-info/build.gradle.kts | 1 + .../navigation/EditMemberInfoNavigation.kt | 14 +++++++++++--- .../kotlin/com/b1nd/dodam/setting/SettingScreen.kt | 2 +- settings.gradle.kts | 4 ++++ 6 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 %25%23ok%C3%A9k%C3%89%C8%A2 create mode 100644 a%20test%20%26 diff --git a/%25%23ok%C3%A9k%C3%89%C8%A2 b/%25%23ok%C3%A9k%C3%89%C8%A2 new file mode 100644 index 00000000..e69de29b diff --git a/a%20test%20%26 b/a%20test%20%26 new file mode 100644 index 00000000..e69de29b diff --git a/feature/edit-member-info/build.gradle.kts b/feature/edit-member-info/build.gradle.kts index efdfcee9..195e12bf 100644 --- a/feature/edit-member-info/build.gradle.kts +++ b/feature/edit-member-info/build.gradle.kts @@ -24,6 +24,7 @@ kotlin { implementation(projects.data.upload) implementation("com.mohamedrejeb.calf:calf-file-picker:0.5.5") implementation("com.mohamedrejeb.calf:calf-permissions:0.5.5") + implementation("net.thauvin.erik.urlencoder:urlencoder-lib:1.6.0") } } android { diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt index cbc2804c..299849bc 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt @@ -9,11 +9,15 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.b1nd.dodam.editmemberinfo.EditMemberInfoScreen +import io.ktor.http.URLBuilder +import io.ktor.http.Url +import io.ktor.http.encodeURLParameter import io.ktor.util.decodeBase64String import io.ktor.util.encodeBase64 import io.ktor.utils.io.core.toByteArray +import net.thauvin.erik.urlencoder.UrlEncoderUtil -const val EDIT_MEMBER_INFO_ROUTE = "login" +const val EDIT_MEMBER_INFO_ROUTE = "edit_member_info" fun NavController.navigationToEditMemberInfo( profileImage: String?, @@ -24,7 +28,11 @@ fun NavController.navigationToEditMemberInfo( launchSingleTop = true }, ) { - val image = (profileImage ?: "default").toByteArray().encodeBase64() + val image = if (profileImage.isNullOrEmpty()){ + "default" + }else{ + UrlEncoderUtil.encode(profileImage) + } navigate("$EDIT_MEMBER_INFO_ROUTE/$image/$name/$email/$phone", navOptions) } @@ -44,7 +52,7 @@ fun NavGraphBuilder.editMemberInfoScreen(popBackStack: () -> Unit) { popExitTransition = { slideOutOfContainer(AnimatedContentTransitionScope.SlideDirection.Down) }, ) { val encodedImage = it.arguments?.getString("image") ?: "default" - val profileImage = encodedImage.decodeBase64String() + val profileImage = UrlEncoderUtil.decode(encodedImage) val name = it.arguments?.getString("name") ?: "" val email = it.arguments?.getString("email") ?: "" val phone = it.arguments?.getString("phone") ?: "" diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index b5bf89e5..31f68860 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -230,7 +230,7 @@ internal fun SettingScreen( DodamAvatar( avatarSize = AvatarSize.ExtraLarge, contentDescription = "프로필 이미지", - model = uiState.profile, + model = if (uiState.profile.isNullOrEmpty()) null else uiState.profile, modifier = Modifier .`if`(uiState.profile.isNullOrEmpty()) { border( diff --git a/settings.gradle.kts b/settings.gradle.kts index 0d334aa4..9fb89904 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,6 +16,10 @@ dependencyResolutionManagement { maven("https://jitpack.io") maven("https://maven.pkg.jetbrains.space/kotlin/p/wasm/experimental") maven("https://s01.oss.sonatype.org/content/repositories/snapshots") + maven("https://oss.sonatype.org/content/repositories/snapshots") { + name = "SonatypeSnapshots" + mavenContent { snapshotsOnly() } + } } } From 5a509384ce9340b675be7bfd59aaa9cb27a84c76 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Tue, 12 Nov 2024 10:55:34 +0900 Subject: [PATCH 13/23] feat: Change Profile Image Shape --- .../kotlin/com/b1nd/dodam/all/AllScreen.kt | 39 ++++++++++--------- .../editmemberinfo/EditMemberInfoScreen.kt | 1 + 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt b/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt index 5b9199e0..83a74726 100644 --- a/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt +++ b/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt @@ -2,6 +2,7 @@ package com.b1nd.dodam.all import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement @@ -16,6 +17,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -34,10 +36,13 @@ import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme import com.b1nd.dodam.designsystem.animation.rememberBounceIndication import com.b1nd.dodam.designsystem.component.ActionIcon +import com.b1nd.dodam.designsystem.component.AvatarSize import com.b1nd.dodam.designsystem.component.DividerType +import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamDefaultTopAppBar import com.b1nd.dodam.designsystem.component.DodamDivider import com.b1nd.dodam.designsystem.foundation.DodamIcons +import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.effect.shimmerEffect import com.b1nd.dodam.ui.icons.ColoredPencil import com.b1nd.dodam.ui.icons.ColoredTrophy @@ -117,25 +122,21 @@ internal fun AllScreen( ), ) } else { - if (uiState.memberInfo.profileImage == null || uiState.memberInfo.profileImage == "") { - Image( - bitmap = DefaultProfile, - contentDescription = "profile", - modifier = Modifier - .size(70.dp) - .clip(DodamTheme.shapes.medium), - contentScale = ContentScale.Crop, - ) - } else { - AsyncImage( - modifier = Modifier - .size(70.dp) - .clip(DodamTheme.shapes.medium), - model = uiState.memberInfo.profileImage, - contentDescription = "profile", - contentScale = ContentScale.Crop, - ) - } + val borderColor = DodamTheme.colors.lineAlternative + DodamAvatar( + avatarSize = AvatarSize.ExtraLarge, + contentDescription = "프로필 이미지", + model = uiState.memberInfo.profileImage, + modifier = Modifier + .`if`(uiState.memberInfo.profileImage.isNullOrEmpty()) { + border( + width = 1.dp, + color = borderColor, + shape = CircleShape, + ) + }, + contentScale = ContentScale.Crop, + ) Spacer(modifier = Modifier.width(16.dp)) Text( text = "환영합니다, " + uiState.memberInfo.name + "님", diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 7a449e36..7cdfecb8 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -81,6 +81,7 @@ internal fun EditMemberInfoScreen( byteArray = file.readByteArray(context) platformSpecificFilePath = file.getPath(context) ?: "" file.getName(context) + viewModel.setProfile(profileImage) viewModel.fileUpload( fileByteArray = byteArray, fileMimeType = file.getPath(context) ?: "", From cbe122cb539434bd3b8451936dbd007613016ee8 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Tue, 12 Nov 2024 12:27:46 +0900 Subject: [PATCH 14/23] feat: Use File Name, Type --- .../com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 7cdfecb8..ccb41a41 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -43,6 +43,7 @@ import com.b1nd.dodam.ui.util.addFocusCleaner import com.mohamedrejeb.calf.core.LocalPlatformContext import com.mohamedrejeb.calf.io.getName import com.mohamedrejeb.calf.io.getPath +import com.mohamedrejeb.calf.io.isFile import com.mohamedrejeb.calf.io.readByteArray import com.mohamedrejeb.calf.picker.FilePickerFileType import com.mohamedrejeb.calf.picker.FilePickerSelectionMode @@ -71,6 +72,7 @@ internal fun EditMemberInfoScreen( var byteArray by remember { mutableStateOf(ByteArray(0)) } var platformSpecificFilePath by remember { mutableStateOf("") } + var fileName by remember { mutableStateOf("") } val pickerLauncher = rememberFilePickerLauncher( type = FilePickerFileType.Image, @@ -80,12 +82,12 @@ internal fun EditMemberInfoScreen( files.firstOrNull()?.let { file -> byteArray = file.readByteArray(context) platformSpecificFilePath = file.getPath(context) ?: "" - file.getName(context) + fileName = file.getName(context)?:"" viewModel.setProfile(profileImage) viewModel.fileUpload( fileByteArray = byteArray, - fileMimeType = file.getPath(context) ?: "", - fileName = file.getName(context) ?: "", + fileMimeType = fileName.split(".")[1], + fileName = fileName.split(".")[0], ) } } From 0144421abb380a662f84d4f41bcd5e59092604e1 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Tue, 12 Nov 2024 12:42:04 +0900 Subject: [PATCH 15/23] feat: Add Navigation Enabled --- .../commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index 31f68860..e82462f6 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -175,6 +175,7 @@ internal fun SettingScreen( .padding(bottom = 8.dp) .fillMaxWidth() .clickable( + enabled = uiState.name.isNotEmpty(), interactionSource = remember { MutableInteractionSource() }, indication = rememberBounceIndication(), onClick = { From 063a883485c7adbedc6fd4d088b20d26fa83edb4 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Tue, 12 Nov 2024 14:06:54 +0900 Subject: [PATCH 16/23] Fix: Profile Border --- .../com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index ccb41a41..1fc52972 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -135,9 +135,9 @@ internal fun EditMemberInfoScreen( DodamAvatar( avatarSize = AvatarSize.XXL, contentDescription = "프로필 이미지", - model = if (uiState.image == "default") null else uiState.image, + model = uiState.image, modifier = Modifier - .`if`(platformSpecificFilePath == "default") { + .`if`(uiState.image.isNullOrEmpty()) { border( width = 1.dp, color = borderColor, From 2310f1f99afe87d190a67645f0104f120d5ffb07 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 20 Nov 2024 11:19:54 +0900 Subject: [PATCH 17/23] feat: Change Version Text --- .../commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt index 1d3cab3e..d8f5d2a9 100644 --- a/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt +++ b/dodam-teacher-android/src/commonMain/kotlin/com/b1nd/dodam/teacher/DodamTeacherApp.kt @@ -257,7 +257,7 @@ fun DodamTeacherApp(exit: () -> Unit, viewModel: DodamTeacherAppViewModel = koin settingScreen( popBackStack = navHostController::popBackStack, logout = exit, - versionInfo = getPlatformName(), + versionInfo = VERSION_INFO, navigationToEditMemberInfo = { profileImage, name, email, phone -> navHostController.navigationToEditMemberInfo( profileImage = profileImage, From cd272daf5dcf28ca552f1b653ef0b670fe3d1878 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 20 Nov 2024 11:21:14 +0900 Subject: [PATCH 18/23] style: Apply Spotless Format --- .../commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt | 3 --- .../b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt | 3 +-- .../navigation/EditMemberInfoNavigation.kt | 10 ++-------- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt b/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt index 83a74726..9b2446a2 100644 --- a/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt +++ b/feature-teacher/all/src/commonMain/kotlin/com/b1nd/dodam/all/AllScreen.kt @@ -27,12 +27,10 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme import com.b1nd.dodam.designsystem.animation.rememberBounceIndication import com.b1nd.dodam.designsystem.component.ActionIcon @@ -46,7 +44,6 @@ import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.effect.shimmerEffect import com.b1nd.dodam.ui.icons.ColoredPencil import com.b1nd.dodam.ui.icons.ColoredTrophy -import com.b1nd.dodam.ui.icons.DefaultProfile import com.b1nd.dodam.ui.icons.Tent import kotlinx.collections.immutable.persistentListOf import org.koin.compose.viewmodel.koinViewModel diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 1fc52972..904592a8 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -43,7 +43,6 @@ import com.b1nd.dodam.ui.util.addFocusCleaner import com.mohamedrejeb.calf.core.LocalPlatformContext import com.mohamedrejeb.calf.io.getName import com.mohamedrejeb.calf.io.getPath -import com.mohamedrejeb.calf.io.isFile import com.mohamedrejeb.calf.io.readByteArray import com.mohamedrejeb.calf.picker.FilePickerFileType import com.mohamedrejeb.calf.picker.FilePickerSelectionMode @@ -82,7 +81,7 @@ internal fun EditMemberInfoScreen( files.firstOrNull()?.let { file -> byteArray = file.readByteArray(context) platformSpecificFilePath = file.getPath(context) ?: "" - fileName = file.getName(context)?:"" + fileName = file.getName(context) ?: "" viewModel.setProfile(profileImage) viewModel.fileUpload( fileByteArray = byteArray, diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt index 299849bc..4dbc5fb5 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/navigation/EditMemberInfoNavigation.kt @@ -9,12 +9,6 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navArgument import com.b1nd.dodam.editmemberinfo.EditMemberInfoScreen -import io.ktor.http.URLBuilder -import io.ktor.http.Url -import io.ktor.http.encodeURLParameter -import io.ktor.util.decodeBase64String -import io.ktor.util.encodeBase64 -import io.ktor.utils.io.core.toByteArray import net.thauvin.erik.urlencoder.UrlEncoderUtil const val EDIT_MEMBER_INFO_ROUTE = "edit_member_info" @@ -28,9 +22,9 @@ fun NavController.navigationToEditMemberInfo( launchSingleTop = true }, ) { - val image = if (profileImage.isNullOrEmpty()){ + val image = if (profileImage.isNullOrEmpty()) { "default" - }else{ + } else { UrlEncoderUtil.encode(profileImage) } navigate("$EDIT_MEMBER_INFO_ROUTE/$image/$name/$email/$phone", navOptions) From 897e3b521546f5c2d979708be80cdce19887d1ca Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 20 Nov 2024 11:37:25 +0900 Subject: [PATCH 19/23] fix: merge conflict --- .../src/main/java/com/b1nd/dodam/member/AllScreen.kt | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt index 4c183b6b..109851ff 100644 --- a/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt +++ b/feature-student/all/src/main/java/com/b1nd/dodam/member/AllScreen.kt @@ -2,6 +2,9 @@ package com.b1nd.dodam.member import androidx.compose.foundation.Image import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -27,27 +30,27 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import coil3.compose.AsyncImage import com.b1nd.dodam.designsystem.DodamTheme import com.b1nd.dodam.designsystem.animation.rememberBounceIndication import com.b1nd.dodam.designsystem.component.ActionIcon +import com.b1nd.dodam.designsystem.component.AvatarSize import com.b1nd.dodam.designsystem.component.DividerType +import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamDefaultTopAppBar import com.b1nd.dodam.designsystem.component.DodamDivider import com.b1nd.dodam.designsystem.foundation.DodamIcons +import com.b1nd.dodam.ui.component.modifier.`if` import com.b1nd.dodam.ui.effect.shimmerEffect import com.b1nd.dodam.ui.icons.BarChart import com.b1nd.dodam.ui.icons.ColoredBus import com.b1nd.dodam.ui.icons.ColoredMegaphone import com.b1nd.dodam.ui.icons.ColoredMusicalNote import com.b1nd.dodam.ui.icons.ColoredTent -import com.b1nd.dodam.ui.icons.DefaultProfile +import kotlinx.collections.immutable.persistentListOf import org.koin.androidx.compose.koinViewModel @OptIn(ExperimentalMaterial3Api::class) From b0f133ac08122ddf7c8679f1a0d1c69c7a1a7d83 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 20 Nov 2024 12:07:36 +0900 Subject: [PATCH 20/23] remove: Pandding Dialog --- .../com/b1nd/dodam/setting/SettingScreen.kt | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt index e82462f6..a39243e0 100644 --- a/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt +++ b/feature/setting/src/commonMain/kotlin/com/b1nd/dodam/setting/SettingScreen.kt @@ -45,7 +45,6 @@ import com.b1nd.dodam.designsystem.component.ButtonRole import com.b1nd.dodam.designsystem.component.DividerType import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamButtonDialog -import com.b1nd.dodam.designsystem.component.DodamDialog import com.b1nd.dodam.designsystem.component.DodamDivider import com.b1nd.dodam.designsystem.component.DodamTopAppBar import com.b1nd.dodam.designsystem.foundation.DodamIcons @@ -67,7 +66,6 @@ internal fun SettingScreen( val uiState by viewModel.uiState.collectAsState() var showLogoutDialog by remember { mutableStateOf(false) } - var showDialog by remember { mutableStateOf(false) } var showEasterEggDialog by remember { mutableStateOf(false) } var showDeactivationDialog by remember { mutableStateOf(false) } @@ -121,19 +119,6 @@ internal fun SettingScreen( } } - if (showDialog) { - Dialog( - onDismissRequest = { showDialog = false }, - ) { - DodamDialog( - confirmButton = { showDialog = false }, - text = "확인", - title = "아직 준비 중인 기능이에요!", - body = "정보를 수정하시려면 도담도담 웹사이트를 이용해 주세요.", - ) - } - } - if (showDeactivationDialog) { Dialog( onDismissRequest = { showDeactivationDialog = false }, From 3ad4421ae039c0d8590866d726db467dd905c1a7 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 20 Nov 2024 19:35:15 +0900 Subject: [PATCH 21/23] remove: Plus Icon --- .../editmemberinfo/EditMemberInfoScreen.kt | 30 +++++++++++++------ .../composeResources/drawable/ic_plus.xml | 12 -------- .../kotlin/com/b1nd/dodam/ui/icons/Icons.kt | 5 ---- 3 files changed, 21 insertions(+), 26 deletions(-) delete mode 100644 ui/src/commonMain/composeResources/drawable/ic_plus.xml diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 904592a8..d58bc8a8 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -25,6 +25,7 @@ import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.unit.dp @@ -35,10 +36,10 @@ import com.b1nd.dodam.designsystem.component.DodamAvatar import com.b1nd.dodam.designsystem.component.DodamButton import com.b1nd.dodam.designsystem.component.DodamTextField import com.b1nd.dodam.designsystem.component.DodamTopAppBar +import com.b1nd.dodam.designsystem.foundation.DodamIcons import com.b1nd.dodam.editmemberinfo.model.EditMemberInfoSideEffect import com.b1nd.dodam.editmemberinfo.viewmodel.EditMemberInfoViewModel import com.b1nd.dodam.ui.component.modifier.`if` -import com.b1nd.dodam.ui.icons.Plus import com.b1nd.dodam.ui.util.addFocusCleaner import com.mohamedrejeb.calf.core.LocalPlatformContext import com.mohamedrejeb.calf.io.getName @@ -145,16 +146,27 @@ internal fun EditMemberInfoScreen( }, contentScale = ContentScale.Crop, ) - Image( - imageVector = Plus, - contentDescription = "image", + Box( modifier = Modifier .size(32.dp) - .align(Alignment.BottomEnd) - .clickable { - pickerLauncher.launch() - }, - ) + .background( + color = DodamTheme.colors.primaryNormal, + shape = CircleShape, + ) + .align(Alignment.BottomEnd), + ) { + Image( + imageVector = DodamIcons.Plus.value, + contentDescription = "plus", + colorFilter = ColorFilter.tint(DodamTheme.colors.staticWhite), + modifier = Modifier + .size(16.dp) + .align(Alignment.Center) + .clickable { + pickerLauncher.launch() + }, + ) + } } Column( modifier = Modifier diff --git a/ui/src/commonMain/composeResources/drawable/ic_plus.xml b/ui/src/commonMain/composeResources/drawable/ic_plus.xml deleted file mode 100644 index 09e656d2..00000000 --- a/ui/src/commonMain/composeResources/drawable/ic_plus.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - diff --git a/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt b/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt index a3c5ab5d..2760b698 100644 --- a/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt +++ b/ui/src/commonMain/kotlin/com/b1nd/dodam/ui/icons/Icons.kt @@ -20,7 +20,6 @@ import dodamdodam_android.ui.generated.resources.ic_colored_xmark_circle import dodamdodam_android.ui.generated.resources.ic_default_profile import dodamdodam_android.ui.generated.resources.ic_default_user import dodamdodam_android.ui.generated.resources.ic_dodamlogo -import dodamdodam_android.ui.generated.resources.ic_plus import org.jetbrains.compose.resources.imageResource import org.jetbrains.compose.resources.vectorResource @@ -95,7 +94,3 @@ val ColoredXMarkCircle val ColoredCookedRice @Composable get() = vectorResource(Res.drawable.ic_colored_cookedrice) - -val Plus - @Composable - get() = vectorResource(Res.drawable.ic_plus) From df860cfcfbaafcab07f35ca7d91acc788685e1d5 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 20 Nov 2024 19:45:14 +0900 Subject: [PATCH 22/23] fix: Block Button Continuous Click --- .../dodam/editmemberinfo/EditMemberInfoScreen.kt | 14 ++++++++------ .../dodam/editmemberinfo/model/ProfileModel.kt | 1 + .../viewmodel/EditMemberInfoViewModel.kt | 7 +++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index d58bc8a8..0a1243e8 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -212,12 +212,14 @@ internal fun EditMemberInfoScreen( } DodamButton( onClick = { - viewModel.editMember( - email = email, - name = name, - phone = phone, - profileImage = uiState.image, - ) + if (!uiState.isLoading) { + viewModel.editMember( + email = email, + name = name, + phone = phone, + profileImage = uiState.image, + ) + } }, text = "수정 완료", modifier = Modifier diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt index acae4ad3..90b53800 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/model/ProfileModel.kt @@ -5,4 +5,5 @@ data class ProfileModel( val email: String = "", val phone: String = "", val image: String? = null, + val isLoading: Boolean = false, ) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt index f62aab19..dd571676 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/viewmodel/EditMemberInfoViewModel.kt @@ -45,14 +45,17 @@ class EditMemberInfoViewModel : ViewModel(), KoinComponent { when (it) { is Result.Success -> { _sideEffect.emit(EditMemberInfoSideEffect.SuccessEditMemberInfo) - println(it.data) + _uiState.value = _uiState.value.copy(isLoading = false) } is Result.Error -> { it.error.printStackTrace() + _uiState.value = _uiState.value.copy(isLoading = false) } - is Result.Loading -> {} + is Result.Loading -> { + _uiState.value = _uiState.value.copy(isLoading = true) + } } } } From 02197e0c70a0fc1ca4ba4713f681ee4d34209616 Mon Sep 17 00:00:00 2001 From: wnsgur1 Date: Wed, 20 Nov 2024 19:50:00 +0900 Subject: [PATCH 23/23] feat: Apply Clickable In Parent --- .../b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt index 0a1243e8..c1c47a17 100644 --- a/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt +++ b/feature/edit-member-info/src/commonMain/kotlin/com/b1nd/dodam/editmemberinfo/EditMemberInfoScreen.kt @@ -149,11 +149,14 @@ internal fun EditMemberInfoScreen( Box( modifier = Modifier .size(32.dp) + .align(Alignment.BottomEnd) .background( color = DodamTheme.colors.primaryNormal, shape = CircleShape, ) - .align(Alignment.BottomEnd), + .clickable { + pickerLauncher.launch() + }, ) { Image( imageVector = DodamIcons.Plus.value, @@ -161,10 +164,7 @@ internal fun EditMemberInfoScreen( colorFilter = ColorFilter.tint(DodamTheme.colors.staticWhite), modifier = Modifier .size(16.dp) - .align(Alignment.Center) - .clickable { - pickerLauncher.launch() - }, + .align(Alignment.Center), ) } }