mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-11-25 23:14:18 +03:00
Prevent underlying page from stealing focus from ResponsiveDialog.
This commit is contained in:
parent
7f1963d310
commit
e42f7e4e67
@ -32,17 +32,16 @@ Future<T?> showBlurDialog<T>({
|
||||
required BuildContext context,
|
||||
required Widget Function(BuildContext) builder,
|
||||
RouteSettings? routeSettings,
|
||||
}) async {
|
||||
const transitionDelay = Duration(milliseconds: 150);
|
||||
final result = await showGeneralDialog<T>(
|
||||
}) async =>
|
||||
await showGeneralDialog<T>(
|
||||
context: context,
|
||||
barrierDismissible: true,
|
||||
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||
pageBuilder: (ctx, anim1, anim2) => builder(ctx),
|
||||
transitionDuration: transitionDelay,
|
||||
transitionDuration: const Duration(milliseconds: 150),
|
||||
transitionBuilder: (ctx, anim1, anim2, child) => BackdropFilter(
|
||||
filter:
|
||||
ImageFilter.blur(sigmaX: 20 * anim1.value, sigmaY: 20 * anim1.value),
|
||||
filter: ImageFilter.blur(
|
||||
sigmaX: 20 * anim1.value, sigmaY: 20 * anim1.value),
|
||||
child: FadeTransition(
|
||||
opacity: anim1,
|
||||
child: child,
|
||||
@ -50,9 +49,3 @@ Future<T?> showBlurDialog<T>({
|
||||
),
|
||||
routeSettings: routeSettings,
|
||||
);
|
||||
// Make sure we wait for the dialog to fade out before returning the result.
|
||||
// This is needed for subsequent dialogs with autofocus.
|
||||
await Future.delayed(transitionDelay);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -39,14 +39,15 @@ class ResponsiveDialog extends StatefulWidget {
|
||||
|
||||
class _ResponsiveDialogState extends State<ResponsiveDialog> {
|
||||
final Key _childKey = GlobalKey();
|
||||
final _focus = FocusScopeNode();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
LayoutBuilder(builder: ((context, constraints) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
if (constraints.maxWidth < 540) {
|
||||
// Fullscreen
|
||||
return Scaffold(
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
_focus.dispose();
|
||||
}
|
||||
|
||||
Widget _buildFullscreen(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: widget.title,
|
||||
actions: widget.actions,
|
||||
@ -60,12 +61,13 @@ class _ResponsiveDialogState extends State<ResponsiveDialog> {
|
||||
: null),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: SafeArea(
|
||||
child: Container(key: _childKey, child: widget.child)),
|
||||
child:
|
||||
SafeArea(child: Container(key: _childKey, child: widget.child)),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
// Dialog
|
||||
|
||||
Widget _buildDialog(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context)!;
|
||||
final cancelText = widget.onCancel == null && widget.actions.isEmpty
|
||||
? l10n.s_close
|
||||
: l10n.s_cancel;
|
||||
@ -90,5 +92,22 @@ class _ResponsiveDialogState extends State<ResponsiveDialog> {
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
LayoutBuilder(builder: ((context, constraints) {
|
||||
// This keeps the focus in the dialog, even if the underlying page changes.
|
||||
return FocusScope(
|
||||
node: _focus,
|
||||
autofocus: true,
|
||||
onFocusChange: (focused) {
|
||||
if (!focused) {
|
||||
_focus.requestFocus();
|
||||
}
|
||||
},
|
||||
child: constraints.maxWidth < 540
|
||||
? _buildFullscreen(context)
|
||||
: _buildDialog(context),
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user