Updated on 2026-08-14
This commit is contained in:
commit
48c179efea
7 changed files with 511 additions and 21 deletions
|
|
@ -66,9 +66,6 @@ internal fun RootContent(
|
|||
},
|
||||
)
|
||||
|
||||
EventMessageEffect(
|
||||
messageHandler = uiDependencies.eventMessageHandler,
|
||||
snackbarHostState = snackbarHostState,
|
||||
)
|
||||
EventMessageEffect()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.tap.routing.component.impl
|
||||
|
||||
import androidx.compose.material3.SnackbarDuration
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -99,10 +98,10 @@ internal class DefaultRoutingComponent @AssistedInject constructor(
|
|||
val message = SnackbarMessage(
|
||||
message = text,
|
||||
duration = when (length) {
|
||||
Snackbar.LENGTH_SHORT -> SnackbarDuration.Short
|
||||
Snackbar.LENGTH_LONG -> SnackbarDuration.Long
|
||||
Snackbar.LENGTH_INDEFINITE -> SnackbarDuration.Indefinite
|
||||
else -> SnackbarDuration.Short
|
||||
Snackbar.LENGTH_SHORT -> SnackbarMessage.Duration.Short
|
||||
Snackbar.LENGTH_LONG -> SnackbarMessage.Duration.Long
|
||||
Snackbar.LENGTH_INDEFINITE -> SnackbarMessage.Duration.Indefinite
|
||||
else -> SnackbarMessage.Duration.Short
|
||||
},
|
||||
actionLabel = buttonTitle,
|
||||
action = action,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.message
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.layout.*
|
||||
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.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.isNullOrEmpty
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
|
||||
@Composable
|
||||
fun MessageBottomSheet(config: TangemBottomSheetConfig) {
|
||||
TangemBottomSheet(config) { notification: MessageBottomSheetUM ->
|
||||
Content(model = notification)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun Content(model: MessageBottomSheetUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier.padding(horizontal = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(40.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Box(modifier = Modifier)
|
||||
|
||||
if (model.iconResId != null) {
|
||||
Icon(
|
||||
modifier = Modifier.size(48.dp),
|
||||
painter = painterResource(model.iconResId),
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
if (!model.title.isNullOrEmpty()) {
|
||||
Text(
|
||||
text = model.title.resolveReference(),
|
||||
style = TangemTheme.typography.h2,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = model.message.resolveReference(),
|
||||
style = TangemTheme.typography.body2,
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 16.dp)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
if (model.primaryAction != null) {
|
||||
PrimaryButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = model.primaryAction.text.resolveReference(),
|
||||
enabled = model.primaryAction.enabled,
|
||||
onClick = model.primaryAction.onClick,
|
||||
)
|
||||
}
|
||||
|
||||
if (model.secondaryAction != null) {
|
||||
SecondaryButton(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
text = model.secondaryAction.text.resolveReference(),
|
||||
enabled = model.secondaryAction.enabled,
|
||||
onClick = model.secondaryAction.onClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// region Preview
|
||||
@Composable
|
||||
@Preview(showBackground = true, widthDp = 360)
|
||||
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
private fun Preview_NotificationBottomSheet(
|
||||
@PreviewParameter(MessageBottomSheetUMPreviewProvider::class) params: MessageBottomSheetUM,
|
||||
) {
|
||||
TangemThemePreview {
|
||||
MessageBottomSheet(
|
||||
config = TangemBottomSheetConfig(
|
||||
content = params,
|
||||
isShow = true,
|
||||
onDismissRequest = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class MessageBottomSheetUMPreviewProvider : PreviewParameterProvider<MessageBottomSheetUM> {
|
||||
val balancesHiddenMessage = MessageBottomSheetUM(
|
||||
iconResId = R.drawable.ic_eye_off_outline_24,
|
||||
title = resourceReference(R.string.balance_hidden_title),
|
||||
message = resourceReference(R.string.balance_hidden_description),
|
||||
primaryAction = MessageBottomSheetUM.ActionUM(
|
||||
text = resourceReference(R.string.balance_hidden_got_it_button),
|
||||
onClick = {},
|
||||
),
|
||||
secondaryAction = MessageBottomSheetUM.ActionUM(
|
||||
text = resourceReference(R.string.balance_hidden_do_not_show_button),
|
||||
onClick = {},
|
||||
),
|
||||
)
|
||||
|
||||
override val values: Sequence<MessageBottomSheetUM>
|
||||
get() = sequenceOf(
|
||||
balancesHiddenMessage,
|
||||
balancesHiddenMessage.copy(title = null),
|
||||
balancesHiddenMessage.copy(iconResId = null),
|
||||
balancesHiddenMessage.copy(primaryAction = null),
|
||||
balancesHiddenMessage.copy(secondaryAction = null),
|
||||
balancesHiddenMessage.copy(
|
||||
primaryAction = null,
|
||||
secondaryAction = null,
|
||||
),
|
||||
balancesHiddenMessage.copy(
|
||||
title = null,
|
||||
iconResId = null,
|
||||
primaryAction = null,
|
||||
secondaryAction = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
// endregion Preview
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.message
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
||||
data class MessageBottomSheetUM(
|
||||
@DrawableRes val iconResId: Int?,
|
||||
val title: TextReference?,
|
||||
val message: TextReference,
|
||||
val primaryAction: ActionUM?,
|
||||
val secondaryAction: ActionUM?,
|
||||
) : TangemBottomSheetConfigContent {
|
||||
|
||||
data class ActionUM(
|
||||
val text: TextReference,
|
||||
val enabled: Boolean = true,
|
||||
val onClick: () -> Unit,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,11 +1,14 @@
|
|||
package com.tangem.core.ui.message
|
||||
|
||||
import androidx.compose.material3.SnackbarDuration
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.ui.UiMessage
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resourceReference
|
||||
import com.tangem.core.ui.message.SnackbarMessage.Duration
|
||||
|
||||
/**
|
||||
* Event that is used to show a message in the UI.
|
||||
|
|
@ -19,16 +22,40 @@ sealed interface EventMessage : UiMessage
|
|||
* Shows a snackbar.
|
||||
*
|
||||
* @param message The message to show.
|
||||
* @param duration The duration of the snackbar.
|
||||
* @param actionLabel The label of the action button.
|
||||
* @param action The action to perform when the action button is clicked.
|
||||
* @param duration The duration of the snackbar. Optional, [Duration.Short] by default.
|
||||
* @param onDismissRequest The action to perform when the snackbar is dismissed. Optional, empty lambda by default.
|
||||
* @param actionLabel The label of the action button. Optional, `null` by default.
|
||||
* @param action The action to perform when the action button is clicked. Optional, `null` by default.
|
||||
* */
|
||||
data class SnackbarMessage(
|
||||
val message: TextReference,
|
||||
val duration: SnackbarDuration = SnackbarDuration.Short,
|
||||
val duration: Duration = Duration.Short,
|
||||
val onDismissRequest: () -> Unit = {},
|
||||
val actionLabel: TextReference? = null,
|
||||
val action: (() -> Unit)? = null,
|
||||
) : EventMessage
|
||||
) : EventMessage {
|
||||
|
||||
/**
|
||||
* The duration of the snackbar.
|
||||
* */
|
||||
enum class Duration {
|
||||
|
||||
/**
|
||||
* Shows the snackbar for a short period of time.
|
||||
* */
|
||||
Short,
|
||||
|
||||
/**
|
||||
* Shows the snackbar for a long period of time.
|
||||
* */
|
||||
Long,
|
||||
|
||||
/**
|
||||
* Shows the snackbar indefinitely, until dismissed or action performed.
|
||||
* */
|
||||
Indefinite,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a [content] in the UI.
|
||||
|
|
@ -44,4 +71,170 @@ data class ContentMessage(val content: Content) : EventMessage {
|
|||
@Composable
|
||||
operator fun invoke(onDismiss: () -> Unit)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows an alert dialog.
|
||||
*
|
||||
* @param message The message to show.
|
||||
* @param title The title of the dialog. Optional, `null` by default.
|
||||
* @param firstAction The first dialog action to perform.
|
||||
* @param secondAction The second dialog action to perform. Optional, `null` by default.
|
||||
* Performing the second action always dismisses the dialog.
|
||||
* @param isDismissable If `false` then dialog can not be dismissed by back button click or by outside click.
|
||||
* @param dismissOnFirstAction If `true` then dialog is dismissed when first action is performed,
|
||||
* ignoring lambda passed to [EventMessageAction.onClick].
|
||||
* `true` by default.
|
||||
* @param onDismissRequest The action to perform when the dialog is dismissed.
|
||||
* */
|
||||
data class DialogMessage(
|
||||
val message: TextReference,
|
||||
val title: TextReference? = null,
|
||||
val firstAction: EventMessageAction,
|
||||
val secondAction: EventMessageAction? = null,
|
||||
val isDismissable: Boolean = true,
|
||||
val dismissOnFirstAction: Boolean = true,
|
||||
val onDismissRequest: () -> Unit = {},
|
||||
) : EventMessage {
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Builder for [DialogMessage].
|
||||
*
|
||||
* @param message The message to show.
|
||||
* @param title The title of the dialog. Optional, `null` by default.
|
||||
* @param isDismissable If `false` then dialog can not be dismissed by back button click or by outside click.
|
||||
* `true` by default.
|
||||
* @param dismissOnFirstAction If `true` then dialog is dismissed when first action is performed,
|
||||
* ignoring lambda passed to [EventMessageAction.onClick].
|
||||
* `true` by default.
|
||||
* @param onDismissRequest The action to perform when the dialog is dismissed.
|
||||
* @param firstActionBuilder The builder for the first action.
|
||||
* By default, it builds an action with title "OK".
|
||||
* @param secondActionBuilder The builder for the second action. Optional, `null` by default.
|
||||
* Performing the second action always dismisses the dialog.
|
||||
*
|
||||
* @return [DialogMessage] with the specified parameters.
|
||||
* */
|
||||
operator fun invoke(
|
||||
message: TextReference,
|
||||
title: TextReference? = null,
|
||||
isDismissable: Boolean = true,
|
||||
dismissOnFirstAction: Boolean = true,
|
||||
onDismissRequest: () -> Unit = {},
|
||||
firstActionBuilder: EventMessageAction.BuilderScope.() -> EventMessageAction = { okAction() },
|
||||
secondActionBuilder: (EventMessageAction.BuilderScope.() -> EventMessageAction)? = null,
|
||||
): DialogMessage {
|
||||
val buttonsScope = EventMessageAction.BuilderScope(onDismissRequest)
|
||||
|
||||
return DialogMessage(
|
||||
message = message,
|
||||
title = title,
|
||||
isDismissable = isDismissable,
|
||||
dismissOnFirstAction = dismissOnFirstAction,
|
||||
onDismissRequest = onDismissRequest,
|
||||
firstAction = firstActionBuilder(buttonsScope),
|
||||
secondAction = secondActionBuilder?.invoke(buttonsScope),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a bottom sheet.
|
||||
*
|
||||
* @param iconResId The icon to show in the bottom sheet.
|
||||
* Optional, `null` by default.
|
||||
* @param title The title of the bottom sheet. Optional, `null` by default.
|
||||
* @param message The message to show in the bottom sheet.
|
||||
* @param firstAction The first action to perform. Optional, `null` by default.
|
||||
* @param secondAction The second action to perform. Optional, `null` by default.
|
||||
* @param onDismissRequest The action to perform when the bottom sheet is dismissed.
|
||||
* */
|
||||
data class BottomSheetMessage(
|
||||
@DrawableRes val iconResId: Int? = null,
|
||||
val title: TextReference? = null,
|
||||
val message: TextReference,
|
||||
val firstAction: EventMessageAction? = null,
|
||||
val secondAction: EventMessageAction? = null,
|
||||
val onDismissRequest: () -> Unit = {},
|
||||
) : EventMessage {
|
||||
|
||||
companion object {
|
||||
|
||||
/**
|
||||
* Builder for [BottomSheetMessage].
|
||||
*
|
||||
* @param iconResId The icon to show in the bottom sheet. Optional, `null` by default.
|
||||
* @param title The title of the bottom sheet. Optional, `null` by default.
|
||||
* @param message The message to show in the bottom sheet.
|
||||
* @param onDismissRequest The action to perform when the bottom sheet is dismissed.
|
||||
* @param firstActionBuilder The builder for the first action. Optional, `null` by default.
|
||||
* @param secondActionBuilder The builder for the second action. Optional, `null` by default.
|
||||
* */
|
||||
operator fun invoke(
|
||||
@DrawableRes iconResId: Int?,
|
||||
title: TextReference?,
|
||||
message: TextReference,
|
||||
onDismissRequest: () -> Unit = {},
|
||||
firstActionBuilder: (EventMessageAction.BuilderScope.() -> EventMessageAction)? = null,
|
||||
secondActionBuilder: (EventMessageAction.BuilderScope.() -> EventMessageAction)? = null,
|
||||
): BottomSheetMessage {
|
||||
val buttonsScope = EventMessageAction.BuilderScope(onDismissRequest)
|
||||
|
||||
return BottomSheetMessage(
|
||||
iconResId = iconResId,
|
||||
title = title,
|
||||
message = message,
|
||||
onDismissRequest = onDismissRequest,
|
||||
firstAction = firstActionBuilder?.invoke(buttonsScope),
|
||||
secondAction = secondActionBuilder?.invoke(buttonsScope),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents an action button in the dialog.
|
||||
*
|
||||
* @param title The title of the action.
|
||||
* @param warning If `true` then the action is highlighted as a warning.
|
||||
* @param enabled If `false` then the action is disabled.
|
||||
* @param onClick The action to perform when the button is clicked.
|
||||
* */
|
||||
data class EventMessageAction(
|
||||
val title: TextReference,
|
||||
val warning: Boolean = false,
|
||||
val enabled: Boolean = true,
|
||||
val onClick: () -> Unit,
|
||||
) {
|
||||
|
||||
/**
|
||||
* Scope for building buttons for the message.
|
||||
*
|
||||
* @param onDismissRequest The action to perform when the dialog is dismissed.
|
||||
* */
|
||||
class BuilderScope internal constructor(val onDismissRequest: () -> Unit) {
|
||||
|
||||
/**
|
||||
* Builds an action with title "OK".
|
||||
*
|
||||
* @param onClick The action to perform when the button is clicked. By default, it dismisses the message.
|
||||
* */
|
||||
fun okAction(onClick: () -> Unit = onDismissRequest) = EventMessageAction(
|
||||
title = resourceReference(id = R.string.common_ok),
|
||||
onClick = onClick,
|
||||
)
|
||||
|
||||
/**
|
||||
* Builds an action with title "Cancel".
|
||||
*
|
||||
* @param onClick The action to perform when the button is clicked. By default, it dismisses the message.
|
||||
* */
|
||||
fun cancelAction(onClick: () -> Unit = onDismissRequest) = EventMessageAction(
|
||||
title = resourceReference(id = R.string.common_cancel),
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,26 +1,49 @@
|
|||
package com.tangem.core.ui.message
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.material3.SnackbarDuration
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.SnackbarResult
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.tangem.core.ui.components.BasicDialog
|
||||
import com.tangem.core.ui.components.DialogButtonUM
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.message.MessageBottomSheetUM
|
||||
import com.tangem.core.ui.event.EventEffect
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.LocalEventMessageHandler
|
||||
import com.tangem.core.ui.res.LocalSnackbarHostState
|
||||
|
||||
@Composable
|
||||
fun EventMessageEffect(messageHandler: EventMessageHandler, snackbarHostState: SnackbarHostState) {
|
||||
fun EventMessageEffect(
|
||||
messageHandler: EventMessageHandler = LocalEventMessageHandler.current,
|
||||
snackbarHostState: SnackbarHostState = LocalSnackbarHostState.current,
|
||||
onShowSnackbar: suspend (SnackbarMessage, Context) -> Unit = { message, context ->
|
||||
showSnackbar(snackbarHostState, message, context)
|
||||
},
|
||||
) {
|
||||
val messageEvent by messageHandler.collectAsState()
|
||||
val context = LocalContext.current
|
||||
|
||||
var contentMessage: ContentMessage? by remember { mutableStateOf(value = null) }
|
||||
var dialogMessage: DialogMessage? by remember { mutableStateOf(value = null) }
|
||||
var bottomSheetMessage: BottomSheetMessage? by remember { mutableStateOf(value = null) }
|
||||
|
||||
EventEffect(event = messageEvent) { message ->
|
||||
when (message) {
|
||||
is SnackbarMessage -> {
|
||||
onShowSnackbar(message, context)
|
||||
}
|
||||
is ContentMessage -> {
|
||||
contentMessage = message
|
||||
}
|
||||
is SnackbarMessage -> {
|
||||
showSnackbar(snackbarHostState, message, context)
|
||||
is DialogMessage -> {
|
||||
dialogMessage = message
|
||||
}
|
||||
is BottomSheetMessage -> {
|
||||
bottomSheetMessage = message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -28,16 +51,110 @@ fun EventMessageEffect(messageHandler: EventMessageHandler, snackbarHostState: S
|
|||
contentMessage?.content?.invoke(
|
||||
onDismiss = { contentMessage = null },
|
||||
)
|
||||
|
||||
dialogMessage?.let { message ->
|
||||
MessageDialog(
|
||||
message = message,
|
||||
onDismissRequest = {
|
||||
dialogMessage = null
|
||||
message.onDismissRequest()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
bottomSheetMessage?.let { message ->
|
||||
MessageBottomSheet(
|
||||
message = message,
|
||||
onDismissRequest = {
|
||||
bottomSheetMessage = null
|
||||
message.onDismissRequest()
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MessageBottomSheet(message: BottomSheetMessage, onDismissRequest: () -> Unit) {
|
||||
val config = TangemBottomSheetConfig(
|
||||
isShow = true,
|
||||
content = MessageBottomSheetUM(
|
||||
iconResId = message.iconResId,
|
||||
title = message.title,
|
||||
message = message.message,
|
||||
primaryAction = message.firstAction?.let { action ->
|
||||
MessageBottomSheetUM.ActionUM(
|
||||
text = action.title,
|
||||
enabled = action.enabled,
|
||||
onClick = {
|
||||
action.onClick()
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
},
|
||||
secondaryAction = message.secondAction?.let { action ->
|
||||
MessageBottomSheetUM.ActionUM(
|
||||
text = action.title,
|
||||
enabled = action.enabled,
|
||||
onClick = {
|
||||
action.onClick()
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
},
|
||||
),
|
||||
onDismissRequest = onDismissRequest,
|
||||
)
|
||||
|
||||
MessageBottomSheet(config)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MessageDialog(message: DialogMessage, onDismissRequest: () -> Unit) {
|
||||
BasicDialog(
|
||||
message = message.message.resolveReference(),
|
||||
title = message.title?.resolveReference(),
|
||||
confirmButton = message.firstAction.let { action ->
|
||||
DialogButtonUM(
|
||||
title = action.title.resolveReference(),
|
||||
warning = action.warning,
|
||||
enabled = action.enabled,
|
||||
onClick = {
|
||||
action.onClick()
|
||||
|
||||
if (message.dismissOnFirstAction) {
|
||||
onDismissRequest()
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
dismissButton = message.secondAction?.let { action ->
|
||||
DialogButtonUM(
|
||||
title = action.title.resolveReference(),
|
||||
warning = action.warning,
|
||||
enabled = action.enabled,
|
||||
onClick = {
|
||||
action.onClick()
|
||||
onDismissRequest()
|
||||
},
|
||||
)
|
||||
},
|
||||
onDismissDialog = onDismissRequest,
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun showSnackbar(snackbarHostState: SnackbarHostState, message: SnackbarMessage, context: Context) {
|
||||
val result = snackbarHostState.showSnackbar(
|
||||
message = message.message.resolveReference(context.resources),
|
||||
actionLabel = message.actionLabel?.resolveReference(context.resources),
|
||||
duration = message.duration,
|
||||
duration = when (message.duration) {
|
||||
SnackbarMessage.Duration.Short -> SnackbarDuration.Short
|
||||
SnackbarMessage.Duration.Long -> SnackbarDuration.Long
|
||||
SnackbarMessage.Duration.Indefinite -> SnackbarDuration.Indefinite
|
||||
},
|
||||
)
|
||||
|
||||
if (result == SnackbarResult.ActionPerformed) {
|
||||
message.action?.invoke()
|
||||
when (result) {
|
||||
SnackbarResult.Dismissed -> message.onDismissRequest()
|
||||
SnackbarResult.ActionPerformed -> message.action?.invoke()
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import com.tangem.core.ui.components.TangemShimmer
|
|||
import com.tangem.core.ui.haptic.DefaultHapticManager
|
||||
import com.tangem.core.ui.haptic.HapticManager
|
||||
import com.tangem.core.ui.haptic.VibratorHapticManager
|
||||
import com.tangem.core.ui.message.EventMessageHandler
|
||||
import com.tangem.core.ui.windowsize.WindowSize
|
||||
import com.tangem.core.ui.windowsize.rememberWindowSize
|
||||
import com.tangem.domain.apptheme.model.AppThemeMode
|
||||
|
|
@ -39,6 +40,7 @@ fun TangemTheme(
|
|||
windowSize = windowSize,
|
||||
vibratorHapticManager = uiDependencies.vibratorHapticManager,
|
||||
snackbarHostState = uiDependencies.globalSnackbarHostState,
|
||||
eventMessageHandler = uiDependencies.eventMessageHandler,
|
||||
overrideSystemBarColors = overrideSystemBarColors,
|
||||
typography = typography,
|
||||
dimens = dimens,
|
||||
|
|
@ -53,6 +55,7 @@ fun TangemTheme(
|
|||
typography: TangemTypography = TangemTheme.typography,
|
||||
dimens: TangemDimens = TangemTheme.dimens,
|
||||
vibratorHapticManager: VibratorHapticManager? = null,
|
||||
eventMessageHandler: EventMessageHandler = remember { EventMessageHandler() },
|
||||
snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },
|
||||
overrideSystemBarColors: Boolean = true,
|
||||
content: @Composable () -> Unit,
|
||||
|
|
@ -93,6 +96,7 @@ fun TangemTheme(
|
|||
LocalIsInDarkTheme provides isDark,
|
||||
LocalHapticManager provides hapticManager,
|
||||
LocalSnackbarHostState provides snackbarHostState,
|
||||
LocalEventMessageHandler provides eventMessageHandler,
|
||||
LocalWindowSize provides windowSize,
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
|
|
@ -285,6 +289,10 @@ val LocalSnackbarHostState = staticCompositionLocalOf<SnackbarHostState> {
|
|||
error("No SnackbarHostState provided")
|
||||
}
|
||||
|
||||
val LocalEventMessageHandler = staticCompositionLocalOf<EventMessageHandler> {
|
||||
error("No EventMessageHandler provided")
|
||||
}
|
||||
|
||||
val LocalWindowSize = staticCompositionLocalOf<WindowSize> {
|
||||
error("No WindowSize provided")
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue