feat(ui): About page now contains links

pull/467/head
Inex Code 2024-02-21 01:48:52 +03:00
parent 0d12b1d2d7
commit 9532ddc8af
21 changed files with 369 additions and 290 deletions

View File

@ -1,12 +0,0 @@
### Пра нас
Усё больш арганізацый жадаюць валодаць нашымі дадзенымі
Праект дазваляе толькі Вам у поўнай меры распараджацца ўласнымі **дадзенымі** на сваім сэрвэры.
### Наша місія
Лічбавая незалежнасць і прыватнасць, даступныя кожнаму
### Мэта
Распрацаваць праграму, якая дазволіць кожнаму разгарнуць свае прыватныя паслугі для сябе і сваіх суседзяў.

View File

@ -1,12 +0,0 @@
### O nás
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Naše poslání
Digitální nezávislost a soukromí dostupné všem
### Cíl
Rozvíjet program, který umožní každému nasadit své soukromé služby pro sebe a své sousedy.

View File

@ -1,12 +0,0 @@
### Über uns
Immer mehr Unternehmen wollen unsere Daten kontrollieren.
Wir wollen selbst die volle Kontrolle über unsere **data** haben.
### Unsere Mission
Digitale Unabhängigkeit und Privatsphäre für alle verfügbar
### Ziel
Das Programm entwickeln, das es jedem ermöglicht, seine privaten Dienste für sich und seine Nachbarn einzusetzen.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Misja projektu
Niezależność i prywatność cyfrowa dostępna dla wszystkich
### Cel
Opracuj program, dzięki któremu każdy będzie mógł stworzyć prywatne usługi dla siebie i swoich bliskich.

View File

@ -1,12 +0,0 @@
### О проекте
Всё больше организаций хотят владеть нашими данными
Проект позволяет только Вам в полной мере распоряжаться собственными **данными** на своём сервере.
### Миссия проекта
Цифровая независимость и приватность, доступная каждому
### Цель
Развивать программу, которая позволит каждому создавать приватные сервисы для себя и своих близких.

View File

@ -1,12 +0,0 @@
### O nás
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Naše poslanie
Digitálna nezávislosť a súkromie dostupné pre každého
### Cieľ
Vytvorte program, ktorý umožní každému vytvoriť súkromné služby pre seba a svojich blízkych.

View File

@ -1,12 +0,0 @@
### About us
More and more corporations want to control our data.
We want to have full control of our **data** on our own.
### Our mission
Digital independence and privacy, available to everyone
### Target
Develop the program, which will allow everyone to deploy their private services for themselves and their neighbours.

View File

@ -1,12 +0,0 @@
### Про нас
Все більше корпорацій хочуть контролювати свої дані.
Ми хочемо мати повний контроль над нашими.
### Наша місія
Цифрова незалежність і конфіденційність доступні кожному
### Ціль
Розробити програму, яка дозволить кожному розгорнути свої приватні послуги для себе та їх сусідів.

View File

