mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2024-11-05 00:13:12 +00:00
Add more instructions to UI
This commit is contained in:
parent
4ca873e794
commit
85a27e8ee2
6
assets/markdown/how_backblaze-en.md
Normal file
6
assets/markdown/how_backblaze-en.md
Normal 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.
|
6
assets/markdown/how_backblaze-ru.md
Normal file
6
assets/markdown/how_backblaze-ru.md
Normal 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_ в надёжном месте. Например в менеджере паролей.
|
15
assets/markdown/how_cloudflare-en.md
Normal file
15
assets/markdown/how_cloudflare-en.md
Normal 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).
|
13
assets/markdown/how_cloudflare-ru.md
Normal file
13
assets/markdown/how_cloudflare-ru.md
Normal 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. Копируем созданный токен, и сохраняем его в надёжном месте (желательно — в менеджере паролей).
|
|
@ -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,
|
||||||
|
|
|
@ -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:"
|
||||||
}
|
}
|
||||||
|
|
|
@ -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": "Подключиться к серверу и создать пользователя можно по адресу:."
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -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';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue