fdroid
Kherel 2021-03-18 08:26:54 +01:00
parent ab2893a075
commit dce4c41fd1
18 changed files with 172 additions and 82 deletions

Binary file not shown.

View File

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

View File

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

View File

@ -0,0 +1,7 @@
### Как получить Hetzner API Token
1. Переходим по ссылке https://hetzner.com
2. Заходим в созданный нами проект. Если такового - нет, значит создаём.
3. Наводим мышкой на боковую панель. Она должна раскрыться, показав нам пункты меню. Нас интересует последний — Security (с иконкой ключика).
4. Далее, в верхней части интерфейса видим примерно такой список: SSH Keys, API Tokens, Certificates, Members. Нам нужен API Tokens. Переходим по нему.
5. В правой части интерфейса, нас будет ожидать кнопка Generate API token. Если же вы используете мобильную версию сайта, в нижнем правом углу вы увидите красный плюсик. Нажимаем на эту кнопку.
6. В поле Description, даём нашему токену название (это может быть любое название, которые вам нравиться. Сути оно не меняет.

View File

@ -0,0 +1,7 @@
### Как получить Hetzner API Token
1. Переходим по ссылке https://hetzner.com
2. Заходим в созданный нами проект. Если такового - нет, значит создаём.
3. Наводим мышкой на боковую панель. Она должна раскрыться, показав нам пункты меню. Нас интересует последний — Security (с иконкой ключика).
4. Далее, в верхней части интерфейса видим примерно такой список: SSH Keys, API Tokens, Certificates, Members. Нам нужен API Tokens. Переходим по нему.
5. В правой части интерфейса, нас будет ожидать кнопка Generate API token. Если же вы используете мобильную версию сайта, в нижнем правом углу вы увидите красный плюсик. Нажимаем на эту кнопку.
6. В поле Description, даём нашему токену название (это может быть любое название, которые вам нравиться. Сути оно не меняет.

View File

@ -1,5 +1,6 @@
{
"test": "en-test",
"locale": "en",
"basis": {
"_comment": "Basic interface elements",
"providers": "Providers",
@ -28,7 +29,10 @@
"about_project": "About us",
"about_app": "About application",
"onboarding": "Onboarding",
"console": "Console"
"console": "Console",
"about_app_page": {
"text": "Тут любая служебная информация, v.{}"
}
},
"onboarding": {
"_comment": "Onboarding pages",
@ -162,6 +166,6 @@
"17": "Проверка",
"18": "Как получить Hetzner API Token'",
"19": "1 Переходим по ссылке ",
"20": "\n2 Заходим в созданный нами проект. Если такового - нет, значит создаём.\n3 Наводим мышкой на боковую панель. Она должна раскрыться, показав нам пункты меню. Нас интересует последний — Security (с иконкой ключика).\n4 Далее, в верхней части интерфейса видим примерно такой список: SSH Keys, API Tokens, Certificates, Members. Нам нужен API Tokens. Переходим по нему.\n5 В правой части интерфейса, нас будет ожидать кнопка Generate API token. Если же вы используете мобильную версию сайта, в нижнем правом углу вы увидите красный плюсик. Нажимаем на эту кнопку.\n6 В поле Description, даём нашему токену название (это может быть любое название, которые вам нравиться. Сути оно не меняет."
"20": "\n"
}
}

View File

@ -1,5 +1,6 @@
{
"test": "ru-test",
"locale": "ru",
"basis": {
"_comment": "базовые элементы интерфейса",
"providers": "Провайдеры",
@ -28,7 +29,10 @@
"about_project": "О проекте SelfPrivacy",
"about_app": "О приложении",
"onboarding": "Onboarding",
"console": "Console"
"console": "Console",
"about_app_page": {
"text": "Тут любая служебная информация, v.{}"
}
},
"onboarding": {
"_comment": "страницы онбординга",

0
lib/config/md_files.dart Normal file
View File

View File

@ -53,6 +53,8 @@ class BrandIcons {
IconData(0xe80e, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData triangle =
IconData(0xe80f, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData engineer =
IconData(0xe810, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData server =
IconData(0xe811, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData box =
@ -67,4 +69,14 @@ class BrandIcons {
IconData(0xe816, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData arrow_left =
IconData(0xe818, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData shape =
IconData(0xe819, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData keyhole =
IconData(0xe81a, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData terminal =
IconData(0xe81b, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData fire =
IconData(0xe81c, fontFamily: _kFontFam, fontPackage: _kFontPkg);
static const IconData start =
IconData(0xe81d, fontFamily: _kFontFam, fontPackage: _kFontPkg);
}

View File

@ -0,0 +1,70 @@
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/config/brand_colors.dart';
import 'package:selfprivacy/config/text_themes.dart';
import 'package:url_launcher/url_launcher.dart';
class BrandMarkdown extends StatefulWidget {
const BrandMarkdown({
Key? key,
required this.fileName,
}) : super(key: key);
final String fileName;
@override
_BrandMarkdownState createState() => _BrandMarkdownState();
}
class _BrandMarkdownState extends State<BrandMarkdown> {
String _mdContent = '';
@override
void initState() {
super.initState();
_loadMdFile();
}
void _loadMdFile() async {
String mdFromFile = await rootBundle
.loadString('assets/markdown/${widget.fileName}-${'locale'.tr()}.md');
setState(() {
_mdContent = mdFromFile;
});
}
@override
Widget build(BuildContext context) {
var isDark = Theme.of(context).brightness == Brightness.dark;
var markdown = MarkdownStyleSheet(
p: defaultTextStyle,
h1: headline1Style.copyWith(
color: isDark ? BrandColors.white : null,
),
h2: headline2Style.copyWith(
color: isDark ? BrandColors.white : null,
),
h3: headline3Style.copyWith(
color: isDark ? BrandColors.white : null,
),
h4: headline4Style.copyWith(
color: isDark ? BrandColors.white : null,
),
);
return Markdown(
styleSheet: markdown,
onTapLink: (String text, String? href, String title) {
if (href != null) {
canLaunch(href).then((canLaunchURL) {
if (canLaunchURL) {
launch(href);
}
});
}
},
data: _mdContent,
);
}
}

View File

@ -1,9 +1,7 @@
import 'package:cubit_form/cubit_form.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/config/brand_colors.dart';
import 'package:selfprivacy/config/brand_theme.dart';
import 'package:selfprivacy/config/text_themes.dart';
import 'package:selfprivacy/logic/cubit/forms/initializing/backblaze_form_cubit.dart';
import 'package:selfprivacy/logic/cubit/forms/initializing/cloudflare_form_cubit.dart';
import 'package:selfprivacy/logic/cubit/forms/initializing/domain_cloudflare.dart';
@ -13,8 +11,8 @@ import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
import 'package:selfprivacy/ui/components/brand_button/brand_button.dart';
import 'package:selfprivacy/ui/components/brand_card/brand_card.dart';
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
import 'package:selfprivacy/ui/components/brand_modal_sheet/brand_modal_sheet.dart';
import 'package:selfprivacy/ui/components/brand_span_button/brand_span_button.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:selfprivacy/ui/components/brand_timer/brand_timer.dart';
import 'package:selfprivacy/ui/components/progress_bar/progress_bar.dart';
@ -488,41 +486,12 @@ class _HowHetzner extends StatelessWidget {
@override
Widget build(BuildContext context) {
var isDark = Theme.of(context).brightness == Brightness.dark;
return BrandModalSheet(
child: Padding(
padding: brandPagePadding2,
child: Column(
children: [
SizedBox(height: 40),
BrandText.h2('initializing.18'.tr()),
SizedBox(height: 20),
RichText(
text: TextSpan(
children: [
TextSpan(
text: 'initializing.19'.tr(),
style: body1Style.copyWith(
color: isDark ? BrandColors.white : BrandColors.black,
),
),
BrandSpanButton.link(
text: 'hetzner.com',
urlString: 'https://hetzner.com',
),
TextSpan(
text: 'initializing.20'.tr(),
style: body1Style.copyWith(
color: isDark ? BrandColors.white : BrandColors.black,
),
),
],
),
),
],
),
),
padding: brandPagePadding1,
child: BrandMarkdown(
fileName: 'how_hetzner',
)),
);
}
}

View File

@ -1,8 +1,7 @@
import 'package:flutter/material.dart';
import 'package:selfprivacy/config/brand_theme.dart';
import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
class AboutPage extends StatelessWidget {
const AboutPage({Key? key}) : super(key: key);
@ -12,37 +11,14 @@ class AboutPage extends StatelessWidget {
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
child: BrandHeader(title: 'О проекте', hasBackButton: true),
child: BrandHeader(
title: 'more.about_project'.tr(), hasBackButton: true),
preferredSize: Size.fromHeight(52),
),
body: ListView(
padding: brandPagePadding2,
children: [
BrandDivider(),
SizedBox(height: 20),
BrandText.h3('О проекте'),
SizedBox(height: 10),
BrandText.body1(
'Всё больше организаций хотят владеть нашими данными'),
SizedBox(height: 10),
BrandText.body1(
'А мы сами хотим распоряжаться своими данными на своем сервере.'),
SizedBox(height: 20),
BrandDivider(),
SizedBox(height: 10),
BrandText.h3('Миссия проекта'),
SizedBox(height: 10),
BrandText.body1(
'Цифровая независимость и приватность доступная каждому'),
SizedBox(height: 20),
BrandDivider(),
SizedBox(height: 10),
BrandText.h3('Цель'),
SizedBox(height: 10),
BrandText.body1(
'Развивать программу, которая позволит каждому создавать приватные сервисы для себя и своих близких'),
SizedBox(height: 10),
],
body: Container(
child: BrandMarkdown(
fileName: 'about',
),
),
),
);

View File

@ -9,6 +9,7 @@ import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:selfprivacy/utils/named_font_weight.dart';
import 'package:easy_localization/easy_localization.dart';
class AppSettingsPage extends StatefulWidget {
const AppSettingsPage({Key? key}) : super(key: key);
@ -27,7 +28,7 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
return Scaffold(
appBar: PreferredSize(
child:
BrandHeader(title: 'Настройки приложения', hasBackButton: true),
BrandHeader(title: 'more.settings'.tr(), hasBackButton: true),
preferredSize: Size.fromHeight(52),
),
body: ListView(

View File

@ -4,6 +4,7 @@ import 'package:selfprivacy/ui/components/brand_divider/brand_divider.dart';
import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
import 'package:package_info/package_info.dart';
import 'package:easy_localization/easy_localization.dart';
class InfoPage extends StatelessWidget {
const InfoPage({Key? key}) : super(key: key);
@ -13,7 +14,7 @@ class InfoPage extends StatelessWidget {
return SafeArea(
child: Scaffold(
appBar: PreferredSize(
child: BrandHeader(title: 'О приложении', hasBackButton: true),
child: BrandHeader(title: 'more.about_app'.tr(), hasBackButton: true),
preferredSize: Size.fromHeight(52),
),
body: ListView(
@ -24,8 +25,8 @@ class InfoPage extends StatelessWidget {
FutureBuilder(
future: _version(),
builder: (context, snapshot) {
return BrandText.body1(
'Тут любая служебная информация, v.${snapshot.data}');
return BrandText.body1('more.about_app_page.text'
.tr(args: [snapshot.data.toString()]));
}),
],
),

View File

@ -35,7 +35,7 @@ class MorePage extends StatelessWidget {
BrandDivider(),
_NavItem(
title: 'more.configuration_wizard'.tr(),
iconData: BrandIcons.settings,
iconData: BrandIcons.triangle,
goTo: InitializingPage(),
),
_NavItem(
@ -45,22 +45,22 @@ class MorePage extends StatelessWidget {
),
_NavItem(
title: 'more.about_project'.tr(),
iconData: BrandIcons.triangle,
iconData: BrandIcons.engineer,
goTo: AboutPage(),
),
_NavItem(
title: 'more.about_app'.tr(),
iconData: BrandIcons.help,
iconData: BrandIcons.fire,
goTo: InfoPage(),
),
_NavItem(
title: 'more.onboarding'.tr(),
iconData: BrandIcons.triangle,
iconData: BrandIcons.start,
goTo: OnboardingPage(nextPage: RootPage()),
),
_NavItem(
title: 'more.console'.tr(),
iconData: BrandIcons.triangle,
iconData: BrandIcons.terminal,
goTo: Console(),
),
],

View File

@ -58,7 +58,7 @@ class _OnboardingPageState extends State<OnboardingPage> {
'onboarding.page1_title'.tr(),
),
SizedBox(height: 20),
BrandText.body2('services.page1_text'.tr()),
BrandText.body2('onboarding.page1_text'.tr()),
Flexible(
child: Center(
child: Image.asset(

View File

@ -298,6 +298,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_markdown:
dependency: "direct main"
description:
name: flutter_markdown
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.0"
flutter_secure_storage:
dependency: "direct main"
description:
@ -420,6 +427,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
markdown:
dependency: transitive
description:
name: markdown
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
mask_text_input_formatter:
dependency: transitive
description:

View File

@ -18,6 +18,7 @@ dependencies:
either_option: ^2.0.1-dev.1
equatable: ^2.0.0
flutter_bloc: ^7.0.0-nullsafety.5
flutter_markdown: ^0.6.0
flutter_secure_storage: ^4.1.0
get_it: ^6.0.0
hive: ^2.0.0
@ -49,6 +50,7 @@ flutter:
- assets/images/onboarding/
- assets/images/logos/
- assets/translations/
- assets/markdown/
fonts:
- family: BrandIcons
fonts:
@ -64,4 +66,3 @@ flutter:
weight: 700
- asset: assets/fonts/Inter-ExtraBold.ttf
weight: 800