Add e2ee settings

This commit is contained in:
Christian Pauly 2020-02-04 14:42:35 +01:00
parent 178e50a564
commit c6c419f76d
15 changed files with 357 additions and 50 deletions

View File

@ -0,0 +1,36 @@
import 'package:fluffychat/i18n/i18n.dart';
import 'package:flutter/material.dart';
class ConfirmDialog extends StatelessWidget {
const ConfirmDialog(
this.text,
this.confirmText,
this.onConfirmed,
);
final String text;
final String confirmText;
final Function(BuildContext) onConfirmed;
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(text),
actions: <Widget>[
FlatButton(
child: Text(I18n.of(context).close.toUpperCase(),
style: TextStyle(color: Colors.blueGrey)),
onPressed: () => Navigator.of(context).pop(),
),
FlatButton(
child: Text(
confirmText.toUpperCase(),
),
onPressed: () {
Navigator.of(context).pop();
onConfirmed(context);
},
),
],
);
}
}

View File

@ -1,36 +0,0 @@
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/i18n/i18n.dart';
import 'package:flutter/material.dart';
import '../matrix.dart';
class RedactMessageDialog extends StatelessWidget {
final Event event;
const RedactMessageDialog(this.event);
void removeAction(BuildContext context) {
Matrix.of(context).tryRequestWithLoadingDialog(event.redact());
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text(I18n.of(context).messageWillBeRemovedWarning),
actions: <Widget>[
FlatButton(
child: Text("Close".toUpperCase(),
style: TextStyle(color: Colors.blueGrey)),
onPressed: () => Navigator.of(context).pop(),
),
FlatButton(
child: Text(
I18n.of(context).remove.toUpperCase(),
style: TextStyle(color: Colors.red),
),
onPressed: () => removeAction(context),
),
],
);
}
}

View File

