diff --git a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/DoubleButtonAlertDialog.kt b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/DoubleButtonAlertDialog.kt index ce924ae12..dc6353210 100644 --- a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/DoubleButtonAlertDialog.kt +++ b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/DoubleButtonAlertDialog.kt @@ -1,22 +1,21 @@ package com.neki.android.core.designsystem.dialog +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn 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.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog @@ -56,9 +55,9 @@ fun DoubleButtonAlertDialog( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.icon_dialog_alert), - tint = Color.Unspecified, + Image( + modifier = Modifier.size(64.dp), + painter = painterResource(R.drawable.image_dialog_alert), contentDescription = null, ) Column( diff --git a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/DoubleButtonDialog.kt b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/DoubleButtonDialog.kt new file mode 100644 index 000000000..1ce6f3331 --- /dev/null +++ b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/DoubleButtonDialog.kt @@ -0,0 +1,107 @@ +package com.neki.android.core.designsystem.dialog + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.neki.android.core.designsystem.ComponentPreview +import com.neki.android.core.designsystem.button.CTAButtonGray +import com.neki.android.core.designsystem.button.CTAButtonPrimary +import com.neki.android.core.designsystem.ui.theme.NekiTheme + +@Composable +fun DoubleButtonDialog( + title: String, + content: String, + grayButtonText: String, + primaryButtonText: String, + onDismissRequest: () -> Unit, + onClickPrimaryButton: () -> Unit, + onClickGrayButton: () -> Unit, + modifier: Modifier = Modifier, + properties: DialogProperties = DialogProperties( + usePlatformDefaultWidth = false, + ), +) { + Dialog( + onDismissRequest = onDismissRequest, + properties = properties, + ) { + Column( + modifier = modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + .widthIn(max = 400.dp) + .clip(RoundedCornerShape(20.dp)) + .background(NekiTheme.colorScheme.white) + .padding(top = 20.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + Column( + modifier = Modifier.padding(horizontal = 24.dp), + verticalArrangement = Arrangement.spacedBy(4.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = title, + style = NekiTheme.typography.title18Bold, + color = NekiTheme.colorScheme.gray900, + textAlign = TextAlign.Center, + ) + Text( + text = content, + style = NekiTheme.typography.body14Regular, + color = NekiTheme.colorScheme.gray500, + textAlign = TextAlign.Center, + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(12.dp), + horizontalArrangement = Arrangement.spacedBy(10.dp), + ) { + CTAButtonGray( + text = grayButtonText, + onClick = onClickGrayButton, + modifier = Modifier.weight(1f), + ) + CTAButtonPrimary( + text = primaryButtonText, + onClick = onClickPrimaryButton, + modifier = Modifier.weight(1f), + ) + } + } + } +} + +@ComponentPreview +@Composable +private fun DoubleButtonDialogPreview() { + NekiTheme { + DoubleButtonDialog( + title = "메인 텍스트가 들어가는 곳", + content = "보조 설명 텍스트가 들어가는 공간입니다", + grayButtonText = "텍스트", + primaryButtonText = "텍스트", + onDismissRequest = {}, + onClickPrimaryButton = {}, + onClickGrayButton = {}, + ) + } +} diff --git a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonAlertDialog.kt b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonAlertDialog.kt index ba4cc3ec2..92c8a368e 100644 --- a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonAlertDialog.kt +++ b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonAlertDialog.kt @@ -1,21 +1,20 @@ package com.neki.android.core.designsystem.dialog +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn 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.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog @@ -54,9 +53,9 @@ fun SingleButtonAlertDialog( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.icon_dialog_alert), - tint = Color.Unspecified, + Image( + modifier = Modifier.size(64.dp), + painter = painterResource(R.drawable.image_dialog_alert), contentDescription = null, ) Column( diff --git a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonDialog.kt b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonDialog.kt new file mode 100644 index 000000000..90d225962 --- /dev/null +++ b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonDialog.kt @@ -0,0 +1,94 @@ +package com.neki.android.core.designsystem.dialog + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.neki.android.core.designsystem.ComponentPreview +import com.neki.android.core.designsystem.button.CTAButtonPrimary +import com.neki.android.core.designsystem.ui.theme.NekiTheme + +@Composable +fun SingleButtonDialog( + title: String, + content: String, + buttonText: String, + onDismissRequest: () -> Unit, + onClick: () -> Unit, + enabled: Boolean = true, + properties: DialogProperties = DialogProperties( + usePlatformDefaultWidth = false, + dismissOnBackPress = false, + dismissOnClickOutside = false, + ), +) { + Dialog( + onDismissRequest = onDismissRequest, + properties = properties, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp) + .widthIn(max = 400.dp) + .clip(RoundedCornerShape(20.dp)) + .background(NekiTheme.colorScheme.white) + .padding(top = 20.dp), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + Column( + modifier = Modifier.padding(horizontal = 24.dp), + verticalArrangement = Arrangement.spacedBy(4.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Text( + text = title, + style = NekiTheme.typography.title18Bold, + color = NekiTheme.colorScheme.gray900, + textAlign = TextAlign.Center, + ) + Text( + text = content, + style = NekiTheme.typography.body14Regular, + color = NekiTheme.colorScheme.gray500, + textAlign = TextAlign.Center, + ) + } + CTAButtonPrimary( + text = buttonText, + onClick = onClick, + modifier = Modifier + .fillMaxWidth() + .padding(12.dp), + enabled = enabled, + ) + } + } +} + +@ComponentPreview +@Composable +private fun SingleButtonDialogPreview() { + NekiTheme { + SingleButtonDialog( + title = "메인 텍스트가 들어가는 곳", + content = "보조 설명 텍스트가 들어가는 공간입니다", + buttonText = "텍스트", + onDismissRequest = {}, + onClick = {}, + ) + } +} diff --git a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonWithTextButtonAlertDialog.kt b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonWithTextButtonAlertDialog.kt index 27aeb1470..be23dd7cd 100644 --- a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonWithTextButtonAlertDialog.kt +++ b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/SingleButtonWithTextButtonAlertDialog.kt @@ -1,21 +1,20 @@ package com.neki.android.core.designsystem.dialog +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.widthIn 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.draw.clip -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextDecoration import androidx.compose.ui.unit.dp @@ -58,9 +57,9 @@ fun SingleButtonWithTextButtonAlertDialog( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.icon_dialog_alert), - tint = Color.Unspecified, + Image( + modifier = Modifier.size(64.dp), + painter = painterResource(R.drawable.image_dialog_alert), contentDescription = null, ) Column( @@ -84,7 +83,7 @@ fun SingleButtonWithTextButtonAlertDialog( Column( modifier = Modifier.padding(vertical = 12.dp), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.spacedBy(4.dp), ) { CTAButtonPrimary( text = buttonText, @@ -96,11 +95,11 @@ fun SingleButtonWithTextButtonAlertDialog( ) Text( modifier = Modifier + .clickableSingle(onClick = onTextButtonClick) .padding( vertical = 4.dp, horizontal = 56.dp, - ) - .clickableSingle(onClick = onTextButtonClick), + ), text = textButtonText, style = NekiTheme.typography.body14Regular, color = NekiTheme.colorScheme.primary600, diff --git a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/WarningDialog.kt b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/WarningDialog.kt index bc2607c6a..d2834096d 100644 --- a/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/WarningDialog.kt +++ b/core/designsystem/src/main/java/com/neki/android/core/designsystem/dialog/WarningDialog.kt @@ -1,5 +1,6 @@ package com.neki.android.core.designsystem.dialog +import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -14,8 +15,8 @@ import androidx.compose.runtime.Composable 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.res.painterResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -62,12 +63,11 @@ fun WarningDialog( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.spacedBy(12.dp), ) { - Icon( - imageVector = ImageVector.vectorResource(R.drawable.icon_dialog_alert), - tint = Color.Unspecified, + Image( + modifier = Modifier.size(64.dp), + painter = painterResource(R.drawable.image_dialog_alert), contentDescription = null, ) - Text( text = content, style = NekiTheme.typography.body14Regular, diff --git a/core/designsystem/src/main/res/drawable/icon_dialog_alert.xml b/core/designsystem/src/main/res/drawable/icon_dialog_alert.xml deleted file mode 100644 index 011a49cab..000000000 --- a/core/designsystem/src/main/res/drawable/icon_dialog_alert.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/core/designsystem/src/main/res/drawable/image_dialog_alert.png b/core/designsystem/src/main/res/drawable/image_dialog_alert.png new file mode 100644 index 000000000..98b1c604f Binary files /dev/null and b/core/designsystem/src/main/res/drawable/image_dialog_alert.png differ diff --git a/core/ui/src/main/java/com/neki/android/core/ui/component/SelectDialog.kt b/core/ui/src/main/java/com/neki/android/core/ui/component/SelectDialog.kt new file mode 100644 index 000000000..2a1e1caab --- /dev/null +++ b/core/ui/src/main/java/com/neki/android/core/ui/component/SelectDialog.kt @@ -0,0 +1,77 @@ +package com.neki.android.core.ui.component + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.Dialog +import androidx.compose.ui.window.DialogProperties +import com.neki.android.core.designsystem.ComponentPreview +import com.neki.android.core.designsystem.modifier.clickableSingle +import com.neki.android.core.designsystem.ui.theme.NekiTheme +import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList + +@Composable +fun SelectDialog( + options: ImmutableList, + onDismissRequest: () -> Unit, + onSelect: (T) -> Unit, + properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false), +) { + Dialog( + onDismissRequest = onDismissRequest, + properties = properties, + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 32.dp) + .widthIn(max = 400.dp) + .clip(RoundedCornerShape(12.dp)) + .background(NekiTheme.colorScheme.white) + .padding(vertical = 12.dp), + ) { + options.forEach { option -> + Text( + modifier = Modifier + .fillMaxWidth() + .clickableSingle(onClick = { onSelect(option) }) + .padding(vertical = 14.dp), + text = option.toString(), + style = NekiTheme.typography.body16SemiBold, + color = NekiTheme.colorScheme.gray800, + textAlign = TextAlign.Center, + ) + } + } + } +} + +private enum class PreviewSelectOption(val label: String) { + OPTION_1("선택지1"), + OPTION_2("선택지2"), + ; + + override fun toString(): String = label +} + +@ComponentPreview +@Composable +private fun SelectDialogPreview() { + NekiTheme { + SelectDialog( + options = PreviewSelectOption.entries.toImmutableList(), + onDismissRequest = {}, + onSelect = {}, + ) + } +} diff --git a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainContract.kt b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainContract.kt index dd9debe4d..3a043923c 100644 --- a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainContract.kt +++ b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainContract.kt @@ -16,7 +16,7 @@ data class ArchiveMainState( val scannedImageUrl: String? = null, val selectedUris: ImmutableList = persistentListOf(), val isShowAddDialog: Boolean = false, - val isShowChooseWithAlbumDialog: Boolean = false, + val isShowSelectWithAlbumDialog: Boolean = false, val isShowAddAlbumBottomSheet: Boolean = false, ) { val uploadType: UploadType @@ -38,7 +38,7 @@ sealed interface ArchiveMainIntent { data object ClickGalleryUploadRow : ArchiveMainIntent data class SelectGalleryImage(val uris: List) : ArchiveMainIntent - data object DismissChooseWithAlbumDialog : ArchiveMainIntent + data object DismissSelectWithAlbumDialog : ArchiveMainIntent data object ClickUploadWithAlbumRow : ArchiveMainIntent data object ClickUploadWithoutAlbumRow : ArchiveMainIntent diff --git a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainScreen.kt b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainScreen.kt index 392c89161..d3a8b095b 100644 --- a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainScreen.kt +++ b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainScreen.kt @@ -45,7 +45,8 @@ import com.neki.android.feature.archive.impl.main.component.ArchiveMainAlbumList import com.neki.android.feature.archive.impl.main.component.ArchiveMainPhotoItem import com.neki.android.feature.archive.impl.main.component.ArchiveMainTitleRow import com.neki.android.feature.archive.impl.main.component.ArchiveMainTopBar -import com.neki.android.feature.archive.impl.main.component.ChooseWithAlbumDialog +import com.neki.android.feature.archive.impl.main.component.AlbumUploadOption +import com.neki.android.feature.archive.impl.main.component.SelectWithAlbumDialog import com.neki.android.feature.archive.impl.main.component.GotoTopButton import com.neki.android.feature.archive.impl.main.component.NoPhotoContent import kotlinx.collections.immutable.persistentListOf @@ -175,11 +176,15 @@ internal fun ArchiveMainScreen( ) } - if (uiState.isShowChooseWithAlbumDialog) { - ChooseWithAlbumDialog( - onDismissRequest = { onIntent(ArchiveMainIntent.DismissChooseWithAlbumDialog) }, - onClickUploadWithOutAlbum = { onIntent(ArchiveMainIntent.ClickUploadWithoutAlbumRow) }, - onClickUploadWithAlbum = { onIntent(ArchiveMainIntent.ClickUploadWithAlbumRow) }, + if (uiState.isShowSelectWithAlbumDialog) { + SelectWithAlbumDialog( + onDismissRequest = { onIntent(ArchiveMainIntent.DismissSelectWithAlbumDialog) }, + onSelect = { option -> + when (option) { + AlbumUploadOption.WITHOUT_ALBUM -> onIntent(ArchiveMainIntent.ClickUploadWithoutAlbumRow) + AlbumUploadOption.WITH_ALBUM -> onIntent(ArchiveMainIntent.ClickUploadWithAlbumRow) + } + }, ) } } diff --git a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainViewModel.kt b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainViewModel.kt index 48d58e1d2..2063d26df 100644 --- a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainViewModel.kt +++ b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/ArchiveMainViewModel.kt @@ -49,7 +49,7 @@ class ArchiveMainViewModel @Inject constructor( is ArchiveMainIntent.QRCodeScanned -> reduce { copy( scannedImageUrl = intent.imageUrl, - isShowChooseWithAlbumDialog = true, + isShowSelectWithAlbumDialog = true, ) } @@ -74,16 +74,16 @@ class ArchiveMainViewModel @Inject constructor( is ArchiveMainIntent.SelectGalleryImage -> reduce { copy( - isShowChooseWithAlbumDialog = true, + isShowSelectWithAlbumDialog = true, selectedUris = intent.uris.toImmutableList(), ) } - ArchiveMainIntent.DismissChooseWithAlbumDialog -> reduce { copy(isShowChooseWithAlbumDialog = false) } + ArchiveMainIntent.DismissSelectWithAlbumDialog -> reduce { copy(isShowSelectWithAlbumDialog = false) } ArchiveMainIntent.ClickUploadWithAlbumRow -> { reduce { copy( - isShowChooseWithAlbumDialog = false, + isShowSelectWithAlbumDialog = false, scannedImageUrl = null, selectedUris = persistentListOf(), ) @@ -171,7 +171,7 @@ class ArchiveMainViewModel @Inject constructor( reduce: (ArchiveMainState.() -> ArchiveMainState) -> Unit, postSideEffect: (ArchiveMainSideEffect) -> Unit, ) { - reduce { copy(isShowChooseWithAlbumDialog = false) } + reduce { copy(isShowSelectWithAlbumDialog = false) } val onSuccessSideEffect = { reduce { copy(isLoading = false) } postSideEffect(ArchiveMainSideEffect.ShowToastMessage("이미지를 추가했어요")) diff --git a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/component/ChooseWithAlbumDialog.kt b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/component/ChooseWithAlbumDialog.kt deleted file mode 100644 index 2d58cc9e3..000000000 --- a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/component/ChooseWithAlbumDialog.kt +++ /dev/null @@ -1,68 +0,0 @@ -package com.neki.android.feature.archive.impl.main.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.widthIn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog -import com.neki.android.core.designsystem.ComponentPreview -import com.neki.android.core.designsystem.modifier.clickableSingle -import com.neki.android.core.designsystem.ui.theme.NekiTheme - -@Composable -internal fun ChooseWithAlbumDialog( - onDismissRequest: () -> Unit = {}, - onClickUploadWithOutAlbum: () -> Unit = {}, - onClickUploadWithAlbum: () -> Unit = {}, -) { - Dialog( - onDismissRequest = onDismissRequest, - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 20.dp) - .widthIn(max = 400.dp) - .clip(RoundedCornerShape(20.dp)) - .background(NekiTheme.colorScheme.white) - .padding(vertical = 12.dp), - ) { - Text( - modifier = Modifier - .fillMaxWidth() - .clickableSingle(onClick = onClickUploadWithOutAlbum) - .padding(vertical = 14.dp), - text = "앨범 없이 업로드하기", - style = NekiTheme.typography.body16SemiBold, - color = NekiTheme.colorScheme.gray800, - textAlign = TextAlign.Center, - ) - Text( - modifier = Modifier - .fillMaxWidth() - .clickableSingle(onClick = onClickUploadWithAlbum) - .padding(vertical = 14.dp), - text = "앨범 선택 후 업로드하기", - style = NekiTheme.typography.body16SemiBold, - color = NekiTheme.colorScheme.gray800, - textAlign = TextAlign.Center, - ) - } - } -} - -@ComponentPreview -@Composable -private fun ChooseWithAlbumDialogPreview() { - NekiTheme { - ChooseWithAlbumDialog() - } -} diff --git a/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/component/SelectWithAlbumDialog.kt b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/component/SelectWithAlbumDialog.kt new file mode 100644 index 000000000..b89834f1b --- /dev/null +++ b/feature/archive/impl/src/main/kotlin/com/neki/android/feature/archive/impl/main/component/SelectWithAlbumDialog.kt @@ -0,0 +1,35 @@ +package com.neki.android.feature.archive.impl.main.component + +import androidx.compose.runtime.Composable +import com.neki.android.core.designsystem.ComponentPreview +import com.neki.android.core.ui.component.SelectDialog +import com.neki.android.core.designsystem.ui.theme.NekiTheme +import kotlinx.collections.immutable.toImmutableList + +internal enum class AlbumUploadOption(val label: String) { + WITHOUT_ALBUM("앨범 없이 업로드하기"), + WITH_ALBUM("앨범 선택 후 업로드하기"), + ; + + override fun toString(): String = label +} + +@Composable +internal fun SelectWithAlbumDialog( + onDismissRequest: () -> Unit = {}, + onSelect: (AlbumUploadOption) -> Unit = {}, +) { + SelectDialog( + options = AlbumUploadOption.entries.toImmutableList(), + onDismissRequest = onDismissRequest, + onSelect = onSelect, + ) +} + +@ComponentPreview +@Composable +private fun SelectWithAlbumDialogPreview() { + NekiTheme { + SelectWithAlbumDialog() + } +} diff --git a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageContract.kt b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageContract.kt index 0c6e89792..a3d8c8320 100644 --- a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageContract.kt +++ b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageContract.kt @@ -12,7 +12,7 @@ data class MyPageState( val profileImageState: EditProfileImageType = EditProfileImageType.OriginalImageUrl(""), val isShowLogoutDialog: Boolean = false, val isShowWithdrawDialog: Boolean = false, - val isShowImageChooseDialog: Boolean = false, + val isShowImageSelectDialog: Boolean = false, // Permission val isGrantedCamera: Boolean = false, val isGrantedLocation: Boolean = false, @@ -37,7 +37,7 @@ sealed interface MyPageIntent { data object ClickBackIcon : MyPageIntent data object ClickEditIcon : MyPageIntent data object ClickCameraIcon : MyPageIntent - data object DismissImageChooseDialog : MyPageIntent + data object DismissImageSelectDialog : MyPageIntent data class SelectProfileImage(val image: EditProfileImageType) : MyPageIntent data class ClickEditComplete(val nickname: String) : MyPageIntent data object ClickLogout : MyPageIntent diff --git a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageViewModel.kt b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageViewModel.kt index af0805dbc..e40086e96 100644 --- a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageViewModel.kt +++ b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/main/MyPageViewModel.kt @@ -55,9 +55,9 @@ internal class MyPageViewModel @Inject constructor( } MyPageIntent.ClickEditIcon -> postSideEffect(MyPageEffect.NavigateToEditProfile) - MyPageIntent.ClickCameraIcon -> reduce { copy(isShowImageChooseDialog = true) } - MyPageIntent.DismissImageChooseDialog -> reduce { copy(isShowImageChooseDialog = false) } - is MyPageIntent.SelectProfileImage -> reduce { copy(profileImageState = intent.image, isShowImageChooseDialog = false) } + MyPageIntent.ClickCameraIcon -> reduce { copy(isShowImageSelectDialog = true) } + MyPageIntent.DismissImageSelectDialog -> reduce { copy(isShowImageSelectDialog = false) } + is MyPageIntent.SelectProfileImage -> reduce { copy(profileImageState = intent.image, isShowImageSelectDialog = false) } is MyPageIntent.ClickEditComplete -> { val isNicknameChanged = state.userInfo.nickname != intent.nickname val isProfileImageChanged = state.profileImageState !is EditProfileImageType.OriginalImageUrl diff --git a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/EditProfileScreen.kt b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/EditProfileScreen.kt index c8308f518..620b70ef5 100644 --- a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/EditProfileScreen.kt +++ b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/EditProfileScreen.kt @@ -46,7 +46,8 @@ import com.neki.android.feature.mypage.impl.main.MyPageViewModel import com.neki.android.feature.mypage.impl.profile.model.EditProfileImageType import com.neki.android.feature.mypage.impl.profile.component.EditProfileImage import com.neki.android.feature.mypage.impl.profile.component.ProfileEditTopBar -import com.neki.android.feature.mypage.impl.profile.component.ProfileImageChooseDialog +import com.neki.android.feature.mypage.impl.profile.component.SelectProfileImageDialog +import com.neki.android.feature.mypage.impl.profile.component.ProfileImageOption import timber.log.Timber @Composable @@ -175,15 +176,21 @@ fun EditProfileScreen( } } - if (uiState.isShowImageChooseDialog) { - ProfileImageChooseDialog( - onDismissRequest = { onIntent(MyPageIntent.DismissImageChooseDialog) }, - onClickDefaultProfile = { onIntent(MyPageIntent.SelectProfileImage(EditProfileImageType.Default)) }, - onClickSelectPhoto = { - onIntent(MyPageIntent.DismissImageChooseDialog) - photoPicker.launch( - PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly), - ) + if (uiState.isShowImageSelectDialog) { + SelectProfileImageDialog( + onDismissRequest = { onIntent(MyPageIntent.DismissImageSelectDialog) }, + onSelect = { option -> + when (option) { + ProfileImageOption.DEFAULT_PROFILE -> { + onIntent(MyPageIntent.SelectProfileImage(EditProfileImageType.Default)) + } + ProfileImageOption.SELECT_PHOTO -> { + onIntent(MyPageIntent.DismissImageSelectDialog) + photoPicker.launch( + PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly), + ) + } + } }, ) } diff --git a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/ProfileSettingScreen.kt b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/ProfileSettingScreen.kt index f153decaa..3c91805bd 100644 --- a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/ProfileSettingScreen.kt +++ b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/ProfileSettingScreen.kt @@ -11,7 +11,7 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.neki.android.core.common.kakao.KakaoAuthHelper import com.neki.android.core.designsystem.ComponentPreview -import com.neki.android.core.designsystem.dialog.DoubleButtonAlertDialog +import com.neki.android.core.designsystem.dialog.DoubleButtonDialog import com.neki.android.core.designsystem.ui.theme.NekiTheme import com.neki.android.core.ui.component.LoadingDialog import com.neki.android.core.ui.compose.collectWithLifecycle @@ -90,7 +90,7 @@ fun ProfileSettingScreen( } if (uiState.isShowLogoutDialog) { - DoubleButtonAlertDialog( + DoubleButtonDialog( title = "로그아웃을 하시겠습니까?", content = "다시 로그인해야 서비스를 이용할 수 있어요.", grayButtonText = "취소", @@ -103,7 +103,7 @@ fun ProfileSettingScreen( } if (uiState.isShowWithdrawDialog) { - DoubleButtonAlertDialog( + DoubleButtonDialog( title = "정말 탈퇴하시겠어요?", content = "계정을 탈퇴하면 사진과 정보가 모두 삭제되며,\n삭제된 데이터는 복구할 수 없어요.", grayButtonText = "취소", diff --git a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/component/ProfileImageChooseDialog.kt b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/component/ProfileImageChooseDialog.kt deleted file mode 100644 index d3d117c8e..000000000 --- a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/component/ProfileImageChooseDialog.kt +++ /dev/null @@ -1,72 +0,0 @@ -package com.neki.android.feature.mypage.impl.profile.component - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.widthIn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.Dialog -import androidx.compose.ui.window.DialogProperties -import com.neki.android.core.designsystem.ComponentPreview -import com.neki.android.core.designsystem.modifier.clickableSingle -import com.neki.android.core.designsystem.ui.theme.NekiTheme - -@Composable -internal fun ProfileImageChooseDialog( - properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false), - onDismissRequest: () -> Unit = {}, - onClickDefaultProfile: () -> Unit = {}, - onClickSelectPhoto: () -> Unit = {}, -) { - Dialog( - onDismissRequest = onDismissRequest, - properties = properties, - ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 32.dp) - .widthIn(max = 400.dp) - .background( - shape = RoundedCornerShape(20.dp), - color = NekiTheme.colorScheme.white, - ) - .padding(vertical = 12.dp), - ) { - Text( - modifier = Modifier - .fillMaxWidth() - .clickableSingle(onClick = onClickDefaultProfile) - .padding(vertical = 14.dp), - text = "기본 프로필로 바꾸기", - style = NekiTheme.typography.body16SemiBold, - color = NekiTheme.colorScheme.gray800, - textAlign = TextAlign.Center, - ) - Text( - modifier = Modifier - .fillMaxWidth() - .clickableSingle(onClick = onClickSelectPhoto) - .padding(vertical = 14.dp), - text = "사진 선택하기", - style = NekiTheme.typography.body16SemiBold, - color = NekiTheme.colorScheme.gray800, - textAlign = TextAlign.Center, - ) - } - } -} - -@ComponentPreview -@Composable -private fun ProfileImageChooseDialogPreview() { - NekiTheme { - ProfileImageChooseDialog() - } -} diff --git a/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/component/SelectProfileImageDialog.kt b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/component/SelectProfileImageDialog.kt new file mode 100644 index 000000000..10a919a2c --- /dev/null +++ b/feature/mypage/impl/src/main/java/com/neki/android/feature/mypage/impl/profile/component/SelectProfileImageDialog.kt @@ -0,0 +1,38 @@ +package com.neki.android.feature.mypage.impl.profile.component + +import androidx.compose.runtime.Composable +import androidx.compose.ui.window.DialogProperties +import com.neki.android.core.designsystem.ComponentPreview +import com.neki.android.core.ui.component.SelectDialog +import com.neki.android.core.designsystem.ui.theme.NekiTheme +import kotlinx.collections.immutable.toImmutableList + +internal enum class ProfileImageOption(val label: String) { + DEFAULT_PROFILE("기본 프로필로 바꾸기"), + SELECT_PHOTO("사진 선택하기"), + ; + + override fun toString(): String = label +} + +@Composable +internal fun SelectProfileImageDialog( + properties: DialogProperties = DialogProperties(usePlatformDefaultWidth = false), + onDismissRequest: () -> Unit = {}, + onSelect: (ProfileImageOption) -> Unit = {}, +) { + SelectDialog( + options = ProfileImageOption.entries.toImmutableList(), + onDismissRequest = onDismissRequest, + onSelect = onSelect, + properties = properties, + ) +} + +@ComponentPreview +@Composable +private fun SelectProfileImageDialogPreview() { + NekiTheme { + SelectProfileImageDialog() + } +}