diff --git a/commet/lib/ui/molecules/timeline_events/timeline_event_menu.dart b/commet/lib/ui/molecules/timeline_events/timeline_event_menu.dart index 3934b7bf3..298b6074c 100644 --- a/commet/lib/ui/molecules/timeline_events/timeline_event_menu.dart +++ b/commet/lib/ui/molecules/timeline_events/timeline_event_menu.dart @@ -7,9 +7,11 @@ import 'package:commet/client/components/photo_album_room/photo_album_room_compo import 'package:commet/client/components/pinned_messages/pinned_messages_component.dart'; import 'package:commet/client/components/push_notification/notification_content.dart'; import 'package:commet/client/components/push_notification/notification_manager.dart'; +import 'package:commet/client/matrix/timeline_events/matrix_timeline_event.dart'; import 'package:commet/client/timeline.dart'; import 'package:commet/client/timeline_events/timeline_event.dart'; import 'package:commet/client/timeline_events/timeline_event_emote.dart'; +import 'package:commet/client/timeline_events/timeline_event_encrypted.dart'; import 'package:commet/client/timeline_events/timeline_event_message.dart'; import 'package:commet/client/timeline_events/timeline_event_sticker.dart'; import 'package:commet/main.dart'; @@ -19,6 +21,7 @@ import 'package:commet/ui/navigation/adaptive_dialog.dart'; import 'package:commet/utils/autofill_utils.dart'; import 'package:commet/utils/common_strings.dart'; import 'package:commet/utils/download_utils.dart'; +import 'package:commet/utils/error_utils.dart'; import 'package:commet/utils/event_bus.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -202,6 +205,18 @@ class TimelineEventMenu { } primaryActions = [ + if (event is TimelineEventEncrypted) + TimelineEventMenuEntry( + name: "Retry Decrypt", + icon: Icons.lock_open, + action: (context) { + var mx = (event as MatrixTimelineEvent).event; + + ErrorUtils.tryRun(context, () async { + await mx.requestKey(); + }); + }, + ), if (canRetrySend) TimelineEventMenuEntry( name: promptRetryEventSend, diff --git a/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_page.dart b/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_page.dart index a0edf4b17..e42146928 100644 --- a/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_page.dart +++ b/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_page.dart @@ -45,8 +45,8 @@ class MatrixCrossSigningPageState extends State { onSetNewSsss: (passphrase) { bootstrapper?.newSsss(passphrase); }, - onAskSetupCrossSigning: () { - bootstrapper?.askSetupCrossSigning( + onAskSetupCrossSigning: () async { + await bootstrapper?.askSetupCrossSigning( setupMasterKey: true, setupSelfSigningKey: true, setupUserSigningKey: true, @@ -70,11 +70,12 @@ class MatrixCrossSigningPageState extends State { }, openExistingSsss: (key) async { await bootstrapper?.newSsssKey!.unlock(keyOrPassphrase: key); - await bootstrapper?.client.encryption!.crossSigning - .selfSign(keyOrPassphrase: key); await bootstrapper?.openExistingSsss(); - await bootstrapper?.askSetupCrossSigning(setupMasterKey: true); - bootstrapper?.wipeOnlineKeyBackup(false); + + if (bootstrapper!.encryption.crossSigning.enabled) { + await bootstrapper?.client.encryption!.crossSigning + .selfSign(keyOrPassphrase: key); + } }, wipeCrossSigning: (wipe) { bootstrapper?.wipeCrossSigning(wipe); diff --git a/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_view.dart b/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_view.dart index 5d208871a..2b2693b21 100644 --- a/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_view.dart +++ b/commet/lib/ui/pages/settings/categories/account/security/matrix/cross_signing/cross_signing_view.dart @@ -1,5 +1,7 @@ +import 'package:commet/main.dart'; import 'package:commet/ui/atoms/code_block.dart'; import 'package:commet/utils/common_strings.dart'; +import 'package:commet/utils/error_utils.dart'; import 'package:commet/utils/text_utils.dart'; import 'package:flutter/material.dart' as m; import 'package:flutter/services.dart' as services; @@ -24,7 +26,7 @@ class MatrixCrossSigningView extends StatefulWidget { final BootstrapState state; final Function(String?)? onSetNewSsss; - final Function()? onAskSetupCrossSigning; + final Future Function()? onAskSetupCrossSigning; final Function(bool)? onAskSetupOnlineBackup; final Function(bool)? useExistingKeys; final Function(bool)? wipeSsss; @@ -47,6 +49,8 @@ class _MatrixCrossSigningViewState extends State { String copyBackupCodeText = CommonStrings.promptCopy; + bool isActionLoading = false; + String get promptWipeMatrixKeys => Intl.message("Wipe Keys", desc: "Text on the button to wipe matrix encryption keys", name: "promptWipeMatrixKeys"); @@ -222,7 +226,15 @@ class _MatrixCrossSigningViewState extends State { constraints: const BoxConstraints(maxWidth: 500, maxHeight: 500), child: Padding( padding: const EdgeInsets.all(8.0), - child: showState(), + child: m.Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + showState(), + if (preferences.developerMode.value) + tiamat.Text.labelLow(widget.state.toString()), + ], + ), ), ); } @@ -295,8 +307,19 @@ class _MatrixCrossSigningViewState extends State { ), tiamat.Button( text: CommonStrings.promptConfirm, - onTap: () { - widget.onAskSetupCrossSigning?.call(); + isLoading: isActionLoading, + onTap: () async { + setState(() { + isActionLoading = true; + }); + + await ErrorUtils.tryRun(context, () async { + await widget.onAskSetupCrossSigning?.call(); + }); + + setState(() { + isActionLoading = false; + }); }) ], ); @@ -326,8 +349,21 @@ class _MatrixCrossSigningViewState extends State { ), tiamat.Button( text: CommonStrings.promptConfirm, - onTap: () { - widget.openExistingSsss?.call(keyInputController.text); + isLoading: isActionLoading, + onTap: () async { + setState(() { + isActionLoading = true; + }); + + await Future.delayed(Duration(milliseconds: 300)); + + await ErrorUtils.tryRun(context, () async { + await widget.openExistingSsss?.call(keyInputController.text); + }); + + setState(() { + isActionLoading = false; + }); }) ], ),