diff --git a/.gitignore b/.gitignore
index 9d532b18..6317d647 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,7 +18,7 @@
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
-#.vscode/
+.vscode/
# Flutter/Dart/Pub related
**/doc/api/
diff --git a/.vscode/launch.json b/.vscode/launch.json
deleted file mode 100644
index 201d6fc1..00000000
--- a/.vscode/launch.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- // Use IntelliSense to learn about possible attributes.
- // Hover to view descriptions of existing attributes.
- // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
- "version": "0.2.0",
- "configurations": [
- {
- "name": "selfprivacy",
- "request": "launch",
- "type": "dart"
- }
- ]
-}
\ No newline at end of file
diff --git a/assets/fonts/BrandIcons.ttf b/assets/fonts/BrandIcons.ttf
index bf40d009..4d4e0f28 100644
Binary files a/assets/fonts/BrandIcons.ttf and b/assets/fonts/BrandIcons.ttf differ
diff --git a/assets/fonts/Inter-Bold.ttf b/assets/fonts/Inter-Bold.ttf
new file mode 100644
index 00000000..e98b84ce
Binary files /dev/null and b/assets/fonts/Inter-Bold.ttf differ
diff --git a/assets/fonts/Inter-ExtraBold.ttf b/assets/fonts/Inter-ExtraBold.ttf
new file mode 100644
index 00000000..7f16a0f0
Binary files /dev/null and b/assets/fonts/Inter-ExtraBold.ttf differ
diff --git a/assets/fonts/Inter-Medium.ttf b/assets/fonts/Inter-Medium.ttf
new file mode 100644
index 00000000..721147d8
Binary files /dev/null and b/assets/fonts/Inter-Medium.ttf differ
diff --git a/assets/fonts/Inter-Regular.ttf b/assets/fonts/Inter-Regular.ttf
new file mode 100644
index 00000000..96fd6a12
Binary files /dev/null and b/assets/fonts/Inter-Regular.ttf differ
diff --git a/assets/fonts/Inter-SemiBold.ttf b/assets/fonts/Inter-SemiBold.ttf
new file mode 100644
index 00000000..ddb27929
Binary files /dev/null and b/assets/fonts/Inter-SemiBold.ttf differ
diff --git a/assets/images/onboarding/logos_line-dark.png b/assets/images/onboarding/logos_line-dark.png
index 772aff40..e651ad05 100644
Binary files a/assets/images/onboarding/logos_line-dark.png and b/assets/images/onboarding/logos_line-dark.png differ
diff --git a/assets/images/onboarding/logos_line-light.png b/assets/images/onboarding/logos_line-light.png
index eb8ecf82..0390a08c 100644
Binary files a/assets/images/onboarding/logos_line-light.png and b/assets/images/onboarding/logos_line-light.png differ
diff --git a/assets/images/onboarding/onboarding1-dark.png b/assets/images/onboarding/onboarding1-dark.png
index 0244d43b..c5871dd7 100644
Binary files a/assets/images/onboarding/onboarding1-dark.png and b/assets/images/onboarding/onboarding1-dark.png differ
diff --git a/assets/images/onboarding/onboarding1-light.png b/assets/images/onboarding/onboarding1-light.png
index 50312094..0d361d41 100644
Binary files a/assets/images/onboarding/onboarding1-light.png and b/assets/images/onboarding/onboarding1-light.png differ
diff --git a/assets/images/onboarding/onboarding2-dark.png b/assets/images/onboarding/onboarding2-dark.png
index e623015a..adfb94ff 100644
Binary files a/assets/images/onboarding/onboarding2-dark.png and b/assets/images/onboarding/onboarding2-dark.png differ
diff --git a/assets/images/onboarding/onboarding2-light.png b/assets/images/onboarding/onboarding2-light.png
index 5786558c..480a54ad 100644
Binary files a/assets/images/onboarding/onboarding2-light.png and b/assets/images/onboarding/onboarding2-light.png differ
diff --git a/assets/markdown/about-en.md b/assets/markdown/about-en.md
new file mode 100644
index 00000000..3ee32766
--- /dev/null
+++ b/assets/markdown/about-en.md
@@ -0,0 +1,12 @@
+### О проекте
+
+Всё больше организаций хотят владеть нашими данными
+А мы сами хотим распоряжаться своими **данными** на своем сервере.
+
+### Миссия проекта
+
+Цифровая независимость и приватность доступная каждому
+
+### Цель
+
+Развивать программу, которая позволит каждому создавать приватные сервисы для себя и своих близких
\ No newline at end of file
diff --git a/assets/markdown/about-ru.md b/assets/markdown/about-ru.md
new file mode 100644
index 00000000..3ee32766
--- /dev/null
+++ b/assets/markdown/about-ru.md
@@ -0,0 +1,12 @@
+### О проекте
+
+Всё больше организаций хотят владеть нашими данными
+А мы сами хотим распоряжаться своими **данными** на своем сервере.
+
+### Миссия проекта
+
+Цифровая независимость и приватность доступная каждому
+
+### Цель
+
+Развивать программу, которая позволит каждому создавать приватные сервисы для себя и своих близких
\ No newline at end of file
diff --git a/assets/markdown/how_hetzner-en.md b/assets/markdown/how_hetzner-en.md
new file mode 100644
index 00000000..4c0c344b
--- /dev/null
+++ b/assets/markdown/how_hetzner-en.md
@@ -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, даём нашему токену название (это может быть любое название, которые вам нравиться. Сути оно не меняет.
\ No newline at end of file
diff --git a/assets/markdown/how_hetzner-ru.md b/assets/markdown/how_hetzner-ru.md
new file mode 100644
index 00000000..4c0c344b
--- /dev/null
+++ b/assets/markdown/how_hetzner-ru.md
@@ -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, даём нашему токену название (это может быть любое название, которые вам нравиться. Сути оно не меняет.
\ No newline at end of file
diff --git a/assets/translations/en.json b/assets/translations/en.json
index 709704c4..c8562456 100644
--- a/assets/translations/en.json
+++ b/assets/translations/en.json
@@ -1,3 +1,171 @@
{
- "test": "en-test"
+ "test": "en-test",
+ "locale": "en",
+ "basis": {
+ "_comment": "Basic interface elements",
+ "providers": "Providers",
+ "services": "Services",
+ "users": "Users",
+ "more": "More",
+ "next": "Next",
+ "got_it": "Got it",
+ "settings": "Settings",
+ "password": "Password",
+ "create": "Add new",
+ "confirmation": "Confirmation",
+ "cancel": "Cancel",
+ "delete": "Delete",
+ "close": "Close",
+ "connect": "Connect",
+ "domain": "Domain",
+ "saving": "Saving..",
+ "nickname": "nickname",
+ "loading": "loading"
+ },
+ "more": {
+ "_comment": "'More' tab",
+ "configuration_wizard": "Setup wizard",
+ "settings": "Application settings",
+ "about_project": "About us",
+ "about_app": "About application",
+ "onboarding": "Onboarding",
+ "console": "Console",
+ "about_app_page": {
+ "text": "Тут любая служебная информация, v.{}"
+ }
+ },
+ "onboarding": {
+ "_comment": "Onboarding pages",
+ "page1_title": "Digital independence, available to all of us",
+ "page1_text": "Mail, VPN, Messenger, social network and much more on your private server, under your control.",
+ "page2_title": "SelfPrivacy — it's not a cloud, but your personal datacenter",
+ "page2_text": "SelfPrivacy works only with your provider accounts: Hetzner, Cloudflare, Backblaze. If you do not own those, we'll help you to create them"
+ },
+ "providers": {
+ "_comment": "'Providers' tab",
+ "page_title": "Your Data Center",
+ "server": {
+ "card_title": "Server",
+ "bottom_sheet": {
+ "1": "It's a virtual computer, where all your services live.",
+ "2": "1 CPU, RAM 4Gb, 40Gb — $5 per month",
+ "3": "Status — Good"
+ }
+ },
+ "domain": {
+ "card_title": "Domain",
+ "bottom_sheet": {
+ "1": "It's your personal internet address that will point to the server and other services of yours.",
+ "2": "{} — expires on {}",
+ "3": "Status — Good"
+ }
+ },
+ "backup": {
+ "card_title": "Backup",
+ "bottom_sheet": {
+ "1": "Will save your day in case of incident: hackers attack, server deletion, etc.",
+ "2": "3Gb/10Gb, last backup was yesterday {}",
+ "3": "Status — Good"
+ }
+ }
+ },
+ "not_ready_card": {
+ "_comment": "Card shown when user skips initial setup",
+ "1": "Please finish application setup using ",
+ "2": "@:more.configuration_wizard",
+ "3": " for further work"
+ },
+ "services": {
+ "_comment": "Вкладка сервисы",
+ "title": "Your personal, private and independent services.",
+ "mail": {
+ "title": "E-Mail",
+ "subtitle": "E-Mail for company and family.",
+ "bottom_sheet": {
+ "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"
+ }
+ },
+ "messenger": {
+ "title": "Messenger",
+ "subtitle": "Telegram or Signal not so private as Delta.Chat that uses your private server.",
+ "bottom_sheet": {
+ "1": "For connection, please use {} domain and credentials that you created."
+ }
+ },
+ "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.",
+ "bottom_sheet": {
+ "1": "You can connect to the service and create a user via this link:"
+ }
+ },
+ "video": {
+ "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.",
+ "bottom_sheet": {
+ "1": "Using Jitsi as simple as just visiting this link:"
+ }
+ },
+ "cloud": {
+ "title": "Cloud Storage",
+ "subtitle": "Do not allow cloud services to read your data by using NextCloud.",
+ "bottom_sheet": {
+ "1": "You can connect and create a new user here:"
+ }
+ },
+ "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.",
+ "bottom_sheet": {
+ "1": "You can connect and create new social user here:"
+ }
+ },
+ "git": {
+ "title": "Git-server",
+ "subtitle": "Private alternative to the Github, that belongs to you, but not a Microsoft.",
+ "bottom_sheet": {
+ "1": "You can connect and create a new user here:"
+ }
+ }
+ },
+ "users": {
+ "_comment": "'Users' tab",
+ "add_new_user": "Добавьте первого пользователя",
+ "new_user": "Новый пользователь",
+ "not_ready": "Подключите сервер, домен и DNS в разделу Провайдеры, чтобы добавить первого пользователя",
+ "nobody_here": "'Здесь пока никого'",
+ "login": "Логин",
+ "onboarding": "Onboarding",
+ "console": "Console",
+ "new_user_info_note": "Новый пользователь автоматически получит доступ ко всем сервисам. Ещё какое-то описание.",
+ "delete_confirm_question": "удалить учетную запись?",
+ "reset_password": "Сбросить пароль",
+ "account": "Учетная запись",
+ "send_regisration_data": "Отправить реквизиты для входа"
+ },
+ "initializing": {
+ "_comment": "initializing page",
+ "1": "Подключите сервер Hetzner",
+ "2": "Здесь будут жить наши данные и SelfPrivacy-сервисы",
+ "how": "Как получить API Token",
+ "3": "'Подключите CloudFlare'",
+ "4": "Для управления DNS вашего домена",
+ "5": "CloudFlare API Token",
+ "6": "Подключите облачное хранилище Backblaze",
+ "7": "На данный момент подлюченных доменов нет",
+ "8": "Загружаем список доменов",
+ "9": "Найдено больше одного домена, для вашей безопастности, просим вам удалить не нужные домены",
+ "10": "Сохранить домен",
+ "11": "Создать сервер",
+ "what": "Что это значит?",
+ "13": "Сервер презагружен, ждем последнюю проверку",
+ "14": "Cервер запушен, сейчас он будет проверен и перезагружен",
+ "15": "Cервер создан, идет проверка ДНС адресов и запуск сервера",
+ "16": "До следующей проверки: ",
+ "17": "Проверка",
+ "18": "Как получить Hetzner API Token'",
+ "19": "1 Переходим по ссылке ",
+ "20": "\n"
+ }
}
\ No newline at end of file
diff --git a/assets/translations/ru.json b/assets/translations/ru.json
index 05f81893..d3b19c1b 100644
--- a/assets/translations/ru.json
+++ b/assets/translations/ru.json
@@ -1,3 +1,171 @@
{
- "test": "ру-тест"
+ "test": "ru-test",
+ "locale": "ru",
+ "basis": {
+ "_comment": "базовые элементы интерфейса",
+ "providers": "Провайдеры",
+ "services": "Сервисы",
+ "users": "Пользователи",
+ "more": "Еще",
+ "next": "Далее",
+ "got_it": "Понял",
+ "settings": "Настройки",
+ "password": "Пароль",
+ "create": "Создать",
+ "confirmation": "Подтверждение",
+ "cancel": "Отменить",
+ "delete": "Удалить",
+ "close": "Закрыть",
+ "connect": "Подключить",
+ "domain": "Домен",
+ "saving": "Сохранение..",
+ "nickname": "Никнейм",
+ "loading": "Загрузка"
+ },
+ "more": {
+ "_comment": "вкладка еще",
+ "configuration_wizard": "Мастер Подключения",
+ "settings": "Настройки приложения",
+ "about_project": "О проекте SelfPrivacy",
+ "about_app": "О приложении",
+ "onboarding": "Onboarding",
+ "console": "Console",
+ "about_app_page": {
+ "text": "Тут любая служебная информация, v.{}"
+ }
+ },
+ "onboarding": {
+ "_comment": "страницы онбординга",
+ "page1_title": "Цифровая независимость доступна каждому",
+ "page1_text": "Почта, VPN, Мессенджер, социальная сеть и многое другое на вашем личном сервере, под вашим полным контролем.",
+ "page2_title": "SelfPrivacy — это не облако, а ваш личный дата-центр",
+ "page2_text": "У SelfPrivacy работает только с вашими сервис-провадерами: Hetzner, Cloudflare, Backblaze. Если у вас нет учетных записей, мы поможем их создать."
+ },
+ "providers": {
+ "_comment": "вкладка провайдеры",
+ "page_title": "Ваш Дата-центр",
+ "server": {
+ "card_title": "Сервер",
+ "bottom_sheet": {
+ "1": "Это виртульный компьютер на котором работают все ваши сервисы.",
+ "2": "1 CPU, RAM 4Gb, 40Gb — $5 в месяц",
+ "3": "Статус — в норме"
+ }
+ },
+ "domain": {
+ "card_title": "Домен",
+ "bottom_sheet": {
+ "1": "Это ваш личный адрес в интернете, который будет указывать на сервер и другие ваши сервисы.",
+ "2": "{} — продлен до {}",
+ "3": "Статус — в норме"
+ }
+ },
+ "backup": {
+ "card_title": "Резервное копирование",
+ "bottom_sheet": {
+ "1": "Выручит в любой ситуации: хакерская атака, удаление сервера и т.п.",
+ "2": "3Gb — бестплатно до 10Gb, последний вчера в {}",
+ "3": "Статус — в норме"
+ }
+ }
+ },
+ "not_ready_card": {
+ "_comment": "Карточка показывающая когда человек скипнул настройку, на карте текст из 3 блоков, средний содержит ссыку на мастер подключения",
+ "1": "Завершите настройку приложения используя ",
+ "2": "@:more.configuration_wizard",
+ "3": " для продолжения работы"
+ },
+ "services": {
+ "_comment": "Вкладка сервисы",
+ "title": "Ваши личные приватные и независимые сервисы",
+ "mail": {
+ "title": "Почта",
+ "subtitle": "Электронная почта для семьи или компании",
+ "bottom_sheet": {
+ "1": "Для подключения почтового ящика используйте {} и логин пароль, который вы создали. Так же приглашайте",
+ "2": "новых пользователей"
+ }
+ },
+ "messenger": {
+ "title": "Мессенджер",
+ "subtitle": "Telegram и Signal не так приватны, как Delta.Chat использующий ваш личный сервер.",
+ "bottom_sheet": {
+ "1": "Для подключения используйте {} и логин пароль, который вы создали"
+ }
+ },
+ "password_manager": {
+ "title": "Менеджер паролей",
+ "subtitle": "Фундамент безопасности. Создавать, хранить, копировать пароли между устройствами, вбивать их в формы поможет — Bitwarden.",
+ "bottom_sheet": {
+ "1": "Подключиться к серверу и создать пользователя можно по адресу:"
+ }
+ },
+ "video": {
+ "title": "Видеоконференция",
+ "subtitle": "Zoom и Google meet отличные инструменты, но Jitsi meet не хуже и дает уверенность, что вас никто не подслушивает.",
+ "bottom_sheet": {
+ "1": "Для использования просто перейдите по ссылке:"
+ }
+ },
+ "cloud": {
+ "title": "Файловое облако",
+ "subtitle": "Не позволяйте облачным сервисам читать ваши данные используйте NextCloud.",
+ "bottom_sheet": {
+ "1": "Подключиться к серверу и создать пользователя можно по адресу:"
+ }
+ },
+ "social_network": {
+ "title": "Социальная сеть",
+ "subtitle": "Сложно поверить, но стало возможным создать свою собственную социальную сеть, со своими правилами и аудиторией.",
+ "bottom_sheet": {
+ "1": "Подключиться к серверу и создать пользователя можно по адресу:"
+ }
+ },
+ "git": {
+ "title": "Git-сервер",
+ "subtitle": "Приватная альтернатива Github, которая принадлежит вам, а не Microsoft.",
+ "bottom_sheet": {
+ "1": "Подключиться к серверу и создать пользователя можно по адресу:"
+ }
+ }
+ },
+ "users": {
+ "_comment": "'Users' tab",
+ "add_new_user": "Добавьте первого пользователя",
+ "new_user": "Новый пользователь",
+ "not_ready": "Подключите сервер, домен и DNS в разделу Провайдеры, чтобы добавить первого пользователя",
+ "nobody_here": "'Здесь пока никого'",
+ "login": "Логин",
+ "onboarding": "Onboarding",
+ "console": "Console",
+ "new_user_info_note": "Новый пользователь автоматически получит доступ ко всем сервисам. Ещё какое-то описание.",
+ "delete_confirm_question": "удалить учетную запись?",
+ "reset_password": "Сбросить пароль",
+ "account": "Учетная запись",
+ "send_regisration_data": "Отправить реквизиты для входа"
+ },
+ "initializing": {
+ "_comment": "initializing page",
+ "1": "Подключите сервер Hetzner",
+ "2": "Здесь будут жить наши данные и SelfPrivacy-сервисы",
+ "how": "Как получить API Token",
+ "3": "'Подключите CloudFlare'",
+ "4": "Для управления DNS вашего домена",
+ "5": "CloudFlare API Token",
+ "6": "Подключите облачное хранилище Backblaze",
+ "7": "На данный момент подлюченных доменов нет",
+ "8": "Загружаем список доменов",
+ "9": "Найдено больше одного домена, для вашей безопастности, просим вам удалить не нужные домены",
+ "10": "Сохранить домен",
+ "11": "Создать сервер",
+ "what": "Что это значит?",
+ "13": "Сервер презагружен, ждем последнюю проверку",
+ "14": "Cервер запушен, сейчас он будет проверен и перезагружен",
+ "15": "Cервер создан, идет проверка ДНС адресов и запуск сервера",
+ "16": "До следующей проверки: ",
+ "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, даём нашему токену название (это может быть любое название, которые вам нравиться. Сути оно не меняет."
+ }
}
\ No newline at end of file
diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt
new file mode 100644
index 00000000..f317508c
--- /dev/null
+++ b/fastlane/metadata/android/en-US/full_description.txt
@@ -0,0 +1,16 @@
+SelfPrivacy - is a platform on your cloud hosting, that allows to deploy your own private services and control them using mobile application.
+To use this application, you'll be required to create accounts of different service providers. Please reffer to this manual: https://hugo.selfprivacy.org/posts/getting_started
+Application will do the following things for you:
+1. Create your personal server
+2. Setup NixOS
+3. Bring all services to the ready-to-use state. Services include:
+* E-mail, ready to use with DeltaChat
+* NextCloud - your personal cloud storage
+* Bitwarden - secure and private password manager
+* Pleroma - your private fediverse space for blogging
+* Jitsi — awesome Zoom alternative
+* Gitea - your own Git server
+* OpenConnect - Personal VPN server
+
+!!! Project is currently in alpha state. Feel free to try it. It would be much appreciated if you would provide us with some feedback.
+!!! Only Russian localization is currently available. English is coming soon
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png
new file mode 100644
index 00000000..7b06195e
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/1.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png
new file mode 100644
index 00000000..351cf4e5
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/2.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png
new file mode 100644
index 00000000..bcdbf2e9
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/3.png differ
diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png
new file mode 100644
index 00000000..0526ab1b
Binary files /dev/null and b/fastlane/metadata/android/en-US/images/phoneScreenshots/4.png differ
diff --git a/fastlane/metadata/android/en-US/short_description.txt b/fastlane/metadata/android/en-US/short_description.txt
new file mode 100644
index 00000000..18bbf5ab
--- /dev/null
+++ b/fastlane/metadata/android/en-US/short_description.txt
@@ -0,0 +1 @@
+Self-hosted services without pain
diff --git a/fastlane/metadata/android/en-US/title.txt b/fastlane/metadata/android/en-US/title.txt
new file mode 100644
index 00000000..adc138c5
--- /dev/null
+++ b/fastlane/metadata/android/en-US/title.txt
@@ -0,0 +1 @@
+SelfPrivacy
diff --git a/fastlane/metadata/android/en-US/video.txt b/fastlane/metadata/android/en-US/video.txt
new file mode 100644
index 00000000..91abd7c0
--- /dev/null
+++ b/fastlane/metadata/android/en-US/video.txt
@@ -0,0 +1 @@
+https://fdroid.selfprivacy.org/SFPresentation.mp4
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index 075d04f6..40f32d30 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -39,13 +39,13 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/wakelock/ios"
SPEC CHECKSUMS:
- Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
+ Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
- wakelock: bfc7955c418d0db797614075aabbc58a39ab5107
+ wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
index 1d526a16..919434a6 100644
--- a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
+++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -2,6 +2,6 @@
+ location = "self:">
diff --git a/ios/build/XCBuildData/e199fc491e5bb495a66f74a37ab3662f-desc.xcbuild b/ios/build/XCBuildData/96ca1c4c467384d05ed244fd468486cb-desc.xcbuild
similarity index 99%
rename from ios/build/XCBuildData/e199fc491e5bb495a66f74a37ab3662f-desc.xcbuild
rename to ios/build/XCBuildData/96ca1c4c467384d05ed244fd468486cb-desc.xcbuild
index f7a6342b..8970bb55 100644
Binary files a/ios/build/XCBuildData/e199fc491e5bb495a66f74a37ab3662f-desc.xcbuild and b/ios/build/XCBuildData/96ca1c4c467384d05ed244fd468486cb-desc.xcbuild differ
diff --git a/ios/build/XCBuildData/e199fc491e5bb495a66f74a37ab3662f-manifest.xcbuild b/ios/build/XCBuildData/96ca1c4c467384d05ed244fd468486cb-manifest.xcbuild
similarity index 100%
rename from ios/build/XCBuildData/e199fc491e5bb495a66f74a37ab3662f-manifest.xcbuild
rename to ios/build/XCBuildData/96ca1c4c467384d05ed244fd468486cb-manifest.xcbuild
diff --git a/ios/build/XCBuildData/BuildDescriptionCacheIndex-8d11405da631cc0b123a3a1283c8088a b/ios/build/XCBuildData/BuildDescriptionCacheIndex-8d11405da631cc0b123a3a1283c8088a
index 4fe175ba..ef6b5410 100644
Binary files a/ios/build/XCBuildData/BuildDescriptionCacheIndex-8d11405da631cc0b123a3a1283c8088a and b/ios/build/XCBuildData/BuildDescriptionCacheIndex-8d11405da631cc0b123a3a1283c8088a differ
diff --git a/ios/build/XCBuildData/94e4d8c67912337ee212f892ab2b8faa-desc.xcbuild b/ios/build/XCBuildData/bc25e7b85ed10bc8d71fbc6f28d8094e-desc.xcbuild
similarity index 99%
rename from ios/build/XCBuildData/94e4d8c67912337ee212f892ab2b8faa-desc.xcbuild
rename to ios/build/XCBuildData/bc25e7b85ed10bc8d71fbc6f28d8094e-desc.xcbuild
index eb9cc275..6a7bab59 100644
Binary files a/ios/build/XCBuildData/94e4d8c67912337ee212f892ab2b8faa-desc.xcbuild and b/ios/build/XCBuildData/bc25e7b85ed10bc8d71fbc6f28d8094e-desc.xcbuild differ
diff --git a/ios/build/XCBuildData/94e4d8c67912337ee212f892ab2b8faa-manifest.xcbuild b/ios/build/XCBuildData/bc25e7b85ed10bc8d71fbc6f28d8094e-manifest.xcbuild
similarity index 100%
rename from ios/build/XCBuildData/94e4d8c67912337ee212f892ab2b8faa-manifest.xcbuild
rename to ios/build/XCBuildData/bc25e7b85ed10bc8d71fbc6f28d8094e-manifest.xcbuild
diff --git a/ios/build/XCBuildData/build.db b/ios/build/XCBuildData/build.db
index 8ed42a0f..8369c8fd 100644
Binary files a/ios/build/XCBuildData/build.db and b/ios/build/XCBuildData/build.db differ
diff --git a/lib/config/bloc_config.dart b/lib/config/bloc_config.dart
index 97ca6866..af289892 100644
--- a/lib/config/bloc_config.dart
+++ b/lib/config/bloc_config.dart
@@ -3,13 +3,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/logic/cubit/app_settings/app_settings_cubit.dart';
import 'package:selfprivacy/logic/cubit/app_config/app_config_cubit.dart';
import 'package:selfprivacy/logic/cubit/providers/providers_cubit.dart';
-import 'package:selfprivacy/logic/cubit/services/services_cubit.dart';
import 'package:selfprivacy/logic/cubit/users/users_cubit.dart';
class BlocAndProviderConfig extends StatelessWidget {
- const BlocAndProviderConfig({Key key, this.child}) : super(key: key);
+ const BlocAndProviderConfig({Key? key, this.child}) : super(key: key);
- final Widget child;
+ final Widget? child;
@override
Widget build(BuildContext context) {
@@ -30,7 +29,6 @@ class BlocAndProviderConfig extends StatelessWidget {
lazy: false,
create: (_) => AppConfigCubit()..load(),
),
- BlocProvider(create: (_) => ServicesCubit()),
BlocProvider(create: (_) => ProvidersCubit()),
BlocProvider(create: (_) => UsersCubit()),
],
diff --git a/lib/config/bloc_observer.dart b/lib/config/bloc_observer.dart
index f19a42af..526ee863 100644
--- a/lib/config/bloc_observer.dart
+++ b/lib/config/bloc_observer.dart
@@ -2,14 +2,14 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:selfprivacy/ui/components/error/error.dart';
import 'package:selfprivacy/utils/route_transitions/basic.dart';
-import 'get_it_config.dart';
+import './get_it_config.dart';
class SimpleBlocObserver extends BlocObserver {
SimpleBlocObserver();
@override
- void onError(Cubit cubit, Object error, StackTrace stackTrace) {
- final navigator = getIt.get().navigator;
+ void onError(Bloc cubit, Object error, StackTrace stackTrace) {
+ final navigator = getIt.get().navigator!;
navigator.push(
materialRoute(
diff --git a/lib/config/brand_theme.dart b/lib/config/brand_theme.dart
index c8fd246e..9f76cc0c 100644
--- a/lib/config/brand_theme.dart
+++ b/lib/config/brand_theme.dart
@@ -1,11 +1,11 @@
import 'package:flutter/material.dart';
-import 'package:google_fonts/google_fonts.dart';
import 'package:selfprivacy/config/text_themes.dart';
import 'brand_colors.dart';
final ligtTheme = ThemeData(
primaryColor: BrandColors.primary,
+ fontFamily: 'Inter',
brightness: Brightness.light,
scaffoldBackgroundColor: BrandColors.scaffoldBackground,
inputDecorationTheme: InputDecorationTheme(
@@ -33,21 +33,17 @@ final ligtTheme = ThemeData(
color: BrandColors.red1,
),
),
- errorStyle: GoogleFonts.inter(
- textStyle: TextStyle(
- fontSize: 12,
- color: BrandColors.red1,
- ),
+ errorStyle: TextStyle(
+ fontSize: 12,
+ color: BrandColors.red1,
),
),
- textTheme: GoogleFonts.interTextTheme(
- TextTheme(
- headline1: headline1Style,
- headline2: headline2Style,
- caption: headline4Style,
- bodyText1: body1Style,
- subtitle1: TextStyle(fontSize: 15, height: 1.6), // text input style
- ),
+ textTheme: TextTheme(
+ headline1: headline1Style,
+ headline2: headline2Style,
+ caption: headline4Style,
+ bodyText1: body1Style,
+ subtitle1: TextStyle(fontSize: 15, height: 1.6), // text input style
),
);
@@ -57,14 +53,12 @@ var darkTheme = ligtTheme.copyWith(
iconTheme: IconThemeData(color: BrandColors.gray3),
cardColor: BrandColors.gray1,
dialogBackgroundColor: Color(0xFF202120),
- textTheme: GoogleFonts.interTextTheme(
- TextTheme(
- headline1: headline1Style.copyWith(color: BrandColors.white),
- headline2: headline2Style.copyWith(color: BrandColors.white),
- caption: headline4Style.copyWith(color: BrandColors.white),
- bodyText1: body1Style.copyWith(color: BrandColors.white),
- subtitle1: TextStyle(fontSize: 15, height: 1.6), // text input style
- ),
+ textTheme: TextTheme(
+ headline1: headline1Style.copyWith(color: BrandColors.white),
+ headline2: headline2Style.copyWith(color: BrandColors.white),
+ caption: headline4Style.copyWith(color: BrandColors.white),
+ bodyText1: body1Style.copyWith(color: BrandColors.white),
+ subtitle1: TextStyle(fontSize: 15, height: 1.6), // text input style
),
inputDecorationTheme: InputDecorationTheme(
labelStyle: TextStyle(color: BrandColors.white),
diff --git a/lib/config/hive_config.dart b/lib/config/hive_config.dart
index cf050972..17a10fb3 100644
--- a/lib/config/hive_config.dart
+++ b/lib/config/hive_config.dart
@@ -32,7 +32,8 @@ class HiveConfig {
await secureStorage.write(key: BNames.key, value: base64UrlEncode(key));
}
- return base64Url.decode(await secureStorage.read(key: BNames.key));
+ String? string = await secureStorage.read(key: BNames.key);
+ return base64Url.decode(string!);
}
}
diff --git a/lib/config/localization.dart b/lib/config/localization.dart
index b8e33be3..abaa2463 100644
--- a/lib/config/localization.dart
+++ b/lib/config/localization.dart
@@ -3,20 +3,20 @@ import 'package:flutter/material.dart';
class Localization extends StatelessWidget {
const Localization({
- Key key,
+ Key? key,
this.child,
}) : super(key: key);
- final Widget child;
+ final Widget? child;
@override
Widget build(BuildContext context) {
return EasyLocalization(
- preloaderColor: Colors.black,
supportedLocales: [Locale('ru'), Locale('en')],
path: 'assets/translations',
- fallbackLocale: Locale('en'),
+ fallbackLocale: Locale('ru'),
+ saveLocale: false,
useOnlyLangCode: true,
- child: child,
+ child: child!,
);
}
}
diff --git a/lib/config/md_files.dart b/lib/config/md_files.dart
new file mode 100644
index 00000000..e69de29b
diff --git a/lib/config/text_themes.dart b/lib/config/text_themes.dart
index 1c8c0fbf..b64ab1a2 100644
--- a/lib/config/text_themes.dart
+++ b/lib/config/text_themes.dart
@@ -1,41 +1,38 @@
import 'package:flutter/material.dart';
-import 'package:google_fonts/google_fonts.dart';
import 'package:selfprivacy/utils/named_font_weight.dart';
import 'brand_colors.dart';
-final defaultTextStyle = GoogleFonts.inter(
- textStyle: TextStyle(
- fontSize: 15,
- color: BrandColors.textColor1,
- ),
+final defaultTextStyle = TextStyle(
+ fontSize: 15,
+ color: BrandColors.textColor1,
);
-final headline1Style = GoogleFonts.inter(
+final headline1Style = defaultTextStyle.copyWith(
fontSize: 40,
fontWeight: NamedFontWeight.extraBold,
color: BrandColors.headlineColor,
);
-final headline2Style = GoogleFonts.inter(
+final headline2Style = defaultTextStyle.copyWith(
fontSize: 24,
fontWeight: NamedFontWeight.extraBold,
color: BrandColors.headlineColor,
);
-final onboardingTitle = GoogleFonts.inter(
+final onboardingTitle = defaultTextStyle.copyWith(
fontSize: 30,
fontWeight: NamedFontWeight.extraBold,
color: BrandColors.headlineColor,
);
-final headline3Style = GoogleFonts.inter(
+final headline3Style = defaultTextStyle.copyWith(
fontSize: 20,
fontWeight: NamedFontWeight.extraBold,
color: BrandColors.headlineColor,
);
-final headline4Style = GoogleFonts.inter(
+final headline4Style = defaultTextStyle.copyWith(
fontSize: 18,
fontWeight: NamedFontWeight.medium,
color: BrandColors.headlineColor,
@@ -59,16 +56,12 @@ final smallStyle = defaultTextStyle.copyWith(fontSize: 11, height: 1.45);
final linkStyle = defaultTextStyle.copyWith(color: BrandColors.blue);
-final progressTextStyleLight = GoogleFonts.inter(
- textStyle: TextStyle(
- fontSize: 11,
- color: BrandColors.textColor1,
- ),
+final progressTextStyleLight = TextStyle(
+ fontSize: 11,
+ color: BrandColors.textColor1,
);
-final progressTextStyleDark = GoogleFonts.inter(
- textStyle: TextStyle(
- fontSize: 11,
- color: BrandColors.white,
- ),
+final progressTextStyleDark = TextStyle(
+ fontSize: 11,
+ color: BrandColors.white,
);
diff --git a/lib/logic/api_maps/api_map.dart b/lib/logic/api_maps/api_map.dart
index a7c8949f..13f05e72 100644
--- a/lib/logic/api_maps/api_map.dart
+++ b/lib/logic/api_maps/api_map.dart
@@ -18,9 +18,9 @@ abstract class ApiMap {
};
loggedClient = client;
}
- String rootAddress;
+ String? rootAddress;
- Dio loggedClient;
+ late Dio loggedClient;
void close() {
loggedClient.close();
@@ -61,7 +61,7 @@ class ConsoleInterceptor extends InterceptorsWrapper {
addMessage(
Message.warn(
text:
- 'response-uri: ${response?.request?.uri}\ncode: ${response?.statusCode}\ndata: ${response?.toString()}\n',
+ 'response-uri: ${response?.request.uri}\ncode: ${response?.statusCode}\ndata: ${response?.toString()}\n',
),
);
return super.onError(err);
diff --git a/lib/logic/api_maps/backblaze.dart b/lib/logic/api_maps/backblaze.dart
index 35782fc7..5bf84863 100644
--- a/lib/logic/api_maps/backblaze.dart
+++ b/lib/logic/api_maps/backblaze.dart
@@ -3,17 +3,17 @@ import 'package:dio/dio.dart';
import 'package:selfprivacy/logic/api_maps/api_map.dart';
class BackblazeApi extends ApiMap {
- BackblazeApi([String token]) {
+ BackblazeApi([String? token]) {
if (token != null) {
loggedClient.options = BaseOptions(
headers: {'Authorization': 'Basic $token'},
- baseUrl: rootAddress,
+ baseUrl: rootAddress!,
);
}
}
@override
- String rootAddress =
+ String? rootAddress =
'https://api.backblazeb2.com/b2api/v2/b2_authorize_account';
Future isValid(String token) async {
@@ -24,7 +24,7 @@ class BackblazeApi extends ApiMap {
},
);
- Response response = await loggedClient.get(rootAddress, options: options);
+ Response response = await loggedClient.get(rootAddress!, options: options);
if (response.statusCode == HttpStatus.ok) {
return true;
diff --git a/lib/logic/api_maps/cloudflare.dart b/lib/logic/api_maps/cloudflare.dart
index cb69cdc3..b78b8ee6 100644
--- a/lib/logic/api_maps/cloudflare.dart
+++ b/lib/logic/api_maps/cloudflare.dart
@@ -5,7 +5,7 @@ import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
import 'package:selfprivacy/logic/models/dns_records.dart';
class CloudflareApi extends ApiMap {
- CloudflareApi([String token]) {
+ CloudflareApi([String? token]) {
if (token != null) {
loggedClient.options =
BaseOptions(headers: {'Authorization': 'Bearer $token'});
@@ -13,7 +13,7 @@ class CloudflareApi extends ApiMap {
}
@override
- String rootAddress = 'https://api.cloudflare.com/client/v4';
+ String? rootAddress = 'https://api.cloudflare.com/client/v4';
Future isValid(String token) async {
var url = '$rootAddress/user/tokens/verify';
@@ -35,7 +35,7 @@ class CloudflareApi extends ApiMap {
}
}
- Future getZoneId(String token, String domain) async {
+ Future getZoneId(String? token, String domain) async {
var url = '$rootAddress/zones';
var options = Options(
@@ -59,8 +59,8 @@ class CloudflareApi extends ApiMap {
}
Future removeSimilarRecords({
- String ip4,
- CloudFlareDomain cloudFlareDomain,
+ String? ip4,
+ required CloudFlareDomain cloudFlareDomain,
}) async {
var domainName = cloudFlareDomain.domainName;
var domainZoneId = cloudFlareDomain.zoneId;
@@ -82,8 +82,8 @@ class CloudflareApi extends ApiMap {
}
Future createMultipleDnsRecords({
- String ip4,
- CloudFlareDomain cloudFlareDomain,
+ String? ip4,
+ required CloudFlareDomain cloudFlareDomain,
}) async {
var domainName = cloudFlareDomain.domainName;
var domainZoneId = cloudFlareDomain.zoneId;
@@ -120,7 +120,7 @@ class CloudflareApi extends ApiMap {
// );
// }
- List projectDnsRecords(String domainName, String ip4) {
+ List projectDnsRecords(String? domainName, String? ip4) {
var domainA = DnsRecords(type: 'A', name: domainName, content: ip4);
var mx = DnsRecords(type: 'MX', name: '@', content: domainName);
@@ -161,7 +161,7 @@ class CloudflareApi extends ApiMap {
];
}
- Future> domainList() async {
+ Future?> domainList() async {
var url = '$rootAddress/zones?per_page=50';
var response = await loggedClient.get(
url,
@@ -169,7 +169,7 @@ class CloudflareApi extends ApiMap {
);
return response.data['result']
- .map((el) => el['name'] as String)
+ .map((el) => el['name'] as String?)
.toList();
}
}
diff --git a/lib/logic/api_maps/hetzner.dart b/lib/logic/api_maps/hetzner.dart
index ebff314c..8459d315 100644
--- a/lib/logic/api_maps/hetzner.dart
+++ b/lib/logic/api_maps/hetzner.dart
@@ -2,24 +2,23 @@ import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
-import 'package:flutter/foundation.dart';
import 'package:selfprivacy/logic/api_maps/api_map.dart';
import 'package:selfprivacy/logic/models/server_details.dart';
import 'package:selfprivacy/logic/models/user.dart';
import 'package:selfprivacy/utils/password_generator2.dart';
class HetznerApi extends ApiMap {
- HetznerApi([String token]) {
+ HetznerApi([String? token]) {
if (token != null) {
loggedClient.options = BaseOptions(
headers: {'Authorization': 'Bearer $token'},
- baseUrl: rootAddress,
+ baseUrl: rootAddress!,
);
}
}
@override
- String rootAddress = 'https://api.hetzner.cloud/v1/servers';
+ String? rootAddress = 'https://api.hetzner.cloud/v1/servers';
Future isValid(String token) async {
var options = Options(
@@ -29,7 +28,7 @@ class HetznerApi extends ApiMap {
},
);
- Response response = await loggedClient.get(rootAddress, options: options);
+ Response response = await loggedClient.get(rootAddress!, options: options);
if (response.statusCode == HttpStatus.ok) {
return true;
@@ -41,9 +40,9 @@ class HetznerApi extends ApiMap {
}
Future createServer({
- @required String cloudFlareKey,
- @required User rootUser,
- @required String domainName,
+ required String? cloudFlareKey,
+ required User rootUser,
+ required String? domainName,
}) async {
var dbPassword = getRandomString(40);
@@ -52,7 +51,7 @@ class HetznerApi extends ApiMap {
);
Response response = await loggedClient.post(
- rootAddress,
+ rootAddress!,
data: data,
);
@@ -64,17 +63,17 @@ class HetznerApi extends ApiMap {
}
Future deleteSelfprivacyServer({
- @required String cloudFlareKey,
+ required String? cloudFlareKey,
}) async {
- Response response = await loggedClient.get(rootAddress);
+ Response response = await loggedClient.get(rootAddress!);
List list = response.data['servers'];
var server = list.firstWhere((el) => el['name'] == 'selfprivacy-server');
- return await loggedClient.delete('$rootAddress/${server['id']}');
+ await loggedClient.delete('$rootAddress/${server['id']}');
}
Future startServer({
- HetznerServerDetails server,
+ required HetznerServerDetails server,
}) async {
await loggedClient.post('/${server.id}/actions/poweron');
@@ -84,7 +83,7 @@ class HetznerApi extends ApiMap {
}
Future restart({
- HetznerServerDetails server,
+ required HetznerServerDetails server,
}) async {
await loggedClient.post('/${server.id}/actions/poweron');
diff --git a/lib/logic/api_maps/server.dart b/lib/logic/api_maps/server.dart
index c5db1576..5f5abda4 100644
--- a/lib/logic/api_maps/server.dart
+++ b/lib/logic/api_maps/server.dart
@@ -5,7 +5,7 @@ import 'package:dio/dio.dart';
import 'api_map.dart';
class ServerApi extends ApiMap {
- ServerApi(String domainName) {
+ ServerApi(String? domainName) {
loggedClient.options = BaseOptions(
baseUrl: 'https://api.$domainName',
);
diff --git a/lib/logic/cubit/app_config/app_config_cubit.dart b/lib/logic/cubit/app_config/app_config_cubit.dart
index bc42f4e0..4d8dd8a5 100644
--- a/lib/logic/cubit/app_config/app_config_cubit.dart
+++ b/lib/logic/cubit/app_config/app_config_cubit.dart
@@ -2,7 +2,6 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
-import 'package:flutter/foundation.dart';
import 'package:selfprivacy/logic/models/backblaze_credential.dart';
import 'package:selfprivacy/logic/models/cloudflare_domain.dart';
@@ -10,6 +9,7 @@ import 'package:selfprivacy/logic/models/server_details.dart';
import 'package:selfprivacy/logic/models/user.dart';
import 'app_config_repository.dart';
+export 'package:provider/provider.dart';
part 'app_config_state.dart';
@@ -64,23 +64,23 @@ class AppConfigCubit extends Cubit {
}
void startServerIfDnsIsOkay({
- AppConfigState state,
+ AppConfigState? state,
bool isImmediate = false,
}) async {
state = state ?? this.state;
final work = () async {
- emit(TimerState(dataState: state, isLoading: true));
+ emit(TimerState(dataState: state!, isLoading: true));
- var ip4 = state.hetznerServer.ip4;
- var domainName = state.cloudFlareDomain.domainName;
+ var ip4 = state.hetznerServer!.ip4;
+ var domainName = state.cloudFlareDomain!.domainName;
var isMatch = await repository.isDnsAddressesMatch(domainName, ip4);
if (isMatch) {
var server = await repository.startServer(
state.hetznerKey,
- state.hetznerServer,
+ state.hetznerServer!,
);
repository.saveServerDetails(server);
emit(
@@ -111,16 +111,16 @@ class AppConfigCubit extends Cubit {
}
void resetServerIfServerIsOkay({
- AppConfigState state,
+ AppConfigState? state,
bool isImmediate = false,
}) async {
state = state ?? this.state;
var work = () async {
- emit(TimerState(dataState: state, isLoading: true));
+ emit(TimerState(dataState: state!, isLoading: true));
var isServerWorking = await repository.isHttpServerWorking(
- state.cloudFlareDomain.domainName,
+ state.cloudFlareDomain!.domainName,
);
if (isServerWorking) {
@@ -133,8 +133,8 @@ class AppConfigCubit extends Cubit {
));
timer = Timer(pauseDuration, () async {
var hetznerServerDetails = await repository.restart(
- state.hetznerKey,
- state.hetznerServer,
+ state!.hetznerKey,
+ state.hetznerServer!,
);
emit(
state.copyWith(
@@ -165,19 +165,19 @@ class AppConfigCubit extends Cubit {
}
}
- Timer timer;
+ Timer? timer;
void finishCheckIfServerIsOkay({
- AppConfigState state,
+ AppConfigState? state,
bool isImmediate = false,
}) async {
state = state ?? this.state;
var work = () async {
- emit(TimerState(dataState: state, isLoading: true));
+ emit(TimerState(dataState: state!, isLoading: true));
var isServerWorking = await repository.isHttpServerWorking(
- state.cloudFlareDomain.domainName,
+ state.cloudFlareDomain!.domainName,
);
if (isServerWorking) {
@@ -238,12 +238,12 @@ class AppConfigCubit extends Cubit {
}
void createServerAndSetDnsRecords() async {
- var _stateCopy = state;
+ AppConfigState _stateCopy = state;
var onSuccess = (serverDetails) async {
await repository.createDnsRecords(
state.cloudFlareKey,
serverDetails.ip4,
- state.cloudFlareDomain,
+ state.cloudFlareDomain!,
);
emit(state.copyWith(
@@ -259,8 +259,8 @@ class AppConfigCubit extends Cubit {
emit(state.copyWith(isLoading: true));
await repository.createServer(
state.hetznerKey,
- state.rootUser,
- state.cloudFlareDomain.domainName,
+ state.rootUser!,
+ state.cloudFlareDomain!.domainName,
state.cloudFlareKey,
onCancel: onCancel,
onSuccess: onSuccess,
@@ -277,54 +277,8 @@ class AppConfigCubit extends Cubit {
}
void _closeTimer() {
- if (timer != null && timer.isActive) {
- timer.cancel();
+ if (timer != null && timer!.isActive) {
+ timer!.cancel();
}
}
}
-
-// void checkDnsAndStartServer() async {
-// var ip4 = state.hetznerServer.ip4;
-// var domainName = state.cloudFlareDomain.domainName;
-
-// var isMatch = await repository.isDnsAddressesMatch(domainName, ip4);
-
-// if (isMatch) {
-// var server = await repository.startServer(
-// state.hetznerKey,
-// state.hetznerServer,
-// );
-// repository.saveServerDetails(server);
-// emit(
-// state.copyWith(
-// hasFinalChecked: true,
-// isServerStarted: true,
-// isLoading: false,
-// hetznerServer: server,
-// ),
-// );
-// } else {
-// emit(state.copyWith(lastDnsCheckTime: DateTime.now()));
-// }
-// }
-
-// void serverReset() async {
-// var callBack = () async {
-// var isServerWorking = await repository.isHttpServerWorking(
-// state.cloudFlareDomain.domainName,
-// );
-// if (!isServerWorking) {
-// var last = DateTime.now();
-// // emit(state.copyWith(lastServerStatusCheckTime: last));
-// return;
-// }
-
-// var hetznerServerDetails = await repository.restart(
-// state.hetznerKey,
-// state.hetznerServer,
-// );
-// emit(state.copyWith(hetznerServer: hetznerServerDetails));
-// };
-
-// _tryOrAddError(state, callBack);
-// }
diff --git a/lib/logic/cubit/app_config/app_config_repository.dart b/lib/logic/cubit/app_config/app_config_repository.dart
index 23709097..1a9f9d2b 100644
--- a/lib/logic/cubit/app_config/app_config_repository.dart
+++ b/lib/logic/cubit/app_config/app_config_repository.dart
@@ -60,7 +60,7 @@ class AppConfigRepository {
}
Future startServer(
- String hetznerKey,
+ String? hetznerKey,
HetznerServerDetails hetznerServer,
) async {
var hetznerApi = HetznerApi(hetznerKey);
@@ -75,7 +75,7 @@ class AppConfigRepository {
await box.put(BNames.hetznerServer, serverDetails);
}
- Future isDnsAddressesMatch(String domainName, String ip4) async {
+ Future isDnsAddressesMatch(String? domainName, String? ip4) async {
print(domainName);
var addresses = [
'$domainName',
@@ -116,12 +116,12 @@ class AppConfigRepository {
}
Future createServer(
- String hetznerKey,
+ String? hetznerKey,
User rootUser,
- String domainName,
- String cloudFlareKey, {
- void Function() onCancel,
- Future Function(HetznerServerDetails serverDetails) onSuccess,
+ String? domainName,
+ String? cloudFlareKey, {
+ void Function()? onCancel,
+ required Future Function(HetznerServerDetails serverDetails) onSuccess,
}) async {
var hetznerApi = HetznerApi(hetznerKey);
@@ -135,7 +135,7 @@ class AppConfigRepository {
hetznerApi.close();
onSuccess(serverDetails);
} on DioError catch (e) {
- if (e.response.data['error']['code'] == 'uniqueness_error') {
+ if (e.response!.data['error']['code'] == 'uniqueness_error') {
var nav = getIt.get();
nav.showPopUpDialog(
BrandAlert(
@@ -165,7 +165,7 @@ class AppConfigRepository {
text: 'Отменить',
onPressed: () {
hetznerApi.close();
- onCancel();
+ onCancel!();
},
),
],
@@ -176,8 +176,8 @@ class AppConfigRepository {
}
Future createDnsRecords(
- String cloudFlareKey,
- String ip4,
+ String? cloudFlareKey,
+ String? ip4,
CloudFlareDomain cloudFlareDomain,
) async {
var cloudflareApi = CloudflareApi(cloudFlareKey);
@@ -195,7 +195,7 @@ class AppConfigRepository {
cloudflareApi.close();
}
- Future isHttpServerWorking(String domainName) async {
+ Future isHttpServerWorking(String? domainName) async {
var api = ServerApi(domainName);
var isHttpServerWorking = await api.isHttpServerWorking();
api.close();
@@ -203,7 +203,7 @@ class AppConfigRepository {
}
Future restart(
- String hetznerKey,
+ String? hetznerKey,
HetznerServerDetails server,
) async {
var hetznerApi = HetznerApi(hetznerKey);
diff --git a/lib/logic/cubit/app_config/app_config_state.dart b/lib/logic/cubit/app_config/app_config_state.dart
index caedcc2c..d49c3382 100644
--- a/lib/logic/cubit/app_config/app_config_state.dart
+++ b/lib/logic/cubit/app_config/app_config_state.dart
@@ -2,21 +2,21 @@ part of 'app_config_cubit.dart';
class AppConfigState extends Equatable {
const AppConfigState({
- @required this.hetznerKey,
- @required this.cloudFlareKey,
- @required this.backblazeCredential,
- @required this.cloudFlareDomain,
- @required this.rootUser,
- @required this.hetznerServer,
- @required this.isServerStarted,
- @required this.isServerReseted,
- @required this.hasFinalChecked,
- @required this.isLoading,
- @required this.error,
+ required this.hetznerKey,
+ required this.cloudFlareKey,
+ required this.backblazeCredential,
+ required this.cloudFlareDomain,
+ required this.rootUser,
+ required this.hetznerServer,
+ required this.isServerStarted,
+ required this.isServerReseted,
+ required this.hasFinalChecked,
+ required this.isLoading,
+ required this.error,
});
@override
- List