Merge branch 'krille/fix-dialogs' into 'main'

fix: Dialog using wrong Navigator

Closes #264

See merge request famedly/fluffychat!388
This commit is contained in:
Krille Fear 2021-02-24 17:59:56 +00:00
commit b49abeca46
30 changed files with 240 additions and 193 deletions

View File

@ -68,6 +68,7 @@ class _ChatSettingsPopupMenuState extends State<ChatSettingsPopupMenu> {
case 'leave':
var confirmed = await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,

View File

@ -3,6 +3,7 @@ import 'package:famedlysdk/encryption.dart';
import 'package:famedlysdk/encryption/utils/bootstrap.dart';
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/components/dialogs/adaptive_flat_button.dart';
import 'package:fluffychat/components/matrix.dart';
import 'package:flutter/services.dart';
import 'package:fluffychat/utils/platform_infos.dart';
import 'package:flutter/cupertino.dart';
@ -15,17 +16,20 @@ class BootstrapDialog extends StatefulWidget {
final bool wipe;
const BootstrapDialog({
Key key,
@required this.l10n,
@required this.client,
this.wipe = false,
}) : super(key: key);
Future<bool> show(BuildContext context) => PlatformInfos.isCupertinoStyle
? showCupertinoDialog(context: context, builder: (context) => this)
: showDialog(context: context, builder: (context) => this);
final L10n l10n;
final Client client;
? showCupertinoDialog(
context: context,
builder: (context) => this,
useRootNavigator: false,
)
: showDialog(
context: context,
builder: (context) => this,
useRootNavigator: false,
);
@override
_BootstrapDialogState createState() => _BootstrapDialogState();
@ -52,7 +56,9 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
_wipe = wipe;
titleText = null;
_recoveryKeyStored = false;
bootstrap = widget.client.encryption
bootstrap = Matrix.of(context)
.client
.encryption
.bootstrap(onUpdate: () => setState(() => null));
});
}
@ -62,19 +68,19 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
_wipe ??= widget.wipe;
final buttons = <AdaptiveFlatButton>[];
Widget body = LinearProgressIndicator();
titleText = widget.l10n.loadingPleaseWait;
titleText = L10n.of(context).loadingPleaseWait;
if (bootstrap == null) {
titleText = widget.l10n.chatBackup;
body = Text(widget.l10n.chatBackupDescription);
titleText = L10n.of(context).chatBackup;
body = Text(L10n.of(context).chatBackupDescription);
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.next),
child: Text(L10n.of(context).next),
onPressed: () => _createBootstrap(false),
));
} else if (bootstrap.newSsssKey?.recoveryKey != null &&
_recoveryKeyStored == false) {
final key = bootstrap.newSsssKey.recoveryKey;
titleText = widget.l10n.securityKey;
titleText = L10n.of(context).securityKey;
body = Container(
alignment: Alignment.center,
width: 200,
@ -89,11 +95,11 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
),
);
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.copyToClipboard),
child: Text(L10n.of(context).copyToClipboard),
onPressed: () => Clipboard.setData(ClipboardData(text: key)),
));
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.next),
child: Text(L10n.of(context).next),
onPressed: () => setState(() => _recoveryKeyStored = true),
));
} else {
@ -120,7 +126,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
case BootstrapState.openExistingSsss:
_recoveryKeyStored = true;
titleText =
_recoveryKeyInputError ?? widget.l10n.pleaseEnterSecurityKey;
_recoveryKeyInputError ?? L10n.of(context).pleaseEnterSecurityKey;
body = PlatformInfos.isCupertinoStyle
? CupertinoTextField(
minLines: 2,
@ -149,10 +155,11 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
if (OkCancelResult.ok ==
await showOkCancelAlertDialog(
context: context,
title: widget.l10n.securityKeyLost,
message: widget.l10n.wipeChatBackup,
okLabel: widget.l10n.ok,
cancelLabel: widget.l10n.cancel,
useRootNavigator: false,
title: L10n.of(context).securityKeyLost,
message: L10n.of(context).wipeChatBackup,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
isDestructiveAction: true,
)) {
_createBootstrap(true);
@ -160,20 +167,18 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
},
));
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.transferFromAnotherDevice),
child: Text(L10n.of(context).transferFromAnotherDevice),
onPressed: () async {
final req = await widget
.client.userDeviceKeys[widget.client.userID]
final req = await Matrix.of(context)
.client
.userDeviceKeys[Matrix.of(context).client.userID]
.startVerification();
await KeyVerificationDialog(
request: req,
l10n: widget.l10n,
).show(context);
Navigator.of(context).pop();
await KeyVerificationDialog(request: req).show(context);
Navigator.of(context, rootNavigator: false).pop();
},
));
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.next),
child: Text(L10n.of(context).next),
onPressed: () async {
setState(() {
_recoveryKeyInputError = null;
@ -187,7 +192,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
} catch (e, s) {
Logs().w('Unable to unlock SSSS', e, s);
setState(() => _recoveryKeyInputError =
widget.l10n.oopsSomethingWentWrong);
L10n.of(context).oopsSomethingWentWrong);
} finally {
setState(() => _recoveryKeyInputLoading = false);
}
@ -220,27 +225,29 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
break;
case BootstrapState.askBadSsss:
case BootstrapState.error:
titleText = widget.l10n.oopsSomethingWentWrong;
titleText = L10n.of(context).oopsSomethingWentWrong;
body = ListTile(
contentPadding: EdgeInsets.zero,
leading: Icon(Icons.error_outline, color: Colors.red),
title: Text(widget.l10n.oopsSomethingWentWrong),
title: Text(L10n.of(context).oopsSomethingWentWrong),
);
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.close),
onPressed: () => Navigator.of(context).pop<bool>(false),
child: Text(L10n.of(context).close),
onPressed: () =>
Navigator.of(context, rootNavigator: false).pop<bool>(false),
));
break;
case BootstrapState.done:
titleText = widget.l10n.everythingReady;
titleText = L10n.of(context).everythingReady;
body = ListTile(
contentPadding: EdgeInsets.zero,
leading: Icon(Icons.check_circle, color: Colors.green),
title: Text(widget.l10n.keysCached),
title: Text(L10n.of(context).keysCached),
);
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.close),
onPressed: () => Navigator.of(context).pop<bool>(false),
child: Text(L10n.of(context).close),
onPressed: () =>
Navigator.of(context, rootNavigator: false).pop<bool>(false),
));
break;
}

