diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 97ca29bb..cc523a62 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -2615,5 +2615,7 @@ "openGallery": "Open gallery", "removeFromSpace": "Remove from space", "removeFromSpaceDescription": "This removes this chat from the current space. It will then still be visible under \"All chats\".", - "addToSpaceDescription": "Select a space to add this chat to it." + "addToSpaceDescription": "Select a space to add this chat to it.", + "start": "Start", + "setupChatBackupNow": "Set up your chat backup now" } diff --git a/lib/pages/bootstrap/bootstrap_dialog.dart b/lib/pages/bootstrap/bootstrap_dialog.dart index 576b3cbc..e8702ddd 100644 --- a/lib/pages/bootstrap/bootstrap_dialog.dart +++ b/lib/pages/bootstrap/bootstrap_dialog.dart @@ -57,14 +57,18 @@ class _BootstrapDialogState extends State { bool _wipe; + @override + void initState() { + _createBootstrap(widget.wipe); + super.initState(); + } + void _createBootstrap(bool wipe) { - setState(() { - _wipe = wipe; - titleText = null; - _recoveryKeyStored = false; - bootstrap = widget.client.encryption - .bootstrap(onUpdate: () => setState(() => null)); - }); + _wipe = wipe; + titleText = null; + _recoveryKeyStored = false; + bootstrap = widget.client.encryption + .bootstrap(onUpdate: () => setState(() => null)); } @override @@ -76,20 +80,7 @@ class _BootstrapDialogState extends State { : const LinearProgressIndicator(); titleText = L10n.of(context).loadingPleaseWait; - if (bootstrap == null) { - titleText = L10n.of(context).setupChatBackup; - body = Column( - mainAxisSize: MainAxisSize.min, - children: [ - Image.asset('assets/backup.png', fit: BoxFit.contain), - Text(L10n.of(context).setupChatBackupDescription), - ], - ); - buttons.add(AdaptiveFlatButton( - label: L10n.of(context).next, - onPressed: () => _createBootstrap(false), - )); - } else if (bootstrap.newSsssKey?.recoveryKey != null && + if (bootstrap.newSsssKey?.recoveryKey != null && _recoveryKeyStored == false) { final key = bootstrap.newSsssKey.recoveryKey; titleText = L10n.of(context).securityKey; @@ -183,6 +174,11 @@ class _BootstrapDialogState extends State { child: ListView( padding: const EdgeInsets.all(16.0), children: [ + Text( + L10n.of(context).setupChatBackupDescription, + textAlign: TextAlign.center, + ), + const SizedBox(height: 16), TextField( minLines: 4, maxLines: 4, @@ -275,7 +271,7 @@ class _BootstrapDialogState extends State { cancelLabel: L10n.of(context).cancel, isDestructiveAction: true, )) { - _createBootstrap(true); + setState(() => _createBootstrap(true)); } }, ) diff --git a/lib/pages/chat_list/chat_list.dart b/lib/pages/chat_list/chat_list.dart index e868c0e3..4b8a387c 100644 --- a/lib/pages/chat_list/chat_list.dart +++ b/lib/pages/chat_list/chat_list.dart @@ -79,13 +79,13 @@ class ChatListController extends State { final selectedRoomIds = {}; bool crossSigningCached; - bool hideChatBackupBanner = false; - - void hideChatBackupBannerAction() => - setState(() => hideChatBackupBanner = true); + bool showChatBackupBanner = false; void firstRunBootstrapAction() async { - hideChatBackupBannerAction(); + setState(() { + showChatBackupBanner = false; + }); + await BootstrapDialog( client: Matrix.of(context).client, ).show(context); @@ -181,7 +181,9 @@ class ChatListController extends State { crossSigning == false; final isUnknownSession = Matrix.of(context).client.isUnknownSession; if (needsBootstrap || isUnknownSession) { - firstRunBootstrapAction(); + setState(() { + showChatBackupBanner = true; + }); } } diff --git a/lib/pages/chat_list/chat_list_view.dart b/lib/pages/chat_list/chat_list_view.dart index 66f2b0a5..df0cf03d 100644 --- a/lib/pages/chat_list/chat_list_view.dart +++ b/lib/pages/chat_list/chat_list_view.dart @@ -182,6 +182,27 @@ class ChatListView extends StatelessWidget { ), body: Column(children: [ const ConnectionStatusHeader(), + AnimatedContainer( + height: controller.showChatBackupBanner ? 54 : 0, + duration: const Duration(milliseconds: 300), + clipBehavior: Clip.hardEdge, + curve: Curves.bounceInOut, + decoration: const BoxDecoration(), + child: MaterialBanner( + leading: Image.asset( + 'assets/backup.png', + fit: BoxFit.contain, + width: 44, + ), + content: Text(L10n.of(context).setupChatBackupNow), + actions: [ + TextButton( + onPressed: controller.firstRunBootstrapAction, + child: Text(L10n.of(context).start), + ), + ], + ), + ), Expanded(child: _ChatListViewBody(controller)), ]), floatingActionButton: selectMode == SelectMode.normal