Skip to content

Commit 78c5cf3

Browse files
committed
fix: Better handling of HTTPS links in the app settings.
1 parent ce754f7 commit 78c5cf3

File tree

5 files changed

+77
-39
lines changed

5 files changed

+77
-39
lines changed

android/app/src/main/AndroidManifest.xml

+7
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,11 @@
5858
android:name="flutter_deeplinking_enabled"
5959
android:value="false" />
6060
</application>
61+
62+
<queries>
63+
<intent>
64+
<action android:name="android.intent.action.VIEW" />
65+
<data android:scheme="https" />
66+
</intent>
67+
</queries>
6168
</manifest>
+18-21
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,28 @@
11
import 'package:flutter/material.dart';
22
import 'package:open_authenticator/app.dart';
33
import 'package:open_authenticator/i18n/translations.g.dart';
4-
import 'package:url_launcher/url_launcher.dart';
4+
import 'package:open_authenticator/pages/settings/entries/uri_settings_entry.dart';
55

66
/// Takes the user to Github to report bugs, suggest new features, ...
7-
class GithubSettingsEntryWidget extends StatelessWidget {
7+
class GithubSettingsEntryWidget extends UriSettingsEntry {
88
/// Creates a new Github settings entry widget instance.
9-
const GithubSettingsEntryWidget({
9+
GithubSettingsEntryWidget({
1010
super.key,
11-
});
11+
}) : super(
12+
icon: Icons.bug_report,
13+
title: translations.settings.about.github.title,
14+
subtitle: translations.settings.about.github.subtitle,
15+
uri: Uri.parse(App.githubRepositoryUrl),
16+
);
1217

1318
@override
14-
Widget build(BuildContext context) => ListTile(
15-
leading: const Icon(Icons.bug_report),
16-
title: Text(translations.settings.about.github.title),
17-
subtitle: Text(translations.settings.about.github.subtitle),
18-
onTap: () async {
19-
Uri uri = Uri.parse(App.githubRepositoryUrl);
20-
Uri withFragment = Uri(
21-
scheme: uri.scheme,
22-
host: uri.host,
23-
path: uri.path,
24-
fragment: 'report-bugs-or-suggest-new-features',
25-
);
26-
if (await canLaunchUrl(withFragment)) {
27-
launchUrl(withFragment);
28-
}
29-
},
30-
);
19+
Uri get uri {
20+
Uri uri = super.uri;
21+
return Uri(
22+
scheme: uri.scheme,
23+
host: uri.host,
24+
path: uri.path,
25+
fragment: 'report-bugs-or-suggest-new-features',
26+
);
27+
}
3128
}
+9-16
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,18 @@
11
import 'package:flutter/material.dart';
22
import 'package:open_authenticator/app.dart';
33
import 'package:open_authenticator/i18n/translations.g.dart';
4+
import 'package:open_authenticator/pages/settings/entries/uri_settings_entry.dart';
45
import 'package:url_launcher/url_launcher.dart';
56

67
/// Takes the user to the app translation page.
7-
class TranslateSettingsEntryWidget extends StatelessWidget {
8+
class TranslateSettingsEntryWidget extends UriSettingsEntry {
89
/// Creates a new translate settings entry widget instance.
9-
const TranslateSettingsEntryWidget({
10+
TranslateSettingsEntryWidget({
1011
super.key,
11-
});
12-
13-
@override
14-
Widget build(BuildContext context) => ListTile(
15-
leading: const Icon(Icons.translate),
16-
title: Text(translations.settings.about.translate.title),
17-
subtitle: Text(translations.settings.about.translate.subtitle(appName: App.appName)),
18-
onTap: () async {
19-
Uri uri = Uri.parse(App.appTranslationUrl);
20-
if (await canLaunchUrl(uri)) {
21-
launchUrl(uri);
22-
}
23-
},
24-
);
12+
}) : super(
13+
icon: Icons.translate,
14+
title: translations.settings.about.translate.title,
15+
subtitle: translations.settings.about.translate.subtitle(appName: App.appName),
16+
uri: Uri.parse(App.appTranslationUrl),
17+
);
2518
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:url_launcher/url_launcher.dart';
3+
4+
/// A settings entry that allows to open a specific URI.
5+
class UriSettingsEntry extends StatelessWidget {
6+
/// The entry widget title.
7+
final String title;
8+
9+
/// The entry widget subtitle.
10+
final String? subtitle;
11+
12+
/// The icon.
13+
final IconData? icon;
14+
15+
/// The URI to open.
16+
final Uri uri;
17+
18+
/// Creates a new URI settings entry instance.
19+
const UriSettingsEntry({
20+
super.key,
21+
required this.title,
22+
this.subtitle,
23+
this.icon,
24+
required this.uri,
25+
});
26+
27+
@override
28+
Widget build(BuildContext context) => FutureBuilder(
29+
future: canLaunchUrl(uri),
30+
builder: (context, snapshot) => createListTile(context, snapshot.data),
31+
);
32+
33+
Widget createListTile(BuildContext context, bool? canLaunchUri) => canLaunchUri == null || canLaunchUri == true
34+
? ListTile(
35+
leading: const Icon(Icons.translate),
36+
title: Text(title),
37+
subtitle: subtitle == null ? null : Text(subtitle!),
38+
onTap: canLaunchUri == true ? (() async => await launchUrl(uri)) : null,
39+
)
40+
: SizedBox.shrink();
41+
}

lib/pages/settings/page.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ class SettingsPage extends ConsumerWidget {
6969
const BackupNowSettingsEntryWidget(),
7070
const ManageBackupSettingsEntryWidget(),
7171
_SettingsPageSectionTitle(title: translations.settings.about.title),
72-
const TranslateSettingsEntryWidget(),
73-
const GithubSettingsEntryWidget(),
72+
TranslateSettingsEntryWidget(),
73+
GithubSettingsEntryWidget(),
7474
const AboutSettingsEntryWidget(),
7575
_SettingsPageSectionTitle(title: translations.settings.dangerZone.title),
7676
const DeleteAccountSettingsEntryWidget(),

0 commit comments

Comments
 (0)