mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-18 23:58:26 +00:00
Organise and fix a few button colors
This commit is contained in:
parent
e44b401bd5
commit
f3d90e3adb
@ -118,7 +118,6 @@ private fun InviteFriend(
|
|||||||
|
|
||||||
SlimOutlineCopyButton(
|
SlimOutlineCopyButton(
|
||||||
modifier = Modifier.weight(1f),
|
modifier = Modifier.weight(1f),
|
||||||
color = LocalColors.current.text,
|
|
||||||
onClick = copyPublicKey
|
onClick = copyPublicKey
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -90,6 +90,8 @@ interface Colors {
|
|||||||
val qrCodeBackground: Color
|
val qrCodeBackground: Color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val Colors.slimOutlineButton: Color get() = text
|
||||||
|
|
||||||
fun sessionColors(
|
fun sessionColors(
|
||||||
isLight: Boolean,
|
isLight: Boolean,
|
||||||
isClassic: Boolean,
|
isClassic: Boolean,
|
||||||
|
@ -40,7 +40,6 @@ sealed class GetString {
|
|||||||
data class FromMap<T>(val value: T, val function: (Context, T) -> String): GetString() {
|
data class FromMap<T>(val value: T, val function: (Context, T) -> String): GetString() {
|
||||||
@Composable
|
@Composable
|
||||||
override fun string(): String = function(LocalContext.current, value)
|
override fun string(): String = function(LocalContext.current, value)
|
||||||
|
|
||||||
override fun string(context: Context): String = function(context, value)
|
override fun string(context: Context): String = function(context, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,28 +2,46 @@ package org.thoughtcrime.securesms.ui.components
|
|||||||
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
|
import androidx.compose.animation.fadeIn
|
||||||
|
import androidx.compose.animation.fadeOut
|
||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||||
import androidx.compose.foundation.interaction.PressInteraction
|
import androidx.compose.foundation.interaction.PressInteraction
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.RowScope
|
||||||
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
|
import androidx.compose.material.ButtonColors
|
||||||
import androidx.compose.material.ButtonDefaults
|
import androidx.compose.material.ButtonDefaults
|
||||||
|
import androidx.compose.material.ButtonElevation
|
||||||
|
import androidx.compose.material.MaterialTheme
|
||||||
import androidx.compose.material.RadioButton
|
import androidx.compose.material.RadioButton
|
||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextButton
|
import androidx.compose.material.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.Shape
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.collectLatest
|
||||||
import kotlinx.coroutines.flow.filter
|
import kotlinx.coroutines.flow.filter
|
||||||
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.ui.GetString
|
import org.thoughtcrime.securesms.ui.GetString
|
||||||
|
import org.thoughtcrime.securesms.ui.LaunchedEffectAsync
|
||||||
import org.thoughtcrime.securesms.ui.LocalColors
|
import org.thoughtcrime.securesms.ui.LocalColors
|
||||||
import org.thoughtcrime.securesms.ui.baseBold
|
import org.thoughtcrime.securesms.ui.baseBold
|
||||||
import org.thoughtcrime.securesms.ui.contentDescription
|
import org.thoughtcrime.securesms.ui.contentDescription
|
||||||
@ -31,7 +49,185 @@ import org.thoughtcrime.securesms.ui.extraSmall
|
|||||||
import org.thoughtcrime.securesms.ui.h8
|
import org.thoughtcrime.securesms.ui.h8
|
||||||
import org.thoughtcrime.securesms.ui.h9
|
import org.thoughtcrime.securesms.ui.h9
|
||||||
import org.thoughtcrime.securesms.ui.radioButtonColors
|
import org.thoughtcrime.securesms.ui.radioButtonColors
|
||||||
|
import org.thoughtcrime.securesms.ui.slimOutlineButton
|
||||||
import org.thoughtcrime.securesms.ui.small
|
import org.thoughtcrime.securesms.ui.small
|
||||||
|
import kotlin.time.Duration
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
|
interface ButtonType {
|
||||||
|
@Composable fun border(color: Color, enabled: Boolean): BorderStroke?
|
||||||
|
@Composable fun buttonColors(color: Color): ButtonColors
|
||||||
|
val elevation: ButtonElevation? @Composable get
|
||||||
|
|
||||||
|
object Outline: ButtonType {
|
||||||
|
@Composable override fun border(color: Color, enabled: Boolean) = BorderStroke(1.dp, if (enabled) color else LocalColors.current.disabled)
|
||||||
|
@Composable override fun buttonColors(color: Color) = ButtonDefaults.buttonColors(
|
||||||
|
contentColor = color,
|
||||||
|
backgroundColor = Color.Unspecified,
|
||||||
|
disabledContentColor = LocalColors.current.disabled,
|
||||||
|
disabledBackgroundColor = Color.Unspecified
|
||||||
|
)
|
||||||
|
override val elevation: ButtonElevation? @Composable get() = null
|
||||||
|
}
|
||||||
|
|
||||||
|
object Fill: ButtonType {
|
||||||
|
@Composable override fun border(color: Color, enabled: Boolean) = null
|
||||||
|
@Composable override fun buttonColors(color: Color) = ButtonDefaults.buttonColors(
|
||||||
|
contentColor = LocalColors.current.background,
|
||||||
|
backgroundColor = color,
|
||||||
|
disabledContentColor = LocalColors.current.disabled,
|
||||||
|
disabledBackgroundColor = Color.Unspecified
|
||||||
|
)
|
||||||
|
override val elevation: ButtonElevation @Composable get() = ButtonDefaults.elevation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base [Button] implementation
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun Button(
|
||||||
|
onClick: () -> Unit,
|
||||||
|
color: Color,
|
||||||
|
type: ButtonType,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
size: ButtonSize = ButtonSize.Large,
|
||||||
|
elevation: ButtonElevation? = type.elevation,
|
||||||
|
shape: Shape = MaterialTheme.shapes.small,
|
||||||
|
border: BorderStroke? = type.border(color, enabled),
|
||||||
|
colors: ButtonColors = type.buttonColors(color),
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
|
content: @Composable RowScope.() -> Unit
|
||||||
|
) {
|
||||||
|
size.applyConstraints {
|
||||||
|
androidx.compose.material.Button(
|
||||||
|
onClick,
|
||||||
|
modifier.heightIn(min = size.minHeight),
|
||||||
|
enabled,
|
||||||
|
interactionSource,
|
||||||
|
elevation,
|
||||||
|
shape,
|
||||||
|
border,
|
||||||
|
colors,
|
||||||
|
content = content
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Courtesy [Button] implementation for buttons that just display text.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun Button(
|
||||||
|
text: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
color: Color,
|
||||||
|
type: ButtonType,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
enabled: Boolean = true,
|
||||||
|
size: ButtonSize = ButtonSize.Large,
|
||||||
|
elevation: ButtonElevation? = type.elevation,
|
||||||
|
shape: Shape = MaterialTheme.shapes.small,
|
||||||
|
border: BorderStroke? = type.border(color, enabled),
|
||||||
|
colors: ButtonColors = type.buttonColors(color),
|
||||||
|
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||||
|
) {
|
||||||
|
Button(onClick, color, type, modifier, enabled, size, elevation, shape, border, colors, interactionSource) {
|
||||||
|
Text(text)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable fun FillButton(text: String, modifier: Modifier = Modifier, enabled: Boolean = true, onClick: () -> Unit) {
|
||||||
|
Button(text, onClick, LocalColors.current.buttonOutline, ButtonType.Fill, modifier, enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable fun PrimaryFillButton(text: String, modifier: Modifier = Modifier, enabled: Boolean = true, onClick: () -> Unit) {
|
||||||
|
Button(text, onClick, LocalColors.current.primary, ButtonType.Fill, modifier, enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable fun OutlineButton(text: String, modifier: Modifier = Modifier, color: Color = LocalColors.current.buttonOutline, enabled: Boolean = true, onClick: () -> Unit) {
|
||||||
|
Button(text, onClick, color, ButtonType.Outline, modifier, enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable fun PrimaryOutlineButton(text: String, modifier: Modifier = Modifier, enabled: Boolean = true, onClick: () -> Unit) {
|
||||||
|
Button(text, onClick, LocalColors.current.primary, ButtonType.Outline, modifier, enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable fun SlimOutlineButton(onClick: () -> Unit, modifier: Modifier = Modifier, color: Color = LocalColors.current.slimOutlineButton, enabled: Boolean = true, content: @Composable () -> Unit) {
|
||||||
|
Button(onClick, color, ButtonType.Outline, modifier, enabled, ButtonSize.Slim) { content() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Courtesy [SlimOutlineButton] implementation for buttons that just display text.
|
||||||
|
*/
|
||||||
|
@Composable fun SlimOutlineButton(text: String, modifier: Modifier = Modifier, color: Color = LocalColors.current.slimOutlineButton, enabled: Boolean = true, onClick: () -> Unit) {
|
||||||
|
Button(text, onClick, color, ButtonType.Outline, modifier, enabled, ButtonSize.Slim)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SlimOutlineCopyButton(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
color: Color = LocalColors.current.slimOutlineButton,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
OutlineCopyButton(modifier, ButtonSize.Slim, color, onClick)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun OutlineCopyButton(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
size: ButtonSize = ButtonSize.Large,
|
||||||
|
color: Color = LocalColors.current.buttonOutline,
|
||||||
|
onClick: () -> Unit
|
||||||
|
) {
|
||||||
|
val interactionSource = remember { MutableInteractionSource() }
|
||||||
|
|
||||||
|
Button(
|
||||||
|
modifier = modifier.contentDescription(R.string.AccessibilityId_copy_button),
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
size = size,
|
||||||
|
type = ButtonType.Outline,
|
||||||
|
color = color,
|
||||||
|
onClick = onClick
|
||||||
|
) {
|
||||||
|
TemporaryClickedContent(
|
||||||
|
interactionSource = interactionSource,
|
||||||
|
content = { Text(stringResource(R.string.copy)) },
|
||||||
|
temporaryContent = { Text(stringResource(R.string.copied)) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TemporaryClickedContent(
|
||||||
|
interactionSource: MutableInteractionSource,
|
||||||
|
content: @Composable () -> Unit,
|
||||||
|
temporaryContent: @Composable () -> Unit,
|
||||||
|
temporaryDelay: Duration = 2.seconds
|
||||||
|
) {
|
||||||
|
var clicked by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
LaunchedEffectAsync {
|
||||||
|
interactionSource.releases.collectLatest {
|
||||||
|
clicked = true
|
||||||
|
delay(temporaryDelay)
|
||||||
|
clicked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Using a Box because the Buttons add children in a Row
|
||||||
|
// and they will jank as they are added and removed.
|
||||||
|
Box(contentAlignment = Alignment.Center) {
|
||||||
|
AnimatedVisibility(!clicked, enter = fadeIn(), exit = fadeOut()) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
AnimatedVisibility(clicked, enter = fadeIn(), exit = fadeOut()) {
|
||||||
|
temporaryContent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun BorderlessButton(
|
fun BorderlessButton(
|
||||||
|
@ -6,7 +6,6 @@ import androidx.compose.material.LocalMinimumInteractiveComponentEnforcement
|
|||||||
import androidx.compose.material.LocalTextStyle
|
import androidx.compose.material.LocalTextStyle
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.text.TextStyle
|
import androidx.compose.ui.text.TextStyle
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
@ -27,14 +26,15 @@ interface ButtonSize {
|
|||||||
|
|
||||||
val textStyle: TextStyle @Composable get
|
val textStyle: TextStyle @Composable get
|
||||||
val minHeight: Dp
|
val minHeight: Dp
|
||||||
}
|
|
||||||
|
|
||||||
object LargeButtonSize: ButtonSize {
|
object Large: ButtonSize {
|
||||||
override val textStyle @Composable get() = baseBold
|
override val textStyle @Composable get() = baseBold
|
||||||
override val minHeight = 41.dp
|
override val minHeight = 41.dp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object Slim: ButtonSize {
|
||||||
|
override val textStyle @Composable get() = extraSmallBold
|
||||||
|
override val minHeight = 29.dp
|
||||||
|
}
|
||||||
|
|
||||||
object SlimButtonSize: ButtonSize {
|
|
||||||
override val textStyle @Composable get() = extraSmallBold
|
|
||||||
override val minHeight = 29.dp
|
|
||||||
}
|
}
|
||||||
|
@ -33,172 +33,3 @@ import org.thoughtcrime.securesms.ui.contentDescription
|
|||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
import kotlin.time.Duration.Companion.seconds
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
interface ButtonType {
|
|
||||||
@Composable fun border(color: Color, enabled: Boolean): BorderStroke?
|
|
||||||
@Composable fun buttonColors(color: Color): ButtonColors
|
|
||||||
val elevation: ButtonElevation? @Composable get
|
|
||||||
|
|
||||||
object Outline: ButtonType {
|
|
||||||
@Composable override fun border(color: Color, enabled: Boolean) = BorderStroke(1.dp, if (enabled) color else LocalColors.current.disabled)
|
|
||||||
@Composable override fun buttonColors(color: Color) = ButtonDefaults.buttonColors(
|
|
||||||
contentColor = color,
|
|
||||||
backgroundColor = Color.Unspecified,
|
|
||||||
disabledContentColor = LocalColors.current.disabled,
|
|
||||||
disabledBackgroundColor = Color.Unspecified
|
|
||||||
)
|
|
||||||
override val elevation: ButtonElevation? @Composable get() = null
|
|
||||||
}
|
|
||||||
object Fill: ButtonType {
|
|
||||||
@Composable override fun border(color: Color, enabled: Boolean) = null
|
|
||||||
@Composable override fun buttonColors(color: Color) = ButtonDefaults.buttonColors(
|
|
||||||
contentColor = LocalColors.current.background,
|
|
||||||
backgroundColor = color,
|
|
||||||
disabledContentColor = LocalColors.current.disabled,
|
|
||||||
disabledBackgroundColor = Color.Unspecified
|
|
||||||
)
|
|
||||||
override val elevation: ButtonElevation? @Composable get() = ButtonDefaults.elevation()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Base [Button] implementation
|
|
||||||
*/
|
|
||||||
@Composable
|
|
||||||
fun Button(
|
|
||||||
onClick: () -> Unit,
|
|
||||||
color: Color,
|
|
||||||
type: ButtonType,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
enabled: Boolean = true,
|
|
||||||
size: ButtonSize = LargeButtonSize,
|
|
||||||
elevation: ButtonElevation? = type.elevation,
|
|
||||||
shape: Shape = MaterialTheme.shapes.small,
|
|
||||||
border: BorderStroke? = type.border(color, enabled),
|
|
||||||
colors: ButtonColors = type.buttonColors(color),
|
|
||||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
|
||||||
content: @Composable RowScope.() -> Unit
|
|
||||||
) {
|
|
||||||
size.applyConstraints {
|
|
||||||
androidx.compose.material.Button(
|
|
||||||
onClick,
|
|
||||||
modifier.heightIn(min = size.minHeight),
|
|
||||||
enabled,
|
|
||||||
interactionSource,
|
|
||||||
elevation,
|
|
||||||
shape,
|
|
||||||
border,
|
|
||||||
colors,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Courtesy [Button] implementation
|
|
||||||
*/
|
|
||||||
@Composable
|
|
||||||
fun Button(
|
|
||||||
text: String,
|
|
||||||
onClick: () -> Unit,
|
|
||||||
color: Color,
|
|
||||||
type: ButtonType,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
enabled: Boolean = true,
|
|
||||||
size: ButtonSize = LargeButtonSize,
|
|
||||||
elevation: ButtonElevation? = type.elevation,
|
|
||||||
shape: Shape = MaterialTheme.shapes.small,
|
|
||||||
border: BorderStroke? = type.border(color, enabled),
|
|
||||||
colors: ButtonColors = type.buttonColors(color),
|
|
||||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
|
||||||
) {
|
|
||||||
Button(onClick, color, type, modifier, enabled, size, elevation, shape, border, colors, interactionSource) {
|
|
||||||
Text(text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable fun FillButton(text: String, modifier: Modifier = Modifier, enabled: Boolean = true, onClick: () -> Unit) {
|
|
||||||
Button(text, onClick, LocalColors.current.buttonOutline, ButtonType.Fill, modifier, enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable fun PrimaryFillButton(text: String, modifier: Modifier = Modifier, enabled: Boolean = true, onClick: () -> Unit) {
|
|
||||||
Button(text, onClick, LocalColors.current.primary, ButtonType.Fill, modifier, enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable fun OutlineButton(text: String, modifier: Modifier = Modifier, color: Color = LocalColors.current.buttonOutline, enabled: Boolean = true, onClick: () -> Unit) {
|
|
||||||
Button(text, onClick, color, ButtonType.Outline, modifier, enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable fun PrimaryOutlineButton(text: String, modifier: Modifier = Modifier, enabled: Boolean = true, onClick: () -> Unit) {
|
|
||||||
Button(text, onClick, LocalColors.current.primary, ButtonType.Outline, modifier, enabled)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable fun SlimOutlineButton(text: String, modifier: Modifier = Modifier, color: Color = LocalColors.current.buttonOutline, enabled: Boolean = true, onClick: () -> Unit) {
|
|
||||||
Button(text, onClick, color, ButtonType.Outline, modifier, enabled, SlimButtonSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable fun SlimOutlineButton(onClick: () -> Unit, modifier: Modifier = Modifier, color: Color = LocalColors.current.buttonOutline, enabled: Boolean = true, content: @Composable () -> Unit) {
|
|
||||||
Button(onClick, color, ButtonType.Outline, modifier, enabled, SlimButtonSize) { content() }
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SlimOutlineCopyButton(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
color: Color = LocalColors.current.buttonOutline,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
OutlineCopyButton(modifier, SlimButtonSize, color, onClick)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun OutlineCopyButton(
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
size: ButtonSize = LargeButtonSize,
|
|
||||||
color: Color = LocalColors.current.buttonOutline,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
val interactionSource = remember { MutableInteractionSource() }
|
|
||||||
|
|
||||||
Button(
|
|
||||||
modifier = modifier.contentDescription(R.string.AccessibilityId_copy_button),
|
|
||||||
interactionSource = interactionSource,
|
|
||||||
size = size,
|
|
||||||
type = ButtonType.Outline,
|
|
||||||
color = color,
|
|
||||||
onClick = onClick
|
|
||||||
) {
|
|
||||||
TemporaryClickedContent(
|
|
||||||
interactionSource = interactionSource,
|
|
||||||
content = { Text(stringResource(R.string.copy)) },
|
|
||||||
temporaryContent = { Text(stringResource(R.string.copied)) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun TemporaryClickedContent(
|
|
||||||
interactionSource: MutableInteractionSource,
|
|
||||||
content: @Composable () -> Unit,
|
|
||||||
temporaryContent: @Composable () -> Unit,
|
|
||||||
temporaryDelay: Duration = 2.seconds
|
|
||||||
) {
|
|
||||||
var clicked by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
LaunchedEffectAsync {
|
|
||||||
interactionSource.releases.collectLatest {
|
|
||||||
clicked = true
|
|
||||||
delay(temporaryDelay)
|
|
||||||
clicked = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Using a Box because the Buttons add children in a Row
|
|
||||||
// and they will jank as they are added and removed.
|
|
||||||
Box(contentAlignment = Alignment.Center) {
|
|
||||||
AnimatedVisibility(!clicked, enter = fadeIn(), exit = fadeOut()) {
|
|
||||||
content()
|
|
||||||
}
|
|
||||||
AnimatedVisibility(clicked, enter = fadeIn(), exit = fadeOut()) {
|
|
||||||
temporaryContent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user