@ -1,6 +1,6 @@
import 'package:bubble/bubble.dart'; import 'package:bubble/bubble.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/dialogs/redact_message_dialog.dart'; import 'package:fluffychat/components/dialogs/confirm_dialog.dart';
import 'package:fluffychat/components/message_content.dart'; import 'package:fluffychat/components/message_content.dart';
import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/utils/app_route.dart'; import 'package:fluffychat/utils/app_route.dart';
@ -107,7 +107,12 @@ class Message extends StatelessWidget {
case "remove": case "remove":
await showDialog( await showDialog(
context: context, context: context,
builder: (BuildContext context) => RedactMessageDialog(event), builder: (BuildContext context) => ConfirmDialog(
I18n.of(context).messageWillBeRemovedWarning,
I18n.of(context).remove, (context) {
Matrix.of(context)
.tryRequestWithLoadingDialog(event.redact());
}),
); );
break; break;
case "resend": case "resend":

View File

@ -265,6 +265,14 @@ class I18n {
String get emptyChat => Intl.message("Empty chat"); String get emptyChat => Intl.message("Empty chat");
String get enableEncryptionWarning => Intl.message(
"You won't be able to disable the encryption anymore. Are you sure?");
String get encryptionAlgorithm => Intl.message("Encryption algorithm");
String get end2endEncryptionSettings =>
Intl.message("End-to-end encryption settings");
String get enterAGroupName => Intl.message("Enter a group name"); String get enterAGroupName => Intl.message("Enter a group name");
String get enterAUsername => Intl.message("Enter a username"); String get enterAUsername => Intl.message("Enter a username");
@ -388,6 +396,9 @@ class I18n {
String get muteChat => Intl.message('Mute chat'); String get muteChat => Intl.message('Mute chat');
String get needPantalaimonWarning => Intl.message(
"Please be aware that you need Pantalaimon to use end-to-end encryption for now.");
String get newMessageInFluffyChat => String get newMessageInFluffyChat =>
Intl.message('New message in FluffyChat'); Intl.message('New message in FluffyChat');
@ -396,6 +407,8 @@ class I18n {
String get noGoogleServicesWarning => Intl.message( String get noGoogleServicesWarning => Intl.message(
"It seems that you have no google services on your phone. That's a good decision for your privacy! To receive push notifications in FluffyChat we recommend using microG: https://microg.org/"); "It seems that you have no google services on your phone. That's a good decision for your privacy! To receive push notifications in FluffyChat we recommend using microG: https://microg.org/");
String get none => Intl.message("None");
String get noRoomsFound => Intl.message("No rooms found..."); String get noRoomsFound => Intl.message("No rooms found...");
String get notSupportedInWeb => Intl.message("Not supported in web"); String get notSupportedInWeb => Intl.message("Not supported in web");
@ -407,6 +420,9 @@ class I18n {
String get optionalGroupName => Intl.message("(Optional) Group name"); String get optionalGroupName => Intl.message("(Optional) Group name");
String get participatingUserDevices =>
Intl.message("Participating user devices");
String get password => Intl.message("Password"); String get password => Intl.message("Password");
String play(String fileName) => Intl.message( String play(String fileName) => Intl.message(
@ -637,6 +653,8 @@ class I18n {
String get writeAMessage => Intl.message("Write a message..."); String get writeAMessage => Intl.message("Write a message...");
String get yes => Intl.message("Yes");
String get you => Intl.message("You"); String get you => Intl.message("You");
String get youAreInvitedToThisChat => String get youAreInvitedToThisChat =>

View File

@ -352,6 +352,21 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"You won't be able to disable the encryption anymore. Are you sure?": "Du wirst die Verschlüsselung nicht mehr ausstellen können. Bist Du sicher?",
"@You won't be able to disable the encryption anymore. Are you sure?": {
"type": "text",
"placeholders": {}
},
"Encryption algorithm": "Verschlüsselungsalgorithmus",
"@Encryption algorithm": {
"type": "text",
"placeholders": {}
},
"End-to-end encryption settings": "Ende-zu-Ende-Verschlüsselung",
"@End-to-end encryption settings": {
"type": "text",
"placeholders": {}
},
"Enter a group name": "Gib einen Gruppennamen ein", "Enter a group name": "Gib einen Gruppennamen ein",
"@Enter a group name": { "@Enter a group name": {
"type": "text", "type": "text",
@ -579,6 +594,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"Please be aware that you need Pantalaimon to use end-to-end encryption for now.": "Bitte beachte, dass du Pantalaimon brauchst, um Ende-zu-Ende-Verschlüsselung benutzen zu können.",
"@Please be aware that you need Pantalaimon to use end-to-end encryption for now.": {
"type": "text",
"placeholders": {}
},
"New message in FluffyChat": "Neue Nachricht in FluffyChat", "New message in FluffyChat": "Neue Nachricht in FluffyChat",
"@New message in FluffyChat": { "@New message in FluffyChat": {
"type": "text", "type": "text",
@ -594,6 +614,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"None": "Keiner",
"@None": {
"type": "text",
"placeholders": {}
},
"No rooms found...": "Keine Räume gefunden ...", "No rooms found...": "Keine Räume gefunden ...",
"@No rooms found...": { "@No rooms found...": {
"type": "text", "type": "text",
@ -619,6 +644,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"Participating user devices": "Teilnehmende Geräte",
"@Participating user devices": {
"type": "text",
"placeholders": {}
},
"Password": "Passwort", "Password": "Passwort",
"@Password": { "@Password": {
"type": "text", "type": "text",
@ -984,6 +1014,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"Yes": "Ja",
"@Yes": {
"type": "text",
"placeholders": {}
},
"You": "Du", "You": "Du",
"@You": { "@You": {
"type": "text", "type": "text",

View File

@ -1,5 +1,5 @@
{ {
"@@last_modified": "2020-01-27T11:02:06.464591", "@@last_modified": "2020-02-04T14:02:33.828211",
"About": "About", "About": "About",
"@About": { "@About": {
"type": "text", "type": "text",
@ -352,6 +352,21 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"You won't be able to disable the encryption anymore. Are you sure?": "You won't be able to disable the encryption anymore. Are you sure?",
"@You won't be able to disable the encryption anymore. Are you sure?": {
"type": "text",
"placeholders": {}
},
"Encryption algorithm": "Encryption algorithm",
"@Encryption algorithm": {
"type": "text",
"placeholders": {}
},
"End-to-end encryption settings": "End-to-end encryption settings",
"@End-to-end encryption settings": {
"type": "text",
"placeholders": {}
},
"Enter a group name": "Enter a group name", "Enter a group name": "Enter a group name",
"@Enter a group name": { "@Enter a group name": {
"type": "text", "type": "text",
@ -579,6 +594,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"Please be aware that you need Pantalaimon to use end-to-end encryption for now.": "Please be aware that you need Pantalaimon to use end-to-end encryption for now.",
"@Please be aware that you need Pantalaimon to use end-to-end encryption for now.": {
"type": "text",
"placeholders": {}
},
"New message in FluffyChat": "New message in FluffyChat", "New message in FluffyChat": "New message in FluffyChat",
"@New message in FluffyChat": { "@New message in FluffyChat": {
"type": "text", "type": "text",
@ -594,6 +614,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"None": "None",
"@None": {
"type": "text",
"placeholders": {}
},
"No rooms found...": "No rooms found...", "No rooms found...": "No rooms found...",
"@No rooms found...": { "@No rooms found...": {
"type": "text", "type": "text",
@ -619,6 +644,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"Participating user devices": "Participating user devices",
"@Participating user devices": {
"type": "text",
"placeholders": {}
},
"Password": "Password", "Password": "Password",
"@Password": { "@Password": {
"type": "text", "type": "text",
@ -984,6 +1014,11 @@
"type": "text", "type": "text",
"placeholders": {} "placeholders": {}
}, },
"Yes": "Yes",
"@Yes": {
"type": "text",
"placeholders": {}
},
"You": "You", "You": "You",
"@You": { "@You": {
"type": "text", "type": "text",

View File

@ -166,6 +166,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Donate" : MessageLookupByLibrary.simpleMessage("Spenden"), "Donate" : MessageLookupByLibrary.simpleMessage("Spenden"),
"Edit displayname" : MessageLookupByLibrary.simpleMessage("Anzeigename ändern"), "Edit displayname" : MessageLookupByLibrary.simpleMessage("Anzeigename ändern"),
"Empty chat" : MessageLookupByLibrary.simpleMessage("Leerer Chat"), "Empty chat" : MessageLookupByLibrary.simpleMessage("Leerer Chat"),
"Encryption algorithm" : MessageLookupByLibrary.simpleMessage("Verschlüsselungsalgorithmus"),
"End-to-end encryption settings" : MessageLookupByLibrary.simpleMessage("Ende-zu-Ende-Verschlüsselung"),
"Enter a group name" : MessageLookupByLibrary.simpleMessage("Gib einen Gruppennamen ein"), "Enter a group name" : MessageLookupByLibrary.simpleMessage("Gib einen Gruppennamen ein"),
"Enter a username" : MessageLookupByLibrary.simpleMessage("Gib einen Benutzernamen ein"), "Enter a username" : MessageLookupByLibrary.simpleMessage("Gib einen Benutzernamen ein"),
"FluffyChat" : MessageLookupByLibrary.simpleMessage("FluffyChat"), "FluffyChat" : MessageLookupByLibrary.simpleMessage("FluffyChat"),
@ -201,10 +203,13 @@ class MessageLookup extends MessageLookupByLibrary {
"New message in FluffyChat" : MessageLookupByLibrary.simpleMessage("Neue Nachricht in FluffyChat"), "New message in FluffyChat" : MessageLookupByLibrary.simpleMessage("Neue Nachricht in FluffyChat"),
"New private chat" : MessageLookupByLibrary.simpleMessage("Neuer privater Chat"), "New private chat" : MessageLookupByLibrary.simpleMessage("Neuer privater Chat"),
"No rooms found..." : MessageLookupByLibrary.simpleMessage("Keine Räume gefunden ..."), "No rooms found..." : MessageLookupByLibrary.simpleMessage("Keine Räume gefunden ..."),
"None" : MessageLookupByLibrary.simpleMessage("Keiner"),
"Not supported in web" : MessageLookupByLibrary.simpleMessage("Wird in der Web-Version nicht unterstützt"), "Not supported in web" : MessageLookupByLibrary.simpleMessage("Wird in der Web-Version nicht unterstützt"),
"Oops something went wrong..." : MessageLookupByLibrary.simpleMessage("Hoppla! Da ist etwas schief gelaufen ..."), "Oops something went wrong..." : MessageLookupByLibrary.simpleMessage("Hoppla! Da ist etwas schief gelaufen ..."),
"Open camera" : MessageLookupByLibrary.simpleMessage("Kamera öffnen"), "Open camera" : MessageLookupByLibrary.simpleMessage("Kamera öffnen"),
"Participating user devices" : MessageLookupByLibrary.simpleMessage("Teilnehmende Geräte"),
"Password" : MessageLookupByLibrary.simpleMessage("Passwort"), "Password" : MessageLookupByLibrary.simpleMessage("Passwort"),
"Please be aware that you need Pantalaimon to use end-to-end encryption for now." : MessageLookupByLibrary.simpleMessage("Bitte beachte, dass du Pantalaimon brauchst, um Ende-zu-Ende-Verschlüsselung benutzen zu können."),
"Please choose a username" : MessageLookupByLibrary.simpleMessage("Bitte wähle einen Benutzernamen"), "Please choose a username" : MessageLookupByLibrary.simpleMessage("Bitte wähle einen Benutzernamen"),
"Please enter a matrix identifier" : MessageLookupByLibrary.simpleMessage("Bitte eine Matrix ID eingeben"), "Please enter a matrix identifier" : MessageLookupByLibrary.simpleMessage("Bitte eine Matrix ID eingeben"),
"Please enter your password" : MessageLookupByLibrary.simpleMessage("Bitte dein Passwort eingeben"), "Please enter your password" : MessageLookupByLibrary.simpleMessage("Bitte dein Passwort eingeben"),
@ -242,11 +247,13 @@ class MessageLookup extends MessageLookupByLibrary {
"Wednesday" : MessageLookupByLibrary.simpleMessage("Mittwoch"), "Wednesday" : MessageLookupByLibrary.simpleMessage("Mittwoch"),
"Who is allowed to join this group" : MessageLookupByLibrary.simpleMessage("Wer darf der Gruppe beitreten"), "Who is allowed to join this group" : MessageLookupByLibrary.simpleMessage("Wer darf der Gruppe beitreten"),
"Write a message..." : MessageLookupByLibrary.simpleMessage("Schreibe eine Nachricht ..."), "Write a message..." : MessageLookupByLibrary.simpleMessage("Schreibe eine Nachricht ..."),
"Yes" : MessageLookupByLibrary.simpleMessage("Ja"),
"You" : MessageLookupByLibrary.simpleMessage("Du"), "You" : MessageLookupByLibrary.simpleMessage("Du"),
"You are invited to this chat" : MessageLookupByLibrary.simpleMessage("Du wurdest eingeladen in diesen Chat"), "You are invited to this chat" : MessageLookupByLibrary.simpleMessage("Du wurdest eingeladen in diesen Chat"),
"You are no longer participating in this chat" : MessageLookupByLibrary.simpleMessage("Du bist kein Teilnehmer mehr in diesem Chat"), "You are no longer participating in this chat" : MessageLookupByLibrary.simpleMessage("Du bist kein Teilnehmer mehr in diesem Chat"),
"You cannot invite yourself" : MessageLookupByLibrary.simpleMessage("Du kannst dich nicht selbst einladen"), "You cannot invite yourself" : MessageLookupByLibrary.simpleMessage("Du kannst dich nicht selbst einladen"),
"You have been banned from this chat" : MessageLookupByLibrary.simpleMessage("Du wurdest aus dem Chat verbannt"), "You have been banned from this chat" : MessageLookupByLibrary.simpleMessage("Du wurdest aus dem Chat verbannt"),
"You won\'t be able to disable the encryption anymore. Are you sure?" : MessageLookupByLibrary.simpleMessage("Du wirst die Verschlüsselung nicht mehr ausstellen können. Bist Du sicher?"),
"Your own username" : MessageLookupByLibrary.simpleMessage("Dein eigener Benutzername"), "Your own username" : MessageLookupByLibrary.simpleMessage("Dein eigener Benutzername"),
"acceptedTheInvitation" : m0, "acceptedTheInvitation" : m0,
"activatedEndToEndEncryption" : m1, "activatedEndToEndEncryption" : m1,

View File

@ -166,6 +166,8 @@ class MessageLookup extends MessageLookupByLibrary {
"Donate" : MessageLookupByLibrary.simpleMessage("Donate"), "Donate" : MessageLookupByLibrary.simpleMessage("Donate"),
"Edit displayname" : MessageLookupByLibrary.simpleMessage("Edit displayname"), "Edit displayname" : MessageLookupByLibrary.simpleMessage("Edit displayname"),
"Empty chat" : MessageLookupByLibrary.simpleMessage("Empty chat"), "Empty chat" : MessageLookupByLibrary.simpleMessage("Empty chat"),
"Encryption algorithm" : MessageLookupByLibrary.simpleMessage("Encryption algorithm"),
"End-to-end encryption settings" : MessageLookupByLibrary.simpleMessage("End-to-end encryption settings"),
"Enter a group name" : MessageLookupByLibrary.simpleMessage("Enter a group name"), "Enter a group name" : MessageLookupByLibrary.simpleMessage("Enter a group name"),
"Enter a username" : MessageLookupByLibrary.simpleMessage("Enter a username"), "Enter a username" : MessageLookupByLibrary.simpleMessage("Enter a username"),
"FluffyChat" : MessageLookupByLibrary.simpleMessage("FluffyChat"), "FluffyChat" : MessageLookupByLibrary.simpleMessage("FluffyChat"),
@ -201,10 +203,13 @@ class MessageLookup extends MessageLookupByLibrary {
"New message in FluffyChat" : MessageLookupByLibrary.simpleMessage("New message in FluffyChat"), "New message in FluffyChat" : MessageLookupByLibrary.simpleMessage("New message in FluffyChat"),
"New private chat" : MessageLookupByLibrary.simpleMessage("New private chat"), "New private chat" : MessageLookupByLibrary.simpleMessage("New private chat"),
"No rooms found..." : MessageLookupByLibrary.simpleMessage("No rooms found..."), "No rooms found..." : MessageLookupByLibrary.simpleMessage("No rooms found..."),
"None" : MessageLookupByLibrary.simpleMessage("None"),
"Not supported in web" : MessageLookupByLibrary.simpleMessage("Not supported in web"), "Not supported in web" : MessageLookupByLibrary.simpleMessage("Not supported in web"),
"Oops something went wrong..." : MessageLookupByLibrary.simpleMessage("Oops something went wrong..."), "Oops something went wrong..." : MessageLookupByLibrary.simpleMessage("Oops something went wrong..."),
"Open camera" : MessageLookupByLibrary.simpleMessage("Open camera"), "Open camera" : MessageLookupByLibrary.simpleMessage("Open camera"),
"Participating user devices" : MessageLookupByLibrary.simpleMessage("Participating user devices"),
"Password" : MessageLookupByLibrary.simpleMessage("Password"), "Password" : MessageLookupByLibrary.simpleMessage("Password"),
"Please be aware that you need Pantalaimon to use end-to-end encryption for now." : MessageLookupByLibrary.simpleMessage("Please be aware that you need Pantalaimon to use end-to-end encryption for now."),
"Please choose a username" : MessageLookupByLibrary.simpleMessage("Please choose a username"), "Please choose a username" : MessageLookupByLibrary.simpleMessage("Please choose a username"),
"Please enter a matrix identifier" : MessageLookupByLibrary.simpleMessage("Please enter a matrix identifier"), "Please enter a matrix identifier" : MessageLookupByLibrary.simpleMessage("Please enter a matrix identifier"),
"Please enter your password" : MessageLookupByLibrary.simpleMessage("Please enter your password"), "Please enter your password" : MessageLookupByLibrary.simpleMessage("Please enter your password"),
@ -242,11 +247,13 @@ class MessageLookup extends MessageLookupByLibrary {
"Wednesday" : MessageLookupByLibrary.simpleMessage("Wednesday"), "Wednesday" : MessageLookupByLibrary.simpleMessage("Wednesday"),
"Who is allowed to join this group" : MessageLookupByLibrary.simpleMessage("Who is allowed to join this group"), "Who is allowed to join this group" : MessageLookupByLibrary.simpleMessage("Who is allowed to join this group"),
"Write a message..." : MessageLookupByLibrary.simpleMessage("Write a message..."), "Write a message..." : MessageLookupByLibrary.simpleMessage("Write a message..."),
"Yes" : MessageLookupByLibrary.simpleMessage("Yes"),
"You" : MessageLookupByLibrary.simpleMessage("You"), "You" : MessageLookupByLibrary.simpleMessage("You"),
"You are invited to this chat" : MessageLookupByLibrary.simpleMessage("You are invited to this chat"), "You are invited to this chat" : MessageLookupByLibrary.simpleMessage("You are invited to this chat"),
"You are no longer participating in this chat" : MessageLookupByLibrary.simpleMessage("You are no longer participating in this chat"), "You are no longer participating in this chat" : MessageLookupByLibrary.simpleMessage("You are no longer participating in this chat"),
"You cannot invite yourself" : MessageLookupByLibrary.simpleMessage("You cannot invite yourself"), "You cannot invite yourself" : MessageLookupByLibrary.simpleMessage("You cannot invite yourself"),
"You have been banned from this chat" : MessageLookupByLibrary.simpleMessage("You have been banned from this chat"), "You have been banned from this chat" : MessageLookupByLibrary.simpleMessage("You have been banned from this chat"),
"You won\'t be able to disable the encryption anymore. Are you sure?" : MessageLookupByLibrary.simpleMessage("You won\'t be able to disable the encryption anymore. Are you sure?"),
"Your own username" : MessageLookupByLibrary.simpleMessage("Your own username"), "Your own username" : MessageLookupByLibrary.simpleMessage("Your own username"),
"acceptedTheInvitation" : m0, "acceptedTheInvitation" : m0,
"activatedEndToEndEncryption" : m1, "activatedEndToEndEncryption" : m1,

View File

@ -0,0 +1,15 @@
extension BeautifyStringExtension on String {
String get beautified {
String beautifiedStr = "";
for (int i = 0; i < this.length; i++) {
beautifiedStr += this.substring(i, i + 1);
if (i % 4 == 3) {
beautifiedStr += " ";
}
if (i % 16 == 15) {
beautifiedStr += "\n";
}
}
return beautifiedStr;
}
}

View File

@ -162,7 +162,9 @@ extension LocalizedBody on Event {
break; break;
case EventTypes.Encryption: case EventTypes.Encryption:
localizedBody = localizedBody =
I18n.of(context).activatedEndToEndEncryption(senderName); I18n.of(context).activatedEndToEndEncryption(senderName) +
". " +
I18n.of(context).needPantalaimonWarning;
break; break;
case EventTypes.Encrypted: case EventTypes.Encrypted:
localizedBody = I18n.of(context).couldNotDecryptMessage; localizedBody = I18n.of(context).couldNotDecryptMessage;

View File

@ -36,6 +36,24 @@ class Store extends StoreAPI {
return await secureStorage.write(key: key, value: value); return await secureStorage.write(key: key, value: value);
} }
Future<Map<String, DeviceKeysList>> getUserDeviceKeys() async {
final deviceKeysListString = await getItem(_UserDeviceKeysKey);
if (deviceKeysListString == null) return {};
Map<String, dynamic> rawUserDeviceKeys = json.decode(deviceKeysListString);
Map<String, DeviceKeysList> userDeviceKeys = {};
for (final entry in rawUserDeviceKeys.entries) {
userDeviceKeys[entry.key] = DeviceKeysList.fromJson(entry.value);
}
return userDeviceKeys;
}
Future<void> storeUserDeviceKeys(
Map<String, DeviceKeysList> userDeviceKeys) async {
await setItem(_UserDeviceKeysKey, json.encode(userDeviceKeys));
}
String get _UserDeviceKeysKey => "${client.clientName}.user_device_keys";
_init() async { _init() async {
final credentialsStr = await getItem(client.clientName); final credentialsStr = await getItem(client.clientName);

View File

@ -8,7 +8,9 @@ import 'package:fluffychat/components/chat_settings_popup_menu.dart';
import 'package:fluffychat/components/list_items/message.dart'; import 'package:fluffychat/components/list_items/message.dart';
import 'package:fluffychat/components/matrix.dart'; import 'package:fluffychat/components/matrix.dart';
import 'package:fluffychat/i18n/i18n.dart'; import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/utils/app_route.dart';
import 'package:fluffychat/utils/room_extension.dart'; import 'package:fluffychat/utils/room_extension.dart';
import 'package:fluffychat/views/chat_encryption_settings.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
@ -422,6 +424,17 @@ class _ChatState extends State<_Chat> {
), ),
)), )),
SizedBox(width: 8), SizedBox(width: 8),
if (sendController.text.isEmpty)
IconButton(
icon: Icon(
room.encrypted ? Icons.lock : Icons.lock_open),
onPressed: () => Navigator.of(context).push(
AppRoute.defaultRoute(
context,
ChatEncryptionSettingsView(widget.id),
),
),
),
IconButton( IconButton(
icon: Icon(Icons.send), icon: Icon(Icons.send),
onPressed: () => send(), onPressed: () => send(),

View File

@ -0,0 +1,159 @@
import 'dart:async';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/adaptive_page_layout.dart';
import 'package:fluffychat/components/dialogs/confirm_dialog.dart';
import 'package:fluffychat/components/matrix.dart';
import 'package:fluffychat/utils/beautify_string_extension.dart';
import 'package:fluffychat/i18n/i18n.dart';
import 'package:fluffychat/views/chat_list.dart';
import 'package:flutter/material.dart';
class ChatEncryptionSettingsView extends StatelessWidget {
final String id;
const ChatEncryptionSettingsView(this.id, {Key key}) : super(key: key);
@override
Widget build(BuildContext context) {
return AdaptivePageLayout(
firstScaffold: ChatList(
activeChat: id,
),
secondScaffold: ChatEncryptionSettings(id),
primaryPage: FocusPage.SECOND,
);
}
}
class ChatEncryptionSettings extends StatefulWidget {
final String id;
const ChatEncryptionSettings(this.id, {Key key}) : super(key: key);
@override
_ChatEncryptionSettingsState createState() => _ChatEncryptionSettingsState();
}
class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
Room room;
StreamSubscription roomUpdate;
@override
void dispose() {
roomUpdate?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
room ??= Matrix.of(context).client.getRoomById(widget.id);
roomUpdate ??= room.onUpdate.stream.listen((s) => setState(() => null));
return Scaffold(
appBar: AppBar(
title: Text(I18n.of(context).end2endEncryptionSettings),
),
body: Column(
children: <Widget>[
ListTile(
title: Text(I18n.of(context).encryptionAlgorithm),
subtitle: Text(room.encryptionAlgorithm ?? I18n.of(context).none),
trailing: Icon(room.encrypted ? Icons.lock : Icons.lock_open),
onTap: () {
if (room.encrypted) return;
showDialog(
context: context,
builder: (BuildContext context) => ConfirmDialog(
I18n.of(context).enableEncryptionWarning +
" " +
I18n.of(context).needPantalaimonWarning,
I18n.of(context).yes,
(context) => Matrix.of(context).tryRequestWithLoadingDialog(
room.enableEncryption(),
),
),
);
},
),
ListTile(
trailing: Icon(Icons.info),
subtitle: Text(
I18n.of(context).needPantalaimonWarning,
),
),
Divider(height: 1),
ListTile(
title: Text(
"${I18n.of(context).participatingUserDevices}:",
style: TextStyle(
fontWeight: FontWeight.bold,
),
),
),
Divider(height: 1),
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: Colors.black),
),
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);
},
),
),
);
},
),
],
),
);
}
}

View File

@ -110,8 +110,8 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
path: "." path: "."
ref: "103eb6734b3c37ffbd124142473bd0080e814f59" ref: "166b1a9464843cd17e86d9330ac8782d6081f46b"
resolved-ref: "103eb6734b3c37ffbd124142473bd0080e814f59" resolved-ref: "166b1a9464843cd17e86d9330ac8782d6081f46b"
url: "https://gitlab.com/famedly/famedlysdk.git" url: "https://gitlab.com/famedly/famedlysdk.git"
source: git source: git
version: "0.0.1" version: "0.0.1"
@ -247,13 +247,6 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.6.1+1" version: "0.6.1+1"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.0"
link_text: link_text:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -27,7 +27,7 @@ dependencies:
famedlysdk: famedlysdk:
git: git:
url: https://gitlab.com/famedly/famedlysdk.git url: https://gitlab.com/famedly/famedlysdk.git
ref: 103eb6734b3c37ffbd124142473bd0080e814f59 ref: 166b1a9464843cd17e86d9330ac8782d6081f46b
localstorage: ^3.0.1+4 localstorage: ^3.0.1+4
bubble: ^1.1.9+1 bubble: ^1.1.9+1