From 3b7144d805198c40dd9f4b5c799471c81a940c64 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Sun, 20 Jun 2021 13:16:51 +0200 Subject: [PATCH] change: Place backup hint banner in chat list --- assets/l10n/intl_en.arb | 5 ++ lib/pages/chat_list.dart | 25 +++++++++ lib/pages/settings.dart | 8 --- lib/pages/views/chat_list_view.dart | 80 +++++++++++++++++++++++------ lib/pages/views/settings_view.dart | 25 --------- 5 files changed, 95 insertions(+), 48 deletions(-) diff --git a/assets/l10n/intl_en.arb b/assets/l10n/intl_en.arb index 768bdb4b..094405b5 100644 --- a/assets/l10n/intl_en.arb +++ b/assets/l10n/intl_en.arb @@ -1238,6 +1238,11 @@ "type": "text", "placeholders": {} }, + "enableChatBackup": "Enable the chat backup to never lose access to your chats.", + "@enableChatBackup": { + "type": "text", + "placeholders": {} + }, "pleaseChoose": "Please choose", "@pleaseChoose": { "type": "text", diff --git a/lib/pages/chat_list.dart b/lib/pages/chat_list.dart index a2034dd3..9261de6d 100644 --- a/lib/pages/chat_list.dart +++ b/lib/pages/chat_list.dart @@ -21,6 +21,8 @@ import '../utils/matrix_sdk_extensions.dart/matrix_file_extension.dart'; import '../utils/url_launcher.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; +import 'bootstrap_dialog.dart'; + enum SelectMode { normal, share, select } enum PopupMenuAction { settings, invite, newGroup, setStatus, archive } @@ -39,6 +41,20 @@ class ChatListController extends State { StreamSubscription _intentUriStreamSubscription; final selectedRoomIds = {}; + Future crossSigningCachedFuture; + bool crossSigningCached; + bool hideChatBackupBanner = false; + + void hideChatBackupBannerAction() => + setState(() => hideChatBackupBanner = true); + + void firstRunBootstrapAction() async { + hideChatBackupBannerAction(); + await BootstrapDialog( + client: Matrix.of(context).client, + ).show(context); + VRouter.of(context).push('/rooms'); + } String get activeChat => VRouter.of(context).pathParameters['roomid']; @@ -250,6 +266,15 @@ class ChatListController extends State { @override Widget build(BuildContext context) { Matrix.of(context).navigatorContext = context; + crossSigningCachedFuture ??= Matrix.of(context) + .client + .encryption + ?.crossSigning + ?.isCached() + ?.then((c) { + if (mounted) setState(() => crossSigningCached = c); + return c; + }); return ChatListView(this); } } diff --git a/lib/pages/settings.dart b/lib/pages/settings.dart index 5dad1bbb..13d1543e 100644 --- a/lib/pages/settings.dart +++ b/lib/pages/settings.dart @@ -13,7 +13,6 @@ import 'package:flutter_app_lock/flutter_app_lock.dart'; import 'package:flutter_gen/gen_l10n/l10n.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:image_picker/image_picker.dart'; -import 'package:vrouter/vrouter.dart'; import 'views/settings_view.dart'; import 'package:future_loading_dialog/future_loading_dialog.dart'; @@ -377,13 +376,6 @@ class SettingsController extends State { ).show(context); } - void firstRunBootstrapAction() async { - await BootstrapDialog( - client: Matrix.of(context).client, - ).show(context); - VRouter.of(context).push('/rooms'); - } - @override Widget build(BuildContext context) { final client = Matrix.of(context).client; diff --git a/lib/pages/views/chat_list_view.dart b/lib/pages/views/chat_list_view.dart index dace63e5..701b1606 100644 --- a/lib/pages/views/chat_list_view.dart +++ b/lib/pages/views/chat_list_view.dart @@ -194,23 +194,73 @@ class ChatListView extends StatelessWidget { ], ); } - final totalCount = rooms.length; + final totalCount = rooms.length + 1; return ListView.builder( itemCount: totalCount, - itemBuilder: (BuildContext context, int i) => - ChatListItem( - rooms[i], - selected: controller.selectedRoomIds - .contains(rooms[i].id), - onTap: selectMode == SelectMode.select - ? () => controller - .toggleSelection(rooms[i].id) - : null, - onLongPress: () => - controller.toggleSelection(rooms[i].id), - activeChat: - controller.activeChat == rooms[i].id, - ), + itemBuilder: (BuildContext context, int i) { + if (i == 0) { + return FutureBuilder( + future: controller + .crossSigningCachedFuture, + builder: (context, snapshot) { + final needsBootstrap = + Matrix.of(context) + .client + .encryption + ?.crossSigning + ?.enabled == + false || + snapshot.data == false; + final isUnknownSession = + Matrix.of(context) + .client + .isUnknownSession; + final displayHeader = + needsBootstrap || + isUnknownSession; + if (!displayHeader || + controller + .hideChatBackupBanner) { + return Container(); + } + return Material( + color: Colors.orange, + child: ListTile( + leading: CircleAvatar( + backgroundColor: Colors.white, + foregroundColor: Colors.black, + child: Icon(Icons.cloud), + ), + trailing: IconButton( + icon: Icon(Icons.close), + onPressed: controller + .hideChatBackupBannerAction, + ), + title: Text(L10n.of(context) + .chatBackup), + subtitle: Text(L10n.of(context) + .enableChatBackup), + onTap: controller + .firstRunBootstrapAction, + ), + ); + }); + } + i--; + return ChatListItem( + rooms[i], + selected: controller.selectedRoomIds + .contains(rooms[i].id), + onTap: selectMode == SelectMode.select + ? () => controller + .toggleSelection(rooms[i].id) + : null, + onLongPress: () => controller + .toggleSelection(rooms[i].id), + activeChat: + controller.activeChat == rooms[i].id, + ); + }, ); } else { return Center( diff --git a/lib/pages/views/settings_view.dart b/lib/pages/views/settings_view.dart index 45cd5192..61c7f1b0 100644 --- a/lib/pages/views/settings_view.dart +++ b/lib/pages/views/settings_view.dart @@ -36,31 +36,6 @@ class SettingsView extends StatelessWidget { floating: true, pinned: true, title: Text(L10n.of(context).settings), - actions: [ - FutureBuilder( - future: controller.crossSigningCachedFuture, - builder: (context, snapshot) { - final needsBootstrap = Matrix.of(context) - .client - .encryption - ?.crossSigning - ?.enabled == - false || - snapshot.data == false; - final isUnknownSession = - Matrix.of(context).client.isUnknownSession; - final displayHeader = needsBootstrap || isUnknownSession; - if (!displayHeader) return Container(); - return TextButton.icon( - icon: Icon(Icons.cloud, color: Colors.red), - label: Text( - L10n.of(context).chatBackup, - style: TextStyle(color: Colors.red), - ), - onPressed: controller.firstRunBootstrapAction, - ); - }), - ], backgroundColor: Theme.of(context).appBarTheme.color, flexibleSpace: FlexibleSpaceBar( background: ContentBanner(