View File

@ -12,16 +12,21 @@ import '../../utils/beautify_string_extension.dart';
class KeyVerificationDialog extends StatefulWidget {
Future<void> show(BuildContext context) => PlatformInfos.isCupertinoStyle
? showCupertinoDialog(context: context, builder: (context) => this)
: showDialog(context: context, builder: (context) => this);
? showCupertinoDialog(
context: context,
builder: (context) => this,
useRootNavigator: false,
)
: showDialog(
context: context,
builder: (context) => this,
useRootNavigator: false,
);
final KeyVerification request;
final L10n l10n;
KeyVerificationDialog({
this.request,
@required this.l10n,
});
@override
@ -92,7 +97,8 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
if (valid.error != null) {
await showOkAlertDialog(
context: context,
message: widget.l10n.incorrectPassphraseOrKey,
message: L10n.of(context).incorrectPassphraseOrKey,
useRootNavigator: false,
);
}
};
@ -100,7 +106,8 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
margin: EdgeInsets.only(left: 8.0, right: 8.0),
child: Column(
children: <Widget>[
Text(widget.l10n.askSSSSSign, style: TextStyle(fontSize: 20)),
Text(L10n.of(context).askSSSSSign,
style: TextStyle(fontSize: 20)),
Container(height: 10),
TextField(
controller: textEditingController,
@ -114,7 +121,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
maxLines: 1,
obscureText: true,
decoration: InputDecoration(
hintText: widget.l10n.passphraseOrKey,
hintText: L10n.of(context).passphraseOrKey,
prefixStyle: TextStyle(color: Theme.of(context).primaryColor),
suffixStyle: TextStyle(color: Theme.of(context).primaryColor),
border: OutlineInputBorder(),
@ -125,32 +132,33 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
),
);
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.submit),
child: Text(L10n.of(context).submit),
onPressed: () {
input = textEditingController.text;
checkInput();
},
));
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.skip),
child: Text(L10n.of(context).skip),
onPressed: () => widget.request.openSSSS(skip: true),
));
break;
case KeyVerificationState.askAccept:
body = Container(
child: Text(widget.l10n.askVerificationRequest(widget.request.userId),
child: Text(
L10n.of(context).askVerificationRequest(widget.request.userId),
style: TextStyle(fontSize: 20)),
margin: EdgeInsets.only(left: 8.0, right: 8.0),
);
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.accept),
child: Text(L10n.of(context).accept),
onPressed: () => widget.request.acceptVerification(),
));
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.reject),
child: Text(L10n.of(context).reject),
onPressed: () {
widget.request.rejectVerification().then((_) {
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
});
},
));
@ -163,7 +171,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
: CircularProgressIndicator(),
SizedBox(height: 10),
Text(
widget.l10n.waitingPartnerAcceptRequest,
L10n.of(context).waitingPartnerAcceptRequest,
textAlign: TextAlign.center,
),
],
@ -173,18 +181,19 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
.deviceKeys[widget.request.deviceId];
if (key != null) {
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.verifyManual),
child: Text(L10n.of(context).verifyManual),
onPressed: () async {
final result = await showOkCancelAlertDialog(
context: context,
title: widget.l10n.verifyManual,
useRootNavigator: false,
title: L10n.of(context).verifyManual,
message: key.ed25519Key.beautified,
);
if (result == OkCancelResult.ok) {
await key.setVerified(true);
}
await widget.request.cancel();
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
},
));
}
@ -196,14 +205,14 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
// view for if "emoji" is a present sasType or not?
String compareText;
if (widget.request.sasTypes.contains('emoji')) {
compareText = widget.l10n.compareEmojiMatch;
compareText = L10n.of(context).compareEmojiMatch;
compareWidget = TextSpan(
children: widget.request.sasEmojis
.map((e) => WidgetSpan(child: _Emoji(e)))
.toList(),
);
} else {
compareText = widget.l10n.compareNumbersMatch;
compareText = L10n.of(context).compareNumbersMatch;
final numbers = widget.request.sasNumbers;
final numbstr = '${numbers[0]}-${numbers[1]}-${numbers[2]}';
compareWidget =
@ -228,18 +237,18 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
);
buttons.add(AdaptiveFlatButton(
textColor: Colors.red,
child: Text(widget.l10n.theyDontMatch),
child: Text(L10n.of(context).theyDontMatch),
onPressed: () => widget.request.rejectSas(),
));
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.theyMatch),
child: Text(L10n.of(context).theyMatch),
onPressed: () => widget.request.acceptSas(),
));
break;
case KeyVerificationState.waitingSas:
var acceptText = widget.request.sasTypes.contains('emoji')
? widget.l10n.waitingPartnerEmoji
: widget.l10n.waitingPartnerNumbers;
? L10n.of(context).waitingPartnerEmoji
: L10n.of(context).waitingPartnerNumbers;
body = Column(
children: <Widget>[
PlatformInfos.isCupertinoStyle
@ -260,15 +269,15 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
Icon(Icons.check_circle_outlined, color: Colors.green, size: 200.0),
SizedBox(height: 10),
Text(
widget.l10n.verifySuccess,
L10n.of(context).verifySuccess,
textAlign: TextAlign.center,
),
],
mainAxisSize: MainAxisSize.min,
);
buttons.add(AdaptiveFlatButton(
child: Text(widget.l10n.close),
onPressed: () => Navigator.of(context).pop(),
child: Text(L10n.of(context).close),
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
));
break;
case KeyVerificationState.error:
@ -284,8 +293,8 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
mainAxisSize: MainAxisSize.min,
);
buttons.add(FlatButton(
child: Text(widget.l10n.close),
onPressed: () => Navigator.of(context).pop(),
child: Text(L10n.of(context).close),
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
));
break;
}
@ -329,7 +338,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
],
crossAxisAlignment: CrossAxisAlignment.start,
);
final title = Text(widget.l10n.verifyTitle);
final title = Text(L10n.of(context).verifyTitle);
final content = Scrollbar(
isAlwaysShown: true,
controller: _scrollController,

View File

@ -8,14 +8,19 @@ class PermissionSliderDialog extends StatefulWidget {
const PermissionSliderDialog({
Key key,
this.initialPermission = 0,
@required this.l10n,
}) : super(key: key);
final L10n l10n;
Future<int> show(BuildContext context) => PlatformInfos.isCupertinoStyle
? showCupertinoDialog<int>(context: context, builder: (context) => this)
: showDialog<int>(context: context, builder: (context) => this);
? showCupertinoDialog<int>(
context: context,
builder: (context) => this,
useRootNavigator: false,
)
: showDialog<int>(
context: context,
builder: (context) => this,
useRootNavigator: false,
);
final int initialPermission;
@override
@ -46,7 +51,7 @@ class _PermissionSliderDialogState extends State<PermissionSliderDialog> {
min: 0.0,
);
final title = Text(
widget.l10n.setPermissionsLevel,
L10n.of(context).setPermissionsLevel,
textAlign: TextAlign.center,
);
final content = Column(
@ -54,9 +59,9 @@ class _PermissionSliderDialogState extends State<PermissionSliderDialog> {
children: [
Text('Level: ' +
(_permission == 100
? '$_permission (${widget.l10n.admin})'
? '$_permission (${L10n.of(context).admin})'
: _permission >= 50
? '$_permission (${widget.l10n.moderator})'
? '$_permission (${L10n.of(context).moderator})'
: _permission.toString())),
Container(
height: 56,
@ -66,12 +71,14 @@ class _PermissionSliderDialogState extends State<PermissionSliderDialog> {
);
final buttons = [
AdaptiveFlatButton(
child: Text(widget.l10n.cancel),
onPressed: () => Navigator.of(context).pop<int>(null),
child: Text(L10n.of(context).cancel),
onPressed: () =>
Navigator.of(context, rootNavigator: false).pop<int>(null),
),
AdaptiveFlatButton(
child: Text(widget.l10n.confirm),
onPressed: () => Navigator.of(context).pop<int>(_permission),
child: Text(L10n.of(context).confirm),
onPressed: () =>
Navigator.of(context, rootNavigator: false).pop<int>(_permission),
),
];
if (PlatformInfos.isCupertinoStyle) {

View File

@ -8,10 +8,7 @@ import 'package:flutter_sound_lite/flutter_sound.dart';
import 'package:path_provider/path_provider.dart';
class RecordingDialog extends StatefulWidget {
final L10n l10n;
const RecordingDialog({
@required this.l10n,
Key key,
}) : super(key: key);
@ -76,7 +73,7 @@ class _RecordingDialogState extends State<RecordingDialog> {
Widget build(BuildContext context) {
if (error) {
Timer(Duration(seconds: 1), () {
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
});
}
const maxDecibalWidth = 64.0;
@ -101,7 +98,7 @@ class _RecordingDialogState extends State<RecordingDialog> {
SizedBox(width: 8),
Expanded(
child: Text(
'${widget.l10n.recording}: $time',
'${L10n.of(context).recording}: $time',
style: TextStyle(
fontSize: 18,
),
@ -112,17 +109,17 @@ class _RecordingDialogState extends State<RecordingDialog> {
actions: <Widget>[
FlatButton(
child: Text(
widget.l10n.cancel.toUpperCase(),
L10n.of(context).cancel.toUpperCase(),
style: TextStyle(
color: Theme.of(context).textTheme.bodyText2.color.withAlpha(150),
),
),
onPressed: () => Navigator.of(context).pop(),
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
),
FlatButton(
child: Row(
children: <Widget>[
Text(widget.l10n.send.toUpperCase()),
Text(L10n.of(context).send.toUpperCase()),
SizedBox(width: 4),
Icon(Icons.send_outlined, size: 15),
],
@ -130,7 +127,8 @@ class _RecordingDialogState extends State<RecordingDialog> {
onPressed: () async {
await _recorderSubscription?.cancel();
await flutterSound.stopRecorder();
Navigator.of(context).pop<String>(_recordedPath);
Navigator.of(context, rootNavigator: false)
.pop<String>(_recordedPath);
},
),
],

View File

@ -10,11 +10,9 @@ import '../../utils/resize_image.dart';
class SendFileDialog extends StatefulWidget {
final Room room;
final MatrixFile file;
final L10n l10n;
const SendFileDialog({
this.room,
@required this.l10n,
this.file,
Key key,
}) : super(key: key);
@ -40,13 +38,13 @@ class _SendFileDialogState extends State<SendFileDialog> {
@override
Widget build(BuildContext context) {
var sendStr = widget.l10n.sendFile;
var sendStr = L10n.of(context).sendFile;
if (widget.file is MatrixImageFile) {
sendStr = widget.l10n.sendImage;
sendStr = L10n.of(context).sendImage;
} else if (widget.file is MatrixAudioFile) {
sendStr = widget.l10n.sendAudio;
sendStr = L10n.of(context).sendAudio;
} else if (widget.file is MatrixVideoFile) {
sendStr = widget.l10n.sendVideo;
sendStr = L10n.of(context).sendVideo;
}
Widget contentWidget;
if (widget.file is MatrixImageFile) {
@ -66,8 +64,8 @@ class _SendFileDialogState extends State<SendFileDialog> {
),
InkWell(
onTap: () => setState(() => origImage = !origImage),
child: Text(
widget.l10n.sendOriginal + ' (${widget.file.sizeString})'),
child: Text(L10n.of(context).sendOriginal +
' (${widget.file.sizeString})'),
),
],
)
@ -80,14 +78,14 @@ class _SendFileDialogState extends State<SendFileDialog> {
content: contentWidget,
actions: <Widget>[
FlatButton(
child: Text(widget.l10n.cancel),
child: Text(L10n.of(context).cancel),
onPressed: () {
// just close the dialog
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
},
),
FlatButton(
child: Text(widget.l10n.send),
child: Text(L10n.of(context).send),
onPressed: _isSending
? null
: () async {
@ -96,7 +94,7 @@ class _SendFileDialogState extends State<SendFileDialog> {
});
await showFutureLoadingDialog(
context: context, future: () => _send());
await Navigator.of(context).pop();
await Navigator.of(context, rootNavigator: false).pop();
},
),
],

View File

@ -34,6 +34,7 @@ class _EncryptionButtonState extends State<EncryptionButton> {
}
if (await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
title: L10n.of(context).enableEncryptionWarning,
message: widget.room.client.encryptionEnabled
? L10n.of(context).warningEncryptionInBeta

View File

@ -233,7 +233,7 @@ class _ImageBubbleState extends State<ImageBubble> {
child: InkWell(
onTap: () {
if (!widget.tapToView) return;
Navigator.of(context).push(
Navigator.of(context, rootNavigator: false).push(
MaterialPageRoute(
builder: (_) => ImageView(widget.event, onLoaded: () {
// If the original file didn't load yet, we want to do that now.

View File

@ -90,12 +90,13 @@ class ChatListItem extends StatelessWidget {
if (Matrix.of(context).shareContent['msgtype'] ==
'chat.fluffy.shared_file') {
await showDialog(
context: context,
builder: (c) => SendFileDialog(
file: Matrix.of(context).shareContent['file'],
room: room,
l10n: L10n.of(context),
));
context: context,
builder: (c) => SendFileDialog(
file: Matrix.of(context).shareContent['file'],
room: room,
),
useRootNavigator: false,
);
} else {
unawaited(room.sendEvent(Matrix.of(context).shareContent));
}
@ -124,6 +125,7 @@ class ChatListItem extends StatelessWidget {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
useRootNavigator: false,
);
if (confirmed == OkCancelResult.cancel) return;
await showFutureLoadingDialog(

View File

@ -29,7 +29,6 @@ class ParticipantListItem extends StatelessWidget {
context: context,
builder: (c) => UserBottomSheet(
user: user,
l10n: L10n.of(context),
),
),
title: Row(

View File

@ -137,6 +137,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
title: L10n.of(context).pleaseEnterYourPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
minLines: 1,
@ -164,6 +165,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
await showOkCancelAlertDialog(
message: L10n.of(context).pleaseFollowInstructionsOnWeb,
context: context,
useRootNavigator: false,
okLabel: L10n.of(context).next,
cancelLabel: L10n.of(context).cancel,
)) {
@ -209,7 +211,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
body: body,
replacesID: _linuxNotificationIds[roomId] ?? -1,
appName: AppConfig.applicationName,
actionCallback: (_) => Navigator.of(context).pushAndRemoveUntil(
actionCallback: (_) => Navigator.of(context, rootNavigator: false).pushAndRemoveUntil(
AppRoute.defaultRoute(
context,
ChatView(roomId),
@ -273,6 +275,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
final sender = room.getUserByMXIDSync(request.sender);
if (await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
title: L10n.of(context).requestToReadOlderMessages,
message:
'${sender.id}\n\n${L10n.of(context).device}:\n${request.requestingDevice.deviceId}\n\n${L10n.of(context).publicKey}:\n${request.requestingDevice.ed25519Key.beautified}',
@ -296,6 +299,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
};
if (await showOkCancelAlertDialog(
context: context,
useRootNavigator: false,
title: L10n.of(context).newVerificationRequest,
message: L10n.of(context).askVerificationRequest(request.userId),
okLabel: L10n.of(context).ok,
@ -305,10 +309,7 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
request.onUpdate = null;
hidPopup = true;
await request.acceptVerification();
await KeyVerificationDialog(
request: request,
l10n: L10n.of(context),
).show(context);
await KeyVerificationDialog(request: request).show(context);
} else {
request.onUpdate = null;
hidPopup = true;

View File

@ -52,10 +52,7 @@ class MessageContent extends StatelessWidget {
timeline.cancelSubscriptions();
}
};
await KeyVerificationDialog(
request: req,
l10n: L10n.of(context),
).show(context);
await KeyVerificationDialog(request: req).show(context);
} else {
final success = await showFutureLoadingDialog(
context: context,

View File

@ -17,12 +17,10 @@ import 'dialogs/key_verification_dialog.dart';
class UserBottomSheet extends StatelessWidget {
final User user;
final Function onMention;
final L10n l10n;
const UserBottomSheet({
Key key,
@required this.user,
@required this.l10n,
this.onMention,
}) : super(key: key);
@ -30,14 +28,15 @@ class UserBottomSheet extends StatelessWidget {
final Function _askConfirmation =
() async => (await showOkCancelAlertDialog(
context: context,
title: l10n.areYouSure,
okLabel: l10n.yes,
cancelLabel: l10n.no,
useRootNavigator: false,
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).no,
) ==
OkCancelResult.ok);
switch (action) {
case 'mention':
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
onMention();
break;
case 'ban':
@ -46,7 +45,7 @@ class UserBottomSheet extends StatelessWidget {
context: context,
future: () => user.ban(),
);
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
}
break;
case 'unban':
@ -55,7 +54,7 @@ class UserBottomSheet extends StatelessWidget {
context: context,
future: () => user.unban(),
);
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
}
break;
case 'kick':
@ -64,21 +63,20 @@ class UserBottomSheet extends StatelessWidget {
context: context,
future: () => user.kick(),
);
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
}
break;
case 'permission':
final newPermission = await PermissionSliderDialog(
initialPermission: user.powerLevel,
l10n: L10n.of(context),
).show(context);
final newPermission =
await PermissionSliderDialog(initialPermission: user.powerLevel)
.show(context);
if (newPermission != null) {
if (newPermission == 100 && await _askConfirmation() == false) break;
await showFutureLoadingDialog(
context: context,
future: () => user.setPower(newPermission),
);
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
}
break;
case 'message':
@ -92,10 +90,7 @@ class UserBottomSheet extends StatelessWidget {
void _verifyAction(BuildContext context) async {
final client = user.room.client;
final req = await client.userDeviceKeys[user.id].startVerification();
await KeyVerificationDialog(
request: req,
l10n: L10n.of(context),
).show(context);
await KeyVerificationDialog(request: req).show(context);
}
@override
@ -109,7 +104,7 @@ class UserBottomSheet extends StatelessWidget {
items.add(
PopupMenuItem(
child: _TextWithIcon(
l10n.mention,
L10n.of(context).mention,
Icons.alternate_email_outlined,
),
value: 'mention'),
@ -119,7 +114,7 @@ class UserBottomSheet extends StatelessWidget {
items.add(
PopupMenuItem(
child: _TextWithIcon(
l10n.sendAMessage,
L10n.of(context).sendAMessage,
Icons.send_outlined,
),
value: 'message'),
@ -129,7 +124,7 @@ class UserBottomSheet extends StatelessWidget {
items.add(
PopupMenuItem(
child: _TextWithIcon(
l10n.setPermissionsLevel,
L10n.of(context).setPermissionsLevel,
Icons.edit_attributes_outlined,
),
value: 'permission'),
@ -139,7 +134,7 @@ class UserBottomSheet extends StatelessWidget {
items.add(
PopupMenuItem(
child: _TextWithIcon(
l10n.kickFromChat,
L10n.of(context).kickFromChat,
Icons.exit_to_app_outlined,
),
value: 'kick'),
@ -149,7 +144,7 @@ class UserBottomSheet extends StatelessWidget {
items.add(
PopupMenuItem(
child: _TextWithIcon(
l10n.banFromChat,
L10n.of(context).banFromChat,
Icons.warning_sharp,
),
value: 'ban'),
@ -158,7 +153,7 @@ class UserBottomSheet extends StatelessWidget {
items.add(
PopupMenuItem(
child: _TextWithIcon(
l10n.removeExile,
L10n.of(context).removeExile,
Icons.warning_outlined,
),
value: 'unban'),
@ -179,7 +174,7 @@ class UserBottomSheet extends StatelessWidget {
Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
leading: IconButton(
icon: Icon(Icons.arrow_downward_outlined),
onPressed: Navigator.of(context).pop,
onPressed: Navigator.of(context, rootNavigator: false).pop,
tooltip: L10n.of(context).close,
),
title: Text(user.calcDisplayname()),
@ -224,7 +219,7 @@ class UserBottomSheet extends StatelessWidget {
),
),
ListTile(
title: Text(l10n.username),
title: Text(L10n.of(context).username),
subtitle: Text(user.id),
trailing: Icon(Icons.share_outlined),
onTap: () => FluffyShare.share(user.id, context),

View File

@ -10,7 +10,7 @@ extension LocalizedBody on Event {
void openFile(BuildContext context, {bool downloadOnly = false}) async {
if (!downloadOnly &&
[MessageTypes.Image, MessageTypes.Sticker].contains(messageType)) {
await Navigator.of(context).push(
await Navigator.of(context, rootNavigator: false).push(
MaterialPageRoute(builder: (_) => ImageView(this)),
);
return;

View File

@ -43,6 +43,7 @@ abstract class PlatformInfos {
var version = await PlatformInfos.getVersion();
showAboutDialog(
context: context,
useRootNavigator: false,
children: [
Text('Version: $version'),
RaisedButton(

View File

@ -73,6 +73,7 @@ class UrlLauncher {
if (await showOkCancelAlertDialog(
context: context,
title: 'Join room $roomIdOrAlias',
useRootNavigator: false,
) ==
OkCancelResult.ok) {
roomId = roomIdOrAlias;
@ -116,6 +117,7 @@ class UrlLauncher {
if (await showOkCancelAlertDialog(
context: context,
title: 'Message user ${user.id}',
useRootNavigator: false,
) ==
OkCancelResult.ok) {
roomId = (await showFutureLoadingDialog(

View File

@ -211,13 +211,13 @@ class _ChatState extends State<Chat> {
if (result == null) return;
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
file: MatrixFile(
bytes: result.toUint8List(),
name: result.fileName,
).detectFileType,
room: room,
l10n: L10n.of(context),
),
);
}
@ -228,13 +228,13 @@ class _ChatState extends State<Chat> {
if (result == null) return;
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
file: MatrixImageFile(
bytes: result.toUint8List(),
name: result.fileName,
),
room: room,
l10n: L10n.of(context),
),
);
}
@ -245,13 +245,13 @@ class _ChatState extends State<Chat> {
final bytes = await file.readAsBytes();
await showDialog(
context: context,
useRootNavigator: false,
builder: (c) => SendFileDialog(
file: MatrixImageFile(
bytes: bytes,
name: file.path,
),
room: room,
l10n: L10n.of(context),
),
);
}
@ -263,9 +263,8 @@ class _ChatState extends State<Chat> {
}
final result = await showDialog<String>(
context: context,
builder: (c) => RecordingDialog(
l10n: L10n.of(context),
),
builder: (c) => RecordingDialog(),
useRootNavigator: false,
);
if (result == null) return;
final audioFile = File(result);
@ -306,6 +305,7 @@ class _ChatState extends State<Chat> {
final score = await showConfirmationDialog<int>(
context: context,
title: L10n.of(context).howOffensiveIsThisContent,
useRootNavigator: false,
actions: [
AlertDialogAction(
key: -100,
@ -326,6 +326,7 @@ class _ChatState extends State<Chat> {
title: L10n.of(context).whyDoYouWantToReportThis,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [DialogTextField(hintText: L10n.of(context).reason)]);
if (reason == null || reason.single.isEmpty) return;
final result = await showFutureLoadingDialog(
@ -350,6 +351,7 @@ class _ChatState extends State<Chat> {
title: L10n.of(context).messageWillBeRemovedWarning,
okLabel: L10n.of(context).remove,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.ok;
if (!confirmed) return;
@ -473,7 +475,7 @@ class _ChatState extends State<Chat> {
// make sure we remove duplicates
prefs.setStringList('recents', recents.toSet().toList());
});
Navigator.of(context).pop<Emoji>(emoji);
Navigator.of(context, rootNavigator: false).pop<Emoji>(emoji);
},
),
],
@ -538,7 +540,6 @@ class _ChatState extends State<Chat> {
? () => showModalBottomSheet(
context: context,
builder: (c) => UserBottomSheet(
l10n: L10n.of(context),
user: room.getUserByMXIDSync(
room.directChatMatrixID),
onMention: () => sendController.text +=
@ -823,7 +824,6 @@ class _ChatState extends State<Chat> {
context: context,
builder: (c) =>
UserBottomSheet(
l10n: L10n.of(context),
user: event.sender,
onMention: () =>
sendController.text +=

View File

@ -39,6 +39,7 @@ class _ChatDetailsState extends State<ChatDetails> {
title: L10n.of(context).changeTheNameOfTheGroup,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
initialText: room.getLocalizedDisplayname(
@ -67,6 +68,7 @@ class _ChatDetailsState extends State<ChatDetails> {
title: L10n.of(context).setInvitationLink,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: '#localpart:domain',
@ -109,6 +111,7 @@ class _ChatDetailsState extends State<ChatDetails> {
title: L10n.of(context).setGroupDescription,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).setGroupDescription,

View File

@ -35,10 +35,7 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
setState(() => null);
}
};
await KeyVerificationDialog(
request: req,
l10n: L10n.of(context),
).show(context);
await KeyVerificationDialog(request: req).show(context);
break;
case 'verify_user':
await unblock();
@ -49,10 +46,7 @@ class _ChatEncryptionSettingsState extends State<ChatEncryptionSettings> {
setState(() => null);
}
};
await KeyVerificationDialog(
request: req,
l10n: L10n.of(context),
).show(context);
await KeyVerificationDialog(request: req).show(context);
break;
case 'block':
if (key.directVerified) {

View File

@ -143,6 +143,7 @@ class _ChatListState extends State<ChatList> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.ok;
if (!confirmed) return;

View File

@ -20,10 +20,9 @@ class ChatPermissionsSettings extends StatelessWidget {
return FlushbarHelper.createError(message: L10n.of(context).noPermission)
.show(context);
}
final newLevel = await PermissionSliderDialog(
initialPermission: currentLevel,
l10n: L10n.of(context),
).show(context);
final newLevel =
await PermissionSliderDialog(initialPermission: currentLevel)
.show(context);
if (newLevel == null) return;
final content = Map<String, dynamic>.from(
room.getState(EventTypes.RoomPowerLevels).content);

View File

@ -43,6 +43,7 @@ class _ContactsState extends State<Contacts> {
title: L10n.of(context).setStatus,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).statusExampleMessage,

View File

@ -66,6 +66,7 @@ class _DiscoverState extends State<Discover> {
title: '${room.name} (${room.numJoinedMembers ?? 0})',
message: room.topic ?? L10n.of(context).noDescription,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -92,6 +93,7 @@ class _DiscoverState extends State<Discover> {
context: context,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
prefixText: 'https://',

View File

@ -29,7 +29,7 @@ class ImageView extends StatelessWidget {
elevation: 0,
leading: IconButton(
icon: Icon(Icons.close),
onPressed: () => Navigator.of(context).pop(),
onPressed: () => Navigator.of(context, rootNavigator: false).pop(),
color: Colors.white,
tooltip: L10n.of(context).close,
),
@ -67,7 +67,7 @@ class ImageView extends StatelessWidget {
onInteractionEnd: (ScaleEndDetails endDetails) {
if (PlatformInfos.usesTouchscreen == false) {
if (endDetails.velocity.pixelsPerSecond.dy > calcVelocity) {
Navigator.of(context).pop();
Navigator.of(context, rootNavigator: false).pop();
}
}
},

View File

@ -96,6 +96,7 @@ class _LoginState extends State<Login> {
title: L10n.of(context).enterAnEmailAddress,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).enterAnEmailAddress,
@ -119,6 +120,7 @@ class _LoginState extends State<Login> {
title: L10n.of(context).weSentYouAnEmail,
message: L10n.of(context).pleaseClickOnLink,
okLabel: L10n.of(context).iHaveClickedOnLink,
useRootNavigator: false,
);
if (ok == null) return;
final password = await showTextInputDialog(
@ -126,6 +128,7 @@ class _LoginState extends State<Login> {
title: L10n.of(context).chooseAStrongPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: '******',

View File

@ -47,6 +47,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).areYouSureYouWantToLogout,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -64,6 +65,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).changePassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).pleaseEnterYourPassword,
@ -98,6 +100,7 @@ class _SettingsState extends State<Settings> {
message: L10n.of(context).deactivateAccountWarning,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -107,6 +110,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) {
return;
@ -116,6 +120,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).pleaseEnterYourPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
obscureText: true,
@ -146,6 +151,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).editJitsiInstance,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
initialText: AppConfig.jitsiInstance.replaceFirst(prefix, ''),
@ -169,6 +175,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).editDisplayname,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
initialText: profile?.displayname ??
@ -233,6 +240,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).askSSSSCache,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).passphraseOrKey,
@ -263,6 +271,8 @@ class _SettingsState extends State<Settings> {
await showOkAlertDialog(
context: context,
message: L10n.of(context).cachedKeys,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
setState(() {
crossSigningCachedFuture = null;
@ -274,6 +284,8 @@ class _SettingsState extends State<Settings> {
await showOkAlertDialog(
context: context,
message: L10n.of(context).incorrectPassphraseOrKey,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
}
}
@ -297,6 +309,7 @@ class _SettingsState extends State<Settings> {
title: L10n.of(context).pleaseChooseAPasscode,
message: L10n.of(context).pleaseEnter4Digits,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
validator: (text) {
@ -516,6 +529,8 @@ class _SettingsState extends State<Settings> {
context: context,
title: L10n.of(context).yourPublicKey,
message: client.fingerprintKey.beautified,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
),
trailing: Icon(Icons.vpn_key_outlined),
),
@ -534,19 +549,13 @@ class _SettingsState extends State<Settings> {
isDestructiveAction: true,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
)) {
await BootstrapDialog(
l10n: L10n.of(context),
client: Matrix.of(context).client,
wipe: true,
).show(context);
await BootstrapDialog(wipe: true).show(context);
}
return;
}
await BootstrapDialog(
l10n: L10n.of(context),
client: Matrix.of(context).client,
).show(context);
await BootstrapDialog().show(context);
},
),
},

View File

@ -19,6 +19,7 @@ class _Settings3PidState extends State<Settings3Pid> {
title: L10n.of(context).enterAnEmailAddress,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: L10n.of(context).enterAnEmailAddress,
@ -42,6 +43,7 @@ class _Settings3PidState extends State<Settings3Pid> {
title: L10n.of(context).weSentYouAnEmail,
message: L10n.of(context).pleaseClickOnLink,
okLabel: L10n.of(context).iHaveClickedOnLink,
useRootNavigator: false,
);
if (ok == null) return;
final password = await showTextInputDialog(
@ -49,6 +51,7 @@ class _Settings3PidState extends State<Settings3Pid> {
title: L10n.of(context).pleaseEnterYourPassword,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: '******',
@ -82,6 +85,7 @@ class _Settings3PidState extends State<Settings3Pid> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) !=
OkCancelResult.ok) {
return;

View File

@ -34,6 +34,7 @@ class DevicesSettingsState extends State<DevicesSettings> {
title: L10n.of(context).areYouSure,
okLabel: L10n.of(context).yes,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
) ==
OkCancelResult.cancel) return;
var matrix = Matrix.of(context);
@ -68,6 +69,7 @@ class DevicesSettingsState extends State<DevicesSettings> {
title: L10n.of(context).changeDeviceName,
okLabel: L10n.of(context).ok,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
textFields: [
DialogTextField(
hintText: device.displayName,
@ -98,10 +100,7 @@ class DevicesSettingsState extends State<DevicesSettings> {
setState(() => null);
}
};
await KeyVerificationDialog(
request: req,
l10n: L10n.of(context),
).show(context);
await KeyVerificationDialog(request: req).show(context);
}
void _blockDeviceAction(BuildContext context, Device device) async {

View File

@ -233,8 +233,11 @@ class _EmotesSettingsState extends State<EmotesSettings> {
newMxcController.text == null ||
newMxcController.text.isEmpty) {
await showOkAlertDialog(
context: context,
message: L10n.of(context).emoteWarnNeedToPick);
context: context,
message: L10n.of(context).emoteWarnNeedToPick,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
final emoteCode = ':${newEmoteController.text}:';
@ -243,14 +246,20 @@ class _EmotesSettingsState extends State<EmotesSettings> {
e.emote == emoteCode && e.mxc != mxc) !=
-1) {
await showOkAlertDialog(
context: context,
message: L10n.of(context).emoteExists);
context: context,
message: L10n.of(context).emoteExists,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
if (!RegExp(r'^:[-\w]+:$').hasMatch(emoteCode)) {
await showOkAlertDialog(
context: context,
message: L10n.of(context).emoteInvalid);
context: context,
message: L10n.of(context).emoteInvalid,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
emotes.add(_EmoteEntry(emote: emoteCode, mxc: mxc));
@ -344,18 +353,22 @@ class _EmotesSettingsState extends State<EmotesSettings> {
-1) {
controller.text = emote.emoteClean;
showOkAlertDialog(
context: context,
message:
L10n.of(context).emoteExists);
context: context,
message: L10n.of(context).emoteExists,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
if (!RegExp(r'^:[-\w]+:$')
.hasMatch(emoteCode)) {
controller.text = emote.emoteClean;
showOkAlertDialog(
context: context,
message:
L10n.of(context).emoteInvalid);
context: context,
message: L10n.of(context).emoteInvalid,
okLabel: L10n.of(context).ok,
useRootNavigator: false,
);
return;
}
setState(() {

View File

@ -88,6 +88,7 @@ class _SignUpPasswordState extends State<SignUpPassword> {
context: context,
okLabel: L10n.of(context).next,
cancelLabel: L10n.of(context).cancel,
useRootNavigator: false,
)) {
_signUpAction(
context,