Skip to content

Commit f365734

Browse files
committed
dialog: Display adaptive dialogs and action buttons based on the target platform
Fixes: #996
1 parent 26c2aa0 commit f365734

File tree

2 files changed

+54
-19
lines changed

2 files changed

+54
-19
lines changed

lib/widgets/dialog.dart

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import 'package:flutter/cupertino.dart';
12
import 'package:flutter/material.dart';
23
import 'package:flutter_gen/gen_l10n/zulip_localizations.dart';
4+
import 'package:flutter/foundation.dart';
35

4-
Widget _dialogActionText(String text) {
6+
Widget _materialDialogActionText(String text) {
57
return Text(
68
text,
79

@@ -15,6 +17,20 @@ Widget _dialogActionText(String text) {
1517
);
1618
}
1719

20+
/// A platform-appropriate action for [AlertDialog.adaptive]'s [actions] param.
21+
Widget _adaptiveAction({required VoidCallback onPressed, required String text}) {
22+
switch (defaultTargetPlatform) {
23+
case TargetPlatform.android:
24+
case TargetPlatform.fuchsia:
25+
case TargetPlatform.linux:
26+
case TargetPlatform.windows:
27+
return TextButton(onPressed: onPressed, child: _materialDialogActionText(text));
28+
case TargetPlatform.iOS:
29+
case TargetPlatform.macOS:
30+
return CupertinoDialogAction(onPressed: onPressed, child: Text(text));
31+
}
32+
}
33+
1834
/// Tracks the status of a dialog, in being still open or already closed.
1935
///
2036
/// See also:
@@ -42,13 +58,13 @@ DialogStatus showErrorDialog({
4258
final zulipLocalizations = ZulipLocalizations.of(context);
4359
final future = showDialog<void>(
4460
context: context,
45-
builder: (BuildContext context) => AlertDialog(
61+
builder: (BuildContext context) => AlertDialog.adaptive(
4662
title: Text(title),
4763
content: message != null ? SingleChildScrollView(child: Text(message)) : null,
4864
actions: [
49-
TextButton(
65+
_adaptiveAction(
5066
onPressed: () => Navigator.pop(context),
51-
child: _dialogActionText(zulipLocalizations.errorDialogContinue)),
67+
text: zulipLocalizations.errorDialogContinue),
5268
]));
5369
return DialogStatus(future);
5470
}
@@ -63,15 +79,15 @@ void showSuggestedActionDialog({
6379
final zulipLocalizations = ZulipLocalizations.of(context);
6480
showDialog<void>(
6581
context: context,
66-
builder: (BuildContext context) => AlertDialog(
82+
builder: (BuildContext context) => AlertDialog.adaptive(
6783
title: Text(title),
6884
content: SingleChildScrollView(child: Text(message)),
6985
actions: [
70-
TextButton(
86+
_adaptiveAction(
7187
onPressed: () => Navigator.pop(context),
72-
child: _dialogActionText(zulipLocalizations.dialogCancel)),
73-
TextButton(
88+
text: zulipLocalizations.dialogCancel),
89+
_adaptiveAction(
7490
onPressed: onActionButtonPress,
75-
child: _dialogActionText(actionButtonText ?? zulipLocalizations.dialogContinue)),
91+
text: actionButtonText ?? zulipLocalizations.dialogContinue),
7692
]));
7793
}

test/widgets/dialog_checks.dart

+29-10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'package:flutter/cupertino.dart';
2+
import 'package:flutter/foundation.dart';
13
import 'package:flutter/material.dart';
24
import 'package:flutter_test/flutter_test.dart';
35

@@ -12,15 +14,32 @@ Widget checkErrorDialog(WidgetTester tester, {
1214
required String expectedTitle,
1315
String? expectedMessage,
1416
}) {
15-
final dialog = tester.widget<AlertDialog>(find.byType(AlertDialog));
16-
tester.widget(find.descendant(matchRoot: true,
17-
of: find.byWidget(dialog.title!), matching: find.text(expectedTitle)));
18-
if (expectedMessage != null) {
19-
tester.widget(find.descendant(matchRoot: true,
20-
of: find.byWidget(dialog.content!), matching: find.text(expectedMessage)));
17+
switch (defaultTargetPlatform) {
18+
case TargetPlatform.android:
19+
case TargetPlatform.fuchsia:
20+
case TargetPlatform.linux:
21+
case TargetPlatform.windows: {
22+
final dialog = tester.widget<Dialog>(find.byType(Dialog));
23+
tester.widget(find.widgetWithText(Dialog, expectedTitle));
24+
if (expectedMessage != null) {
25+
tester.widget(find.widgetWithText(Dialog, expectedMessage));
26+
}
27+
return tester.widget(
28+
find.descendant(of: find.byWidget(dialog),
29+
matching: find.widgetWithText(TextButton, 'OK')));
30+
}
31+
case TargetPlatform.iOS:
32+
case TargetPlatform.macOS: {
33+
final dialog = tester.widget<CupertinoAlertDialog>(
34+
find.byType(CupertinoAlertDialog));
35+
tester.widget(find.descendant(matchRoot: true,
36+
of: find.byWidget(dialog.title!), matching: find.text(expectedTitle)));
37+
if (expectedMessage != null) {
38+
tester.widget(find.descendant(matchRoot: true,
39+
of: find.byWidget(dialog.content!), matching: find.text(expectedMessage)));
40+
}
41+
return tester.widget(find.descendant(of: find.byWidget(dialog),
42+
matching: find.widgetWithText(CupertinoDialogAction, 'OK')));
43+
}
2144
}
22-
23-
return tester.widget(
24-
find.descendant(of: find.byWidget(dialog),
25-
matching: find.widgetWithText(TextButton, 'OK')));
2645
}

0 commit comments

Comments
 (0)