refactor(ui): Code deduplication in AboutApplicationPage
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
e36cba045a
commit
490e5f92f3
|
@ -66,6 +66,8 @@
|
||||||
"email_support": "Email support",
|
"email_support": "Email support",
|
||||||
"contribute": "Contribute",
|
"contribute": "Contribute",
|
||||||
"source_code": "Source code",
|
"source_code": "Source code",
|
||||||
|
"bug_report": "Report a bug",
|
||||||
|
"bug_report_subtitle": "Due to spam, manual account confirmation is required. Contact us in the support chat to activate your account.",
|
||||||
"help_translate": "Help us translate",
|
"help_translate": "Help us translate",
|
||||||
"matrix_contributors_chat": "Matrix contributors chat",
|
"matrix_contributors_chat": "Matrix contributors chat",
|
||||||
"telegram_contributors_chat": "Telegram contributors chat",
|
"telegram_contributors_chat": "Telegram contributors chat",
|
||||||
|
|
|
@ -44,15 +44,7 @@ class AboutApplicationPage extends StatelessWidget {
|
||||||
heroTitle: 'about_application_page.title'.tr(),
|
heroTitle: 'about_application_page.title'.tr(),
|
||||||
bodyPadding: const EdgeInsets.symmetric(vertical: 16),
|
bodyPadding: const EdgeInsets.symmetric(vertical: 16),
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
SectionTitle(title: 'about_application_page.versions'.tr()),
|
||||||
padding: const EdgeInsets.all(16),
|
|
||||||
child: Text(
|
|
||||||
'about_application_page.versions'.tr(),
|
|
||||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FutureBuilder(
|
FutureBuilder(
|
||||||
future: _packageVersion(),
|
future: _packageVersion(),
|
||||||
builder: (final context, final snapshot) => ListTile(
|
builder: (final context, final snapshot) => ListTile(
|
||||||
|
@ -111,273 +103,98 @@ class AboutApplicationPage extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
SectionTitle(
|
||||||
padding: const EdgeInsets.all(16),
|
title: 'about_application_page.links'.tr(),
|
||||||
child: Text(
|
|
||||||
'about_application_page.links'.tr(),
|
|
||||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
ListTile(
|
LinkListTile(
|
||||||
title: Text('about_application_page.website'.tr()),
|
title: 'about_application_page.website'.tr(),
|
||||||
subtitle: const Text('selfprivacy.org'),
|
subtitle: 'selfprivacy.org',
|
||||||
onTap: () => launchUrl(
|
uri: 'https://selfprivacy.org/',
|
||||||
Uri.parse('https://selfprivacy.org/'),
|
icon: Icons.language_outlined,
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.language_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'https://selfprivacy.org/',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
LinkListTile(
|
||||||
title: Text('about_application_page.documentation'.tr()),
|
title: 'about_application_page.documentation'.tr(),
|
||||||
subtitle: const Text('selfprivacy.org/docs'),
|
subtitle: 'selfprivacy.org/docs',
|
||||||
onTap: () => launchUrl(
|
uri: 'https://selfprivacy.org/docs/',
|
||||||
Uri.parse('https://selfprivacy.org/docs/'),
|
icon: Icons.library_books_outlined,
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.library_books_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'https://selfprivacy.org/docs/',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
ListTile(
|
LinkListTile(
|
||||||
title: Text('about_application_page.privacy_policy'.tr()),
|
title: 'about_application_page.privacy_policy'.tr(),
|
||||||
subtitle: const Text('selfprivacy.org/privacy-policy'),
|
subtitle: 'selfprivacy.org/privacy-policy',
|
||||||
onTap: () => launchUrl(
|
uri: 'https://selfprivacy.org/privacy-policy/',
|
||||||
Uri.parse('https://selfprivacy.org/privacy-policy/'),
|
icon: Icons.policy_outlined,
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.policy_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'https://selfprivacy.org/privacy-policy/',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
// Matrix channel
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.matrix_channel'.tr(),
|
||||||
title: Text('about_application_page.matrix_channel'.tr()),
|
subtitle: '#news:selfprivacy.org',
|
||||||
subtitle: const Text('#news:selfprivacy.org'),
|
uri: 'https://matrix.to/#/#news:selfprivacy.org',
|
||||||
onTap: () => launchUrl(
|
icon: Icons.feed_outlined,
|
||||||
Uri.parse('https://matrix.to/#/#news:selfprivacy.org'),
|
longPressText: '#news:selfprivacy.org',
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.feed_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'#news:selfprivacy.org',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
// Telegram channel
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.telegram_channel'.tr(),
|
||||||
title: Text('about_application_page.telegram_channel'.tr()),
|
subtitle: '@selfprivacy',
|
||||||
subtitle: const Text('@selfprivacy'),
|
uri: 'https://t.me/selfprivacy',
|
||||||
onTap: () => launchUrl(
|
icon: Icons.feed_outlined,
|
||||||
Uri.parse('https://t.me/selfprivacy'),
|
longPressText: '@selfprivacy',
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.feed_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'@selfprivacy',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
Padding(
|
SectionTitle(title: 'about_application_page.get_support'.tr()),
|
||||||
padding: const EdgeInsets.all(16),
|
LinkListTile(
|
||||||
child: Text(
|
title: 'about_application_page.matrix_support_chat'.tr(),
|
||||||
'about_application_page.get_support'.tr(),
|
subtitle: '#chat:selfprivacy.org',
|
||||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
uri: 'https://matrix.to/#/#chat:selfprivacy.org',
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
icon: Icons.question_answer_outlined,
|
||||||
),
|
longPressText: '#chat:selfprivacy.org',
|
||||||
),
|
|
||||||
),
|
),
|
||||||
// Matrix
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.telegram_support_chat'.tr(),
|
||||||
title: Text('about_application_page.matrix_support_chat'.tr()),
|
subtitle: '@selfprivacy_chat',
|
||||||
subtitle: const Text('#chat:selfprivacy.org'),
|
uri: 'https://t.me/selfprivacy_chat',
|
||||||
onTap: () => launchUrl(
|
icon: Icons.question_answer_outlined,
|
||||||
Uri.parse('https://matrix.to/#/#chat:selfprivacy.org'),
|
longPressText: '@selfprivacy_chat',
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.question_answer_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'#chat:selfprivacy.org',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
// Telegram
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.email_support'.tr(),
|
||||||
title: Text('about_application_page.telegram_support_chat'.tr()),
|
subtitle: 'support@selfprivacy.org',
|
||||||
subtitle: const Text('@selfprivacy_chat'),
|
uri: 'mailto:support@selfprivacy.org',
|
||||||
onTap: () => launchUrl(
|
icon: Icons.email_outlined,
|
||||||
Uri.parse('https://t.me/selfprivacy_chat'),
|
longPressText: 'support@selfprivacy.org',
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.question_answer_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'@selfprivacy_chat',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
// Email
|
SectionTitle(
|
||||||
ListTile(
|
title: 'about_application_page.contribute'.tr(),
|
||||||
title: Text('about_application_page.email_support'.tr()),
|
|
||||||
subtitle: const Text('support@selfprivacy.org'),
|
|
||||||
onTap: () => launchUrl(
|
|
||||||
Uri.parse('mailto:support@selfprivacy.org'),
|
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.email_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'support@selfprivacy.org',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
Padding(
|
LinkListTile(
|
||||||
padding: const EdgeInsets.all(16),
|
title: 'about_application_page.source_code'.tr(),
|
||||||
child: Text(
|
subtitle: 'git.selfprivacy.org',
|
||||||
'about_application_page.contribute'.tr(),
|
uri: 'https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app',
|
||||||
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
icon: Icons.code_outlined,
|
||||||
color: Theme.of(context).colorScheme.secondary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
// Source code
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.bug_report'.tr(),
|
||||||
title: Text('about_application_page.source_code'.tr()),
|
subtitle: 'about_application_page.bug_report_subtitle'.tr(),
|
||||||
subtitle: const Text('git.selfprivacy.org'),
|
uri:
|
||||||
onTap: () => launchUrl(
|
'https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app/issues',
|
||||||
Uri.parse(
|
icon: Icons.bug_report_outlined,
|
||||||
'https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app',
|
|
||||||
),
|
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.code_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
// translate
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.help_translate'.tr(),
|
||||||
title: Text('about_application_page.help_translate'.tr()),
|
subtitle: 'weblate.selfprivacy.org',
|
||||||
subtitle: const Text('weblate.selfprivacy.org'),
|
uri: 'https://weblate.selfprivacy.org/projects/selfprivacy/',
|
||||||
onTap: () => launchUrl(
|
icon: Icons.translate_outlined,
|
||||||
Uri.parse(
|
|
||||||
'https://weblate.selfprivacy.org/projects/selfprivacy/',
|
|
||||||
),
|
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.translate_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'https://weblate.selfprivacy.org/projects/selfprivacy/',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
// matrix chat
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.matrix_contributors_chat'.tr(),
|
||||||
title: Text('about_application_page.matrix_contributors_chat'.tr()),
|
subtitle: '#dev:selfprivacy.org',
|
||||||
subtitle: const Text('#dev:selfprivacy.org'),
|
uri: 'https://matrix.to/#/#dev:selfprivacy.org',
|
||||||
onTap: () => launchUrl(
|
icon: Icons.question_answer_outlined,
|
||||||
Uri.parse('https://matrix.to/#/#dev:selfprivacy.org'),
|
longPressText: '#dev:selfprivacy.org',
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.question_answer_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'#dev:selfprivacy.org',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
// telegram
|
LinkListTile(
|
||||||
ListTile(
|
title: 'about_application_page.telegram_contributors_chat'.tr(),
|
||||||
title: Text('about_application_page.telegram_contributors_chat'.tr()),
|
subtitle: '@selfprivacy_dev',
|
||||||
subtitle: const Text('@selfprivacy_dev'),
|
uri: 'https://t.me/selfprivacy_dev',
|
||||||
onTap: () => launchUrl(
|
icon: Icons.question_answer_outlined,
|
||||||
Uri.parse('https://t.me/selfprivacy_dev'),
|
longPressText: '@selfprivacy_dev',
|
||||||
mode: LaunchMode.externalApplication,
|
|
||||||
),
|
|
||||||
leading: const Icon(
|
|
||||||
Icons.question_answer_outlined,
|
|
||||||
),
|
|
||||||
onLongPress: () {
|
|
||||||
PlatformAdapter.setClipboard(
|
|
||||||
'@selfprivacy_dev',
|
|
||||||
);
|
|
||||||
getIt<NavigationService>().showSnackBar(
|
|
||||||
'basis.copied_to_clipboard'.tr(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
@ -402,3 +219,59 @@ class AboutApplicationPage extends StatelessWidget {
|
||||||
return apiVersion;
|
return apiVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SectionTitle extends StatelessWidget {
|
||||||
|
const SectionTitle({
|
||||||
|
required this.title,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => Padding(
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
child: Text(
|
||||||
|
title,
|
||||||
|
style: Theme.of(context).textTheme.labelLarge!.copyWith(
|
||||||
|
color: Theme.of(context).colorScheme.secondary,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class LinkListTile extends StatelessWidget {
|
||||||
|
const LinkListTile({
|
||||||
|
required this.title,
|
||||||
|
required this.subtitle,
|
||||||
|
required this.uri,
|
||||||
|
required this.icon,
|
||||||
|
this.longPressText,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final String title;
|
||||||
|
final String subtitle;
|
||||||
|
final String uri;
|
||||||
|
final IconData icon;
|
||||||
|
final String? longPressText;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(final BuildContext context) => ListTile(
|
||||||
|
title: Text(title),
|
||||||
|
subtitle: Text(subtitle),
|
||||||
|
onTap: () => launchUrl(
|
||||||
|
Uri.parse(uri),
|
||||||
|
mode: LaunchMode.externalApplication,
|
||||||
|
),
|
||||||
|
leading: Icon(icon),
|
||||||
|
onLongPress: () {
|
||||||
|
PlatformAdapter.setClipboard(
|
||||||
|
longPressText ?? uri,
|
||||||
|
);
|
||||||
|
getIt<NavigationService>().showSnackBar(
|
||||||
|
'basis.copied_to_clipboard'.tr(),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue