2024-02-20 23:03:53 +00:00
|
|
|
import 'dart:io';
|
|
|
|
|
2023-03-22 11:38:18 +00:00
|
|
|
import 'package:auto_route/auto_route.dart';
|
2024-01-31 05:14:23 +00:00
|
|
|
import 'package:easy_localization/easy_localization.dart';
|
2020-12-02 09:16:23 +00:00
|
|
|
import 'package:flutter/material.dart';
|
2024-01-31 05:14:23 +00:00
|
|
|
import 'package:package_info/package_info.dart';
|
2024-02-20 22:48:52 +00:00
|
|
|
import 'package:selfprivacy/config/get_it_config.dart';
|
2024-02-23 16:50:28 +00:00
|
|
|
import 'package:selfprivacy/ui/components/list_tiles/section_title.dart';
|
2023-02-23 14:49:14 +00:00
|
|
|
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
|
2024-02-20 23:11:57 +00:00
|
|
|
import 'package:selfprivacy/utils/breakpoints.dart';
|
2024-02-20 22:48:52 +00:00
|
|
|
import 'package:selfprivacy/utils/platform_adapter.dart';
|
2022-12-31 06:04:25 +00:00
|
|
|
import 'package:url_launcher/url_launcher.dart';
|
2020-12-02 09:16:23 +00:00
|
|
|
|
2023-03-22 11:38:18 +00:00
|
|
|
@RoutePage()
|
2022-10-03 23:32:35 +00:00
|
|
|
class AboutApplicationPage extends StatelessWidget {
|
2022-10-26 16:26:09 +00:00
|
|
|
const AboutApplicationPage({super.key});
|
2020-12-02 09:16:23 +00:00
|
|
|
|
|
|
|
@override
|
2024-02-20 23:03:53 +00:00
|
|
|
Widget build(final BuildContext context) {
|
|
|
|
IconData getPlatformIcon() {
|
|
|
|
if (Platform.isAndroid) {
|
2024-02-20 23:11:57 +00:00
|
|
|
if (Breakpoints.small.isActive(context)) {
|
|
|
|
return Icons.phone_android_outlined;
|
|
|
|
}
|
|
|
|
return Icons.tablet_android_outlined;
|
2024-02-20 23:03:53 +00:00
|
|
|
} else if (Platform.isIOS) {
|
2024-02-20 23:11:57 +00:00
|
|
|
if (Breakpoints.small.isActive(context)) {
|
|
|
|
return Icons.phone_iphone_outlined;
|
|
|
|
}
|
|
|
|
return Icons.tablet_mac_outlined;
|
2024-02-20 23:03:53 +00:00
|
|
|
} else if (Platform.isWindows || Platform.isLinux) {
|
|
|
|
return Icons.desktop_windows_outlined;
|
|
|
|
} else if (Platform.isMacOS) {
|
|
|
|
return Icons.desktop_mac_outlined;
|
|
|
|
} else {
|
|
|
|
return Icons.devices_other_outlined;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
final deviceIcon = getPlatformIcon();
|
|
|
|
|
|
|
|
return BrandHeroScreen(
|
|
|
|
hasBackButton: true,
|
|
|
|
hasFlashButton: false,
|
|
|
|
heroTitle: 'about_application_page.title'.tr(),
|
|
|
|
bodyPadding: const EdgeInsets.symmetric(vertical: 16),
|
|
|
|
children: [
|
2024-02-21 14:48:31 +00:00
|
|
|
SectionTitle(title: 'about_application_page.versions'.tr()),
|
2024-02-20 23:03:53 +00:00
|
|
|
FutureBuilder(
|
|
|
|
future: _packageVersion(),
|
|
|
|
builder: (final context, final snapshot) => ListTile(
|
|
|
|
title: Text(
|
|
|
|
'about_application_page.application_version_text'.tr(),
|
2024-02-20 22:48:52 +00:00
|
|
|
),
|
2024-02-20 23:03:53 +00:00
|
|
|
subtitle: Text(
|
|
|
|
snapshot.data.toString(),
|
|
|
|
),
|
|
|
|
leading: Icon(
|
|
|
|
deviceIcon,
|
|
|
|
),
|
|
|
|
onLongPress: () {
|
|
|
|
PlatformAdapter.setClipboard(
|
|
|
|
snapshot.data.toString(),
|
|
|
|
);
|
|
|
|
getIt<NavigationService>().showSnackBar(
|
|
|
|
'basis.copied_to_clipboard'.tr(),
|
|
|
|
);
|
|
|
|
},
|
2024-02-20 22:48:52 +00:00
|
|
|
),
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
|
|
|
if (getIt<ApiConnectionRepository>().apiData.apiVersion.data != null)
|
2023-02-23 14:49:14 +00:00
|
|
|
FutureBuilder(
|
2024-02-20 23:03:53 +00:00
|
|
|
future: _apiVersion(),
|
2024-02-20 22:48:52 +00:00
|
|
|
builder: (final context, final snapshot) => ListTile(
|
|
|
|
title: Text(
|
2024-02-20 23:03:53 +00:00
|
|
|
'about_application_page.api_version_text'.tr(),
|
2024-02-20 22:48:52 +00:00
|
|
|
),
|
2024-02-20 23:03:53 +00:00
|
|
|
subtitle: Text(snapshot.data.toString()),
|
2024-02-20 22:48:52 +00:00
|
|
|
leading: const Icon(
|
2024-02-20 23:03:53 +00:00
|
|
|
Icons.api_outlined,
|
2024-02-20 22:48:52 +00:00
|
|
|
),
|
|
|
|
onLongPress: () {
|
|
|
|
PlatformAdapter.setClipboard(
|
|
|
|
snapshot.data.toString(),
|
|
|
|
);
|
|
|
|
getIt<NavigationService>().showSnackBar(
|
|
|
|
'basis.copied_to_clipboard'.tr(),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
),
|
2024-02-20 23:03:53 +00:00
|
|
|
FutureBuilder(
|
|
|
|
future: _packageVersion(),
|
|
|
|
builder: (final context, final snapshot) => ListTile(
|
|
|
|
title: Text('about_application_page.open_source_licenses'.tr()),
|
|
|
|
onTap: () => showLicensePage(
|
|
|
|
context: context,
|
|
|
|
applicationName: 'SelfPrivacy',
|
|
|
|
applicationVersion: snapshot.data.toString(),
|
|
|
|
applicationLegalese: '© 2024 SelfPrivacy',
|
2024-02-20 22:48:52 +00:00
|
|
|
),
|
2024-02-20 23:03:53 +00:00
|
|
|
leading: const Icon(
|
|
|
|
Icons.copyright_outlined,
|
2024-02-20 22:48:52 +00:00
|
|
|
),
|
|
|
|
),
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
SectionTitle(
|
|
|
|
title: 'about_application_page.links'.tr(),
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.website'.tr(),
|
|
|
|
subtitle: 'selfprivacy.org',
|
|
|
|
uri: 'https://selfprivacy.org/',
|
|
|
|
icon: Icons.language_outlined,
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.documentation'.tr(),
|
|
|
|
subtitle: 'selfprivacy.org/docs',
|
|
|
|
uri: 'https://selfprivacy.org/docs/',
|
|
|
|
icon: Icons.library_books_outlined,
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.privacy_policy'.tr(),
|
|
|
|
subtitle: 'selfprivacy.org/privacy-policy',
|
|
|
|
uri: 'https://selfprivacy.org/privacy-policy/',
|
|
|
|
icon: Icons.policy_outlined,
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.matrix_channel'.tr(),
|
|
|
|
subtitle: '#news:selfprivacy.org',
|
|
|
|
uri: 'https://matrix.to/#/#news:selfprivacy.org',
|
|
|
|
icon: Icons.feed_outlined,
|
|
|
|
longPressText: '#news:selfprivacy.org',
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.telegram_channel'.tr(),
|
|
|
|
subtitle: '@selfprivacy',
|
|
|
|
uri: 'https://t.me/selfprivacy',
|
|
|
|
icon: Icons.feed_outlined,
|
|
|
|
longPressText: '@selfprivacy',
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
SectionTitle(title: 'about_application_page.get_support'.tr()),
|
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.matrix_support_chat'.tr(),
|
|
|
|
subtitle: '#chat:selfprivacy.org',
|
|
|
|
uri: 'https://matrix.to/#/#chat:selfprivacy.org',
|
|
|
|
icon: Icons.question_answer_outlined,
|
|
|
|
longPressText: '#chat:selfprivacy.org',
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.telegram_support_chat'.tr(),
|
|
|
|
subtitle: '@selfprivacy_chat',
|
|
|
|
uri: 'https://t.me/selfprivacy_chat',
|
|
|
|
icon: Icons.question_answer_outlined,
|
|
|
|
longPressText: '@selfprivacy_chat',
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.email_support'.tr(),
|
|
|
|
subtitle: 'support@selfprivacy.org',
|
|
|
|
uri: 'mailto:support@selfprivacy.org',
|
|
|
|
icon: Icons.email_outlined,
|
|
|
|
longPressText: 'support@selfprivacy.org',
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
SectionTitle(
|
|
|
|
title: 'about_application_page.contribute'.tr(),
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.source_code'.tr(),
|
|
|
|
subtitle: 'git.selfprivacy.org',
|
|
|
|
uri: 'https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app',
|
|
|
|
icon: Icons.code_outlined,
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.bug_report'.tr(),
|
|
|
|
subtitle: 'about_application_page.bug_report_subtitle'.tr(),
|
|
|
|
uri:
|
|
|
|
'https://git.selfprivacy.org/SelfPrivacy/selfprivacy.org.app/issues',
|
|
|
|
icon: Icons.bug_report_outlined,
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.help_translate'.tr(),
|
|
|
|
subtitle: 'weblate.selfprivacy.org',
|
|
|
|
uri: 'https://weblate.selfprivacy.org/projects/selfprivacy/',
|
|
|
|
icon: Icons.translate_outlined,
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.matrix_contributors_chat'.tr(),
|
|
|
|
subtitle: '#dev:selfprivacy.org',
|
|
|
|
uri: 'https://matrix.to/#/#dev:selfprivacy.org',
|
|
|
|
icon: Icons.question_answer_outlined,
|
|
|
|
longPressText: '#dev:selfprivacy.org',
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
2024-02-21 14:48:31 +00:00
|
|
|
LinkListTile(
|
|
|
|
title: 'about_application_page.telegram_contributors_chat'.tr(),
|
|
|
|
subtitle: '@selfprivacy_dev',
|
|
|
|
uri: 'https://t.me/selfprivacy_dev',
|
|
|
|
icon: Icons.question_answer_outlined,
|
|
|
|
longPressText: '@selfprivacy_dev',
|
2024-02-20 23:03:53 +00:00
|
|
|
),
|
|
|
|
],
|
|
|
|
);
|
|
|
|
}
|
2020-12-02 09:16:23 +00:00
|
|
|
|
2022-07-25 14:06:55 +00:00
|
|
|
Future<String> _packageVersion() async {
|
2022-06-09 04:36:22 +00:00
|
|
|
String packageVersion = 'unknown';
|
|
|
|
try {
|
|
|
|
final PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
2024-02-20 22:48:52 +00:00
|
|
|
packageVersion = '${packageInfo.version} (${packageInfo.buildNumber})';
|
2022-06-09 04:36:22 +00:00
|
|
|
} catch (e) {
|
|
|
|
print(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
return packageVersion;
|
2020-12-02 09:16:23 +00:00
|
|
|
}
|
2022-07-25 14:06:55 +00:00
|
|
|
|
|
|
|
Future<String> _apiVersion() async {
|
2024-02-20 22:48:52 +00:00
|
|
|
final apiVersion =
|
|
|
|
getIt<ApiConnectionRepository>().apiData.apiVersion.data ?? 'unknown';
|
2022-07-25 14:06:55 +00:00
|
|
|
|
|
|
|
return apiVersion;
|
|
|
|
}
|
2020-12-02 09:16:23 +00:00
|
|
|
}
|
2024-02-21 14:48:31 +00:00
|
|
|
|
|
|
|
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(),
|
|
|
|
);
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|