From 818798d65dc453defc17805531afc73acb848c41 Mon Sep 17 00:00:00 2001 From: arinming Date: Mon, 7 Aug 2023 16:48:24 +0900 Subject: [PATCH 01/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=99=94=EB=A9=B4=20ViewModel=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=20=EC=84=B8=ED=8C=85=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/MainActivity.kt | 12 ------------ .../presentation/ui/main/MainScreen.kt | 2 -- .../myPage/profile/MyPageProfileActivity.kt | 2 +- .../myPage/profile/MyPageProfileContract.kt | 12 ++++++++++++ .../ui/myPage/profile/MyPageProfileScreen.kt | 9 ++++++--- .../myPage/profile/MyPageProfileViewModel.kt | 19 +++++++++++++++++++ 6 files changed, 38 insertions(+), 18 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index f0484c6..9ef0568 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -1,20 +1,8 @@ package com.meongmoryteam.presentation.ui.main import android.os.Bundle -import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -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.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt index 7270c1e..05bc7c8 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt @@ -16,9 +16,7 @@ import com.meongmoryteam.presentation.ui.bottom.MeongMoryBottomNavigation import com.meongmoryteam.presentation.ui.bottom.navigateBottomNavigationScreen import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen -import com.meongmoryteam.presentation.ui.myPage.MyPageProfileButton import com.meongmoryteam.presentation.ui.myPage.MyPageScreen -import com.meongmoryteam.presentation.ui.myPage.profile.MypageProfileScreen @Composable fun MainScreen( diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt index 33930ab..5740b96 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt @@ -11,7 +11,7 @@ class MyPageProfileActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { - MypageProfileScreen() + MyPageProfileScreen() } } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt new file mode 100644 index 0000000..5f71273 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -0,0 +1,12 @@ +package com.meongmoryteam.presentation.ui.myPage.profile + +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewState + +class MyPageProfileContract { + // 모델 클래스 + data class MyPageUiState( + val loadState: LoadState = LoadState.SUCCESS, + val nickname: String = "" + ) : ViewState +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 4d71c9c..90d83ef 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -31,18 +31,21 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R -import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme val PADDING_16 = 16.dp val PADDING_24 = 24.dp @Composable -fun MypageProfileScreen() { +fun MyPageProfileScreen( + viewModel: MyPageProfileViewModel = hiltViewModel(), +) { Column( modifier = Modifier .fillMaxHeight() @@ -213,6 +216,6 @@ fun ProfileChangeButton() { @Composable fun PreviewProfileScreen() { MeongmoryTheme { - MypageProfileScreen() + MyPageProfileScreen() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt new file mode 100644 index 0000000..e303a01 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -0,0 +1,19 @@ +package com.meongmoryteam.presentation.ui.myPage.profile + +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import javax.inject.Inject + +@HiltViewModel +class MyPageProfileViewModel @Inject constructor( + private val saveStateHandle: SavedStateHandle, +) : ViewModel() { + private val _uiState = MutableStateFlow(MyPageProfileContract.MyPageUiState()) + private lateinit var currentProfile: String + // asStateFlow() -> 변경 가능 상태 흐름을 읽기 전용 상태 흐름으로 만든다 + val uiState: StateFlow = _uiState.asStateFlow() +} \ No newline at end of file From 687fc24dc7233c0079275e05ccef0f75b90e1879 Mon Sep 17 00:00:00 2001 From: arinming Date: Mon, 7 Aug 2023 19:07:00 +0900 Subject: [PATCH 02/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=99=94=EB=A9=B4=20ViewModel=20Event=20=EA=B5=AC?= =?UTF-8?q?=EC=B2=B4=ED=99=94=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../myPage/profile/MyPageProfileContract.kt | 19 ++++++- .../ui/myPage/profile/MyPageProfileScreen.kt | 14 +++-- .../myPage/profile/MyPageProfileViewModel.kt | 54 +++++++++++++++---- 3 files changed, 70 insertions(+), 17 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 5f71273..76a6e67 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -1,12 +1,27 @@ package com.meongmoryteam.presentation.ui.myPage.profile import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect import com.meongmoryteam.presentation.base.ViewState class MyPageProfileContract { // 모델 클래스 - data class MyPageUiState( + data class MyPageProfileViewState( val loadState: LoadState = LoadState.SUCCESS, - val nickname: String = "" + val nickName: String = "", + val isError: Boolean = true ) : ViewState + + sealed class MyPageProfileSideEffect: ViewSideEffect { + object NavigateToHome : MyPageProfileSideEffect() + } + + sealed class MyPageProfileEvent: ViewEvent { + data class FillNickName( + val nickName: String + ) : MyPageProfileEvent() + object ClearNickName: MyPageProfileEvent() + object OnClickChangeButton: MyPageProfileEvent() + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 90d83ef..4cab41d 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.material3.Divider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -43,9 +44,7 @@ val PADDING_16 = 16.dp val PADDING_24 = 24.dp @Composable -fun MyPageProfileScreen( - viewModel: MyPageProfileViewModel = hiltViewModel(), -) { +fun MyPageProfileScreen() { Column( modifier = Modifier .fillMaxHeight() @@ -195,9 +194,14 @@ fun MyPageEditForm() { } @Composable -fun ProfileChangeButton() { +fun ProfileChangeButton( + viewModel: MyPageProfileViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() Button( - onClick = { /*TODO*/ }, + onClick = { + viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) + }, colors = ButtonDefaults.buttonColors(EditButtonFalse), modifier = Modifier .padding(16.dp) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index e303a01..42911a1 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -1,19 +1,53 @@ package com.meongmoryteam.presentation.ui.myPage.profile import androidx.lifecycle.SavedStateHandle -import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.meongmoryteam.presentation.base.BaseViewModel +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileContract.MyPageProfileEvent +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileContract.MyPageProfileSideEffect +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileContract.MyPageProfileViewState import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class MyPageProfileViewModel @Inject constructor( private val saveStateHandle: SavedStateHandle, -) : ViewModel() { - private val _uiState = MutableStateFlow(MyPageProfileContract.MyPageUiState()) - private lateinit var currentProfile: String - // asStateFlow() -> 변경 가능 상태 흐름을 읽기 전용 상태 흐름으로 만든다 - val uiState: StateFlow = _uiState.asStateFlow() -} \ No newline at end of file +) : BaseViewModel( + MyPageProfileViewState() +) { + override fun handleEvents(event: MyPageProfileEvent) { + when (event) { + MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") + is MyPageProfileEvent.FillNickName -> reflectUpdatedState(event.nickName) + MyPageProfileEvent.OnClickChangeButton -> changeNickName(viewState.value.nickName) + } + } + + private fun reflectUpdatedState( + nickName: String = viewState.value.nickName + ) { + updateState { + copy( + nickName = nickName, + isError = isOverflowed(nickName) + ) + } + } + + private fun changeNickName(nickName: String) = viewModelScope.launch { + updateState { + copy( + loadState = LoadState.LOADING + ) + } + } + + // 텍스트 길이 초과 + private fun isOverflowed(nickName: String): Boolean { + return nickName.isBlank() || (nickName.length > MAX_LENGTH_NICKNAME) + } +} + +const val MAX_LENGTH_NICKNAME = 6 From 9d852bbc83906df3aea116d13ebb1cf1641f36a6 Mon Sep 17 00:00:00 2001 From: arinming Date: Tue, 8 Aug 2023 17:21:05 +0900 Subject: [PATCH 03/37] =?UTF-8?q?[refactor/mypage]=20=EB=AC=B8=EC=9D=98=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=9C=EB=B3=B4=ED=95=98=EA=B8=B0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20ViewModel,=20Contract=20=EC=83=9D=EC=84=B1=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/MyPageQuestionConstract.kt | 27 ++++++++++++ .../myPage/question/MyPageQuestionScreen.kt | 17 ++++++-- .../question/MyPageQuestionViewModel.kt | 43 +++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt new file mode 100644 index 0000000..1553182 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt @@ -0,0 +1,27 @@ +package com.meongmoryteam.presentation.ui.myPage.question + +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class MyPageQuestionConstract { + data class MyPageQuestionViewState( + val loadState: LoadState = LoadState.SUCCESS, + val email: String = "", + val question: String = "", + val isError: Boolean = true + ) : ViewState + + sealed class MyPageQuestionSideEffect: ViewSideEffect { + object NavigateToHome : MyPageQuestionSideEffect() + } + + sealed class MyPageQuestionEvent: ViewEvent { + data class FillEmail( + val email: String + ): MyPageQuestionEvent() + object ClearEmail: MyPageQuestionEvent() + object OnClickButton: MyPageQuestionEvent() + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index ea596da..fba2770 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -33,12 +34,13 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar import com.meongmoryteam.presentation.ui.theme.EditButtonFalse -import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.QuestionButtonText import com.meongmoryteam.presentation.ui.theme.QuestionEditFill import com.meongmoryteam.presentation.ui.theme.QuestionSubTitle @@ -59,7 +61,9 @@ fun MyPageQuestionScreen() { MyPageToolBar(stringResource(R.string.question_title)) Spacer(modifier = Modifier.padding(PADDING_8)) EmailEdit() - Column(modifier = Modifier.fillMaxHeight(0.5f)) { + Column( + modifier = Modifier.fillMaxHeight(0.5f) + ) { DetailEdit() } Box( @@ -225,9 +229,14 @@ fun DetailForm() { } @Composable -fun QuestionButton() { +fun QuestionButton( + viewModel: MyPageQuestionViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() Button( - onClick = { /*TODO*/ }, + onClick = { + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickButton) + }, colors = ButtonDefaults.buttonColors(EditButtonFalse), modifier = Modifier .padding(16.dp) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt new file mode 100644 index 0000000..9c10b10 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -0,0 +1,43 @@ +package com.meongmoryteam.presentation.ui.myPage.question + +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.viewModelScope +import com.meongmoryteam.presentation.base.BaseViewModel +import com.meongmoryteam.presentation.base.LoadState +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.* +import kotlinx.coroutines.launch + +@HiltViewModel +class MyPageQuestionViewModel @Inject constructor( + private val savedStateHandle: SavedStateHandle +) : BaseViewModel( + MyPageQuestionViewState() +) { + override fun handleEvents(event: MyPageQuestionEvent) { + when (event) { + MyPageQuestionEvent.ClearEmail -> reflectUpdatedState("") + is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(event.email) + MyPageQuestionEvent.OnClickButton -> setEmail(viewState.value.email) + } + } + + private fun reflectUpdatedState( + email: String = viewState.value.email + ) { + updateState { + copy( + email = email, + ) + } + } + + private fun setEmail(email: String) = viewModelScope.launch { + updateState { + copy( + loadState = LoadState.LOADING + ) + } + } +} \ No newline at end of file From 11d16974948f1525cc4075cf59a7cb862b471cc6 Mon Sep 17 00:00:00 2001 From: arinming Date: Tue, 8 Aug 2023 23:49:39 +0900 Subject: [PATCH 04/37] =?UTF-8?q?[refactor/mypage]=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=99=94=EB=A9=B4=20ViewModel,?= =?UTF-8?q?=20Contract=20=EC=83=9D=EC=84=B1=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/myPage/MyPageContract.kt | 24 +++++++++++++++++ .../presentation/ui/myPage/MyPageViewModel.kt | 27 +++++++++++++++++++ .../ui/myPage/profile/MyPageProfileScreen.kt | 5 +++- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt new file mode 100644 index 0000000..143313e --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -0,0 +1,24 @@ +package com.meongmoryteam.presentation.ui.myPage + +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class MyPageContract { + data class MyPageViewState( + val loadState: LoadState = LoadState.SUCCESS, + val nickName: String = "", + val isDialogVisible: Boolean = false + ) : ViewState + + sealed class MyPageSideEffect: ViewSideEffect { + object EditNickName: MyPageSideEffect() + object NavigateToQuestion: MyPageSideEffect() + } + + sealed class MyPageEvent: ViewEvent { + object OnClickProfileEditButtonClicked: MyPageEvent() + object OnClickQuestionButtonClicked: MyPageEvent() + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt new file mode 100644 index 0000000..ca25db2 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -0,0 +1,27 @@ +package com.meongmoryteam.presentation.ui.myPage + +import androidx.lifecycle.SavedStateHandle +import com.meongmoryteam.presentation.base.BaseViewModel +import com.meongmoryteam.presentation.base.LoadState +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.* + + +@HiltViewModel +class MyPageViewModel @Inject constructor( + private val savedStateHandle: SavedStateHandle +) : BaseViewModel( + MyPageViewState() +) { + override fun handleEvents(event: MyPageEvent) { + when (event) { + is MyPageEvent.OnClickProfileEditButtonClicked -> { + sendEffect({ MyPageSideEffect.EditNickName }) + } + is MyPageEvent.OnClickQuestionButtonClicked -> { + sendEffect({ MyPageSideEffect.NavigateToQuestion }) + } + } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 4cab41d..d4c67af 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -33,6 +33,8 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditDivider @@ -44,7 +46,8 @@ val PADDING_16 = 16.dp val PADDING_24 = 24.dp @Composable -fun MyPageProfileScreen() { +fun MyPageProfileScreen( +) { Column( modifier = Modifier .fillMaxHeight() From 12a3068052eedf1324d91b850004a78231c92105 Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 02:13:23 +0900 Subject: [PATCH 05/37] =?UTF-8?q?[refactor/mypage]=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=ED=8E=B8=EC=A7=91,=20=EB=AC=B8=EC=9D=98=ED=95=98=EA=B8=B0=20ro?= =?UTF-8?q?ute=20=EC=84=A4=EC=A0=95=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/bottom/BottomNavigation.kt | 2 ++ .../presentation/ui/main/MainActivity.kt | 9 +++++- .../presentation/ui/main/MainContract.kt | 23 +++++++++++++ .../presentation/ui/main/MainScreen.kt | 17 ++++++++-- .../presentation/ui/main/MainViewModel.kt | 18 +++++++++++ .../presentation/ui/myPage/MyPageContract.kt | 2 +- .../presentation/ui/myPage/MyPageScreen.kt | 32 ++++++++++++++++--- .../presentation/ui/myPage/MyPageViewModel.kt | 2 +- 8 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt index 1f2cfd0..54fbc48 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt @@ -25,4 +25,6 @@ enum class MeongMoryRoute(val route: String) { MAP("map"), HOME("home"), MY_PAGE("my-page"), + EDIT_NICKNAME("edit-nickname"), + QUESTION("question"), } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index 9ef0568..310c969 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -1,13 +1,18 @@ package com.meongmoryteam.presentation.ui.main +import android.content.Context +import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.viewModels import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { + private val viewModel: MainViewModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -17,7 +22,9 @@ class MainActivity : ComponentActivity() { private fun setMainScreen() { setContent { MeongmoryTheme { - MainScreen() + MainScreen( + intentToCreateHome = { } + ) } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt new file mode 100644 index 0000000..23f1ceb --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt @@ -0,0 +1,23 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class MainContract { + data class MainViewState( + val loginState: LoginState = LoginState.NONE + ) : ViewState + + sealed class MainSideEffect : ViewSideEffect { + object Navigate + } + + sealed class MainEvent : ViewEvent { + object OnBottomNavigationClicked : MainEvent() + } + + enum class LoginState { + NONE, LOGIN + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt index 05bc7c8..6a7d61a 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt @@ -3,9 +3,12 @@ package com.meongmoryteam.presentation.ui.main import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -13,15 +16,20 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.ui.bottom.BottomNavigation import com.meongmoryteam.presentation.ui.bottom.MeongMoryBottomNavigation +import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute import com.meongmoryteam.presentation.ui.bottom.navigateBottomNavigationScreen import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen import com.meongmoryteam.presentation.ui.myPage.MyPageScreen +import kotlinx.coroutines.flow.collect @Composable fun MainScreen( + viewModel: MainViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), + intentToCreateHome: () -> Unit, ) { + val viewState by viewModel.viewState.collectAsState() val navBackStackEntry by navController.currentBackStackEntryAsState() val currentDestination = navBackStackEntry?.destination @@ -50,7 +58,10 @@ fun MainScreen( MapScreen() } composable(route = BottomNavigation.MY_PAGE.route) { - MyPageScreen() + MyPageScreen( + navigateToEditNickNameScreen = { navController.navigate(MeongMoryRoute.EDIT_NICKNAME.route) }, + navigateToQuestionScreen = { navController.navigate(MeongMoryRoute.QUESTION.route) }, + ) } } } @@ -59,5 +70,7 @@ fun MainScreen( @Preview @Composable fun MainScreenPreview() { - MainScreen() + MainScreen( + intentToCreateHome = { } + ) } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt new file mode 100644 index 0000000..6e1f836 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt @@ -0,0 +1,18 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.main.MainContract.* + +@HiltViewModel +class MainViewModel @Inject constructor() : BaseViewModel( + MainViewState() +) { + override fun handleEvents(event: MainEvent) { + when (event) { + is MainEvent.OnBottomNavigationClicked -> { + } + } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt index 143313e..8b7a5bc 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -13,7 +13,7 @@ class MyPageContract { ) : ViewState sealed class MyPageSideEffect: ViewSideEffect { - object EditNickName: MyPageSideEffect() + object NavigateToEditProfile: MyPageSideEffect() object NavigateToQuestion: MyPageSideEffect() } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 2751a16..01489b3 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -20,7 +20,9 @@ import androidx.compose.material3.Divider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState +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 import androidx.compose.ui.Alignment @@ -34,8 +36,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.navigation.NavHostController -import androidx.navigation.compose.rememberNavController +import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog @@ -46,14 +47,32 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.MyPageProfileEditButton import com.meongmoryteam.presentation.ui.theme.MyPageYellowFill import com.meongmoryteam.presentation.ui.theme.MyPageYellowStroke +import kotlinx.coroutines.flow.collect val PADDING_8 = 8.dp val PADDING_16 = 16.dp @Composable fun MyPageScreen( - navController: NavHostController = rememberNavController() + viewModel: MyPageViewModel = hiltViewModel(), + navigateToEditNickNameScreen: () -> Unit, + navigateToQuestionScreen: () -> Unit, ) { + val viewState by viewModel.viewState.collectAsState() + + LaunchedEffect(key1 = viewModel.effect) { + viewModel.effect.collect { effect -> + when (effect) { + is MyPageContract.MyPageSideEffect.NavigateToEditProfile -> { + navigateToEditNickNameScreen() + } + is MyPageContract.MyPageSideEffect.NavigateToQuestion -> { + navigateToQuestionScreen() + } + } + } + } + Column { MyPageTitle() MyPageProfile() @@ -311,7 +330,10 @@ fun ListButton( @Composable fun PreviewMyPageScreen() { MeongmoryTheme { - MyPageScreen() + MyPageScreen( + navigateToEditNickNameScreen = { }, + navigateToQuestionScreen = { }, + ) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt index ca25db2..85c8edf 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -17,7 +17,7 @@ class MyPageViewModel @Inject constructor( override fun handleEvents(event: MyPageEvent) { when (event) { is MyPageEvent.OnClickProfileEditButtonClicked -> { - sendEffect({ MyPageSideEffect.EditNickName }) + sendEffect({ MyPageSideEffect.NavigateToEditProfile }) } is MyPageEvent.OnClickQuestionButtonClicked -> { sendEffect({ MyPageSideEffect.NavigateToQuestion }) From 02ceea7d7761a3139b4813f48f6cc0b6a29007e8 Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 14:36:28 +0900 Subject: [PATCH 06/37] =?UTF-8?q?[refactor/mypage]=20route=EB=B3=84=20?= =?UTF-8?q?=EB=B0=94=ED=85=80=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EA=B0=80=EC=8B=9C=EC=84=B1=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/HomeContract.kt | 21 +++++ .../ui/main/{MainScreen.kt => HomeScreen.kt} | 47 ++++++---- .../presentation/ui/main/HomeViewModel.kt | 15 ++++ .../presentation/ui/main/MainActivity.kt | 41 ++++++++- .../presentation/ui/main/MainContract.kt | 12 +-- .../presentation/ui/main/MainViewModel.kt | 7 +- .../presentation/ui/myPage/MyPageScreen.kt | 90 +++++++++++++++---- 7 files changed, 185 insertions(+), 48 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt rename presentation/src/main/java/com/meongmoryteam/presentation/ui/main/{MainScreen.kt => HomeScreen.kt} (60%) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt new file mode 100644 index 0000000..69e220e --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt @@ -0,0 +1,21 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class HomeContract { + data class HomeViewState( + val loginState: LoginState = LoginState.NONE, + ) : ViewState + + sealed class HomeSideEffect : ViewSideEffect { + } + + sealed class HomeEvent : ViewEvent { + } + + enum class LoginState { + NONE, LOGIN + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt similarity index 60% rename from presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt rename to presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt index 6a7d61a..818d031 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt @@ -3,9 +3,11 @@ package com.meongmoryteam.presentation.ui.main import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold 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.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel @@ -14,14 +16,13 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import com.meongmoryteam.presentation.ui.bottom.BottomNavigation import com.meongmoryteam.presentation.ui.bottom.MeongMoryBottomNavigation import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute import com.meongmoryteam.presentation.ui.bottom.navigateBottomNavigationScreen import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen import com.meongmoryteam.presentation.ui.myPage.MyPageScreen -import kotlinx.coroutines.flow.collect +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen @Composable fun MainScreen( @@ -32,39 +33,53 @@ fun MainScreen( val viewState by viewModel.viewState.collectAsState() val navBackStackEntry by navController.currentBackStackEntryAsState() val currentDestination = navBackStackEntry?.destination + var bottomBarState by rememberSaveable { mutableStateOf(true) } Scaffold( bottomBar = { - MeongMoryBottomNavigation( - currentDestination = currentDestination, - navigateToScreen = { navigationItem -> - navigateBottomNavigationScreen( - navController = navController, - navigationItem = navigationItem, - ) - } - ) + if (bottomBarState) { + MeongMoryBottomNavigation( + currentDestination = currentDestination, + navigateToScreen = { navigationItem -> + navigateBottomNavigationScreen( + navController = navController, + navigationItem = navigationItem, + ) + } + ) + } } ) { padding -> NavHost( modifier = Modifier.padding(padding), navController = navController, - startDestination = BottomNavigation.HOME.route, + startDestination = MeongMoryRoute.HOME.route, ) { - composable(route = BottomNavigation.HOME.route) { + composable(route = MeongMoryRoute.HOME.route) { HomeScreen() } - composable(route = BottomNavigation.MAP.route) { + composable(route = MeongMoryRoute.MAP.route) { MapScreen() } - composable(route = BottomNavigation.MY_PAGE.route) { + composable(route = MeongMoryRoute.MY_PAGE.route) { MyPageScreen( navigateToEditNickNameScreen = { navController.navigate(MeongMoryRoute.EDIT_NICKNAME.route) }, navigateToQuestionScreen = { navController.navigate(MeongMoryRoute.QUESTION.route) }, ) } + composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { + MyPageProfileScreen() + } } } + + // 바텀 네비게이션 보이기, 숨기기 + bottomBarState = when (currentDestination?.route) { + MeongMoryRoute.HOME.route -> true + MeongMoryRoute.MAP.route -> true + MeongMoryRoute.MY_PAGE.route -> true + else -> false + } } @Preview diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt new file mode 100644 index 0000000..579175d --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt @@ -0,0 +1,15 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.main.HomeContract.* + +@HiltViewModel +class HomeViewModel @Inject constructor( +) : BaseViewModel( + HomeViewState() +) { + override fun handleEvents(event: HomeEvent) { + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index 310c969..dbdc281 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -2,16 +2,29 @@ package com.meongmoryteam.presentation.ui.main import android.content.Context import android.content.Intent +import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { private val viewModel: MainViewModel by viewModels() + private var createResultLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { _ -> + viewModel.setEvent(MainContract.MainEvent.FinishedCreateActivity) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -22,10 +35,30 @@ class MainActivity : ComponentActivity() { private fun setMainScreen() { setContent { MeongmoryTheme { - MainScreen( - intentToCreateHome = { } - ) + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = MeongMoryRoute.HOME.route, + ) { + composable(route = MeongMoryRoute.HOME.route) { + MainScreen(intentToCreateHome = { }) + } + composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { + MyPageProfileScreen() + } + composable(route = MeongMoryRoute.QUESTION.route) { + MyPageQuestionScreen() + } + } } } } -} \ No newline at end of file + + companion object { + fun startActivity(context: Context, uri: Uri?) { + val intent = Intent(context, MainActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_NEW_TASK + context.startActivity(intent) + } + } +} diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt index 23f1ceb..34aab94 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt @@ -5,19 +5,13 @@ import com.meongmoryteam.presentation.base.ViewSideEffect import com.meongmoryteam.presentation.base.ViewState class MainContract { - data class MainViewState( - val loginState: LoginState = LoginState.NONE - ) : ViewState + object MainViewState : ViewState sealed class MainSideEffect : ViewSideEffect { - object Navigate + object RefreshScreen : MainSideEffect() } sealed class MainEvent : ViewEvent { - object OnBottomNavigationClicked : MainEvent() - } - - enum class LoginState { - NONE, LOGIN + object FinishedCreateActivity : MainEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt index 6e1f836..00d32b6 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt @@ -6,12 +6,11 @@ import javax.inject.Inject import com.meongmoryteam.presentation.ui.main.MainContract.* @HiltViewModel -class MainViewModel @Inject constructor() : BaseViewModel( - MainViewState() -) { +class MainViewModel @Inject constructor( +) : BaseViewModel(MainViewState) { override fun handleEvents(event: MainEvent) { when (event) { - is MainEvent.OnBottomNavigationClicked -> { + is MainEvent.FinishedCreateActivity-> { } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 01489b3..2a690a5 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -38,8 +38,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog +import com.meongmoryteam.presentation.ui.main.MainViewModel import com.meongmoryteam.presentation.ui.theme.ListDivider import com.meongmoryteam.presentation.ui.theme.ListNextButton import com.meongmoryteam.presentation.ui.theme.ListTitle @@ -47,7 +49,6 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.MyPageProfileEditButton import com.meongmoryteam.presentation.ui.theme.MyPageYellowFill import com.meongmoryteam.presentation.ui.theme.MyPageYellowStroke -import kotlinx.coroutines.flow.collect val PADDING_8 = 8.dp val PADDING_16 = 16.dp @@ -66,16 +67,38 @@ fun MyPageScreen( is MyPageContract.MyPageSideEffect.NavigateToEditProfile -> { navigateToEditNickNameScreen() } + is MyPageContract.MyPageSideEffect.NavigateToQuestion -> { navigateToQuestionScreen() } } } } + when (viewState.loadState) { + LoadState.SUCCESS -> { + MyPageProfileButton( + OnClickEditNickname = { + navigateToEditNickNameScreen + }, + ) + } + LoadState.LOADING -> { + + } + LoadState.ERROR -> { + + } + } + + + Column { MyPageTitle() - MyPageProfile() + MyPageProfile( + userName = "", + OnClickEditNickname = { navigateToEditNickNameScreen() } + ) MyPageList() } } @@ -98,7 +121,10 @@ fun MyPageTitle() { @Composable -fun MyPageProfile() { +fun MyPageProfile( + userName: String, + OnClickEditNickname: () -> Unit, +) { // 상단 프로필 메뉴 Column { Row( @@ -128,10 +154,18 @@ fun MyPageProfile() { fontSize = 14.sp ) - Row(modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End) { - MyPageProfileButton(stringResource(R.string.my_page_profile_alarm)) - MyPageProfileButton(stringResource(R.string.my_page_profile_edit)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End + ) { + MyPageProfileButton( + stringResource(R.string.my_page_profile_alarm), + OnClickEditNickname = { } + ) + MyPageProfileButton( + stringResource(R.string.my_page_profile_edit), + OnClickEditNickname = { } + ) } @@ -163,7 +197,7 @@ fun MyPageList() { .fillMaxWidth() .fillMaxHeight() ) { - Column{ + Column { Text( text = stringResource(R.string.my_page_list_account), fontWeight = FontWeight.Bold, @@ -174,8 +208,16 @@ fun MyPageList() { ) ListButton(R.drawable.ic_coin, stringResource(R.string.my_page_pro_ver)) - ListButton(R.drawable.ic_logout, stringResource(R.string.my_page_logout), stringResource(R.string.my_page_logout)) - ListButton(R.drawable.ic_user, stringResource(R.string.my_page_drop), stringResource(R.string.my_page_drop)) + ListButton( + R.drawable.ic_logout, + stringResource(R.string.my_page_logout), + stringResource(R.string.my_page_logout) + ) + ListButton( + R.drawable.ic_user, + stringResource(R.string.my_page_drop), + stringResource(R.string.my_page_drop) + ) Spacer(modifier = Modifier.padding(top = PADDING_16)) @@ -231,12 +273,20 @@ fun MyPageList() { @Composable fun MyPageProfileButton( - buttonText: String? = null + buttonText: String? = null, + onClickAction: String? = null, + OnClickEditNickname: () -> Unit, ) { + val refreshButton = remember { + mutableStateOf(false) + } Column(modifier = Modifier) { Button( - onClick = { /*TODO*/ }, + onClick = { + // 프로필 편집 버튼이 클릭되었을 때 + OnClickEditNickname + }, modifier = Modifier .padding(end = PADDING_8) .wrapContentSize(), @@ -252,6 +302,15 @@ fun MyPageProfileButton( } } } + // 버튼마다 다른 다이어로그 + if (refreshButton.value) { + if (onClickAction == stringResource(R.string.my_page_profile_edit)) { + LogoutAlertDialog(openDialogCustom = refreshButton) + } + if (onClickAction == stringResource(R.string.my_page_question)) { + SecessionAlertDialog(openDialogCustom = refreshButton) + } + } } @@ -294,9 +353,10 @@ fun ListButton( ) } - Box(modifier = Modifier - .padding() - .fillMaxWidth(), + Box( + modifier = Modifier + .padding() + .fillMaxWidth(), contentAlignment = Alignment.CenterEnd ) { Button( From ceeb1e2073ead33f28724cbada85507dbf87d236 Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 16:53:41 +0900 Subject: [PATCH 07/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=88=98=EC=A0=95,=20=EB=AC=B8=EC=9D=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=A0=9C=EB=B3=B4=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/bottom/BottomNavigationScreen.kt | 3 +- .../presentation/ui/main/HomeScreen.kt | 9 +- .../presentation/ui/main/MainActivity.kt | 30 +---- .../presentation/ui/myPage/MyPageContract.kt | 3 +- .../presentation/ui/myPage/MyPageScreen.kt | 122 ++++++++++++------ .../presentation/ui/myPage/MyPageViewModel.kt | 11 +- .../ui/myPage/profile/MyPageProfileScreen.kt | 3 + .../myPage/profile/MyPageProfileViewModel.kt | 1 - .../question/MyPageQuestionViewModel.kt | 8 +- .../presentation/util/ActivityViewModelExt.kt | 14 ++ 10 files changed, 121 insertions(+), 83 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt index 19f39cf..f551b91 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavDestination +import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import com.meongmoryteam.presentation.ui.theme.GRAY100 @@ -48,7 +49,7 @@ fun MeongMoryBottomNavigation( } ) }, - selected = currentDestination?.route == bottomItem.route, + selected = currentDestination?.hierarchy?.any { it.route == bottomItem.route } == true, onClick = { navigateToScreen(bottomItem) }, colors = NavigationBarItemDefaults.colors(indicatorColor = Color.White), ) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt index 818d031..0e58ccf 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt @@ -23,12 +23,12 @@ import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen import com.meongmoryteam.presentation.ui.myPage.MyPageScreen import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen @Composable fun MainScreen( viewModel: MainViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), - intentToCreateHome: () -> Unit, ) { val viewState by viewModel.viewState.collectAsState() val navBackStackEntry by navController.currentBackStackEntryAsState() @@ -70,6 +70,9 @@ fun MainScreen( composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { MyPageProfileScreen() } + composable(route = MeongMoryRoute.QUESTION.route) { + MyPageQuestionScreen() + } } } @@ -85,7 +88,5 @@ fun MainScreen( @Preview @Composable fun MainScreenPreview() { - MainScreen( - intentToCreateHome = { } - ) + MainScreen() } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index dbdc281..21e58f2 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -1,31 +1,17 @@ package com.meongmoryteam.presentation.ui.main -import android.content.Context -import android.content.Intent -import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.result.contract.ActivityResultContracts -import androidx.activity.viewModels import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute -import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen -import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { - private val viewModel: MainViewModel by viewModels() - private var createResultLauncher = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { _ -> - viewModel.setEvent(MainContract.MainEvent.FinishedCreateActivity) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -41,24 +27,10 @@ class MainActivity : ComponentActivity() { startDestination = MeongMoryRoute.HOME.route, ) { composable(route = MeongMoryRoute.HOME.route) { - MainScreen(intentToCreateHome = { }) - } - composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { - MyPageProfileScreen() - } - composable(route = MeongMoryRoute.QUESTION.route) { - MyPageQuestionScreen() + MainScreen() } } } } } - - companion object { - fun startActivity(context: Context, uri: Uri?) { - val intent = Intent(context, MainActivity::class.java) - intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_NEW_TASK - context.startActivity(intent) - } - } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt index 8b7a5bc..63c6eb3 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -18,7 +18,8 @@ class MyPageContract { } sealed class MyPageEvent: ViewEvent { + object InitMyPageScreen : MyPageEvent() object OnClickProfileEditButtonClicked: MyPageEvent() - object OnClickQuestionButtonClicked: MyPageEvent() + object OnQuestionClicked: MyPageEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 2a690a5..4824bb4 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -41,6 +41,7 @@ import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog +import com.meongmoryteam.presentation.ui.main.MainContract import com.meongmoryteam.presentation.ui.main.MainViewModel import com.meongmoryteam.presentation.ui.theme.ListDivider import com.meongmoryteam.presentation.ui.theme.ListNextButton @@ -49,19 +50,25 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.MyPageProfileEditButton import com.meongmoryteam.presentation.ui.theme.MyPageYellowFill import com.meongmoryteam.presentation.ui.theme.MyPageYellowStroke +import com.meongmoryteam.presentation.util.composableActivityViewModel val PADDING_8 = 8.dp val PADDING_16 = 16.dp @Composable fun MyPageScreen( + mainViewModel: MainViewModel = composableActivityViewModel(), viewModel: MyPageViewModel = hiltViewModel(), navigateToEditNickNameScreen: () -> Unit, navigateToQuestionScreen: () -> Unit, ) { val viewState by viewModel.viewState.collectAsState() - LaunchedEffect(key1 = viewModel.effect) { + LaunchedEffect(true) { + viewModel.setEvent(MyPageContract.MyPageEvent.InitMyPageScreen) + } + + LaunchedEffect(viewModel.effect) { viewModel.effect.collect { effect -> when (effect) { is MyPageContract.MyPageSideEffect.NavigateToEditProfile -> { @@ -74,32 +81,36 @@ fun MyPageScreen( } } } - when (viewState.loadState) { - LoadState.SUCCESS -> { - MyPageProfileButton( - OnClickEditNickname = { - navigateToEditNickNameScreen - }, - ) - } - LoadState.LOADING -> { - - } - LoadState.ERROR -> { + LaunchedEffect(mainViewModel.effect) { + mainViewModel.effect.collect { effect -> + when (effect) { + is MainContract.MainSideEffect.RefreshScreen -> { + viewModel.setEvent(MyPageContract.MyPageEvent.InitMyPageScreen) + } + } } } + when (viewState.loadState) { + LoadState.SUCCESS -> { + Column { + MyPageTitle() + MyPageProfile( + OnClickEditNickname = { + viewModel.setEvent(MyPageContract.MyPageEvent.OnClickProfileEditButtonClicked) + } + ) + MyPageList( + onQuestionClicked = { + viewModel.setEvent(MyPageContract.MyPageEvent.OnQuestionClicked) + } + ) + } + } - - - Column { - MyPageTitle() - MyPageProfile( - userName = "", - OnClickEditNickname = { navigateToEditNickNameScreen() } - ) - MyPageList() + LoadState.LOADING -> {} + LoadState.ERROR -> {} } } @@ -122,7 +133,6 @@ fun MyPageTitle() { @Composable fun MyPageProfile( - userName: String, OnClickEditNickname: () -> Unit, ) { // 상단 프로필 메뉴 @@ -160,11 +170,11 @@ fun MyPageProfile( ) { MyPageProfileButton( stringResource(R.string.my_page_profile_alarm), - OnClickEditNickname = { } + onClick = { } ) MyPageProfileButton( stringResource(R.string.my_page_profile_edit), - OnClickEditNickname = { } + onClick = OnClickEditNickname ) } @@ -185,7 +195,9 @@ fun MyPageProfile( @Composable -fun MyPageList() { +fun MyPageList( + onQuestionClicked: () -> Unit, +) { // 마이페이지 목록 부분 Row( @@ -207,16 +219,22 @@ fun MyPageList() { fontSize = 11.sp ) - ListButton(R.drawable.ic_coin, stringResource(R.string.my_page_pro_ver)) + ListButton( + R.drawable.ic_coin, + stringResource(R.string.my_page_pro_ver), + onClick = { }, + ) ListButton( R.drawable.ic_logout, stringResource(R.string.my_page_logout), - stringResource(R.string.my_page_logout) + stringResource(R.string.my_page_logout), + onClick = { }, ) ListButton( R.drawable.ic_user, stringResource(R.string.my_page_drop), - stringResource(R.string.my_page_drop) + stringResource(R.string.my_page_drop), + onClick = { }, ) Spacer(modifier = Modifier.padding(top = PADDING_16)) @@ -239,8 +257,16 @@ fun MyPageList() { fontSize = 11.sp ) - ListButton(R.drawable.ic_mail, stringResource(R.string.my_page_notice)) - ListButton(R.drawable.ic_send, stringResource(R.string.my_page_question)) + ListButton( + R.drawable.ic_mail, + stringResource(R.string.my_page_notice), + onClick = { }, + ) + ListButton( + R.drawable.ic_send, + stringResource(R.string.my_page_question), + onClick = onQuestionClicked, + ) Spacer(modifier = Modifier.padding(top = PADDING_16)) @@ -261,8 +287,16 @@ fun MyPageList() { color = ListTitle, fontSize = 11.sp ) - ListButton(R.drawable.ic_info, stringResource(R.string.my_page_clause)) - ListButton(R.drawable.ic_unlock, stringResource(R.string.my_page_personal)) + ListButton( + R.drawable.ic_info, + stringResource(R.string.my_page_clause), + onClick = { }, + ) + ListButton( + R.drawable.ic_unlock, + stringResource(R.string.my_page_personal), + onClick = { }, + ) } @@ -275,7 +309,7 @@ fun MyPageList() { fun MyPageProfileButton( buttonText: String? = null, onClickAction: String? = null, - OnClickEditNickname: () -> Unit, + onClick: () -> Unit ) { val refreshButton = remember { mutableStateOf(false) @@ -284,8 +318,10 @@ fun MyPageProfileButton( Button( onClick = { - // 프로필 편집 버튼이 클릭되었을 때 - OnClickEditNickname + onClick() + if (onClickAction != null) { + refreshButton.value = true + } }, modifier = Modifier .padding(end = PADDING_8) @@ -318,20 +354,28 @@ fun MyPageProfileButton( fun ListButton( buttonIcon: Int? = null, buttonText: String, - onClickAction: String? = null + onClickAction: String? = null, + onClick: () -> Unit, ) { val openDialogCustom = remember { mutableStateOf(false) } - + val refreshButton = remember { + mutableStateOf(false) + } Row( modifier = Modifier .fillMaxWidth() ) { Button( - onClick = { openDialogCustom.value = true }, + onClick = { + onClick() + if (onClickAction != null) { + refreshButton.value = true + } + }, colors = ButtonDefaults.buttonColors( contentColor = Color.Unspecified, containerColor = Color.Transparent diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt index 85c8edf..6a88862 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -1,25 +1,28 @@ package com.meongmoryteam.presentation.ui.myPage -import androidx.lifecycle.SavedStateHandle import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.MyPageEvent +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.MyPageSideEffect +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.MyPageViewState import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -import com.meongmoryteam.presentation.ui.myPage.MyPageContract.* @HiltViewModel class MyPageViewModel @Inject constructor( - private val savedStateHandle: SavedStateHandle ) : BaseViewModel( MyPageViewState() ) { override fun handleEvents(event: MyPageEvent) { when (event) { + is MyPageEvent.InitMyPageScreen -> { + updateState { copy(loadState = LoadState.SUCCESS) } + } is MyPageEvent.OnClickProfileEditButtonClicked -> { sendEffect({ MyPageSideEffect.NavigateToEditProfile }) } - is MyPageEvent.OnClickQuestionButtonClicked -> { + is MyPageEvent.OnQuestionClicked -> { sendEffect({ MyPageSideEffect.NavigateToQuestion }) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index d4c67af..7dc51cb 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -47,7 +47,10 @@ val PADDING_24 = 24.dp @Composable fun MyPageProfileScreen( + viewModel: MyPageProfileViewModel = hiltViewModel(), ) { + val uiState by viewModel.viewState.collectAsState() + Column( modifier = Modifier .fillMaxHeight() diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index 42911a1..fc7494a 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -13,7 +13,6 @@ import javax.inject.Inject @HiltViewModel class MyPageProfileViewModel @Inject constructor( - private val saveStateHandle: SavedStateHandle, ) : BaseViewModel( MyPageProfileViewState() ) { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt index 9c10b10..179893f 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -1,17 +1,17 @@ package com.meongmoryteam.presentation.ui.myPage.question -import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.MyPageQuestionEvent +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.MyPageQuestionSideEffect +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.MyPageQuestionViewState import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.* import kotlinx.coroutines.launch +import javax.inject.Inject @HiltViewModel class MyPageQuestionViewModel @Inject constructor( - private val savedStateHandle: SavedStateHandle ) : BaseViewModel( MyPageQuestionViewState() ) { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt b/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt new file mode 100644 index 0000000..6a7c402 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt @@ -0,0 +1,14 @@ +package com.meongmoryteam.presentation.util + +import androidx.activity.ComponentActivity +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewmodel.compose.viewModel + +@Composable +fun getActivity() = LocalContext.current as ComponentActivity + +@Composable +inline fun composableActivityViewModel( +) : VM = viewModel(getActivity()) \ No newline at end of file From 127fa058d3a7777df6b6765c700cfec3fd21afd7 Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 17:16:34 +0900 Subject: [PATCH 08/37] =?UTF-8?q?[refactor/mypage]=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=88=98=EC=A0=95,=20=EC=95=A1?= =?UTF-8?q?=ED=8B=B0=EB=B9=84=ED=8B=B0=20=EC=82=AD=EC=A0=9C=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/myPage/MyPageScreen.kt | 8 +++++++- .../ui/myPage/profile/MyPageProfileActivity.kt | 17 ----------------- .../ui/myPage/profile/MyPageProfileScreen.kt | 7 ++++--- .../myPage/question/MyPageQuestionActivity.kt | 14 -------------- .../ui/myPage/question/MyPageQuestionScreen.kt | 5 +++-- 5 files changed, 14 insertions(+), 37 deletions(-) delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 4824bb4..e7dbf4a 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -372,6 +372,7 @@ fun ListButton( Button( onClick = { onClick() + openDialogCustom.value = true if (onClickAction != null) { refreshButton.value = true } @@ -404,7 +405,12 @@ fun ListButton( contentAlignment = Alignment.CenterEnd ) { Button( - onClick = { openDialogCustom.value = true }, + onClick = { + onClick() + openDialogCustom.value = true + if (onClickAction != null) { + refreshButton.value = true + }}, colors = ButtonDefaults.buttonColors(Color.Transparent, ListNextButton) ) { Icon( diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt deleted file mode 100644 index 5740b96..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.meongmoryteam.presentation.ui.myPage.profile - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import dagger.hilt.android.AndroidEntryPoint - - -@AndroidEntryPoint -class MyPageProfileActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - MyPageProfileScreen() - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 7dc51cb..b204440 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.material3.Button @@ -212,12 +213,12 @@ fun ProfileChangeButton( modifier = Modifier .padding(16.dp) .fillMaxWidth() - .height(45.dp), - shape = RoundedCornerShape(10.dp) + .wrapContentHeight(), + shape = RoundedCornerShape(10.dp), ) { Text( text = stringResource(R.string.profile_change_button), - fontSize = 15.sp + fontSize = 15.sp, ) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt deleted file mode 100644 index 0d81010..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.meongmoryteam.presentation.ui.myPage.question - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent - -class MyPageQuestionActivity: ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - MyPageQuestionScreen() - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index fba2770..181b802 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.material3.Button @@ -241,13 +242,13 @@ fun QuestionButton( modifier = Modifier .padding(16.dp) .fillMaxWidth() - .height(45.dp), + .wrapContentHeight(), shape = RoundedCornerShape(10.dp) ) { Text( text = stringResource(R.string.question_button), color = QuestionButtonText, - fontSize = 15.sp + fontSize = 15.sp, ) } } From 6b427f6b5d69621de09cff069d15b45bc7c27e7e Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 17:50:14 +0900 Subject: [PATCH 09/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=8E=B8=EC=A7=91,=20=EB=AC=B8=EC=9D=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=98=A4=EB=A5=98=EC=A0=9C=EB=B3=B4=20?= =?UTF-8?q?=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/HomeScreen.kt | 8 ++- .../myPage/profile/MyPageProfileContract.kt | 3 +- .../ui/myPage/profile/MyPageProfileScreen.kt | 51 +++++++++++++++++-- .../myPage/profile/MyPageProfileViewModel.kt | 7 +-- .../myPage/question/MyPageQuestionScreen.kt | 29 +++++++++-- 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt index 0e58ccf..5f6f2ba 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt @@ -68,10 +68,14 @@ fun MainScreen( ) } composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { - MyPageProfileScreen() + MyPageProfileScreen( + navigateToPrevious = { navController.navigate(MeongMoryRoute.MY_PAGE.route) } + ) } composable(route = MeongMoryRoute.QUESTION.route) { - MyPageQuestionScreen() + MyPageQuestionScreen( + navigateToPrevious = { navController.navigate(MeongMoryRoute.MY_PAGE.route)} + ) } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 76a6e67..5244b89 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -10,11 +10,12 @@ class MyPageProfileContract { data class MyPageProfileViewState( val loadState: LoadState = LoadState.SUCCESS, val nickName: String = "", + val nickNameHint: String = "", val isError: Boolean = true ) : ViewState sealed class MyPageProfileSideEffect: ViewSideEffect { - object NavigateToHome : MyPageProfileSideEffect() + object NavigateToPrevious : MyPageProfileSideEffect() } sealed class MyPageProfileEvent: ViewEvent { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index b204440..d28508e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -1,6 +1,7 @@ package com.meongmoryteam.presentation.ui.myPage.profile import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -18,6 +19,7 @@ import androidx.compose.material3.Divider import androidx.compose.material3.Icon 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 @@ -26,6 +28,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle @@ -42,6 +45,7 @@ import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme +import kotlinx.coroutines.flow.collect val PADDING_16 = 16.dp val PADDING_24 = 24.dp @@ -49,9 +53,13 @@ val PADDING_24 = 24.dp @Composable fun MyPageProfileScreen( viewModel: MyPageProfileViewModel = hiltViewModel(), + navigateToPrevious: () -> Unit, ) { val uiState by viewModel.viewState.collectAsState() - + // refreshButton 상태 + val refreshButton = remember { + mutableStateOf(false) + } Column( modifier = Modifier .fillMaxHeight() @@ -66,7 +74,13 @@ fun MyPageProfileScreen( modifier = Modifier.fillMaxHeight(), Arrangement.spacedBy(150.dp) ) { - MyPageToolBar(stringResource(R.string.profile_change_title)) + MyPageToolBar( + stringResource(R.string.profile_change_title), + onBackClick = { + navigateToPrevious + refreshButton.value = true + }, + ) ProfileChangeEdit() } Column( @@ -77,13 +91,24 @@ fun MyPageProfileScreen( } } } + + // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 + LaunchedEffect(refreshButton.value) { + if (refreshButton.value) { + navigateToPrevious() + } + } } @Composable fun MyPageToolBar( - title: String + title: String, + onBackClick: () -> Unit, ) { + val refreshButton = remember { + mutableStateOf(false) + } Column() { // 위 아래 여백 Row( @@ -101,10 +126,16 @@ fun MyPageToolBar( .height(24.dp) .fillMaxWidth() ) { + Icon( imageVector = ImageVector.vectorResource(R.drawable.ic_left_btn), contentDescription = stringResource(R.string.profile_back_btn_description), - modifier = Modifier.padding(start = PADDING_16), + modifier = Modifier + .padding(start = PADDING_16) + .clickable { + onBackClick() + refreshButton.value = true + } ) } Text( @@ -118,9 +149,16 @@ fun MyPageToolBar( ) } + // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 + LaunchedEffect(refreshButton.value) { + if (refreshButton.value) { + onBackClick() + } + } } + @Composable fun ProfileChangeLabel() { Box( @@ -227,6 +265,9 @@ fun ProfileChangeButton( @Composable fun PreviewProfileScreen() { MeongmoryTheme { - MyPageProfileScreen() + MyPageProfileScreen( + viewModel = MyPageProfileViewModel(), + navigateToPrevious = { } + ) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index fc7494a..b0f8487 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -36,11 +36,8 @@ class MyPageProfileViewModel @Inject constructor( } private fun changeNickName(nickName: String) = viewModelScope.launch { - updateState { - copy( - loadState = LoadState.LOADING - ) - } + updateState { copy( loadState = LoadState.SUCCESS) } + sendEffect({ MyPageProfileSideEffect.NavigateToPrevious }) } // 텍스트 길이 초과 diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index 181b802..4ccc49e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon 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 @@ -37,6 +38,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileViewModel import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditStroke @@ -52,14 +54,26 @@ val PADDING_24 = 24.dp @Composable -fun MyPageQuestionScreen() { +fun MyPageQuestionScreen( + viewModel: MyPageProfileViewModel = hiltViewModel(), + navigateToPrevious: () -> Unit, +) { + val refreshButton = remember { + mutableStateOf(false) + } Column( modifier = Modifier .fillMaxHeight() .fillMaxWidth(), verticalArrangement = Arrangement.Top, ) { - MyPageToolBar(stringResource(R.string.question_title)) + MyPageToolBar( + stringResource(R.string.question_title), + onBackClick = { + navigateToPrevious + refreshButton.value = true + } + ) Spacer(modifier = Modifier.padding(PADDING_8)) EmailEdit() Column( @@ -73,7 +87,12 @@ fun MyPageQuestionScreen() { ) { QuestionButton() } - + } + // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 + LaunchedEffect(refreshButton.value) { + if (refreshButton.value) { + navigateToPrevious() + } } } @@ -257,6 +276,8 @@ fun QuestionButton( @Composable fun PreviewQuestionScreen() { MeongmoryTheme { - MyPageQuestionScreen() + MyPageQuestionScreen( + navigateToPrevious = { } + ) } } From 3387121348797ee12aff226cc589c818c6a3bcfb Mon Sep 17 00:00:00 2001 From: arinming Date: Fri, 11 Aug 2023 10:44:17 +0900 Subject: [PATCH 10/37] =?UTF-8?q?[refactor/mypage]=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=85=EB=A0=A5=EC=8B=9C=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=95=84=EB=93=9C=20=EC=83=89=EC=83=81=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/myPage/profile/MyPageProfileScreen.kt | 24 +++++++++++++++-- .../myPage/question/MyPageQuestionScreen.kt | 27 +++++++++++++++---- .../presentation/ui/theme/Color.kt | 4 +++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index d28508e..fadbce3 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -1,5 +1,6 @@ package com.meongmoryteam.presentation.ui.myPage.profile +import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -27,6 +28,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource @@ -41,6 +43,8 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.theme.EditButtonFalse +import com.meongmoryteam.presentation.ui.theme.EditChangeFill +import com.meongmoryteam.presentation.ui.theme.EditChangeStroke import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText @@ -201,15 +205,24 @@ fun ProfileChangeEdit( @Composable -fun MyPageEditForm() { +fun MyPageEditForm( +) { var text by remember { mutableStateOf("") } + var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 + Box( modifier = Modifier .padding(PADDING_16) .fillMaxWidth() .height(48.dp) + .background( + if (isTextEmpty) Color.White + else EditChangeFill + ) .border( - color = EditStroke, + color = + if (isTextEmpty) EditStroke + else EditChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp) ), @@ -220,6 +233,7 @@ fun MyPageEditForm() { onValueChange = { newText -> // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 text = newText.replace(Regex("[\n]"), "") + isTextEmpty = newText.isBlank() // Text가 비어있는지 여부 업데이트 }, textStyle = TextStyle( fontSize = 14.sp, @@ -243,6 +257,11 @@ fun ProfileChangeButton( viewModel: MyPageProfileViewModel = hiltViewModel() ) { val uiState by viewModel.viewState.collectAsState() + + val buttonColors = ButtonDefaults.buttonColors( + contentColor = Color.White + ) + Button( onClick = { viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) @@ -261,6 +280,7 @@ fun ProfileChangeButton( } } + @Preview(showBackground = true) @Composable fun PreviewProfileScreen() { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index 4ccc49e..c7905ba 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -45,6 +45,8 @@ import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.QuestionButtonText +import com.meongmoryteam.presentation.ui.theme.QuestionChangeFill +import com.meongmoryteam.presentation.ui.theme.QuestionChangeStroke import com.meongmoryteam.presentation.ui.theme.QuestionEditFill import com.meongmoryteam.presentation.ui.theme.QuestionSubTitle @@ -133,17 +135,23 @@ fun QuestionLabel( @Composable fun EmailForm() { var email by remember { mutableStateOf("") } + var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 + Box( modifier = Modifier .padding(all = PADDING_16) .height(48.dp) .fillMaxWidth(0.5f) .border( - color = EditStroke, + color = if (isTextEmpty) EditStroke + else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) - .background(color = QuestionEditFill, shape = RoundedCornerShape(10.dp)), + .background( + color = if (isTextEmpty) QuestionEditFill + else QuestionChangeFill, + shape = RoundedCornerShape(10.dp)), contentAlignment = Alignment.CenterStart // 정렬 ) { @@ -152,6 +160,7 @@ fun EmailForm() { onValueChange = { newText -> // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 email = newText.replace(Regex("[\n]"), "") + isTextEmpty = newText.isBlank() }, textStyle = TextStyle( fontSize = 14.sp, @@ -211,16 +220,22 @@ fun DetailEdit() { @Composable fun DetailForm() { var detail by remember { mutableStateOf("") } + var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 + Box( modifier = Modifier .padding(PADDING_16) .fillMaxSize() .border( - color = EditStroke, + color = if (isTextEmpty) EditStroke + else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) - .background(color = QuestionEditFill, shape = RoundedCornerShape(10.dp)), + .background( + color = if (isTextEmpty) QuestionEditFill + else QuestionChangeFill, + shape = RoundedCornerShape(10.dp)), contentAlignment = Alignment.TopStart // 정렬 ) { @@ -229,12 +244,14 @@ fun DetailForm() { onValueChange = { newText -> // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 detail = newText + isTextEmpty = newText.isBlank() }, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start ), - modifier = Modifier.padding(PADDING_16) + modifier = Modifier + .padding(PADDING_16) ) if (detail.isEmpty()) { Text( diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt index 63a9bc0..8c632a2 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt @@ -42,6 +42,10 @@ val EditText = Color(0xFF737373) val EditStroke = Color(0xFFE7E7E7) val EditButtonFalse = Color(0xFFD9D9D9) val EditDivider = Color(0xFF757575) +val EditChangeStroke = Color(0xFFBEB7AD) +val EditChangeFill = Color(0xFFF5F4F2) +val EditChangeButtonFill = Color(0xFF3C270A) + // 문의 및 오류 제보 색상 val QuestionSubTitle = Color(0xFF454545) From c521aca2d029c192bc6c8bc4337224750d33c77e Mon Sep 17 00:00:00 2001 From: arinming Date: Fri, 11 Aug 2023 12:02:34 +0900 Subject: [PATCH 11/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EB=B3=80=EA=B2=BD,=20=EB=AC=B8=EC=9D=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=A0=9C=EB=B3=B4=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?ViewModel=EB=A1=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../myPage/profile/MyPageProfileContract.kt | 3 +- .../ui/myPage/profile/MyPageProfileScreen.kt | 55 +++++++----- .../myPage/profile/MyPageProfileViewModel.kt | 14 ++- .../question/MyPageQuestionConstract.kt | 9 +- .../myPage/question/MyPageQuestionScreen.kt | 90 +++++++++++-------- .../question/MyPageQuestionViewModel.kt | 21 ++++- 6 files changed, 124 insertions(+), 68 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 5244b89..9c8e6b9 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -11,11 +11,12 @@ class MyPageProfileContract { val loadState: LoadState = LoadState.SUCCESS, val nickName: String = "", val nickNameHint: String = "", + val isFilled: Boolean = false, val isError: Boolean = true ) : ViewState sealed class MyPageProfileSideEffect: ViewSideEffect { - object NavigateToPrevious : MyPageProfileSideEffect() + object NavigateToPreviousScreen : MyPageProfileSideEffect() } sealed class MyPageProfileEvent: ViewEvent { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index fadbce3..c9d5f5e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -35,20 +35,25 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.ui.theme.ButtonContent import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditChangeFill import com.meongmoryteam.presentation.ui.theme.EditChangeStroke import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme +import com.meongmoryteam.presentation.ui.theme.Orange import kotlinx.coroutines.flow.collect val PADDING_16 = 16.dp @@ -83,7 +88,7 @@ fun MyPageProfileScreen( onBackClick = { navigateToPrevious refreshButton.value = true - }, + } ) ProfileChangeEdit() } @@ -91,7 +96,9 @@ fun MyPageProfileScreen( Modifier.fillMaxHeight(), Arrangement.Bottom ) { - ProfileChangeButton() + ProfileChangeButton( + isFilled = uiState.isFilled + ) } } } @@ -195,10 +202,17 @@ fun ProfileChangeExplain() { @Composable fun ProfileChangeEdit( + viewModel: MyPageProfileViewModel = hiltViewModel() ) { + val uiState by viewModel.viewState.collectAsState() Column { ProfileChangeLabel() - MyPageEditForm() + MyPageEditForm( + value = uiState.nickName, + isOverflow = uiState.isError + ) { + viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.FillNickName(it)) + } ProfileChangeExplain() } } @@ -206,22 +220,23 @@ fun ProfileChangeEdit( @Composable fun MyPageEditForm( + value: String, + isOverflow: Boolean, + onValueChange: (String) -> Unit, ) { - var text by remember { mutableStateOf("") } - var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 - Box( modifier = Modifier .padding(PADDING_16) .fillMaxWidth() .height(48.dp) .background( - if (isTextEmpty) Color.White + if (value.isEmpty()) Color.White else EditChangeFill ) .border( color = - if (isTextEmpty) EditStroke + if (value.isEmpty()) EditStroke + else if (isOverflow) Color.Red else EditChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp) @@ -229,12 +244,8 @@ fun MyPageEditForm( contentAlignment = Alignment.CenterStart // 정렬 ) { BasicTextField( - value = text, - onValueChange = { newText -> - // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 - text = newText.replace(Regex("[\n]"), "") - isTextEmpty = newText.isBlank() // Text가 비어있는지 여부 업데이트 - }, + value = value, + onValueChange = onValueChange, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start @@ -242,7 +253,7 @@ fun MyPageEditForm( modifier = Modifier.padding(start = PADDING_16, end = PADDING_16) ) - if (text.isEmpty()) { + if (value.isEmpty()) { Text( text = stringResource(R.string.profile_now_nickname), color = EditText, @@ -254,19 +265,18 @@ fun MyPageEditForm( @Composable fun ProfileChangeButton( + isFilled: Boolean, viewModel: MyPageProfileViewModel = hiltViewModel() ) { - val uiState by viewModel.viewState.collectAsState() - - val buttonColors = ButtonDefaults.buttonColors( - contentColor = Color.White - ) - Button( onClick = { viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) }, - colors = ButtonDefaults.buttonColors(EditButtonFalse), + colors = if (!isFilled) { + ButtonDefaults.textButtonColors(LightGrey) + } else { + ButtonDefaults.textButtonColors(Orange) + }, modifier = Modifier .padding(16.dp) .fillMaxWidth() @@ -276,6 +286,7 @@ fun ProfileChangeButton( Text( text = stringResource(R.string.profile_change_button), fontSize = 15.sp, + color = ButtonContent ) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index b0f8487..c76c93f 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -1,6 +1,5 @@ package com.meongmoryteam.presentation.ui.myPage.profile -import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState @@ -18,7 +17,7 @@ class MyPageProfileViewModel @Inject constructor( ) { override fun handleEvents(event: MyPageProfileEvent) { when (event) { - MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") + is MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") is MyPageProfileEvent.FillNickName -> reflectUpdatedState(event.nickName) MyPageProfileEvent.OnClickChangeButton -> changeNickName(viewState.value.nickName) } @@ -30,20 +29,27 @@ class MyPageProfileViewModel @Inject constructor( updateState { copy( nickName = nickName, - isError = isOverflowed(nickName) + isError = isOverflowed(nickName), + isFilled = isFilled(nickName) ) } } private fun changeNickName(nickName: String) = viewModelScope.launch { updateState { copy( loadState = LoadState.SUCCESS) } - sendEffect({ MyPageProfileSideEffect.NavigateToPrevious }) + sendEffect({ MyPageProfileSideEffect.NavigateToPreviousScreen }) } // 텍스트 길이 초과 private fun isOverflowed(nickName: String): Boolean { return nickName.isBlank() || (nickName.length > MAX_LENGTH_NICKNAME) } + + private fun isFilled( + nickName: String + ) : Boolean { + return (nickName.isNotEmpty()) + } } const val MAX_LENGTH_NICKNAME = 6 diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt index 1553182..8c02ca2 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt @@ -10,18 +10,23 @@ class MyPageQuestionConstract { val loadState: LoadState = LoadState.SUCCESS, val email: String = "", val question: String = "", - val isError: Boolean = true + val isError: Boolean = true, + val isAllFilled: Boolean = false, ) : ViewState sealed class MyPageQuestionSideEffect: ViewSideEffect { - object NavigateToHome : MyPageQuestionSideEffect() + object NavigateToPreviousScreen : MyPageQuestionSideEffect() } sealed class MyPageQuestionEvent: ViewEvent { data class FillEmail( val email: String ): MyPageQuestionEvent() + data class FillQuestion( + val question: String + ): MyPageQuestionEvent() object ClearEmail: MyPageQuestionEvent() + object ClearQuestion: MyPageQuestionEvent() object OnClickButton: MyPageQuestionEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index c7905ba..9c61ca7 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -43,8 +43,11 @@ import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme +import com.meongmoryteam.presentation.ui.theme.Orange import com.meongmoryteam.presentation.ui.theme.QuestionButtonText +import com.meongmoryteam.presentation.ui.theme.QuestionChangeButtonFill import com.meongmoryteam.presentation.ui.theme.QuestionChangeFill import com.meongmoryteam.presentation.ui.theme.QuestionChangeStroke import com.meongmoryteam.presentation.ui.theme.QuestionEditFill @@ -52,14 +55,14 @@ import com.meongmoryteam.presentation.ui.theme.QuestionSubTitle val PADDING_8 = 8.dp val PADDING_16 = 16.dp -val PADDING_24 = 24.dp @Composable fun MyPageQuestionScreen( - viewModel: MyPageProfileViewModel = hiltViewModel(), + viewModel: MyPageQuestionViewModel = hiltViewModel(), navigateToPrevious: () -> Unit, ) { + val uiState by viewModel.viewState.collectAsState() val refreshButton = remember { mutableStateOf(false) } @@ -87,7 +90,9 @@ fun MyPageQuestionScreen( modifier = Modifier.fillMaxHeight(), contentAlignment = Alignment.BottomCenter ) { - QuestionButton() + QuestionButton( + isAllFilled = uiState.isAllFilled + ) } } // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 @@ -99,14 +104,21 @@ fun MyPageQuestionScreen( } @Composable -fun EmailEdit() { +fun EmailEdit( + viewModel: MyPageQuestionViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() Column { QuestionLabel(stringResource(R.string.question_email_form_title)) Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, ) { - EmailForm() + EmailForm( + value = uiState.email + ) { + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.FillEmail(it)) + } Text(text = stringResource(R.string.question_at)) EmailSelect() } @@ -133,35 +145,32 @@ fun QuestionLabel( @Composable -fun EmailForm() { - var email by remember { mutableStateOf("") } - var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 - +fun EmailForm( + value: String, + onValueChange: (String) -> Unit +) { Box( modifier = Modifier .padding(all = PADDING_16) .height(48.dp) .fillMaxWidth(0.5f) .border( - color = if (isTextEmpty) EditStroke + color = if (value.isEmpty()) EditStroke else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) .background( - color = if (isTextEmpty) QuestionEditFill + color = if (value.isEmpty()) QuestionEditFill else QuestionChangeFill, - shape = RoundedCornerShape(10.dp)), + shape = RoundedCornerShape(10.dp) + ), contentAlignment = Alignment.CenterStart // 정렬 ) { BasicTextField( - value = email, - onValueChange = { newText -> - // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 - email = newText.replace(Regex("[\n]"), "") - isTextEmpty = newText.isBlank() - }, + value = value, + onValueChange = onValueChange, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start @@ -169,7 +178,7 @@ fun EmailForm() { modifier = Modifier.padding(start = PADDING_16, end = PADDING_16) ) - if (email.isEmpty()) { + if (value.isEmpty()) { Text( text = stringResource(R.string.question_email_form_hint), color = EditText, @@ -212,40 +221,44 @@ fun EmailSelect() { @Composable -fun DetailEdit() { +fun DetailEdit( + viewModel: MyPageQuestionViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() QuestionLabel(stringResource(R.string.question_content_title)) - DetailForm() + DetailForm( + value = uiState.question + ) { + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.FillQuestion(it)) + } } @Composable -fun DetailForm() { - var detail by remember { mutableStateOf("") } - var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 - +fun DetailForm( + value: String, + onValueChange: (String) -> Unit +) { Box( modifier = Modifier .padding(PADDING_16) .fillMaxSize() .border( - color = if (isTextEmpty) EditStroke + color = if (value.isEmpty()) EditStroke else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) .background( - color = if (isTextEmpty) QuestionEditFill + color = if (value.isEmpty()) QuestionEditFill else QuestionChangeFill, - shape = RoundedCornerShape(10.dp)), + shape = RoundedCornerShape(10.dp) + ), contentAlignment = Alignment.TopStart // 정렬 ) { BasicTextField( - value = detail, - onValueChange = { newText -> - // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 - detail = newText - isTextEmpty = newText.isBlank() - }, + value = value, + onValueChange = onValueChange, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start @@ -253,7 +266,7 @@ fun DetailForm() { modifier = Modifier .padding(PADDING_16) ) - if (detail.isEmpty()) { + if (value.isEmpty()) { Text( text = stringResource(R.string.question_content_detail), color = EditText, @@ -267,6 +280,7 @@ fun DetailForm() { @Composable fun QuestionButton( + isAllFilled: Boolean, viewModel: MyPageQuestionViewModel = hiltViewModel() ) { val uiState by viewModel.viewState.collectAsState() @@ -274,7 +288,11 @@ fun QuestionButton( onClick = { viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickButton) }, - colors = ButtonDefaults.buttonColors(EditButtonFalse), + colors = if (!isAllFilled) { + ButtonDefaults.textButtonColors(LightGrey) + } else { + ButtonDefaults.textButtonColors(QuestionChangeButtonFill) + }, modifier = Modifier .padding(16.dp) .fillMaxWidth() diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt index 179893f..83f2736 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -17,18 +17,26 @@ class MyPageQuestionViewModel @Inject constructor( ) { override fun handleEvents(event: MyPageQuestionEvent) { when (event) { - MyPageQuestionEvent.ClearEmail -> reflectUpdatedState("") - is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(event.email) + MyPageQuestionEvent.ClearEmail -> reflectUpdatedState(email = "") + MyPageQuestionEvent.ClearQuestion -> reflectUpdatedState(question = "") + is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(email = event.email) + is MyPageQuestionEvent.FillQuestion -> reflectUpdatedState(question = event.question) MyPageQuestionEvent.OnClickButton -> setEmail(viewState.value.email) } } private fun reflectUpdatedState( - email: String = viewState.value.email + email: String = viewState.value.email, + question: String = viewState.value.question ) { updateState { copy( email = email, + question = question, + isAllFilled = isFilled( + email, + question + ) ) } } @@ -40,4 +48,11 @@ class MyPageQuestionViewModel @Inject constructor( ) } } + + private fun isFilled( + email: String, + question: String, + ): Boolean { + return (email.isNotEmpty() && question.isNotEmpty()) + } } \ No newline at end of file From 1820af58c12154f29a88f63471db65214e789569 Mon Sep 17 00:00:00 2001 From: arinming Date: Fri, 11 Aug 2023 12:08:35 +0900 Subject: [PATCH 12/37] =?UTF-8?q?[refactor/mypage]=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/myPage/MyPageContract.kt | 12 ++++----- .../presentation/ui/myPage/MyPageScreen.kt | 26 ++----------------- .../presentation/ui/myPage/MyPageViewModel.kt | 2 ++ .../myPage/profile/MyPageProfileContract.kt | 9 ++++--- .../ui/myPage/profile/MyPageProfileScreen.kt | 18 ++++--------- .../myPage/profile/MyPageProfileViewModel.kt | 8 +++--- .../question/MyPageQuestionConstract.kt | 16 +++++++----- .../myPage/question/MyPageQuestionScreen.kt | 6 ----- .../question/MyPageQuestionViewModel.kt | 4 +-- 9 files changed, 35 insertions(+), 66 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt index 63c6eb3..133a348 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -12,14 +12,14 @@ class MyPageContract { val isDialogVisible: Boolean = false ) : ViewState - sealed class MyPageSideEffect: ViewSideEffect { - object NavigateToEditProfile: MyPageSideEffect() - object NavigateToQuestion: MyPageSideEffect() + sealed class MyPageSideEffect : ViewSideEffect { + object NavigateToEditProfile : MyPageSideEffect() + object NavigateToQuestion : MyPageSideEffect() } - sealed class MyPageEvent: ViewEvent { + sealed class MyPageEvent : ViewEvent { object InitMyPageScreen : MyPageEvent() - object OnClickProfileEditButtonClicked: MyPageEvent() - object OnQuestionClicked: MyPageEvent() + object OnClickProfileEditButtonClicked : MyPageEvent() + object OnQuestionClicked : MyPageEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index e7dbf4a..fe60213 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -126,7 +126,6 @@ fun MyPageTitle() { text = stringResource(R.string.my_page_title), fontSize = 15.sp ) - } } @@ -177,8 +176,6 @@ fun MyPageProfile( onClick = OnClickEditNickname ) } - - } Text( modifier = Modifier.padding(bottom = 8.dp), @@ -186,10 +183,7 @@ fun MyPageProfile( fontSize = 10.sp ) } - } - - } } @@ -198,7 +192,6 @@ fun MyPageProfile( fun MyPageList( onQuestionClicked: () -> Unit, ) { - // 마이페이지 목록 부분 Row( modifier = Modifier @@ -218,7 +211,6 @@ fun MyPageList( color = ListTitle, fontSize = 11.sp ) - ListButton( R.drawable.ic_coin, stringResource(R.string.my_page_pro_ver), @@ -248,7 +240,6 @@ fun MyPageList( .padding(start = 24.dp, end = 24.dp) ) - Text( text = stringResource(R.string.my_page_support), fontWeight = FontWeight.Bold, @@ -268,7 +259,6 @@ fun MyPageList( onClick = onQuestionClicked, ) - Spacer(modifier = Modifier.padding(top = PADDING_16)) // 구분선 @@ -297,12 +287,8 @@ fun MyPageList( stringResource(R.string.my_page_personal), onClick = { }, ) - } - - } - } @Composable @@ -315,7 +301,6 @@ fun MyPageProfileButton( mutableStateOf(false) } Column(modifier = Modifier) { - Button( onClick = { onClick() @@ -329,7 +314,6 @@ fun MyPageProfileButton( contentPadding = PaddingValues(4.dp), colors = ButtonDefaults.buttonColors(MyPageProfileEditButton, Color.Black) ) { - if (buttonText != null) { Text( text = buttonText, @@ -357,14 +341,12 @@ fun ListButton( onClickAction: String? = null, onClick: () -> Unit, ) { - val openDialogCustom = remember { mutableStateOf(false) } val refreshButton = remember { mutableStateOf(false) } - Row( modifier = Modifier .fillMaxWidth() @@ -397,7 +379,6 @@ fun ListButton( fontSize = 12.sp ) } - Box( modifier = Modifier .padding() @@ -410,7 +391,8 @@ fun ListButton( openDialogCustom.value = true if (onClickAction != null) { refreshButton.value = true - }}, + } + }, colors = ButtonDefaults.buttonColors(Color.Transparent, ListNextButton) ) { Icon( @@ -420,19 +402,15 @@ fun ListButton( } } } - // 버튼마다 다른 다이어로그 if (openDialogCustom.value) { if (onClickAction == stringResource(R.string.my_page_logout)) { LogoutAlertDialog(openDialogCustom = openDialogCustom) } - if (onClickAction == stringResource(R.string.my_page_drop)) { SecessionAlertDialog(openDialogCustom = openDialogCustom) } - } - } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt index 6a88862..3242535 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -19,9 +19,11 @@ class MyPageViewModel @Inject constructor( is MyPageEvent.InitMyPageScreen -> { updateState { copy(loadState = LoadState.SUCCESS) } } + is MyPageEvent.OnClickProfileEditButtonClicked -> { sendEffect({ MyPageSideEffect.NavigateToEditProfile }) } + is MyPageEvent.OnQuestionClicked -> { sendEffect({ MyPageSideEffect.NavigateToQuestion }) } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 9c8e6b9..2887f82 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -15,15 +15,16 @@ class MyPageProfileContract { val isError: Boolean = true ) : ViewState - sealed class MyPageProfileSideEffect: ViewSideEffect { + sealed class MyPageProfileSideEffect : ViewSideEffect { object NavigateToPreviousScreen : MyPageProfileSideEffect() } - sealed class MyPageProfileEvent: ViewEvent { + sealed class MyPageProfileEvent : ViewEvent { data class FillNickName( val nickName: String ) : MyPageProfileEvent() - object ClearNickName: MyPageProfileEvent() - object OnClickChangeButton: MyPageProfileEvent() + + object ClearNickName : MyPageProfileEvent() + object OnClickChangeButton : MyPageProfileEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index c9d5f5e..f953443 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -25,27 +25,20 @@ import androidx.compose.runtime.collectAsState 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.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.viewmodel.compose.viewModel -import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.theme.ButtonContent -import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditChangeFill import com.meongmoryteam.presentation.ui.theme.EditChangeStroke import com.meongmoryteam.presentation.ui.theme.EditDivider @@ -54,7 +47,6 @@ import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.Orange -import kotlinx.coroutines.flow.collect val PADDING_16 = 16.dp val PADDING_24 = 24.dp @@ -86,7 +78,6 @@ fun MyPageProfileScreen( MyPageToolBar( stringResource(R.string.profile_change_title), onBackClick = { - navigateToPrevious refreshButton.value = true } ) @@ -97,7 +88,8 @@ fun MyPageProfileScreen( Arrangement.Bottom ) { ProfileChangeButton( - isFilled = uiState.isFilled + isFilled = uiState.isFilled, + isOverflow = uiState.isError ) } } @@ -120,7 +112,7 @@ fun MyPageToolBar( val refreshButton = remember { mutableStateOf(false) } - Column() { + Column { // 위 아래 여백 Row( modifier = Modifier @@ -169,7 +161,6 @@ fun MyPageToolBar( } - @Composable fun ProfileChangeLabel() { Box( @@ -266,13 +257,14 @@ fun MyPageEditForm( @Composable fun ProfileChangeButton( isFilled: Boolean, + isOverflow: Boolean, viewModel: MyPageProfileViewModel = hiltViewModel() ) { Button( onClick = { viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) }, - colors = if (!isFilled) { + colors = if (!isFilled || isOverflow) { ButtonDefaults.textButtonColors(LightGrey) } else { ButtonDefaults.textButtonColors(Orange) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index c76c93f..280b3d9 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -19,7 +19,7 @@ class MyPageProfileViewModel @Inject constructor( when (event) { is MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") is MyPageProfileEvent.FillNickName -> reflectUpdatedState(event.nickName) - MyPageProfileEvent.OnClickChangeButton -> changeNickName(viewState.value.nickName) + MyPageProfileEvent.OnClickChangeButton -> changeNickName() } } @@ -35,8 +35,8 @@ class MyPageProfileViewModel @Inject constructor( } } - private fun changeNickName(nickName: String) = viewModelScope.launch { - updateState { copy( loadState = LoadState.SUCCESS) } + private fun changeNickName() = viewModelScope.launch { + updateState { copy(loadState = LoadState.SUCCESS) } sendEffect({ MyPageProfileSideEffect.NavigateToPreviousScreen }) } @@ -47,7 +47,7 @@ class MyPageProfileViewModel @Inject constructor( private fun isFilled( nickName: String - ) : Boolean { + ): Boolean { return (nickName.isNotEmpty()) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt index 8c02ca2..9669acb 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt @@ -14,19 +14,21 @@ class MyPageQuestionConstract { val isAllFilled: Boolean = false, ) : ViewState - sealed class MyPageQuestionSideEffect: ViewSideEffect { + sealed class MyPageQuestionSideEffect : ViewSideEffect { object NavigateToPreviousScreen : MyPageQuestionSideEffect() } - sealed class MyPageQuestionEvent: ViewEvent { + sealed class MyPageQuestionEvent : ViewEvent { data class FillEmail( val email: String - ): MyPageQuestionEvent() + ) : MyPageQuestionEvent() + data class FillQuestion( val question: String - ): MyPageQuestionEvent() - object ClearEmail: MyPageQuestionEvent() - object ClearQuestion: MyPageQuestionEvent() - object OnClickButton: MyPageQuestionEvent() + ) : MyPageQuestionEvent() + + object ClearEmail : MyPageQuestionEvent() + object ClearQuestion : MyPageQuestionEvent() + object OnClickButton : MyPageQuestionEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index 9c61ca7..7e7534b 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -25,7 +25,6 @@ import androidx.compose.runtime.collectAsState 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.graphics.vector.ImageVector @@ -38,14 +37,11 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R -import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileViewModel import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar -import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme -import com.meongmoryteam.presentation.ui.theme.Orange import com.meongmoryteam.presentation.ui.theme.QuestionButtonText import com.meongmoryteam.presentation.ui.theme.QuestionChangeButtonFill import com.meongmoryteam.presentation.ui.theme.QuestionChangeFill @@ -75,7 +71,6 @@ fun MyPageQuestionScreen( MyPageToolBar( stringResource(R.string.question_title), onBackClick = { - navigateToPrevious refreshButton.value = true } ) @@ -283,7 +278,6 @@ fun QuestionButton( isAllFilled: Boolean, viewModel: MyPageQuestionViewModel = hiltViewModel() ) { - val uiState by viewModel.viewState.collectAsState() Button( onClick = { viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickButton) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt index 83f2736..c19918c 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -21,7 +21,7 @@ class MyPageQuestionViewModel @Inject constructor( MyPageQuestionEvent.ClearQuestion -> reflectUpdatedState(question = "") is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(email = event.email) is MyPageQuestionEvent.FillQuestion -> reflectUpdatedState(question = event.question) - MyPageQuestionEvent.OnClickButton -> setEmail(viewState.value.email) + MyPageQuestionEvent.OnClickButton -> setEmail() } } @@ -41,7 +41,7 @@ class MyPageQuestionViewModel @Inject constructor( } } - private fun setEmail(email: String) = viewModelScope.launch { + private fun setEmail() = viewModelScope.launch { updateState { copy( loadState = LoadState.LOADING From b9474e4339e9c5409e1cdf4287aa0f3b64910ca8 Mon Sep 17 00:00:00 2001 From: arinming Date: Mon, 7 Aug 2023 16:48:24 +0900 Subject: [PATCH 13/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=99=94=EB=A9=B4=20ViewModel=20=EC=B4=88=EA=B8=B0?= =?UTF-8?q?=20=EC=84=B8=ED=8C=85=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/MainActivity.kt | 12 ------------ .../presentation/ui/main/MainScreen.kt | 2 -- .../myPage/profile/MyPageProfileActivity.kt | 2 +- .../myPage/profile/MyPageProfileContract.kt | 12 ++++++++++++ .../ui/myPage/profile/MyPageProfileScreen.kt | 9 ++++++--- .../myPage/profile/MyPageProfileViewModel.kt | 19 +++++++++++++++++++ 6 files changed, 38 insertions(+), 18 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index f0484c6..9ef0568 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -1,20 +1,8 @@ package com.meongmoryteam.presentation.ui.main import android.os.Bundle -import android.util.Log import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Surface -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.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt index 7270c1e..05bc7c8 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt @@ -16,9 +16,7 @@ import com.meongmoryteam.presentation.ui.bottom.MeongMoryBottomNavigation import com.meongmoryteam.presentation.ui.bottom.navigateBottomNavigationScreen import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen -import com.meongmoryteam.presentation.ui.myPage.MyPageProfileButton import com.meongmoryteam.presentation.ui.myPage.MyPageScreen -import com.meongmoryteam.presentation.ui.myPage.profile.MypageProfileScreen @Composable fun MainScreen( diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt index 33930ab..5740b96 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt @@ -11,7 +11,7 @@ class MyPageProfileActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { - MypageProfileScreen() + MyPageProfileScreen() } } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt new file mode 100644 index 0000000..5f71273 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -0,0 +1,12 @@ +package com.meongmoryteam.presentation.ui.myPage.profile + +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewState + +class MyPageProfileContract { + // 모델 클래스 + data class MyPageUiState( + val loadState: LoadState = LoadState.SUCCESS, + val nickname: String = "" + ) : ViewState +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 4d71c9c..90d83ef 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -31,18 +31,21 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R -import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme val PADDING_16 = 16.dp val PADDING_24 = 24.dp @Composable -fun MypageProfileScreen() { +fun MyPageProfileScreen( + viewModel: MyPageProfileViewModel = hiltViewModel(), +) { Column( modifier = Modifier .fillMaxHeight() @@ -213,6 +216,6 @@ fun ProfileChangeButton() { @Composable fun PreviewProfileScreen() { MeongmoryTheme { - MypageProfileScreen() + MyPageProfileScreen() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt new file mode 100644 index 0000000..e303a01 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -0,0 +1,19 @@ +package com.meongmoryteam.presentation.ui.myPage.profile + +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import javax.inject.Inject + +@HiltViewModel +class MyPageProfileViewModel @Inject constructor( + private val saveStateHandle: SavedStateHandle, +) : ViewModel() { + private val _uiState = MutableStateFlow(MyPageProfileContract.MyPageUiState()) + private lateinit var currentProfile: String + // asStateFlow() -> 변경 가능 상태 흐름을 읽기 전용 상태 흐름으로 만든다 + val uiState: StateFlow = _uiState.asStateFlow() +} \ No newline at end of file From 21fcfd5c9b5bbae31dd3e7e61440d46e46589232 Mon Sep 17 00:00:00 2001 From: arinming Date: Mon, 7 Aug 2023 19:07:00 +0900 Subject: [PATCH 14/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=99=94=EB=A9=B4=20ViewModel=20Event=20=EA=B5=AC?= =?UTF-8?q?=EC=B2=B4=ED=99=94=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../myPage/profile/MyPageProfileContract.kt | 19 ++++++- .../ui/myPage/profile/MyPageProfileScreen.kt | 14 +++-- .../myPage/profile/MyPageProfileViewModel.kt | 54 +++++++++++++++---- 3 files changed, 70 insertions(+), 17 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 5f71273..76a6e67 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -1,12 +1,27 @@ package com.meongmoryteam.presentation.ui.myPage.profile import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect import com.meongmoryteam.presentation.base.ViewState class MyPageProfileContract { // 모델 클래스 - data class MyPageUiState( + data class MyPageProfileViewState( val loadState: LoadState = LoadState.SUCCESS, - val nickname: String = "" + val nickName: String = "", + val isError: Boolean = true ) : ViewState + + sealed class MyPageProfileSideEffect: ViewSideEffect { + object NavigateToHome : MyPageProfileSideEffect() + } + + sealed class MyPageProfileEvent: ViewEvent { + data class FillNickName( + val nickName: String + ) : MyPageProfileEvent() + object ClearNickName: MyPageProfileEvent() + object OnClickChangeButton: MyPageProfileEvent() + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 90d83ef..4cab41d 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.material3.Divider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -43,9 +44,7 @@ val PADDING_16 = 16.dp val PADDING_24 = 24.dp @Composable -fun MyPageProfileScreen( - viewModel: MyPageProfileViewModel = hiltViewModel(), -) { +fun MyPageProfileScreen() { Column( modifier = Modifier .fillMaxHeight() @@ -195,9 +194,14 @@ fun MyPageEditForm() { } @Composable -fun ProfileChangeButton() { +fun ProfileChangeButton( + viewModel: MyPageProfileViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() Button( - onClick = { /*TODO*/ }, + onClick = { + viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) + }, colors = ButtonDefaults.buttonColors(EditButtonFalse), modifier = Modifier .padding(16.dp) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index e303a01..42911a1 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -1,19 +1,53 @@ package com.meongmoryteam.presentation.ui.myPage.profile import androidx.lifecycle.SavedStateHandle -import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.meongmoryteam.presentation.base.BaseViewModel +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileContract.MyPageProfileEvent +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileContract.MyPageProfileSideEffect +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileContract.MyPageProfileViewState import dagger.hilt.android.lifecycle.HiltViewModel -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch import javax.inject.Inject @HiltViewModel class MyPageProfileViewModel @Inject constructor( private val saveStateHandle: SavedStateHandle, -) : ViewModel() { - private val _uiState = MutableStateFlow(MyPageProfileContract.MyPageUiState()) - private lateinit var currentProfile: String - // asStateFlow() -> 변경 가능 상태 흐름을 읽기 전용 상태 흐름으로 만든다 - val uiState: StateFlow = _uiState.asStateFlow() -} \ No newline at end of file +) : BaseViewModel( + MyPageProfileViewState() +) { + override fun handleEvents(event: MyPageProfileEvent) { + when (event) { + MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") + is MyPageProfileEvent.FillNickName -> reflectUpdatedState(event.nickName) + MyPageProfileEvent.OnClickChangeButton -> changeNickName(viewState.value.nickName) + } + } + + private fun reflectUpdatedState( + nickName: String = viewState.value.nickName + ) { + updateState { + copy( + nickName = nickName, + isError = isOverflowed(nickName) + ) + } + } + + private fun changeNickName(nickName: String) = viewModelScope.launch { + updateState { + copy( + loadState = LoadState.LOADING + ) + } + } + + // 텍스트 길이 초과 + private fun isOverflowed(nickName: String): Boolean { + return nickName.isBlank() || (nickName.length > MAX_LENGTH_NICKNAME) + } +} + +const val MAX_LENGTH_NICKNAME = 6 From 91c0e69732ecb209fc70d02e91e9ae4955c91fde Mon Sep 17 00:00:00 2001 From: arinming Date: Tue, 8 Aug 2023 17:21:05 +0900 Subject: [PATCH 15/37] =?UTF-8?q?[refactor/mypage]=20=EB=AC=B8=EC=9D=98=20?= =?UTF-8?q?=EB=B0=8F=20=EC=A0=9C=EB=B3=B4=ED=95=98=EA=B8=B0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20ViewModel,=20Contract=20=EC=83=9D=EC=84=B1=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../question/MyPageQuestionConstract.kt | 27 ++++++++++++ .../myPage/question/MyPageQuestionScreen.kt | 17 ++++++-- .../question/MyPageQuestionViewModel.kt | 43 +++++++++++++++++++ 3 files changed, 83 insertions(+), 4 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt new file mode 100644 index 0000000..1553182 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt @@ -0,0 +1,27 @@ +package com.meongmoryteam.presentation.ui.myPage.question + +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class MyPageQuestionConstract { + data class MyPageQuestionViewState( + val loadState: LoadState = LoadState.SUCCESS, + val email: String = "", + val question: String = "", + val isError: Boolean = true + ) : ViewState + + sealed class MyPageQuestionSideEffect: ViewSideEffect { + object NavigateToHome : MyPageQuestionSideEffect() + } + + sealed class MyPageQuestionEvent: ViewEvent { + data class FillEmail( + val email: String + ): MyPageQuestionEvent() + object ClearEmail: MyPageQuestionEvent() + object OnClickButton: MyPageQuestionEvent() + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index ea596da..fba2770 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -19,6 +19,7 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -33,12 +34,13 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar import com.meongmoryteam.presentation.ui.theme.EditButtonFalse -import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.QuestionButtonText import com.meongmoryteam.presentation.ui.theme.QuestionEditFill import com.meongmoryteam.presentation.ui.theme.QuestionSubTitle @@ -59,7 +61,9 @@ fun MyPageQuestionScreen() { MyPageToolBar(stringResource(R.string.question_title)) Spacer(modifier = Modifier.padding(PADDING_8)) EmailEdit() - Column(modifier = Modifier.fillMaxHeight(0.5f)) { + Column( + modifier = Modifier.fillMaxHeight(0.5f) + ) { DetailEdit() } Box( @@ -225,9 +229,14 @@ fun DetailForm() { } @Composable -fun QuestionButton() { +fun QuestionButton( + viewModel: MyPageQuestionViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() Button( - onClick = { /*TODO*/ }, + onClick = { + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickButton) + }, colors = ButtonDefaults.buttonColors(EditButtonFalse), modifier = Modifier .padding(16.dp) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt new file mode 100644 index 0000000..9c10b10 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -0,0 +1,43 @@ +package com.meongmoryteam.presentation.ui.myPage.question + +import androidx.lifecycle.SavedStateHandle +import androidx.lifecycle.viewModelScope +import com.meongmoryteam.presentation.base.BaseViewModel +import com.meongmoryteam.presentation.base.LoadState +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.* +import kotlinx.coroutines.launch + +@HiltViewModel +class MyPageQuestionViewModel @Inject constructor( + private val savedStateHandle: SavedStateHandle +) : BaseViewModel( + MyPageQuestionViewState() +) { + override fun handleEvents(event: MyPageQuestionEvent) { + when (event) { + MyPageQuestionEvent.ClearEmail -> reflectUpdatedState("") + is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(event.email) + MyPageQuestionEvent.OnClickButton -> setEmail(viewState.value.email) + } + } + + private fun reflectUpdatedState( + email: String = viewState.value.email + ) { + updateState { + copy( + email = email, + ) + } + } + + private fun setEmail(email: String) = viewModelScope.launch { + updateState { + copy( + loadState = LoadState.LOADING + ) + } + } +} \ No newline at end of file From cbec8e6bce3b2084fa9d25b0c9f5b86607e9d03a Mon Sep 17 00:00:00 2001 From: arinming Date: Tue, 8 Aug 2023 23:49:39 +0900 Subject: [PATCH 16/37] =?UTF-8?q?[refactor/mypage]=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=99=94=EB=A9=B4=20ViewModel,?= =?UTF-8?q?=20Contract=20=EC=83=9D=EC=84=B1=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/myPage/MyPageContract.kt | 24 +++++++++++++++++ .../presentation/ui/myPage/MyPageViewModel.kt | 27 +++++++++++++++++++ .../ui/myPage/profile/MyPageProfileScreen.kt | 5 +++- 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt new file mode 100644 index 0000000..143313e --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -0,0 +1,24 @@ +package com.meongmoryteam.presentation.ui.myPage + +import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class MyPageContract { + data class MyPageViewState( + val loadState: LoadState = LoadState.SUCCESS, + val nickName: String = "", + val isDialogVisible: Boolean = false + ) : ViewState + + sealed class MyPageSideEffect: ViewSideEffect { + object EditNickName: MyPageSideEffect() + object NavigateToQuestion: MyPageSideEffect() + } + + sealed class MyPageEvent: ViewEvent { + object OnClickProfileEditButtonClicked: MyPageEvent() + object OnClickQuestionButtonClicked: MyPageEvent() + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt new file mode 100644 index 0000000..ca25db2 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -0,0 +1,27 @@ +package com.meongmoryteam.presentation.ui.myPage + +import androidx.lifecycle.SavedStateHandle +import com.meongmoryteam.presentation.base.BaseViewModel +import com.meongmoryteam.presentation.base.LoadState +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.* + + +@HiltViewModel +class MyPageViewModel @Inject constructor( + private val savedStateHandle: SavedStateHandle +) : BaseViewModel( + MyPageViewState() +) { + override fun handleEvents(event: MyPageEvent) { + when (event) { + is MyPageEvent.OnClickProfileEditButtonClicked -> { + sendEffect({ MyPageSideEffect.EditNickName }) + } + is MyPageEvent.OnClickQuestionButtonClicked -> { + sendEffect({ MyPageSideEffect.NavigateToQuestion }) + } + } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 4cab41d..d4c67af 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -33,6 +33,8 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavController import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditDivider @@ -44,7 +46,8 @@ val PADDING_16 = 16.dp val PADDING_24 = 24.dp @Composable -fun MyPageProfileScreen() { +fun MyPageProfileScreen( +) { Column( modifier = Modifier .fillMaxHeight() From 24fd4fef35a04a448286076a237dab40cd12ff39 Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 02:13:23 +0900 Subject: [PATCH 17/37] =?UTF-8?q?[refactor/mypage]=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=ED=94=84=EB=A1=9C=ED=95=84=20?= =?UTF-8?q?=ED=8E=B8=EC=A7=91,=20=EB=AC=B8=EC=9D=98=ED=95=98=EA=B8=B0=20ro?= =?UTF-8?q?ute=20=EC=84=A4=EC=A0=95=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/bottom/BottomNavigation.kt | 2 ++ .../presentation/ui/main/MainActivity.kt | 9 +++++- .../presentation/ui/main/MainContract.kt | 23 +++++++++++++ .../presentation/ui/main/MainScreen.kt | 17 ++++++++-- .../presentation/ui/main/MainViewModel.kt | 18 +++++++++++ .../presentation/ui/myPage/MyPageContract.kt | 2 +- .../presentation/ui/myPage/MyPageScreen.kt | 32 ++++++++++++++++--- .../presentation/ui/myPage/MyPageViewModel.kt | 2 +- 8 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt index 1f2cfd0..54fbc48 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigation.kt @@ -25,4 +25,6 @@ enum class MeongMoryRoute(val route: String) { MAP("map"), HOME("home"), MY_PAGE("my-page"), + EDIT_NICKNAME("edit-nickname"), + QUESTION("question"), } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index 9ef0568..310c969 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -1,13 +1,18 @@ package com.meongmoryteam.presentation.ui.main +import android.content.Context +import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.viewModels import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { + private val viewModel: MainViewModel by viewModels() + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -17,7 +22,9 @@ class MainActivity : ComponentActivity() { private fun setMainScreen() { setContent { MeongmoryTheme { - MainScreen() + MainScreen( + intentToCreateHome = { } + ) } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt new file mode 100644 index 0000000..23f1ceb --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt @@ -0,0 +1,23 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class MainContract { + data class MainViewState( + val loginState: LoginState = LoginState.NONE + ) : ViewState + + sealed class MainSideEffect : ViewSideEffect { + object Navigate + } + + sealed class MainEvent : ViewEvent { + object OnBottomNavigationClicked : MainEvent() + } + + enum class LoginState { + NONE, LOGIN + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt index 05bc7c8..6a7d61a 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt @@ -3,9 +3,12 @@ package com.meongmoryteam.presentation.ui.main import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview +import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -13,15 +16,20 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.ui.bottom.BottomNavigation import com.meongmoryteam.presentation.ui.bottom.MeongMoryBottomNavigation +import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute import com.meongmoryteam.presentation.ui.bottom.navigateBottomNavigationScreen import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen import com.meongmoryteam.presentation.ui.myPage.MyPageScreen +import kotlinx.coroutines.flow.collect @Composable fun MainScreen( + viewModel: MainViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), + intentToCreateHome: () -> Unit, ) { + val viewState by viewModel.viewState.collectAsState() val navBackStackEntry by navController.currentBackStackEntryAsState() val currentDestination = navBackStackEntry?.destination @@ -50,7 +58,10 @@ fun MainScreen( MapScreen() } composable(route = BottomNavigation.MY_PAGE.route) { - MyPageScreen() + MyPageScreen( + navigateToEditNickNameScreen = { navController.navigate(MeongMoryRoute.EDIT_NICKNAME.route) }, + navigateToQuestionScreen = { navController.navigate(MeongMoryRoute.QUESTION.route) }, + ) } } } @@ -59,5 +70,7 @@ fun MainScreen( @Preview @Composable fun MainScreenPreview() { - MainScreen() + MainScreen( + intentToCreateHome = { } + ) } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt new file mode 100644 index 0000000..6e1f836 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt @@ -0,0 +1,18 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.main.MainContract.* + +@HiltViewModel +class MainViewModel @Inject constructor() : BaseViewModel( + MainViewState() +) { + override fun handleEvents(event: MainEvent) { + when (event) { + is MainEvent.OnBottomNavigationClicked -> { + } + } + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt index 143313e..8b7a5bc 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -13,7 +13,7 @@ class MyPageContract { ) : ViewState sealed class MyPageSideEffect: ViewSideEffect { - object EditNickName: MyPageSideEffect() + object NavigateToEditProfile: MyPageSideEffect() object NavigateToQuestion: MyPageSideEffect() } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 2751a16..01489b3 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -20,7 +20,9 @@ import androidx.compose.material3.Divider import androidx.compose.material3.Icon import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState +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 import androidx.compose.ui.Alignment @@ -34,8 +36,7 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import androidx.navigation.NavHostController -import androidx.navigation.compose.rememberNavController +import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog @@ -46,14 +47,32 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.MyPageProfileEditButton import com.meongmoryteam.presentation.ui.theme.MyPageYellowFill import com.meongmoryteam.presentation.ui.theme.MyPageYellowStroke +import kotlinx.coroutines.flow.collect val PADDING_8 = 8.dp val PADDING_16 = 16.dp @Composable fun MyPageScreen( - navController: NavHostController = rememberNavController() + viewModel: MyPageViewModel = hiltViewModel(), + navigateToEditNickNameScreen: () -> Unit, + navigateToQuestionScreen: () -> Unit, ) { + val viewState by viewModel.viewState.collectAsState() + + LaunchedEffect(key1 = viewModel.effect) { + viewModel.effect.collect { effect -> + when (effect) { + is MyPageContract.MyPageSideEffect.NavigateToEditProfile -> { + navigateToEditNickNameScreen() + } + is MyPageContract.MyPageSideEffect.NavigateToQuestion -> { + navigateToQuestionScreen() + } + } + } + } + Column { MyPageTitle() MyPageProfile() @@ -311,7 +330,10 @@ fun ListButton( @Composable fun PreviewMyPageScreen() { MeongmoryTheme { - MyPageScreen() + MyPageScreen( + navigateToEditNickNameScreen = { }, + navigateToQuestionScreen = { }, + ) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt index ca25db2..85c8edf 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -17,7 +17,7 @@ class MyPageViewModel @Inject constructor( override fun handleEvents(event: MyPageEvent) { when (event) { is MyPageEvent.OnClickProfileEditButtonClicked -> { - sendEffect({ MyPageSideEffect.EditNickName }) + sendEffect({ MyPageSideEffect.NavigateToEditProfile }) } is MyPageEvent.OnClickQuestionButtonClicked -> { sendEffect({ MyPageSideEffect.NavigateToQuestion }) From 70b6a76b62796963898d8c434c0fc5445ff57279 Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 14:36:28 +0900 Subject: [PATCH 18/37] =?UTF-8?q?[refactor/mypage]=20route=EB=B3=84=20?= =?UTF-8?q?=EB=B0=94=ED=85=80=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EA=B0=80=EC=8B=9C=EC=84=B1=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/HomeContract.kt | 21 +++++ .../ui/main/{MainScreen.kt => HomeScreen.kt} | 47 ++++++---- .../presentation/ui/main/HomeViewModel.kt | 15 ++++ .../presentation/ui/main/MainActivity.kt | 41 ++++++++- .../presentation/ui/main/MainContract.kt | 12 +-- .../presentation/ui/main/MainViewModel.kt | 7 +- .../presentation/ui/myPage/MyPageScreen.kt | 90 +++++++++++++++---- 7 files changed, 185 insertions(+), 48 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt rename presentation/src/main/java/com/meongmoryteam/presentation/ui/main/{MainScreen.kt => HomeScreen.kt} (60%) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt new file mode 100644 index 0000000..69e220e --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt @@ -0,0 +1,21 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.ViewEvent +import com.meongmoryteam.presentation.base.ViewSideEffect +import com.meongmoryteam.presentation.base.ViewState + +class HomeContract { + data class HomeViewState( + val loginState: LoginState = LoginState.NONE, + ) : ViewState + + sealed class HomeSideEffect : ViewSideEffect { + } + + sealed class HomeEvent : ViewEvent { + } + + enum class LoginState { + NONE, LOGIN + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt similarity index 60% rename from presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt rename to presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt index 6a7d61a..818d031 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt @@ -3,9 +3,11 @@ package com.meongmoryteam.presentation.ui.main import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold 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.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import androidx.hilt.navigation.compose.hiltViewModel @@ -14,14 +16,13 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import com.meongmoryteam.presentation.ui.bottom.BottomNavigation import com.meongmoryteam.presentation.ui.bottom.MeongMoryBottomNavigation import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute import com.meongmoryteam.presentation.ui.bottom.navigateBottomNavigationScreen import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen import com.meongmoryteam.presentation.ui.myPage.MyPageScreen -import kotlinx.coroutines.flow.collect +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen @Composable fun MainScreen( @@ -32,39 +33,53 @@ fun MainScreen( val viewState by viewModel.viewState.collectAsState() val navBackStackEntry by navController.currentBackStackEntryAsState() val currentDestination = navBackStackEntry?.destination + var bottomBarState by rememberSaveable { mutableStateOf(true) } Scaffold( bottomBar = { - MeongMoryBottomNavigation( - currentDestination = currentDestination, - navigateToScreen = { navigationItem -> - navigateBottomNavigationScreen( - navController = navController, - navigationItem = navigationItem, - ) - } - ) + if (bottomBarState) { + MeongMoryBottomNavigation( + currentDestination = currentDestination, + navigateToScreen = { navigationItem -> + navigateBottomNavigationScreen( + navController = navController, + navigationItem = navigationItem, + ) + } + ) + } } ) { padding -> NavHost( modifier = Modifier.padding(padding), navController = navController, - startDestination = BottomNavigation.HOME.route, + startDestination = MeongMoryRoute.HOME.route, ) { - composable(route = BottomNavigation.HOME.route) { + composable(route = MeongMoryRoute.HOME.route) { HomeScreen() } - composable(route = BottomNavigation.MAP.route) { + composable(route = MeongMoryRoute.MAP.route) { MapScreen() } - composable(route = BottomNavigation.MY_PAGE.route) { + composable(route = MeongMoryRoute.MY_PAGE.route) { MyPageScreen( navigateToEditNickNameScreen = { navController.navigate(MeongMoryRoute.EDIT_NICKNAME.route) }, navigateToQuestionScreen = { navController.navigate(MeongMoryRoute.QUESTION.route) }, ) } + composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { + MyPageProfileScreen() + } } } + + // 바텀 네비게이션 보이기, 숨기기 + bottomBarState = when (currentDestination?.route) { + MeongMoryRoute.HOME.route -> true + MeongMoryRoute.MAP.route -> true + MeongMoryRoute.MY_PAGE.route -> true + else -> false + } } @Preview diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt new file mode 100644 index 0000000..579175d --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt @@ -0,0 +1,15 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.main.HomeContract.* + +@HiltViewModel +class HomeViewModel @Inject constructor( +) : BaseViewModel( + HomeViewState() +) { + override fun handleEvents(event: HomeEvent) { + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index 310c969..dbdc281 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -2,16 +2,29 @@ package com.meongmoryteam.presentation.ui.main import android.content.Context import android.content.Intent +import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent +import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import androidx.navigation.compose.rememberNavController +import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { private val viewModel: MainViewModel by viewModels() + private var createResultLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() + ) { _ -> + viewModel.setEvent(MainContract.MainEvent.FinishedCreateActivity) + } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -22,10 +35,30 @@ class MainActivity : ComponentActivity() { private fun setMainScreen() { setContent { MeongmoryTheme { - MainScreen( - intentToCreateHome = { } - ) + val navController = rememberNavController() + NavHost( + navController = navController, + startDestination = MeongMoryRoute.HOME.route, + ) { + composable(route = MeongMoryRoute.HOME.route) { + MainScreen(intentToCreateHome = { }) + } + composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { + MyPageProfileScreen() + } + composable(route = MeongMoryRoute.QUESTION.route) { + MyPageQuestionScreen() + } + } } } } -} \ No newline at end of file + + companion object { + fun startActivity(context: Context, uri: Uri?) { + val intent = Intent(context, MainActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_NEW_TASK + context.startActivity(intent) + } + } +} diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt index 23f1ceb..34aab94 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt @@ -5,19 +5,13 @@ import com.meongmoryteam.presentation.base.ViewSideEffect import com.meongmoryteam.presentation.base.ViewState class MainContract { - data class MainViewState( - val loginState: LoginState = LoginState.NONE - ) : ViewState + object MainViewState : ViewState sealed class MainSideEffect : ViewSideEffect { - object Navigate + object RefreshScreen : MainSideEffect() } sealed class MainEvent : ViewEvent { - object OnBottomNavigationClicked : MainEvent() - } - - enum class LoginState { - NONE, LOGIN + object FinishedCreateActivity : MainEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt index 6e1f836..00d32b6 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt @@ -6,12 +6,11 @@ import javax.inject.Inject import com.meongmoryteam.presentation.ui.main.MainContract.* @HiltViewModel -class MainViewModel @Inject constructor() : BaseViewModel( - MainViewState() -) { +class MainViewModel @Inject constructor( +) : BaseViewModel(MainViewState) { override fun handleEvents(event: MainEvent) { when (event) { - is MainEvent.OnBottomNavigationClicked -> { + is MainEvent.FinishedCreateActivity-> { } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 01489b3..2a690a5 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -38,8 +38,10 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog +import com.meongmoryteam.presentation.ui.main.MainViewModel import com.meongmoryteam.presentation.ui.theme.ListDivider import com.meongmoryteam.presentation.ui.theme.ListNextButton import com.meongmoryteam.presentation.ui.theme.ListTitle @@ -47,7 +49,6 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.MyPageProfileEditButton import com.meongmoryteam.presentation.ui.theme.MyPageYellowFill import com.meongmoryteam.presentation.ui.theme.MyPageYellowStroke -import kotlinx.coroutines.flow.collect val PADDING_8 = 8.dp val PADDING_16 = 16.dp @@ -66,16 +67,38 @@ fun MyPageScreen( is MyPageContract.MyPageSideEffect.NavigateToEditProfile -> { navigateToEditNickNameScreen() } + is MyPageContract.MyPageSideEffect.NavigateToQuestion -> { navigateToQuestionScreen() } } } } + when (viewState.loadState) { + LoadState.SUCCESS -> { + MyPageProfileButton( + OnClickEditNickname = { + navigateToEditNickNameScreen + }, + ) + } + LoadState.LOADING -> { + + } + LoadState.ERROR -> { + + } + } + + + Column { MyPageTitle() - MyPageProfile() + MyPageProfile( + userName = "", + OnClickEditNickname = { navigateToEditNickNameScreen() } + ) MyPageList() } } @@ -98,7 +121,10 @@ fun MyPageTitle() { @Composable -fun MyPageProfile() { +fun MyPageProfile( + userName: String, + OnClickEditNickname: () -> Unit, +) { // 상단 프로필 메뉴 Column { Row( @@ -128,10 +154,18 @@ fun MyPageProfile() { fontSize = 14.sp ) - Row(modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End) { - MyPageProfileButton(stringResource(R.string.my_page_profile_alarm)) - MyPageProfileButton(stringResource(R.string.my_page_profile_edit)) + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End + ) { + MyPageProfileButton( + stringResource(R.string.my_page_profile_alarm), + OnClickEditNickname = { } + ) + MyPageProfileButton( + stringResource(R.string.my_page_profile_edit), + OnClickEditNickname = { } + ) } @@ -163,7 +197,7 @@ fun MyPageList() { .fillMaxWidth() .fillMaxHeight() ) { - Column{ + Column { Text( text = stringResource(R.string.my_page_list_account), fontWeight = FontWeight.Bold, @@ -174,8 +208,16 @@ fun MyPageList() { ) ListButton(R.drawable.ic_coin, stringResource(R.string.my_page_pro_ver)) - ListButton(R.drawable.ic_logout, stringResource(R.string.my_page_logout), stringResource(R.string.my_page_logout)) - ListButton(R.drawable.ic_user, stringResource(R.string.my_page_drop), stringResource(R.string.my_page_drop)) + ListButton( + R.drawable.ic_logout, + stringResource(R.string.my_page_logout), + stringResource(R.string.my_page_logout) + ) + ListButton( + R.drawable.ic_user, + stringResource(R.string.my_page_drop), + stringResource(R.string.my_page_drop) + ) Spacer(modifier = Modifier.padding(top = PADDING_16)) @@ -231,12 +273,20 @@ fun MyPageList() { @Composable fun MyPageProfileButton( - buttonText: String? = null + buttonText: String? = null, + onClickAction: String? = null, + OnClickEditNickname: () -> Unit, ) { + val refreshButton = remember { + mutableStateOf(false) + } Column(modifier = Modifier) { Button( - onClick = { /*TODO*/ }, + onClick = { + // 프로필 편집 버튼이 클릭되었을 때 + OnClickEditNickname + }, modifier = Modifier .padding(end = PADDING_8) .wrapContentSize(), @@ -252,6 +302,15 @@ fun MyPageProfileButton( } } } + // 버튼마다 다른 다이어로그 + if (refreshButton.value) { + if (onClickAction == stringResource(R.string.my_page_profile_edit)) { + LogoutAlertDialog(openDialogCustom = refreshButton) + } + if (onClickAction == stringResource(R.string.my_page_question)) { + SecessionAlertDialog(openDialogCustom = refreshButton) + } + } } @@ -294,9 +353,10 @@ fun ListButton( ) } - Box(modifier = Modifier - .padding() - .fillMaxWidth(), + Box( + modifier = Modifier + .padding() + .fillMaxWidth(), contentAlignment = Alignment.CenterEnd ) { Button( From 837c70cb67a9e7ee02e4f404b30304ef5b30333f Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 16:53:41 +0900 Subject: [PATCH 19/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EC=88=98=EC=A0=95,=20=EB=AC=B8=EC=9D=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=A0=9C=EB=B3=B4=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/bottom/BottomNavigationScreen.kt | 3 +- .../presentation/ui/main/HomeScreen.kt | 9 +- .../presentation/ui/main/MainActivity.kt | 30 +---- .../presentation/ui/myPage/MyPageContract.kt | 3 +- .../presentation/ui/myPage/MyPageScreen.kt | 122 ++++++++++++------ .../presentation/ui/myPage/MyPageViewModel.kt | 11 +- .../ui/myPage/profile/MyPageProfileScreen.kt | 3 + .../myPage/profile/MyPageProfileViewModel.kt | 1 - .../question/MyPageQuestionViewModel.kt | 8 +- .../presentation/util/ActivityViewModelExt.kt | 14 ++ 10 files changed, 121 insertions(+), 83 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt index 19f39cf..f551b91 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/bottom/BottomNavigationScreen.kt @@ -15,6 +15,7 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavDestination +import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import com.meongmoryteam.presentation.ui.theme.GRAY100 @@ -48,7 +49,7 @@ fun MeongMoryBottomNavigation( } ) }, - selected = currentDestination?.route == bottomItem.route, + selected = currentDestination?.hierarchy?.any { it.route == bottomItem.route } == true, onClick = { navigateToScreen(bottomItem) }, colors = NavigationBarItemDefaults.colors(indicatorColor = Color.White), ) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt index 818d031..0e58ccf 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt @@ -23,12 +23,12 @@ import com.meongmoryteam.presentation.ui.home.HomeScreen import com.meongmoryteam.presentation.ui.map.MapScreen import com.meongmoryteam.presentation.ui.myPage.MyPageScreen import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen @Composable fun MainScreen( viewModel: MainViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), - intentToCreateHome: () -> Unit, ) { val viewState by viewModel.viewState.collectAsState() val navBackStackEntry by navController.currentBackStackEntryAsState() @@ -70,6 +70,9 @@ fun MainScreen( composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { MyPageProfileScreen() } + composable(route = MeongMoryRoute.QUESTION.route) { + MyPageQuestionScreen() + } } } @@ -85,7 +88,5 @@ fun MainScreen( @Preview @Composable fun MainScreenPreview() { - MainScreen( - intentToCreateHome = { } - ) + MainScreen() } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt index dbdc281..21e58f2 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainActivity.kt @@ -1,31 +1,17 @@ package com.meongmoryteam.presentation.ui.main -import android.content.Context -import android.content.Intent -import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.result.contract.ActivityResultContracts -import androidx.activity.viewModels import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute -import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen -import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import dagger.hilt.android.AndroidEntryPoint @AndroidEntryPoint class MainActivity : ComponentActivity() { - private val viewModel: MainViewModel by viewModels() - private var createResultLauncher = registerForActivityResult( - ActivityResultContracts.StartActivityForResult() - ) { _ -> - viewModel.setEvent(MainContract.MainEvent.FinishedCreateActivity) - } - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -41,24 +27,10 @@ class MainActivity : ComponentActivity() { startDestination = MeongMoryRoute.HOME.route, ) { composable(route = MeongMoryRoute.HOME.route) { - MainScreen(intentToCreateHome = { }) - } - composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { - MyPageProfileScreen() - } - composable(route = MeongMoryRoute.QUESTION.route) { - MyPageQuestionScreen() + MainScreen() } } } } } - - companion object { - fun startActivity(context: Context, uri: Uri?) { - val intent = Intent(context, MainActivity::class.java) - intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP + Intent.FLAG_ACTIVITY_NEW_TASK - context.startActivity(intent) - } - } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt index 8b7a5bc..63c6eb3 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -18,7 +18,8 @@ class MyPageContract { } sealed class MyPageEvent: ViewEvent { + object InitMyPageScreen : MyPageEvent() object OnClickProfileEditButtonClicked: MyPageEvent() - object OnClickQuestionButtonClicked: MyPageEvent() + object OnQuestionClicked: MyPageEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 2a690a5..4824bb4 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -41,6 +41,7 @@ import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog +import com.meongmoryteam.presentation.ui.main.MainContract import com.meongmoryteam.presentation.ui.main.MainViewModel import com.meongmoryteam.presentation.ui.theme.ListDivider import com.meongmoryteam.presentation.ui.theme.ListNextButton @@ -49,19 +50,25 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.MyPageProfileEditButton import com.meongmoryteam.presentation.ui.theme.MyPageYellowFill import com.meongmoryteam.presentation.ui.theme.MyPageYellowStroke +import com.meongmoryteam.presentation.util.composableActivityViewModel val PADDING_8 = 8.dp val PADDING_16 = 16.dp @Composable fun MyPageScreen( + mainViewModel: MainViewModel = composableActivityViewModel(), viewModel: MyPageViewModel = hiltViewModel(), navigateToEditNickNameScreen: () -> Unit, navigateToQuestionScreen: () -> Unit, ) { val viewState by viewModel.viewState.collectAsState() - LaunchedEffect(key1 = viewModel.effect) { + LaunchedEffect(true) { + viewModel.setEvent(MyPageContract.MyPageEvent.InitMyPageScreen) + } + + LaunchedEffect(viewModel.effect) { viewModel.effect.collect { effect -> when (effect) { is MyPageContract.MyPageSideEffect.NavigateToEditProfile -> { @@ -74,32 +81,36 @@ fun MyPageScreen( } } } - when (viewState.loadState) { - LoadState.SUCCESS -> { - MyPageProfileButton( - OnClickEditNickname = { - navigateToEditNickNameScreen - }, - ) - } - LoadState.LOADING -> { - - } - LoadState.ERROR -> { + LaunchedEffect(mainViewModel.effect) { + mainViewModel.effect.collect { effect -> + when (effect) { + is MainContract.MainSideEffect.RefreshScreen -> { + viewModel.setEvent(MyPageContract.MyPageEvent.InitMyPageScreen) + } + } } } + when (viewState.loadState) { + LoadState.SUCCESS -> { + Column { + MyPageTitle() + MyPageProfile( + OnClickEditNickname = { + viewModel.setEvent(MyPageContract.MyPageEvent.OnClickProfileEditButtonClicked) + } + ) + MyPageList( + onQuestionClicked = { + viewModel.setEvent(MyPageContract.MyPageEvent.OnQuestionClicked) + } + ) + } + } - - - Column { - MyPageTitle() - MyPageProfile( - userName = "", - OnClickEditNickname = { navigateToEditNickNameScreen() } - ) - MyPageList() + LoadState.LOADING -> {} + LoadState.ERROR -> {} } } @@ -122,7 +133,6 @@ fun MyPageTitle() { @Composable fun MyPageProfile( - userName: String, OnClickEditNickname: () -> Unit, ) { // 상단 프로필 메뉴 @@ -160,11 +170,11 @@ fun MyPageProfile( ) { MyPageProfileButton( stringResource(R.string.my_page_profile_alarm), - OnClickEditNickname = { } + onClick = { } ) MyPageProfileButton( stringResource(R.string.my_page_profile_edit), - OnClickEditNickname = { } + onClick = OnClickEditNickname ) } @@ -185,7 +195,9 @@ fun MyPageProfile( @Composable -fun MyPageList() { +fun MyPageList( + onQuestionClicked: () -> Unit, +) { // 마이페이지 목록 부분 Row( @@ -207,16 +219,22 @@ fun MyPageList() { fontSize = 11.sp ) - ListButton(R.drawable.ic_coin, stringResource(R.string.my_page_pro_ver)) + ListButton( + R.drawable.ic_coin, + stringResource(R.string.my_page_pro_ver), + onClick = { }, + ) ListButton( R.drawable.ic_logout, stringResource(R.string.my_page_logout), - stringResource(R.string.my_page_logout) + stringResource(R.string.my_page_logout), + onClick = { }, ) ListButton( R.drawable.ic_user, stringResource(R.string.my_page_drop), - stringResource(R.string.my_page_drop) + stringResource(R.string.my_page_drop), + onClick = { }, ) Spacer(modifier = Modifier.padding(top = PADDING_16)) @@ -239,8 +257,16 @@ fun MyPageList() { fontSize = 11.sp ) - ListButton(R.drawable.ic_mail, stringResource(R.string.my_page_notice)) - ListButton(R.drawable.ic_send, stringResource(R.string.my_page_question)) + ListButton( + R.drawable.ic_mail, + stringResource(R.string.my_page_notice), + onClick = { }, + ) + ListButton( + R.drawable.ic_send, + stringResource(R.string.my_page_question), + onClick = onQuestionClicked, + ) Spacer(modifier = Modifier.padding(top = PADDING_16)) @@ -261,8 +287,16 @@ fun MyPageList() { color = ListTitle, fontSize = 11.sp ) - ListButton(R.drawable.ic_info, stringResource(R.string.my_page_clause)) - ListButton(R.drawable.ic_unlock, stringResource(R.string.my_page_personal)) + ListButton( + R.drawable.ic_info, + stringResource(R.string.my_page_clause), + onClick = { }, + ) + ListButton( + R.drawable.ic_unlock, + stringResource(R.string.my_page_personal), + onClick = { }, + ) } @@ -275,7 +309,7 @@ fun MyPageList() { fun MyPageProfileButton( buttonText: String? = null, onClickAction: String? = null, - OnClickEditNickname: () -> Unit, + onClick: () -> Unit ) { val refreshButton = remember { mutableStateOf(false) @@ -284,8 +318,10 @@ fun MyPageProfileButton( Button( onClick = { - // 프로필 편집 버튼이 클릭되었을 때 - OnClickEditNickname + onClick() + if (onClickAction != null) { + refreshButton.value = true + } }, modifier = Modifier .padding(end = PADDING_8) @@ -318,20 +354,28 @@ fun MyPageProfileButton( fun ListButton( buttonIcon: Int? = null, buttonText: String, - onClickAction: String? = null + onClickAction: String? = null, + onClick: () -> Unit, ) { val openDialogCustom = remember { mutableStateOf(false) } - + val refreshButton = remember { + mutableStateOf(false) + } Row( modifier = Modifier .fillMaxWidth() ) { Button( - onClick = { openDialogCustom.value = true }, + onClick = { + onClick() + if (onClickAction != null) { + refreshButton.value = true + } + }, colors = ButtonDefaults.buttonColors( contentColor = Color.Unspecified, containerColor = Color.Transparent diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt index 85c8edf..6a88862 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -1,25 +1,28 @@ package com.meongmoryteam.presentation.ui.myPage -import androidx.lifecycle.SavedStateHandle import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.MyPageEvent +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.MyPageSideEffect +import com.meongmoryteam.presentation.ui.myPage.MyPageContract.MyPageViewState import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject -import com.meongmoryteam.presentation.ui.myPage.MyPageContract.* @HiltViewModel class MyPageViewModel @Inject constructor( - private val savedStateHandle: SavedStateHandle ) : BaseViewModel( MyPageViewState() ) { override fun handleEvents(event: MyPageEvent) { when (event) { + is MyPageEvent.InitMyPageScreen -> { + updateState { copy(loadState = LoadState.SUCCESS) } + } is MyPageEvent.OnClickProfileEditButtonClicked -> { sendEffect({ MyPageSideEffect.NavigateToEditProfile }) } - is MyPageEvent.OnClickQuestionButtonClicked -> { + is MyPageEvent.OnQuestionClicked -> { sendEffect({ MyPageSideEffect.NavigateToQuestion }) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index d4c67af..7dc51cb 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -47,7 +47,10 @@ val PADDING_24 = 24.dp @Composable fun MyPageProfileScreen( + viewModel: MyPageProfileViewModel = hiltViewModel(), ) { + val uiState by viewModel.viewState.collectAsState() + Column( modifier = Modifier .fillMaxHeight() diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index 42911a1..fc7494a 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -13,7 +13,6 @@ import javax.inject.Inject @HiltViewModel class MyPageProfileViewModel @Inject constructor( - private val saveStateHandle: SavedStateHandle, ) : BaseViewModel( MyPageProfileViewState() ) { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt index 9c10b10..179893f 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -1,17 +1,17 @@ package com.meongmoryteam.presentation.ui.myPage.question -import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.MyPageQuestionEvent +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.MyPageQuestionSideEffect +import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.MyPageQuestionViewState import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionConstract.* import kotlinx.coroutines.launch +import javax.inject.Inject @HiltViewModel class MyPageQuestionViewModel @Inject constructor( - private val savedStateHandle: SavedStateHandle ) : BaseViewModel( MyPageQuestionViewState() ) { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt b/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt new file mode 100644 index 0000000..6a7c402 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt @@ -0,0 +1,14 @@ +package com.meongmoryteam.presentation.util + +import androidx.activity.ComponentActivity +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewmodel.compose.viewModel + +@Composable +fun getActivity() = LocalContext.current as ComponentActivity + +@Composable +inline fun composableActivityViewModel( +) : VM = viewModel(getActivity()) \ No newline at end of file From 3d7ffd031b9ff8e828eeb61a481e2cc5e155ab5b Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 17:16:34 +0900 Subject: [PATCH 20/37] =?UTF-8?q?[refactor/mypage]=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=B2=A4=ED=8A=B8=20=EC=88=98=EC=A0=95,=20=EC=95=A1?= =?UTF-8?q?=ED=8B=B0=EB=B9=84=ED=8B=B0=20=EC=82=AD=EC=A0=9C=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/myPage/MyPageScreen.kt | 8 +++++++- .../ui/myPage/profile/MyPageProfileActivity.kt | 17 ----------------- .../ui/myPage/profile/MyPageProfileScreen.kt | 7 ++++--- .../myPage/question/MyPageQuestionActivity.kt | 14 -------------- .../ui/myPage/question/MyPageQuestionScreen.kt | 5 +++-- 5 files changed, 14 insertions(+), 37 deletions(-) delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index 4824bb4..e7dbf4a 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -372,6 +372,7 @@ fun ListButton( Button( onClick = { onClick() + openDialogCustom.value = true if (onClickAction != null) { refreshButton.value = true } @@ -404,7 +405,12 @@ fun ListButton( contentAlignment = Alignment.CenterEnd ) { Button( - onClick = { openDialogCustom.value = true }, + onClick = { + onClick() + openDialogCustom.value = true + if (onClickAction != null) { + refreshButton.value = true + }}, colors = ButtonDefaults.buttonColors(Color.Transparent, ListNextButton) ) { Icon( diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt deleted file mode 100644 index 5740b96..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileActivity.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.meongmoryteam.presentation.ui.myPage.profile - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent -import dagger.hilt.android.AndroidEntryPoint - - -@AndroidEntryPoint -class MyPageProfileActivity : ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - MyPageProfileScreen() - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index 7dc51cb..b204440 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.material3.Button @@ -212,12 +213,12 @@ fun ProfileChangeButton( modifier = Modifier .padding(16.dp) .fillMaxWidth() - .height(45.dp), - shape = RoundedCornerShape(10.dp) + .wrapContentHeight(), + shape = RoundedCornerShape(10.dp), ) { Text( text = stringResource(R.string.profile_change_button), - fontSize = 15.sp + fontSize = 15.sp, ) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt deleted file mode 100644 index 0d81010..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionActivity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.meongmoryteam.presentation.ui.myPage.question - -import android.os.Bundle -import androidx.activity.ComponentActivity -import androidx.activity.compose.setContent - -class MyPageQuestionActivity: ComponentActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - MyPageQuestionScreen() - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index fba2770..181b802 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.material3.Button @@ -241,13 +242,13 @@ fun QuestionButton( modifier = Modifier .padding(16.dp) .fillMaxWidth() - .height(45.dp), + .wrapContentHeight(), shape = RoundedCornerShape(10.dp) ) { Text( text = stringResource(R.string.question_button), color = QuestionButtonText, - fontSize = 15.sp + fontSize = 15.sp, ) } } From ad960261e81e029eede138fb33a68d2b801005b0 Mon Sep 17 00:00:00 2001 From: arinming Date: Thu, 10 Aug 2023 17:50:14 +0900 Subject: [PATCH 21/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=ED=8E=B8=EC=A7=91,=20=EB=AC=B8=EC=9D=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=98=A4=EB=A5=98=EC=A0=9C=EB=B3=B4=20?= =?UTF-8?q?=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/HomeScreen.kt | 8 ++- .../myPage/profile/MyPageProfileContract.kt | 3 +- .../ui/myPage/profile/MyPageProfileScreen.kt | 51 +++++++++++++++++-- .../myPage/profile/MyPageProfileViewModel.kt | 7 +-- .../myPage/question/MyPageQuestionScreen.kt | 29 +++++++++-- 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt index 0e58ccf..5f6f2ba 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt @@ -68,10 +68,14 @@ fun MainScreen( ) } composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { - MyPageProfileScreen() + MyPageProfileScreen( + navigateToPrevious = { navController.navigate(MeongMoryRoute.MY_PAGE.route) } + ) } composable(route = MeongMoryRoute.QUESTION.route) { - MyPageQuestionScreen() + MyPageQuestionScreen( + navigateToPrevious = { navController.navigate(MeongMoryRoute.MY_PAGE.route)} + ) } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 76a6e67..5244b89 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -10,11 +10,12 @@ class MyPageProfileContract { data class MyPageProfileViewState( val loadState: LoadState = LoadState.SUCCESS, val nickName: String = "", + val nickNameHint: String = "", val isError: Boolean = true ) : ViewState sealed class MyPageProfileSideEffect: ViewSideEffect { - object NavigateToHome : MyPageProfileSideEffect() + object NavigateToPrevious : MyPageProfileSideEffect() } sealed class MyPageProfileEvent: ViewEvent { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index b204440..d28508e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -1,6 +1,7 @@ package com.meongmoryteam.presentation.ui.myPage.profile import androidx.compose.foundation.border +import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -18,6 +19,7 @@ import androidx.compose.material3.Divider import androidx.compose.material3.Icon 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 @@ -26,6 +28,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle @@ -42,6 +45,7 @@ import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme +import kotlinx.coroutines.flow.collect val PADDING_16 = 16.dp val PADDING_24 = 24.dp @@ -49,9 +53,13 @@ val PADDING_24 = 24.dp @Composable fun MyPageProfileScreen( viewModel: MyPageProfileViewModel = hiltViewModel(), + navigateToPrevious: () -> Unit, ) { val uiState by viewModel.viewState.collectAsState() - + // refreshButton 상태 + val refreshButton = remember { + mutableStateOf(false) + } Column( modifier = Modifier .fillMaxHeight() @@ -66,7 +74,13 @@ fun MyPageProfileScreen( modifier = Modifier.fillMaxHeight(), Arrangement.spacedBy(150.dp) ) { - MyPageToolBar(stringResource(R.string.profile_change_title)) + MyPageToolBar( + stringResource(R.string.profile_change_title), + onBackClick = { + navigateToPrevious + refreshButton.value = true + }, + ) ProfileChangeEdit() } Column( @@ -77,13 +91,24 @@ fun MyPageProfileScreen( } } } + + // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 + LaunchedEffect(refreshButton.value) { + if (refreshButton.value) { + navigateToPrevious() + } + } } @Composable fun MyPageToolBar( - title: String + title: String, + onBackClick: () -> Unit, ) { + val refreshButton = remember { + mutableStateOf(false) + } Column() { // 위 아래 여백 Row( @@ -101,10 +126,16 @@ fun MyPageToolBar( .height(24.dp) .fillMaxWidth() ) { + Icon( imageVector = ImageVector.vectorResource(R.drawable.ic_left_btn), contentDescription = stringResource(R.string.profile_back_btn_description), - modifier = Modifier.padding(start = PADDING_16), + modifier = Modifier + .padding(start = PADDING_16) + .clickable { + onBackClick() + refreshButton.value = true + } ) } Text( @@ -118,9 +149,16 @@ fun MyPageToolBar( ) } + // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 + LaunchedEffect(refreshButton.value) { + if (refreshButton.value) { + onBackClick() + } + } } + @Composable fun ProfileChangeLabel() { Box( @@ -227,6 +265,9 @@ fun ProfileChangeButton( @Composable fun PreviewProfileScreen() { MeongmoryTheme { - MyPageProfileScreen() + MyPageProfileScreen( + viewModel = MyPageProfileViewModel(), + navigateToPrevious = { } + ) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index fc7494a..b0f8487 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -36,11 +36,8 @@ class MyPageProfileViewModel @Inject constructor( } private fun changeNickName(nickName: String) = viewModelScope.launch { - updateState { - copy( - loadState = LoadState.LOADING - ) - } + updateState { copy( loadState = LoadState.SUCCESS) } + sendEffect({ MyPageProfileSideEffect.NavigateToPrevious }) } // 텍스트 길이 초과 diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index 181b802..4ccc49e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -20,6 +20,7 @@ import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Icon 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 @@ -37,6 +38,7 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileViewModel import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditStroke @@ -52,14 +54,26 @@ val PADDING_24 = 24.dp @Composable -fun MyPageQuestionScreen() { +fun MyPageQuestionScreen( + viewModel: MyPageProfileViewModel = hiltViewModel(), + navigateToPrevious: () -> Unit, +) { + val refreshButton = remember { + mutableStateOf(false) + } Column( modifier = Modifier .fillMaxHeight() .fillMaxWidth(), verticalArrangement = Arrangement.Top, ) { - MyPageToolBar(stringResource(R.string.question_title)) + MyPageToolBar( + stringResource(R.string.question_title), + onBackClick = { + navigateToPrevious + refreshButton.value = true + } + ) Spacer(modifier = Modifier.padding(PADDING_8)) EmailEdit() Column( @@ -73,7 +87,12 @@ fun MyPageQuestionScreen() { ) { QuestionButton() } - + } + // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 + LaunchedEffect(refreshButton.value) { + if (refreshButton.value) { + navigateToPrevious() + } } } @@ -257,6 +276,8 @@ fun QuestionButton( @Composable fun PreviewQuestionScreen() { MeongmoryTheme { - MyPageQuestionScreen() + MyPageQuestionScreen( + navigateToPrevious = { } + ) } } From 55275138b50843a0bde985d8996f3bc749b3db24 Mon Sep 17 00:00:00 2001 From: arinming Date: Fri, 11 Aug 2023 10:44:17 +0900 Subject: [PATCH 22/37] =?UTF-8?q?[refactor/mypage]=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=85=EB=A0=A5=EC=8B=9C=20=ED=85=8D=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=ED=95=84=EB=93=9C=20=EC=83=89=EC=83=81=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/myPage/profile/MyPageProfileScreen.kt | 24 +++++++++++++++-- .../myPage/question/MyPageQuestionScreen.kt | 27 +++++++++++++++---- .../presentation/ui/theme/Color.kt | 4 +++ 3 files changed, 48 insertions(+), 7 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index d28508e..fadbce3 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -1,5 +1,6 @@ package com.meongmoryteam.presentation.ui.myPage.profile +import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -27,6 +28,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource @@ -41,6 +43,8 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.theme.EditButtonFalse +import com.meongmoryteam.presentation.ui.theme.EditChangeFill +import com.meongmoryteam.presentation.ui.theme.EditChangeStroke import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText @@ -201,15 +205,24 @@ fun ProfileChangeEdit( @Composable -fun MyPageEditForm() { +fun MyPageEditForm( +) { var text by remember { mutableStateOf("") } + var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 + Box( modifier = Modifier .padding(PADDING_16) .fillMaxWidth() .height(48.dp) + .background( + if (isTextEmpty) Color.White + else EditChangeFill + ) .border( - color = EditStroke, + color = + if (isTextEmpty) EditStroke + else EditChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp) ), @@ -220,6 +233,7 @@ fun MyPageEditForm() { onValueChange = { newText -> // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 text = newText.replace(Regex("[\n]"), "") + isTextEmpty = newText.isBlank() // Text가 비어있는지 여부 업데이트 }, textStyle = TextStyle( fontSize = 14.sp, @@ -243,6 +257,11 @@ fun ProfileChangeButton( viewModel: MyPageProfileViewModel = hiltViewModel() ) { val uiState by viewModel.viewState.collectAsState() + + val buttonColors = ButtonDefaults.buttonColors( + contentColor = Color.White + ) + Button( onClick = { viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) @@ -261,6 +280,7 @@ fun ProfileChangeButton( } } + @Preview(showBackground = true) @Composable fun PreviewProfileScreen() { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index 4ccc49e..c7905ba 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -45,6 +45,8 @@ import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.QuestionButtonText +import com.meongmoryteam.presentation.ui.theme.QuestionChangeFill +import com.meongmoryteam.presentation.ui.theme.QuestionChangeStroke import com.meongmoryteam.presentation.ui.theme.QuestionEditFill import com.meongmoryteam.presentation.ui.theme.QuestionSubTitle @@ -133,17 +135,23 @@ fun QuestionLabel( @Composable fun EmailForm() { var email by remember { mutableStateOf("") } + var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 + Box( modifier = Modifier .padding(all = PADDING_16) .height(48.dp) .fillMaxWidth(0.5f) .border( - color = EditStroke, + color = if (isTextEmpty) EditStroke + else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) - .background(color = QuestionEditFill, shape = RoundedCornerShape(10.dp)), + .background( + color = if (isTextEmpty) QuestionEditFill + else QuestionChangeFill, + shape = RoundedCornerShape(10.dp)), contentAlignment = Alignment.CenterStart // 정렬 ) { @@ -152,6 +160,7 @@ fun EmailForm() { onValueChange = { newText -> // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 email = newText.replace(Regex("[\n]"), "") + isTextEmpty = newText.isBlank() }, textStyle = TextStyle( fontSize = 14.sp, @@ -211,16 +220,22 @@ fun DetailEdit() { @Composable fun DetailForm() { var detail by remember { mutableStateOf("") } + var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 + Box( modifier = Modifier .padding(PADDING_16) .fillMaxSize() .border( - color = EditStroke, + color = if (isTextEmpty) EditStroke + else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) - .background(color = QuestionEditFill, shape = RoundedCornerShape(10.dp)), + .background( + color = if (isTextEmpty) QuestionEditFill + else QuestionChangeFill, + shape = RoundedCornerShape(10.dp)), contentAlignment = Alignment.TopStart // 정렬 ) { @@ -229,12 +244,14 @@ fun DetailForm() { onValueChange = { newText -> // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 detail = newText + isTextEmpty = newText.isBlank() }, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start ), - modifier = Modifier.padding(PADDING_16) + modifier = Modifier + .padding(PADDING_16) ) if (detail.isEmpty()) { Text( diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt index 63a9bc0..8c632a2 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt @@ -42,6 +42,10 @@ val EditText = Color(0xFF737373) val EditStroke = Color(0xFFE7E7E7) val EditButtonFalse = Color(0xFFD9D9D9) val EditDivider = Color(0xFF757575) +val EditChangeStroke = Color(0xFFBEB7AD) +val EditChangeFill = Color(0xFFF5F4F2) +val EditChangeButtonFill = Color(0xFF3C270A) + // 문의 및 오류 제보 색상 val QuestionSubTitle = Color(0xFF454545) From 18801fc5e71bab04fdf37d2119044f6105dc173e Mon Sep 17 00:00:00 2001 From: arinming Date: Fri, 11 Aug 2023 12:02:34 +0900 Subject: [PATCH 23/37] =?UTF-8?q?[refactor/mypage]=20=ED=94=84=EB=A1=9C?= =?UTF-8?q?=ED=95=84=20=EB=B3=80=EA=B2=BD,=20=EB=AC=B8=EC=9D=98=ED=95=98?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=EC=A0=9C=EB=B3=B4=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?ViewModel=EB=A1=9C=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84=20?= =?UTF-8?q?(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../myPage/profile/MyPageProfileContract.kt | 3 +- .../ui/myPage/profile/MyPageProfileScreen.kt | 55 +++++++----- .../myPage/profile/MyPageProfileViewModel.kt | 14 ++- .../question/MyPageQuestionConstract.kt | 9 +- .../myPage/question/MyPageQuestionScreen.kt | 90 +++++++++++-------- .../question/MyPageQuestionViewModel.kt | 21 ++++- 6 files changed, 124 insertions(+), 68 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 5244b89..9c8e6b9 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -11,11 +11,12 @@ class MyPageProfileContract { val loadState: LoadState = LoadState.SUCCESS, val nickName: String = "", val nickNameHint: String = "", + val isFilled: Boolean = false, val isError: Boolean = true ) : ViewState sealed class MyPageProfileSideEffect: ViewSideEffect { - object NavigateToPrevious : MyPageProfileSideEffect() + object NavigateToPreviousScreen : MyPageProfileSideEffect() } sealed class MyPageProfileEvent: ViewEvent { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index fadbce3..c9d5f5e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -35,20 +35,25 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController +import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.ui.theme.ButtonContent import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditChangeFill import com.meongmoryteam.presentation.ui.theme.EditChangeStroke import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme +import com.meongmoryteam.presentation.ui.theme.Orange import kotlinx.coroutines.flow.collect val PADDING_16 = 16.dp @@ -83,7 +88,7 @@ fun MyPageProfileScreen( onBackClick = { navigateToPrevious refreshButton.value = true - }, + } ) ProfileChangeEdit() } @@ -91,7 +96,9 @@ fun MyPageProfileScreen( Modifier.fillMaxHeight(), Arrangement.Bottom ) { - ProfileChangeButton() + ProfileChangeButton( + isFilled = uiState.isFilled + ) } } } @@ -195,10 +202,17 @@ fun ProfileChangeExplain() { @Composable fun ProfileChangeEdit( + viewModel: MyPageProfileViewModel = hiltViewModel() ) { + val uiState by viewModel.viewState.collectAsState() Column { ProfileChangeLabel() - MyPageEditForm() + MyPageEditForm( + value = uiState.nickName, + isOverflow = uiState.isError + ) { + viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.FillNickName(it)) + } ProfileChangeExplain() } } @@ -206,22 +220,23 @@ fun ProfileChangeEdit( @Composable fun MyPageEditForm( + value: String, + isOverflow: Boolean, + onValueChange: (String) -> Unit, ) { - var text by remember { mutableStateOf("") } - var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 - Box( modifier = Modifier .padding(PADDING_16) .fillMaxWidth() .height(48.dp) .background( - if (isTextEmpty) Color.White + if (value.isEmpty()) Color.White else EditChangeFill ) .border( color = - if (isTextEmpty) EditStroke + if (value.isEmpty()) EditStroke + else if (isOverflow) Color.Red else EditChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp) @@ -229,12 +244,8 @@ fun MyPageEditForm( contentAlignment = Alignment.CenterStart // 정렬 ) { BasicTextField( - value = text, - onValueChange = { newText -> - // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 - text = newText.replace(Regex("[\n]"), "") - isTextEmpty = newText.isBlank() // Text가 비어있는지 여부 업데이트 - }, + value = value, + onValueChange = onValueChange, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start @@ -242,7 +253,7 @@ fun MyPageEditForm( modifier = Modifier.padding(start = PADDING_16, end = PADDING_16) ) - if (text.isEmpty()) { + if (value.isEmpty()) { Text( text = stringResource(R.string.profile_now_nickname), color = EditText, @@ -254,19 +265,18 @@ fun MyPageEditForm( @Composable fun ProfileChangeButton( + isFilled: Boolean, viewModel: MyPageProfileViewModel = hiltViewModel() ) { - val uiState by viewModel.viewState.collectAsState() - - val buttonColors = ButtonDefaults.buttonColors( - contentColor = Color.White - ) - Button( onClick = { viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) }, - colors = ButtonDefaults.buttonColors(EditButtonFalse), + colors = if (!isFilled) { + ButtonDefaults.textButtonColors(LightGrey) + } else { + ButtonDefaults.textButtonColors(Orange) + }, modifier = Modifier .padding(16.dp) .fillMaxWidth() @@ -276,6 +286,7 @@ fun ProfileChangeButton( Text( text = stringResource(R.string.profile_change_button), fontSize = 15.sp, + color = ButtonContent ) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index b0f8487..c76c93f 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -1,6 +1,5 @@ package com.meongmoryteam.presentation.ui.myPage.profile -import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState @@ -18,7 +17,7 @@ class MyPageProfileViewModel @Inject constructor( ) { override fun handleEvents(event: MyPageProfileEvent) { when (event) { - MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") + is MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") is MyPageProfileEvent.FillNickName -> reflectUpdatedState(event.nickName) MyPageProfileEvent.OnClickChangeButton -> changeNickName(viewState.value.nickName) } @@ -30,20 +29,27 @@ class MyPageProfileViewModel @Inject constructor( updateState { copy( nickName = nickName, - isError = isOverflowed(nickName) + isError = isOverflowed(nickName), + isFilled = isFilled(nickName) ) } } private fun changeNickName(nickName: String) = viewModelScope.launch { updateState { copy( loadState = LoadState.SUCCESS) } - sendEffect({ MyPageProfileSideEffect.NavigateToPrevious }) + sendEffect({ MyPageProfileSideEffect.NavigateToPreviousScreen }) } // 텍스트 길이 초과 private fun isOverflowed(nickName: String): Boolean { return nickName.isBlank() || (nickName.length > MAX_LENGTH_NICKNAME) } + + private fun isFilled( + nickName: String + ) : Boolean { + return (nickName.isNotEmpty()) + } } const val MAX_LENGTH_NICKNAME = 6 diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt index 1553182..8c02ca2 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt @@ -10,18 +10,23 @@ class MyPageQuestionConstract { val loadState: LoadState = LoadState.SUCCESS, val email: String = "", val question: String = "", - val isError: Boolean = true + val isError: Boolean = true, + val isAllFilled: Boolean = false, ) : ViewState sealed class MyPageQuestionSideEffect: ViewSideEffect { - object NavigateToHome : MyPageQuestionSideEffect() + object NavigateToPreviousScreen : MyPageQuestionSideEffect() } sealed class MyPageQuestionEvent: ViewEvent { data class FillEmail( val email: String ): MyPageQuestionEvent() + data class FillQuestion( + val question: String + ): MyPageQuestionEvent() object ClearEmail: MyPageQuestionEvent() + object ClearQuestion: MyPageQuestionEvent() object OnClickButton: MyPageQuestionEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index c7905ba..9c61ca7 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -43,8 +43,11 @@ import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText +import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme +import com.meongmoryteam.presentation.ui.theme.Orange import com.meongmoryteam.presentation.ui.theme.QuestionButtonText +import com.meongmoryteam.presentation.ui.theme.QuestionChangeButtonFill import com.meongmoryteam.presentation.ui.theme.QuestionChangeFill import com.meongmoryteam.presentation.ui.theme.QuestionChangeStroke import com.meongmoryteam.presentation.ui.theme.QuestionEditFill @@ -52,14 +55,14 @@ import com.meongmoryteam.presentation.ui.theme.QuestionSubTitle val PADDING_8 = 8.dp val PADDING_16 = 16.dp -val PADDING_24 = 24.dp @Composable fun MyPageQuestionScreen( - viewModel: MyPageProfileViewModel = hiltViewModel(), + viewModel: MyPageQuestionViewModel = hiltViewModel(), navigateToPrevious: () -> Unit, ) { + val uiState by viewModel.viewState.collectAsState() val refreshButton = remember { mutableStateOf(false) } @@ -87,7 +90,9 @@ fun MyPageQuestionScreen( modifier = Modifier.fillMaxHeight(), contentAlignment = Alignment.BottomCenter ) { - QuestionButton() + QuestionButton( + isAllFilled = uiState.isAllFilled + ) } } // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 @@ -99,14 +104,21 @@ fun MyPageQuestionScreen( } @Composable -fun EmailEdit() { +fun EmailEdit( + viewModel: MyPageQuestionViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() Column { QuestionLabel(stringResource(R.string.question_email_form_title)) Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, ) { - EmailForm() + EmailForm( + value = uiState.email + ) { + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.FillEmail(it)) + } Text(text = stringResource(R.string.question_at)) EmailSelect() } @@ -133,35 +145,32 @@ fun QuestionLabel( @Composable -fun EmailForm() { - var email by remember { mutableStateOf("") } - var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 - +fun EmailForm( + value: String, + onValueChange: (String) -> Unit +) { Box( modifier = Modifier .padding(all = PADDING_16) .height(48.dp) .fillMaxWidth(0.5f) .border( - color = if (isTextEmpty) EditStroke + color = if (value.isEmpty()) EditStroke else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) .background( - color = if (isTextEmpty) QuestionEditFill + color = if (value.isEmpty()) QuestionEditFill else QuestionChangeFill, - shape = RoundedCornerShape(10.dp)), + shape = RoundedCornerShape(10.dp) + ), contentAlignment = Alignment.CenterStart // 정렬 ) { BasicTextField( - value = email, - onValueChange = { newText -> - // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 - email = newText.replace(Regex("[\n]"), "") - isTextEmpty = newText.isBlank() - }, + value = value, + onValueChange = onValueChange, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start @@ -169,7 +178,7 @@ fun EmailForm() { modifier = Modifier.padding(start = PADDING_16, end = PADDING_16) ) - if (email.isEmpty()) { + if (value.isEmpty()) { Text( text = stringResource(R.string.question_email_form_hint), color = EditText, @@ -212,40 +221,44 @@ fun EmailSelect() { @Composable -fun DetailEdit() { +fun DetailEdit( + viewModel: MyPageQuestionViewModel = hiltViewModel() +) { + val uiState by viewModel.viewState.collectAsState() QuestionLabel(stringResource(R.string.question_content_title)) - DetailForm() + DetailForm( + value = uiState.question + ) { + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.FillQuestion(it)) + } } @Composable -fun DetailForm() { - var detail by remember { mutableStateOf("") } - var isTextEmpty by remember { mutableStateOf(true) } // Text가 비어있는지 여부를 추적 - +fun DetailForm( + value: String, + onValueChange: (String) -> Unit +) { Box( modifier = Modifier .padding(PADDING_16) .fillMaxSize() .border( - color = if (isTextEmpty) EditStroke + color = if (value.isEmpty()) EditStroke else QuestionChangeStroke, width = 1.dp, shape = RoundedCornerShape(10.dp), ) .background( - color = if (isTextEmpty) QuestionEditFill + color = if (value.isEmpty()) QuestionEditFill else QuestionChangeFill, - shape = RoundedCornerShape(10.dp)), + shape = RoundedCornerShape(10.dp) + ), contentAlignment = Alignment.TopStart // 정렬 ) { BasicTextField( - value = detail, - onValueChange = { newText -> - // 한 줄만 입력 가능하게 \n키를 누르면 입력 반영 안함 - detail = newText - isTextEmpty = newText.isBlank() - }, + value = value, + onValueChange = onValueChange, textStyle = TextStyle( fontSize = 14.sp, textAlign = TextAlign.Start @@ -253,7 +266,7 @@ fun DetailForm() { modifier = Modifier .padding(PADDING_16) ) - if (detail.isEmpty()) { + if (value.isEmpty()) { Text( text = stringResource(R.string.question_content_detail), color = EditText, @@ -267,6 +280,7 @@ fun DetailForm() { @Composable fun QuestionButton( + isAllFilled: Boolean, viewModel: MyPageQuestionViewModel = hiltViewModel() ) { val uiState by viewModel.viewState.collectAsState() @@ -274,7 +288,11 @@ fun QuestionButton( onClick = { viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickButton) }, - colors = ButtonDefaults.buttonColors(EditButtonFalse), + colors = if (!isAllFilled) { + ButtonDefaults.textButtonColors(LightGrey) + } else { + ButtonDefaults.textButtonColors(QuestionChangeButtonFill) + }, modifier = Modifier .padding(16.dp) .fillMaxWidth() diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt index 179893f..83f2736 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -17,18 +17,26 @@ class MyPageQuestionViewModel @Inject constructor( ) { override fun handleEvents(event: MyPageQuestionEvent) { when (event) { - MyPageQuestionEvent.ClearEmail -> reflectUpdatedState("") - is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(event.email) + MyPageQuestionEvent.ClearEmail -> reflectUpdatedState(email = "") + MyPageQuestionEvent.ClearQuestion -> reflectUpdatedState(question = "") + is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(email = event.email) + is MyPageQuestionEvent.FillQuestion -> reflectUpdatedState(question = event.question) MyPageQuestionEvent.OnClickButton -> setEmail(viewState.value.email) } } private fun reflectUpdatedState( - email: String = viewState.value.email + email: String = viewState.value.email, + question: String = viewState.value.question ) { updateState { copy( email = email, + question = question, + isAllFilled = isFilled( + email, + question + ) ) } } @@ -40,4 +48,11 @@ class MyPageQuestionViewModel @Inject constructor( ) } } + + private fun isFilled( + email: String, + question: String, + ): Boolean { + return (email.isNotEmpty() && question.isNotEmpty()) + } } \ No newline at end of file From 708b5580332772511eee11b2a0747bb47df38cbb Mon Sep 17 00:00:00 2001 From: arinming Date: Fri, 11 Aug 2023 12:08:35 +0900 Subject: [PATCH 24/37] =?UTF-8?q?[refactor/mypage]=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=A0=95=EB=A6=AC=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/myPage/MyPageContract.kt | 12 ++++----- .../presentation/ui/myPage/MyPageScreen.kt | 26 ++----------------- .../presentation/ui/myPage/MyPageViewModel.kt | 2 ++ .../myPage/profile/MyPageProfileContract.kt | 9 ++++--- .../ui/myPage/profile/MyPageProfileScreen.kt | 18 ++++--------- .../myPage/profile/MyPageProfileViewModel.kt | 8 +++--- .../question/MyPageQuestionConstract.kt | 16 +++++++----- .../myPage/question/MyPageQuestionScreen.kt | 6 ----- .../question/MyPageQuestionViewModel.kt | 4 +-- 9 files changed, 35 insertions(+), 66 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt index 63c6eb3..133a348 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageContract.kt @@ -12,14 +12,14 @@ class MyPageContract { val isDialogVisible: Boolean = false ) : ViewState - sealed class MyPageSideEffect: ViewSideEffect { - object NavigateToEditProfile: MyPageSideEffect() - object NavigateToQuestion: MyPageSideEffect() + sealed class MyPageSideEffect : ViewSideEffect { + object NavigateToEditProfile : MyPageSideEffect() + object NavigateToQuestion : MyPageSideEffect() } - sealed class MyPageEvent: ViewEvent { + sealed class MyPageEvent : ViewEvent { object InitMyPageScreen : MyPageEvent() - object OnClickProfileEditButtonClicked: MyPageEvent() - object OnQuestionClicked: MyPageEvent() + object OnClickProfileEditButtonClicked : MyPageEvent() + object OnQuestionClicked : MyPageEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index e7dbf4a..fe60213 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -126,7 +126,6 @@ fun MyPageTitle() { text = stringResource(R.string.my_page_title), fontSize = 15.sp ) - } } @@ -177,8 +176,6 @@ fun MyPageProfile( onClick = OnClickEditNickname ) } - - } Text( modifier = Modifier.padding(bottom = 8.dp), @@ -186,10 +183,7 @@ fun MyPageProfile( fontSize = 10.sp ) } - } - - } } @@ -198,7 +192,6 @@ fun MyPageProfile( fun MyPageList( onQuestionClicked: () -> Unit, ) { - // 마이페이지 목록 부분 Row( modifier = Modifier @@ -218,7 +211,6 @@ fun MyPageList( color = ListTitle, fontSize = 11.sp ) - ListButton( R.drawable.ic_coin, stringResource(R.string.my_page_pro_ver), @@ -248,7 +240,6 @@ fun MyPageList( .padding(start = 24.dp, end = 24.dp) ) - Text( text = stringResource(R.string.my_page_support), fontWeight = FontWeight.Bold, @@ -268,7 +259,6 @@ fun MyPageList( onClick = onQuestionClicked, ) - Spacer(modifier = Modifier.padding(top = PADDING_16)) // 구분선 @@ -297,12 +287,8 @@ fun MyPageList( stringResource(R.string.my_page_personal), onClick = { }, ) - } - - } - } @Composable @@ -315,7 +301,6 @@ fun MyPageProfileButton( mutableStateOf(false) } Column(modifier = Modifier) { - Button( onClick = { onClick() @@ -329,7 +314,6 @@ fun MyPageProfileButton( contentPadding = PaddingValues(4.dp), colors = ButtonDefaults.buttonColors(MyPageProfileEditButton, Color.Black) ) { - if (buttonText != null) { Text( text = buttonText, @@ -357,14 +341,12 @@ fun ListButton( onClickAction: String? = null, onClick: () -> Unit, ) { - val openDialogCustom = remember { mutableStateOf(false) } val refreshButton = remember { mutableStateOf(false) } - Row( modifier = Modifier .fillMaxWidth() @@ -397,7 +379,6 @@ fun ListButton( fontSize = 12.sp ) } - Box( modifier = Modifier .padding() @@ -410,7 +391,8 @@ fun ListButton( openDialogCustom.value = true if (onClickAction != null) { refreshButton.value = true - }}, + } + }, colors = ButtonDefaults.buttonColors(Color.Transparent, ListNextButton) ) { Icon( @@ -420,19 +402,15 @@ fun ListButton( } } } - // 버튼마다 다른 다이어로그 if (openDialogCustom.value) { if (onClickAction == stringResource(R.string.my_page_logout)) { LogoutAlertDialog(openDialogCustom = openDialogCustom) } - if (onClickAction == stringResource(R.string.my_page_drop)) { SecessionAlertDialog(openDialogCustom = openDialogCustom) } - } - } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt index 6a88862..3242535 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -19,9 +19,11 @@ class MyPageViewModel @Inject constructor( is MyPageEvent.InitMyPageScreen -> { updateState { copy(loadState = LoadState.SUCCESS) } } + is MyPageEvent.OnClickProfileEditButtonClicked -> { sendEffect({ MyPageSideEffect.NavigateToEditProfile }) } + is MyPageEvent.OnQuestionClicked -> { sendEffect({ MyPageSideEffect.NavigateToQuestion }) } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 9c8e6b9..2887f82 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -15,15 +15,16 @@ class MyPageProfileContract { val isError: Boolean = true ) : ViewState - sealed class MyPageProfileSideEffect: ViewSideEffect { + sealed class MyPageProfileSideEffect : ViewSideEffect { object NavigateToPreviousScreen : MyPageProfileSideEffect() } - sealed class MyPageProfileEvent: ViewEvent { + sealed class MyPageProfileEvent : ViewEvent { data class FillNickName( val nickName: String ) : MyPageProfileEvent() - object ClearNickName: MyPageProfileEvent() - object OnClickChangeButton: MyPageProfileEvent() + + object ClearNickName : MyPageProfileEvent() + object OnClickChangeButton : MyPageProfileEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index c9d5f5e..f953443 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -25,27 +25,20 @@ import androidx.compose.runtime.collectAsState 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.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.viewmodel.compose.viewModel -import androidx.navigation.NavController -import androidx.navigation.compose.rememberNavController import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.theme.ButtonContent -import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditChangeFill import com.meongmoryteam.presentation.ui.theme.EditChangeStroke import com.meongmoryteam.presentation.ui.theme.EditDivider @@ -54,7 +47,6 @@ import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.Orange -import kotlinx.coroutines.flow.collect val PADDING_16 = 16.dp val PADDING_24 = 24.dp @@ -86,7 +78,6 @@ fun MyPageProfileScreen( MyPageToolBar( stringResource(R.string.profile_change_title), onBackClick = { - navigateToPrevious refreshButton.value = true } ) @@ -97,7 +88,8 @@ fun MyPageProfileScreen( Arrangement.Bottom ) { ProfileChangeButton( - isFilled = uiState.isFilled + isFilled = uiState.isFilled, + isOverflow = uiState.isError ) } } @@ -120,7 +112,7 @@ fun MyPageToolBar( val refreshButton = remember { mutableStateOf(false) } - Column() { + Column { // 위 아래 여백 Row( modifier = Modifier @@ -169,7 +161,6 @@ fun MyPageToolBar( } - @Composable fun ProfileChangeLabel() { Box( @@ -266,13 +257,14 @@ fun MyPageEditForm( @Composable fun ProfileChangeButton( isFilled: Boolean, + isOverflow: Boolean, viewModel: MyPageProfileViewModel = hiltViewModel() ) { Button( onClick = { viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) }, - colors = if (!isFilled) { + colors = if (!isFilled || isOverflow) { ButtonDefaults.textButtonColors(LightGrey) } else { ButtonDefaults.textButtonColors(Orange) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index c76c93f..280b3d9 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -19,7 +19,7 @@ class MyPageProfileViewModel @Inject constructor( when (event) { is MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") is MyPageProfileEvent.FillNickName -> reflectUpdatedState(event.nickName) - MyPageProfileEvent.OnClickChangeButton -> changeNickName(viewState.value.nickName) + MyPageProfileEvent.OnClickChangeButton -> changeNickName() } } @@ -35,8 +35,8 @@ class MyPageProfileViewModel @Inject constructor( } } - private fun changeNickName(nickName: String) = viewModelScope.launch { - updateState { copy( loadState = LoadState.SUCCESS) } + private fun changeNickName() = viewModelScope.launch { + updateState { copy(loadState = LoadState.SUCCESS) } sendEffect({ MyPageProfileSideEffect.NavigateToPreviousScreen }) } @@ -47,7 +47,7 @@ class MyPageProfileViewModel @Inject constructor( private fun isFilled( nickName: String - ) : Boolean { + ): Boolean { return (nickName.isNotEmpty()) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt index 8c02ca2..9669acb 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt @@ -14,19 +14,21 @@ class MyPageQuestionConstract { val isAllFilled: Boolean = false, ) : ViewState - sealed class MyPageQuestionSideEffect: ViewSideEffect { + sealed class MyPageQuestionSideEffect : ViewSideEffect { object NavigateToPreviousScreen : MyPageQuestionSideEffect() } - sealed class MyPageQuestionEvent: ViewEvent { + sealed class MyPageQuestionEvent : ViewEvent { data class FillEmail( val email: String - ): MyPageQuestionEvent() + ) : MyPageQuestionEvent() + data class FillQuestion( val question: String - ): MyPageQuestionEvent() - object ClearEmail: MyPageQuestionEvent() - object ClearQuestion: MyPageQuestionEvent() - object OnClickButton: MyPageQuestionEvent() + ) : MyPageQuestionEvent() + + object ClearEmail : MyPageQuestionEvent() + object ClearQuestion : MyPageQuestionEvent() + object OnClickButton : MyPageQuestionEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index 9c61ca7..7e7534b 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -25,7 +25,6 @@ import androidx.compose.runtime.collectAsState 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.graphics.vector.ImageVector @@ -38,14 +37,11 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R -import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileViewModel import com.meongmoryteam.presentation.ui.myPage.profile.MyPageToolBar -import com.meongmoryteam.presentation.ui.theme.EditButtonFalse import com.meongmoryteam.presentation.ui.theme.EditStroke import com.meongmoryteam.presentation.ui.theme.EditText import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme -import com.meongmoryteam.presentation.ui.theme.Orange import com.meongmoryteam.presentation.ui.theme.QuestionButtonText import com.meongmoryteam.presentation.ui.theme.QuestionChangeButtonFill import com.meongmoryteam.presentation.ui.theme.QuestionChangeFill @@ -75,7 +71,6 @@ fun MyPageQuestionScreen( MyPageToolBar( stringResource(R.string.question_title), onBackClick = { - navigateToPrevious refreshButton.value = true } ) @@ -283,7 +278,6 @@ fun QuestionButton( isAllFilled: Boolean, viewModel: MyPageQuestionViewModel = hiltViewModel() ) { - val uiState by viewModel.viewState.collectAsState() Button( onClick = { viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickButton) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt index 83f2736..c19918c 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -21,7 +21,7 @@ class MyPageQuestionViewModel @Inject constructor( MyPageQuestionEvent.ClearQuestion -> reflectUpdatedState(question = "") is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(email = event.email) is MyPageQuestionEvent.FillQuestion -> reflectUpdatedState(question = event.question) - MyPageQuestionEvent.OnClickButton -> setEmail(viewState.value.email) + MyPageQuestionEvent.OnClickButton -> setEmail() } } @@ -41,7 +41,7 @@ class MyPageQuestionViewModel @Inject constructor( } } - private fun setEmail(email: String) = viewModelScope.launch { + private fun setEmail() = viewModelScope.launch { updateState { copy( loadState = LoadState.LOADING From 623ba3ec9e95d44e01731543ac5d9f786e22a611 Mon Sep 17 00:00:00 2001 From: arinming Date: Sun, 13 Aug 2023 11:08:20 +0900 Subject: [PATCH 25/37] =?UTF-8?q?[refactor/mypage]=20MainViewModel=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=BD=94=EB=93=9C=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 1 + .../presentation/ui/main/HomeScreen.kt | 2 -- .../presentation/ui/main/MainContract.kt | 17 ----------------- .../presentation/ui/main/MainViewModel.kt | 17 ----------------- .../presentation/ui/map/MapScreen.kt | 12 +++++++----- .../presentation/ui/myPage/MyPageScreen.kt | 14 +------------- .../presentation/util/ActivityViewModelExt.kt | 14 -------------- 7 files changed, 9 insertions(+), 68 deletions(-) delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt diff --git a/build.gradle.kts b/build.gradle.kts index b816fd0..0f72e95 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -4,6 +4,7 @@ buildscript { google() mavenCentral() gradlePluginPortal() + maven("https://naver.jfrog.io/artifactory/maven/") } dependencies { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt index 5f6f2ba..51ade5c 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt @@ -27,10 +27,8 @@ import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen @Composable fun MainScreen( - viewModel: MainViewModel = hiltViewModel(), navController: NavHostController = rememberNavController(), ) { - val viewState by viewModel.viewState.collectAsState() val navBackStackEntry by navController.currentBackStackEntryAsState() val currentDestination = navBackStackEntry?.destination var bottomBarState by rememberSaveable { mutableStateOf(true) } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt deleted file mode 100644 index 34aab94..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.meongmoryteam.presentation.ui.main - -import com.meongmoryteam.presentation.base.ViewEvent -import com.meongmoryteam.presentation.base.ViewSideEffect -import com.meongmoryteam.presentation.base.ViewState - -class MainContract { - object MainViewState : ViewState - - sealed class MainSideEffect : ViewSideEffect { - object RefreshScreen : MainSideEffect() - } - - sealed class MainEvent : ViewEvent { - object FinishedCreateActivity : MainEvent() - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt deleted file mode 100644 index 00d32b6..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.meongmoryteam.presentation.ui.main - -import com.meongmoryteam.presentation.base.BaseViewModel -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import com.meongmoryteam.presentation.ui.main.MainContract.* - -@HiltViewModel -class MainViewModel @Inject constructor( -) : BaseViewModel(MainViewState) { - override fun handleEvents(event: MainEvent) { - when (event) { - is MainEvent.FinishedCreateActivity-> { - } - } - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/map/MapScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/map/MapScreen.kt index 82dd220..51b68b0 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/map/MapScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/map/MapScreen.kt @@ -3,18 +3,20 @@ package com.meongmoryteam.presentation.ui.map import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview +import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme @Composable -fun MapScreen( - -) { +fun MapScreen() { Text( text = "MapScreen", ) } -@Preview +@Preview(showBackground = true) + @Composable fun MapScreenPreview() { - MapScreen() + MeongmoryTheme { + MapScreen() + } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index fe60213..bc56ea6 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -41,8 +41,6 @@ import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog -import com.meongmoryteam.presentation.ui.main.MainContract -import com.meongmoryteam.presentation.ui.main.MainViewModel import com.meongmoryteam.presentation.ui.theme.ListDivider import com.meongmoryteam.presentation.ui.theme.ListNextButton import com.meongmoryteam.presentation.ui.theme.ListTitle @@ -50,14 +48,12 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.MyPageProfileEditButton import com.meongmoryteam.presentation.ui.theme.MyPageYellowFill import com.meongmoryteam.presentation.ui.theme.MyPageYellowStroke -import com.meongmoryteam.presentation.util.composableActivityViewModel val PADDING_8 = 8.dp val PADDING_16 = 16.dp @Composable fun MyPageScreen( - mainViewModel: MainViewModel = composableActivityViewModel(), viewModel: MyPageViewModel = hiltViewModel(), navigateToEditNickNameScreen: () -> Unit, navigateToQuestionScreen: () -> Unit, @@ -82,15 +78,7 @@ fun MyPageScreen( } } - LaunchedEffect(mainViewModel.effect) { - mainViewModel.effect.collect { effect -> - when (effect) { - is MainContract.MainSideEffect.RefreshScreen -> { - viewModel.setEvent(MyPageContract.MyPageEvent.InitMyPageScreen) - } - } - } - } + when (viewState.loadState) { LoadState.SUCCESS -> { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt b/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt deleted file mode 100644 index 6a7c402..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.meongmoryteam.presentation.util - -import androidx.activity.ComponentActivity -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewmodel.compose.viewModel - -@Composable -fun getActivity() = LocalContext.current as ComponentActivity - -@Composable -inline fun composableActivityViewModel( -) : VM = viewModel(getActivity()) \ No newline at end of file From 382de38e7ed69da038348409ef40244db18c1183 Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Sun, 6 Aug 2023 21:55:27 +0900 Subject: [PATCH 26/37] =?UTF-8?q?feat:=20=EA=B0=95=EC=95=84=EC=A7=80=20?= =?UTF-8?q?=ED=92=88=EC=A2=85=20=EA=B2=80=EC=83=89=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 16 +- .../ui/register_dog/RegisterDogActivity.kt | 13 +- .../ui/register_dog/RegisterDogContract.kt | 9 +- .../ui/register_dog/RegisterDogScreen.kt | 50 ++-- .../ui/register_dog/RegisterDogViewModel.kt | 27 ++- .../ui/register_dog/SearchBreedScreen.kt | 220 ++++++++++++++++++ .../register_family/RegisterFamilyActivity.kt | 4 +- .../register_family/RegisterFamilyScreen.kt | 8 +- .../ui/register_family/RegisterForm.kt | 18 +- .../invitation/RegisterByCodeScreen.kt | 4 +- .../name/RegisterByNameScreen.kt | 2 +- .../presentation/ui/theme/Color.kt | 1 - presentation/src/main/res/values/strings.xml | 5 + 13 files changed, 314 insertions(+), 63 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 09a8ea8..b42f373 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,21 +20,21 @@ android:label="@string/app_name" android:theme="@style/Theme.Meongmory"> - - + + - - + + - - + + - - + + Unit ) { val viewState by viewModel.viewState.collectAsState() - val buttonItemList = listOf(ButtonItem(0, "수컷"), ButtonItem(1, "암컷")) + val buttonItemList = listOf("수컷", "암컷") val coroutineScope = rememberCoroutineScope() val focusManager = LocalFocusManager.current val bringIntoViewRequester = BringIntoViewRequester() + val scrollState = rememberScrollState() RegisterDogForm( bottomPadding = 0.dp, - navController = navController, + navController = navController, modifier = Modifier.verticalScroll(state = scrollState), navigateTo = { viewModel.setEvent(RegisterDogEvent.OnClickBackButton) }) { RenderProfile() RenderName(value = viewState.name) { viewModel.setEvent(RegisterDogEvent.FillInName(it)) } - RenderBreed(value = viewState.breed, onValueChange = { - viewModel.setEvent( - RegisterDogEvent.FillInBreed( - it - ) - ) - }) { viewModel.setEvent(RegisterDogEvent.OnClickSearchButton) } + RenderBreed( + value = viewState.breed, + onValueChange = { viewModel.setEvent(RegisterDogEvent.FillInBreed(it)) } + ) { viewModel.setEvent(RegisterDogEvent.OnClickSearchButton) } RenderGender( label = R.string.gender, - buttonItem = buttonItemList - ) + buttonItem = buttonItemList, + value = viewState.gender + ) { viewModel.setEvent(RegisterDogEvent.OnGenderClicked(it)) } RenderAge(value = viewState.age) { viewModel.setEvent(RegisterDogEvent.FillInAge(it)) } RenderAdoptionDate( year = viewState.year, @@ -184,23 +183,24 @@ fun RenderName(value: String, onValueChange: (String) -> Unit) { @Composable fun RenderBreed(value: String, onValueChange: (String) -> Unit, navigateToSearch: () -> Unit) { - Box(contentAlignment = Alignment.BottomEnd) { + Box(contentAlignment = Alignment.CenterEnd) { LabelNInputForm( label = R.string.breed, placeholder = R.string.breed, value = value, onValueChange = onValueChange ) - SearchButton(navigateToSearch) + SearchButton(padding = 15.dp, navigateToSearch) } } @Composable fun RenderGender( label: Int, - buttonItem: List + buttonItem: List, + value: String, + onValueChange: (String) -> Unit ) { - var selectedIndex by rememberSaveable { mutableStateOf(-1) } Column( modifier = Modifier .padding(bottom = 14.dp) @@ -223,10 +223,10 @@ fun RenderGender( items(buttonItem) { item -> GenderButton( item = item, - isSelected = selectedIndex == item.index, + isSelected = value == item, ) { - selectedIndex = item.index + onValueChange(item) } } } @@ -316,7 +316,7 @@ fun RenderRegisterButton( color = ButtonContent, platformStyle = PlatformTextStyle(includeFontPadding = false) ), - modifier = Modifier.bringIntoViewRequester(bringIntoViewRequester), + modifier = Modifier.bringIntoViewRequester(bringIntoViewRequester).padding(bottom = 30.dp), onClick = navigateTo ) } @@ -360,12 +360,12 @@ fun LabelNInputForm( } @Composable -fun SearchButton(navigateToSearch: () -> Unit) { +fun SearchButton(padding: Dp = 0.dp, navigateToSearch: () -> Unit) { IconButton( onClick = navigateToSearch, modifier = Modifier .size(45.dp) - .padding(bottom = 25.dp) + .padding(top = padding) ) { Icon( painter = painterResource(R.drawable.search), @@ -377,7 +377,7 @@ fun SearchButton(navigateToSearch: () -> Unit) { @Composable fun GenderButton( - item: ButtonItem, + item: String, isSelected: Boolean, modifier: Modifier = Modifier, onTap: () -> Unit @@ -407,7 +407,7 @@ fun GenderButton( contentAlignment = Alignment.Center ) { Text( - text = item.label, + text = item, color = contentColor, style = Typography.titleSmall, ) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt index 5f64b50..36f060a 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt @@ -21,7 +21,8 @@ class RegisterDogViewModel @Inject constructor() : is RegisterDogEvent.FillInMonth -> reflectUpdateState(month = event.month) is RegisterDogEvent.FillInDay -> reflectUpdateState(day = event.day) is RegisterDogEvent.FillInRegistrationNum -> reflectUpdateState(registrationNumber = event.num) - + is RegisterDogEvent.OnPetTypeClicked -> reflectUpdateState(petType = event.petType) + is RegisterDogEvent.OnGenderClicked -> reflectUpdateState(gender = event.gender) is RegisterDogEvent.OnClickSearchButton -> sendEffect({ RegisterDogSideEffect.NavigateToSearchBreedScreen }) is RegisterDogEvent.OnClickBackButton -> sendEffect({ RegisterDogSideEffect.NavigateToPreviousScreen }) is RegisterDogEvent.OnClickMakeButton -> sendEffect({ RegisterDogSideEffect.NavigateToNextScreen }) @@ -35,7 +36,9 @@ class RegisterDogViewModel @Inject constructor() : year: String = viewState.value.year, month: String = viewState.value.month, day: String = viewState.value.day, - registrationNumber: String = viewState.value.registrationNumber + registrationNumber: String = viewState.value.registrationNumber, + petType: String = viewState.value.petType, + gender: String = viewState.value.gender ) { updateState { copy( @@ -46,6 +49,8 @@ class RegisterDogViewModel @Inject constructor() : month = month, day = day, registrationNumber = registrationNumber, + petType = petType, + gender = gender, isAllFilled = isFilled( name, breed, @@ -53,8 +58,10 @@ class RegisterDogViewModel @Inject constructor() : year, month, day, - registrationNumber - ) + registrationNumber, + gender + ), + isSelected = isConfirmed(petType, breed) ) } } @@ -66,8 +73,16 @@ class RegisterDogViewModel @Inject constructor() : year: String, month: String, day: String, - registrationNumber: String + registrationNumber: String, + gender: String ): Boolean { - return (name.isNotEmpty() && breed.isNotEmpty() && age.isNotEmpty() && year.isNotEmpty() && month.isNotEmpty() && day.isNotEmpty() && registrationNumber.isNotEmpty()) + return (name.isNotEmpty() && breed.isNotEmpty() && age.isNotEmpty() && year.isNotEmpty() && month.isNotEmpty() && day.isNotEmpty() && registrationNumber.isNotEmpty() && gender.isNotEmpty()) + } + + private fun isConfirmed( + petType: String, + breed: String + ): Boolean{ + return (petType.isNotEmpty() && breed.isNotEmpty()) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt new file mode 100644 index 0000000..33eb731 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt @@ -0,0 +1,220 @@ +@file:OptIn(ExperimentalFoundationApi::class) + +package com.meongmoryteam.presentation.ui.register_dog + +import android.util.Log +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyRow +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.relocation.BringIntoViewRequester +import androidx.compose.foundation.relocation.bringIntoViewRequester +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.ButtonDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.PlatformTextStyle +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.RegisterDogEvent +import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.RegisterDogSideEffect +import com.meongmoryteam.presentation.ui.register_family.RegisterDogForm +import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent +import com.meongmoryteam.presentation.ui.register_family.TextFieldComponent +import com.meongmoryteam.presentation.ui.theme.Black +import com.meongmoryteam.presentation.ui.theme.ButtonContent +import com.meongmoryteam.presentation.ui.theme.InputBoxOutline +import com.meongmoryteam.presentation.ui.theme.LightGrey +import com.meongmoryteam.presentation.ui.theme.LightYellow +import com.meongmoryteam.presentation.ui.theme.NotoSansKR +import com.meongmoryteam.presentation.ui.theme.Orange +import com.meongmoryteam.presentation.ui.theme.QuestionEditFill +import com.meongmoryteam.presentation.ui.theme.Yellow + +@Composable +fun SearchBreedScreen( + navController: NavController, + viewModel: RegisterDogViewModel = hiltViewModel(), + navigateToPreviousScreen: () -> Unit, + navigateToSelectScreen: () -> Unit +) { + val buttonItemList = listOf("강아지", "고양이") + val searchList = listOf(Breed("말티즈", "강아지"), Breed("말티즈", "고양이"), Breed("푸들", "강아지"), Breed("푸들", "고양이"), ) + val viewState by viewModel.viewState.collectAsState() + val coroutineScope = rememberCoroutineScope() + val focusManager = LocalFocusManager.current + val bringIntoViewRequester = BringIntoViewRequester() + + RegisterDogForm( + navController = navController, + title = stringResource(R.string.search_breed), + bottomPadding = 20.dp, + verticalArrangement = Arrangement.Top, + navigateTo = { viewModel.setEvent(RegisterDogEvent.OnClickBackButton) } + ) { + CategoryScreen( + buttonItem = buttonItemList, + petType = viewState.petType + ) { viewModel.setEvent(RegisterDogEvent.OnPetTypeClicked(it)) } + SearchScreen( + value = viewState.breed, + onValueChange = { + viewModel.setEvent( + RegisterDogEvent.FillInBreed(it) + ) + }, + navigateToSearch = { viewModel.setEvent(RegisterDogEvent.OnClickSearchButton) } + ) + SearchList(searchList = searchList) + RenderSelectButton( + isSelected = viewState.isSelected, + bringIntoViewRequester = bringIntoViewRequester + ) { + viewModel.setEvent(RegisterDogEvent.OnClickMakeButton) + } + } + + LaunchedEffect(key1 = viewModel.effect) { + viewModel.effect.collect { effect -> + when (effect) { + is RegisterDogSideEffect.NavigateToPreviousScreen -> { + navigateToPreviousScreen() + } + + is RegisterDogSideEffect.NavigateToSearchBreedScreen -> {} + is RegisterDogSideEffect.NavigateToNextScreen -> { + navigateToSelectScreen() + } + } + } + } +} + +// +@Composable +fun CategoryScreen( + buttonItem: List, + petType: String, + onValueChange: (String) -> Unit +) { + LazyRow( + modifier = Modifier + .fillMaxWidth() + .padding(bottom = 20.dp), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + items(buttonItem) { item -> + GenderButton( + item = item, + isSelected = petType == item, + ) + { + onValueChange(item) + } + } + } +} + +@Composable +fun SearchScreen( + value: String, + modifier: Modifier = Modifier.fillMaxWidth(), + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default, + onValueChange: (String) -> Unit, + navigateToSearch: () -> Unit +) { + Box(contentAlignment = Alignment.CenterEnd) { + TextFieldComponent( + name = value, + onValueChange = onValueChange, + placeholder = stringResource(R.string.blank), + bgColor = if (value.isEmpty()) { + QuestionEditFill + } else { + LightYellow + }, + borderColor = if (value.isEmpty()) { + InputBoxOutline + } else { + Yellow + }, + modifier = modifier, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions + ) + SearchButton { navigateToSearch } + } +} + +@Composable +fun SearchList( + searchList: List +){ + LazyColumn( + modifier = Modifier.background(Black).fillMaxWidth().fillMaxHeight(0.85f) + ){ + items(searchList) { item -> + + } + } +} + +@Composable +fun RenderSelectButton( + isSelected: Boolean, + bringIntoViewRequester: BringIntoViewRequester, + navigateTo: () -> Unit +) { + TextButtonComponent( + text = stringResource(R.string.select), + colors = if (!isSelected) { + ButtonDefaults.textButtonColors(LightGrey) + } else { + ButtonDefaults.textButtonColors(Orange) + }, + style = TextStyle( + fontFamily = NotoSansKR, + fontWeight = FontWeight.W500, + fontSize = 15.sp, + lineHeight = 20.sp, + color = ButtonContent, + platformStyle = PlatformTextStyle(includeFontPadding = false) + ), + modifier = Modifier + .bringIntoViewRequester(bringIntoViewRequester) + .padding(bottom = 30.dp), + onClick = { + if(isSelected) navigateTo else {} + } + ) +} + +data class Breed( + val breed: String, + val category: String +) \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyActivity.kt index 90b7bdf..9f475e8 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyActivity.kt @@ -51,9 +51,9 @@ fun RegisterFamilyNavigation( composable(route = RouteScreen.Choose.route) { RegisterFamilyScreen( navController = navController, - navigatetoRegisterByName = { navController.navigate(RouteScreen.Name.route) }, + navigateToRegisterByName = { navController.navigate(RouteScreen.Name.route) }, navigateToRegisterByCode = { navController.navigate(RouteScreen.Code.route) }, - navigatetoPreviousScreen = { navController.popBackStack() } + navigateToPreviousScreen = { navController.popBackStack() } ) } composable(route = RouteScreen.Name.route) { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt index bcfcaa3..ac5815e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt @@ -25,8 +25,8 @@ fun RegisterFamilyScreen( navController: NavController, viewModel: RegisterFamilyViewModel = hiltViewModel(), navigateToRegisterByCode: () -> Unit, - navigatetoRegisterByName: () -> Unit, - navigatetoPreviousScreen: () -> Unit + navigateToRegisterByName: () -> Unit, + navigateToPreviousScreen: () -> Unit ) { RegisterDogForm(navController = navController) { Column { @@ -82,11 +82,11 @@ fun RegisterFamilyScreen( } RegisterFamilySideEffect.NavigateToRegisterNameScreen -> { - navigatetoRegisterByName() + navigateToRegisterByName() } RegisterFamilySideEffect.NavigateToPreviousScreen -> { - navigatetoPreviousScreen() + navigateToPreviousScreen() } RegisterFamilySideEffect.NavigateToNextScreen -> {} diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt index dea2be2..851c443 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt @@ -22,6 +22,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.ButtonColors +import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton @@ -58,20 +59,22 @@ fun RegisterDogForm( bottomPadding: Dp = 65.dp, navController: NavController, navigateTo: () -> Unit = { navController.navigate(RouteScreen.Choose.route) }, + title: String = "", + verticalArrangement: Arrangement.Vertical = Arrangement.SpaceBetween, + modifier: Modifier = Modifier, content: @Composable ColumnScope.() -> Unit ) { - val scrollState = rememberScrollState() Scaffold( modifier = Modifier.padding(horizontal = 6.dp), containerColor = White, topBar = { - TopAppBar( - title = { Text("") }, + CenterAlignedTopAppBar( + title = { Text(text = title, style = Typography.titleMedium) }, modifier = Modifier.padding(top = 15.dp, bottom = bottomPadding), colors = TopAppBarDefaults.topAppBarColors(White), navigationIcon = { IconButton( - onClick = navigateTo, + onClick = navigateTo, modifier = Modifier.size(30.dp) ) { @@ -96,10 +99,9 @@ fun RegisterDogForm( .padding(horizontal = 10.dp), ) { Column( - verticalArrangement = Arrangement.SpaceBetween, - modifier = Modifier - .fillMaxHeight() - .verticalScroll(state = scrollState), + verticalArrangement = verticalArrangement, + modifier = modifier + .fillMaxHeight(), horizontalAlignment = Alignment.CenterHorizontally ) { content() diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt index d077229..a954124 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt @@ -106,7 +106,7 @@ fun RegisterByCodeScreen( color = ButtonContent ), width = 1f - ) { viewModel.setEvent(RegisterFamilyEvent.OnClickOkButton) } + ) { if (viewState.isFilledCode) viewModel.setEvent(RegisterFamilyEvent.OnClickOkButton) else {} } } CheckValidCode(isInvalid = viewState.isFilledCode) } @@ -127,7 +127,7 @@ fun RegisterByCodeScreen( color = ButtonContent, platformStyle = PlatformTextStyle(includeFontPadding = false) //폰트 패딩을 제거하지 않으면 정렬이 맞지 않음 ) - ) { viewModel.setEvent(RegisterFamilyEvent.OnClickNextButton) } + ) { if (viewState.isFilledCode) viewModel.setEvent(RegisterFamilyEvent.OnClickNextButton) else {} } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt index c3e6596..fda791f 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt @@ -105,7 +105,7 @@ fun RegisterByNameScreen( color = ButtonContent, platformStyle = PlatformTextStyle(includeFontPadding = false) //폰트 패딩을 제거하지 않으면 정렬이 맞지 않음 ) - ) { viewModel.setEvent(RegisterFamilyEvent.OnClickMakeButton) } + ) { if(viewState.isFilledName) viewModel.setEvent(RegisterFamilyEvent.OnClickMakeButton) else {} } } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt index 8c632a2..dbe5ad6 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt @@ -27,7 +27,6 @@ val GRAY100 = Color(0xFFB9BEC1) val MAIN100 = Color(0xFFFC9C13) - // 마이페이지 색 val MyPageYellowFill = Color(0xFFFFFBF3) val MyPageYellowStroke = Color(0xFFFFD985) diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index 15596d9..eea133d 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -4,6 +4,7 @@ 확인 등록하기 닫기 + 유효한 코드가 아닙니다. 가족 및 지인에게서 멍모리에서 보낸 초대 코드를 입력해주세요!\n유효한 초대코드를 입력하면 강아지의 일상을 같이 볼 수 있어요! @@ -35,6 +36,10 @@ 반려동물 등록번호 + 반려동물 품종 검색 + 선택하기 + + 마이페이지 강아지밥주는사람 From 6279b10249942b2a81c164360ba58e38347352a0 Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Mon, 7 Aug 2023 04:37:24 +0900 Subject: [PATCH 27/37] =?UTF-8?q?feat:=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/register_dog/RegisterDogContract.kt | 1 + .../ui/register_dog/RegisterDogViewModel.kt | 1 + .../ui/register_dog/SearchBreedScreen.kt | 99 +++++++++++++++++-- .../presentation/ui/theme/Color.kt | 3 +- presentation/src/main/res/drawable/cat.xml | 10 ++ .../src/main/res/drawable/cat_selected.xml | 10 ++ .../src/main/res/drawable/checkbox.xml | 9 ++ .../main/res/drawable/checkbox_selected.xml | 9 ++ .../src/main/res/drawable/default_profile.xml | 4 + presentation/src/main/res/drawable/dog.xml | 9 ++ .../src/main/res/drawable/dog_selected.xml | 9 ++ presentation/src/main/res/drawable/search.xml | 20 ++++ presentation/src/main/res/values/strings.xml | 4 + 13 files changed, 178 insertions(+), 10 deletions(-) create mode 100644 presentation/src/main/res/drawable/cat.xml create mode 100644 presentation/src/main/res/drawable/cat_selected.xml create mode 100644 presentation/src/main/res/drawable/checkbox.xml create mode 100644 presentation/src/main/res/drawable/checkbox_selected.xml create mode 100644 presentation/src/main/res/drawable/default_profile.xml create mode 100644 presentation/src/main/res/drawable/dog.xml create mode 100644 presentation/src/main/res/drawable/dog_selected.xml create mode 100644 presentation/src/main/res/drawable/search.xml diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt index 77746f8..66a9ae9 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt @@ -37,6 +37,7 @@ class RegisterDogContract { data class FillInDay(val day: String) : RegisterDogEvent() data class FillInRegistrationNum(val num: String) : RegisterDogEvent() data class OnPetTypeClicked(val petType: String) : RegisterDogEvent() + data class OnBreedClicked(val breed: String) : RegisterDogEvent() data class OnGenderClicked(val gender: String) : RegisterDogEvent() object OnClickSearchButton : RegisterDogEvent() object OnClickMakeButton : RegisterDogEvent() diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt index 36f060a..8a13971 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt @@ -22,6 +22,7 @@ class RegisterDogViewModel @Inject constructor() : is RegisterDogEvent.FillInDay -> reflectUpdateState(day = event.day) is RegisterDogEvent.FillInRegistrationNum -> reflectUpdateState(registrationNumber = event.num) is RegisterDogEvent.OnPetTypeClicked -> reflectUpdateState(petType = event.petType) + is RegisterDogEvent.OnBreedClicked -> reflectUpdateState(breed = event.breed) is RegisterDogEvent.OnGenderClicked -> reflectUpdateState(gender = event.gender) is RegisterDogEvent.OnClickSearchButton -> sendEffect({ RegisterDogSideEffect.NavigateToSearchBreedScreen }) is RegisterDogEvent.OnClickBackButton -> sendEffect({ RegisterDogSideEffect.NavigateToPreviousScreen }) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt index 33eb731..15f3839 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt @@ -4,25 +4,39 @@ package com.meongmoryteam.presentation.ui.register_dog import android.util.Log import androidx.compose.foundation.ExperimentalFoundationApi +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.Arrangement import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight 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.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.relocation.BringIntoViewRequester import androidx.compose.foundation.relocation.bringIntoViewRequester import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Checkbox +import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -30,8 +44,13 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope 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.vector.ImageVector import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.PlatformTextStyle import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -47,12 +66,16 @@ import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent import com.meongmoryteam.presentation.ui.register_family.TextFieldComponent import com.meongmoryteam.presentation.ui.theme.Black import com.meongmoryteam.presentation.ui.theme.ButtonContent +import com.meongmoryteam.presentation.ui.theme.DarkGrey +import com.meongmoryteam.presentation.ui.theme.DeepYellow import com.meongmoryteam.presentation.ui.theme.InputBoxOutline import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.LightYellow import com.meongmoryteam.presentation.ui.theme.NotoSansKR import com.meongmoryteam.presentation.ui.theme.Orange +import com.meongmoryteam.presentation.ui.theme.Placeholer import com.meongmoryteam.presentation.ui.theme.QuestionEditFill +import com.meongmoryteam.presentation.ui.theme.Typography import com.meongmoryteam.presentation.ui.theme.Yellow @Composable @@ -63,7 +86,8 @@ fun SearchBreedScreen( navigateToSelectScreen: () -> Unit ) { val buttonItemList = listOf("강아지", "고양이") - val searchList = listOf(Breed("말티즈", "강아지"), Breed("말티즈", "고양이"), Breed("푸들", "강아지"), Breed("푸들", "고양이"), ) + val searchList = + listOf(Breed("말티즈", "강아지"), Breed("페르시안", "고양이"), Breed("푸들", "강아지"), Breed("벵갈", "고양이")) val viewState by viewModel.viewState.collectAsState() val coroutineScope = rememberCoroutineScope() val focusManager = LocalFocusManager.current @@ -89,7 +113,11 @@ fun SearchBreedScreen( }, navigateToSearch = { viewModel.setEvent(RegisterDogEvent.OnClickSearchButton) } ) - SearchList(searchList = searchList) + SearchList( + searchList = searchList, + breed = viewState.breed, + isSelected = viewState.isSelected, + onValueChange = { viewModel.setEvent(RegisterDogEvent.OnBreedClicked(it)) }) RenderSelectButton( isSelected = viewState.isSelected, bringIntoViewRequester = bringIntoViewRequester @@ -148,7 +176,7 @@ fun SearchScreen( onValueChange: (String) -> Unit, navigateToSearch: () -> Unit ) { - Box(contentAlignment = Alignment.CenterEnd) { + Box(contentAlignment = Alignment.CenterEnd, modifier = modifier.padding(bottom = 20.dp)) { TextFieldComponent( name = value, onValueChange = onValueChange, @@ -173,13 +201,65 @@ fun SearchScreen( @Composable fun SearchList( - searchList: List -){ + searchList: List, + breed: String, + isSelected: Boolean, + onValueChange: (String) -> Unit +) { LazyColumn( - modifier = Modifier.background(Black).fillMaxWidth().fillMaxHeight(0.85f) - ){ - items(searchList) { item -> + modifier = Modifier + .fillMaxWidth() + .fillMaxHeight(0.85f) + ) { + itemsIndexed(searchList) { index, item -> + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Row { + var imageVector = + if (item.category == stringResource(R.string.dog_icon)) R.drawable.dog else R.drawable.cat + Icon( + modifier = Modifier.padding(horizontal = 5.dp), + imageVector = ImageVector.vectorResource(imageVector), + contentDescription = stringResource( + id = R.string.dog_icon + ) + ) + Text(text = item.breed, style = Typography.labelSmall, color = Black) + Text( + modifier = Modifier.padding(horizontal = 5.dp), + text = "[${item.category}]", + style = Typography.labelSmall, + color = DarkGrey + ) + } + Checkbox( + checked = item.breed == breed, + onCheckedChange = { onValueChange(item.breed) }, + colors = CheckboxDefaults.colors( + checkedColor = DeepYellow, + uncheckedColor = DarkGrey, + ) + ) +// Box( +// modifier = Modifier +// .size(21.dp) +// .background(color = Color.Transparent) +// ) { +// IconButton( +// onClick = { onValueChange(item.breed) +// } +// ) { +// Icon( +// imageVector = if (item.breed == breed) ImageVector.vectorResource(R.drawable.checkbox_selected) else ImageVector.vectorResource(R.drawable.checkbox), +// contentDescription = stringResource(R.string.unchecked_box) +// ) +// } +// } + } } } } @@ -209,7 +289,8 @@ fun RenderSelectButton( .bringIntoViewRequester(bringIntoViewRequester) .padding(bottom = 30.dp), onClick = { - if(isSelected) navigateTo else {} + if (isSelected) navigateTo else { + } } ) } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt index dbe5ad6..7d3ce8c 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/theme/Color.kt @@ -13,6 +13,7 @@ val Purple40 = Color(0xFFAAA1C4) val PurpleGrey40 = Color(0xFF625b71) val Pink40 = Color(0xFF7D5260) +//등록페이지 색 val LightGrey = Color(0xFFD9D9D9) val Placeholer = Color(0xFF737373) val InputBoxOutline = Color(0xFFE7E7E7) @@ -25,7 +26,7 @@ val LightYellow = Color(0xFFFFF9EC) val Yellow = Color(0xFFFFD881) val GRAY100 = Color(0xFFB9BEC1) val MAIN100 = Color(0xFFFC9C13) - +val DeepYellow = Color(0xFFFEC23D) // 마이페이지 색 val MyPageYellowFill = Color(0xFFFFFBF3) diff --git a/presentation/src/main/res/drawable/cat.xml b/presentation/src/main/res/drawable/cat.xml new file mode 100644 index 0000000..8f5aae4 --- /dev/null +++ b/presentation/src/main/res/drawable/cat.xml @@ -0,0 +1,10 @@ + + + diff --git a/presentation/src/main/res/drawable/cat_selected.xml b/presentation/src/main/res/drawable/cat_selected.xml new file mode 100644 index 0000000..f63aa32 --- /dev/null +++ b/presentation/src/main/res/drawable/cat_selected.xml @@ -0,0 +1,10 @@ + + + diff --git a/presentation/src/main/res/drawable/checkbox.xml b/presentation/src/main/res/drawable/checkbox.xml new file mode 100644 index 0000000..ef095e3 --- /dev/null +++ b/presentation/src/main/res/drawable/checkbox.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/checkbox_selected.xml b/presentation/src/main/res/drawable/checkbox_selected.xml new file mode 100644 index 0000000..27d6568 --- /dev/null +++ b/presentation/src/main/res/drawable/checkbox_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/default_profile.xml b/presentation/src/main/res/drawable/default_profile.xml new file mode 100644 index 0000000..6320b72 --- /dev/null +++ b/presentation/src/main/res/drawable/default_profile.xml @@ -0,0 +1,4 @@ + + + diff --git a/presentation/src/main/res/drawable/dog.xml b/presentation/src/main/res/drawable/dog.xml new file mode 100644 index 0000000..30f9be7 --- /dev/null +++ b/presentation/src/main/res/drawable/dog.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/dog_selected.xml b/presentation/src/main/res/drawable/dog_selected.xml new file mode 100644 index 0000000..ce0985f --- /dev/null +++ b/presentation/src/main/res/drawable/dog_selected.xml @@ -0,0 +1,9 @@ + + + diff --git a/presentation/src/main/res/drawable/search.xml b/presentation/src/main/res/drawable/search.xml new file mode 100644 index 0000000..23734e6 --- /dev/null +++ b/presentation/src/main/res/drawable/search.xml @@ -0,0 +1,20 @@ + + + + diff --git a/presentation/src/main/res/values/strings.xml b/presentation/src/main/res/values/strings.xml index eea133d..f9abf05 100644 --- a/presentation/src/main/res/values/strings.xml +++ b/presentation/src/main/res/values/strings.xml @@ -38,6 +38,10 @@ 반려동물 품종 검색 선택하기 + 강아지 + 고양이 + 선택된 체크박스 + 선택되진 않은 체크박스 From c8fec60abb5831e7b8961ca713c9d502f96ddbe1 Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Mon, 7 Aug 2023 20:17:00 +0900 Subject: [PATCH 28/37] =?UTF-8?q?feat:=20=EA=B5=AC=EB=B6=84=EC=84=A0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=84=A0=ED=83=9D=20=EC=8B=9C?= =?UTF-8?q?=20=EC=83=89=EC=83=81=20=EB=B3=80=EA=B2=BD=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/register_dog/SearchBreedScreen.kt | 49 +++++++++---------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt index 15f3839..8bc971d 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt @@ -33,6 +33,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.Checkbox import androidx.compose.material3.CheckboxDefaults +import androidx.compose.material3.Divider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text @@ -68,6 +69,7 @@ import com.meongmoryteam.presentation.ui.theme.Black import com.meongmoryteam.presentation.ui.theme.ButtonContent import com.meongmoryteam.presentation.ui.theme.DarkGrey import com.meongmoryteam.presentation.ui.theme.DeepYellow +import com.meongmoryteam.presentation.ui.theme.EditDivider import com.meongmoryteam.presentation.ui.theme.InputBoxOutline import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.LightYellow @@ -176,7 +178,7 @@ fun SearchScreen( onValueChange: (String) -> Unit, navigateToSearch: () -> Unit ) { - Box(contentAlignment = Alignment.CenterEnd, modifier = modifier.padding(bottom = 20.dp)) { + Box(contentAlignment = Alignment.CenterEnd, modifier = modifier.padding(bottom = 30.dp)) { TextFieldComponent( name = value, onValueChange = onValueChange, @@ -212,6 +214,7 @@ fun SearchList( .fillMaxHeight(0.85f) ) { itemsIndexed(searchList) { index, item -> + var tint = if (item.breed == breed) DeepYellow else EditDivider Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, @@ -225,7 +228,8 @@ fun SearchList( imageVector = ImageVector.vectorResource(imageVector), contentDescription = stringResource( id = R.string.dog_icon - ) + ), + tint = tint ) Text(text = item.breed, style = Typography.labelSmall, color = Black) Text( @@ -235,31 +239,24 @@ fun SearchList( color = DarkGrey ) } - Checkbox( - checked = item.breed == breed, - onCheckedChange = { onValueChange(item.breed) }, - colors = CheckboxDefaults.colors( - checkedColor = DeepYellow, - uncheckedColor = DarkGrey, - ) - ) - -// Box( -// modifier = Modifier -// .size(21.dp) -// .background(color = Color.Transparent) -// ) { -// IconButton( -// onClick = { onValueChange(item.breed) -// } -// ) { -// Icon( -// imageVector = if (item.breed == breed) ImageVector.vectorResource(R.drawable.checkbox_selected) else ImageVector.vectorResource(R.drawable.checkbox), -// contentDescription = stringResource(R.string.unchecked_box) -// ) -// } -// } + Box( + modifier = Modifier + .size(21.dp) + .background(color = Color.Transparent) + ) { + IconButton( + onClick = { onValueChange(item.breed) + } + ) { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.checkbox), + contentDescription = stringResource(R.string.unchecked_box), + tint = tint + ) + } + } } + Divider(modifier = Modifier.padding(vertical = 15.dp), thickness = 1.dp, color = InputBoxOutline) } } } From 26a1ab231b55963f875898444ef2e638dd88b4b3 Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Mon, 7 Aug 2023 21:02:39 +0900 Subject: [PATCH 29/37] =?UTF-8?q?feat:=20=EB=B0=98=EB=A0=A4=EB=8F=99?= =?UTF-8?q?=EB=AC=BC=20=EB=B3=84=20=EC=A0=95=EB=A0=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/register_dog/SearchBreedScreen.kt | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt index 8bc971d..dab0f37 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt @@ -87,9 +87,23 @@ fun SearchBreedScreen( navigateToPreviousScreen: () -> Unit, navigateToSelectScreen: () -> Unit ) { - val buttonItemList = listOf("강아지", "고양이") + val buttonItemList = listOf(stringResource(R.string.dog_icon), stringResource(R.string.cat_icon)) + //임시데이터 val searchList = - listOf(Breed("말티즈", "강아지"), Breed("페르시안", "고양이"), Breed("푸들", "강아지"), Breed("벵갈", "고양이")) + listOf( + Breed("말티즈", "강아지"), + Breed("페르시안", "고양이"), + Breed("푸들", "강아지"), + Breed("벵갈", "고양이"), + Breed("포메라니안", "강아지"), + Breed("엑조틱", "고양이"), + Breed("비숑", "강아지"), + Breed("레그돌", "고양이"), + Breed("골든리트리버", "강아지"), + Breed("브리티쉬 숏헤어", "고양이"), + Breed("진돗개", "강아지"), + Breed("아메리칸 숏헤어", "고양이") + ) val viewState by viewModel.viewState.collectAsState() val coroutineScope = rememberCoroutineScope() val focusManager = LocalFocusManager.current @@ -117,6 +131,7 @@ fun SearchBreedScreen( ) SearchList( searchList = searchList, + category = viewState.petType, breed = viewState.breed, isSelected = viewState.isSelected, onValueChange = { viewModel.setEvent(RegisterDogEvent.OnBreedClicked(it)) }) @@ -204,16 +219,21 @@ fun SearchScreen( @Composable fun SearchList( searchList: List, + category: String, breed: String, isSelected: Boolean, onValueChange: (String) -> Unit ) { + var lazyList = if (category == stringResource(R.string.blank)) searchList else selectLogic( + searchList = searchList, + category = category + ) LazyColumn( modifier = Modifier .fillMaxWidth() .fillMaxHeight(0.85f) ) { - itemsIndexed(searchList) { index, item -> + items(lazyList) { item -> var tint = if (item.breed == breed) DeepYellow else EditDivider Row( modifier = Modifier.fillMaxWidth(), @@ -245,7 +265,8 @@ fun SearchList( .background(color = Color.Transparent) ) { IconButton( - onClick = { onValueChange(item.breed) + onClick = { + onValueChange(item.breed) } ) { Icon( @@ -256,7 +277,11 @@ fun SearchList( } } } - Divider(modifier = Modifier.padding(vertical = 15.dp), thickness = 1.dp, color = InputBoxOutline) + Divider( + modifier = Modifier.padding(vertical = 15.dp), + thickness = 1.dp, + color = InputBoxOutline + ) } } } @@ -292,6 +317,19 @@ fun RenderSelectButton( ) } +@Composable +fun selectLogic( + searchList: List, + category: String +): MutableList { + var selectedList = mutableListOf() + + for (item in searchList) { + if (item.category == category) selectedList.add(item) + } + return selectedList +} + data class Breed( val breed: String, val category: String From c7a43ca9d2fa3b2554c646e502a92268a671a90e Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Tue, 8 Aug 2023 00:04:05 +0900 Subject: [PATCH 30/37] =?UTF-8?q?feat:=20=EA=B2=80=EC=83=89=ED=95=9C=20?= =?UTF-8?q?=EB=8F=99=EB=AC=BC=20=EB=93=B1=EB=A1=9D=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A1=9C=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/register_dog/RegisterDogActivity.kt | 14 +++- .../ui/register_dog/RegisterDogContract.kt | 3 +- .../ui/register_dog/RegisterDogScreen.kt | 66 ++++++++++++--- .../ui/register_dog/RegisterDogViewModel.kt | 7 +- .../ui/register_dog/SearchBreedScreen.kt | 83 +++++++++---------- 5 files changed, 111 insertions(+), 62 deletions(-) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt index aa2c047..122c344 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt @@ -12,9 +12,11 @@ import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding import androidx.navigation.NavHostController +import androidx.navigation.NavType import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.White import dagger.hilt.android.AndroidEntryPoint @@ -56,12 +58,16 @@ fun RegisterDogNavigation( startDestination = Route.SearchBreed.route, modifier = modifier ) { - composable(route = Route.RegisterDog.route) { + composable( + route = Route.RegisterDog.route.plus("/{breed}"), + arguments = listOf(navArgument("breed") { type = NavType.StringType }) + ) { RegisterDogScreen( navController = navController, navigateToSearchBreedScreen = { navController.navigate(Route.SearchBreed.route) }, navigateToMakeScreen = { navController.navigate(Route.SuccessRegister.route) }, - navigateToPreviousScreen = { navController.navigate(Route.Main.route) } + navigateToPreviousScreen = { navController.navigate(Route.Main.route) }, + searchBreed = "${it.arguments?.getString("breed")}" ) } composable(route = Route.SuccessRegister.route) { @@ -71,8 +77,8 @@ fun RegisterDogNavigation( //품종 검색 스크린 SearchBreedScreen( navController = navController, - navigateToPreviousScreen = {navController.navigate(Route.RegisterDog.route)}, - navigateToSelectScreen = {navController.navigate(Route.RegisterDog.route)} + navigateToPreviousScreen = { navController.navigate(Route.RegisterDog.route) }, +// navigateToRegisterScreen = {navController.navigate(Route.RegisterDog.route)} ) } composable(route = Route.Main.route) { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt index 66a9ae9..cea62bd 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogContract.kt @@ -1,6 +1,5 @@ package com.meongmoryteam.presentation.ui.register_dog -import androidx.compose.runtime.MutableState import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.base.ViewEvent import com.meongmoryteam.presentation.base.ViewSideEffect @@ -26,6 +25,7 @@ class RegisterDogContract { object NavigateToSearchBreedScreen : RegisterDogSideEffect() object NavigateToNextScreen : RegisterDogSideEffect() object NavigateToPreviousScreen : RegisterDogSideEffect() + data class NavigateToRegisterScreen(val breed: String) : RegisterDogSideEffect() } sealed class RegisterDogEvent : ViewEvent { @@ -42,5 +42,6 @@ class RegisterDogContract { object OnClickSearchButton : RegisterDogEvent() object OnClickMakeButton : RegisterDogEvent() object OnClickBackButton : RegisterDogEvent() + data class OnClickSelectButton(val breed: String) : RegisterDogEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt index 19fd692..61258e5 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt @@ -1,5 +1,6 @@ package com.meongmoryteam.presentation.ui.register_dog +import android.util.Log import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -67,6 +68,7 @@ import com.meongmoryteam.presentation.ui.theme.LightYellow import com.meongmoryteam.presentation.ui.theme.NotoSansKR import com.meongmoryteam.presentation.ui.theme.Orange import com.meongmoryteam.presentation.ui.theme.Placeholer +import com.meongmoryteam.presentation.ui.theme.QuestionEditFill import com.meongmoryteam.presentation.ui.theme.Typography import com.meongmoryteam.presentation.ui.theme.Yellow import kotlinx.coroutines.CoroutineScope @@ -79,7 +81,8 @@ fun RegisterDogScreen( viewModel: RegisterDogViewModel = hiltViewModel(), navigateToSearchBreedScreen: () -> Unit, navigateToPreviousScreen: () -> Unit, - navigateToMakeScreen: () -> Unit + navigateToMakeScreen: () -> Unit, + searchBreed: String ) { val viewState by viewModel.viewState.collectAsState() val buttonItemList = listOf("수컷", "암컷") @@ -95,8 +98,8 @@ fun RegisterDogScreen( RenderProfile() RenderName(value = viewState.name) { viewModel.setEvent(RegisterDogEvent.FillInName(it)) } RenderBreed( - value = viewState.breed, - onValueChange = { viewModel.setEvent(RegisterDogEvent.FillInBreed(it)) } +// value = viewState.breed, + value = searchBreed ) { viewModel.setEvent(RegisterDogEvent.OnClickSearchButton) } RenderGender( label = R.string.gender, @@ -145,6 +148,8 @@ fun RegisterDogScreen( is RegisterDogSideEffect.NavigateToPreviousScreen -> { navigateToPreviousScreen() } + + is RegisterDogSideEffect.NavigateToRegisterScreen -> {} } } } @@ -182,14 +187,47 @@ fun RenderName(value: String, onValueChange: (String) -> Unit) { } @Composable -fun RenderBreed(value: String, onValueChange: (String) -> Unit, navigateToSearch: () -> Unit) { +fun RenderBreed(value: String, navigateToSearch: () -> Unit) { Box(contentAlignment = Alignment.CenterEnd) { - LabelNInputForm( - label = R.string.breed, - placeholder = R.string.breed, - value = value, - onValueChange = onValueChange - ) + val bgColor = if (value.isEmpty()) { + QuestionEditFill + } else { + LightYellow + } + val borderColor = if (value.isEmpty()) { + InputBoxOutline + } else { + Yellow + } + Column(modifier = Modifier.padding(bottom = 14.dp)) { + Text( + text = stringResource(R.string.breed), + color = Placeholer, + style = Typography.titleSmall, + modifier = Modifier.padding(bottom = 12.dp) + ) + Box( + modifier = Modifier + .fillMaxWidth() + .height(43.dp) + .background(bgColor) + .border(width = 1.dp, color = borderColor, shape = RoundedCornerShape(10.dp)) + .padding(horizontal = 15.dp, vertical = 14.dp) + ) { + val text: String + val color: Color + if (value.isEmpty()) { + text = stringResource(R.string.breed) + color = Placeholer + } else { + text = value + color = Black + Log.d("CHANGE", "change") + } + Text(text = text, style = Typography.titleSmall, color = color, maxLines = 1) + } + } + SearchButton(padding = 15.dp, navigateToSearch) } } @@ -316,7 +354,9 @@ fun RenderRegisterButton( color = ButtonContent, platformStyle = PlatformTextStyle(includeFontPadding = false) ), - modifier = Modifier.bringIntoViewRequester(bringIntoViewRequester).padding(bottom = 30.dp), + modifier = Modifier + .bringIntoViewRequester(bringIntoViewRequester) + .padding(bottom = 30.dp), onClick = navigateTo ) } @@ -343,7 +383,7 @@ fun LabelNInputForm( onValueChange = onValueChange, placeholder = stringResource(placeholder), bgColor = if (value.isEmpty()) { - Color(0xFFF9F9F9) + QuestionEditFill } else { LightYellow }, @@ -458,7 +498,7 @@ fun DateInputForm( onValueChange = valueChangeList[itemList.indexOf(it)], placeholder = placeholderList[itemList.indexOf(it)], bgColor = if (textValueList[itemList.indexOf(it)].isEmpty()) { - Color(0xFFF9F9F9) + QuestionEditFill } else { LightYellow }, diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt index 8a13971..48acede 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogViewModel.kt @@ -27,6 +27,11 @@ class RegisterDogViewModel @Inject constructor() : is RegisterDogEvent.OnClickSearchButton -> sendEffect({ RegisterDogSideEffect.NavigateToSearchBreedScreen }) is RegisterDogEvent.OnClickBackButton -> sendEffect({ RegisterDogSideEffect.NavigateToPreviousScreen }) is RegisterDogEvent.OnClickMakeButton -> sendEffect({ RegisterDogSideEffect.NavigateToNextScreen }) + is RegisterDogEvent.OnClickSelectButton -> sendEffect({ + RegisterDogSideEffect.NavigateToRegisterScreen( + breed = event.breed + ) + }) } } @@ -83,7 +88,7 @@ class RegisterDogViewModel @Inject constructor() : private fun isConfirmed( petType: String, breed: String - ): Boolean{ + ): Boolean { return (petType.isNotEmpty() && breed.isNotEmpty()) } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt index dab0f37..4421a08 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt @@ -2,42 +2,27 @@ package com.meongmoryteam.presentation.ui.register_dog -import android.util.Log import androidx.compose.foundation.ExperimentalFoundationApi -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.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxHeight -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.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items -import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.relocation.BringIntoViewRequester import androidx.compose.foundation.relocation.bringIntoViewRequester -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.verticalScroll import androidx.compose.material3.ButtonDefaults -import androidx.compose.material3.Checkbox -import androidx.compose.material3.CheckboxDefaults import androidx.compose.material3.Divider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.Text -import androidx.compose.material3.TextField import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.collectAsState @@ -45,16 +30,17 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip +import androidx.compose.ui.focus.FocusManager +import androidx.compose.ui.focus.onFocusEvent import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.colorResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.PlatformTextStyle import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel @@ -75,19 +61,21 @@ import com.meongmoryteam.presentation.ui.theme.LightGrey import com.meongmoryteam.presentation.ui.theme.LightYellow import com.meongmoryteam.presentation.ui.theme.NotoSansKR import com.meongmoryteam.presentation.ui.theme.Orange -import com.meongmoryteam.presentation.ui.theme.Placeholer import com.meongmoryteam.presentation.ui.theme.QuestionEditFill import com.meongmoryteam.presentation.ui.theme.Typography import com.meongmoryteam.presentation.ui.theme.Yellow +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch @Composable fun SearchBreedScreen( navController: NavController, viewModel: RegisterDogViewModel = hiltViewModel(), navigateToPreviousScreen: () -> Unit, - navigateToSelectScreen: () -> Unit +// navigateToRegisterScreen: () -> Unit ) { - val buttonItemList = listOf(stringResource(R.string.dog_icon), stringResource(R.string.cat_icon)) + val buttonItemList = + listOf(stringResource(R.string.dog_icon), stringResource(R.string.cat_icon)) //임시데이터 val searchList = listOf( @@ -122,6 +110,9 @@ fun SearchBreedScreen( ) { viewModel.setEvent(RegisterDogEvent.OnPetTypeClicked(it)) } SearchScreen( value = viewState.breed, + coroutineScope = coroutineScope, + bringIntoViewRequester = bringIntoViewRequester, + focusManager = focusManager, onValueChange = { viewModel.setEvent( RegisterDogEvent.FillInBreed(it) @@ -133,14 +124,13 @@ fun SearchBreedScreen( searchList = searchList, category = viewState.petType, breed = viewState.breed, - isSelected = viewState.isSelected, onValueChange = { viewModel.setEvent(RegisterDogEvent.OnBreedClicked(it)) }) RenderSelectButton( isSelected = viewState.isSelected, - bringIntoViewRequester = bringIntoViewRequester - ) { - viewModel.setEvent(RegisterDogEvent.OnClickMakeButton) - } + breed = viewState.breed, + bringIntoViewRequester = bringIntoViewRequester, + navigateTo = { viewModel.setEvent(RegisterDogEvent.OnClickSelectButton(it)) } + ) } LaunchedEffect(key1 = viewModel.effect) { @@ -151,15 +141,16 @@ fun SearchBreedScreen( } is RegisterDogSideEffect.NavigateToSearchBreedScreen -> {} - is RegisterDogSideEffect.NavigateToNextScreen -> { - navigateToSelectScreen() + is RegisterDogSideEffect.NavigateToRegisterScreen -> { + navController.navigate(Route.RegisterDog.route.plus("/${effect.breed}")) } + + is RegisterDogSideEffect.NavigateToNextScreen -> {} } } } } -// @Composable fun CategoryScreen( buttonItem: List, @@ -188,8 +179,9 @@ fun CategoryScreen( fun SearchScreen( value: String, modifier: Modifier = Modifier.fillMaxWidth(), - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default, + coroutineScope: CoroutineScope, + bringIntoViewRequester: BringIntoViewRequester, + focusManager: FocusManager, onValueChange: (String) -> Unit, navigateToSearch: () -> Unit ) { @@ -208,9 +200,17 @@ fun SearchScreen( } else { Yellow }, - modifier = modifier, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions + modifier = modifier.onFocusEvent { event -> + if (event.isFocused) { + coroutineScope.launch { + bringIntoViewRequester.bringIntoView() + } + } + }, + keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done), + keyboardActions = KeyboardActions( + onDone = { focusManager.clearFocus() } + ) ) SearchButton { navigateToSearch } } @@ -221,10 +221,9 @@ fun SearchList( searchList: List, category: String, breed: String, - isSelected: Boolean, onValueChange: (String) -> Unit ) { - var lazyList = if (category == stringResource(R.string.blank)) searchList else selectLogic( + val lazyList = if (category == stringResource(R.string.blank)) searchList else selectLogic( searchList = searchList, category = category ) @@ -234,14 +233,14 @@ fun SearchList( .fillMaxHeight(0.85f) ) { items(lazyList) { item -> - var tint = if (item.breed == breed) DeepYellow else EditDivider + val tint = if (item.breed == breed) DeepYellow else EditDivider Row( modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Row { - var imageVector = + val imageVector = if (item.category == stringResource(R.string.dog_icon)) R.drawable.dog else R.drawable.cat Icon( modifier = Modifier.padding(horizontal = 5.dp), @@ -289,8 +288,9 @@ fun SearchList( @Composable fun RenderSelectButton( isSelected: Boolean, + breed: String, bringIntoViewRequester: BringIntoViewRequester, - navigateTo: () -> Unit + navigateTo: (String) -> Unit ) { TextButtonComponent( text = stringResource(R.string.select), @@ -310,10 +310,7 @@ fun RenderSelectButton( modifier = Modifier .bringIntoViewRequester(bringIntoViewRequester) .padding(bottom = 30.dp), - onClick = { - if (isSelected) navigateTo else { - } - } + onClick = { navigateTo(breed) } ) } @@ -322,7 +319,7 @@ fun selectLogic( searchList: List, category: String ): MutableList { - var selectedList = mutableListOf() + val selectedList = mutableListOf() for (item in searchList) { if (item.category == category) selectedList.add(item) From 61f540e18eb03f5d03b4f00d0fad5adf5e7aa61b Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Tue, 8 Aug 2023 00:05:10 +0900 Subject: [PATCH 31/37] =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=95=EB=A0=AC?= =?UTF-8?q?=20=EB=B0=8F=20=EC=A3=BC=EC=84=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b42f373..09a8ea8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,21 +20,21 @@ android:label="@string/app_name" android:theme="@style/Theme.Meongmory"> - - + + - - + + - - + + - - + + Date: Tue, 8 Aug 2023 04:23:35 +0900 Subject: [PATCH 32/37] =?UTF-8?q?feat:=20=EB=B0=98=EB=A0=A4=EB=8F=99?= =?UTF-8?q?=EB=AC=BC=20=EB=93=B1=EB=A1=9D=20=EC=84=B1=EA=B3=B5=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20UI=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/register_dog/RegisterDogActivity.kt | 15 ++- .../ui/register_dog/RegisterDogScreen.kt | 22 +--- .../ui/register_dog/SuccessRegisterScreen.kt | 124 ++++++++++++++++++ .../ui/register_family/RegisterForm.kt | 6 +- .../main/res/drawable-v24/default_profile.png | Bin 1446 -> 0 bytes .../src/main/res/drawable-v24/search.png | Bin 550 -> 0 bytes ...lt_profile.xml => default_profile_img.xml} | 0 .../drawable/{search.xml => search_btn.xml} | 0 .../res/drawable/success_registration.png | Bin 0 -> 12933 bytes presentation/src/main/res/values/strings.xml | 7 + 10 files changed, 151 insertions(+), 23 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt delete mode 100644 presentation/src/main/res/drawable-v24/default_profile.png delete mode 100644 presentation/src/main/res/drawable-v24/search.png rename presentation/src/main/res/drawable/{default_profile.xml => default_profile_img.xml} (100%) rename presentation/src/main/res/drawable/{search.xml => search_btn.xml} (100%) create mode 100644 presentation/src/main/res/drawable/success_registration.png diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt index 122c344..f9cc3e2 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat @@ -17,6 +18,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument +import com.meongmoryteam.presentation.R import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.White import dagger.hilt.android.AndroidEntryPoint @@ -55,7 +57,7 @@ fun RegisterDogNavigation( ) { NavHost( navController = navController, - startDestination = Route.SearchBreed.route, + startDestination = Route.RegisterDog.route.plus("/{breed}"), modifier = modifier ) { composable( @@ -67,18 +69,23 @@ fun RegisterDogNavigation( navigateToSearchBreedScreen = { navController.navigate(Route.SearchBreed.route) }, navigateToMakeScreen = { navController.navigate(Route.SuccessRegister.route) }, navigateToPreviousScreen = { navController.navigate(Route.Main.route) }, - searchBreed = "${it.arguments?.getString("breed")}" + searchBreed = + if (it.arguments?.getString("breed") == null || it.arguments?.getString("breed") == "{breed}") stringResource(R.string.blank) + else "${it.arguments?.getString("breed")}" ) } composable(route = Route.SuccessRegister.route) { //등록 성공 스크린 + SuccessRegisterScreen( + navController = navController, + navigateToMainScreen = {navController.navigate(Route.Main.route)} + ) } composable(route = Route.SearchBreed.route) { //품종 검색 스크린 SearchBreedScreen( navController = navController, - navigateToPreviousScreen = { navController.navigate(Route.RegisterDog.route) }, -// navigateToRegisterScreen = {navController.navigate(Route.RegisterDog.route)} + navigateToPreviousScreen = { navController.navigate(Route.RegisterDog.route.plus("/{breed}")) }, ) } composable(route = Route.Main.route) { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt index 61258e5..8f1d4b6 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt @@ -41,10 +41,11 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.focus.onFocusEvent import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource +import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.PlatformTextStyle import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight @@ -97,10 +98,7 @@ fun RegisterDogScreen( navigateTo = { viewModel.setEvent(RegisterDogEvent.OnClickBackButton) }) { RenderProfile() RenderName(value = viewState.name) { viewModel.setEvent(RegisterDogEvent.FillInName(it)) } - RenderBreed( -// value = viewState.breed, - value = searchBreed - ) { viewModel.setEvent(RegisterDogEvent.OnClickSearchButton) } + RenderBreed(value = searchBreed) { viewModel.setEvent(RegisterDogEvent.OnClickSearchButton) } RenderGender( label = R.string.gender, buttonItem = buttonItemList, @@ -156,12 +154,12 @@ fun RegisterDogScreen( } @Composable -fun RenderProfile(painterResource: Int = R.drawable.default_profile) { +fun RenderProfile() { Column( horizontalAlignment = Alignment.CenterHorizontally, ) { Image( - painter = painterResource(painterResource), + imageVector = ImageVector.vectorResource(R.drawable.default_profile_img), contentDescription = stringResource(R.string.profile_img), contentScale = ContentScale.Crop, modifier = Modifier @@ -173,7 +171,6 @@ fun RenderProfile(painterResource: Int = R.drawable.default_profile) { modifier = Modifier.padding(top = 10.dp, bottom = 30.dp) ) } - } @Composable @@ -216,7 +213,7 @@ fun RenderBreed(value: String, navigateToSearch: () -> Unit) { ) { val text: String val color: Color - if (value.isEmpty()) { + if (value == null) { text = stringResource(R.string.breed) color = Placeholer } else { @@ -408,7 +405,7 @@ fun SearchButton(padding: Dp = 0.dp, navigateToSearch: () -> Unit) { .padding(top = padding) ) { Icon( - painter = painterResource(R.drawable.search), + imageVector = ImageVector.vectorResource(R.drawable.search_btn), contentDescription = stringResource(R.string.search), modifier = Modifier.size(20.dp) ) @@ -520,8 +517,3 @@ fun DateInputForm( } } } - -data class ButtonItem( - var index: Int, - var label: String -) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt new file mode 100644 index 0000000..9a161f9 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt @@ -0,0 +1,124 @@ +package com.meongmoryteam.presentation.ui.register_dog + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.withStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavController +import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent +import com.meongmoryteam.presentation.ui.register_family.TextComponent +import com.meongmoryteam.presentation.ui.theme.AppleSD +import com.meongmoryteam.presentation.ui.theme.Brown +import com.meongmoryteam.presentation.ui.theme.EditDivider +import com.meongmoryteam.presentation.ui.theme.Orange +import com.meongmoryteam.presentation.ui.theme.Typography + +@Composable +fun SuccessRegisterScreen( + navController: NavController, + viewModel: RegisterDogViewModel = hiltViewModel(), + navigateToMainScreen: () -> Unit +) { + val viewState by viewModel.viewState.collectAsState() + + Column( + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + RenderSuccessRegister() + RenderConfirmButton() + } +} + +@Composable +fun RenderSuccessRegister() { + Column( + modifier = Modifier + .fillMaxWidth(), + verticalArrangement = Arrangement.Center, + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painterResource(id = R.drawable.success_registration), + contentDescription = stringResource(R.string.breed), + modifier = Modifier + .width(300.dp) + .height(200.dp) + .padding(bottom = 30.dp) + ) + TextComponent( + text = stringResource(R.string.success_registration_title), + style = Typography.titleLarge, + color = Brown + ) + TextComponent( + text = stringResource(R.string.success_registration_content1), + style = Typography.titleMedium, + color = EditDivider, + modifier = Modifier.padding(vertical = 5.dp) + ) + Text(buildAnnotatedString { + withStyle( + style = SpanStyle( + color = Orange, + fontSize = 14.sp, + fontWeight = FontWeight.W400, + fontFamily = AppleSD, + letterSpacing = 0.6.sp + ) + ) { append(stringResource(R.string.success_registration_content2)) } + withStyle( + style = SpanStyle( + color = EditDivider, + fontSize = 14.sp, + fontWeight = FontWeight.W400, + fontFamily = AppleSD, + letterSpacing = 0.6.sp + ) + ) { append(stringResource(R.string.success_registration_content3)) } + }) + TextComponent( + text = stringResource(R.string.success_registration_content4), + style = Typography.titleMedium, + color = EditDivider, + modifier = Modifier.padding(vertical = 5.dp) + ) + } +} + +@Composable +fun RenderConfirmButton() { + TextButtonComponent( + text = stringResource(R.string.check), + colors = ButtonDefaults.textButtonColors(Orange), + style = Typography.labelMedium, + width = 0.6f, + modifier = Modifier.padding(top = 20.dp) + ) { + + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt index 851c443..1e1dfc5 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt @@ -13,12 +13,10 @@ 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.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions -import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material3.ButtonColors @@ -30,7 +28,6 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.TextButton -import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment @@ -39,7 +36,6 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -50,6 +46,7 @@ import com.meongmoryteam.presentation.ui.theme.AppleSD import com.meongmoryteam.presentation.ui.theme.Black import com.meongmoryteam.presentation.ui.theme.InputBoxOutline import com.meongmoryteam.presentation.ui.theme.Placeholer +import com.meongmoryteam.presentation.ui.theme.QuestionButtonText import com.meongmoryteam.presentation.ui.theme.Typography import com.meongmoryteam.presentation.ui.theme.White @@ -150,6 +147,7 @@ fun TextButtonComponent( text = text, style = style, textAlign = TextAlign.Center, + color = QuestionButtonText ) } } diff --git a/presentation/src/main/res/drawable-v24/default_profile.png b/presentation/src/main/res/drawable-v24/default_profile.png deleted file mode 100644 index f12b07ebdda4f6532359d90d09f0d01fed41b349..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1446 zcmV;X1zGxuP)tLE+PZTs=@(Xnm&H6NS&^nv=d6Y&z4 zZxhS1CVU(|JUsl`*w`3uZf*`+t=5DV1dA#JqTb!z{mXaXvY>5>7BVj`i$CDw>2x|B z?CZjLxo|53u0f)e~|6@r&0^2NmkY@ow8L~fHRgaz;O;dp0fXGkSr zTx2Eg$19Jq;NfTN`UgqeHgN6QFtJQis^6kPRk47VO9KMs@9CuN0xr6hr zsD0Q}05ona@DEx|fq@r597t^{KyHyQFE2a%zl;c8X8%otC-m9bS#B%LB{E0wM{b4t zv_`N;f5P{s9Ax%nd=N))m(~=H>MnO)dRbnRN#yZ({DCuw&mbe+z_6`{W4Z$@!?EN>h*dnZk!|5F8G3^*hG4oNwyIg$tsGkNXSH7S{E6~ z9L3_pIZ%K7FL)ucx@^=YAv4e|YQ)ZtI5F2Ci10*IG(YoXPT3Av}1HZa%EzwgWM5pJTv&ZT51WwZxW0EU$*b>?+-{Y2G+pX)9F-1Hi);#h-6^i zC|Jd1;|B@G;K8C-h~!nDFjy&;Wxcl5f<(a};>qT53QYnR(jg+3fQVcIB60~pWS0b! zxDv_c@doWnSt-A+px_Ba{zHN>xLf@bJwAzKv$!^gvrB?85X3f*+z&`FMx)Uf+G>`I zOM(g9U`haUN`iJ&ajB;spZ`G63t!svg4YwdR;!(mV1faDcp}3$B%1XCJ^j_HLARQd z=5HiugRLT1;2wy)wYAmf!@|_JTmc6Doj_!j%1Jb90Hx1n7q&keg=5R;lc0m+*$2-= z#$pm_0E+?r!Zko&j3=YQ9|^gM(l2t^?|3}^F4JkVqoVj-`1!~yBNEN|KvC7G=Oaai zH*+K(laQKlMlnn5H9pRpyCivYTHK_+{#cP!-u#|~xp3;6SPnSxYBfr}h;1YTeOTar z(m8Xd1Ss2ZNr=K#`Xn+}WY`8)y_5KJ7_aPan)=GACbz(E_ze$92w*)@*T7Fbg9vFI z-k1dV@c(H`NP>8OdGK9+k0C zxS7@j<-vW*L7|NUP&tYt8s*I#T3wJ`9cJ<1FtR&CGS%n+Vd{GCi-d~amQI0z)<~WOUX7ZcOSFqw zuSnyT`2J)VWFRQ5xTyQ_nG`qp94ZM_q7u8#R9zYkQ_@Z_!^gC^KBbB50~_H3qPtV} z9;uj$hM7`2b|%a8*;FCE;GB`P>8bLRL;7%)9h^2Ajgzv4ouyKd!=UKY_4V}ui-VFq zjw*Q4ROKR^h?ltPIK)yetTe(J7%b7KQq(Yi0Z15S`SY>cbpQYW07*qoM6N<$f-V5H AJpcdz diff --git a/presentation/src/main/res/drawable-v24/search.png b/presentation/src/main/res/drawable-v24/search.png deleted file mode 100644 index 8e0f8476305917806a36bb409c6485b869be6683..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 550 zcmV+>0@?kEP) z!axv(ca7+MgZKuC=pq_Zk&fIT3 zQ}alT0{A`+d;n~>+wIoknjith-BUcjrRyWIslsMP2_PSY!p~eTm+hZO&1Ta^ zsM2`7UcV-QBwUv|0(FGbXf)cVV90r4cV7Hf9JC%lRU|#}RHLwC7>0%mjZ>x5qz~UGdb3_A5D*mg7yWyz0s+=tb=kvf*8@CO zIYf6|aa9CNK#)r!hbsbdCzHus?{)pFgFq%TlLL~>OwwOIVP?8tUgo{m)m>d(T?L@g zXfzs)Mx)VaG#ZU29w0OVzF$7k-7eJ-B_$=P>E}GZ7c`niM1vLbLu)2vxh$iXK>0IE z!ZsvYwR7lB68NU=c!feI#e_Dj4D z5N|=CED7+a+aaFCK6zfyXc{p|Ka%@Czw0z`Iv?aqxsFBM1q4flkdvJK=WGIvMw7fk zPU~}<`uxQ=BjK%pvMXPThp*-tmymzKzH@efMx!Ys>4co}b5s1na}`LM${)M)k3j%y z?MUPIk+-02_PkQiXf(%2Dj^Sic~37AwnvFzB!6@wpecdgvFzgR^gc87(wIgQg`^Pj z?H}j5+GKcsPDC^KVS&FrC42UJi0Y$8qlrbr3ONfg1`8&4F6_aC1^C7 zDoIEorwzG|V4!%klsK6`4K7!;#FgT@6?;6f8#EeCwMaN;80BZ~_Z^-LB&GmTdRZZX z2L!$83YinIM_w^#G@5FYa6;a~fsYd4c-AqTWd(>K3Gj4E(~OzeG1m_ojiyEZcN$hX*P-uGx3e<>dl{mMCD_Pe0bXif?Nam1VdKpPO&yz&AL zWnOIZK`r1KP3>SnoS?OnTS_ut;J3re7bD=^?(EsmfJURK72+b~Maw5PC4q0Twe5oP zzrI|6Ls5dPqKht zUA`O<-}ATvIf%IuG#X8|OU66>=$U{dZY}?JS-=+t0`jJoJ)bQBjYd=J)QgbQ z{P{+pmGd@!H=TbR$17l!88UCn95VYLXf&ESpgNU(jeYbxNJ8>&nmu2yYWn|Ko+| zM@f@h{qo)ejYd=F)Tz4eqvEF#A-jATfBusby?+OdMpG};neVzUf8q^%`WMTW5#fIc zt!q-V=QN6-4@6@O-fL*dojMWnK*4=yNNIk=XKz!kco%_nWlHwk z1|7CZMYRb9ih5fXUc$F`I8TU9Vw2ZB`lrU-j8bKhEm?+#%3t zPLf&|^3oOewF8^EfKNQQ+#m6wfa{(8^4@|5igML;*l`qJ>>WHxcjs$XQEg7lut{L@ zw5E{HHP1=*7fyC`*EDWweNJvT%$p>^!0;HVxY+USpnpOGgg(x7m8KM5APl^RKPgvT zXB9oCNr3wW(E)z7^VpsSlA5wWyN(@!VB_0&1`<9QK=b@S{>16aJ(-(^4a+q_qp2aa zHj=C8s{S=O=Ys`{!Wt~VW)OI>yWgzupn>82?7p_>w0?(J=BDeeBXQ;J6@LF)VWayTrgsr$&kKP@Qv+&E$OEe; z_9P)*C!k*CP9Ky=SEcsPYjCN9OV>;qgC;z|cd&D`dKPHO0==83DIcMMfA@He6)nzv z+Edv%OIF<5%5F1mW=q)welRU7RPW}|{|?9E%!Qb%ef%}mr&ffV3V-hm6zzCSZ50i# zfF-W%jL{8gs7%nd&f~5fBc~@583+(btpqi%#${%O<$+SDT zlX$9vMx?Z*FM@vOC0XbFP8;Mj)uvXQVFJb9594|GjTMRyqMPn*Py$Zl?EaRHYf!>V zQ3agJmc_oX2!3-2Gj4Vdn7OPb0bO$^9bP&5p{@XJ5z&G*bdNO^2%%Ko|6{x z!=FxTLS#+gk*9fBg@l=|UbDZ2286dDbr?@al!H&xighgX9trXZSDIsV>VUlW+GgjT zaCX&>!(Q|YFrMePJ0dD2+*X=WdKPFj)#RjwJS8{der(`}l__Rn0+!t^kdunw->}+_NI5hs{PR z;9}=;Cp;{qG0ZV=##hil*!S6e>1l5BS?;~Ai>M^{$mOQ7*sJ!p%lh-DoK9dxYD0({ zO+OAxKS!r))>O?&jpT+QrvZdnmw7r$vl^0sD^gsci7d=x!wL!f{PUoDK;8v)A>ayE z_KdA8(fcDRB(-+9pfzYT)!>AMyrf`qZyr%bmoG!YtuBKa)aH}o{G9G=@VblN9t(EC z>Ujwv-sdXGm<4qVAw`bl0<$E^W}wkjgA)>RW!)80K2YAm%niTPMEL^towEZP2(&%d zWg~ium&?k}!}swBK7Av2p2uNzpPP+4&d9$(BoL?@Xf)N}gqC8wX`W#Q!lmJ*_-QK0 zm!JU=I$Ux+kK!ZYn2#`r%4!9rB{hJ5k0N>xN$TILrNpbl;n&hL} zLas(}VaTZv9ta^sLj0rIz`XCF0YHW0oj#jCm*1UUR)AC(lynE48K3J@(+2Kj(jv+U ziVOp0j(yYcc6h#TI3iZj%0XIhOJVtYFM2xcG^KsopLN&*iY4S2!E#EnG<#8VJw z1R7^VD`$265G-w`bH{0_MU~DlWnrBPCSSqoYm4&bZ2Vc2Iv}+{Y>+5TKipe@xT)*| zq9nt(yY=v=y%0wzH&+CqxLefC_=r0zMu+*|<_p^fLH0J#*kKBz#1=%;FhU{#VgTFX zC-N`-fOh=9&YeGKP}_esRa2#qdsaQr)NaG8)bMc(mV057FE@mM5M|M2$;xFTo0|Wc zED--#@z3;6A>Le3;)9y{*l!V}0LZp{ zNLrZ%B?Pc_>!{q*PhV6BnnpvF>bk>jox=hi9;5*2zxG|`T1awu#lVJk>keL~x>$Wy z!4@eUrVq=Fe^k_x5=a#SqN(eWEOUKWNzl=Oj`*@4@j@hOC;6Fi_s|ufymg+gwF1E# zwr{`D1)4@fr9!S$bpmVjG1tyxzh%5p|DIp9PiS>&R4&?-mMv^OC^5I}vxQ#~Jn)%P7C5eiH9+&Sd=Q6jvAh##wc z1XY|`sq^<27LI5KnnppTLLPA8xjdSjR-yP+I3p|RbBcTY@+$7Yj=HXfgiZV(c8rJH zYII1*pG7NY6@E*KCu?8%GR!Ur{jfXqB1pJbg3Mu?$yTVGu7+vp5K@hVm_mLe?QmH> zuksk&>Xc`4kgFP2?P-vuPfAnt^Sc2Qg|Joe@@6aczS7v#eA*vs4UO~u6ChgTHEY}C!FC$ zlUzhs*TFa!%7q|i4zu3=0VFZ$?$8Z9`6wUZbd}TTh}$;OSlH0`dBsGBWgu*E+cLMn z2~d{qn8ZF-UHBP_oc7%oC4|F|rhbUFz{tO^NEC7?=M+3r8Pdjs9dO*(rufG0wkO>5!)BOgvCT8m=tkgUqvuHl=TK|tplOsu zsOuE4+VCjewp@{EL$M5!6xw`WIxm^s5>`gAq_z?h))q8>zClu4#&07srt&bn((N!d zfJSoyM46MDL-@b)KGXYb!L(J7q?CG;n`im;ehk_~Oec}}amJS&xHB3VwT|%b*k@*3 z_qS`3moOn$>*Kt1HX`f@f83{~EYi#j1In7xuxjC$m@Bjp?e?x-dv<20&*`SCDWLdG`Sx7Pp*A8vRo$00A zX|-cbWFY!{ZqUSyaCP0HR;;ccU!x_kq>0-g39%QOBYFA}9&|y#8mHI36A}ouuicWA z0}vTso$voQt{po+gCwG`aD)>b_Ft0P_dsP{g=hi|0!`cqTS5~cT1XWm?D#ruX~?pY z&T(Sz$9JXy8n;H);Hx-1u?$$g01f9Q%6?I*LOhPYf@2q0kl@h#F~*KFJ?%+^+Jj{_ zk%;GU2V2&RsBEK+Y(q58o@mpg#zL5oha{b9;PEn2!4#4(h<|FTa~KQs+2x}lag#gb z3kBYS1VUv<@%xI#LwW7#SS4*UoyK1w!TI>(p|));4-F=SyGa^dfMg~Yw<(K4P&QbQ zn*NR4RHnnD@K=vvgN@lm!VkA zoD=XCJ-UAVn5Iz2sJv?khVsOV>{JN1kw`p`yz+dz@uJHMHy8aCk<S%j zyYYf2d7WXI5awPLZ3Su>-(km`k z)OCI1?vuBx+9v|)E>ZkhhQxwU$a&??oxf;Sn+_ecW2!ps@QYkC^HaxV*7@XtwB?7RM?<`&BC6Ka?Wrc zQ1h##@OZN!^y3kxd&P2+xPn)5svK_^m0zrEDT_M>2Veg{VZkiF$JXYDA3lANi)+Q- z-7k$P{H;!ls2~Wj9prEB1d08A6zsVmxP8;mzgxnwo;#s7f<$L2RHhc_2uBk{(y_Lr z0%LaP=g=a`X1X-~otsQF&F{ZC|B?3H{u8(BRC@)s{^hl10UNcI7*at?%cdKK6x@%A z;ufj)Z(A%_;6;Gyw3~z`T*#49!Y&EHQ6voIF_!Q`K3{F{z!g{W+XzdwVbHSboP#a! z+gP{{asxFHMFw{ZnfyLop!{XfYg0}%CoSZG)j2&#()j2@9eo-q_WltPkd9|8+rck8 zV%6v8k4|aU%p+}HXNphIByKy(-VoKc!T0p0fMr;_z8U>c+inZ@Lp}5H(4n>sFTFI9 z4ThHsf^%4*ZHbbyRGlnKCS`5fTM~Nn@FkbL35yqRf+VNXTxi@7opv^w@Y{rUh`FrO z$}SS{+-M!Ilt%ReH6lL8%I0S*)Ilj_Q&!oV^T^sn5*7*5Is_+)N&y{^@(J!t(xd$G zgBH+?jA8TYz0ubO*~cTz_zMev@hSvuZa5M<-l?vaJ5RQgfSc6H0m9cjT<-GKD&%adM1c6~j1yWO}-uyhe2PI^$A930Jz21L!BP21E3OTDP4q-r@TbgSF zHV$3PU${e*s@<;a8C4}4D5Gol51xlQ#7F5@^Q_^r$QmMn_+HT=BVl5{pA22Pe58aT zXWQ48whD>TE+}Lccc2DY&{PPvvGrQ`!4U5AAO*T&XsfAQOsG_9j{Y&{$NS)s(;~(P$0{j><3YN6%$HIbMVz5E3G# zQ}N2lXS0!iPK@erO$(lFonYR0CrhU@-&2uyjz!;5>*PJU_cY^~oTG5Wh!z2&Y#zXx zR%^0N*v@vYyCmrIOcE}~Z2+M*euBN2UNnwtKZGQpa*Hu9I6c{b7w_ylrs3+0gsrI>8GRM3%Fk?l zQ9GUrmWA@}1ZBD8;54=_o()Mth5h6Z;bFx+ULQzsSOxCM4=&nvMvozEaZRzT{JOIs z?M|LfTpslRfv=@D%a{wAdLe{nD?-Yw*1-ba?6Gw5>tNyS{OR~$ry}QCP^~FoA`sr2 zQPeNq`=`AI2@8+b=h06~Ibk3i`Y~w6)jAsJeCkDflOKv+OFO{8>4}u0siDJ$RUQ!F zl*$iMnPKrWgY47&D<^ejdr7z*Mer(%4U@)x5;f-(yi@mH6p(M>AY#sP@HzXjm zdVCAN#IDhO7DU_vUeKy3t^H&@#0@9=c)IlZp`Q7uLgkFI869$f*v(Qde=t1iinyemNq%<_kPUdJqvm zAv=-yl}>nceWfAaD_h@x|E-0=L)Ae%=VRKkVJ%se==BIC-77}hmYBaqgd3vyrt`?Ym#sEa6D>VcW8uvA-`~2g zr1%9xhQ{;g{h(z)PVXg4{+m57yu+pZT;ShEAH*U-B!q!RP%8~gvXmCYlVU0&I-j2uDF=y z&wmuhj!l@DV;eT)I>1-lF-CQ1s;{WtvZQ!dO&l!&WVXt?m-7uUsAwuikc;irRZhW0xY6HtC zxsa?#=PDk@SEf;D2P7F04N{O;Mgn(nBMS=!rM6xAIxbf^%d5B9qaNrK@TmM|DN!qV z?u-5FN3AL?$hlGwy+Sd*3v2NU-L~}cJP$94bq=Cj+t!WCC-5@nZ_5gfOh5)(A^6?a zjl<>XJwEt%`C}35-f#N7{QMM3OKWcH31-ZFNoz6*ZBJxX`9$AAyekAYWki4XcuW*zIA$JeR_`$!r=p(+U>%%I_ zLT`$RJnvjy&Ar)m4p~+^MB$89$6vQzqK}k*Iq@3q5MNX~_97|?LOd$J84Ag}QwCI? zk#zf(FZxLV_eU5P5c*1_oWjk+Q|$(PZ%Itqx@CFuy?clLyJgE|B~XX3fU{C(n`Qz1 ziWiP{fW_8m#O|m(5RQg>BIOB2?b*0a#lSXkvR#9A{ zeg_uNRh9_dn>l3m!OG6F>zmQddF^#ljHN);z%J&WmrYB)M$-C#MQm#EUT2*KIGFsLn?6k9nDl4V2^gZ@^Uc z(4RmMbt2@neqz%>X~lC`W&J%sET4Yb%yx~7Q_iY7jMIhf?dXC!W-Ov*N0mVbYijsYG3GRaU%FPuv8~&2il%xX6uD~7EYgwOUC1qw`MNA=g4W3cR%VtrN?XlVImrZ5KFCfkc z17iufMS!&$O4{?~R@h;p#a-wmsE(C2h!k0ej}w`TQ^%tj5L~$t9tA z((9RpOU63`EsJj9zw|hFbXhUJgP+&7UkQ}@re>Y@T#bW0{*<_3<4-@cAVC@4y0r>T z_59+kTZ=5Ktiw}6QTcubg62GR899Ic{13(^kP}sTJkoWRUEob+T~b95esG4I??RGO zX>VNS<{ApU0c8fC2pk0RQLnG)R}eQa)(B@A;5ey~+?PM~)OIaxFSEM*3_ty-0?s4a zK^FeITzf;~Pej0z5nF2NdpuoxM5Sx2#^I7I+0)gtZ+A#Q_Ixlo)dofmUrY4mNY>79 z@Do2ml2fJ1rIG|97_<0-mq%0*v@`%84SY25F&BTki}(DSr>V!c~Y zd6ZB>9-#&*y~}O{YrHjS5PvAEsJXXJL>3zYCkc+JJLoYQqG>c5*i_Dj(%nL z?ySa&M^L3qssx_Sv@>kBgxSHUBF1jsd}+Eje?l7~c^AZTiv~72yHhJ&QCN4;=Ci$9h{(x^vRZB*YS!atqWXyLHg zZPh$YnQ<*tFy%b|zR>#!@^?IXM_vb_$qjmg1iH)JEaTehtbsRl&~y0Tyo#axDJrvn z_;{_eUp`SnI8Zrl#n;%a(yO`cD7Wol(T?GcX}jN(@myuLrtL$Ay3j^6VdZH5nFrufaE?M>qGnGw$I|f9%mRmWkFxIKdLZ zhc}J9qN^G>AVH|{7fBs3`&|R2vN%^XG$F6;Uga;yn5(SPP!CvY`hXBIA66qd>++SS zfZ`|O&!2da-H-o~YV?j8Y_W`e`~+_}44F4&44DH5`M_{sl?-|mfdjEYa- zH_f;^#Yn*GcmyAm5o(npWb~yy9>uphDdUC8&SP3uJ3@J(T0ID_A?3CB8&ihv+PLbg zgzySgoKSD$>_6vifjE?fX-(w$3d%10PZc^oGuP=CMEJ)I^kl+4;qD-9>+@Ge}(1`22 zeCy^5vq|7@QmiK6uu@|lhe*@0s%KqV`mKS+Q+#klKo4#=DFWdxUU~Zcri(`n-9Gfj zxa4~)&k3s(&i*skxn0%>?jHZlJzDvtEQ5Q)u{M|WS)kzFI_=HW!(a<OD?evTI>Vq$ECrS?eYWotwBb&^iT^mT1P*S;1g&6yf>;kU(aRBN`CYf zEn^$igWO&=M4ko=wnLmJ5#B9z@4q#F^tiaXfS=U70neQKqie_DJNTw4D`mJPlCX;< zjgP$fIkz8JF+Kz82qfGRqv98*pI$Uvz4fe}+>)2YrumG(DsFL)L-aW4J|5W@hmfvt zH_x~(YmknIUR_jt0e{iHZBlK!B{~>c&q|kJ8`;|Lk4yZ1F9n8jJGme;*cxmxw>yY^ zysH0Db%u6dtZ152XSv*EHA+3oS!l}2=Zika1ce_|aG zV!O=quJ6uX4mIS=rSHDO+AOcgP}DZV14jq8N#q~}Zd*TmOk7-iYd!suZ{4&`G8ml3 zqx)zK^CY5TmiqT>gnzO@`f5ChIj#y19q81dg8(_oBDj}F?T(ckuGY~b*38wM+fw_% zQO;F!d(?C8T4Cw7ZGA!^OGV15Akg$BS?2W1di3}g)Fa<+x@d?&j<;L-I<^uq7F<{p zS?5H@1=#P&6WWK7&(?OAC1(JMt5rOm7>5OUczG!^#eHx41q2%aJlwXVZu71h$-cP_rpF>c7=W^P9#6Gdp_R{?MMsd3@G7T5Dx0!Sf z2r-O~EO*r?<0^MNUY;Lr;!fdR!>}!~r};Nwm&W6*Rv)~)c28=S+dB-T{4?M1Bb_{= z#q;(1Oo#1nS9I)n80v}b+lOXJpYzEkf%dn%tr#;##Jy6&jj01>om7hJGG`dFp5$v* zyE9{1_73vjd#u-zg|nd^sS_bDk8+R+1bo?q_A3yqvsqhi$3oUrsm-j;m+i4)(MUr!aC<}>n8XwnzzwRk4-04t5*t+`_pKPHtaAA?<+0Zt7o*uR9 zkR^qMPSb>+bL%>vfBLXSmxeCqrK3(etzP~63pZUbG&R)Xl_tS9(L+&DS(xlcU7n05 zaoEWR##}pM^kBBQ<#Jm+hp)Thi2f~?y=O?RiZ=Qsx{m_HZkIiM^{Z z7~kRLGRm?me>*#Wi0n#(WGas;WHN#@xCMR(R1`ry)vK!SPh?1Wx1ER93MCcLYY6 z84pR2L<5C#cA@II&>}qO?w|KKXc`qNoRi%FA9ADVAFZAR{6`i3S~+(?9k5~O&@^5* zGdnI@=2rt;JcCZeRmiJC&Fz0|THro9my<3P5@uH-;Cn17r#2P=S0t^FD|YS;KE{u2aaG3&ga<&=;3+A%w>Lj) z6?`<-dYK7APOM3w&4xfy3wf8ah%Ckwo||v0>^L=d_vcT!2s90r;+1zbLn&0;^iyIT z!zSDp-OkLnp^=f)LauQ3pRtV%EVEdWD|JQXC5(rtuzt3{YU&r2YS=Cuj|qV>J91u| zdCS=(V|-&Uv{fYOg`6KA?e=8;jZKKJK$K8W#}9-dfg;=8MDuGL7D|)2(1u)x4?ItB zL-=jXc=$vc4pPbOjdf2#(hIqw+&_PjbzfSIT?2q9NEvuABK!JNPkwKC7D9t6SbXo*(a8v=nfo^h6h zKeBko+TB<}WZj<9Z{`=!h-olFu1Fv7`}JT+)vL#jvPp15>?Sv?O6nppSFo9+pRQVyL+IWRc416Ekj{ zBzQcf@9ft=)9{2`;Vw>pj}3AU#j?2bJjk+U$J#flVNk}Es%kx=BP+Or5)Sf@RK)N zOrt3w{K4(Y$Z3pg;g!*#h5RVKf=Ms1;&x-SIu`V~&f){paM+7Fu3G}a>)>etU-9Ft zci#<_YM%5vm*>zU`Z-3@Al3DXxclebL_{&%8R@n_degf>lW{yfoG^ zEZ~P(N1x>CJL3gC2aipoP}h$_YbIp*Eisob`&#}K9uo+0uO-Crw7xUG0!>`;t)BRE zkb>vm)P+CB3bDEy1YYazJ98OmDy2~gxq>#_ndbMolnd8uXbcN&eYL0rO~MCN5P)YmbeUgA7Pm@Ma8JC{r%E>r)1TX zxMjO&tf(wIfr8>E!IH06Cg7}-{|iBm)B;|88r?{Kl(OARzT(>rghwPn#nc)r$Q~M# z(&w3-ps90wYo>J|8Jvp*m&QJ-EH2yc4+QDq_CsdZYjT2Qr_lLLiLc5jy%l0+lUSz*m-u52g*8 z^#N#3h(<5uN1;vAI{3YzT)rW{tkCF+rKI~0wt*Mgx7TXo$x@u3)7$|xh6txrmcx#h z$BJ0U7mz*pguBllv^I4TXdy2LZO?W24|paZQZAK?GQ!qeKMVdpTwu?^?5B!Ab3#!5 zgf@OOST(0#L)6^xM-PPkY+{?_3gMfm=ieud7V;>RuAY20N~x03htJay@`E85pE)>h z1!$@bt$3i7-{zl40OPp9Rh9YXLnPZht^rSf1DaYv3waERSKi;uVGG>HBf4^_3|HR) z=BAjTnK<~FV$j5dHcV;l4_J5dy4UUeu|?%aqw-C7z_mB{I*!ztW@{5I_MPwd9J@g8dMXF;ygMN1S}E~iHe5EV^jL($d@tX2+3$x%Ju&`&AtMapfXc-%k9(OHDUmnk-cJW4S2Mu=Z)Lojv ztN4EWiW^pEZe6xYekH_~^^XJ?PuPC+uhOG;-JylN26(@k)YmZKF&=$}0v(Sn#=`F* zm6uK8t1f%`V(gpSX!fV8qy{#0Uci>}vAo`WE*CY2N*AEtpx7!ZWBX_*eLS9Sw z*G%amO*x83^&9x6_JHX7phH~uH4FY~6j&fY<{$JK{|lkziRY#ZqH%W5NA?WDc8l11UkQADMMU%kPs?9*+0qv_Ci_I9qJ_Mcp|z7!1D5$SN#Yhk zZ~+T+W~IM?u#1(~t$f^8wo0$#*Uc#|v4y(>UkMnYkd(nD;0{6mT_J$BR!t+IsQEMO z00;aC4iE0Lr>A7v`~k01I7FuDhYrHP{wSfBMCe>*5eGsY zSE|%Mh$Y-Hcvx$wRFK#vkS3*UNdmI?K{w@dHRVyZDL;1pAqSich+e+P-Td<()=CyS zh5Rhp?G6nUE#&op+S2OJC_0<1(W6<&#&XeVkfgAE!OI=iO737@u`FY0+Q1omK$FmD zA+KkYz?)gc1I-Zr41^qpC|NgA|}#~Ipw zqszCiX+Oijb1kAFtWtO9;?rwl?5f3Y!-yaFl?{WiT1sn83c5bgJMWSkE#wIVeLv9+ zrJ1QEC5KxW5_+N#-FPXgC+o선택된 체크박스 선택되진 않은 체크박스 + 등록 성공 + 반려동물 등록 성공! + 더 많은 반려동물 등록을 원하시나요? + 반려동물 등록하기\ + 버튼을 클릭해서 + 다른 반려동물의 추억과 일정을 관리해보세요! + 마이페이지 From b331a663f04a9c57f75dddc6e6b5245102d88f76 Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Thu, 10 Aug 2023 01:59:47 +0900 Subject: [PATCH 33/37] =?UTF-8?q?fix:=20navArguments=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EC=83=81=EC=88=98=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 21 ++++++++------ .../ui/register_dog/RegisterDogActivity.kt | 28 ++++++++++++++----- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 09a8ea8..48eb3a4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,21 +20,21 @@ android:label="@string/app_name" android:theme="@style/Theme.Meongmory"> - - + + - - + + - - + + - - + + + + + + + diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt index f9cc3e2..c3c9733 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt @@ -23,6 +23,11 @@ import com.meongmoryteam.presentation.ui.theme.MeongmoryTheme import com.meongmoryteam.presentation.ui.theme.White import dagger.hilt.android.AndroidEntryPoint +object NavArgs { + const val BREED_ROUTE_PLUS = "/{breed}" + const val BREED_ARG = "breed" +} + sealed class Route(val route: String) { object RegisterDog : Route("RegisterDog") object SuccessRegister : Route("SuccessRegister") @@ -57,12 +62,12 @@ fun RegisterDogNavigation( ) { NavHost( navController = navController, - startDestination = Route.RegisterDog.route.plus("/{breed}"), + startDestination = Route.RegisterDog.route.plus(NavArgs.BREED_ROUTE_PLUS), modifier = modifier ) { composable( - route = Route.RegisterDog.route.plus("/{breed}"), - arguments = listOf(navArgument("breed") { type = NavType.StringType }) + route = Route.RegisterDog.route.plus(NavArgs.BREED_ROUTE_PLUS), + arguments = listOf(navArgument(NavArgs.BREED_ARG) { type = NavType.StringType }) ) { RegisterDogScreen( navController = navController, @@ -70,22 +75,31 @@ fun RegisterDogNavigation( navigateToMakeScreen = { navController.navigate(Route.SuccessRegister.route) }, navigateToPreviousScreen = { navController.navigate(Route.Main.route) }, searchBreed = - if (it.arguments?.getString("breed") == null || it.arguments?.getString("breed") == "{breed}") stringResource(R.string.blank) - else "${it.arguments?.getString("breed")}" + if (it.arguments?.getString(NavArgs.BREED_ARG) == null || it.arguments?.getString( + NavArgs.BREED_ARG + ) == NavArgs.BREED_ROUTE_PLUS + ) stringResource(R.string.blank) + else "${it.arguments?.getString(NavArgs.BREED_ARG)}" ) } composable(route = Route.SuccessRegister.route) { //등록 성공 스크린 SuccessRegisterScreen( navController = navController, - navigateToMainScreen = {navController.navigate(Route.Main.route)} + navigateToMainScreen = { navController.navigate(Route.Main.route) } ) } composable(route = Route.SearchBreed.route) { //품종 검색 스크린 SearchBreedScreen( navController = navController, - navigateToPreviousScreen = { navController.navigate(Route.RegisterDog.route.plus("/{breed}")) }, + navigateToPreviousScreen = { + navController.navigate( + Route.RegisterDog.route.plus( + NavArgs.BREED_ROUTE_PLUS + ) + ) + }, ) } composable(route = Route.Main.route) { From 234fa876a7763b69753b940408bdedc4d4ab870b Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Thu, 10 Aug 2023 02:22:28 +0900 Subject: [PATCH 34/37] =?UTF-8?q?fix:=20Text=20=ED=95=84=EB=93=9C=20?= =?UTF-8?q?=EB=82=B4=EB=B6=80=EB=A1=9C=20=EC=A7=80=EC=97=AD=EB=B3=80?= =?UTF-8?q?=EC=88=98=20=EC=9D=B4=EB=8F=99=20=EB=B0=8F=20TextComponent=20?= =?UTF-8?q?=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 21 ++++++-------- .../ui/register_dog/RegisterDogActivity.kt | 3 +- .../ui/register_dog/RegisterDogScreen.kt | 28 ++++++++++--------- .../ui/register_family/RegisterForm.kt | 6 ++-- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 48eb3a4..09a8ea8 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,21 +20,21 @@ android:label="@string/app_name" android:theme="@style/Theme.Meongmory"> - - + + - - + + - - + + - - + + - - - - - diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt index c3c9733..bc3cec5 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogActivity.kt @@ -26,6 +26,7 @@ import dagger.hilt.android.AndroidEntryPoint object NavArgs { const val BREED_ROUTE_PLUS = "/{breed}" const val BREED_ARG = "breed" + const val BREED_EXCEPTION_ARG = "{breed}" } sealed class Route(val route: String) { @@ -77,7 +78,7 @@ fun RegisterDogNavigation( searchBreed = if (it.arguments?.getString(NavArgs.BREED_ARG) == null || it.arguments?.getString( NavArgs.BREED_ARG - ) == NavArgs.BREED_ROUTE_PLUS + ) == NavArgs.BREED_EXCEPTION_ARG ) stringResource(R.string.blank) else "${it.arguments?.getString(NavArgs.BREED_ARG)}" ) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt index 8f1d4b6..82e2032 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt @@ -60,6 +60,7 @@ import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.Regist import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.RegisterDogSideEffect import com.meongmoryteam.presentation.ui.register_family.RegisterDogForm import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent +import com.meongmoryteam.presentation.ui.register_family.TextComponent import com.meongmoryteam.presentation.ui.register_family.TextFieldComponent import com.meongmoryteam.presentation.ui.theme.Black import com.meongmoryteam.presentation.ui.theme.ButtonContent @@ -197,10 +198,10 @@ fun RenderBreed(value: String, navigateToSearch: () -> Unit) { Yellow } Column(modifier = Modifier.padding(bottom = 14.dp)) { - Text( + TextComponent( text = stringResource(R.string.breed), - color = Placeholer, style = Typography.titleSmall, + color = Placeholer, modifier = Modifier.padding(bottom = 12.dp) ) Box( @@ -211,17 +212,18 @@ fun RenderBreed(value: String, navigateToSearch: () -> Unit) { .border(width = 1.dp, color = borderColor, shape = RoundedCornerShape(10.dp)) .padding(horizontal = 15.dp, vertical = 14.dp) ) { - val text: String - val color: Color - if (value == null) { - text = stringResource(R.string.breed) - color = Placeholer - } else { - text = value - color = Black - Log.d("CHANGE", "change") - } - Text(text = text, style = Typography.titleSmall, color = color, maxLines = 1) + TextComponent( + text = stringResource(R.string.breed), + style = Typography.titleSmall, + color = Placeholer, + modifier = Modifier.padding(bottom = 12.dp) + ) + Text( + text = value.ifEmpty { stringResource(R.string.breed) }, + style = Typography.titleSmall, + color = if (value.isEmpty()) Placeholer else Black, + maxLines = 1 + ) } } diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt index 1e1dfc5..1458ca7 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt @@ -114,13 +114,15 @@ fun TextComponent( text: String, style: TextStyle, modifier: Modifier = Modifier, - color: Color + color: Color, + maxLine: Int = 1 ) { Text( text = text, style = style, modifier = modifier, - color = color + color = color, + maxLines = maxLine ) } From d9b2b3f438e98a56e681c751602bf4192c6b6dff Mon Sep 17 00:00:00 2001 From: seuriseuljjeok Date: Sun, 13 Aug 2023 03:05:42 +0900 Subject: [PATCH 35/37] =?UTF-8?q?refactor:=20Text=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=ED=95=A8=EC=88=98=20=EA=B3=B5=EC=9A=A9=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/base/CommonText.kt | 118 ++++++++++++++++++ .../ui/register_dog/RegisterDogScreen.kt | 7 +- .../ui/register_dog/SearchBreedScreen.kt | 4 +- .../ui/register_dog/SuccessRegisterScreen.kt | 4 +- .../register_family/RegisterFamilyScreen.kt | 2 + .../ui/register_family/RegisterForm.kt | 108 ---------------- .../invitation/RegisterByCodeScreen.kt | 7 +- .../name/RegisterByNameScreen.kt | 6 +- 8 files changed, 133 insertions(+), 123 deletions(-) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/base/CommonText.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/base/CommonText.kt b/presentation/src/main/java/com/meongmoryteam/presentation/base/CommonText.kt new file mode 100644 index 0000000..005fecd --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/base/CommonText.kt @@ -0,0 +1,118 @@ +package com.meongmoryteam.presentation.base + +import android.util.Log +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ButtonColors +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.meongmoryteam.presentation.ui.theme.AppleSD +import com.meongmoryteam.presentation.ui.theme.Black +import com.meongmoryteam.presentation.ui.theme.InputBoxOutline +import com.meongmoryteam.presentation.ui.theme.Placeholer +import com.meongmoryteam.presentation.ui.theme.QuestionButtonText +import com.meongmoryteam.presentation.ui.theme.Typography + +@Composable +fun TextComponent( + text: String, + style: TextStyle, + modifier: Modifier = Modifier, + color: Color, + maxLine: Int = 1 +) { + Text( + text = text, + style = style, + modifier = modifier, + color = color, + maxLines = maxLine + ) +} + +@Composable +fun TextButtonComponent( + text: String, + colors: ButtonColors, + style: TextStyle, + width: Float = 1f, + modifier: Modifier = Modifier, + onClick: () -> Unit +) { + TextButton( + onClick = onClick, + shape = RoundedCornerShape(10.dp), + modifier = modifier + .fillMaxWidth(width) + .height(50.dp) + .padding(vertical = 5.dp), + colors = colors, + ) + { + Text( + text = text, + style = style, + textAlign = TextAlign.Center, + color = QuestionButtonText + ) + } +} + +@Composable +fun TextFieldComponent( + name: String, + onValueChange: (String) -> Unit, + placeholder: String, + modifier: Modifier = Modifier.fillMaxWidth(), + bgColor: Color = Color(0xFFF9F9F9), + borderColor: Color = InputBoxOutline, + keyboardOptions: KeyboardOptions = KeyboardOptions.Default, + keyboardActions: KeyboardActions = KeyboardActions.Default +) { + BasicTextField( + value = name, + onValueChange = onValueChange, + modifier = Modifier.height(43.dp), + singleLine = true, + textStyle = TextStyle( + color = Black, + fontFamily = AppleSD, + fontWeight = FontWeight.W400, + fontSize = 12.sp, + lineHeight = 20.sp + ), + decorationBox = { + Box( + modifier = modifier + .background(bgColor) + .border(width = 1.dp, color = borderColor, shape = RoundedCornerShape(10.dp)) + .padding(horizontal = 15.dp, vertical = 14.dp) + ) { + if (name.isEmpty()) { + Text(text = placeholder, style = Typography.titleSmall, color = Placeholer) + } else { + it() + Log.d("CHANGE", "change") + } + } + }, + keyboardOptions = keyboardOptions, + keyboardActions = keyboardActions + ) +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt index 82e2032..38129b5 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/RegisterDogScreen.kt @@ -1,6 +1,5 @@ package com.meongmoryteam.presentation.ui.register_dog -import android.util.Log import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -56,12 +55,12 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.base.TextButtonComponent +import com.meongmoryteam.presentation.base.TextComponent +import com.meongmoryteam.presentation.base.TextFieldComponent import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.RegisterDogEvent import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.RegisterDogSideEffect import com.meongmoryteam.presentation.ui.register_family.RegisterDogForm -import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent -import com.meongmoryteam.presentation.ui.register_family.TextComponent -import com.meongmoryteam.presentation.ui.register_family.TextFieldComponent import com.meongmoryteam.presentation.ui.theme.Black import com.meongmoryteam.presentation.ui.theme.ButtonContent import com.meongmoryteam.presentation.ui.theme.InputBoxOutline diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt index 4421a08..6348363 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SearchBreedScreen.kt @@ -46,11 +46,11 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.base.TextButtonComponent +import com.meongmoryteam.presentation.base.TextFieldComponent import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.RegisterDogEvent import com.meongmoryteam.presentation.ui.register_dog.RegisterDogContract.RegisterDogSideEffect import com.meongmoryteam.presentation.ui.register_family.RegisterDogForm -import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent -import com.meongmoryteam.presentation.ui.register_family.TextFieldComponent import com.meongmoryteam.presentation.ui.theme.Black import com.meongmoryteam.presentation.ui.theme.ButtonContent import com.meongmoryteam.presentation.ui.theme.DarkGrey diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt index 9a161f9..67dde02 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_dog/SuccessRegisterScreen.kt @@ -26,8 +26,8 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R -import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent -import com.meongmoryteam.presentation.ui.register_family.TextComponent +import com.meongmoryteam.presentation.base.TextButtonComponent +import com.meongmoryteam.presentation.base.TextComponent import com.meongmoryteam.presentation.ui.theme.AppleSD import com.meongmoryteam.presentation.ui.theme.Brown import com.meongmoryteam.presentation.ui.theme.EditDivider diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt index ac5815e..f035a9e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterFamilyScreen.kt @@ -12,6 +12,8 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.base.TextButtonComponent +import com.meongmoryteam.presentation.base.TextComponent import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyContract.RegisterFamilyEvent import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyContract.RegisterFamilySideEffect import com.meongmoryteam.presentation.ui.theme.Brown diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt index 1458ca7..456c574 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/RegisterForm.kt @@ -1,25 +1,16 @@ package com.meongmoryteam.presentation.ui.register_family -import android.util.Log 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 import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.fillMaxHeight 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.shape.RoundedCornerShape -import androidx.compose.foundation.text.BasicTextField -import androidx.compose.foundation.text.KeyboardActions -import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack -import androidx.compose.material3.ButtonColors import androidx.compose.material3.CenterAlignedTopAppBar import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon @@ -27,26 +18,15 @@ import androidx.compose.material3.IconButton import androidx.compose.material3.Scaffold import androidx.compose.material3.Surface import androidx.compose.material3.Text -import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import androidx.navigation.NavController import com.meongmoryteam.presentation.R -import com.meongmoryteam.presentation.ui.theme.AppleSD -import com.meongmoryteam.presentation.ui.theme.Black -import com.meongmoryteam.presentation.ui.theme.InputBoxOutline -import com.meongmoryteam.presentation.ui.theme.Placeholer -import com.meongmoryteam.presentation.ui.theme.QuestionButtonText import com.meongmoryteam.presentation.ui.theme.Typography import com.meongmoryteam.presentation.ui.theme.White @@ -109,91 +89,3 @@ fun RegisterDogForm( } -@Composable -fun TextComponent( - text: String, - style: TextStyle, - modifier: Modifier = Modifier, - color: Color, - maxLine: Int = 1 -) { - Text( - text = text, - style = style, - modifier = modifier, - color = color, - maxLines = maxLine - ) -} - -@Composable -fun TextButtonComponent( - text: String, - colors: ButtonColors, - style: TextStyle, - width: Float = 1f, - modifier: Modifier = Modifier, - onClick: () -> Unit -) { - TextButton( - onClick = onClick, - shape = RoundedCornerShape(10.dp), - modifier = modifier - .fillMaxWidth(width) - .height(50.dp) - .padding(vertical = 5.dp), - colors = colors, - ) - { - Text( - text = text, - style = style, - textAlign = TextAlign.Center, - color = QuestionButtonText - ) - } -} - -@Composable -fun TextFieldComponent( - name: String, - onValueChange: (String) -> Unit, - placeholder: String, - modifier: Modifier = Modifier.fillMaxWidth(), - bgColor: Color = Color(0xFFF9F9F9), - borderColor: Color = InputBoxOutline, - keyboardOptions: KeyboardOptions = KeyboardOptions.Default, - keyboardActions: KeyboardActions = KeyboardActions.Default -) { - BasicTextField( - value = name, - onValueChange = onValueChange, - modifier = Modifier.height(43.dp), - singleLine = true, - textStyle = TextStyle( - color = Black, - fontFamily = AppleSD, - fontWeight = FontWeight.W400, - fontSize = 12.sp, - lineHeight = 20.sp - ), - decorationBox = { - Box( - modifier = modifier - .background(bgColor) - .border(width = 1.dp, color = borderColor, shape = RoundedCornerShape(10.dp)) - .padding(horizontal = 15.dp, vertical = 14.dp) - ) { - if (name.isEmpty()) { - Text(text = placeholder, style = Typography.titleSmall, color = Placeholer) - } else { - it() - Log.d("CHANGE", "change") - } - } - }, - keyboardOptions = keyboardOptions, - keyboardActions = keyboardActions - ) -} - diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt index a954124..afba7f9 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/invitation/RegisterByCodeScreen.kt @@ -14,7 +14,6 @@ import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.PlatformTextStyle import androidx.compose.ui.text.TextStyle @@ -24,14 +23,14 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.base.TextButtonComponent +import com.meongmoryteam.presentation.base.TextComponent +import com.meongmoryteam.presentation.base.TextFieldComponent import com.meongmoryteam.presentation.ui.register_family.RegisterDogForm import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyContract.RegisterFamilyEvent import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyContract.RegisterFamilyEvent.FillInCode import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyContract.RegisterFamilySideEffect import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyViewModel -import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent -import com.meongmoryteam.presentation.ui.register_family.TextComponent -import com.meongmoryteam.presentation.ui.register_family.TextFieldComponent import com.meongmoryteam.presentation.ui.theme.AppleSD import com.meongmoryteam.presentation.ui.theme.Black import com.meongmoryteam.presentation.ui.theme.ButtonContent diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt index fda791f..74f27ef 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/register_family/name/RegisterByNameScreen.kt @@ -22,13 +22,13 @@ import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavController import com.meongmoryteam.presentation.R +import com.meongmoryteam.presentation.base.TextButtonComponent +import com.meongmoryteam.presentation.base.TextComponent +import com.meongmoryteam.presentation.base.TextFieldComponent import com.meongmoryteam.presentation.ui.register_family.RegisterDogForm import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyContract.RegisterFamilyEvent import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyContract.RegisterFamilySideEffect import com.meongmoryteam.presentation.ui.register_family.RegisterFamilyViewModel -import com.meongmoryteam.presentation.ui.register_family.TextButtonComponent -import com.meongmoryteam.presentation.ui.register_family.TextComponent -import com.meongmoryteam.presentation.ui.register_family.TextFieldComponent import com.meongmoryteam.presentation.ui.theme.ButtonContent import com.meongmoryteam.presentation.ui.theme.DarkGrey import com.meongmoryteam.presentation.ui.theme.InputBoxOutline From e8e72fe7a309a28d6599e15357a2b5e276027f37 Mon Sep 17 00:00:00 2001 From: arinming Date: Sun, 13 Aug 2023 12:45:23 +0900 Subject: [PATCH 36/37] =?UTF-8?q?[refactor/mypage]=20ViewState=20=EA=B0=92?= =?UTF-8?q?=EC=9D=84=20State=20Hoisting=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#?= =?UTF-8?q?37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/HomeViewModel.kt | 15 - .../main/{HomeContract.kt => MainContract.kt} | 10 +- .../ui/main/{HomeScreen.kt => MainScreen.kt} | 2 - .../presentation/ui/main/MainViewModel.kt | 15 + .../presentation/ui/myPage/MyPageScreen.kt | 545 +++++++++--------- .../presentation/ui/myPage/MyPageViewModel.kt | 3 + .../myPage/profile/MyPageProfileContract.kt | 3 +- .../ui/myPage/profile/MyPageProfileScreen.kt | 30 +- .../myPage/profile/MyPageProfileViewModel.kt | 25 +- .../question/MyPageQuestionConstract.kt | 5 +- .../myPage/question/MyPageQuestionScreen.kt | 15 +- .../question/MyPageQuestionViewModel.kt | 21 +- 12 files changed, 350 insertions(+), 339 deletions(-) delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt rename presentation/src/main/java/com/meongmoryteam/presentation/ui/main/{HomeContract.kt => MainContract.kt} (67%) rename presentation/src/main/java/com/meongmoryteam/presentation/ui/main/{HomeScreen.kt => MainScreen.kt} (97%) create mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt deleted file mode 100644 index 579175d..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.meongmoryteam.presentation.ui.main - -import com.meongmoryteam.presentation.base.BaseViewModel -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import com.meongmoryteam.presentation.ui.main.HomeContract.* - -@HiltViewModel -class HomeViewModel @Inject constructor( -) : BaseViewModel( - HomeViewState() -) { - override fun handleEvents(event: HomeEvent) { - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt similarity index 67% rename from presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt rename to presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt index 69e220e..a33e491 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainContract.kt @@ -4,18 +4,18 @@ import com.meongmoryteam.presentation.base.ViewEvent import com.meongmoryteam.presentation.base.ViewSideEffect import com.meongmoryteam.presentation.base.ViewState -class HomeContract { - data class HomeViewState( +class MainContract { + data class MainViewState( val loginState: LoginState = LoginState.NONE, ) : ViewState - sealed class HomeSideEffect : ViewSideEffect { + sealed class MainSideEffect : ViewSideEffect { } - sealed class HomeEvent : ViewEvent { + sealed class MainEvent : ViewEvent { } enum class LoginState { - NONE, LOGIN + NONE } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt similarity index 97% rename from presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt rename to presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt index 51ade5c..0b5c7bd 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainScreen.kt @@ -3,14 +3,12 @@ package com.meongmoryteam.presentation.ui.main import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview -import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt new file mode 100644 index 0000000..eadad17 --- /dev/null +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/MainViewModel.kt @@ -0,0 +1,15 @@ +package com.meongmoryteam.presentation.ui.main + +import com.meongmoryteam.presentation.base.BaseViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import com.meongmoryteam.presentation.ui.main.MainContract.* + +@HiltViewModel +class MainViewModel @Inject constructor( +) : BaseViewModel( + MainViewState() +) { + override fun handleEvents(event: MainEvent) { + } +} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt index bc56ea6..e57a801 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageScreen.kt @@ -21,8 +21,6 @@ import androidx.compose.material3.Icon 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 import androidx.compose.ui.Alignment @@ -38,7 +36,6 @@ import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.hilt.navigation.compose.hiltViewModel import com.meongmoryteam.presentation.R -import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.base.LogoutAlertDialog import com.meongmoryteam.presentation.base.SecessionAlertDialog import com.meongmoryteam.presentation.ui.theme.ListDivider @@ -58,8 +55,6 @@ fun MyPageScreen( navigateToEditNickNameScreen: () -> Unit, navigateToQuestionScreen: () -> Unit, ) { - val viewState by viewModel.viewState.collectAsState() - LaunchedEffect(true) { viewModel.setEvent(MyPageContract.MyPageEvent.InitMyPageScreen) } @@ -78,300 +73,262 @@ fun MyPageScreen( } } - - - when (viewState.loadState) { - LoadState.SUCCESS -> { - Column { - MyPageTitle() - MyPageProfile( - OnClickEditNickname = { - viewModel.setEvent(MyPageContract.MyPageEvent.OnClickProfileEditButtonClicked) - } - ) - MyPageList( - onQuestionClicked = { - viewModel.setEvent(MyPageContract.MyPageEvent.OnQuestionClicked) - } - ) + Column { + MyPageTitle() + MyPageProfile( + OnClickEditNickname = { + viewModel.setEvent(MyPageContract.MyPageEvent.OnClickProfileEditButtonClicked) } - } - - LoadState.LOADING -> {} - LoadState.ERROR -> {} + ) + MyPageList( + onQuestionClicked = { + viewModel.setEvent(MyPageContract.MyPageEvent.OnQuestionClicked) + } + ) } } -@Composable -fun MyPageTitle() { - Box( - modifier = Modifier - .padding(24.dp) - .fillMaxWidth(), - contentAlignment = Alignment.Center - ) { - Text( - text = stringResource(R.string.my_page_title), - fontSize = 15.sp - ) + @Composable + fun MyPageTitle() { + Box( + modifier = Modifier + .padding(24.dp) + .fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Text( + text = stringResource(R.string.my_page_title), + fontSize = 15.sp + ) + } } -} -@Composable -fun MyPageProfile( - OnClickEditNickname: () -> Unit, -) { + @Composable + fun MyPageProfile( + OnClickEditNickname: () -> Unit, + ) { // 상단 프로필 메뉴 - Column { - Row( - Modifier - .padding(PADDING_16) - .fillMaxWidth() - .clip(RoundedCornerShape(20)) - .border(width = 1.dp, color = MyPageYellowStroke, shape = RoundedCornerShape(20.dp)) - .background(color = Color(MyPageYellowFill.value)), - // 중앙 정렬 - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center - ) { - Column( - modifier = Modifier + Column { + Row( + Modifier .padding(PADDING_16) .fillMaxWidth() + .clip(RoundedCornerShape(20)) + .border( + width = 1.dp, + color = MyPageYellowStroke, + shape = RoundedCornerShape(20.dp) + ) + .background(color = Color(MyPageYellowFill.value)), + // 중앙 정렬 + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center ) { - Row( - modifier = Modifier.fillMaxWidth(), - verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.SpaceBetween + Column( + modifier = Modifier + .padding(PADDING_16) + .fillMaxWidth() ) { - Text( - text = stringResource(R.string.my_page_profile), - fontWeight = FontWeight.Bold, - fontSize = 14.sp - ) - Row( modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.End + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween ) { - MyPageProfileButton( - stringResource(R.string.my_page_profile_alarm), - onClick = { } - ) - MyPageProfileButton( - stringResource(R.string.my_page_profile_edit), - onClick = OnClickEditNickname + Text( + text = stringResource(R.string.my_page_profile), + fontWeight = FontWeight.Bold, + fontSize = 14.sp ) + + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.End + ) { + MyPageProfileButton( + stringResource(R.string.my_page_profile_alarm), + onClick = { } + ) + MyPageProfileButton( + stringResource(R.string.my_page_profile_edit), + onClick = OnClickEditNickname + ) + } } + Text( + modifier = Modifier.padding(bottom = 8.dp), + text = stringResource(R.string.my_page_phone_number), + fontSize = 10.sp + ) } - Text( - modifier = Modifier.padding(bottom = 8.dp), - text = stringResource(R.string.my_page_phone_number), - fontSize = 10.sp - ) } } } -} -@Composable -fun MyPageList( - onQuestionClicked: () -> Unit, -) { - // 마이페이지 목록 부분 - Row( - modifier = Modifier - .padding(PADDING_16) - .clip(RoundedCornerShape(5)) - .background(color = MyPageYellowFill) - .border(width = 1.dp, color = MyPageYellowStroke, shape = RoundedCornerShape(19.dp)) - .fillMaxWidth() - .fillMaxHeight() + @Composable + fun MyPageList( + onQuestionClicked: () -> Unit, ) { - Column { - Text( - text = stringResource(R.string.my_page_list_account), - fontWeight = FontWeight.Bold, - modifier = Modifier - .padding(start = 24.dp, top = 24.dp, bottom = 8.dp), - color = ListTitle, - fontSize = 11.sp - ) - ListButton( - R.drawable.ic_coin, - stringResource(R.string.my_page_pro_ver), - onClick = { }, - ) - ListButton( - R.drawable.ic_logout, - stringResource(R.string.my_page_logout), - stringResource(R.string.my_page_logout), - onClick = { }, - ) - ListButton( - R.drawable.ic_user, - stringResource(R.string.my_page_drop), - stringResource(R.string.my_page_drop), - onClick = { }, - ) - - Spacer(modifier = Modifier.padding(top = PADDING_16)) + // 마이페이지 목록 부분 + Row( + modifier = Modifier + .padding(PADDING_16) + .clip(RoundedCornerShape(5)) + .background(color = MyPageYellowFill) + .border(width = 1.dp, color = MyPageYellowStroke, shape = RoundedCornerShape(19.dp)) + .fillMaxWidth() + .fillMaxHeight() + ) { + Column { + Text( + text = stringResource(R.string.my_page_list_account), + fontWeight = FontWeight.Bold, + modifier = Modifier + .padding(start = 24.dp, top = 24.dp, bottom = 8.dp), + color = ListTitle, + fontSize = 11.sp + ) + ListButton( + R.drawable.ic_coin, + stringResource(R.string.my_page_pro_ver), + onClick = { }, + ) + ListButton( + R.drawable.ic_logout, + stringResource(R.string.my_page_logout), + stringResource(R.string.my_page_logout), + onClick = { }, + ) + ListButton( + R.drawable.ic_user, + stringResource(R.string.my_page_drop), + stringResource(R.string.my_page_drop), + onClick = { }, + ) - // 구분선 - Divider( - color = ListDivider, - modifier = Modifier - .fillMaxWidth() - .height(1.dp) - .padding(start = 24.dp, end = 24.dp) - ) + Spacer(modifier = Modifier.padding(top = PADDING_16)) - Text( - text = stringResource(R.string.my_page_support), - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(start = 24.dp, top = 24.dp, bottom = 8.dp), - color = ListTitle, - fontSize = 11.sp - ) + // 구분선 + Divider( + color = ListDivider, + modifier = Modifier + .fillMaxWidth() + .height(1.dp) + .padding(start = 24.dp, end = 24.dp) + ) - ListButton( - R.drawable.ic_mail, - stringResource(R.string.my_page_notice), - onClick = { }, - ) - ListButton( - R.drawable.ic_send, - stringResource(R.string.my_page_question), - onClick = onQuestionClicked, - ) + Text( + text = stringResource(R.string.my_page_support), + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(start = 24.dp, top = 24.dp, bottom = 8.dp), + color = ListTitle, + fontSize = 11.sp + ) - Spacer(modifier = Modifier.padding(top = PADDING_16)) + ListButton( + R.drawable.ic_mail, + stringResource(R.string.my_page_notice), + onClick = { }, + ) + ListButton( + R.drawable.ic_send, + stringResource(R.string.my_page_question), + onClick = onQuestionClicked, + ) - // 구분선 - Divider( - color = ListDivider, - modifier = Modifier - .fillMaxWidth() - .height(1.dp) - .padding(start = 24.dp, end = 24.dp) - ) + Spacer(modifier = Modifier.padding(top = PADDING_16)) - Text( - text = stringResource(R.string.my_page_app_info), - fontWeight = FontWeight.Bold, - modifier = Modifier.padding(start = 24.dp, top = 24.dp, bottom = 8.dp), - color = ListTitle, - fontSize = 11.sp - ) - ListButton( - R.drawable.ic_info, - stringResource(R.string.my_page_clause), - onClick = { }, - ) - ListButton( - R.drawable.ic_unlock, - stringResource(R.string.my_page_personal), - onClick = { }, - ) - } - } -} + // 구분선 + Divider( + color = ListDivider, + modifier = Modifier + .fillMaxWidth() + .height(1.dp) + .padding(start = 24.dp, end = 24.dp) + ) -@Composable -fun MyPageProfileButton( - buttonText: String? = null, - onClickAction: String? = null, - onClick: () -> Unit -) { - val refreshButton = remember { - mutableStateOf(false) - } - Column(modifier = Modifier) { - Button( - onClick = { - onClick() - if (onClickAction != null) { - refreshButton.value = true - } - }, - modifier = Modifier - .padding(end = PADDING_8) - .wrapContentSize(), - contentPadding = PaddingValues(4.dp), - colors = ButtonDefaults.buttonColors(MyPageProfileEditButton, Color.Black) - ) { - if (buttonText != null) { Text( - text = buttonText, - fontSize = 9.sp + text = stringResource(R.string.my_page_app_info), + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(start = 24.dp, top = 24.dp, bottom = 8.dp), + color = ListTitle, + fontSize = 11.sp + ) + ListButton( + R.drawable.ic_info, + stringResource(R.string.my_page_clause), + onClick = { }, + ) + ListButton( + R.drawable.ic_unlock, + stringResource(R.string.my_page_personal), + onClick = { }, ) } } } - // 버튼마다 다른 다이어로그 - if (refreshButton.value) { - if (onClickAction == stringResource(R.string.my_page_profile_edit)) { - LogoutAlertDialog(openDialogCustom = refreshButton) + + @Composable + fun MyPageProfileButton( + buttonText: String? = null, + onClickAction: String? = null, + onClick: () -> Unit, + viewModel: MyPageViewModel = hiltViewModel() + ) { + val refreshButton = viewModel.refreshButton + + Column(modifier = Modifier) { + Button( + onClick = { + onClick() + if (onClickAction != null) { + // ViewModel 내의 refreshButton 값을 직접 수정 + viewModel.refreshButton.value = true + } + }, + modifier = Modifier + .padding(end = PADDING_8) + .wrapContentSize(), + contentPadding = PaddingValues(4.dp), + colors = ButtonDefaults.buttonColors(MyPageProfileEditButton, Color.Black) + ) { + if (buttonText != null) { + Text( + text = buttonText, + fontSize = 9.sp + ) + } + } } - if (onClickAction == stringResource(R.string.my_page_question)) { - SecessionAlertDialog(openDialogCustom = refreshButton) + // 버튼마다 다른 다이어로그 + if (refreshButton.value) { + if (onClickAction == stringResource(R.string.my_page_profile_edit)) { + LogoutAlertDialog(openDialogCustom = refreshButton) + } + if (onClickAction == stringResource(R.string.my_page_question)) { + SecessionAlertDialog(openDialogCustom = refreshButton) + } } } -} -@Composable -fun ListButton( - buttonIcon: Int? = null, - buttonText: String, - onClickAction: String? = null, - onClick: () -> Unit, -) { - val openDialogCustom = remember { - mutableStateOf(false) - } - val refreshButton = remember { - mutableStateOf(false) - } - Row( - modifier = Modifier - .fillMaxWidth() + @Composable + fun ListButton( + buttonIcon: Int? = null, + buttonText: String, + onClickAction: String? = null, + onClick: () -> Unit, ) { - Button( - onClick = { - onClick() - openDialogCustom.value = true - if (onClickAction != null) { - refreshButton.value = true - } - }, - colors = ButtonDefaults.buttonColors( - contentColor = Color.Unspecified, - containerColor = Color.Transparent - ) - ) { - - if (buttonIcon != null) { - Icon( - imageVector = ImageVector.vectorResource(buttonIcon), - contentDescription = stringResource(R.string.my_page_list_button_icon), - ) - } - Text( - text = buttonText, - Modifier - .padding(start = PADDING_16), - color = Color.Black, - fontSize = 12.sp - ) + val openDialogCustom = remember { + mutableStateOf(false) } - Box( + val refreshButton = remember { + mutableStateOf(false) + } + Row( modifier = Modifier - .padding() - .fillMaxWidth(), - contentAlignment = Alignment.CenterEnd + .fillMaxWidth() ) { Button( onClick = { @@ -381,35 +338,69 @@ fun ListButton( refreshButton.value = true } }, - colors = ButtonDefaults.buttonColors(Color.Transparent, ListNextButton) + colors = ButtonDefaults.buttonColors( + contentColor = Color.Unspecified, + containerColor = Color.Transparent + ) ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.ic_right_btn), - contentDescription = stringResource(R.string.my_page_list_button_right), + + if (buttonIcon != null) { + Icon( + imageVector = ImageVector.vectorResource(buttonIcon), + contentDescription = stringResource(R.string.my_page_list_button_icon), + ) + } + Text( + text = buttonText, + Modifier + .padding(start = PADDING_16), + color = Color.Black, + fontSize = 12.sp ) } + Box( + modifier = Modifier + .padding() + .fillMaxWidth(), + contentAlignment = Alignment.CenterEnd + ) { + Button( + onClick = { + onClick() + openDialogCustom.value = true + if (onClickAction != null) { + refreshButton.value = true + } + }, + colors = ButtonDefaults.buttonColors(Color.Transparent, ListNextButton) + ) { + Icon( + imageVector = ImageVector.vectorResource(R.drawable.ic_right_btn), + contentDescription = stringResource(R.string.my_page_list_button_right), + ) + } + } } - } - // 버튼마다 다른 다이어로그 - if (openDialogCustom.value) { - if (onClickAction == stringResource(R.string.my_page_logout)) { - LogoutAlertDialog(openDialogCustom = openDialogCustom) - } - if (onClickAction == stringResource(R.string.my_page_drop)) { - SecessionAlertDialog(openDialogCustom = openDialogCustom) + // 버튼마다 다른 다이어로그 + if (openDialogCustom.value) { + if (onClickAction == stringResource(R.string.my_page_logout)) { + LogoutAlertDialog(openDialogCustom = openDialogCustom) + } + if (onClickAction == stringResource(R.string.my_page_drop)) { + SecessionAlertDialog(openDialogCustom = openDialogCustom) + } } } -} -@Preview(showBackground = true) -@Composable -fun PreviewMyPageScreen() { - MeongmoryTheme { - MyPageScreen( - navigateToEditNickNameScreen = { }, - navigateToQuestionScreen = { }, - ) + @Preview(showBackground = true) + @Composable + fun PreviewMyPageScreen() { + MeongmoryTheme { + MyPageScreen( + navigateToEditNickNameScreen = { }, + navigateToQuestionScreen = { }, + ) + } } -} diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt index 3242535..9f91d3e 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/MyPageViewModel.kt @@ -1,5 +1,6 @@ package com.meongmoryteam.presentation.ui.myPage +import androidx.compose.runtime.mutableStateOf import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState import com.meongmoryteam.presentation.ui.myPage.MyPageContract.MyPageEvent @@ -14,6 +15,8 @@ class MyPageViewModel @Inject constructor( ) : BaseViewModel( MyPageViewState() ) { + val refreshButton = mutableStateOf(false) + override fun handleEvents(event: MyPageEvent) { when (event) { is MyPageEvent.InitMyPageScreen -> { diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt index 2887f82..05d727d 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileContract.kt @@ -16,7 +16,7 @@ class MyPageProfileContract { ) : ViewState sealed class MyPageProfileSideEffect : ViewSideEffect { - object NavigateToPreviousScreen : MyPageProfileSideEffect() + object NavigateToMyPageScreen : MyPageProfileSideEffect() } sealed class MyPageProfileEvent : ViewEvent { @@ -25,6 +25,7 @@ class MyPageProfileContract { ) : MyPageProfileEvent() object ClearNickName : MyPageProfileEvent() + object OnClickPreviousButton : MyPageProfileEvent() object OnClickChangeButton : MyPageProfileEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt index f953443..828a21b 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileScreen.kt @@ -23,8 +23,6 @@ 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 import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color @@ -57,10 +55,10 @@ fun MyPageProfileScreen( navigateToPrevious: () -> Unit, ) { val uiState by viewModel.viewState.collectAsState() - // refreshButton 상태 - val refreshButton = remember { - mutableStateOf(false) - } + + // ViewModel에서 refreshButton 상태 가져오기 + val refreshButton by viewModel.refreshButton + Column( modifier = Modifier .fillMaxHeight() @@ -78,7 +76,8 @@ fun MyPageProfileScreen( MyPageToolBar( stringResource(R.string.profile_change_title), onBackClick = { - refreshButton.value = true + // ViewModel 내부의 refreshButton 상태 변경 + viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickPreviousButton) } ) ProfileChangeEdit() @@ -96,8 +95,8 @@ fun MyPageProfileScreen( } // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 - LaunchedEffect(refreshButton.value) { - if (refreshButton.value) { + LaunchedEffect(refreshButton) { + if (refreshButton) { navigateToPrevious() } } @@ -109,9 +108,6 @@ fun MyPageToolBar( title: String, onBackClick: () -> Unit, ) { - val refreshButton = remember { - mutableStateOf(false) - } Column { // 위 아래 여백 Row( @@ -137,7 +133,6 @@ fun MyPageToolBar( .padding(start = PADDING_16) .clickable { onBackClick() - refreshButton.value = true } ) } @@ -151,13 +146,6 @@ fun MyPageToolBar( color = EditDivider.copy(0.2f) ) } - - // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 - LaunchedEffect(refreshButton.value) { - if (refreshButton.value) { - onBackClick() - } - } } @@ -262,7 +250,7 @@ fun ProfileChangeButton( ) { Button( onClick = { - viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickChangeButton) + viewModel.setEvent(MyPageProfileContract.MyPageProfileEvent.OnClickPreviousButton) }, colors = if (!isFilled || isOverflow) { ButtonDefaults.textButtonColors(LightGrey) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt index 280b3d9..4dfdde0 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/profile/MyPageProfileViewModel.kt @@ -1,5 +1,7 @@ package com.meongmoryteam.presentation.ui.myPage.profile +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.viewModelScope import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState @@ -15,11 +17,19 @@ class MyPageProfileViewModel @Inject constructor( ) : BaseViewModel( MyPageProfileViewState() ) { + // refreshButton 상태를 ViewModel 내부에서 관리 + private val _refreshButton = mutableStateOf(false) + val refreshButton: State = _refreshButton + override fun handleEvents(event: MyPageProfileEvent) { when (event) { is MyPageProfileEvent.ClearNickName -> reflectUpdatedState("") is MyPageProfileEvent.FillNickName -> reflectUpdatedState(event.nickName) - MyPageProfileEvent.OnClickChangeButton -> changeNickName() + MyPageProfileEvent.OnClickPreviousButton -> _refreshButton.value = true + is MyPageProfileEvent.OnClickChangeButton -> { + changeNickName() + _refreshButton.value = true + } } } @@ -35,9 +45,16 @@ class MyPageProfileViewModel @Inject constructor( } } - private fun changeNickName() = viewModelScope.launch { - updateState { copy(loadState = LoadState.SUCCESS) } - sendEffect({ MyPageProfileSideEffect.NavigateToPreviousScreen }) + private fun changeNickName( + nickName: String = viewState.value.nickName + ) = viewModelScope.launch { + updateState { + copy( + loadState = LoadState.SUCCESS, + nickName = nickName + ) + } + sendEffect({ MyPageProfileSideEffect.NavigateToMyPageScreen }) } // 텍스트 길이 초과 diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt index 9669acb..7b9d702 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionConstract.kt @@ -15,7 +15,7 @@ class MyPageQuestionConstract { ) : ViewState sealed class MyPageQuestionSideEffect : ViewSideEffect { - object NavigateToPreviousScreen : MyPageQuestionSideEffect() + object NavigateToMyPageScreen : MyPageQuestionSideEffect() } sealed class MyPageQuestionEvent : ViewEvent { @@ -29,6 +29,7 @@ class MyPageQuestionConstract { object ClearEmail : MyPageQuestionEvent() object ClearQuestion : MyPageQuestionEvent() - object OnClickButton : MyPageQuestionEvent() + object OnClickPreviousButton : MyPageQuestionEvent() + object OnClickPostButton : MyPageQuestionEvent() } } \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt index 7e7534b..d064113 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionScreen.kt @@ -23,8 +23,6 @@ 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 import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector @@ -59,9 +57,8 @@ fun MyPageQuestionScreen( navigateToPrevious: () -> Unit, ) { val uiState by viewModel.viewState.collectAsState() - val refreshButton = remember { - mutableStateOf(false) - } + val refreshButton by viewModel.refreshButton + Column( modifier = Modifier .fillMaxHeight() @@ -71,7 +68,7 @@ fun MyPageQuestionScreen( MyPageToolBar( stringResource(R.string.question_title), onBackClick = { - refreshButton.value = true + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickPreviousButton) } ) Spacer(modifier = Modifier.padding(PADDING_8)) @@ -91,8 +88,8 @@ fun MyPageQuestionScreen( } } // refreshButton 상태가 변경되었을 때 이전 페이지로 이동 - LaunchedEffect(refreshButton.value) { - if (refreshButton.value) { + LaunchedEffect(refreshButton) { + if (refreshButton) { navigateToPrevious() } } @@ -280,7 +277,7 @@ fun QuestionButton( ) { Button( onClick = { - viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickButton) + viewModel.setEvent(MyPageQuestionConstract.MyPageQuestionEvent.OnClickPreviousButton) }, colors = if (!isAllFilled) { ButtonDefaults.textButtonColors(LightGrey) diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt index c19918c..fe81a25 100644 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt +++ b/presentation/src/main/java/com/meongmoryteam/presentation/ui/myPage/question/MyPageQuestionViewModel.kt @@ -1,5 +1,7 @@ package com.meongmoryteam.presentation.ui.myPage.question +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf import androidx.lifecycle.viewModelScope import com.meongmoryteam.presentation.base.BaseViewModel import com.meongmoryteam.presentation.base.LoadState @@ -15,13 +17,20 @@ class MyPageQuestionViewModel @Inject constructor( ) : BaseViewModel( MyPageQuestionViewState() ) { + private val _refreshButton = mutableStateOf(false) + val refreshButton: State = _refreshButton + override fun handleEvents(event: MyPageQuestionEvent) { when (event) { MyPageQuestionEvent.ClearEmail -> reflectUpdatedState(email = "") MyPageQuestionEvent.ClearQuestion -> reflectUpdatedState(question = "") is MyPageQuestionEvent.FillEmail -> reflectUpdatedState(email = event.email) is MyPageQuestionEvent.FillQuestion -> reflectUpdatedState(question = event.question) - MyPageQuestionEvent.OnClickButton -> setEmail() + MyPageQuestionEvent.OnClickPreviousButton -> _refreshButton.value = true + is MyPageQuestionEvent.OnClickPostButton -> { + setEmail() + _refreshButton.value = true + } } } @@ -41,12 +50,18 @@ class MyPageQuestionViewModel @Inject constructor( } } - private fun setEmail() = viewModelScope.launch { + private fun setEmail( + email: String = viewState.value.email, + question: String = viewState.value.question + ) = viewModelScope.launch { updateState { copy( - loadState = LoadState.LOADING + loadState = LoadState.SUCCESS, + email = email, + question = question ) } + sendEffect({ MyPageQuestionSideEffect.NavigateToMyPageScreen }) } private fun isFilled( From 64d0db7bf8ee2747e4588bb0bde46d8a39654ee1 Mon Sep 17 00:00:00 2001 From: arinming Date: Sun, 13 Aug 2023 12:47:36 +0900 Subject: [PATCH 37/37] =?UTF-8?q?[refactor/mypage]=20HomeScreen,=20ViewMod?= =?UTF-8?q?el,=20Contract=20=EC=82=AD=EC=A0=9C=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/main/HomeContract.kt | 21 ---- .../presentation/ui/main/HomeScreen.kt | 96 ------------------- .../presentation/ui/main/HomeViewModel.kt | 15 --- .../presentation/util/ActivityViewModelExt.kt | 14 --- 4 files changed, 146 deletions(-) delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt delete mode 100644 presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt deleted file mode 100644 index 69e220e..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeContract.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.meongmoryteam.presentation.ui.main - -import com.meongmoryteam.presentation.base.ViewEvent -import com.meongmoryteam.presentation.base.ViewSideEffect -import com.meongmoryteam.presentation.base.ViewState - -class HomeContract { - data class HomeViewState( - val loginState: LoginState = LoginState.NONE, - ) : ViewState - - sealed class HomeSideEffect : ViewSideEffect { - } - - sealed class HomeEvent : ViewEvent { - } - - enum class LoginState { - NONE, LOGIN - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt deleted file mode 100644 index 5f6f2ba..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeScreen.kt +++ /dev/null @@ -1,96 +0,0 @@ -package com.meongmoryteam.presentation.ui.main - -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.runtime.collectAsState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Preview -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.navigation.NavHostController -import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable -import androidx.navigation.compose.currentBackStackEntryAsState -import androidx.navigation.compose.rememberNavController -import com.meongmoryteam.presentation.ui.bottom.MeongMoryBottomNavigation -import com.meongmoryteam.presentation.ui.bottom.MeongMoryRoute -import com.meongmoryteam.presentation.ui.bottom.navigateBottomNavigationScreen -import com.meongmoryteam.presentation.ui.home.HomeScreen -import com.meongmoryteam.presentation.ui.map.MapScreen -import com.meongmoryteam.presentation.ui.myPage.MyPageScreen -import com.meongmoryteam.presentation.ui.myPage.profile.MyPageProfileScreen -import com.meongmoryteam.presentation.ui.myPage.question.MyPageQuestionScreen - -@Composable -fun MainScreen( - viewModel: MainViewModel = hiltViewModel(), - navController: NavHostController = rememberNavController(), -) { - val viewState by viewModel.viewState.collectAsState() - val navBackStackEntry by navController.currentBackStackEntryAsState() - val currentDestination = navBackStackEntry?.destination - var bottomBarState by rememberSaveable { mutableStateOf(true) } - - Scaffold( - bottomBar = { - if (bottomBarState) { - MeongMoryBottomNavigation( - currentDestination = currentDestination, - navigateToScreen = { navigationItem -> - navigateBottomNavigationScreen( - navController = navController, - navigationItem = navigationItem, - ) - } - ) - } - } - ) { padding -> - NavHost( - modifier = Modifier.padding(padding), - navController = navController, - startDestination = MeongMoryRoute.HOME.route, - ) { - composable(route = MeongMoryRoute.HOME.route) { - HomeScreen() - } - composable(route = MeongMoryRoute.MAP.route) { - MapScreen() - } - composable(route = MeongMoryRoute.MY_PAGE.route) { - MyPageScreen( - navigateToEditNickNameScreen = { navController.navigate(MeongMoryRoute.EDIT_NICKNAME.route) }, - navigateToQuestionScreen = { navController.navigate(MeongMoryRoute.QUESTION.route) }, - ) - } - composable(route = MeongMoryRoute.EDIT_NICKNAME.route) { - MyPageProfileScreen( - navigateToPrevious = { navController.navigate(MeongMoryRoute.MY_PAGE.route) } - ) - } - composable(route = MeongMoryRoute.QUESTION.route) { - MyPageQuestionScreen( - navigateToPrevious = { navController.navigate(MeongMoryRoute.MY_PAGE.route)} - ) - } - } - } - - // 바텀 네비게이션 보이기, 숨기기 - bottomBarState = when (currentDestination?.route) { - MeongMoryRoute.HOME.route -> true - MeongMoryRoute.MAP.route -> true - MeongMoryRoute.MY_PAGE.route -> true - else -> false - } -} - -@Preview -@Composable -fun MainScreenPreview() { - MainScreen() -} diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt b/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt deleted file mode 100644 index 579175d..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/ui/main/HomeViewModel.kt +++ /dev/null @@ -1,15 +0,0 @@ -package com.meongmoryteam.presentation.ui.main - -import com.meongmoryteam.presentation.base.BaseViewModel -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import com.meongmoryteam.presentation.ui.main.HomeContract.* - -@HiltViewModel -class HomeViewModel @Inject constructor( -) : BaseViewModel( - HomeViewState() -) { - override fun handleEvents(event: HomeEvent) { - } -} \ No newline at end of file diff --git a/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt b/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt deleted file mode 100644 index 6a7c402..0000000 --- a/presentation/src/main/java/com/meongmoryteam/presentation/util/ActivityViewModelExt.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.meongmoryteam.presentation.util - -import androidx.activity.ComponentActivity -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewmodel.compose.viewModel - -@Composable -fun getActivity() = LocalContext.current as ComponentActivity - -@Composable -inline fun composableActivityViewModel( -) : VM = viewModel(getActivity()) \ No newline at end of file