-
Notifications
You must be signed in to change notification settings - Fork 2
[Feature] 콜밴 리스트 BottomSheet 및 FAB ui 구현 #1366
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
Changes from all commits
6b99c6f
e0ff0dc
1d80458
e56fbab
83da4d2
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 |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package `in`.koreatech.koin.feature.callvan.enums | ||
|
|
||
| enum class ConfirmType { | ||
| JOIN, | ||
| CANCEL_JOIN, | ||
| CLOSE, | ||
| REOPEN; | ||
|
|
||
| companion object { | ||
| fun from(state: CallvanRouteState): ConfirmType? = when (state) { | ||
| CallvanRouteState.DEFAULT -> JOIN | ||
| CallvanRouteState.JOINED -> CANCEL_JOIN | ||
| CallvanRouteState.OWNER_ACTIVE -> CLOSE | ||
| CallvanRouteState.OWNER_CLOSED -> REOPEN | ||
| CallvanRouteState.CLOSED -> null | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,81 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||
| package `in`.koreatech.koin.feature.callvan.ui.list.component | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.background | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.border | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Box | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Row | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Spacer | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.WindowInsets | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.padding | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.width | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.windowInsetsPadding | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.wrapContentSize | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.shape.RoundedCornerShape | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Icon | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Text | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Alignment | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Modifier | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.graphics.Color | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.graphics.vector.ImageVector | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.res.stringResource | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.res.vectorResource | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.tooling.preview.Preview | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.unit.dp | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.noRippleClickable | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.theme.KoinTheme | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.theme.RebrandKoinTheme | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+27
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. [Minor] 두 가지 테마 시스템 혼용
또한 아래 **Preview(line 73~80)**에서는 |
||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.R | ||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.ui.list.model.CallvanFABDefaults | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||
| fun CallvanFAB( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier: Modifier = Modifier, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick: () -> Unit, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| windowInsets: WindowInsets = CallvanFABDefaults.windowInsets | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Box( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = modifier | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .windowInsetsPadding(windowInsets) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .wrapContentSize(Alignment.BottomEnd) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Box( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = Modifier | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .border( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| width = 1.dp, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| color = RebrandKoinTheme.colors.primary400, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| shape = RoundedCornerShape(50) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .background( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| color = KoinTheme.colors.neutral50, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| shape = RoundedCornerShape(50) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .noRippleClickable(onClick = onClick) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| .padding(vertical = 8.dp, horizontal = 12.dp) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+44
to
+55
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. [Major] Compose에서 수정자는 체인 순서대로 적용되기 때문에,
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| Row(verticalAlignment = Alignment.CenterVertically) { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Icon( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| imageVector = ImageVector.vectorResource(R.drawable.ic_write_fab), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| contentDescription = stringResource(R.string.callvan_fab_write_btn), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| tint = Color.Unspecified | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Spacer( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = Modifier.width(4.dp) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||||||||||||||||||
| text = stringResource(R.string.callvan_fab_write_btn), | ||||||||||||||||||||||||||||||||||||||||||||||||||
| style = KoinTheme.typography.medium16, | ||||||||||||||||||||||||||||||||||||||||||||||||||
| color = RebrandKoinTheme.colors.primary600 | ||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||
| @Preview(showBackground = true) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||
| private fun CallvanFABPreview() { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| KoinTheme { | ||||||||||||||||||||||||||||||||||||||||||||||||||
| CallvanFAB(onClick = {}) | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,31 @@ | ||||||||||||||||||||||||||||||||||||
| package `in`.koreatech.koin.feature.callvan.ui.list.component | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.Composable | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.res.stringResource | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.tooling.preview.Preview | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.theme.RebrandKoinTheme | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.R | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.ui.component.CallvanConfirmBottomSheet | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||
| fun CompleteBottomSheet( | ||||||||||||||||||||||||||||||||||||
| onConfirm: () -> Unit, | ||||||||||||||||||||||||||||||||||||
| onDismiss: () -> Unit | ||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||
| CallvanConfirmBottomSheet( | ||||||||||||||||||||||||||||||||||||
| title = stringResource(R.string.callvan_complete_title), | ||||||||||||||||||||||||||||||||||||
| description = stringResource(R.string.callvan_complete_description), | ||||||||||||||||||||||||||||||||||||
| confirmText = stringResource(R.string.callvan_confirm_positive), | ||||||||||||||||||||||||||||||||||||
| cancelText = stringResource(R.string.callvan_confirm_negative), | ||||||||||||||||||||||||||||||||||||
| onConfirm = onConfirm, | ||||||||||||||||||||||||||||||||||||
| onDismiss = onDismiss | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Preview | ||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||
| private fun CompleteBottomSheetPreview() { | ||||||||||||||||||||||||||||||||||||
| RebrandKoinTheme { | ||||||||||||||||||||||||||||||||||||
| CompleteBottomSheet(onConfirm = {}, onDismiss = {}) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+31
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. [Major] Preview가 실제 컴포넌트를 호출하지 않고 내부 구현을 중복합니다
Suggested change
|
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,127 @@ | ||||||||||||||||||||||||||||||||||||
| package `in`.koreatech.koin.feature.callvan.ui.list.component | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.BorderStroke | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Arrangement | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Column | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.PaddingValues | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.padding | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Button | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.ButtonDefaults | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.OutlinedButton | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Text | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.Composable | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Modifier | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.res.stringResource | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.tooling.preview.Preview | ||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.unit.dp | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.theme.KoinTheme | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.theme.RebrandKoinTheme | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.R | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.enums.ConfirmType | ||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.ui.component.CallvanBottomSheet | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||
| fun ConfirmBottomSheet( | ||||||||||||||||||||||||||||||||||||
| confirmType: ConfirmType, | ||||||||||||||||||||||||||||||||||||
| onConfirm: () -> Unit, | ||||||||||||||||||||||||||||||||||||
| onDismiss: () -> Unit, | ||||||||||||||||||||||||||||||||||||
| title: String? = null | ||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||
| val resolvedTitle = title ?: when (confirmType) { | ||||||||||||||||||||||||||||||||||||
| ConfirmType.JOIN -> stringResource(R.string.callvan_confirm_join_title) | ||||||||||||||||||||||||||||||||||||
| ConfirmType.CANCEL_JOIN -> stringResource(R.string.callvan_confirm_cancel_title) | ||||||||||||||||||||||||||||||||||||
| ConfirmType.CLOSE -> stringResource(R.string.callvan_confirm_close_title) | ||||||||||||||||||||||||||||||||||||
| ConfirmType.REOPEN -> stringResource(R.string.callvan_confirm_reopen_title) | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+28
to
+35
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. [Minor] 기본 파라미터에서
Suggested change
외부 오버라이드 가능성을 열어두고 싶다면 |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| CallvanBottomSheet( | ||||||||||||||||||||||||||||||||||||
| title = resolvedTitle, | ||||||||||||||||||||||||||||||||||||
| onDismiss = onDismiss, | ||||||||||||||||||||||||||||||||||||
| showCloseButton = false | ||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||
| Column( | ||||||||||||||||||||||||||||||||||||
| modifier = Modifier | ||||||||||||||||||||||||||||||||||||
| .fillMaxWidth() | ||||||||||||||||||||||||||||||||||||
| .padding(start = 32.dp, end = 32.dp, top = 16.dp, bottom = 12.dp), | ||||||||||||||||||||||||||||||||||||
| verticalArrangement = Arrangement.spacedBy(16.dp) | ||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||
| Button( | ||||||||||||||||||||||||||||||||||||
| onClick = onConfirm, | ||||||||||||||||||||||||||||||||||||
| modifier = Modifier.fillMaxWidth(), | ||||||||||||||||||||||||||||||||||||
| shape = KoinTheme.shapes.small, | ||||||||||||||||||||||||||||||||||||
| contentPadding = PaddingValues(horizontal = 16.dp, vertical = 10.dp), | ||||||||||||||||||||||||||||||||||||
| colors = ButtonDefaults.buttonColors( | ||||||||||||||||||||||||||||||||||||
| containerColor = RebrandKoinTheme.colors.primary500 | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||||
| text = stringResource(R.string.callvan_confirm_positive), | ||||||||||||||||||||||||||||||||||||
| style = KoinTheme.typography.medium16 | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| OutlinedButton( | ||||||||||||||||||||||||||||||||||||
| onClick = onDismiss, | ||||||||||||||||||||||||||||||||||||
| modifier = Modifier.fillMaxWidth(), | ||||||||||||||||||||||||||||||||||||
| shape = KoinTheme.shapes.small, | ||||||||||||||||||||||||||||||||||||
| contentPadding = PaddingValues(horizontal = 16.dp, vertical = 10.dp), | ||||||||||||||||||||||||||||||||||||
| border = BorderStroke(1.dp, KoinTheme.colors.neutral300), | ||||||||||||||||||||||||||||||||||||
| colors = ButtonDefaults.outlinedButtonColors( | ||||||||||||||||||||||||||||||||||||
| contentColor = KoinTheme.colors.neutral600 | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||||
| text = stringResource(R.string.callvan_confirm_negative), | ||||||||||||||||||||||||||||||||||||
| style = KoinTheme.typography.medium16 | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Preview(showBackground = true) | ||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||
| private fun ConfirmBottomSheetJoinPreview() { | ||||||||||||||||||||||||||||||||||||
| RebrandKoinTheme { | ||||||||||||||||||||||||||||||||||||
| ConfirmBottomSheet( | ||||||||||||||||||||||||||||||||||||
| confirmType = ConfirmType.JOIN, | ||||||||||||||||||||||||||||||||||||
| onConfirm = {}, | ||||||||||||||||||||||||||||||||||||
| onDismiss = {} | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Preview(showBackground = true) | ||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||
| private fun ConfirmBottomSheetCancelJoinPreview() { | ||||||||||||||||||||||||||||||||||||
| RebrandKoinTheme { | ||||||||||||||||||||||||||||||||||||
| ConfirmBottomSheet( | ||||||||||||||||||||||||||||||||||||
| confirmType = ConfirmType.CANCEL_JOIN, | ||||||||||||||||||||||||||||||||||||
| onConfirm = {}, | ||||||||||||||||||||||||||||||||||||
| onDismiss = {} | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Preview(showBackground = true) | ||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||
| private fun ConfirmBottomSheetClosePreview() { | ||||||||||||||||||||||||||||||||||||
| RebrandKoinTheme { | ||||||||||||||||||||||||||||||||||||
| ConfirmBottomSheet( | ||||||||||||||||||||||||||||||||||||
| confirmType = ConfirmType.CLOSE, | ||||||||||||||||||||||||||||||||||||
| onConfirm = {}, | ||||||||||||||||||||||||||||||||||||
| onDismiss = {} | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Preview(showBackground = true) | ||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||
| private fun ConfirmBottomSheetReopenPreview() { | ||||||||||||||||||||||||||||||||||||
| RebrandKoinTheme { | ||||||||||||||||||||||||||||||||||||
| ConfirmBottomSheet( | ||||||||||||||||||||||||||||||||||||
| confirmType = ConfirmType.REOPEN, | ||||||||||||||||||||||||||||||||||||
| onConfirm = {}, | ||||||||||||||||||||||||||||||||||||
| onDismiss = {} | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+79
to
+127
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. [Good] 각 ConfirmType별 Preview를 개별적으로 작성한 점이 훌륭합니다 👍 4가지 상태를 모두 Preview로 커버한 덕분에 UI 회귀를 빠르게 발견할 수 있습니다. 이 패턴을 다른 Bottom Sheet에도 적용하면 좋겠습니다. |
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,79 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package `in`.koreatech.koin.feature.callvan.ui.list.component | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.BorderStroke | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Arrangement | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.Column | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.PaddingValues | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.fillMaxWidth | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.foundation.layout.padding | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Button | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.ButtonDefaults | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.OutlinedButton | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.material3.Text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.runtime.Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.Modifier | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.res.stringResource | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.tooling.preview.Preview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import androidx.compose.ui.unit.dp | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.theme.KoinTheme | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.core.designsystem.theme.RebrandKoinTheme | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.R | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import `in`.koreatech.koin.feature.callvan.ui.component.CallvanBottomSheet | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fun LoginBottomSheet( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onLogin: () -> Unit, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDismiss: () -> Unit | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| CallvanBottomSheet( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| title = stringResource(R.string.callvan_login_title), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDismiss = onDismiss, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| showCloseButton = false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Column( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = Modifier | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .fillMaxWidth() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .padding(start = 32.dp, end = 32.dp, top = 16.dp, bottom = 12.dp), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| verticalArrangement = Arrangement.spacedBy(16.dp) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Button( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick = onLogin, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = Modifier.fillMaxWidth(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shape = KoinTheme.shapes.small, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contentPadding = PaddingValues(horizontal = 16.dp, vertical = 10.dp), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colors = ButtonDefaults.buttonColors( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| containerColor = RebrandKoinTheme.colors.primary500 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| text = stringResource(R.string.callvan_login_login), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style = KoinTheme.typography.medium16 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| OutlinedButton( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onClick = onDismiss, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| modifier = Modifier.fillMaxWidth(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shape = KoinTheme.shapes.small, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contentPadding = PaddingValues(horizontal = 16.dp, vertical = 10.dp), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| border = BorderStroke(1.dp, KoinTheme.colors.neutral300), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
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. [Trivial] 불필요한 빈 줄 같은 역할을 하는
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| colors = ButtonDefaults.outlinedButtonColors( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| contentColor = KoinTheme.colors.neutral600 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Text( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| text = stringResource(R.string.callvan_login_close), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| style = KoinTheme.typography.medium16 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Preview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Composable | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private fun LoginBottomSheetPreview() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| LoginBottomSheet( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onLogin = {}, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDismiss = {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+73
to
+79
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. [Major] Preview가 실제 컴포넌트를 호출하지 않고 레이아웃 코드를 전부 중복합니다 현재 Preview는
아래처럼 간단하게 수정하세요:
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package `in`.koreatech.koin.feature.callvan.ui.list.model | ||
|
|
||
| import androidx.compose.foundation.layout.WindowInsets | ||
| import androidx.compose.foundation.layout.WindowInsetsSides | ||
| import androidx.compose.foundation.layout.only | ||
| import androidx.compose.foundation.layout.systemBars | ||
| import androidx.compose.runtime.Composable | ||
|
|
||
| object CallvanFABDefaults { | ||
| val windowInsets: WindowInsets | ||
| @Composable | ||
| get() = | ||
| WindowInsets.systemBars.only( | ||
| WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom | ||
| ) | ||
|
Comment on lines
+9
to
+15
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. [Good]
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| <vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
| android:width="24dp" | ||
| android:height="24dp" | ||
| android:viewportWidth="24" | ||
| android:viewportHeight="24"> | ||
| <path | ||
| android:pathData="M5.553,5.658C5.802,5.16 6.185,4.741 6.659,4.448C7.133,4.155 7.679,4 8.236,4H15.764C16.321,4 16.867,4.155 17.341,4.448C17.815,4.741 18.198,5.16 18.447,5.658L19.833,8.429C20.077,8.329 20.317,8.221 20.553,8.105C20.79,7.986 21.065,7.967 21.317,8.051C21.569,8.135 21.776,8.316 21.895,8.553C22.014,8.79 22.033,9.065 21.949,9.317C21.865,9.568 21.684,9.776 21.447,9.895C21.207,10.002 20.965,10.106 20.722,10.207L21.683,12.13C21.892,12.547 22,13.007 22,13.473V16C22,16.422 21.911,16.839 21.739,17.225C21.566,17.61 21.315,17.955 21,18.236V19.5C21,19.898 20.842,20.279 20.561,20.561C20.279,20.842 19.898,21 19.5,21C19.102,21 18.721,20.842 18.439,20.561C18.158,20.279 18,19.898 18,19.5V19H6V19.5C6,19.898 5.842,20.279 5.561,20.561C5.279,20.842 4.898,21 4.5,21C4.102,21 3.721,20.842 3.439,20.561C3.158,20.279 3,19.898 3,19.5V18.236C2.386,17.686 2,16.888 2,16V13.472C2,13.006 2.109,12.547 2.317,12.131L3.27,10.223C3.029,10.122 2.79,10.013 2.555,9.896C2.319,9.776 2.139,9.568 2.055,9.317C1.971,9.065 1.989,8.791 2.105,8.553C2.164,8.435 2.245,8.331 2.344,8.244C2.443,8.158 2.559,8.092 2.683,8.051C2.808,8.009 2.939,7.993 3.07,8.002C3.202,8.011 3.329,8.046 3.447,8.105C3.684,8.222 3.924,8.33 4.167,8.429L5.553,5.658Z" | ||
| android:strokeAlpha="0.3" | ||
| android:fillColor="#B611F5" | ||
| android:fillType="evenOdd" | ||
| android:fillAlpha="0.3"/> | ||
| <path | ||
| android:pathData="M7.342,6.553C7.425,6.387 7.553,6.247 7.71,6.15C7.868,6.052 8.05,6 8.236,6H15.764C16.143,6 16.489,6.214 16.658,6.553L17.928,9.091C16.38,9.555 14.294,10 12,10C9.706,10 7.62,9.555 6.073,9.09L7.342,6.553ZM16.5,16C16.898,16 17.279,15.842 17.561,15.561C17.842,15.279 18,14.898 18,14.5C18,14.102 17.842,13.721 17.561,13.439C17.279,13.158 16.898,13 16.5,13C16.102,13 15.721,13.158 15.439,13.439C15.158,13.721 15,14.102 15,14.5C15,14.898 15.158,15.279 15.439,15.561C15.721,15.842 16.102,16 16.5,16ZM9,14.5C9,14.898 8.842,15.279 8.561,15.561C8.279,15.842 7.898,16 7.5,16C7.102,16 6.721,15.842 6.439,15.561C6.158,15.279 6,14.898 6,14.5C6,14.102 6.158,13.721 6.439,13.439C6.721,13.158 7.102,13 7.5,13C7.898,13 8.279,13.158 8.561,13.439C8.842,13.721 9,14.102 9,14.5Z" | ||
| android:fillColor="#B611F5" | ||
| android:fillType="evenOdd"/> | ||
| </vector> |
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.
[Good]
CLOSED상태에 대해null을 명시적으로 반환하는 설계가 좋습니다 👍CallvanRouteState.CLOSED를null로 매핑함으로써 호출부에서 Nullable 타입을 강제하여 "닫힌 상태에서는 ConfirmBottomSheet를 보여주지 않아야 한다"는 의도를 타입 시스템으로 표현했습니다.다만
CallvanRouteState에 새로운 상태가 추가될 경우when블록이 컴파일 에러를 내어 누락을 즉시 알려주므로 안전합니다 (exhaustive when). 유지보수 관점에서 좋은 패턴입니다.