Enhance chatencryptionsettings page
This commit is contained in:
parent
0116031812
commit
6f48a68798
|
@ -97,6 +97,11 @@ class MatrixState extends State<Matrix> {
|
||||||
|
|
||||||
hideLoadingDialog() => Navigator.of(_loadingDialogContext)?.pop();
|
hideLoadingDialog() => Navigator.of(_loadingDialogContext)?.pop();
|
||||||
|
|
||||||
|
bool get encryptionEnabled =>
|
||||||
|
client.userDeviceKeys.containsKey(client.userID) &&
|
||||||
|
client.userDeviceKeys[client.userID].deviceKeys
|
||||||
|
.containsKey(client.deviceID);
|
||||||
|
|
||||||
Future<String> downloadAndSaveContent(MxContent content,
|
Future<String> downloadAndSaveContent(MxContent content,
|
||||||
{int width, int height, ThumbnailMethod method}) async {
|
{int width, int height, ThumbnailMethod method}) async {
|
||||||
final bool thumbnail = width == null && height == null ? false : true;
|
final bool thumbnail = width == null && height == null ? false : true;
|
||||||
|
|
|
@ -383,58 +383,61 @@ class _ChatState extends State<_Chat> {
|
||||||
),
|
),
|
||||||
SizedBox(width: 8),
|
SizedBox(width: 8),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||||
child: TextField(
|
child: TextField(
|
||||||
minLines: 1,
|
minLines: 1,
|
||||||
maxLines: kIsWeb ? 1 : 8,
|
maxLines: kIsWeb ? 1 : 8,
|
||||||
keyboardType: kIsWeb
|
keyboardType: kIsWeb
|
||||||
? TextInputType.text
|
? TextInputType.text
|
||||||
: TextInputType.multiline,
|
: TextInputType.multiline,
|
||||||
onSubmitted: (String text) {
|
onSubmitted: (String text) {
|
||||||
send();
|
send();
|
||||||
FocusScope.of(context).requestFocus(inputFocus);
|
FocusScope.of(context).requestFocus(inputFocus);
|
||||||
},
|
},
|
||||||
focusNode: inputFocus,
|
focusNode: inputFocus,
|
||||||
controller: sendController,
|
controller: sendController,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: I18n.of(context).writeAMessage,
|
hintText: I18n.of(context).writeAMessage,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
),
|
suffixIcon: sendController.text.isEmpty
|
||||||
onChanged: (String text) {
|
? InkWell(
|
||||||
this.typingCoolDown?.cancel();
|
child: Icon(room.encrypted
|
||||||
this.typingCoolDown =
|
? Icons.lock
|
||||||
Timer(Duration(seconds: 2), () {
|
: Icons.lock_open),
|
||||||
this.typingCoolDown = null;
|
onTap: () => Navigator.of(context).push(
|
||||||
this.currentlyTyping = false;
|
AppRoute.defaultRoute(
|
||||||
room.sendTypingInfo(false);
|
context,
|
||||||
});
|
ChatEncryptionSettingsView(
|
||||||
this.typingTimeout ??=
|
widget.id),
|
||||||
Timer(Duration(seconds: 30), () {
|
),
|
||||||
this.typingTimeout = null;
|
),
|
||||||
this.currentlyTyping = false;
|
)
|
||||||
});
|
: null,
|
||||||
if (!this.currentlyTyping) {
|
|
||||||
this.currentlyTyping = true;
|
|
||||||
room.sendTypingInfo(true,
|
|
||||||
timeout:
|
|
||||||
Duration(seconds: 30).inMilliseconds);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
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),
|
|
||||||
),
|
),
|
||||||
|
onChanged: (String text) {
|
||||||
|
this.typingCoolDown?.cancel();
|
||||||
|
this.typingCoolDown =
|
||||||
|
Timer(Duration(seconds: 2), () {
|
||||||
|
this.typingCoolDown = null;
|
||||||
|
this.currentlyTyping = false;
|
||||||
|
room.sendTypingInfo(false);
|
||||||
|
});
|
||||||
|
this.typingTimeout ??=
|
||||||
|
Timer(Duration(seconds: 30), () {
|
||||||
|
this.typingTimeout = null;
|
||||||
|
this.currentlyTyping = false;
|
||||||
|
});
|
||||||
|
if (!this.currentlyTyping) {
|
||||||
|
this.currentlyTyping = true;
|
||||||
|
room.sendTypingInfo(true,
|
||||||
|
timeout:
|
||||||
|
Duration(seconds: 30).inMilliseconds);
|
||||||
|
}
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(Icons.send),
|
icon: Icon(Icons.send),
|
||||||
onPressed: () => send(),
|
onPressed: () => send(),
|
||||||
|
|
|
@ -8,6 +8,7 @@ import 'package:fluffychat/utils/beautify_string_extension.dart';
|
||||||
import 'package:fluffychat/i18n/i18n.dart';
|
import 'package:fluffychat/i18n/i18n.dart';
|
||||||
import 'package:fluffychat/views/chat_list.dart';
|
import 'package:fluffychat/views/chat_list.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:toast/toast.dart';
|
||||||
|
|
||||||
class ChatEncryptionSettingsView extends StatelessWidget {
|
class ChatEncryptionSettingsView extends StatelessWidget {
|
||||||
final String id;
|
final String id;
|
||||||
|
@ -49,6 +50,7 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
room ??= Matrix.of(context).client.getRoomById(widget.id);
|
room ??= Matrix.of(context).client.getRoomById(widget.id);
|
||||||
roomUpdate ??= room.onUpdate.stream.listen((s) => setState(() => null));
|
roomUpdate ??= room.onUpdate.stream.listen((s) => setState(() => null));
|
||||||
|
print(Matrix.of(context).client.userDeviceKeys.length);
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
@ -59,15 +61,19 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
|
||||||
ListTile(
|
ListTile(
|
||||||
title: Text(I18n.of(context).encryptionAlgorithm),
|
title: Text(I18n.of(context).encryptionAlgorithm),
|
||||||
subtitle: Text(room.encryptionAlgorithm ?? I18n.of(context).none),
|
subtitle: Text(room.encryptionAlgorithm ?? I18n.of(context).none),
|
||||||
trailing: Icon(room.encrypted ? Icons.lock : Icons.lock_open),
|
trailing: Icon(room.encrypted ? Icons.lock : Icons.lock_open,
|
||||||
|
color: room.encrypted ? Colors.green : Colors.red),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
if (room.encrypted) return;
|
if (room.encrypted) return;
|
||||||
|
if (!Matrix.of(context).encryptionEnabled) {
|
||||||
|
Toast.show(I18n.of(context).needPantalaimonWarning, context,
|
||||||
|
duration: 8);
|
||||||
|
return;
|
||||||
|
}
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) => ConfirmDialog(
|
builder: (BuildContext context) => ConfirmDialog(
|
||||||
I18n.of(context).enableEncryptionWarning +
|
I18n.of(context).enableEncryptionWarning,
|
||||||
" " +
|
|
||||||
I18n.of(context).needPantalaimonWarning,
|
|
||||||
I18n.of(context).yes,
|
I18n.of(context).yes,
|
||||||
(context) => Matrix.of(context).tryRequestWithLoadingDialog(
|
(context) => Matrix.of(context).tryRequestWithLoadingDialog(
|
||||||
room.enableEncryption(),
|
room.enableEncryption(),
|
||||||
|
@ -83,75 +89,77 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Divider(height: 1),
|
Divider(height: 1),
|
||||||
ListTile(
|
if (room.encrypted)
|
||||||
title: Text(
|
ListTile(
|
||||||
"${I18n.of(context).participatingUserDevices}:",
|
title: Text(
|
||||||
style: TextStyle(
|
"${I18n.of(context).participatingUserDevices}:",
|
||||||
fontWeight: FontWeight.bold,
|
style: TextStyle(
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (room.encrypted) Divider(height: 1),
|
||||||
Divider(height: 1),
|
if (room.encrypted)
|
||||||
FutureBuilder<List<DeviceKeys>>(
|
FutureBuilder<List<DeviceKeys>>(
|
||||||
future: room.getUserDeviceKeys(),
|
future: room.getUserDeviceKeys(),
|
||||||
builder: (BuildContext context, snapshot) {
|
builder: (BuildContext context, snapshot) {
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(I18n.of(context).oopsSomethingWentWrong +
|
child: Text(I18n.of(context).oopsSomethingWentWrong +
|
||||||
": " +
|
": " +
|
||||||
snapshot.error.toString()),
|
snapshot.error.toString()),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!snapshot.hasData) {
|
if (!snapshot.hasData) {
|
||||||
return Center(child: CircularProgressIndicator());
|
return Center(child: CircularProgressIndicator());
|
||||||
}
|
}
|
||||||
final List<DeviceKeys> deviceKeys = snapshot.data;
|
final List<DeviceKeys> deviceKeys = snapshot.data;
|
||||||
return Expanded(
|
return Expanded(
|
||||||
child: ListView.separated(
|
child: ListView.separated(
|
||||||
separatorBuilder: (BuildContext context, int i) =>
|
separatorBuilder: (BuildContext context, int i) =>
|
||||||
Divider(height: 1),
|
Divider(height: 1),
|
||||||
itemCount: deviceKeys.length,
|
itemCount: deviceKeys.length,
|
||||||
itemBuilder: (BuildContext context, int i) =>
|
itemBuilder: (BuildContext context, int i) =>
|
||||||
CheckboxListTile(
|
CheckboxListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
"${deviceKeys[i].userId} - ${deviceKeys[i].deviceId}",
|
"${deviceKeys[i].userId} - ${deviceKeys[i].deviceId}",
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: deviceKeys[i].blocked
|
color: deviceKeys[i].blocked
|
||||||
? Colors.red
|
? Colors.red
|
||||||
: deviceKeys[i].verified
|
: deviceKeys[i].verified
|
||||||
? Colors.green
|
? Colors.green
|
||||||
: Colors.orange),
|
: Colors.orange),
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
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]
|
deviceKeys[i]
|
||||||
.setVerified(true, Matrix.of(context).client);
|
.keys["ed25519:${deviceKeys[i].deviceId}"]
|
||||||
} else {
|
.beautified,
|
||||||
if (deviceKeys[i].verified) {
|
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]
|
deviceKeys[i]
|
||||||
.setVerified(false, Matrix.of(context).client);
|
.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);
|
||||||
}
|
}
|
||||||
deviceKeys[i]
|
setState(() => null);
|
||||||
.setBlocked(true, Matrix.of(context).client);
|
},
|
||||||
}
|
),
|
||||||
setState(() => null);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -110,8 +110,8 @@ packages:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: "166b1a9464843cd17e86d9330ac8782d6081f46b"
|
ref: "6a6ca40e96712d2ad3638fec7ec3ec5b17eaedca"
|
||||||
resolved-ref: "166b1a9464843cd17e86d9330ac8782d6081f46b"
|
resolved-ref: "6a6ca40e96712d2ad3638fec7ec3ec5b17eaedca"
|
||||||
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"
|
||||||
|
|
|
@ -27,7 +27,7 @@ dependencies:
|
||||||
famedlysdk:
|
famedlysdk:
|
||||||
git:
|
git:
|
||||||
url: https://gitlab.com/famedly/famedlysdk.git
|
url: https://gitlab.com/famedly/famedlysdk.git
|
||||||
ref: 166b1a9464843cd17e86d9330ac8782d6081f46b
|
ref: 4bf6a4bcb60ca8877b5f2d435978e47358c20cad
|
||||||
|
|
||||||
localstorage: ^3.0.1+4
|
localstorage: ^3.0.1+4
|
||||||
bubble: ^1.1.9+1
|
bubble: ^1.1.9+1
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/main.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('Test if the app starts', (WidgetTester tester) async {
|
testWidgets('Test if the app starts', (WidgetTester tester) async {
|
||||||
// Build our app and trigger a frame.
|
// Build our app and trigger a frame.
|
||||||
|
|
Loading…
Reference in a new issue