Better E2EE UI
This commit is contained in:
parent
494737e28a
commit
2bf2da13b0
|
@ -1,10 +1,13 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
|
import 'package:fluffychat/i18n/i18n.dart';
|
||||||
import 'package:fluffychat/utils/app_route.dart';
|
import 'package:fluffychat/utils/app_route.dart';
|
||||||
import 'package:fluffychat/views/chat_encryption_settings.dart';
|
import 'package:fluffychat/views/chat_encryption_settings.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:toast/toast.dart';
|
||||||
|
|
||||||
|
import 'dialogs/simple_dialogs.dart';
|
||||||
import 'matrix.dart';
|
import 'matrix.dart';
|
||||||
|
|
||||||
class EncryptionButton extends StatefulWidget {
|
class EncryptionButton extends StatefulWidget {
|
||||||
|
@ -17,6 +20,36 @@ class EncryptionButton extends StatefulWidget {
|
||||||
class _EncryptionButtonState extends State<EncryptionButton> {
|
class _EncryptionButtonState extends State<EncryptionButton> {
|
||||||
StreamSubscription _onSyncSub;
|
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
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_onSyncSub?.cancel();
|
_onSyncSub?.cancel();
|
||||||
|
@ -50,12 +83,7 @@ class _EncryptionButtonState extends State<EncryptionButton> {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
icon: Icon(widget.room.encrypted ? Icons.lock : Icons.lock_open,
|
icon: Icon(widget.room.encrypted ? Icons.lock : Icons.lock_open,
|
||||||
size: 20, color: color),
|
size: 20, color: color),
|
||||||
onPressed: () => Navigator.of(context).push(
|
onPressed: _enableEncryptionAction,
|
||||||
AppRoute.defaultRoute(
|
|
||||||
context,
|
|
||||||
ChatEncryptionSettingsView(widget.room.id),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ class _ChatDetailsState extends State<ChatDetails> {
|
||||||
linkStyle: TextStyle(color: Colors.blueAccent),
|
linkStyle: TextStyle(color: Colors.blueAccent),
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: Theme.of(context).accentColor,
|
color: Theme.of(context).textTheme.body1.color,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: widget.room.canSendEvent("m.room.topic")
|
onTap: widget.room.canSendEvent("m.room.topic")
|
||||||
|
|
|
@ -2,7 +2,7 @@ import 'dart:async';
|
||||||
|
|
||||||
import 'package:famedlysdk/famedlysdk.dart';
|
import 'package:famedlysdk/famedlysdk.dart';
|
||||||
import 'package:fluffychat/components/adaptive_page_layout.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/components/matrix.dart';
|
||||||
import 'package:fluffychat/utils/beautify_string_extension.dart';
|
import 'package:fluffychat/utils/beautify_string_extension.dart';
|
||||||
import 'package:fluffychat/i18n/i18n.dart';
|
import 'package:fluffychat/i18n/i18n.dart';
|
||||||
|
@ -53,120 +53,100 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(I18n.of(context).end2endEncryptionSettings),
|
title: Text(I18n.of(context).participatingUserDevices),
|
||||||
),
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
ListTile(
|
FutureBuilder<List<DeviceKeys>>(
|
||||||
title: Text(I18n.of(context).encryptionAlgorithm),
|
future: room.getUserDeviceKeys(),
|
||||||
subtitle: Text(room.encryptionAlgorithm ?? I18n.of(context).none),
|
builder: (BuildContext context, snapshot) {
|
||||||
trailing: Icon(room.encrypted ? Icons.lock : Icons.lock_open,
|
if (snapshot.hasError) {
|
||||||
color: room.encrypted ? Colors.green : Colors.red),
|
return Center(
|
||||||
onTap: () async {
|
child: Text(I18n.of(context).oopsSomethingWentWrong +
|
||||||
if (room.encrypted) return;
|
": " +
|
||||||
if (!room.client.encryptionEnabled) {
|
snapshot.error.toString()),
|
||||||
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(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (!snapshot.hasData) {
|
||||||
|
return Center(child: CircularProgressIndicator());
|
||||||
|
}
|
||||||
|
final List<DeviceKeys> 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: <Widget>[
|
||||||
|
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(
|
ListTile(
|
||||||
trailing: Icon(Icons.info),
|
title: Text("Outbound MegOlm session ID:"),
|
||||||
subtitle: Text(
|
subtitle: Text(
|
||||||
room.client.encryptionEnabled
|
room.outboundGroupSession?.session_id()?.beautified ?? "None"),
|
||||||
? I18n.of(context).warningEncryptionInBeta
|
|
||||||
: I18n.of(context).needPantalaimonWarning,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
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<List<DeviceKeys>>(
|
|
||||||
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> 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"),
|
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue