From 2bf2da13b0dd6d1b9ee6fb61f39f271b3911fac5 Mon Sep 17 00:00:00 2001 From: Christian Pauly Date: Sun, 23 Feb 2020 09:31:44 +0100 Subject: [PATCH] Better E2EE UI --- lib/components/encryption_button.dart | 40 ++++- lib/views/chat_details.dart | 2 +- lib/views/chat_encryption_settings.dart | 190 +++++++++++------------- 3 files changed, 120 insertions(+), 112 deletions(-) diff --git a/lib/components/encryption_button.dart b/lib/components/encryption_button.dart index 1a23f61..28b410d 100644 --- a/lib/components/encryption_button.dart +++ b/lib/components/encryption_button.dart @@ -1,10 +1,13 @@ import 'dart:async'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/views/chat_encryption_settings.dart'; import 'package:flutter/material.dart'; +import 'package:toast/toast.dart'; +import 'dialogs/simple_dialogs.dart'; import 'matrix.dart'; class EncryptionButton extends StatefulWidget { @@ -17,6 +20,36 @@ class EncryptionButton extends StatefulWidget { class _EncryptionButtonState extends State { StreamSubscription _onSyncSub; + void _enableEncryptionAction() async { + if (widget.room.encrypted) { + Toast.show(I18n.of(context).warningEncryptionInBeta, context, + duration: 5); + await Navigator.of(context).push( + AppRoute.defaultRoute( + context, + ChatEncryptionSettingsView(widget.room.id), + ), + ); + return; + } + if (!widget.room.client.encryptionEnabled) { + Toast.show(I18n.of(context).needPantalaimonWarning, context, duration: 8); + return; + } + if (await SimpleDialogs(context).askConfirmation( + titleText: I18n.of(context).enableEncryptionWarning, + contentText: widget.room.client.encryptionEnabled + ? I18n.of(context).warningEncryptionInBeta + : I18n.of(context).needPantalaimonWarning, + confirmText: I18n.of(context).yes, + ) == + true) { + await Matrix.of(context).tryRequestWithLoadingDialog( + widget.room.enableEncryption(), + ); + } + } + @override void dispose() { _onSyncSub?.cancel(); @@ -50,12 +83,7 @@ class _EncryptionButtonState extends State { return IconButton( icon: Icon(widget.room.encrypted ? Icons.lock : Icons.lock_open, size: 20, color: color), - onPressed: () => Navigator.of(context).push( - AppRoute.defaultRoute( - context, - ChatEncryptionSettingsView(widget.room.id), - ), - ), + onPressed: _enableEncryptionAction, ); }); } diff --git a/lib/views/chat_details.dart b/lib/views/chat_details.dart index 1e4700c..c7f332a 100644 --- a/lib/views/chat_details.dart +++ b/lib/views/chat_details.dart @@ -240,7 +240,7 @@ class _ChatDetailsState extends State { linkStyle: TextStyle(color: Colors.blueAccent), textStyle: TextStyle( fontSize: 14, - color: Theme.of(context).accentColor, + color: Theme.of(context).textTheme.body1.color, ), ), onTap: widget.room.canSendEvent("m.room.topic") diff --git a/lib/views/chat_encryption_settings.dart b/lib/views/chat_encryption_settings.dart index d0cfa15..16808d0 100644 --- a/lib/views/chat_encryption_settings.dart +++ b/lib/views/chat_encryption_settings.dart @@ -2,7 +2,7 @@ import 'dart:async'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:fluffychat/components/adaptive_page_layout.dart'; -import 'package:fluffychat/components/dialogs/simple_dialogs.dart'; +import 'package:fluffychat/components/avatar.dart'; import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/utils/beautify_string_extension.dart'; import 'package:fluffychat/i18n/i18n.dart'; @@ -53,120 +53,100 @@ class _ChatEncryptionSettingsState extends State { return Scaffold( appBar: AppBar( - title: Text(I18n.of(context).end2endEncryptionSettings), + title: Text(I18n.of(context).participatingUserDevices), ), body: Column( children: [ - ListTile( - title: Text(I18n.of(context).encryptionAlgorithm), - subtitle: Text(room.encryptionAlgorithm ?? I18n.of(context).none), - trailing: Icon(room.encrypted ? Icons.lock : Icons.lock_open, - color: room.encrypted ? Colors.green : Colors.red), - onTap: () async { - if (room.encrypted) return; - if (!room.client.encryptionEnabled) { - Toast.show(I18n.of(context).needPantalaimonWarning, context, - duration: 8); - return; - } - if (await SimpleDialogs(context).askConfirmation( - titleText: I18n.of(context).enableEncryptionWarning, - confirmText: I18n.of(context).yes) == - true) { - await Matrix.of(context).tryRequestWithLoadingDialog( - room.enableEncryption(), + FutureBuilder>( + future: room.getUserDeviceKeys(), + builder: (BuildContext context, snapshot) { + if (snapshot.hasError) { + return Center( + child: Text(I18n.of(context).oopsSomethingWentWrong + + ": " + + snapshot.error.toString()), ); } + if (!snapshot.hasData) { + return Center(child: CircularProgressIndicator()); + } + final List deviceKeys = snapshot.data; + return Expanded( + child: ListView.separated( + separatorBuilder: (BuildContext context, int i) => + Divider(height: 1), + itemCount: deviceKeys.length, + itemBuilder: (BuildContext context, int i) => Column( + mainAxisSize: MainAxisSize.min, + children: [ + if (i == 0 || + deviceKeys[i].userId != deviceKeys[i - 1].userId) + Material( + child: ListTile( + leading: Avatar( + room + .getUserByMXIDSync(deviceKeys[i].userId) + .avatarUrl, + room + .getUserByMXIDSync(deviceKeys[i].userId) + .calcDisplayname(), + ), + title: Text(room + .getUserByMXIDSync(deviceKeys[i].userId) + .calcDisplayname()), + subtitle: Text(deviceKeys[i].userId), + ), + elevation: 2, + ), + CheckboxListTile( + title: Text( + "${deviceKeys[i].unsigned["device_display_name"] ?? I18n.of(context).unknownDevice} - ${deviceKeys[i].deviceId}", + style: TextStyle( + color: deviceKeys[i].blocked + ? Colors.red + : deviceKeys[i].verified + ? Colors.green + : Colors.orange), + ), + subtitle: Text( + deviceKeys[i] + .keys["ed25519:${deviceKeys[i].deviceId}"] + .beautified, + style: TextStyle( + color: Theme.of(context).textTheme.body1.color), + ), + value: deviceKeys[i].verified, + onChanged: (bool newVal) { + if (newVal == true) { + if (deviceKeys[i].blocked) { + deviceKeys[i] + .setBlocked(false, Matrix.of(context).client); + } + deviceKeys[i] + .setVerified(true, Matrix.of(context).client); + } else { + if (deviceKeys[i].verified) { + deviceKeys[i].setVerified( + false, Matrix.of(context).client); + } + deviceKeys[i] + .setBlocked(true, Matrix.of(context).client); + } + setState(() => null); + }, + ), + ], + ), + ), + ); }, ), + Divider(thickness: 1, height: 1), ListTile( - trailing: Icon(Icons.info), + title: Text("Outbound MegOlm session ID:"), subtitle: Text( - room.client.encryptionEnabled - ? I18n.of(context).warningEncryptionInBeta - : I18n.of(context).needPantalaimonWarning, - ), + room.outboundGroupSession?.session_id()?.beautified ?? "None"), ), - Divider(height: 1), - if (room.encrypted) - ListTile( - title: Text( - "${I18n.of(context).participatingUserDevices}:", - style: TextStyle( - fontWeight: FontWeight.bold, - ), - ), - ), - if (room.encrypted) Divider(height: 1), - if (room.encrypted) - FutureBuilder>( - future: room.getUserDeviceKeys(), - builder: (BuildContext context, snapshot) { - if (snapshot.hasError) { - return Center( - child: Text(I18n.of(context).oopsSomethingWentWrong + - ": " + - snapshot.error.toString()), - ); - } - if (!snapshot.hasData) { - return Center(child: CircularProgressIndicator()); - } - final List deviceKeys = snapshot.data; - return Expanded( - child: ListView.separated( - separatorBuilder: (BuildContext context, int i) => - Divider(height: 1), - itemCount: deviceKeys.length, - itemBuilder: (BuildContext context, int i) => - CheckboxListTile( - title: Text( - "${deviceKeys[i].userId} - ${deviceKeys[i].deviceId}", - style: TextStyle( - color: deviceKeys[i].blocked - ? Colors.red - : deviceKeys[i].verified - ? Colors.green - : Colors.orange), - ), - subtitle: Text( - deviceKeys[i] - .keys["ed25519:${deviceKeys[i].deviceId}"] - .beautified, - style: TextStyle( - color: Theme.of(context).textTheme.body1.color), - ), - value: deviceKeys[i].verified, - onChanged: (bool newVal) { - if (newVal == true) { - if (deviceKeys[i].blocked) { - deviceKeys[i] - .setBlocked(false, Matrix.of(context).client); - } - deviceKeys[i] - .setVerified(true, Matrix.of(context).client); - } else { - if (deviceKeys[i].verified) { - deviceKeys[i] - .setVerified(false, Matrix.of(context).client); - } - deviceKeys[i] - .setBlocked(true, Matrix.of(context).client); - } - setState(() => null); - }, - ), - ), - ); - }, - ), - if (room.encrypted) - ListTile( - title: Text("Outbound MegOlm session ID:"), - subtitle: Text( - room.outboundGroupSession?.session_id()?.beautified ?? - "None"), - ), ], ), );