From cf1649a6af76adc888e9a0aa559a6dae52dfd745 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 12 Jun 2024 11:06:13 +0930 Subject: [PATCH] Refactor copy button --- .../newmessage/NewMessageFragment.kt | 2 +- .../start/InviteFriendFragment.kt | 14 ++-- .../RecoveryPasswordActivity.kt | 18 ++--- .../securesms/preferences/SettingsActivity.kt | 15 ++--- .../org/thoughtcrime/securesms/ui/Themes.kt | 1 + .../securesms/ui/components/Button.kt | 66 ++++++++++++++++--- .../securesms/ui/components/Text.kt | 43 ++++++++++++ 7 files changed, 118 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/newmessage/NewMessageFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/newmessage/NewMessageFragment.kt index 0f1a279286..3317b74bf8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/newmessage/NewMessageFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/newmessage/NewMessageFragment.kt @@ -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() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/InviteFriendFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/InviteFriendFragment.kt index 79f6dc4776..ac91bb6592 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/InviteFriendFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/InviteFriendFragment.kt @@ -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 - ) - } + ) } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/recoverypassword/RecoveryPasswordActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/recoverypassword/RecoveryPasswordActivity.kt index b0a2a48e7e..768dd21d07 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/recoverypassword/RecoveryPasswordActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/recoverypassword/RecoveryPasswordActivity.kt @@ -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 }, ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt index ee36ea82c4..82e4b97349 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt @@ -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)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/Themes.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/Themes.kt index a90e2fc0dc..7cacc8a004 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/Themes.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/Themes.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt index 985d657bf5..8eeac15687 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt @@ -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), diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt index be4c6c0209..84a8ae3e03 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt @@ -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 + ) +}