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 ce387b38f7..16ca590cf1 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 @@ -58,6 +58,7 @@ import org.thoughtcrime.securesms.ui.components.AppBar import org.thoughtcrime.securesms.ui.components.BorderlessButtonWithIcon import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode import org.thoughtcrime.securesms.ui.components.OutlineButton +import org.thoughtcrime.securesms.ui.components.SessionButtonText import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField import org.thoughtcrime.securesms.ui.components.SessionTabRow import org.thoughtcrime.securesms.ui.contentDescription @@ -165,7 +166,7 @@ fun EnterAccountId( error = state.error?.string(), ) if (state.error == null) { - BorderlessButtonWithIcon( + BorderlessButtonSecondary( text = stringResource(R.string.messageNewDescription), iconRes = R.drawable.ic_circle_question_mark, contentColor = classicDarkColors[5], @@ -185,10 +186,7 @@ fun EnterAccountId( onClick = { callbacks.onContinue() } ) { LoadingArcOr(state.loading) { - Text( - stringResource(R.string.next), - style = MaterialTheme.typography.baseBold - ) + SessionButtonText(stringResource(R.string.next)) } } } 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 ac91bb6592..fb36b2d90f 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 @@ -34,13 +34,11 @@ import org.thoughtcrime.securesms.preferences.copyPublicKey import org.thoughtcrime.securesms.preferences.sendInvitationToUseSession import org.thoughtcrime.securesms.ui.AppTheme import org.thoughtcrime.securesms.ui.base -import org.thoughtcrime.securesms.ui.baseBold 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 import org.thoughtcrime.securesms.ui.small @@ -122,13 +120,9 @@ private fun InviteFriend( modifier = Modifier .weight(1f) .contentDescription("Share button"), + text = stringResource(R.string.share), onClick = sendInvitation - ) { - Text( - stringResource(R.string.share), - style = MaterialTheme.typography.baseBold - ) - } + ) OutlineCopyButton( modifier = Modifier.weight(1f), diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt index 9390f60d5f..7cbd0f168c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt @@ -78,6 +78,7 @@ import org.thoughtcrime.securesms.ui.baseBold import org.thoughtcrime.securesms.ui.baseMonospace import org.thoughtcrime.securesms.ui.blackAlpha40 import org.thoughtcrime.securesms.ui.colorDestructive +import org.thoughtcrime.securesms.ui.components.SessionButtonText import org.thoughtcrime.securesms.ui.destructiveButtonColors import javax.inject.Inject @@ -400,15 +401,7 @@ fun TitledText( @Composable fun TitledView(title: GetString, modifier: Modifier = Modifier, content: @Composable () -> Unit) { Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(4.dp)) { - Title(title) + SessionButtonText(text = title.string()) content() } } - -@Composable -fun Title(title: GetString) { - Text( - title.string(), - style = MaterialTheme.typography.baseBold - ) -} 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 af2ba71974..e27e3e6d7b 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 @@ -2,15 +2,19 @@ package org.thoughtcrime.securesms.ui.components import androidx.annotation.DrawableRes import androidx.annotation.StringRes -import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.Crossfade import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.PressInteraction +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.wrapContentHeight -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ButtonDefaults import androidx.compose.material.ContentAlpha import androidx.compose.material.Icon @@ -25,6 +29,7 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource @@ -43,7 +48,6 @@ import org.thoughtcrime.securesms.ui.baseBold import org.thoughtcrime.securesms.ui.colorDestructive import org.thoughtcrime.securesms.ui.contentDescription import org.thoughtcrime.securesms.ui.extraSmall -import kotlin.time.Duration.Companion.seconds val LocalButtonSize = staticCompositionLocalOf { mediumButton } @@ -53,6 +57,18 @@ fun Modifier.applyButtonSize() = then(LocalButtonSize.current) val mediumButton = Modifier.height(41.dp) val smallButton = Modifier.wrapContentHeight() +@Composable +fun SessionButtonText( + text: String, + modifier: Modifier = Modifier +){ + Text( + modifier = modifier, + text = text, + style = MaterialTheme.typography.baseBold + ) +} + @Composable fun OutlineButton( @StringRes textId: Int, @@ -69,7 +85,9 @@ fun OutlineButton( OutlineButton( modifier = modifier, onClick = onClick - ) { Text(text, style = MaterialTheme.typography.baseBold) } + ) { + SessionButtonText(text = text) + } } @Composable @@ -98,64 +116,68 @@ 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 - ) -} + val interactionSource = remember { MutableInteractionSource() } -@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 + OutlineButton( + modifier = modifier, + interactionSource = interactionSource, + onClick = onClick + ) { + TemporaryClickedContent( + interactionSource = interactionSource, + content = { + // using a centered box because the outline button uses rowscope internally and it shows the crossfade + Box( + modifier = Modifier.fillMaxWidth() + ) { + SessionButtonText( + modifier = Modifier.align(Alignment.Center), + text = stringResource(R.string.copy) + ) + } + }, + temporaryContent = { + // using a centered box because the outline button uses rowscope internally and it shows the crossfade + Box( + modifier = Modifier.fillMaxWidth() + ) { + SessionButtonText( + modifier = Modifier.align(Alignment.Center), + text = stringResource(R.string.copied) + ) + } + } ) } } @Composable -fun OutlineTemporaryStateButton( +fun TemporaryClickedContent( modifier: Modifier = Modifier, - onClick: () -> Unit = {}, - content: @Composable (Boolean) -> Unit, + interactionSource: MutableInteractionSource, + content: @Composable () -> Unit, + temporaryContent: @Composable () -> Unit, + temporaryDelay: Long = 2000 ) { - TemporaryStateButton { source, isTemporary -> - OutlineButton( - modifier = modifier, - interactionSource = source, - onClick = onClick, - ) { - AnimatedVisibility(isTemporary) { content(true) } - AnimatedVisibility(!isTemporary) { content(false) } - } - } -} - -@Composable -fun TemporaryStateButton( - content: @Composable (MutableInteractionSource, Boolean) -> Unit, -) { - val interactions = remember { MutableInteractionSource() } - var clicked by remember { mutableStateOf(false) } - content(interactions, clicked) - LaunchedEffectAsync { - interactions.releases.collectLatest { + interactionSource.releases.collectLatest { clicked = true - delay(2.seconds) + delay(temporaryDelay) clicked = false } } + + Crossfade( + modifier = modifier, + targetState = clicked + ) { + when(it) { + false -> content() + true -> temporaryContent() + } + } } @Composable @@ -172,7 +194,7 @@ fun FilledButton( backgroundColor = LocalButtonColor.current ) ) { - Text(text = text, style = MaterialTheme.typography.baseBold) + SessionButtonText(text) } } @@ -190,32 +212,6 @@ fun BorderlessButtonSecondary( ) } -@Composable -fun BorderlessButton( - text: String, - modifier: Modifier = Modifier, - contentDescription: GetString = GetString(text), - contentColor: Color = MaterialTheme.colors.onBackground, - backgroundColor: Color = Color.Transparent, - onClick: () -> Unit -) { - TextButton( - onClick = onClick, - modifier = modifier.contentDescription(contentDescription), - colors = ButtonDefaults.outlinedButtonColors( - contentColor = contentColor, - backgroundColor = backgroundColor - ) - ) { - Text( - text = text, - textAlign = TextAlign.Center, - style = MaterialTheme.typography.extraSmall, - modifier = Modifier.padding(horizontal = 2.dp) - ) - } -} - @Composable fun BorderlessButton( modifier: Modifier = Modifier, @@ -234,6 +230,30 @@ fun BorderlessButton( ) { content() } } +@Composable +fun BorderlessButton( + text: String, + modifier: Modifier = Modifier, + contentDescription: GetString = GetString(text), + contentColor: Color = MaterialTheme.colors.onBackground, + backgroundColor: Color = Color.Transparent, + onClick: () -> Unit +) { + BorderlessButton( + modifier = modifier.contentDescription(contentDescription), + contentColor = contentColor, + backgroundColor = backgroundColor, + onClick = onClick + ) { + Text( + text = text, + textAlign = TextAlign.Center, + style = MaterialTheme.typography.extraSmall, + modifier = Modifier.padding(horizontal = 2.dp) + ) + } +} + @Composable fun BorderlessButtonWithIcon( text: String,