-
Notifications
You must be signed in to change notification settings - Fork 0
[Feat] 리뷰v2 작성 중 뒤로가기시 다이알로그 추가 #507
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
c4c0874
0fa7479
008e8c1
fe506bf
0cdc5a8
f5b2736
26963f5
56489e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,6 @@ | ||
| package com.eatssu.android.presentation.cafeteria.review.modify | ||
|
|
||
| import androidx.activity.compose.BackHandler | ||
| import androidx.compose.foundation.layout.Column | ||
| import androidx.compose.foundation.layout.Spacer | ||
| import androidx.compose.foundation.layout.fillMaxSize | ||
|
|
@@ -18,6 +19,9 @@ import androidx.compose.material3.Text | |
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.LaunchedEffect | ||
| import androidx.compose.runtime.getValue | ||
| import androidx.compose.runtime.mutableStateOf | ||
| import androidx.compose.runtime.remember | ||
| import androidx.compose.runtime.setValue | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.platform.LocalContext | ||
|
|
@@ -36,6 +40,7 @@ import com.eatssu.common.UiState | |
| import com.eatssu.common.enums.ScreenId | ||
| import com.eatssu.design_system.component.CloseTopBar | ||
| import com.eatssu.design_system.component.EatSsuButton | ||
| import com.eatssu.design_system.component.EatSsuDialog | ||
| import com.eatssu.design_system.component.RatingBarMedium | ||
| import com.eatssu.design_system.theme.EatssuTheme | ||
| import com.eatssu.design_system.theme.Gray100 | ||
|
|
@@ -78,6 +83,40 @@ fun ModifyReviewScreen( | |
| } | ||
| } | ||
|
|
||
| var showExitDialog by remember { mutableStateOf(false) } | ||
|
|
||
| val hasUnsavedChanges = (ui as? UiState.Success)?.data?.let { | ||
| (it as? ModifyState.Editing)?.hasChanges ?: false | ||
| } ?: false | ||
|
|
||
| val handleBack = { | ||
| if (hasUnsavedChanges) { | ||
| showExitDialog = true | ||
| } else { | ||
| onBack() | ||
| } | ||
| } | ||
|
|
||
| BackHandler(enabled = true) { | ||
| handleBack() | ||
| } | ||
|
|
||
| if (showExitDialog) { | ||
| EatSsuDialog( | ||
| title = stringResource(R.string.review_exit_dialog_title), | ||
| description = stringResource(R.string.review_exit_dialog_description), | ||
| confirmText = stringResource(R.string.review_exit_dialog_confirm), | ||
| dismissText = stringResource(R.string.review_exit_dialog_dismiss), | ||
| onConfirmClick = { showExitDialog = false }, | ||
| onDismissButtonClick = { | ||
| showExitDialog = false | ||
| onBack() | ||
| }, | ||
| onDismissRequest = { showExitDialog = false }, | ||
| visible = showExitDialog | ||
| ) | ||
|
Comment on lines
+105
to
+117
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
하지만 코드상으로는 '확인(confirm)'을 의미하는 파라미터에 '취소'에 해당하는 액션을, '취소(dismiss)'를 의미하는 파라미터에 '확인'에 해당하는 액션을 연결하고 있어 매우 혼란스럽고 잠재적인 버그의 원인이 될 수 있습니다. 의도된 UX가 '계속 작성'을 강조하는 것이 맞다면, |
||
| } | ||
|
|
||
| when (val data = (ui as? UiState.Success)?.data) { | ||
| is ModifyState.Editing -> { | ||
| ModifyReviewScreen( | ||
|
|
@@ -88,7 +127,7 @@ fun ModifyReviewScreen( | |
| menuLikeInfos = data.menuLikeInfos, | ||
| isSubmitting = false, | ||
| canSubmit = data.canSubmit, | ||
| onBack = onBack, | ||
| onBack = handleBack, | ||
| onRatingChanged = viewModel::onRatingChanged, | ||
| onContentChanged = { new -> | ||
| if (new.length <= MAX_TEXT_COUNT) viewModel.onContentChanged(new) | ||
|
|
@@ -108,7 +147,7 @@ fun ModifyReviewScreen( | |
| menuLikeInfos = data.menuLikeInfos, | ||
| isSubmitting = true, | ||
| canSubmit = false, | ||
| onBack = onBack, | ||
| onBack = handleBack, | ||
| onRatingChanged = {}, // 수정 불가 | ||
| onContentChanged = {}, // 수정 불가 | ||
| onToggleLike = {}, // 수정 불가 | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,7 @@ | ||
| package com.eatssu.android.presentation.cafeteria.review.write | ||
|
|
||
| import android.net.Uri | ||
| import androidx.activity.compose.BackHandler | ||
| import androidx.activity.compose.rememberLauncherForActivityResult | ||
| import androidx.activity.result.contract.ActivityResultContracts | ||
| import androidx.compose.foundation.background | ||
|
|
@@ -30,6 +31,9 @@ import androidx.compose.material3.Text | |
| import androidx.compose.runtime.Composable | ||
| import androidx.compose.runtime.LaunchedEffect | ||
| import androidx.compose.runtime.getValue | ||
| import androidx.compose.runtime.mutableStateOf | ||
| import androidx.compose.runtime.remember | ||
| import androidx.compose.runtime.setValue | ||
| import androidx.compose.ui.Alignment | ||
| import androidx.compose.ui.Modifier | ||
| import androidx.compose.ui.draw.clip | ||
|
|
@@ -39,9 +43,9 @@ import androidx.compose.ui.res.painterResource | |
| import androidx.compose.ui.res.stringResource | ||
| import androidx.compose.ui.tooling.preview.Preview | ||
| import androidx.compose.ui.unit.dp | ||
| import androidx.core.net.toUri | ||
| import androidx.hilt.navigation.compose.hiltViewModel | ||
| import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
| import coil.compose.AsyncImage | ||
| import com.eatssu.android.R | ||
| import com.eatssu.android.domain.model.MenuMini | ||
| import com.eatssu.android.presentation.cafeteria.review.write.component.MenuLikeButtonItem | ||
|
|
@@ -53,6 +57,7 @@ import com.eatssu.common.enums.MenuType | |
| import com.eatssu.common.enums.ScreenId | ||
| import com.eatssu.design_system.component.CloseTopBar | ||
| import com.eatssu.design_system.component.EatSsuButton | ||
| import com.eatssu.design_system.component.EatSsuDialog | ||
| import com.eatssu.design_system.component.RatingBarMedium | ||
| import com.eatssu.design_system.theme.EatssuTheme | ||
| import com.eatssu.design_system.theme.Gray100 | ||
|
|
@@ -62,7 +67,7 @@ import com.eatssu.design_system.theme.Gray400 | |
| import com.eatssu.design_system.theme.Gray500 | ||
| import com.eatssu.design_system.theme.Gray700 | ||
| import com.eatssu.design_system.theme.Primary | ||
| import androidx.core.net.toUri | ||
| import coil.compose.AsyncImage | ||
|
|
||
| const val MAX_TEXT_COUNT = 300 | ||
|
|
||
|
|
@@ -102,6 +107,41 @@ fun WriteReviewScreen( | |
| } | ||
| } | ||
|
|
||
| var showExitDialog by remember { mutableStateOf(false) } | ||
|
|
||
| val hasUnsavedChanges = when (val data = (ui as? UiState.Success)?.data) { | ||
| is WriteReviewState.Editing -> data.rating > 0 || data.content.isNotEmpty() || data.selectedImageUri != null | ||
| else -> false | ||
| } | ||
|
Comment on lines
+112
to
+115
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
val hasUnsavedChanges = remember(ui) {
when (val data = (ui as? UiState.Success)?.data) {
is WriteReviewState.Editing -> data.rating > 0 || data.content.isNotEmpty() || data.selectedImageUri != null
else -> false
}
} |
||
|
|
||
| val handleBack = { | ||
| if (hasUnsavedChanges) { | ||
| showExitDialog = true | ||
| } else { | ||
| onBack() | ||
| } | ||
| } | ||
|
|
||
| BackHandler(enabled = true) { | ||
| handleBack() | ||
| } | ||
|
|
||
| if (showExitDialog) { | ||
| EatSsuDialog( | ||
| title = stringResource(R.string.review_exit_dialog_title), | ||
| description = stringResource(R.string.review_exit_dialog_description), | ||
| confirmText = stringResource(R.string.review_exit_dialog_confirm), | ||
| dismissText = stringResource(R.string.review_exit_dialog_dismiss), | ||
| onConfirmClick = { showExitDialog = false }, | ||
| onDismissButtonClick = { | ||
| showExitDialog = false | ||
| onBack() | ||
| }, | ||
| onDismissRequest = { showExitDialog = false }, | ||
| visible = showExitDialog | ||
| ) | ||
|
Comment on lines
+130
to
+142
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
하지만 코드상으로는 '확인(confirm)'을 의미하는 파라미터에 '취소'에 해당하는 액션을, '취소(dismiss)'를 의미하는 파라미터에 '확인'에 해당하는 액션을 연결하고 있어 매우 혼란스럽고 잠재적인 버그의 원인이 될 수 있습니다. 의도된 UX가 '계속 작성'을 강조하는 것이 맞다면, |
||
| } | ||
|
|
||
| when (val data = (ui as? UiState.Success)?.data) { | ||
| is WriteReviewState.Editing -> { | ||
| WriteReviewScreen( | ||
|
|
@@ -113,7 +153,7 @@ fun WriteReviewScreen( | |
| likedMenuIds = data.likedMenuIds, | ||
| selectedImageUri = data.selectedImageUri, | ||
| isPosting = false, | ||
| onBack = onBack, | ||
| onBack = handleBack, | ||
| onRatingChanged = viewModel::onRatingChanged, | ||
| onContentChanged = { new -> | ||
| if (new.length <= MAX_TEXT_COUNT) viewModel.onContentChanged(new) | ||
|
|
@@ -135,7 +175,7 @@ fun WriteReviewScreen( | |
| likedMenuIds = data.likedMenuIds, | ||
| selectedImageUri = data.selectedImageUri, | ||
| isPosting = true, | ||
| onBack = onBack, | ||
| onBack = handleBack, | ||
| onRatingChanged = {}, // 비활성 | ||
| onContentChanged = {}, // 비활성 | ||
| onToggleLike = {}, // 비활성 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hasUnsavedChanges가 recomposition이 일어날 때마다 계속해서 재계산되고 있습니다.remember를 사용하여ui상태가 변경될 때만 값을 다시 계산하도록 하여 불필요한 계산을 줄일 수 있습니다. 또한, 표현을 더 간결하게 만들 수 있습니다.