Add more instructions to UI

remotes/1708434123922220183/feature/service-configurations
Inex Code 2021-12-23 13:52:12 +00:00 committed by kherel
parent 5957e5720b
commit 8622ed30f1
12 changed files with 162 additions and 49 deletions

View File

@ -0,0 +1,6 @@
### How to get Backblaze API Token
1. Visit the following link and authorize: https://secure.backblaze.com/user_signin.htm
2. On the left side of the interface, select **App Keys** in the **B2 Cloud Storage** subcategory.
3. Click on the blue **Generate New Master Application Key** button.
4. In the appeared pop-up window confirm the generation.
5. Save _keyID_ and _applicationKey_ in the safe place. For example, in the password manager.

View File

@ -0,0 +1,6 @@
### Как получить Backblaze API Token
1. Переходим по ссылке https://secure.backblaze.com/user_signin.htm и авторизуемся.
2. В левой части интерфейса выбираем **App Keys** в подкатегории **"Account"**.
3. Нажимаем на синюю кнопку **Generate New Master Application Key**.
4. Во всплывающем окне подтверждаем генерацию.
5. Сохраняем _keyID_ и _applicationKey_ в надёжном месте. Например в менеджере паролей.

View File

@ -0,0 +1,15 @@
### How to get Cloudflare API Token
1. Visit the following link: https://dash.cloudflare.com/
2. the right corner, click on the profile icon (a man in a circle). For the mobile version of the site, in the upper left corner, click the **Menu** button (three horizontal bars), in the dropdown menu, click on **My Profile**
3. There are four configuration categories to choose from: *Communication*, *Authentication*, **API Tokens**, *Session*. Choose **API Tokens**.
4. Click on **Create Token** button.
5. Go down to the bottom and see the **Create Custom Token** field and press **Get Started** button on the right side.
6. In the **Token Name** field, give your token a name.
7. Next we have Permissions. In the leftmost field, select **Zone**. In the longest field, center, select **DNS**. In the rightmost field, select **Edit**.
8. Next, right under this line, click Add More. Similar field will appear.
9. In the leftmost field of the new line, select, similar to the last line — **Zone**. In the center — a little different. Here choose the same as in the left — **Zone**. In the rightmost field, select **Read**.
10. Next look at **Zone Resources**. Under this inscription there is a line with two fields. The left must have **Include** and the right must have **Specific Zone**. Once you select Specific Zone, another field appears on the right. Choose your domain in it.
11. Flick to the bottom and press the blue **Continue to Summary** button.
12. Check if you got everything right. A similar string must be present: *Domain — DNS:Edit, Zone:Read*.
13. Click on **Create Token**.
14. We copy the created token, and save it in a reliable place (preferably in the password manager).

View File

@ -0,0 +1,13 @@
### Как получить Cloudflare API Token
1. Переходим по [ссылке](https://dash.cloudflare.com/) и авторизуемся в ранее созданном аккаунте. https://dash.cloudflare.com/
В правом углу кликаем на иконку профиля (человечек в кружочке). Для мобильной версии сайта, в верхнем левом углу, нажимаем кнопку **Меню** (три горизонтальных полоски), в выпавшем меню, ищем пункт **My Profile**.
3. Нам предлагается на выбор, четыре категории настройки: **Preferences**, **Authentication**, **API Tokens**, **Sessions**. Выбираем **API Tokens**.
4. Самым первым пунктом видим кнопку **Create Token**. С полной уверенностью в себе и желанием обрести приватность, нажимаем на неё.
5. Спускаемся в самый низ и видим поле **Create Custom Token** и кнопку **Get Started** с правой стороны. Нажимаем.
6. В поле **Token Name** даём своему токену имя. Можете покреативить и отнестись к этому как к наименованию домашнего зверька :)
7. Далее, у нас **Permissions**. В первом поле выбираем Zone. Во втором поле, по центру, выбираем **DNS**. В последнем поле выбираем **Edit**.
8. Далее смотрим на **Zone Resources**. Под этой надписью есть строка с двумя полями. В первом должно быть **Include**, а во втором — **Specific Zone**. Как только Вы выберите **Specific Zone**, справа появится ещё одно поле. В нём выбираем наш домен.
9. Листаем в самый низ и нажимаем на синюю кнопку **Continue to Summary**.
10. Проверяем, всё ли мы правильно выбрали. Должна присутствовать подобная строка: ваш.домен — **DNS:Edit, Zone:Read**.
11. Нажимаем **Create Token**.
12. Копируем созданный токен, и сохраняем его в надёжном месте (желательно — в менеджере паролей).

