Skip to content

Commit e5d418f

Browse files
committed
refactor(ui): generalized external link launch request dialog
1 parent f2c96ae commit e5d418f

5 files changed

Lines changed: 142 additions & 270 deletions

File tree

lib/pages/cakepay/cakepay_card_detail_view.dart

Lines changed: 2 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import 'package:decimal/decimal.dart';
22
import 'package:flutter/gestures.dart';
33
import 'package:flutter/material.dart';
4-
import 'package:url_launcher/url_launcher.dart';
54

65
import '../../services/cakepay/cakepay_service.dart';
76
import '../../services/cakepay/src/models/card.dart';
@@ -11,10 +10,9 @@ import '../../utilities/util.dart';
1110
import '../../widgets/background.dart';
1211
import '../../widgets/conditional_parent.dart';
1312
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
14-
import '../../widgets/desktop/desktop_dialog.dart';
1513
import '../../widgets/desktop/desktop_dialog_close_button.dart';
1614
import '../../widgets/desktop/primary_button.dart';
17-
import '../../widgets/desktop/secondary_button.dart';
15+
import '../../widgets/dialogs/request_external_link_navigation_dialog.dart';
1816
import '../../widgets/dialogs/s_dialog.dart';
1917
import '../../widgets/icon_widgets/credit_card_icon.dart';
2018
import '../../widgets/loading_indicator.dart';
@@ -75,101 +73,9 @@ class _CakePayCardDetailViewState extends State<CakePayCardDetailView> {
7573
return true;
7674
}
7775

78-
Future<bool> _showOpenBrowserWarning(String url) async {
79-
final uri = Uri.parse(url);
80-
final shouldContinue = await showDialog<bool>(
81-
context: context,
82-
barrierDismissible: false,
83-
builder: (_) => Util.isDesktop
84-
? DesktopDialog(
85-
maxWidth: 550,
86-
maxHeight: 250,
87-
child: Padding(
88-
padding: const EdgeInsets.symmetric(
89-
horizontal: 32,
90-
vertical: 20,
91-
),
92-
child: Column(
93-
children: [
94-
Text("Attention", style: STextStyles.desktopH2(context)),
95-
const SizedBox(height: 16),
96-
Text(
97-
"You are about to open "
98-
"${uri.scheme}://${uri.host} "
99-
"in your browser.",
100-
style: STextStyles.desktopTextSmall(context),
101-
),
102-
const SizedBox(height: 35),
103-
Row(
104-
mainAxisAlignment: MainAxisAlignment.center,
105-
children: [
106-
SecondaryButton(
107-
width: 200,
108-
buttonHeight: ButtonHeight.l,
109-
label: "Cancel",
110-
onPressed: () {
111-
Navigator.of(
112-
context,
113-
rootNavigator: true,
114-
).pop(false);
115-
},
116-
),
117-
const SizedBox(width: 20),
118-
PrimaryButton(
119-
width: 200,
120-
buttonHeight: ButtonHeight.l,
121-
label: "Continue",
122-
onPressed: () {
123-
Navigator.of(
124-
context,
125-
rootNavigator: true,
126-
).pop(true);
127-
},
128-
),
129-
],
130-
),
131-
],
132-
),
133-
),
134-
)
135-
: StackDialog(
136-
title: "Attention",
137-
message:
138-
"You are about to open "
139-
"${uri.scheme}://${uri.host} "
140-
"in your browser.",
141-
leftButton: TextButton(
142-
onPressed: () {
143-
Navigator.of(context).pop(false);
144-
},
145-
child: Text(
146-
"Cancel",
147-
style: STextStyles.button(context).copyWith(
148-
color: Theme.of(
149-
context,
150-
).extension<StackColors>()!.accentColorDark,
151-
),
152-
),
153-
),
154-
rightButton: TextButton(
155-
style: Theme.of(context)
156-
.extension<StackColors>()!
157-
.getPrimaryEnabledButtonStyle(context),
158-
onPressed: () {
159-
Navigator.of(context).pop(true);
160-
},
161-
child: Text("Continue", style: STextStyles.button(context)),
162-
),
163-
),
164-
);
165-
return shouldContinue ?? false;
166-
}
167-
16876
Future<void> _openTerms() async {
16977
const url = "https://cakepay.com/terms/";
170-
if (await _showOpenBrowserWarning(url)) {
171-
await launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
172-
}
78+
await showRequestExternalLinkAndMaybeLaunch(context, uri: Uri.parse(url));
17379
}
17480

