Refactor copy button

This commit is contained in:
Andrew 2024-06-12 11:06:13 +09:30
parent 48febb4f10
commit cf1649a6af
7 changed files with 118 additions and 41 deletions

View File

@ -161,7 +161,7 @@ fun EnterAccountId(
error = state.error?.string(),
)
if (state.error == null) {
BorderlessButtonSecondary(
BorderlessButtonWithIcon(
text = stringResource(R.string.messageNewDescription),
modifier = Modifier.contentDescription(R.string.AccessibilityId_help_desk_link)
) { onHelp() }

View File

@ -39,6 +39,7 @@ import org.thoughtcrime.securesms.ui.classicDarkColors
import org.thoughtcrime.securesms.ui.components.AppBar
import org.thoughtcrime.securesms.ui.components.OnPrimaryButtons
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.OutlineCopyButton
import org.thoughtcrime.securesms.ui.components.OutlineTemporaryStateButton
import org.thoughtcrime.securesms.ui.components.SmallButtons
import org.thoughtcrime.securesms.ui.contentDescription
@ -129,17 +130,10 @@ private fun InviteFriend(
)
}
OutlineTemporaryStateButton(
Modifier
.weight(1f)
.contentDescription(R.string.AccessibilityId_copy_button),
OutlineCopyButton(
modifier = Modifier.weight(1f),
onClick = copyPublicKey
) { isTemporary ->
Text(
stringResource(if (isTemporary) R.string.copied else R.string.copy),
style = MaterialTheme.typography.baseBold
)
}
)
}
}
}

View File

@ -40,16 +40,15 @@ import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionShieldIcon
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.baseBold
import org.thoughtcrime.securesms.ui.classicDarkColors
import org.thoughtcrime.securesms.ui.components.DestructiveButtons
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.OutlineTemporaryStateButton
import org.thoughtcrime.securesms.ui.components.OutlineCopyButton
import org.thoughtcrime.securesms.ui.components.QrImage
import org.thoughtcrime.securesms.ui.components.SmallButtons
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.extraSmallMonospace
import org.thoughtcrime.securesms.ui.h8
import org.thoughtcrime.securesms.ui.smallMonospace
class RecoveryPasswordActivity : BaseActionBarActivity() {
@ -168,18 +167,13 @@ fun RecoveryPasswordCell(seed: String, copySeed:() -> Unit = {}) {
}
AnimatedVisibility(!showQr) {
Row(horizontalArrangement = Arrangement.spacedBy(32.dp)) {
OutlineTemporaryStateButton(
Row(horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.marginMedium)) {
OutlineCopyButton(
Modifier
.weight(1f)
.contentDescription(R.string.AccessibilityId_copy_button),
onClick = copySeed
) { isTemporary ->
Text(
stringResource( if (isTemporary) R.string.copied else R.string.copy),
style = MaterialTheme.typography.baseBold
)
}
)
OutlineButton(
textId = R.string.qrView,
modifier = Modifier.weight(1f),
@ -212,7 +206,7 @@ private fun RecoveryPassword(seed: String) {
)
.padding(LocalDimensions.current.marginSmall),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.smallMonospace,
style = MaterialTheme.typography.extraSmallMonospace,
color = MaterialTheme.colors.run { if (isLight) onSurface else secondary },
)
}

View File

@ -82,6 +82,7 @@ import org.thoughtcrime.securesms.ui.ItemButton
import org.thoughtcrime.securesms.ui.ItemButtonWithDrawable
import org.thoughtcrime.securesms.ui.baseBold
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.OutlineCopyButton
import org.thoughtcrime.securesms.ui.components.OutlineTemporaryStateButton
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.destructiveButtonColors
@ -401,16 +402,10 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
onClick = { sendInvitationToUseSession() }
)
OutlineTemporaryStateButton(
modifier = Modifier.weight(1f)
.contentDescription(R.string.AccessibilityId_copy_button),
onClick = { copyPublicKey() },
) { isTemporary ->
Text(
stringResource(if (isTemporary) R.string.copied else R.string.copy),
style = MaterialTheme.typography.baseBold
)
}
OutlineCopyButton(
modifier = Modifier.weight(1f),
onClick = ::copyPublicKey,
)
}
Spacer(modifier = Modifier.height(24.dp))

View File

