Merge pull request #1651 from vector-im/feature/bma/uiUpdate
Preparatory work for SecureBackup: UI update
This commit is contained in:
commit
bf905dd79b
22 changed files with 375 additions and 180 deletions
|
|
@ -16,41 +16,27 @@
|
|||
|
||||
package io.element.android.features.preferences.impl.notifications
|
||||
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import io.element.android.libraries.androidutils.system.startNotificationSettingsIntent
|
||||
import io.element.android.libraries.architecture.Async
|
||||
import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule
|
||||
import io.element.android.libraries.designsystem.components.ProgressDialog
|
||||
import io.element.android.libraries.designsystem.components.dialogs.ErrorDialog
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceCategory
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferenceText
|
||||
import io.element.android.libraries.designsystem.components.preferences.PreferencePage
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.ButtonSize
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.designsystem.utils.OnLifecycleEvent
|
||||
import io.element.android.libraries.matrix.api.room.RoomNotificationMode
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
/**
|
||||
|
|
@ -197,41 +183,14 @@ private fun InvalidNotificationSettingsView(
|
|||
onDismissError: () -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
||||
Surface(
|
||||
Modifier.fillMaxWidth(),
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = MaterialTheme.colorScheme.surfaceVariant
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
) {
|
||||
Row {
|
||||
Text(
|
||||
stringResource(CommonStrings.screen_notification_settings_configuration_mismatch),
|
||||
modifier = Modifier.weight(1f),
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
textAlign = TextAlign.Start,
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
stringResource(CommonStrings.screen_notification_settings_configuration_mismatch_description),
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Button(
|
||||
text = stringResource(CommonStrings.action_continue),
|
||||
size = ButtonSize.Medium,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = onContinueClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
DialogLikeBannerMolecule(
|
||||
modifier = modifier,
|
||||
title = stringResource(CommonStrings.screen_notification_settings_configuration_mismatch),
|
||||
content = stringResource(CommonStrings.screen_notification_settings_configuration_mismatch_description),
|
||||
onSubmitClicked = onContinueClicked,
|
||||
onDismissClicked = null,
|
||||
)
|
||||
|
||||
if (showError) {
|
||||
ErrorDialog(
|
||||
title = stringResource(id = CommonStrings.dialog_title_error),
|
||||
|
|
|
|||
|
|
@ -16,31 +16,13 @@
|
|||
|
||||
package io.element.android.features.roomlist.impl.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.features.roomlist.impl.R
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.atomic.molecules.DialogLikeBannerMolecule
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.ButtonSize
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
|
||||
@Composable
|
||||
internal fun RequestVerificationHeader(
|
||||
|
|
@ -48,50 +30,20 @@ internal fun RequestVerificationHeader(
|
|||
onDismissClicked: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
||||
Surface(
|
||||
Modifier.fillMaxWidth(),
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = MaterialTheme.colorScheme.surfaceVariant
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
) {
|
||||
Row {
|
||||
Text(
|
||||
stringResource(R.string.session_verification_banner_title),
|
||||
modifier = Modifier.weight(1f),
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
textAlign = TextAlign.Start,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier.clickable(onClick = onDismissClicked),
|
||||
resourceId = CommonDrawables.ic_compound_close,
|
||||
contentDescription = stringResource(CommonStrings.action_close)
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
stringResource(R.string.session_verification_banner_message),
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Button(
|
||||
text = stringResource(CommonStrings.action_continue),
|
||||
size = ButtonSize.Medium,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = onVerifyClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
DialogLikeBannerMolecule(
|
||||
modifier = modifier,
|
||||
title = stringResource(R.string.session_verification_banner_title),
|
||||
content = stringResource(R.string.session_verification_banner_message),
|
||||
onSubmitClicked = onVerifyClicked,
|
||||
onDismissClicked = onDismissClicked,
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RequestVerificationHeaderPreview() = ElementPreview {
|
||||
RequestVerificationHeader(onVerifyClicked = {}, onDismissClicked = {})
|
||||
RequestVerificationHeader(
|
||||
onVerifyClicked = {},
|
||||
onDismissClicked = {},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.atomic.atoms
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
|
||||
@Composable
|
||||
fun RedIndicatorAtom(
|
||||
modifier: Modifier = Modifier,
|
||||
size: Dp = 10.dp,
|
||||
borderSize: Dp = 1.dp,
|
||||
color: Color = ElementTheme.colors.bgCriticalPrimary,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(size)
|
||||
.border(borderSize, ElementTheme.materialColors.background, CircleShape)
|
||||
.padding(borderSize / 2)
|
||||
.clip(CircleShape)
|
||||
.background(color)
|
||||
)
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun RedIndicatorAtomPreview() = ElementPreview {
|
||||
RedIndicatorAtom()
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2023 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.designsystem.atomic.molecules
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.preview.ElementPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
|
||||
import io.element.android.libraries.designsystem.theme.components.Button
|
||||
import io.element.android.libraries.designsystem.theme.components.ButtonSize
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
import io.element.android.libraries.designsystem.theme.components.Surface
|
||||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.theme.ElementTheme
|
||||
import io.element.android.libraries.ui.strings.CommonStrings
|
||||
|
||||
@Composable
|
||||
fun DialogLikeBannerMolecule(
|
||||
title: String,
|
||||
content: String,
|
||||
onSubmitClicked: () -> Unit,
|
||||
onDismissClicked: (() -> Unit)?,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Box(modifier = modifier.padding(horizontal = 16.dp, vertical = 8.dp)) {
|
||||
Surface(
|
||||
Modifier.fillMaxWidth(),
|
||||
shape = MaterialTheme.shapes.small,
|
||||
color = MaterialTheme.colorScheme.surfaceVariant
|
||||
) {
|
||||
Column(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
) {
|
||||
Row {
|
||||
Text(
|
||||
text = title,
|
||||
modifier = Modifier.weight(1f),
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
textAlign = TextAlign.Start,
|
||||
)
|
||||
if (onDismissClicked != null) {
|
||||
Icon(
|
||||
modifier = Modifier.clickable(onClick = onDismissClicked),
|
||||
resourceId = CommonDrawables.ic_compound_close,
|
||||
contentDescription = stringResource(CommonStrings.action_close)
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
Text(
|
||||
text = content,
|
||||
style = ElementTheme.typography.fontBodyMdRegular,
|
||||
)
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
Button(
|
||||
text = stringResource(CommonStrings.action_continue),
|
||||
size = ButtonSize.Medium,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
onClick = onSubmitClicked,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewsDayNight
|
||||
@Composable
|
||||
internal fun DialogLikeBannerMoleculePreview() = ElementPreview {
|
||||
DialogLikeBannerMolecule(
|
||||
title = "Title",
|
||||
content = "Content",
|
||||
onSubmitClicked = {},
|
||||
onDismissClicked = {}
|
||||
)
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ fun ConfirmationDialog(
|
|||
title: String? = null,
|
||||
submitText: String = stringResource(id = CommonStrings.action_ok),
|
||||
cancelText: String = stringResource(id = CommonStrings.action_cancel),
|
||||
destructiveSubmit: Boolean = false,
|
||||
thirdButtonText: String? = null,
|
||||
onCancelClicked: () -> Unit = onDismiss,
|
||||
onThirdButtonClicked: () -> Unit = {},
|
||||
|
|
@ -49,6 +50,7 @@ fun ConfirmationDialog(
|
|||
submitText = submitText,
|
||||
cancelText = cancelText,
|
||||
thirdButtonText = thirdButtonText,
|
||||
destructiveSubmit = destructiveSubmit,
|
||||
onSubmitClicked = onSubmitClicked,
|
||||
onCancelClicked = onCancelClicked,
|
||||
onThirdButtonClicked = onThirdButtonClicked,
|
||||
|
|
@ -67,6 +69,7 @@ private fun ConfirmationDialogContent(
|
|||
title: String? = null,
|
||||
thirdButtonText: String? = null,
|
||||
onThirdButtonClicked: () -> Unit = {},
|
||||
destructiveSubmit: Boolean = false,
|
||||
icon: @Composable (() -> Unit)? = null,
|
||||
) {
|
||||
SimpleAlertDialogContent(
|
||||
|
|
@ -79,6 +82,7 @@ private fun ConfirmationDialogContent(
|
|||
onCancelClicked = onCancelClicked,
|
||||
thirdButtonText = thirdButtonText,
|
||||
onThirdButtonClicked = onThirdButtonClicked,
|
||||
destructiveSubmit = destructiveSubmit,
|
||||
icon = icon,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ fun PreferenceText(
|
|||
icon: ImageVector? = null,
|
||||
@DrawableRes iconResourceId: Int? = null,
|
||||
showIconAreaIfNoIcon: Boolean = false,
|
||||
showIconBadge: Boolean = false,
|
||||
tintColor: Color? = null,
|
||||
onClick: () -> Unit = {},
|
||||
) {
|
||||
|
|
@ -73,6 +74,7 @@ fun PreferenceText(
|
|||
PreferenceIcon(
|
||||
icon = icon,
|
||||
iconResourceId = iconResourceId,
|
||||
showIconBadge = showIconBadge,
|
||||
enabled = enabled,
|
||||
isVisible = showIconAreaIfNoIcon,
|
||||
tintColor = tintColor ?: enabled.toSecondaryEnabledColor(),
|
||||
|
|
|
|||
|
|
@ -17,17 +17,20 @@
|
|||
package io.element.android.libraries.designsystem.components.preferences.components
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
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.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.libraries.designsystem.atomic.atoms.RedIndicatorAtom
|
||||
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
|
||||
import io.element.android.libraries.designsystem.preview.PreviewGroup
|
||||
import io.element.android.libraries.designsystem.theme.components.Icon
|
||||
|
|
@ -38,20 +41,30 @@ fun PreferenceIcon(
|
|||
modifier: Modifier = Modifier,
|
||||
icon: ImageVector? = null,
|
||||
@DrawableRes iconResourceId: Int? = null,
|
||||
showIconBadge: Boolean = false,
|
||||
tintColor: Color? = null,
|
||||
enabled: Boolean = true,
|
||||
isVisible: Boolean = true,
|
||||
) {
|
||||
if (icon != null || iconResourceId != null) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
resourceId = iconResourceId,
|
||||
contentDescription = "",
|
||||
tint = tintColor ?: enabled.toSecondaryEnabledColor(),
|
||||
modifier = modifier
|
||||
.padding(end = 16.dp)
|
||||
.size(24.dp),
|
||||
)
|
||||
Box(modifier = modifier) {
|
||||
Icon(
|
||||
imageVector = icon,
|
||||
resourceId = iconResourceId,
|
||||
contentDescription = "",
|
||||
tint = tintColor ?: enabled.toSecondaryEnabledColor(),
|
||||
modifier = Modifier
|
||||
.padding(end = 16.dp)
|
||||
.size(24.dp),
|
||||
)
|
||||
if (showIconBadge) {
|
||||
RedIndicatorAtom(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.padding(end = 16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else if (isVisible) {
|
||||
Spacer(modifier = modifier.width(40.dp))
|
||||
}
|
||||
|
|
@ -60,9 +73,19 @@ fun PreferenceIcon(
|
|||
@Preview(group = PreviewGroup.Preferences)
|
||||
@Composable
|
||||
internal fun PreferenceIconPreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) =
|
||||
ElementThemedPreview { ContentToPreview(content) }
|
||||
ElementThemedPreview {
|
||||
PreferenceIcon(
|
||||
icon = content,
|
||||
showIconBadge = false,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview(group = PreviewGroup.Preferences)
|
||||
@Composable
|
||||
private fun ContentToPreview(content: ImageVector?) {
|
||||
PreferenceIcon(icon = content)
|
||||
}
|
||||
internal fun PreferenceIconWithBadgePreview(@PreviewParameter(ImageVectorProvider::class) content: ImageVector?) =
|
||||
ElementThemedPreview {
|
||||
PreferenceIcon(
|
||||
icon = content,
|
||||
showIconBadge = true,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ internal fun SimpleAlertDialogContent(
|
|||
title: String? = null,
|
||||
subtitle: @Composable (() -> Unit)? = null,
|
||||
submitText: String? = null,
|
||||
destructiveSubmit: Boolean = false,
|
||||
onSubmitClicked: () -> Unit = {},
|
||||
thirdButtonText: String? = null,
|
||||
onThirdButtonClicked: () -> Unit = {},
|
||||
|
|
@ -76,6 +77,7 @@ internal fun SimpleAlertDialogContent(
|
|||
title = title,
|
||||
subtitle = subtitle,
|
||||
submitText = submitText,
|
||||
destructiveSubmit = destructiveSubmit,
|
||||
onSubmitClicked = onSubmitClicked,
|
||||
thirdButtonText = thirdButtonText,
|
||||
onThirdButtonClicked = onThirdButtonClicked,
|
||||
|
|
@ -92,6 +94,7 @@ internal fun SimpleAlertDialogContent(
|
|||
title: String? = null,
|
||||
subtitle: @Composable (() -> Unit)? = null,
|
||||
submitText: String? = null,
|
||||
destructiveSubmit: Boolean = false,
|
||||
onSubmitClicked: () -> Unit = {},
|
||||
thirdButtonText: String? = null,
|
||||
onThirdButtonClicked: () -> Unit = {},
|
||||
|
|
@ -126,6 +129,7 @@ internal fun SimpleAlertDialogContent(
|
|||
enabled = enabled,
|
||||
size = ButtonSize.Medium,
|
||||
onClick = onSubmitClicked,
|
||||
destructive = destructiveSubmit,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -345,8 +349,10 @@ private fun AlertDialogFlowRow(
|
|||
val arrangement = Arrangement.End
|
||||
val mainAxisPositions = IntArray(childrenMainAxisSizes.size) { 0 }
|
||||
with(arrangement) {
|
||||
arrange(mainAxisLayoutSize, childrenMainAxisSizes,
|
||||
layoutDirection, mainAxisPositions)
|
||||
arrange(
|
||||
mainAxisLayoutSize, childrenMainAxisSizes,
|
||||
layoutDirection, mainAxisPositions
|
||||
)
|
||||
}
|
||||
placeables.forEachIndexed { j, placeable ->
|
||||
placeable.place(
|
||||
|
|
@ -385,22 +391,22 @@ internal object DialogContentDefaults {
|
|||
val containerColor: Color
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get()= ElementTheme.colors.bgCanvasDefault
|
||||
get() = ElementTheme.colors.bgCanvasDefault
|
||||
|
||||
val textContentColor: Color
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get()= ElementTheme.materialColors.onSurfaceVariant
|
||||
get() = ElementTheme.materialColors.onSurfaceVariant
|
||||
|
||||
val titleContentColor: Color
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get()= ElementTheme.materialColors.onSurface
|
||||
get() = ElementTheme.materialColors.onSurface
|
||||
|
||||
val iconContentColor: Color
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get()= ElementTheme.materialColors.primary
|
||||
get() = ElementTheme.materialColors.primary
|
||||
}
|
||||
|
||||
// Paddings for each of the dialog's parts. Taken from M3 source code.
|
||||
|
|
@ -462,3 +468,21 @@ internal fun DialogWithOnlyMessageAndOkButtonPreview() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(group = PreviewGroup.Dialogs, name = "Dialog with destructive button")
|
||||
@Composable
|
||||
@Suppress("MaxLineLength")
|
||||
internal fun DialogWithDestructiveButtonPreview() {
|
||||
ElementThemedPreview(showBackground = false) {
|
||||
DialogPreview {
|
||||
SimpleAlertDialogContent(
|
||||
title = "Dialog Title",
|
||||
content = "A dialog with a destructive action",
|
||||
cancelText = "Cancel",
|
||||
submitText = "Delete",
|
||||
destructiveSubmit = true,
|
||||
onCancelClicked = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ import androidx.compose.foundation.BorderStroke
|
|||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
|
|
@ -64,6 +65,7 @@ fun Button(
|
|||
enabled: Boolean = true,
|
||||
size: ButtonSize = ButtonSize.Large,
|
||||
showProgress: Boolean = false,
|
||||
destructive: Boolean = false,
|
||||
leadingIcon: IconSource? = null,
|
||||
) = ButtonInternal(
|
||||
text = text,
|
||||
|
|
@ -73,6 +75,7 @@ fun Button(
|
|||
enabled = enabled,
|
||||
size = size,
|
||||
showProgress = showProgress,
|
||||
destructive = destructive,
|
||||
leadingIcon = leadingIcon
|
||||
)
|
||||
|
||||
|
|
@ -84,6 +87,7 @@ fun OutlinedButton(
|
|||
enabled: Boolean = true,
|
||||
size: ButtonSize = ButtonSize.Large,
|
||||
showProgress: Boolean = false,
|
||||
destructive: Boolean = false,
|
||||
leadingIcon: IconSource? = null,
|
||||
) = ButtonInternal(
|
||||
text = text,
|
||||
|
|
@ -93,6 +97,7 @@ fun OutlinedButton(
|
|||
enabled = enabled,
|
||||
size = size,
|
||||
showProgress = showProgress,
|
||||
destructive = destructive,
|
||||
leadingIcon = leadingIcon
|
||||
)
|
||||
|
||||
|
|
@ -104,6 +109,7 @@ fun TextButton(
|
|||
enabled: Boolean = true,
|
||||
size: ButtonSize = ButtonSize.Large,
|
||||
showProgress: Boolean = false,
|
||||
destructive: Boolean = false,
|
||||
leadingIcon: IconSource? = null,
|
||||
) = ButtonInternal(
|
||||
text = text,
|
||||
|
|
@ -113,6 +119,7 @@ fun TextButton(
|
|||
enabled = enabled,
|
||||
size = size,
|
||||
showProgress = showProgress,
|
||||
destructive = destructive,
|
||||
leadingIcon = leadingIcon
|
||||
)
|
||||
|
||||
|
|
@ -122,7 +129,8 @@ private fun ButtonInternal(
|
|||
onClick: () -> Unit,
|
||||
style: ButtonStyle,
|
||||
modifier: Modifier = Modifier,
|
||||
colors: ButtonColors = style.getColors(),
|
||||
destructive: Boolean = false,
|
||||
colors: ButtonColors = style.getColors(destructive),
|
||||
enabled: Boolean = true,
|
||||
size: ButtonSize = ButtonSize.Large,
|
||||
showProgress: Boolean = false,
|
||||
|
|
@ -170,7 +178,12 @@ private fun ButtonInternal(
|
|||
ButtonStyle.Filled -> null
|
||||
ButtonStyle.Outlined -> BorderStroke(
|
||||
width = 1.dp,
|
||||
color = ElementTheme.colors.borderInteractiveSecondary
|
||||
color = if (destructive)
|
||||
ElementTheme.colors.borderCriticalPrimary.copy(
|
||||
alpha = if (enabled) 1f else 0.5f
|
||||
)
|
||||
else
|
||||
ElementTheme.colors.borderInteractiveSecondary
|
||||
)
|
||||
ButtonStyle.Text -> null
|
||||
}
|
||||
|
|
@ -246,26 +259,52 @@ internal enum class ButtonStyle {
|
|||
Filled, Outlined, Text;
|
||||
|
||||
@Composable
|
||||
fun getColors(): ButtonColors = when (this) {
|
||||
fun getColors(destructive: Boolean): ButtonColors = when (this) {
|
||||
Filled -> ButtonDefaults.buttonColors(
|
||||
containerColor = ElementTheme.materialColors.primary,
|
||||
containerColor = getPrimaryColor(destructive),
|
||||
contentColor = ElementTheme.materialColors.onPrimary,
|
||||
disabledContainerColor = ElementTheme.colors.bgActionPrimaryDisabled,
|
||||
disabledContainerColor = if (destructive) {
|
||||
ElementTheme.colors.bgCriticalPrimary.copy(alpha = 0.5f)
|
||||
} else {
|
||||
ElementTheme.colors.bgActionPrimaryDisabled
|
||||
},
|
||||
disabledContentColor = ElementTheme.colors.textOnSolidPrimary
|
||||
)
|
||||
Outlined -> ButtonDefaults.buttonColors(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor = ElementTheme.materialColors.primary,
|
||||
contentColor = getPrimaryColor(destructive),
|
||||
disabledContainerColor = Color.Transparent,
|
||||
disabledContentColor = ElementTheme.colors.textDisabled,
|
||||
disabledContentColor = getDisabledContentColor(destructive),
|
||||
)
|
||||
Text -> ButtonDefaults.buttonColors(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor = if (LocalContentColor.current.isSpecified) LocalContentColor.current else ElementTheme.materialColors.primary,
|
||||
contentColor = if (destructive) {
|
||||
ElementTheme.colors.textCriticalPrimary
|
||||
} else {
|
||||
if (LocalContentColor.current.isSpecified) LocalContentColor.current else ElementTheme.materialColors.primary
|
||||
},
|
||||
disabledContainerColor = Color.Transparent,
|
||||
disabledContentColor = ElementTheme.colors.textDisabled,
|
||||
disabledContentColor = getDisabledContentColor(destructive),
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getPrimaryColor(destructive: Boolean): Color {
|
||||
return if (destructive) {
|
||||
ElementTheme.colors.bgCriticalPrimary
|
||||
} else {
|
||||
ElementTheme.materialColors.primary
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getDisabledContentColor(destructive: Boolean): Color {
|
||||
return if (destructive) {
|
||||
ElementTheme.colors.textCriticalPrimary.copy(alpha = 0.5f)
|
||||
} else {
|
||||
ElementTheme.colors.textDisabled
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(group = PreviewGroup.Buttons)
|
||||
|
|
@ -326,7 +365,6 @@ internal fun TextButtonLargePreview() {
|
|||
private fun ButtonCombinationPreview(
|
||||
style: ButtonStyle,
|
||||
size: ButtonSize,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
ElementThemedPreview {
|
||||
Column(
|
||||
|
|
@ -335,59 +373,70 @@ private fun ButtonCombinationPreview(
|
|||
.padding(16.dp)
|
||||
.width(IntrinsicSize.Max),
|
||||
) {
|
||||
// Normal
|
||||
ButtonRowPreview(
|
||||
modifier = Modifier.then(modifier),
|
||||
style = style,
|
||||
size = size,
|
||||
)
|
||||
|
||||
// With icon
|
||||
ButtonRowPreview(
|
||||
modifier = Modifier.then(modifier),
|
||||
leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_share_android),
|
||||
style = style,
|
||||
size = size,
|
||||
)
|
||||
|
||||
// With progress
|
||||
ButtonRowPreview(
|
||||
modifier = Modifier.then(modifier),
|
||||
showProgress = true,
|
||||
style = style,
|
||||
size = size,
|
||||
)
|
||||
ButtonMatrixPreview(style = style, size = size, destructive = false)
|
||||
ButtonMatrixPreview(style = style, size = size, destructive = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.ButtonMatrixPreview(
|
||||
style: ButtonStyle,
|
||||
size: ButtonSize,
|
||||
destructive: Boolean,
|
||||
) {
|
||||
// Normal
|
||||
ButtonRowPreview(
|
||||
style = style,
|
||||
size = size,
|
||||
destructive = destructive,
|
||||
)
|
||||
// With icon
|
||||
ButtonRowPreview(
|
||||
leadingIcon = IconSource.Resource(CommonDrawables.ic_compound_share_android),
|
||||
style = style,
|
||||
size = size,
|
||||
destructive = destructive,
|
||||
)
|
||||
// With progress
|
||||
ButtonRowPreview(
|
||||
showProgress = true,
|
||||
style = style,
|
||||
size = size,
|
||||
destructive = destructive,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ButtonRowPreview(
|
||||
style: ButtonStyle,
|
||||
size: ButtonSize,
|
||||
modifier: Modifier = Modifier,
|
||||
leadingIcon: IconSource? = null,
|
||||
showProgress: Boolean = false,
|
||||
destructive: Boolean = false,
|
||||
) {
|
||||
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally)) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp, Alignment.CenterHorizontally),
|
||||
) {
|
||||
ButtonInternal(
|
||||
text = "A button",
|
||||
showProgress = showProgress,
|
||||
destructive = destructive,
|
||||
onClick = {},
|
||||
style = style,
|
||||
size = size,
|
||||
leadingIcon = leadingIcon,
|
||||
modifier = Modifier.then(modifier),
|
||||
)
|
||||
ButtonInternal(
|
||||
text = "A button",
|
||||
showProgress = showProgress,
|
||||
destructive = destructive,
|
||||
enabled = false,
|
||||
onClick = {},
|
||||
style = style,
|
||||
size = size,
|
||||
leadingIcon = leadingIcon,
|
||||
modifier = Modifier.then(modifier),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:f54912dfb9235aa915025d496f280de362286997f746481da41deb02a1ec67e3
|
||||
size 4768
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ae078e1bb55967e9e583a588b4fb410eb0417d944b20911158b24f3824ee6dca
|
||||
size 4752
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:45736b242f9bf1a50fb14af9b340633f0fdc348ed7a846c4c57c3a56a4b2a48c
|
||||
size 11429
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1f9989dadb7c68cf705683997689f48595be9283eb939d934819399ec3c6805f
|
||||
size 11209
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a6d2243cb6bedd4b7a2f1c8c9b5aeac8356642271061c1439e591ce07c55c822
|
||||
size 6390
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a2d302d58c1faec3c3f0aa3286977b2698cd642c1e6dbcb9632510c6a4a922eb
|
||||
size 4501
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d0f2dc7bfcf59bf26362775625ddc9dedf53f400057997560628614136e2880b
|
||||
size 44144
|
||||
oid sha256:222795141c044e5bd7929cb9b894535124a176fd88347eea83037116f4ba6e8b
|
||||
size 68192
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:1e240c572aab6db77995c93787a7b0aaba76060861c45934eb87d4ba48c5675c
|
||||
size 42789
|
||||
oid sha256:b2d816dac6d468ede766719ec854cd575c89f454346ddd6ef8048c836bd04c14
|
||||
size 66223
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:54497bfab92c6ed850f753df61a31366ca68d41c7d90e322e7cc7eceb6dd4277
|
||||
size 48139
|
||||
oid sha256:a8d423b71168b3bd5dab8da01376fa3f114865aa0d4eb48d41fccfb4640367e3
|
||||
size 77867
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e7d3f2e50b395f86ed7c78146d5a428b099c672d763c278c1b2899d915abf717
|
||||
size 47615
|
||||
oid sha256:5381c6f070f2c81019ce39af5902f6f2c683c7ce4db4636b3b3259fdca270cdf
|
||||
size 75884
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:876eba4a9f8214aa2d33dad84ccbbb95994c615f25f158cb6596fd4512241bd9
|
||||
size 31582
|
||||
oid sha256:093a5bd68ebca0a9eaf8cac3cf748514cc0f3165c1079016d54d40762c7c0287
|
||||
size 46434
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:3dd7259e0b14b9ad5e9a6aed46383f91822ee11f1e77b0f2cdc5d2e0b38f7abd
|
||||
size 29702
|
||||
oid sha256:dfa423f2008049e54046449c19615eb66f28e7e66645eff76e80e33062b5c59a
|
||||
size 43655
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a3079a82a70fc20feac8c694a8571eac5dac9e2dea800bd7ca01628fe7c90d29
|
||||
size 33019
|
||||
Loading…
Add table
Add a link
Reference in a new issue