View File

@ -1,3 +1,4 @@
### How to get Hetzner API Token
1. Visit the following [link](https://console.hetzner.cloud/) and sign 1. Visit the following [link](https://console.hetzner.cloud/) and sign
into newly created account. into newly created account.
2. Enter into previously created project. If you haven't created one, 2. Enter into previously created project. If you haven't created one,

View File

@ -127,6 +127,7 @@
"mail": { "mail": {
"title": "E-Mail", "title": "E-Mail",
"subtitle": "E-Mail for company and family.", "subtitle": "E-Mail for company and family.",
"login_info": "Use username and password from users tab. IMAP port is 143 with STARTTLS, SMTP port is 587 with STARTTLS.",
"bottom_sheet": { "bottom_sheet": {
"1": "To connect to the mailserver, please use {} domain alongside with username and password, that you created. Also feel free to invite", "1": "To connect to the mailserver, please use {} domain alongside with username and password, that you created. Also feel free to invite",
"2": "new users" "2": "new users"
@ -135,6 +136,7 @@
"messenger": { "messenger": {
"title": "Messenger", "title": "Messenger",
"subtitle": "Telegram or Signal not so private as Delta.Chat that uses your private server.", "subtitle": "Telegram or Signal not so private as Delta.Chat that uses your private server.",
"login_info": "Use the same username and password as for e-mail.",
"bottom_sheet": { "bottom_sheet": {
"1": "For connection, please use {} domain and credentials that you created." "1": "For connection, please use {} domain and credentials that you created."
} }
@ -142,6 +144,7 @@
"password_manager": { "password_manager": {
"title": "Password Manager", "title": "Password Manager",
"subtitle": "Base of your security. Bitwarden will help you to create, store and move passwords between devices, as well as input them, when requested using autocompletion.", "subtitle": "Base of your security. Bitwarden will help you to create, store and move passwords between devices, as well as input them, when requested using autocompletion.",
"login_info": "You will have to create an account on the website.",
"bottom_sheet": { "bottom_sheet": {
"1": "You can connect to the service and create a user via this link:" "1": "You can connect to the service and create a user via this link:"
} }
@ -149,6 +152,7 @@
"video": { "video": {
"title": "Videomeet", "title": "Videomeet",
"subtitle": "Zoom and Google Meet are good, but Jitsi Meet is a worth alternative that also gives you confidence that you're not being listened.", "subtitle": "Zoom and Google Meet are good, but Jitsi Meet is a worth alternative that also gives you confidence that you're not being listened.",
"login_info": "No account needed.",
"bottom_sheet": { "bottom_sheet": {
"1": "Using Jitsi as simple as just visiting this link:" "1": "Using Jitsi as simple as just visiting this link:"
} }
@ -156,6 +160,7 @@
"cloud": { "cloud": {
"title": "Cloud Storage", "title": "Cloud Storage",
"subtitle": "Do not allow cloud services to read your data by using NextCloud.", "subtitle": "Do not allow cloud services to read your data by using NextCloud.",
"login_info": "Login is admin, password is the same as with your main user. Create new accounts in Nextcloud interface.",
"bottom_sheet": { "bottom_sheet": {
"1": "You can connect and create a new user here:" "1": "You can connect and create a new user here:"
} }
@ -163,6 +168,7 @@
"social_network": { "social_network": {
"title": "Social Network", "title": "Social Network",
"subtitle": "It's hard to believe, but it became possible to create your own social network, with your own rules and target audience.", "subtitle": "It's hard to believe, but it became possible to create your own social network, with your own rules and target audience.",
"login_info": "You will have to create an account on the website.",
"bottom_sheet": { "bottom_sheet": {
"1": "You can connect and create new social user here:" "1": "You can connect and create new social user here:"
} }
@ -170,6 +176,7 @@
"git": { "git": {
"title": "Git Server", "title": "Git Server",
"subtitle": "Private alternative to the Github, that belongs to you, but not a Microsoft.", "subtitle": "Private alternative to the Github, that belongs to you, but not a Microsoft.",
"login_info": "You will have to create an account on the website. First user will become an admin.",
"bottom_sheet": { "bottom_sheet": {
"1": "You can connect and create a new user here:" "1": "You can connect and create a new user here:"
} }

View File

@ -128,6 +128,7 @@
"mail": { "mail": {
"title": "Почта", "title": "Почта",
"subtitle": "Электронная почта для семьи или компании.", "subtitle": "Электронная почта для семьи или компании.",
"login_info": "Используйте логин и пароль из вкладки пользователей. IMAP порт: 143, STARTTLS. SMTP порт: 587, STARTTLS.",
"bottom_sheet": { "bottom_sheet": {
"1": "Для подключения почтового ящика используйте {} и профиль, который Вы создали. Так же приглашайте", "1": "Для подключения почтового ящика используйте {} и профиль, который Вы создали. Так же приглашайте",
"2": "новых пользователей." "2": "новых пользователей."
@ -136,6 +137,7 @@
"messenger": { "messenger": {
"title": "Мессенджер", "title": "Мессенджер",
"subtitle": "Telegram и Signal не так приватны, как Delta.Chat — он использует Ваш личный сервер.", "subtitle": "Telegram и Signal не так приватны, как Delta.Chat — он использует Ваш личный сервер.",
"login_info": "Используйте те же логин и пароль, что и для почты.",
"bottom_sheet": { "bottom_sheet": {
"1": "Для подключения используйте {} и логин пароль, который Вы создали." "1": "Для подключения используйте {} и логин пароль, который Вы создали."
} }
@ -143,6 +145,7 @@
"password_manager": { "password_manager": {
"title": "Менеджер паролей", "title": "Менеджер паролей",
"subtitle": "Это фундамент Вашей безопасности. Создавать, хранить, копировать пароли между устройствами и вбивать их в формы поможет Bitwarden.", "subtitle": "Это фундамент Вашей безопасности. Создавать, хранить, копировать пароли между устройствами и вбивать их в формы поможет Bitwarden.",
"login_info": "Аккаунт нужно создать на сайте.",
"bottom_sheet": { "bottom_sheet": {
"1": "Подключиться к серверу и создать пользователя можно по адресу:." "1": "Подключиться к серверу и создать пользователя можно по адресу:."
} }
@ -150,6 +153,7 @@
"video": { "video": {
"title": "Видеоконференция", "title": "Видеоконференция",
"subtitle": "Jitsi meet — отличный аналог Zoom и Google meet который помимо удобства ещё и гарантирует Вам защищённые высококачественные видеоконференции.", "subtitle": "Jitsi meet — отличный аналог Zoom и Google meet который помимо удобства ещё и гарантирует Вам защищённые высококачественные видеоконференции.",
"login_info": "Аккаунт не требуется.",
"bottom_sheet": { "bottom_sheet": {
"1": "Для использования просто перейдите по ссылке:." "1": "Для использования просто перейдите по ссылке:."
} }
@ -157,6 +161,7 @@
"cloud": { "cloud": {
"title": "Файловое облако", "title": "Файловое облако",
"subtitle": "Не позволяйте облачным сервисам просматривать ваши данные. Используйте NextCloud — надёжный дом для всех Ваших данных.", "subtitle": "Не позволяйте облачным сервисам просматривать ваши данные. Используйте NextCloud — надёжный дом для всех Ваших данных.",
"login_info": "Логин администратора: admin, пароль такой же как у основного пользователя. Создавайте новых пользователей в интерфейсе администратора NextCloud.",
"bottom_sheet": { "bottom_sheet": {
"1": "Подключиться к серверу и создать пользователя можно по адресу:." "1": "Подключиться к серверу и создать пользователя можно по адресу:."
} }
@ -164,6 +169,7 @@
"social_network": { "social_network": {
"title": "Социальная сеть", "title": "Социальная сеть",
"subtitle": "Сложно поверить, но стало возможным создать свою собственную социальную сеть, со своими правилами и аудиторией.", "subtitle": "Сложно поверить, но стало возможным создать свою собственную социальную сеть, со своими правилами и аудиторией.",
"login_info": "Аккаунт нужно создать на сайте.",
"bottom_sheet": { "bottom_sheet": {
"1": "Подключиться к серверу и создать пользователя можно по адресу:." "1": "Подключиться к серверу и создать пользователя можно по адресу:."
} }
@ -171,6 +177,7 @@
"git": { "git": {
"title": "Git-сервер", "title": "Git-сервер",
"subtitle": "Приватная альтернатива Github, которая принадлежит вам, а не Microsoft.", "subtitle": "Приватная альтернатива Github, которая принадлежит вам, а не Microsoft.",
"login_info": "Аккаунт нужно создать на сайте. Первый зарегистрированный пользователь становится администратором.",
"bottom_sheet": { "bottom_sheet": {
"1": "Подключиться к серверу и создать пользователя можно по адресу:." "1": "Подключиться к серверу и создать пользователя можно по адресу:."
} }

View File

@ -69,6 +69,46 @@ extension ServiceTypesExt on ServiceTypes {
} }
} }
String get loginInfo {
switch (this) {
case ServiceTypes.mail:
return 'services.mail.login_info'.tr();
case ServiceTypes.messenger:
return 'services.messenger.login_info'.tr();
case ServiceTypes.passwordManager:
return 'services.password_manager.login_info'.tr();
case ServiceTypes.video:
return 'services.video.login_info'.tr();
case ServiceTypes.cloud:
return 'services.cloud.login_info'.tr();
case ServiceTypes.socialNetwork:
return 'services.social_network.login_info'.tr();
case ServiceTypes.git:
return 'services.git.login_info'.tr();
case ServiceTypes.vpn:
return '';
}
}
String get subdomain {
switch (this) {
case ServiceTypes.passwordManager:
return 'password';
case ServiceTypes.video:
return 'meet';
case ServiceTypes.cloud:
return 'cloud';
case ServiceTypes.socialNetwork:
return 'social';
case ServiceTypes.git:
return 'git';
case ServiceTypes.vpn:
case ServiceTypes.messenger:
default:
return '';
}
}
IconData get icon { IconData get icon {
switch (this) { switch (this) {
case ServiceTypes.mail: case ServiceTypes.mail:

View File

@ -6,6 +6,7 @@ import 'package:selfprivacy/logic/models/backblaze_bucket.dart';
import 'package:selfprivacy/logic/models/backup.dart'; import 'package:selfprivacy/logic/models/backup.dart';
import 'package:selfprivacy/logic/api_maps/server.dart'; import 'package:selfprivacy/logic/api_maps/server.dart';
import 'package:selfprivacy/logic/api_maps/backblaze.dart'; import 'package:selfprivacy/logic/api_maps/backblaze.dart';
import 'package:easy_localization/easy_localization.dart';
part 'backups_state.dart'; part 'backups_state.dart';
@ -151,7 +152,8 @@ class BackupsCubit extends AppConfigDependendCubit<BackupsState> {
Future<void> forceUpdateBackups() async { Future<void> forceUpdateBackups() async {
emit(state.copyWith(preventActions: true)); emit(state.copyWith(preventActions: true));
await api.forceBackupListReload(); await api.forceBackupListReload();
getIt<NavigationService>().showSnackBar('providers.backup.refetchingList'); getIt<NavigationService>()
.showSnackBar('providers.backup.refetchingList'.tr());
emit(state.copyWith(preventActions: false)); emit(state.copyWith(preventActions: false));
} }

View File

@ -137,7 +137,8 @@ class InitializingPage extends StatelessWidget {
), ),
SizedBox(height: 10), SizedBox(height: 10),
BrandButton.text( BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()), onPressed: () =>
_showModal(context, _HowTo(fileName: 'how_hetzner')),
title: 'initializing.how'.tr(), title: 'initializing.how'.tr(),
), ),
], ],
@ -192,7 +193,11 @@ class InitializingPage extends StatelessWidget {
), ),
SizedBox(height: 10), SizedBox(height: 10),
BrandButton.text( BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()), onPressed: () => _showModal(
context,
_HowTo(
fileName: 'how_cloudflare',
)),
title: 'initializing.how'.tr(), title: 'initializing.how'.tr(),
), ),
], ],
@ -243,7 +248,11 @@ class InitializingPage extends StatelessWidget {
), ),
SizedBox(height: 10), SizedBox(height: 10),
BrandButton.text( BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()), onPressed: () => _showModal(
context,
_HowTo(
fileName: 'how_backblaze',
)),
title: 'initializing.how'.tr(), title: 'initializing.how'.tr(),
), ),
], ],
@ -336,11 +345,6 @@ class InitializingPage extends StatelessWidget {
], ],
SizedBox(height: 10), SizedBox(height: 10),
Spacer(), Spacer(),
SizedBox(height: 10),
BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()),
title: 'initializing.how'.tr(),
),
], ],
); );
}), }),
@ -403,11 +407,6 @@ class InitializingPage extends StatelessWidget {
: () => context.read<RootUserFormCubit>().trySubmit(), : () => context.read<RootUserFormCubit>().trySubmit(),
text: 'basis.connect'.tr(), text: 'basis.connect'.tr(),
), ),
SizedBox(height: 10),
BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()),
title: 'initializing.how'.tr(),
),
], ],
); );
}), }),
@ -431,11 +430,6 @@ class InitializingPage extends StatelessWidget {
: () => appConfigCubit.createServerAndSetDnsRecords(), : () => appConfigCubit.createServerAndSetDnsRecords(),
text: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(), text: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(),
), ),
Spacer(flex: 2),
BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()),
title: 'initializing.what'.tr(),
),
], ],
); );
}); });
@ -482,13 +476,6 @@ class InitializingPage extends StatelessWidget {
], ],
), ),
if (state.isLoading) BrandText.body2('initializing.17'.tr()), if (state.isLoading) BrandText.body2('initializing.17'.tr()),
Spacer(
flex: 2,
),
BrandButton.text(
onPressed: () => _showModal(context, _HowHetzner()),
title: 'initializing.what'.tr(),
),
], ],
); );
}); });
@ -503,11 +490,14 @@ class InitializingPage extends StatelessWidget {
} }
} }
class _HowHetzner extends StatelessWidget { class _HowTo extends StatelessWidget {
const _HowHetzner({ const _HowTo({
Key? key, Key? key,
required this.fileName,
}) : super(key: key); }) : super(key: key);
final String fileName;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BrandBottomSheet( return BrandBottomSheet(
@ -515,7 +505,7 @@ class _HowHetzner extends StatelessWidget {
child: Padding( child: Padding(
padding: paddingH15V0, padding: paddingH15V0,
child: BrandMarkdown( child: BrandMarkdown(
fileName: 'how_hetzner', fileName: fileName,
), ),
), ),
); );

View File

@ -38,6 +38,23 @@ class ServicesPage extends StatefulWidget {
_ServicesPageState createState() => _ServicesPageState(); _ServicesPageState createState() => _ServicesPageState();
} }
void _launchURL(url) async {
var _possible = await canLaunch(url);
if (_possible) {
try {
await launch(
url,
enableJavaScript: true,
);
} catch (e) {
print(e);
}
} else {
throw 'Could not launch $url';
}
}
class _ServicesPageState extends State<ServicesPage> { class _ServicesPageState extends State<ServicesPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -94,6 +111,9 @@ class _Card extends StatelessWidget {
(!switchableServices.contains(serviceType) || (!switchableServices.contains(serviceType) ||
serviceState.isEnableByType(serviceType)); serviceState.isEnableByType(serviceType));
var config = context.watch<AppConfigCubit>().state;
var domainName = UiHelpers.getDomainName(config);
return GestureDetector( return GestureDetector(
onTap: isSwithOn onTap: isSwithOn
? () => showDialog<void>( ? () => showDialog<void>(
@ -163,6 +183,30 @@ class _Card extends StatelessWidget {
SizedBox(height: 10), SizedBox(height: 10),
BrandText.h2(serviceType.title), BrandText.h2(serviceType.title),
SizedBox(height: 10), SizedBox(height: 10),
if (serviceType.subdomain != '')
Column(
children: [
GestureDetector(
onTap: () => _launchURL(
'https://${serviceType.subdomain}.$domainName'),
child: Text(
'${serviceType.subdomain}.$domainName',
style: linkStyle,
),
),
SizedBox(height: 10),
],
),
if (serviceType == ServiceTypes.mail)
Column(children: [
Text(
domainName,
style: linkStyle,
),
SizedBox(height: 10),
]),
BrandText.body2(serviceType.loginInfo),
SizedBox(height: 10),
BrandText.body2(serviceType.subtitle), BrandText.body2(serviceType.subtitle),
SizedBox(height: 10), SizedBox(height: 10),
], ],
@ -438,21 +482,4 @@ class _ServiceDetails extends StatelessWidget {
), ),
); );
} }
void _launchURL(url) async {
var _possible = await canLaunch(url);
if (_possible) {
try {
await launch(
url,
enableJavaScript: true,
);
} catch (e) {
print(e);
}
} else {
throw 'Could not launch $url';
}
}
} }

View File

@ -75,9 +75,8 @@ class _UserDetails extends StatelessWidget {
), ),
), ),
onPressed: () { onPressed: () {
context context.read<JobsCubit>().addJob(
.read<JobsCubit>() DeleteUserJob(user: user));
.addJob(DeleteUserJob(user: user));
Navigator.of(context) Navigator.of(context)
..pop() ..pop()
..pop(); ..pop();