17581
Future<void> _purchase() async {

lib/pages/more_view/services_view.dart

Lines changed: 15 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import 'package:flutter/gestures.dart';
33
import 'package:flutter/material.dart';
44
import 'package:flutter_riverpod/flutter_riverpod.dart';
55
import 'package:flutter_svg/svg.dart';
6-
import 'package:url_launcher/url_launcher.dart';
76

87
import '../../models/shopinbit/shopinbit_order_model.dart';
98
import '../../providers/providers.dart';
@@ -14,6 +13,7 @@ import '../../widgets/background.dart';
1413
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
1514
import '../../widgets/desktop/primary_button.dart';
1615
import '../../widgets/desktop/secondary_button.dart';
16+
import '../../widgets/dialogs/request_external_link_navigation_dialog.dart';
1717
import '../../widgets/rounded_white_container.dart';
1818
import '../../widgets/stack_dialog.dart';
1919
import '../shopinbit/shopinbit_settings_view.dart';
@@ -31,44 +31,6 @@ class ServicesView extends ConsumerStatefulWidget {
3131
}
3232

3333
class _ServicesViewState extends ConsumerState<ServicesView> {
34-
Future<bool> _showOpenBrowserWarning(BuildContext context, String url) async {
35-
final uri = Uri.parse(url);
36-
final shouldContinue = await showDialog<bool>(
37-
context: context,
38-
barrierDismissible: false,
39-
builder: (_) => StackDialog(
40-
title: "Attention",
41-
message:
42-
"You are about to open "
43-
"${uri.scheme}://${uri.host} "
44-
"in your browser.",
45-
leftButton: TextButton(
46-
onPressed: () {
47-
Navigator.of(context).pop(false);
48-
},
49-
child: Text(
50-
"Cancel",
51-
style: STextStyles.button(context).copyWith(
52-
color: Theme.of(
53-
context,
54-
).extension<StackColors>()!.accentColorDark,
55-
),
56-
),
57-
),
58-
rightButton: TextButton(
59-
style: Theme.of(
60-
context,
61-
).extension<StackColors>()!.getPrimaryEnabledButtonStyle(context),
62-
onPressed: () {
63-
Navigator.of(context).pop(true);
64-
},
65-
child: Text("Continue", style: STextStyles.button(context)),
66-
),
67-
),
68-
);
69-
return shouldContinue ?? false;
70-
}
71-
7234
void _showShopDialog() {
7335
showDialog<void>(
7436
context: context,
@@ -99,16 +61,11 @@ class _ServicesViewState extends ConsumerState<ServicesView> {
9961
..onTap = () async {
10062
const url =
10163
"https://api.shopinbit.com/static/policy/privacy.html";
102-
final shouldOpen = await _showOpenBrowserWarning(
103-
dialogContext,
104-
url,
64+
65+
await showRequestExternalLinkAndMaybeLaunch(
66+
context,
67+
uri: Uri.parse(url),
10568
);
106-
if (shouldOpen) {
107-
await launchUrl(
108-
Uri.parse(url),
109-
mode: LaunchMode.externalApplication,
110-
);
111-
}
11269
},
11370
),
11471
const TextSpan(text: "."),
@@ -270,14 +227,11 @@ class _ServicesViewState extends ConsumerState<ServicesView> {
270227
..onTap = () async {
271228
const url =
272229
"https://api.shopinbit.com/static/policy/terms.html";
273-
final shouldOpen =
274-
await _showOpenBrowserWarning(context, url);
275-
if (shouldOpen) {
276-
await launchUrl(
277-
Uri.parse(url),
278-
mode: LaunchMode.externalApplication,
279-
);
280-
}
230+
231+
await showRequestExternalLinkAndMaybeLaunch(
232+
context,
233+
uri: Uri.parse(url),
234+
);
281235
},
282236
),
283237
const TextSpan(text: " and "),
@@ -290,14 +244,11 @@ class _ServicesViewState extends ConsumerState<ServicesView> {
290244
..onTap = () async {
291245
const url =
292246
"https://api.shopinbit.com/static/policy/privacy.html";
293-
final shouldOpen =
294-
await _showOpenBrowserWarning(context, url);
295-
if (shouldOpen) {
296-
await launchUrl(
297-
Uri.parse(url),
298-
mode: LaunchMode.externalApplication,
299-
);
300-
}
247+
248+
await showRequestExternalLinkAndMaybeLaunch(
249+
context,
250+
uri: Uri.parse(url),
251+
);
301252
},
302253
),
303254
const TextSpan(text: "."),

lib/pages/shopinbit/step_4_components/shopinbit_privacy_checkbox.dart

Lines changed: 5 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import "package:flutter/gestures.dart";
22
import "package:flutter/material.dart";
3-
import "package:url_launcher/url_launcher.dart";
43

54
import "../../../utilities/text_styles.dart";
65
import "../../../utilities/util.dart";
76
import "../../../widgets/desktop/desktop_dialog.dart";
87
import "../../../widgets/desktop/primary_button.dart";
98
import "../../../widgets/desktop/secondary_button.dart";
10-
import "../../../widgets/stack_dialog.dart";
9+
import "../../../widgets/dialogs/request_external_link_navigation_dialog.dart";
1110

1211
const String _shopInBitPrivacyUrl =
1312
"https://api.shopinbit.com/static/policy/privacy.html";
@@ -22,45 +21,6 @@ class ShopInBitPrivacyCheckbox extends StatelessWidget {
2221
final bool value;
2322
final ValueChanged<bool> onChanged;
2423

25-
Future<void> _openPrivacyPolicy(BuildContext context) async {
26-
final bool shouldOpen = await _showOpenBrowserWarning(
27-
context,
28-
_shopInBitPrivacyUrl,
29-
);
30-
if (shouldOpen) {
31-
await launchUrl(
32-
Uri.parse(_shopInBitPrivacyUrl),
33-
mode: LaunchMode.externalApplication,
34-
);
35-
}
36-
}
37-
38-
Future<bool> _showOpenBrowserWarning(BuildContext context, String url) async {
39-
final Uri uri = Uri.parse(url);
40-
final String message =
41-
"You are about to open ${uri.scheme}://${uri.host} in your browser.";
42-
43-
final bool? shouldContinue = await showDialog<bool>(
44-
context: context,
45-
barrierDismissible: false,
46-
builder: (context) => Util.isDesktop
47-
? _DesktopBrowserWarning(message: message)
48-
: StackDialog(
49-
title: "Attention",
50-
message: message,
51-
leftButton: SecondaryButton(
52-
label: "Cancel",
53-
onPressed: () => Navigator.of(context).pop(false),
54-
),
55-
rightButton: PrimaryButton(
56-
label: "Continue",
57-
onPressed: () => Navigator.of(context).pop(true),
58-
),
59-
),
60-
);
61-
return shouldContinue ?? false;
62-
}
63-
6424
@override
6525
Widget build(BuildContext context) {
6626
final isDesktop = Util.isDesktop;
@@ -105,7 +65,10 @@ class ShopInBitPrivacyCheckbox extends StatelessWidget {
10565
context,
10666
).copyWith(fontSize: isDesktop ? 18 : 14),
10767
recognizer: TapGestureRecognizer()
108-
..onTap = () => _openPrivacyPolicy(context),
68+
..onTap = () => showRequestExternalLinkAndMaybeLaunch(
69+
context,
70+
uri: Uri.parse(_shopInBitPrivacyUrl),
71+
),
10972
),
11073
const TextSpan(text: "."),
11174
],

0 commit comments

Comments
 (0)