@ -41,25 +41,34 @@
},
"more_page": {
"configuration_wizard": "Setup wizard",
"about_project": "About us",
"about_application": "About",
"onboarding": "Onboarding",
"create_ssh_key": "Superuser SSH keys",
"console": "Console",
"application_settings": "Application settings"
"create_ssh_key": "Superuser SSH keys"
},
"console_page": {
"title": "Console",
"waiting": "Waiting for initialization…",
"copy": "Copy"
},
"about_us_page": {
"title": "About us"
},
"about_application_page": {
"title": "About",
"application_version_text": "Application version {}",
"api_version_text": "Server API version {}",
"title": "About & support",
"versions": "Versions",
"application_version_text": "Application version",
"api_version_text": "Server API version",
"open_source_licenses": "Open source licenses",
"links": "Links",
"website": "Our website",
"documentation": "Documentation",
"matrix_channel": "Matrix channel",
"telegram_channel": "Telegram channel",
"get_support": "Get support",
"matrix_support_chat": "Matrix support chat",
"telegram_support_chat": "Telegram support chat",
"email_support": "Email support",
"contribute": "Contribute",
"source_code": "Source code",
"help_translate": "Help us translate",
"matrix_contributors_chat": "Matrix contributors chat",
"telegram_contributors_chat": "Telegram contributors chat",
"privacy_policy": "Privacy policy"
},
"application_settings": {

View File

@ -17,10 +17,6 @@ class StrayDeerPainter extends CustomPainter {
final Color deerSkin =
const Color(0xffe0ac9c).harmonizeWith(colorScheme.primary);
print('deerSkin: $deerSkin');
print('colorScheme.primary: ${colorScheme.primary}');
print('colorPalette.tertiary.get(10): ${colorPalette.tertiary.get(50)}');
final Path path0 = Path();
path0.moveTo(size.width * 0.6099773, size.height * 0.6719577);
path0.lineTo(size.width * 0.6088435, size.height * 0.6719577);

View File

@ -2,10 +2,9 @@ import 'package:auto_route/auto_route.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:package_info/package_info.dart';
import 'package:selfprivacy/logic/api_maps/graphql_maps/server_api/server_api.dart';
import 'package:selfprivacy/logic/cubit/server_installation/server_installation_cubit.dart';
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
import 'package:selfprivacy/config/get_it_config.dart';
import 'package:selfprivacy/ui/layouts/brand_hero_screen.dart';
import 'package:selfprivacy/utils/platform_adapter.dart';
import 'package:url_launcher/url_launcher.dart';
@RoutePage()
@ -13,67 +12,356 @@ class AboutApplicationPage extends StatelessWidget {
const AboutApplicationPage({super.key});
@override
Widget build(final BuildContext context) {
final bool isReady = context.watch<ServerInstallationCubit>().state
is ServerInstallationFinished;
return BrandHeroScreen(
hasBackButton: true,
hasFlashButton: false,
heroTitle: 'about_application_page.title'.tr(),
children: [
FutureBuilder(
future: _packageVersion(),
builder: (final context, final snapshot) => Text(
'about_application_page.application_version_text'
.tr(args: [snapshot.data.toString()]),
style: Theme.of(context).textTheme.bodyLarge,
),
),
if (isReady)
FutureBuilder(
future: _apiVersion(),
builder: (final context, final snapshot) => Text(
'about_application_page.api_version_text'
.tr(args: [snapshot.data.toString()]),
style: Theme.of(context).textTheme.bodyLarge,
Widget build(final BuildContext context) => BrandHeroScreen(
hasBackButton: true,
hasFlashButton: false,
heroTitle: 'about_application_page.title'.tr(),
bodyPadding: const EdgeInsets.symmetric(vertical: 16),
children: [
Padding(
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,
),
),
),
const SizedBox(height: 10),
// Button to call showAboutDialog
TextButton(
onPressed: () => showAboutDialog(
context: context,
applicationName: 'SelfPrivacy',
applicationLegalese: '© 2024 SelfPrivacy',
// Link to privacy policy
children: [
TextButton(
onPressed: () => launchUrl(
Uri.parse('https://selfprivacy.org/privacy-policy/'),
mode: LaunchMode.externalApplication,
),
child: Text('about_application_page.privacy_policy'.tr()),
FutureBuilder(
future: _packageVersion(),
builder: (final context, final snapshot) => ListTile(
title: Text(
'about_application_page.application_version_text'.tr(),
),
],
subtitle: Text(
snapshot.data.toString(),
),
leading: const Icon(
Icons.phone_android_outlined,
),
onLongPress: () {
PlatformAdapter.setClipboard(
snapshot.data.toString(),
);
getIt<NavigationService>().showSnackBar(
'basis.copied_to_clipboard'.tr(),
);
},
),
),
child: const Text('Show about dialog'),
),
const SizedBox(height: 8),
const Divider(height: 0),
const SizedBox(height: 8),
const BrandMarkdown(
fileName: 'about',
),
],
);
}
if (getIt<ApiConnectionRepository>().apiData.apiVersion.data != null)
FutureBuilder(
future: _apiVersion(),
builder: (final context, final snapshot) => ListTile(
title: Text(
'about_application_page.api_version_text'.tr(),
),
subtitle: Text(snapshot.data.toString()),
leading: const Icon(
Icons.api_outlined,
),
onLongPress: () {
PlatformAdapter.setClipboard(
snapshot.data.toString(),
);
getIt<NavigationService>().showSnackBar(
'basis.copied_to_clipboard'.tr(),
);
},
),
),
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',
),
leading: const Icon(
Icons.copyright_outlined,
),
),
),
Padding(
padding: const EdgeInsets.all(16),
child: Text(
'about_application_page.links'.tr(),
style: Theme.of(context).textTheme.labelLarge!.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
),
),
ListTile(
title: Text('about_application_page.website'.tr()),
subtitle: const Text('selfprivacy.org'),
onTap: () => launchUrl(
Uri.parse('https://selfprivacy.org/'),
mode: LaunchMode.externalApplication,
),
leading: const Icon(
Icons.language_outlined,
),
onLongPress: () {
PlatformAdapter.setClipboard(
'https://selfprivacy.org/',
);
getIt<NavigationService>().showSnackBar(
'basis.copied_to_clipboard'.tr(),
);
},
),
ListTile(
title: Text('about_application_page.documentation'.tr()),
subtitle: const Text('selfprivacy.org/docs'),
onTap: () => launchUrl(
Uri.parse('https://selfprivacy.org/docs/'),
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(
title: Text('about_application_page.privacy_policy'.tr()),
subtitle: const Text('selfprivacy.org/privacy-policy'),
onTap: () => launchUrl(
Uri.parse('https://selfprivacy.org/privacy-policy/'),
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
ListTile(
title: Text('about_application_page.matrix_channel'.tr()),
subtitle: const Text('#news:selfprivacy.org'),
onTap: () => launchUrl(
Uri.parse('https://matrix.to/#/#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
ListTile(
title: Text('about_application_page.telegram_channel'.tr()),
subtitle: const Text('@selfprivacy'),
onTap: () => launchUrl(
Uri.parse('https://t.me/selfprivacy'),
mode: LaunchMode.externalApplication,
),
leading: const Icon(
Icons.feed_outlined,
),
onLongPress: () {
PlatformAdapter.setClipboard(
'@selfprivacy',
);
getIt<NavigationService>().showSnackBar(
'basis.copied_to_clipboard'.tr(),
);
},
),
Padding(
padding: const EdgeInsets.all(16),
child: Text(
'about_application_page.get_support'.tr(),
style: Theme.of(context).textTheme.labelLarge!.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
),
),
// Matrix
ListTile(
title: Text('about_application_page.matrix_support_chat'.tr()),
subtitle: const Text('#chat:selfprivacy.org'),
onTap: () => launchUrl(
Uri.parse('https://matrix.to/#/#chat:selfprivacy.org'),
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
ListTile(
title: Text('about_application_page.telegram_support_chat'.tr()),
subtitle: const Text('@selfprivacy_chat'),
onTap: () => launchUrl(
Uri.parse('https://t.me/selfprivacy_chat'),
mode: LaunchMode.externalApplication,
),
leading: const Icon(
Icons.question_answer_outlined,
),
onLongPress: () {
PlatformAdapter.setClipboard(
'@selfprivacy_chat',
);
getIt<NavigationService>().showSnackBar(
'basis.copied_to_clipboard'.tr(),
);
},
),
// Email
ListTile(
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(
padding: const EdgeInsets.all(16),
child: Text(
'about_application_page.contribute'.tr(),
style: Theme.of(context).textTheme.labelLarge!.copyWith(
color: Theme.of(context).colorScheme.secondary,
),
),
),
// Source code
ListTile(
title: Text('about_application_page.source_code'.tr()),
subtitle: const Text('git.selfprivacy.org'),
onTap: () => launchUrl(
Uri.parse(
'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
ListTile(
title: Text('about_application_page.help_translate'.tr()),
subtitle: const Text('weblate.selfprivacy.org'),
onTap: () => launchUrl(
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
ListTile(
title: Text('about_application_page.matrix_contributors_chat'.tr()),
subtitle: const Text('#dev:selfprivacy.org'),
onTap: () => launchUrl(
Uri.parse('https://matrix.to/#/#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
ListTile(
title:
Text('about_application_page.telegram_contributors_chat'.tr()),
subtitle: const Text('@selfprivacy_dev'),
onTap: () => launchUrl(
Uri.parse('https://t.me/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(),
);
},
),
],
);
Future<String> _packageVersion() async {
String packageVersion = 'unknown';
try {
final PackageInfo packageInfo = await PackageInfo.fromPlatform();
packageVersion = packageInfo.version;
packageVersion = '${packageInfo.version} (${packageInfo.buildNumber})';
} catch (e) {
print(e);
}
@ -82,12 +370,8 @@ class AboutApplicationPage extends StatelessWidget {
}
Future<String> _apiVersion() async {
String apiVersion = 'unknown';
try {
apiVersion = await ServerApi().getApiVersion() ?? apiVersion;
} catch (e) {
print(e);
}
final apiVersion =
getIt<ApiConnectionRepository>().apiData.apiVersion.data ?? 'unknown';
return apiVersion;
}

View File

@ -1,30 +0,0 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:selfprivacy/config/brand_theme.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
class AboutUsPage extends StatelessWidget {
const AboutUsPage({super.key});
@override
Widget build(final BuildContext context) => SafeArea(
child: Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(52),
child: BrandHeader(
title: 'about_us_page.title'.tr(),
hasBackButton: true,
),
),
body: ListView(
padding: paddingH15V0,
children: const [
BrandMarkdown(
fileName: 'about',
),
],
),
),
);
}

View File

@ -63,12 +63,12 @@ class MorePage extends StatelessWidget {
title: 'devices.main_screen.header'.tr(),
),
_MoreMenuItem(
title: 'more_page.application_settings'.tr(),
title: 'application_settings.title'.tr(),
iconData: Icons.settings_outlined,
goTo: () => const AppSettingsRoute(),
),
_MoreMenuItem(
title: 'more_page.about_application'.tr(),
title: 'about_application_page.title'.tr(),
iconData: BrandIcons.fire,
goTo: () => const AboutApplicationRoute(),
longGoTo: const DeveloperSettingsRoute(),
@ -80,7 +80,7 @@ class MorePage extends StatelessWidget {
goTo: () => const OnboardingRoute(),
),
_MoreMenuItem(
title: 'more_page.console'.tr(),
title: 'console_page.title'.tr(),
iconData: BrandIcons.terminal,
goTo: () => const ConsoleRoute(),
),

View File

@ -132,7 +132,7 @@ String getRouteTitle(final String routeName) {
case 'DevicesRoute':
return 'devices.main_screen.header';
case 'AboutApplicationRoute':
return 'about_us_page.title';
return 'about_application_page.title';
case 'ConsoleRoute':
return 'console_page.title';
case 'DeveloperSettingsRoute':