From 7aa5f449edc8db7130b07fd9aa10502336197a06 Mon Sep 17 00:00:00 2001
From: 8954sood <8954sood@naver.com>
Date: Wed, 26 Jun 2024 23:31:27 +0900
Subject: [PATCH 1/7] feat: Create Profile Screen
---
.../src/main/res/drawable/ic_write_line.xml | 14 ++
feature-main/main/build.gradle.kts | 2 +-
.../com/apeun/gidaechi/main/MainScreen.kt | 6 +-
feature-main/profile/.gitignore | 1 +
feature-main/profile/build.gradle.kts | 13 ++
.../apeun/gidaechi/profile/ProfileScreen.kt | 183 ++++++++++++++++++
.../profile/navigation/ProfileNavigation.kt | 17 ++
settings.gradle.kts | 3 +
8 files changed, 237 insertions(+), 2 deletions(-)
create mode 100644 designsystem/src/main/res/drawable/ic_write_line.xml
create mode 100644 feature-main/profile/.gitignore
create mode 100644 feature-main/profile/build.gradle.kts
create mode 100644 feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
create mode 100644 feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt
diff --git a/designsystem/src/main/res/drawable/ic_write_line.xml b/designsystem/src/main/res/drawable/ic_write_line.xml
new file mode 100644
index 00000000..1265e75c
--- /dev/null
+++ b/designsystem/src/main/res/drawable/ic_write_line.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/feature-main/main/build.gradle.kts b/feature-main/main/build.gradle.kts
index 955d00cf..db48e52a 100644
--- a/feature-main/main/build.gradle.kts
+++ b/feature-main/main/build.gradle.kts
@@ -14,5 +14,5 @@ dependencies {
implementation(projects.featureMain.home)
implementation(projects.featureMain.room)
implementation(projects.featureMain.roomCreate)
-
+ implementation(projects.featureMain.profile)
}
\ No newline at end of file
diff --git a/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt b/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt
index f8784b58..b862d62c 100644
--- a/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt
+++ b/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt
@@ -26,6 +26,8 @@ import com.apeun.gidaechi.designsystem.component.BottomNavigationItemType
import com.apeun.gidaechi.designsystem.component.SeugiBottomNavigation
import com.apeun.gidaechi.home.navigation.HOME_ROUTE
import com.apeun.gidaechi.home.navigation.homeScreen
+import com.apeun.gidaechi.profile.navigation.PROFILE_ROUTE
+import com.apeun.gidaechi.profile.navigation.profileScreen
import com.apeun.gidaechi.room.navigation.ROOM_ROUTE
import com.apeun.gidaechi.room.navigation.roomScreen
import com.apeun.gidaechi.roomcreate.navigation.navigateToRoomCreate
@@ -54,7 +56,7 @@ internal fun MainScreen(navHostController: NavHostController = rememberNavContro
is BottomNavigationItemType.Chat -> CHAT_ROUTE
is BottomNavigationItemType.Group -> ROOM_ROUTE
is BottomNavigationItemType.Notification -> "route"
- is BottomNavigationItemType.Profile -> "route"
+ is BottomNavigationItemType.Profile -> PROFILE_ROUTE
else -> "route"
},
) {
@@ -130,6 +132,8 @@ internal fun MainScreen(navHostController: NavHostController = rememberNavContro
)
},
)
+
+ profileScreen()
}
}
}
diff --git a/feature-main/profile/.gitignore b/feature-main/profile/.gitignore
new file mode 100644
index 00000000..42afabfd
--- /dev/null
+++ b/feature-main/profile/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/feature-main/profile/build.gradle.kts b/feature-main/profile/build.gradle.kts
new file mode 100644
index 00000000..12dec288
--- /dev/null
+++ b/feature-main/profile/build.gradle.kts
@@ -0,0 +1,13 @@
+plugins {
+ alias(libs.plugins.seugi.android.feature)
+}
+
+android {
+ namespace = "com.apeun.gidaechi.profile"
+}
+
+dependencies {
+
+ implementation(projects.designsystem)
+ implementation(projects.common)
+}
\ No newline at end of file
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
new file mode 100644
index 00000000..70d461d2
--- /dev/null
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
@@ -0,0 +1,183 @@
+package com.apeun.gidaechi.profile
+
+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.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.width
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.ColorFilter
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.unit.dp
+import com.apeun.gidaechi.designsystem.R.drawable
+import com.apeun.gidaechi.designsystem.component.AvatarType
+import com.apeun.gidaechi.designsystem.component.DividerType
+import com.apeun.gidaechi.designsystem.component.SeugiAvatar
+import com.apeun.gidaechi.designsystem.component.SeugiDivider
+import com.apeun.gidaechi.designsystem.component.SeugiTopBar
+import com.apeun.gidaechi.designsystem.theme.Black
+import com.apeun.gidaechi.designsystem.theme.Gray500
+import com.apeun.gidaechi.designsystem.theme.White
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun ProfileScreen() {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .background(White)
+ ) {
+ SeugiTopBar(
+ title = {
+ Text(
+ text = "내 프로필",
+ style = MaterialTheme.typography.titleLarge,
+ color = Black
+ )
+ }
+ )
+ Row(
+ modifier = Modifier.fillMaxWidth(),
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Spacer(modifier = Modifier.width(16.dp))
+ SeugiAvatar(type = AvatarType.Medium)
+ Spacer(modifier = Modifier.width(10.dp))
+ Text(
+ text = "노영재",
+ style = MaterialTheme.typography.titleMedium,
+ color = Black
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ Image(
+ modifier = Modifier
+ .padding(vertical = 8.dp)
+ .size(32.dp),
+ painter = painterResource(id = drawable.ic_setting_fill),
+ contentDescription = "설정 톱니바퀴",
+ colorFilter = ColorFilter.tint(Gray500)
+ )
+ Spacer(modifier = Modifier.width(16.dp))
+ }
+ Spacer(modifier = Modifier.height(16.dp))
+ SeugiDivider(
+ size = 8.dp,
+ type = DividerType.WIDTH
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+ ProfileCard(
+ title = "상태메세지",
+ content = "대소고 어딘가",
+ onClickEdit = {}
+ )
+ Spacer(modifier = Modifier.height(8.dp))
+ SeugiDivider(
+ modifier = Modifier.padding(horizontal = 16.dp),
+ type = DividerType.WIDTH,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+ ProfileCard(
+ title = "직위",
+ content = "제갈 여친",
+ onClickEdit = {}
+ )
+ Spacer(modifier = Modifier.height(8.dp))
+ SeugiDivider(
+ modifier = Modifier.padding(horizontal = 16.dp),
+ type = DividerType.WIDTH,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+ ProfileCard(
+ title = "소속",
+ content = "대소고 어딘가",
+ onClickEdit = {}
+ )
+ Spacer(modifier = Modifier.height(8.dp))
+ SeugiDivider(
+ modifier = Modifier.padding(horizontal = 16.dp),
+ type = DividerType.WIDTH,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+ ProfileCard(
+ title = "휴대전화번호",
+ content = "010-1234-5678",
+ onClickEdit = {}
+ )
+ Spacer(modifier = Modifier.height(8.dp))
+ SeugiDivider(
+ modifier = Modifier.padding(horizontal = 16.dp),
+ type = DividerType.WIDTH,
+ )
+
+ Spacer(modifier = Modifier.height(8.dp))
+ ProfileCard(
+ title = "유선전화번호",
+ content = "02-1234-5678",
+ onClickEdit = {}
+ )
+ Spacer(modifier = Modifier.height(8.dp))
+ SeugiDivider(
+ modifier = Modifier.padding(horizontal = 16.dp),
+ type = DividerType.WIDTH,
+ )
+
+ }
+}
+
+@Composable
+internal fun ProfileCard(
+ title: String,
+ content: String,
+ onClickEdit: () -> Unit,
+) {
+ Column {
+ Row(
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Spacer(modifier = Modifier.width(20.dp))
+ Text(
+ text = title,
+ style = MaterialTheme.typography.bodyLarge,
+ color = Gray500
+ )
+ Spacer(modifier = Modifier.weight(1f))
+ Image(
+ modifier = Modifier.size(20.dp),
+ painter = painterResource(id = drawable.ic_write_line),
+ contentDescription = "수정하기 아이콘",
+ colorFilter = ColorFilter.tint(Gray500)
+ )
+ Spacer(modifier = Modifier.width(20.dp))
+ }
+ Box(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(56.dp),
+ ) {
+ Text(
+ modifier = Modifier
+ .align(Alignment.CenterStart)
+ .padding(start = 20.dp),
+ text = content,
+ style = MaterialTheme.typography.titleMedium,
+ color = Black
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt
new file mode 100644
index 00000000..dd4b683a
--- /dev/null
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt
@@ -0,0 +1,17 @@
+package com.apeun.gidaechi.profile.navigation
+
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import com.apeun.gidaechi.profile.ProfileScreen
+
+const val PROFILE_ROUTE = "profile"
+
+fun NavController.navigateToProfile(navOptions: NavOptions?) = navigate(PROFILE_ROUTE, navOptions)
+
+fun NavGraphBuilder.profileScreen() {
+ composable(PROFILE_ROUTE) {
+ ProfileScreen()
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 07778356..1fc6a7f3 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,5 +1,8 @@
import java.net.URI
+include(":feature-main:profile")
+
+
include(":data:group-chat")
From 023d38c734c148daf6753f8ce71094427e9b84f7 Mon Sep 17 00:00:00 2001
From: 8954sood <8954sood@naver.com>
Date: Thu, 27 Jun 2024 08:38:30 +0900
Subject: [PATCH 2/7] feat: Create Profile Bottom Sheet
---
.../apeun/gidaechi/profile/ProfileScreen.kt | 76 ++++++++++++++++++-
1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
index 70d461d2..f9d1fff4 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
@@ -9,31 +9,100 @@ 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.imePadding
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.safeGesturesPadding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
+import androidx.compose.material.rememberBottomSheetState
+import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.ModalBottomSheet
+import androidx.compose.material3.ModalBottomSheetProperties
import androidx.compose.material3.Text
+import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
+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.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.apeun.gidaechi.designsystem.R.drawable
+import com.apeun.gidaechi.designsystem.animation.bounceClick
import com.apeun.gidaechi.designsystem.component.AvatarType
+import com.apeun.gidaechi.designsystem.component.ButtonType
import com.apeun.gidaechi.designsystem.component.DividerType
import com.apeun.gidaechi.designsystem.component.SeugiAvatar
import com.apeun.gidaechi.designsystem.component.SeugiDivider
+import com.apeun.gidaechi.designsystem.component.SeugiFullWidthButton
import com.apeun.gidaechi.designsystem.component.SeugiTopBar
+import com.apeun.gidaechi.designsystem.component.textfield.SeugiTextField
import com.apeun.gidaechi.designsystem.theme.Black
import com.apeun.gidaechi.designsystem.theme.Gray500
import com.apeun.gidaechi.designsystem.theme.White
+import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
internal fun ProfileScreen() {
+ var isShowDialog by remember { mutableStateOf(false) }
+ val modalBottomSheetState = rememberModalBottomSheetState()
+ val coroutineScope = rememberCoroutineScope()
+
+ val dialogDismissRequest: () -> Unit = {
+ coroutineScope.launch {
+ isShowDialog = false
+ }
+ }
+
+ if (isShowDialog) {
+ ModalBottomSheet(
+ onDismissRequest = { dialogDismissRequest() },
+ sheetState = modalBottomSheetState,
+ dragHandle = { BottomSheetDefaults.DragHandle() },
+ containerColor = White,
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .background(White)
+ .safeGesturesPadding(),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ Column(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(
+ horizontal = 20.dp
+ )
+ ) {
+ Text(
+ text = "직위 수정",
+ style = MaterialTheme.typography.titleMedium,
+ color = Black
+ )
+ Spacer(modifier = Modifier.height(4.dp))
+ SeugiTextField(value = "qew", onValueChange = {}, onClickDelete = { /*TODO*/ })
+ }
+ Spacer(modifier = Modifier.height(32.dp))
+ SeugiFullWidthButton(
+ modifier = Modifier.padding(horizontal = 20.dp),
+ onClick = { dialogDismissRequest() },
+ type = ButtonType.Primary,
+ text = "저장"
+ )
+ Spacer(modifier = Modifier.imePadding())
+ }
+ }
+ }
+
Column(
modifier = Modifier
.fillMaxSize()
@@ -81,7 +150,9 @@ internal fun ProfileScreen() {
ProfileCard(
title = "상태메세지",
content = "대소고 어딘가",
- onClickEdit = {}
+ onClickEdit = {
+ isShowDialog = true
+ }
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -167,6 +238,9 @@ internal fun ProfileCard(
}
Box(
modifier = Modifier
+ .bounceClick(
+ onClick = onClickEdit
+ )
.fillMaxWidth()
.height(56.dp),
) {
From 514034d2d5c8338a055c50f4af8f8562a4069156 Mon Sep 17 00:00:00 2001
From: 8954sood <8954sood@naver.com>
Date: Thu, 27 Jun 2024 13:48:10 +0900
Subject: [PATCH 3/7] feat: Create Profile Remote Load
---
feature-main/profile/build.gradle.kts | 2 +
.../apeun/gidaechi/profile/ProfileScreen.kt | 39 ++++++++++++-----
.../gidaechi/profile/ProfileViewModel.kt | 42 +++++++++++++++++++
.../gidaechi/profile/model/ProfileUiState.kt | 18 ++++++++
4 files changed, 91 insertions(+), 10 deletions(-)
create mode 100644 feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
create mode 100644 feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt
diff --git a/feature-main/profile/build.gradle.kts b/feature-main/profile/build.gradle.kts
index 12dec288..0a9b669a 100644
--- a/feature-main/profile/build.gradle.kts
+++ b/feature-main/profile/build.gradle.kts
@@ -10,4 +10,6 @@ dependencies {
implementation(projects.designsystem)
implementation(projects.common)
+ implementation(projects.data.profile)
+ implementation(projects.data.core)
}
\ No newline at end of file
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
index f9d1fff4..3e3cc156 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
@@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeGesturesPadding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
-import androidx.compose.material.rememberBottomSheetState
import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
@@ -23,6 +22,7 @@ import androidx.compose.material3.ModalBottomSheetProperties
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
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
@@ -34,6 +34,8 @@ import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.apeun.gidaechi.designsystem.R.drawable
import com.apeun.gidaechi.designsystem.animation.bounceClick
import com.apeun.gidaechi.designsystem.component.AvatarType
@@ -51,8 +53,14 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-internal fun ProfileScreen() {
+internal fun ProfileScreen(
+ viewModel: ProfileViewModel = hiltViewModel(),
+) {
+ val state by viewModel.state.collectAsStateWithLifecycle()
+
var isShowDialog by remember { mutableStateOf(false) }
+ var editTextTarget by remember { mutableStateOf("") }
+ var editText by remember { mutableStateOf("") }
val modalBottomSheetState = rememberModalBottomSheetState()
val coroutineScope = rememberCoroutineScope()
@@ -62,6 +70,10 @@ internal fun ProfileScreen() {
}
}
+ LaunchedEffect(key1 = true) {
+ viewModel.load()
+ }
+
if (isShowDialog) {
ModalBottomSheet(
onDismissRequest = { dialogDismissRequest() },
@@ -84,12 +96,19 @@ internal fun ProfileScreen() {
)
) {
Text(
- text = "직위 수정",
+ text = "$editTextTarget 수정",
style = MaterialTheme.typography.titleMedium,
color = Black
)
Spacer(modifier = Modifier.height(4.dp))
- SeugiTextField(value = "qew", onValueChange = {}, onClickDelete = { /*TODO*/ })
+
+ SeugiTextField(
+ value = editText,
+ onValueChange = {
+ editText = it
+ },
+ onClickDelete = { /*TODO*/ }
+ )
}
Spacer(modifier = Modifier.height(32.dp))
SeugiFullWidthButton(
@@ -125,7 +144,7 @@ internal fun ProfileScreen() {
SeugiAvatar(type = AvatarType.Medium)
Spacer(modifier = Modifier.width(10.dp))
Text(
- text = "노영재",
+ text = state.profileInfo.member.name,
style = MaterialTheme.typography.titleMedium,
color = Black
)
@@ -149,7 +168,7 @@ internal fun ProfileScreen() {
Spacer(modifier = Modifier.height(8.dp))
ProfileCard(
title = "상태메세지",
- content = "대소고 어딘가",
+ content = state.profileInfo.status,
onClickEdit = {
isShowDialog = true
}
@@ -163,7 +182,7 @@ internal fun ProfileScreen() {
Spacer(modifier = Modifier.height(8.dp))
ProfileCard(
title = "직위",
- content = "제갈 여친",
+ content = state.profileInfo.spot,
onClickEdit = {}
)
Spacer(modifier = Modifier.height(8.dp))
@@ -175,7 +194,7 @@ internal fun ProfileScreen() {
Spacer(modifier = Modifier.height(8.dp))
ProfileCard(
title = "소속",
- content = "대소고 어딘가",
+ content = state.profileInfo.belong,
onClickEdit = {}
)
Spacer(modifier = Modifier.height(8.dp))
@@ -187,7 +206,7 @@ internal fun ProfileScreen() {
Spacer(modifier = Modifier.height(8.dp))
ProfileCard(
title = "휴대전화번호",
- content = "010-1234-5678",
+ content = state.profileInfo.phone,
onClickEdit = {}
)
Spacer(modifier = Modifier.height(8.dp))
@@ -199,7 +218,7 @@ internal fun ProfileScreen() {
Spacer(modifier = Modifier.height(8.dp))
ProfileCard(
title = "유선전화번호",
- content = "02-1234-5678",
+ content = state.profileInfo.wire,
onClickEdit = {}
)
Spacer(modifier = Modifier.height(8.dp))
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
new file mode 100644
index 00000000..1b7b28e9
--- /dev/null
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
@@ -0,0 +1,42 @@
+package com.apeun.gidaechi.profile
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import com.apeun.gidaechi.common.model.Result
+import com.apeun.gidaechi.data.profile.ProfileRepository
+import com.apeun.gidaechi.profile.model.ProfileUiState
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.update
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@HiltViewModel
+class ProfileViewModel @Inject constructor(
+ private val profileRepository: ProfileRepository
+): ViewModel() {
+
+ private val _state = MutableStateFlow(ProfileUiState())
+ val state = _state.asStateFlow()
+
+ fun load() = viewModelScope.launch {
+ profileRepository.getProfile("664bdd0b9dfce726abd30462").collect { result ->
+ when(result) {
+ is Result.Success -> {
+ _state.update {
+ it.copy(
+ profileInfo = result.data
+ )
+ }
+ }
+ is Result.Loading -> {
+
+ }
+ is Result.Error -> {
+ result.throwable.printStackTrace()
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt
new file mode 100644
index 00000000..f776534f
--- /dev/null
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt
@@ -0,0 +1,18 @@
+package com.apeun.gidaechi.profile.model
+
+import com.apeun.gidaechi.data.core.model.ProfileModel
+import com.apeun.gidaechi.data.core.model.UserModel
+
+data class ProfileUiState(
+ val profileInfo: ProfileModel = ProfileModel(
+ "",
+ UserModel(0, "", "", "", ""),
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ ""
+ )
+)
\ No newline at end of file
From e14faa20710e0e35711db10eb91f8d80430e08af Mon Sep 17 00:00:00 2001
From: 8954sood <8954sood@naver.com>
Date: Thu, 27 Jun 2024 14:08:51 +0900
Subject: [PATCH 4/7] feat: Create Profile Info Update Ui Logic
---
.../apeun/gidaechi/profile/ProfileScreen.kt | 45 ++++++++++++++++---
.../gidaechi/profile/ProfileViewModel.kt | 21 +++++++++
2 files changed, 59 insertions(+), 7 deletions(-)
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
index 3e3cc156..c69e79b0 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
@@ -96,7 +96,7 @@ internal fun ProfileScreen(
)
) {
Text(
- text = "$editTextTarget 수정",
+ text = "${getTargetTextToString(editTextTarget)} 수정",
style = MaterialTheme.typography.titleMedium,
color = Black
)
@@ -113,7 +113,15 @@ internal fun ProfileScreen(
Spacer(modifier = Modifier.height(32.dp))
SeugiFullWidthButton(
modifier = Modifier.padding(horizontal = 20.dp),
- onClick = { dialogDismissRequest() },
+ onClick = {
+ viewModel.updateState(
+ target = editTextTarget,
+ text = editText
+ )
+ editText = ""
+ editTextTarget = ""
+ dialogDismissRequest()
+ },
type = ButtonType.Primary,
text = "저장"
)
@@ -170,6 +178,7 @@ internal fun ProfileScreen(
title = "상태메세지",
content = state.profileInfo.status,
onClickEdit = {
+ editTextTarget = "status"
isShowDialog = true
}
)
@@ -183,7 +192,10 @@ internal fun ProfileScreen(
ProfileCard(
title = "직위",
content = state.profileInfo.spot,
- onClickEdit = {}
+ onClickEdit = {
+ editTextTarget = "spot"
+ isShowDialog = true
+ }
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -195,7 +207,10 @@ internal fun ProfileScreen(
ProfileCard(
title = "소속",
content = state.profileInfo.belong,
- onClickEdit = {}
+ onClickEdit = {
+ editTextTarget = "belong"
+ isShowDialog = true
+ }
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -207,7 +222,10 @@ internal fun ProfileScreen(
ProfileCard(
title = "휴대전화번호",
content = state.profileInfo.phone,
- onClickEdit = {}
+ onClickEdit = {
+ editTextTarget = "phone"
+ isShowDialog = true
+ }
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -219,7 +237,10 @@ internal fun ProfileScreen(
ProfileCard(
title = "유선전화번호",
content = state.profileInfo.wire,
- onClickEdit = {}
+ onClickEdit = {
+ editTextTarget = "wire"
+ isShowDialog = true
+ }
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -273,4 +294,14 @@ internal fun ProfileCard(
)
}
}
-}
\ No newline at end of file
+}
+
+private fun getTargetTextToString(text: String) =
+ when(text) {
+ "status" -> "상태메세지"
+ "spot" -> "직위"
+ "belong" -> "소속"
+ "phone" -> "휴대전화번호"
+ "wire" -> "유선전화번호"
+ else -> ""
+ }
\ No newline at end of file
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
index 1b7b28e9..c437206a 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
@@ -39,4 +39,25 @@ class ProfileViewModel @Inject constructor(
}
}
}
+
+ fun updateState(target: String, text: String) {
+ val info = _state.value.profileInfo
+ with(info) {
+ _state.update {
+ it.copy(
+ profileInfo = info.copy(
+ status = if (target == "status") text else status,
+ member = member,
+ workspaceId = workspaceId,
+ nick = if (target == "nick") text else nick,
+ spot = if (target == "spot") text else spot,
+ belong = if (target == "belong") text else belong,
+ phone = if (target == "phone") text else phone,
+ wire = if (target == "wire") text else wire,
+ location = location
+ )
+ )
+ }
+ }
+ }
}
\ No newline at end of file
From 1215022fea479f767d992d235a7f5f1c1e05296f Mon Sep 17 00:00:00 2001
From: 8954sood <8954sood@naver.com>
Date: Thu, 27 Jun 2024 15:08:42 +0900
Subject: [PATCH 5/7] feat: Create Profile Bottom Sheet Placeholder
---
.../apeun/gidaechi/profile/ProfileScreen.kt | 23 +++++++++++--------
1 file changed, 14 insertions(+), 9 deletions(-)
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
index c69e79b0..7d234aff 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
@@ -23,6 +23,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@@ -61,6 +62,7 @@ internal fun ProfileScreen(
var isShowDialog by remember { mutableStateOf(false) }
var editTextTarget by remember { mutableStateOf("") }
var editText by remember { mutableStateOf("") }
+ val editTextString by remember { derivedStateOf { getTargetTextToString(editTextTarget) } }
val modalBottomSheetState = rememberModalBottomSheetState()
val coroutineScope = rememberCoroutineScope()
@@ -96,7 +98,7 @@ internal fun ProfileScreen(
)
) {
Text(
- text = "${getTargetTextToString(editTextTarget)} 수정",
+ text = "${editTextString.first} 수정",
style = MaterialTheme.typography.titleMedium,
color = Black
)
@@ -107,7 +109,10 @@ internal fun ProfileScreen(
onValueChange = {
editText = it
},
- onClickDelete = { /*TODO*/ }
+ placeholder = "${editTextString.first}${editTextString.second} 입력해주세요",
+ onClickDelete = {
+ editText = ""
+ }
)
}
Spacer(modifier = Modifier.height(32.dp))
@@ -296,12 +301,12 @@ internal fun ProfileCard(
}
}
-private fun getTargetTextToString(text: String) =
+private fun getTargetTextToString(text: String): Pair =
when(text) {
- "status" -> "상태메세지"
- "spot" -> "직위"
- "belong" -> "소속"
- "phone" -> "휴대전화번호"
- "wire" -> "유선전화번호"
- else -> ""
+ "status" -> Pair("상태메세지", "를")
+ "spot" -> Pair("직위", "를")
+ "belong" -> Pair("소속", "을")
+ "phone" -> Pair("휴대전화번호", "를")
+ "wire" -> Pair("유선전화번호", "를")
+ else -> Pair("", "")
}
\ No newline at end of file
From 6337e86a1c56c1545aee7206cd545d68aba2b859 Mon Sep 17 00:00:00 2001
From: 8954sood <8954sood@naver.com>
Date: Thu, 27 Jun 2024 15:10:10 +0900
Subject: [PATCH 6/7] style: Apply Spotless Format
---
.../apeun/gidaechi/profile/ProfileScreen.kt | 78 ++++++++-----------
.../gidaechi/profile/ProfileViewModel.kt | 17 ++--
.../gidaechi/profile/model/ProfileUiState.kt | 6 +-
.../profile/navigation/ProfileNavigation.kt | 2 +-
4 files changed, 46 insertions(+), 57 deletions(-)
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
index 7d234aff..2ed0bf62 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileScreen.kt
@@ -18,7 +18,6 @@ import androidx.compose.material3.BottomSheetDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.ModalBottomSheet
-import androidx.compose.material3.ModalBottomSheetProperties
import androidx.compose.material3.Text
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
@@ -33,7 +32,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
-import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -54,9 +52,7 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-internal fun ProfileScreen(
- viewModel: ProfileViewModel = hiltViewModel(),
-) {
+internal fun ProfileScreen(viewModel: ProfileViewModel = hiltViewModel()) {
val state by viewModel.state.collectAsStateWithLifecycle()
var isShowDialog by remember { mutableStateOf(false) }
@@ -88,19 +84,19 @@ internal fun ProfileScreen(
.fillMaxWidth()
.background(White)
.safeGesturesPadding(),
- horizontalAlignment = Alignment.CenterHorizontally
+ horizontalAlignment = Alignment.CenterHorizontally,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(
- horizontal = 20.dp
- )
+ horizontal = 20.dp,
+ ),
) {
Text(
text = "${editTextString.first} 수정",
style = MaterialTheme.typography.titleMedium,
- color = Black
+ color = Black,
)
Spacer(modifier = Modifier.height(4.dp))
@@ -112,7 +108,7 @@ internal fun ProfileScreen(
placeholder = "${editTextString.first}${editTextString.second} 입력해주세요",
onClickDelete = {
editText = ""
- }
+ },
)
}
Spacer(modifier = Modifier.height(32.dp))
@@ -121,14 +117,14 @@ internal fun ProfileScreen(
onClick = {
viewModel.updateState(
target = editTextTarget,
- text = editText
+ text = editText,
)
editText = ""
editTextTarget = ""
dialogDismissRequest()
},
type = ButtonType.Primary,
- text = "저장"
+ text = "저장",
)
Spacer(modifier = Modifier.imePadding())
}
@@ -138,20 +134,20 @@ internal fun ProfileScreen(
Column(
modifier = Modifier
.fillMaxSize()
- .background(White)
+ .background(White),
) {
SeugiTopBar(
title = {
Text(
text = "내 프로필",
style = MaterialTheme.typography.titleLarge,
- color = Black
+ color = Black,
)
- }
+ },
)
Row(
modifier = Modifier.fillMaxWidth(),
- verticalAlignment = Alignment.CenterVertically
+ verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.width(16.dp))
SeugiAvatar(type = AvatarType.Medium)
@@ -159,7 +155,7 @@ internal fun ProfileScreen(
Text(
text = state.profileInfo.member.name,
style = MaterialTheme.typography.titleMedium,
- color = Black
+ color = Black,
)
Spacer(modifier = Modifier.weight(1f))
Image(
@@ -168,14 +164,14 @@ internal fun ProfileScreen(
.size(32.dp),
painter = painterResource(id = drawable.ic_setting_fill),
contentDescription = "설정 톱니바퀴",
- colorFilter = ColorFilter.tint(Gray500)
+ colorFilter = ColorFilter.tint(Gray500),
)
Spacer(modifier = Modifier.width(16.dp))
}
Spacer(modifier = Modifier.height(16.dp))
SeugiDivider(
size = 8.dp,
- type = DividerType.WIDTH
+ type = DividerType.WIDTH,
)
Spacer(modifier = Modifier.height(8.dp))
@@ -185,7 +181,7 @@ internal fun ProfileScreen(
onClickEdit = {
editTextTarget = "status"
isShowDialog = true
- }
+ },
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -200,7 +196,7 @@ internal fun ProfileScreen(
onClickEdit = {
editTextTarget = "spot"
isShowDialog = true
- }
+ },
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -215,7 +211,7 @@ internal fun ProfileScreen(
onClickEdit = {
editTextTarget = "belong"
isShowDialog = true
- }
+ },
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -230,7 +226,7 @@ internal fun ProfileScreen(
onClickEdit = {
editTextTarget = "phone"
isShowDialog = true
- }
+ },
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
@@ -245,46 +241,41 @@ internal fun ProfileScreen(
onClickEdit = {
editTextTarget = "wire"
isShowDialog = true
- }
+ },
)
Spacer(modifier = Modifier.height(8.dp))
SeugiDivider(
modifier = Modifier.padding(horizontal = 16.dp),
type = DividerType.WIDTH,
)
-
}
}
@Composable
-internal fun ProfileCard(
- title: String,
- content: String,
- onClickEdit: () -> Unit,
-) {
+internal fun ProfileCard(title: String, content: String, onClickEdit: () -> Unit) {
Column {
Row(
- verticalAlignment = Alignment.CenterVertically
+ verticalAlignment = Alignment.CenterVertically,
) {
Spacer(modifier = Modifier.width(20.dp))
Text(
text = title,
style = MaterialTheme.typography.bodyLarge,
- color = Gray500
+ color = Gray500,
)
Spacer(modifier = Modifier.weight(1f))
Image(
modifier = Modifier.size(20.dp),
painter = painterResource(id = drawable.ic_write_line),
contentDescription = "수정하기 아이콘",
- colorFilter = ColorFilter.tint(Gray500)
+ colorFilter = ColorFilter.tint(Gray500),
)
Spacer(modifier = Modifier.width(20.dp))
}
Box(
modifier = Modifier
.bounceClick(
- onClick = onClickEdit
+ onClick = onClickEdit,
)
.fillMaxWidth()
.height(56.dp),
@@ -295,18 +286,17 @@ internal fun ProfileCard(
.padding(start = 20.dp),
text = content,
style = MaterialTheme.typography.titleMedium,
- color = Black
+ color = Black,
)
}
}
}
-private fun getTargetTextToString(text: String): Pair =
- when(text) {
- "status" -> Pair("상태메세지", "를")
- "spot" -> Pair("직위", "를")
- "belong" -> Pair("소속", "을")
- "phone" -> Pair("휴대전화번호", "를")
- "wire" -> Pair("유선전화번호", "를")
- else -> Pair("", "")
- }
\ No newline at end of file
+private fun getTargetTextToString(text: String): Pair = when (text) {
+ "status" -> Pair("상태메세지", "를")
+ "spot" -> Pair("직위", "를")
+ "belong" -> Pair("소속", "을")
+ "phone" -> Pair("휴대전화번호", "를")
+ "wire" -> Pair("유선전화번호", "를")
+ else -> Pair("", "")
+}
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
index c437206a..846f405c 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/ProfileViewModel.kt
@@ -6,32 +6,31 @@ import com.apeun.gidaechi.common.model.Result
import com.apeun.gidaechi.data.profile.ProfileRepository
import com.apeun.gidaechi.profile.model.ProfileUiState
import dagger.hilt.android.lifecycle.HiltViewModel
+import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
-import javax.inject.Inject
@HiltViewModel
class ProfileViewModel @Inject constructor(
- private val profileRepository: ProfileRepository
-): ViewModel() {
+ private val profileRepository: ProfileRepository,
+) : ViewModel() {
private val _state = MutableStateFlow(ProfileUiState())
val state = _state.asStateFlow()
fun load() = viewModelScope.launch {
profileRepository.getProfile("664bdd0b9dfce726abd30462").collect { result ->
- when(result) {
+ when (result) {
is Result.Success -> {
_state.update {
it.copy(
- profileInfo = result.data
+ profileInfo = result.data,
)
}
}
is Result.Loading -> {
-
}
is Result.Error -> {
result.throwable.printStackTrace()
@@ -54,10 +53,10 @@ class ProfileViewModel @Inject constructor(
belong = if (target == "belong") text else belong,
phone = if (target == "phone") text else phone,
wire = if (target == "wire") text else wire,
- location = location
- )
+ location = location,
+ ),
)
}
}
}
-}
\ No newline at end of file
+}
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt
index f776534f..d2f6b7d7 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/model/ProfileUiState.kt
@@ -13,6 +13,6 @@ data class ProfileUiState(
"",
"",
"",
- ""
- )
-)
\ No newline at end of file
+ "",
+ ),
+)
diff --git a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt
index dd4b683a..83cab4c4 100644
--- a/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt
+++ b/feature-main/profile/src/main/java/com/apeun/gidaechi/profile/navigation/ProfileNavigation.kt
@@ -14,4 +14,4 @@ fun NavGraphBuilder.profileScreen() {
composable(PROFILE_ROUTE) {
ProfileScreen()
}
-}
\ No newline at end of file
+}
From c443cf5bfeb612a675465aa9153bb8f53938a10c Mon Sep 17 00:00:00 2001
From: 8954sood <8954sood@naver.com>
Date: Thu, 27 Jun 2024 15:36:03 +0900
Subject: [PATCH 7/7] chore: Recovery On Merge Delete
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
머지가 되면서 사라진 것을 복구하였습니다.
---
.../main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt b/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt
index c3ffe65c..f3cc04cc 100644
--- a/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt
+++ b/feature-main/main/src/main/java/com/apeun/gidaechi/main/MainScreen.kt
@@ -57,8 +57,8 @@ internal fun MainScreen(navHostController: NavHostController = rememberNavContro
is BottomNavigationItemType.Home -> HOME_ROUTE
is BottomNavigationItemType.Chat -> CHAT_ROUTE
is BottomNavigationItemType.Group -> ROOM_ROUTE
- is BottomNavigationItemType.Notification -> "route"
- is BottomNavigationItemType.Profile -> "route"
+ is BottomNavigationItemType.Notification -> NOTIFICATION_ROUTE
+ is BottomNavigationItemType.Profile -> PROFILE_ROUTE
else -> "route"
},
) {