@ -145,6 +145,7 @@ val Typography.baseMonospace get() = defaultStyle(14.sp).copy(fontFamily = FontF
val Typography.small get() = defaultStyle(12.sp)
val Typography.smallMonospace get() = defaultStyle(12.sp).copy(fontFamily = FontFamily.Monospace)
val Typography.extraSmall get() = defaultStyle(11.sp)
val Typography.extraSmallMonospace get() = defaultStyle(11.sp).copy(fontFamily = FontFamily.Monospace)
val Typography.fine get() = defaultStyle(9.sp)
val Typography.h7 get() = boldStyle(18.sp)

View File

@ -49,14 +49,20 @@ val mediumButton = Modifier.height(41.dp)
val smallButton = Modifier.wrapContentHeight()
@Composable
fun OutlineButton(@StringRes textId: Int, modifier: Modifier = Modifier, onClick: () -> Unit) {
OutlineButton(stringResource(textId), modifier, onClick)
}
fun OutlineButton(
@StringRes textId: Int,
modifier: Modifier = Modifier,
onClick: () -> Unit
) { OutlineButton(stringResource(textId), modifier, onClick) }
@Composable
fun OutlineButton(text: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
fun OutlineButton(
text: String,
modifier: Modifier = Modifier,
onClick: () -> Unit
) {
OutlineButton(
modifier.contentDescription(text),
modifier = modifier,
onClick = onClick
) { Text(text, style = MaterialTheme.typography.baseBold) }
}
@ -82,6 +88,34 @@ fun OutlineButton(
}
}
@Composable
fun OutlineCopyButton(
modifier: Modifier = Modifier,
onClick: () -> Unit = {}
) {
OutlineTemporaryStateButton(
text = stringResource(R.string.copy),
temporaryText = stringResource(R.string.copy),
modifier = modifier.contentDescription(R.string.AccessibilityId_copy_button),
onClick = onClick
)
}
@Composable
fun OutlineTemporaryStateButton(
text: String,
temporaryText: String,
modifier: Modifier = Modifier,
onClick: () -> Unit = {}
) {
OutlineTemporaryStateButton(modifier, onClick) { isTemporary ->
Text(
if (isTemporary) temporaryText else text,
style = MaterialTheme.typography.baseBold
)
}
}
@Composable
fun OutlineTemporaryStateButton(
modifier: Modifier = Modifier,
@ -178,12 +212,12 @@ fun BorderlessButton(
}
@Composable
fun BorderlessHtmlButton(
textId: Int,
fun BorderlessButton(
modifier: Modifier = Modifier,
contentColor: Color = MaterialTheme.colors.onBackground,
backgroundColor: Color = Color.Transparent,
onClick: () -> Unit
onClick: () -> Unit,
content: @Composable () -> Unit
) {
TextButton(
onClick = onClick,
@ -192,6 +226,22 @@ fun BorderlessHtmlButton(
contentColor = contentColor,
backgroundColor = backgroundColor
)
) { content() }
}
@Composable
fun BorderlessHtmlButton(
textId: Int,
modifier: Modifier = Modifier,
contentColor: Color = MaterialTheme.colors.onBackground,
backgroundColor: Color = Color.Transparent,
onClick: () -> Unit
) {
BorderlessButton(
modifier,
contentColor = contentColor,
backgroundColor = backgroundColor,
onClick = onClick
) {
Text(
text = annotatedStringResource(textId),

View File

@ -3,15 +3,27 @@ package org.thoughtcrime.securesms.ui.components
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.baseBold
@ -60,3 +72,34 @@ fun SessionOutlinedTextField(
}
}
}
@Composable
fun AnnotatedTextWithIcon(
text: String,
icon: ImageVector,
modifier: Modifier = Modifier,
iconTint: Color = Color.Unspecified,
iconDescription: String = "",
iconSize: TextUnit = 12.sp,
textWidth: Dp = 100.dp
) {
val myId = "inlineContent"
val annotatedText = buildAnnotatedString {
append(text)
appendInlineContent(myId, "[icon]")
}
val inlineContent = mapOf(
myId to Placeholder(
width = iconSize,
height = iconSize,
placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline
).let { InlineTextContent(it) { Icon(icon, iconDescription, tint = iconTint) } }
)
Text(
text = annotatedText,
modifier = modifier.width(textWidth),
inlineContent = inlineContent
)
}