Removes second dialog and adds learnmore.

This commit is contained in:
Alex Hart 2026-06-12 11:16:19 -03:00 committed by GitHub
parent c5efb2ce6c
commit 73f81075ce
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 57 additions and 92 deletions

View File

@ -157,7 +157,6 @@ fun MessageBackupsKeyRecordScreen(
val url = stringResource(R.string.recovery_key_phishing_support_url)
val events: (RecoveryKeyWarningSheetEvent) -> Unit = {
when (it) {
RecoveryKeyWarningSheetEvent.DoNotShareClick -> error("Not supported")
RecoveryKeyWarningSheetEvent.GotItClick -> {
onCopyToClipboardClick(backupKeyString)
displayRecoveryKeyCopyWarning = false
@ -167,7 +166,7 @@ fun MessageBackupsKeyRecordScreen(
displayRecoveryKeyCopyWarning = false
}
RecoveryKeyWarningSheetEvent.PasteKeyClick -> error("Not supported")
RecoveryKeyWarningSheetEvent.DoNotShareClick -> error("Not supported")
RecoveryKeyWarningSheetEvent.ShareKeyClick -> error("Not supported")
}
}

View File

@ -5,22 +5,16 @@
package org.thoughtcrime.securesms.backup.v2.ui.warning
import android.app.Dialog
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.rememberModalBottomSheetState
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.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.fragment.app.setFragmentResult
import org.signal.core.ui.compose.BottomSheets
import org.signal.core.ui.compose.ComposeFullScreenDialogFragment
import org.signal.core.ui.compose.ComposeBottomSheetDialogFragment
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.backup.v2.ui.warning.RecoveryKeyPasteWarningFragment.Companion.REQUEST_KEY
import org.thoughtcrime.securesms.util.CommunicationActions
/**
* Displayed via the [org.thoughtcrime.securesms.components.settings.conversation.ConversationSettingsFragment] whenever the user
@ -30,7 +24,7 @@ import org.signal.core.ui.compose.ComposeFullScreenDialogFragment
* indicating whether the user chose to proceed with the paste. The host can rely on this firing for
* every dismissal path (paste, decline, or cancel) to restore its own state.
*/
class RecoveryKeyPasteWarningFragment : ComposeFullScreenDialogFragment() {
class RecoveryKeyPasteWarningFragment : ComposeBottomSheetDialogFragment() {
companion object {
const val REQUEST_KEY = "recovery_key_request"
@ -38,13 +32,6 @@ class RecoveryKeyPasteWarningFragment : ComposeFullScreenDialogFragment() {
private var shouldPaste = false
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
window?.setWindowAnimations(0)
}
}
override fun onDismiss(dialog: DialogInterface) {
setFragmentResult(
REQUEST_KEY,
@ -56,10 +43,10 @@ class RecoveryKeyPasteWarningFragment : ComposeFullScreenDialogFragment() {
super.onDismiss(dialog)
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
override fun DialogContent() {
var isDisplayingFinalWarningDialog by remember { mutableStateOf(false) }
override fun SheetContent() {
val context = LocalContext.current
val url = stringResource(R.string.recovery_key_phishing_support_url)
val eventHandler: (RecoveryKeyWarningSheetEvent) -> Unit = {
when (it) {
@ -67,34 +54,25 @@ class RecoveryKeyPasteWarningFragment : ComposeFullScreenDialogFragment() {
dismissAllowingStateLoss()
}
RecoveryKeyWarningSheetEvent.GotItClick -> error("Not supported for paste")
RecoveryKeyWarningSheetEvent.LearnMoreClick -> error("Not supported for paste")
RecoveryKeyWarningSheetEvent.PasteKeyClick -> {
shouldPaste = true
RecoveryKeyWarningSheetEvent.GotItClick -> {
error("Not supported for paste")
}
RecoveryKeyWarningSheetEvent.LearnMoreClick -> {
CommunicationActions.openBrowserLink(context, url)
dismissAllowingStateLoss()
}
RecoveryKeyWarningSheetEvent.ShareKeyClick -> {
isDisplayingFinalWarningDialog = true
shouldPaste = true
dismissAllowingStateLoss()
}
}
}
if (isDisplayingFinalWarningDialog) {
RecoveryKeyWarningDialog(
events = eventHandler
)
} else {
ModalBottomSheet(
onDismissRequest = { dismissAllowingStateLoss() },
dragHandle = { BottomSheets.Handle() },
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
) {
RecoveryKeyWarningSheetContent(
clipStage = ClipStage.PASTE,
events = eventHandler
)
}
}
RecoveryKeyWarningSheetContent(
clipStage = ClipStage.PASTE,
events = eventHandler
)
}
}

View File

@ -12,6 +12,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
@ -22,16 +23,17 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.LinkAnnotation
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLinkStyles
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.withLink
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.unit.dp
import org.signal.core.ui.compose.Buttons
import org.signal.core.ui.compose.DayNightPreviews
import org.signal.core.ui.compose.Dialogs
import org.signal.core.ui.compose.Previews
import org.signal.core.ui.compose.horizontalGutters
import org.thoughtcrime.securesms.R
@ -64,17 +66,32 @@ fun RecoveryKeyWarningSheetContent(
modifier = Modifier.padding(bottom = 12.dp)
)
val signalWillNeverMessageYou = stringResource(R.string.RecoveryKeyWarningSheetContent__signal_will_never_message_you)
val recoveryKeyWarningBody = stringResource(R.string.RecoveryKeyWarningSheetContent__for_your_recovery_key_never_respond)
Text(
text = buildAnnotatedString {
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(signalWillNeverMessageYou)
append(stringResource(R.string.RecoveryKeyWarningSheetContent__signal_will_never_message_you))
}
append(" ")
append(recoveryKeyWarningBody)
append(stringResource(R.string.RecoveryKeyWarningSheetContent__for_your_recovery_key_never_respond))
if (clipStage == ClipStage.PASTE) {
append(" ")
withLink(
link = LinkAnnotation.Clickable(
tag = "learn-more",
styles = TextLinkStyles(
style = SpanStyle(
color = MaterialTheme.colorScheme.primary
)
)
) {
events(RecoveryKeyWarningSheetEvent.LearnMoreClick)
}
) {
append(stringResource(R.string.RecoveryKeyWarningSheetContent__learn_more_period))
}
}
},
textAlign = TextAlign.Center,
color = MaterialTheme.colorScheme.onSurfaceVariant,
@ -113,40 +130,18 @@ fun PasteActionButtons(events: (RecoveryKeyWarningSheetEvent) -> Unit) {
Text(text = stringResource(R.string.RecoveryKeyWarningSheetContent__do_not_share_key))
}
TextButton(onClick = {
events(RecoveryKeyWarningSheetEvent.ShareKeyClick)
}) {
TextButton(
colors = ButtonDefaults.textButtonColors(
contentColor = MaterialTheme.colorScheme.error
),
onClick = {
events(RecoveryKeyWarningSheetEvent.ShareKeyClick)
}
) {
Text(text = stringResource(R.string.RecoveryKeyWarningSheetContent__share_key))
}
}
@Composable
fun RecoveryKeyWarningDialog(events: (RecoveryKeyWarningSheetEvent) -> Unit) {
val bodyIntro = stringResource(R.string.RecoveryKeyWarningDialog__do_not_share_your_recovery_key_with_anyone)
val bodyEmphasis = stringResource(R.string.RecoveryKeyWarningDialog__signal_will_never_message_you_for_your_recovery_key)
val bodyOutro = stringResource(R.string.RecoveryKeyWarningDialog__never_respond_to_a_chat)
Dialogs.SimpleAlertDialog(
title = AnnotatedString(stringResource(R.string.RecoveryKeyWarningDialog__do_not_share_recovery_key)),
body = buildAnnotatedString {
append(bodyIntro)
append(" ")
withStyle(style = SpanStyle(fontWeight = FontWeight.Bold)) {
append(bodyEmphasis)
}
append(" ")
append(bodyOutro)
},
confirm = AnnotatedString(stringResource(R.string.RecoveryKeyWarningDialog__paste_key)),
confirmColor = MaterialTheme.colorScheme.error,
dismiss = AnnotatedString(stringResource(R.string.RecoveryKeyWarningDialog__dont_share)),
onConfirm = { events(RecoveryKeyWarningSheetEvent.PasteKeyClick) },
onDeny = { events(RecoveryKeyWarningSheetEvent.DoNotShareClick) }
)
}
enum class ClipStage {
COPY,
PASTE
@ -175,11 +170,3 @@ private fun RecoveryKeyWarningSheetContentPastePreview() {
)
}
}
@DayNightPreviews
@Composable
private fun RecoveryKeyWarningDialogPreview() {
Previews.Preview {
RecoveryKeyWarningDialog(events = {})
}
}

View File

@ -8,7 +8,6 @@ package org.thoughtcrime.securesms.backup.v2.ui.warning
sealed interface RecoveryKeyWarningSheetEvent {
data object DoNotShareClick : RecoveryKeyWarningSheetEvent
data object ShareKeyClick : RecoveryKeyWarningSheetEvent
data object PasteKeyClick : RecoveryKeyWarningSheetEvent
data object GotItClick : RecoveryKeyWarningSheetEvent
data object LearnMoreClick : RecoveryKeyWarningSheetEvent
}

View File

@ -9946,6 +9946,8 @@
<string name="RecoveryKeyWarningSheetContent__got_it">Got it</string>
<!-- Button opening a help article with more information about recovery key safety -->
<string name="RecoveryKeyWarningSheetContent__learn_more">Learn more</string>
<!-- Inline link opening a help article with more information about recovery key safety -->
<string name="RecoveryKeyWarningSheetContent__learn_more_period">Learn more.</string>
<!-- Button declining to paste/share the recovery key, dismissing the warning sheet -->
<string name="RecoveryKeyWarningSheetContent__do_not_share_key">Do not share key</string>
<!-- Button indicating the user wants to proceed with sharing/pasting the recovery key, which shows a final confirmation -->