mirror of
https://gitlab.com/famedly/fluffychat.git
synced 2025-02-25 19:00:45 +01:00
chore: Nicer verification dialog
This commit is contained in:
parent
b1699cfa16
commit
94b19cf6a6
@ -1,7 +1,6 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
@ -11,25 +10,15 @@ import 'package:future_loading_dialog/future_loading_dialog.dart';
|
|||||||
import 'package:matrix/encryption.dart';
|
import 'package:matrix/encryption.dart';
|
||||||
import 'package:matrix/matrix.dart';
|
import 'package:matrix/matrix.dart';
|
||||||
|
|
||||||
import 'package:fluffychat/utils/platform_infos.dart';
|
|
||||||
import 'package:fluffychat/widgets/avatar.dart';
|
import 'package:fluffychat/widgets/avatar.dart';
|
||||||
import '../../utils/beautify_string_extension.dart';
|
|
||||||
import '../../widgets/adaptive_flat_button.dart';
|
|
||||||
|
|
||||||
class KeyVerificationDialog extends StatefulWidget {
|
class KeyVerificationDialog extends StatefulWidget {
|
||||||
Future<void> show(BuildContext context) => PlatformInfos.isCupertinoStyle
|
Future<void> show(BuildContext context) => showModalBottomSheet(
|
||||||
? showCupertinoDialog(
|
context: context,
|
||||||
context: context,
|
builder: (context) => this,
|
||||||
barrierDismissible: true,
|
useRootNavigator: true,
|
||||||
builder: (context) => this,
|
isDismissible: false,
|
||||||
useRootNavigator: false,
|
);
|
||||||
)
|
|
||||||
: showDialog(
|
|
||||||
context: context,
|
|
||||||
barrierDismissible: true,
|
|
||||||
builder: (context) => this,
|
|
||||||
useRootNavigator: false,
|
|
||||||
);
|
|
||||||
|
|
||||||
final KeyVerification request;
|
final KeyVerification request;
|
||||||
|
|
||||||
@ -152,12 +141,16 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton(
|
||||||
label: L10n.of(context)!.submit,
|
child: Text(
|
||||||
|
L10n.of(context)!.submit,
|
||||||
|
),
|
||||||
onPressed: () => checkInput(textEditingController.text),
|
onPressed: () => checkInput(textEditingController.text),
|
||||||
));
|
));
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton(
|
||||||
label: L10n.of(context)!.skip,
|
child: Text(
|
||||||
|
L10n.of(context)!.skip,
|
||||||
|
),
|
||||||
onPressed: () => widget.request.openSSSS(skip: true),
|
onPressed: () => widget.request.openSSSS(skip: true),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
@ -166,102 +159,78 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
body = Column(
|
body = Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Row(children: [
|
|
||||||
if (!PlatformInfos.isCupertinoStyle)
|
|
||||||
Avatar(mxContent: user?.avatarUrl, name: displayName),
|
|
||||||
const SizedBox(width: 12),
|
|
||||||
Expanded(
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
crossAxisAlignment: PlatformInfos.isCupertinoStyle
|
|
||||||
? CrossAxisAlignment.center
|
|
||||||
: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
displayName,
|
|
||||||
style: const TextStyle(fontSize: 16),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
'${widget.request.userId} - ${widget.request.deviceId}',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontWeight: FontWeight.w300,
|
|
||||||
fontSize: 14,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Image.asset('assets/verification.png', fit: BoxFit.contain),
|
Avatar(
|
||||||
|
mxContent: user?.avatarUrl,
|
||||||
|
name: displayName,
|
||||||
|
size: Avatar.defaultSize * 2,
|
||||||
|
),
|
||||||
const SizedBox(height: 16),
|
const SizedBox(height: 16),
|
||||||
Text(
|
Text(
|
||||||
L10n.of(context)!.askVerificationRequest(displayName),
|
L10n.of(context)!.askVerificationRequest(displayName),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton.icon(
|
||||||
label: L10n.of(context)!.reject,
|
icon: const Icon(Icons.close),
|
||||||
textColor: Colors.red,
|
style: TextButton.styleFrom(foregroundColor: Colors.red),
|
||||||
|
label: Text(L10n.of(context)!.reject),
|
||||||
onPressed: () => widget.request
|
onPressed: () => widget.request
|
||||||
.rejectVerification()
|
.rejectVerification()
|
||||||
.then((_) => Navigator.of(context, rootNavigator: false).pop()),
|
.then((_) => Navigator.of(context, rootNavigator: false).pop()),
|
||||||
));
|
));
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton.icon(
|
||||||
label: L10n.of(context)!.accept,
|
icon: const Icon(Icons.check),
|
||||||
|
label: Text(L10n.of(context)!.accept),
|
||||||
onPressed: () => widget.request.acceptVerification(),
|
onPressed: () => widget.request.acceptVerification(),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
case KeyVerificationState.waitingAccept:
|
case KeyVerificationState.waitingAccept:
|
||||||
body = Column(
|
body = Center(
|
||||||
mainAxisSize: MainAxisSize.min,
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Image.asset('assets/verification.png', fit: BoxFit.contain),
|
Stack(
|
||||||
const SizedBox(height: 16),
|
alignment: Alignment.center,
|
||||||
const CircularProgressIndicator.adaptive(strokeWidth: 2),
|
children: [
|
||||||
const SizedBox(height: 16),
|
Avatar(
|
||||||
Text(
|
mxContent: user?.avatarUrl,
|
||||||
L10n.of(context)!.waitingPartnerAcceptRequest,
|
name: displayName,
|
||||||
textAlign: TextAlign.center,
|
),
|
||||||
),
|
const SizedBox(
|
||||||
],
|
width: Avatar.defaultSize + 2,
|
||||||
|
height: Avatar.defaultSize + 2,
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
const SizedBox(height: 16),
|
||||||
|
Text(
|
||||||
|
L10n.of(context)!.waitingPartnerAcceptRequest,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
final key = widget.request.client.userDeviceKeys[widget.request.userId]
|
|
||||||
?.deviceKeys[widget.request.deviceId];
|
|
||||||
if (key != null) {
|
|
||||||
buttons.add(AdaptiveFlatButton(
|
|
||||||
label: L10n.of(context)!.verifyManual,
|
|
||||||
onPressed: () async {
|
|
||||||
final result = await showOkCancelAlertDialog(
|
|
||||||
useRootNavigator: false,
|
|
||||||
context: context,
|
|
||||||
title: L10n.of(context)!.verifyManual,
|
|
||||||
message: key.ed25519Key?.beautified ?? 'Key not found',
|
|
||||||
);
|
|
||||||
if (result == OkCancelResult.ok) {
|
|
||||||
await key.setVerified(true);
|
|
||||||
}
|
|
||||||
await widget.request.cancel();
|
|
||||||
Navigator.of(context, rootNavigator: false).pop();
|
|
||||||
},
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case KeyVerificationState.askSas:
|
case KeyVerificationState.askSas:
|
||||||
TextSpan compareWidget;
|
TextSpan compareWidget;
|
||||||
// maybe add a button to switch between the two and only determine default
|
// maybe add a button to switch between the two and only determine default
|
||||||
// view for if "emoji" is a present sasType or not?
|
// view for if "emoji" is a present sasType or not?
|
||||||
String compareText;
|
|
||||||
if (widget.request.sasTypes.contains('emoji')) {
|
if (widget.request.sasTypes.contains('emoji')) {
|
||||||
compareText = L10n.of(context)!.compareEmojiMatch;
|
title = Text(
|
||||||
|
L10n.of(context)!.compareEmojiMatch,
|
||||||
|
maxLines: 2,
|
||||||
|
style: const TextStyle(fontSize: 16),
|
||||||
|
);
|
||||||
compareWidget = TextSpan(
|
compareWidget = TextSpan(
|
||||||
children: widget.request.sasEmojis
|
children: widget.request.sasEmojis
|
||||||
.map((e) => WidgetSpan(child: _Emoji(e, sasEmoji)))
|
.map((e) => WidgetSpan(child: _Emoji(e, sasEmoji)))
|
||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
compareText = L10n.of(context)!.compareNumbersMatch;
|
title = Text(L10n.of(context)!.compareNumbersMatch);
|
||||||
final numbers = widget.request.sasNumbers;
|
final numbers = widget.request.sasNumbers;
|
||||||
final numbstr = '${numbers[0]}-${numbers[1]}-${numbers[2]}';
|
final numbstr = '${numbers[0]}-${numbers[1]}-${numbers[2]}';
|
||||||
compareWidget =
|
compareWidget =
|
||||||
@ -270,27 +239,23 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
body = Column(
|
body = Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Center(
|
|
||||||
child: Text(
|
|
||||||
compareText,
|
|
||||||
style: const TextStyle(fontSize: 16),
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const SizedBox(height: 10),
|
|
||||||
Text.rich(
|
Text.rich(
|
||||||
compareWidget,
|
compareWidget,
|
||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton.icon(
|
||||||
textColor: Colors.red,
|
icon: const Icon(Icons.close),
|
||||||
label: L10n.of(context)!.theyDontMatch,
|
style: TextButton.styleFrom(
|
||||||
|
foregroundColor: Colors.red,
|
||||||
|
),
|
||||||
|
label: Text(L10n.of(context)!.theyDontMatch),
|
||||||
onPressed: () => widget.request.rejectSas(),
|
onPressed: () => widget.request.rejectSas(),
|
||||||
));
|
));
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton.icon(
|
||||||
label: L10n.of(context)!.theyMatch,
|
icon: const Icon(Icons.check_outlined),
|
||||||
|
label: Text(L10n.of(context)!.theyMatch),
|
||||||
onPressed: () => widget.request.acceptSas(),
|
onPressed: () => widget.request.acceptSas(),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
@ -315,7 +280,7 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const Icon(Icons.check_circle_outlined,
|
const Icon(Icons.check_circle_outlined,
|
||||||
color: Colors.green, size: 200.0),
|
color: Colors.green, size: 128.0),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
L10n.of(context)!.verifySuccess,
|
L10n.of(context)!.verifySuccess,
|
||||||
@ -323,8 +288,10 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton(
|
||||||
label: L10n.of(context)!.close,
|
child: Text(
|
||||||
|
L10n.of(context)!.close,
|
||||||
|
),
|
||||||
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
|
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
@ -332,7 +299,7 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
body = Column(
|
body = Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
const Icon(Icons.cancel, color: Colors.red, size: 200.0),
|
const Icon(Icons.cancel, color: Colors.red, size: 128.0),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
'Error ${widget.request.canceledCode}: ${widget.request.canceledReason}',
|
'Error ${widget.request.canceledCode}: ${widget.request.canceledReason}',
|
||||||
@ -340,33 +307,32 @@ class KeyVerificationPageState extends State<KeyVerificationDialog> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
buttons.add(AdaptiveFlatButton(
|
buttons.add(TextButton(
|
||||||
label: L10n.of(context)!.close,
|
child: Text(
|
||||||
|
L10n.of(context)!.close,
|
||||||
|
),
|
||||||
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
|
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
|
||||||
));
|
));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
final content = SingleChildScrollView(
|
return Scaffold(
|
||||||
scrollDirection: Axis.vertical,
|
appBar: AppBar(
|
||||||
child: Column(
|
leading: const CloseButton(),
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
body,
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
if (PlatformInfos.isCupertinoStyle) {
|
|
||||||
return CupertinoAlertDialog(
|
|
||||||
title: title,
|
title: title,
|
||||||
content: content,
|
),
|
||||||
actions: buttons,
|
body: ListView(
|
||||||
);
|
padding: const EdgeInsets.all(12.0),
|
||||||
}
|
children: [body],
|
||||||
return AlertDialog(
|
),
|
||||||
title: title,
|
bottomNavigationBar: SafeArea(
|
||||||
content: content,
|
child: Padding(
|
||||||
actions: buttons,
|
padding: const EdgeInsets.all(12.0),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
children: buttons,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user