mirror of
https://git.selfprivacy.org/kherel/selfprivacy.org.app.git
synced 2025-01-23 09:16:54 +00:00
Completely refactor language asset files
This commit is contained in:
parent
fecf96f31e
commit
d36c8e987d
|
@ -2,9 +2,10 @@
|
|||
"test": "en-test",
|
||||
"locale": "en",
|
||||
"basis": {
|
||||
"_comment": "Basic interface elements",
|
||||
"providers": "Providers",
|
||||
"providers_title": "Your Data Center",
|
||||
"services": "Services",
|
||||
"services_title": "Your personal, private and independent services.",
|
||||
"users": "Users",
|
||||
"more": "More",
|
||||
"next": "Next",
|
||||
|
@ -29,41 +30,38 @@
|
|||
"wait": "Wait",
|
||||
"remove": "Remove",
|
||||
"apply": "Apply",
|
||||
"done": "Done"
|
||||
"done": "Done",
|
||||
"continue": "Continue"
|
||||
},
|
||||
"more": {
|
||||
"_comment": "'More' tab",
|
||||
"more_page": {
|
||||
"configuration_wizard": "Setup wizard",
|
||||
"about_project": "About us",
|
||||
"about_app": "About application",
|
||||
"about_application": "About",
|
||||
"onboarding": "Onboarding",
|
||||
"create_ssh_key": "Create SSH key",
|
||||
"generate_key": "Generate key",
|
||||
"generate_key_text": "You can generate ssh key",
|
||||
"console": "Console",
|
||||
"remove": "Remove",
|
||||
"enable": "Enable",
|
||||
"ok": "ok",
|
||||
"continue": "Continue",
|
||||
"ssh_key_exist_text": "You have generated ssh key",
|
||||
"yes_delete": "Yes, delete my SSH key",
|
||||
"share": "Share",
|
||||
"copy_buffer": "Copy to buffer",
|
||||
"copied_ssh": "SSH copied to clipboard",
|
||||
"delete_ssh_text": "Delete SSH key?",
|
||||
"about_app_page": {
|
||||
"application_settings": "Application settings"
|
||||
},
|
||||
"console_page": {
|
||||
"title": "Console",
|
||||
"waiting": "Waiting for initialization..."
|
||||
},
|
||||
"about_us_page": {
|
||||
"title": "About us"
|
||||
},
|
||||
"about_application_page": {
|
||||
"title": "About",
|
||||
"application_version_text": "Application version v.{}",
|
||||
"api_version_text": "Server API version v.{}"
|
||||
},
|
||||
"settings": {
|
||||
"application_settings": {
|
||||
"title": "Application settings",
|
||||
"1": "Dark Theme",
|
||||
"2": "Change your the app theme",
|
||||
"3": "Reset app config",
|
||||
"4": "Reset api keys and root user",
|
||||
"5": "Delete Server",
|
||||
"6": "This removes the Server. It will be no longer accessible"
|
||||
}
|
||||
"dark_theme_title": "Dark theme",
|
||||
"dark_theme_description": "Switch your application theme",
|
||||
"reset_config_title": "Reset application config",
|
||||
"reset_config_description": "Reset api keys and root user",
|
||||
"delete_server_title": "Delete server",
|
||||
"delete_server_description": "This removes your server. It will be no longer accessible"
|
||||
},
|
||||
"ssh": {
|
||||
"title": "SSH keys",
|
||||
|
@ -73,31 +71,17 @@
|
|||
"subtitle_with_keys": "{} keys",
|
||||
"subtitle_without_keys": "No keys",
|
||||
"no_key_name": "Unnamed key",
|
||||
"root": {
|
||||
"title": "These are superuser keys",
|
||||
"subtitle": "Owners of these keys get full access to the server and can do anything on it. Only add your own keys to the server."
|
||||
},
|
||||
"root_title": "These are superuser keys",
|
||||
"root_subtitle": "Owners of these keys get full access to the server and can do anything on it. Only add your own keys to the server.",
|
||||
"input_label": "Public ED25519 or RSA key"
|
||||
},
|
||||
"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",
|
||||
"status": "Status — Good",
|
||||
"bottom_sheet": {
|
||||
"1": "It's a virtual computer, where all your services live.",
|
||||
"2": "General information",
|
||||
"3": "Location"
|
||||
},
|
||||
"chart": {
|
||||
"resource_chart": {
|
||||
"month": "Month",
|
||||
"day": "Day",
|
||||
"hour": "Hour",
|
||||
|
@ -106,16 +90,17 @@
|
|||
"in": "In",
|
||||
"out": "Out"
|
||||
},
|
||||
"server": {
|
||||
"card_title": "Server",
|
||||
"description": "All your services live here",
|
||||
"general_information": "General information",
|
||||
"resource_usage": "Resource usage",
|
||||
"settings": {
|
||||
"allow_autoupgrade": "Allow auto-upgrade",
|
||||
"allow_autoupgrade_hint": "Allow automatic packages upgrades on server",
|
||||
"reboot_after_upgrade": "Reboot after upgrade",
|
||||
"reboot_after_upgrade_hint": "Reboot without prompt after applying changes on server",
|
||||
"server_timezone": "Server timezone",
|
||||
"select_timezone": "Select timezone"
|
||||
},
|
||||
"info": {
|
||||
"select_timezone": "Select timezone",
|
||||
"server_id": "Server ID",
|
||||
"status": "Status",
|
||||
"cpu": "CPU",
|
||||
|
@ -127,23 +112,8 @@
|
|||
"one": "{} core",
|
||||
"other": "{} cores"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain": {
|
||||
"card_title": "Domain",
|
||||
"status": "Status — Good",
|
||||
"bottom_sheet": {
|
||||
"1": "It's your personal internet address that will point to the server and other services of yours."
|
||||
},
|
||||
"screen_title": "Domain and DNS",
|
||||
"states": {
|
||||
"ok": "Records are OK",
|
||||
"error": "Problems found",
|
||||
"error_subtitle": "Tap here to fix them",
|
||||
"refreshing": "Refreshing status...",
|
||||
"uninitialized": "Data is not retrieved yet"
|
||||
},
|
||||
"record_description": {
|
||||
"record": {
|
||||
"root": "Root domain",
|
||||
"api": "SelfPrivacy API",
|
||||
"cloud": "File cloud",
|
||||
|
@ -157,28 +127,26 @@
|
|||
"spf": "SPF record",
|
||||
"dkim": "DKIM key"
|
||||
},
|
||||
"cards": {
|
||||
"services": {
|
||||
"title": "Services",
|
||||
"subtitle": "Type “A” records required for each service."
|
||||
},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"subtitle": "Records necessary for secure email exchange."
|
||||
}
|
||||
}
|
||||
"domain": {
|
||||
"card_title": "Domain",
|
||||
"screen_title": "Domain and DNS",
|
||||
"ok": "Records are OK",
|
||||
"error": "Problems found",
|
||||
"error_subtitle": "Tap here to fix them",
|
||||
"refreshing": "Refreshing status...",
|
||||
"uninitialized": "Data is not retrieved yet",
|
||||
"services_title": "Services",
|
||||
"services_subtitle": "Type “A” records required for each service.",
|
||||
"email_title": "Email",
|
||||
"email_subtitle": "Records necessary for secure email exchange."
|
||||
},
|
||||
"backup": {
|
||||
"card_title": "Backup",
|
||||
"status": "Status — Good",
|
||||
"bottom_sheet": {
|
||||
"1": "Will save your day in case of incident: hackers attack, server deletion, etc.",
|
||||
"2": "3Gb/10Gb, last backup was yesterday {}"
|
||||
},
|
||||
"reuploadKey": "Force reupload key",
|
||||
"reuploadedKey": "Key reuploaded",
|
||||
"description": "Will save your day in case of incident: hackers attack, server deletion, etc.",
|
||||
"reupload_key": "Force reupload key",
|
||||
"reuploaded_key": "Key reuploaded",
|
||||
"initialize": "Initialize",
|
||||
"waitingForRebuild": "You will be able to create your first backup in a few minutes.",
|
||||
"waiting_for_rebuild": "You will be able to create your first backup in a few minutes.",
|
||||
"restore": "Restore from backup",
|
||||
"no_backups": "There are no backups yet",
|
||||
"create_new": "Create a new backup",
|
||||
|
@ -187,8 +155,8 @@
|
|||
"error_pending": "Server returned error, check it below",
|
||||
"restore_alert": "You are about to restore from backup created on {}. All current data will be lost. Are you sure?",
|
||||
"refresh": "Refresh status",
|
||||
"refetchBackups": "Refetch backup list",
|
||||
"refetchingList": "In a few minutes list will be updated"
|
||||
"refetch_backups": "Refetch backup list",
|
||||
"refetching_list": "In a few minutes list will be updated"
|
||||
},
|
||||
"storage": {
|
||||
"card_title": "Server Storage",
|
||||
|
@ -211,18 +179,13 @@
|
|||
"start_migration_button": "Start migration",
|
||||
"migration_process": "Migrating...",
|
||||
"migration_done": "Finish"
|
||||
}
|
||||
},
|
||||
"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",
|
||||
"begin": "Please finish application setup using ",
|
||||
"insertion": "@:more.configuration_wizard",
|
||||
"end": " for further work",
|
||||
"in_menu": "Server is not set up yet. Please finish setup using setup wizard for further work."
|
||||
},
|
||||
"services": {
|
||||
"_comment": "Services",
|
||||
"title": "Your personal, private and independent services.",
|
||||
"service_page": {
|
||||
"open_in_browser": "Open in browser",
|
||||
"restart": "Restart service",
|
||||
|
@ -234,87 +197,44 @@
|
|||
"mail": {
|
||||
"title": "E-Mail",
|
||||
"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": {
|
||||
"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.",
|
||||
"login_info": "Use the same username and password as for e-mail.",
|
||||
"bottom_sheet": {
|
||||
"1": "For connection, please use {} domain and credentials that you created."
|
||||
}
|
||||
"login_info": "Use username and password from users tab. IMAP port is 143 with STARTTLS, SMTP port is 587 with STARTTLS."
|
||||
},
|
||||
"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.",
|
||||
"login_info": "You will have to create an account on the website.",
|
||||
"bottom_sheet": {
|
||||
"1": "You can connect to the service and create a user via this link:"
|
||||
}
|
||||
"login_info": "You will have to create an account on the website."
|
||||
},
|
||||
"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.",
|
||||
"login_info": "No account needed.",
|
||||
"bottom_sheet": {
|
||||
"1": "Using Jitsi as simple as just visiting this link:"
|
||||
}
|
||||
"login_info": "No account needed."
|
||||
},
|
||||
"cloud": {
|
||||
"title": "Cloud Storage",
|
||||
"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": {
|
||||
"1": "You can connect and create a new user here:"
|
||||
}
|
||||
"login_info": "Login is admin, password is the same as with your main user. Create new accounts in Nextcloud interface."
|
||||
},
|
||||
"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.",
|
||||
"login_info": "You will have to create an account on the website.",
|
||||
"bottom_sheet": {
|
||||
"1": "You can connect and create new social user here:"
|
||||
}
|
||||
"login_info": "You will have to create an account on the website."
|
||||
},
|
||||
"git": {
|
||||
"title": "Git Server",
|
||||
"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": {
|
||||
"1": "You can connect and create a new user here:"
|
||||
}
|
||||
"login_info": "You will have to create an account on the website. First user will become an admin."
|
||||
},
|
||||
"vpn": {
|
||||
"title": "VPN Server",
|
||||
"subtitle": "Private VPN server",
|
||||
"bottom_sheet": {
|
||||
"1": "Openconnect VPN Server. Engine for secure and scalable VPN infrastructure"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"up_and_running": "Up and running",
|
||||
"resource_usage": "Resource usage",
|
||||
"disk_used": "{} of disk space used",
|
||||
"users": "Users",
|
||||
"controlled_by": "Controlled by {}",
|
||||
"apps": "Apps",
|
||||
"settings": "Settings and maintenance"
|
||||
}
|
||||
"subtitle": "Private VPN server"
|
||||
},
|
||||
"users": {
|
||||
"_comment": "'Users' tab",
|
||||
"add_new_user": "Add a first user",
|
||||
"new_user": "New user",
|
||||
"delete_user": "Delete user",
|
||||
"not_ready": "Please connect server, domain and DNS in the Providers tab, to be able to add a first user",
|
||||
"nobody_here": "Nobody here",
|
||||
"login": "Login",
|
||||
"onboarding": "Onboarding",
|
||||
"console": "Console",
|
||||
"new_user_info_note": "New user will automatically be granted an access to all of the services",
|
||||
"delete_confirm_question": "Are you sure?",
|
||||
"reset_password": "Reset password",
|
||||
|
@ -327,38 +247,34 @@
|
|||
"could_not_delete_user": "Couldn't delete user",
|
||||
"could_not_add_ssh_key": "Couldn't add SSH key",
|
||||
"email_login": "Email login",
|
||||
"no_sso_notice": "Only email and SSH accounts are created for this user. Single Sign On for all services is coming soon."
|
||||
"no_ssh_notice": "Only email and SSH accounts are created for this user. Single Sign On for all services is coming soon."
|
||||
},
|
||||
"initializing": {
|
||||
"_comment": "initializing page",
|
||||
"1": "Connect a server",
|
||||
"2": "A place where your data and SelfPrivacy services will reside:",
|
||||
"connect_to_server": "Connect a server",
|
||||
"place_where_data": "A place where your data and SelfPrivacy services will reside:",
|
||||
"how": "How to obtain API token",
|
||||
"hetzner_bad_key_error": "Hetzner API key is invalid",
|
||||
"cloudflare_bad_key_error": "Cloudflare API key is invalid",
|
||||
"backblaze_bad_key_error": "Backblaze storage information is invalid",
|
||||
"3": "Connect CloudFlare",
|
||||
"4": "To manage your domain's DNS",
|
||||
"5": "CloudFlare API Token",
|
||||
"6": "Connect Backblaze storage",
|
||||
"7": "No connected domains at the moment",
|
||||
"8": "Loading domains list",
|
||||
"9": "Found more than one domain. For your own security, please be asked to delete unnecessary domains",
|
||||
"10": "Save domain",
|
||||
"connect_cloudflare": "Connect CloudFlare",
|
||||
"manage_domain_dns": "To manage your domain's DNS",
|
||||
"cloudflare_api_token": "CloudFlare API Token",
|
||||
"connect_backblaze_storage": "Connect Backblaze storage",
|
||||
"no_connected_domains": "No connected domains at the moment",
|
||||
"loading_domain_list": "Loading domain list",
|
||||
"found_more_domains": "Found more than one domain. For your own security, please be asked to delete unnecessary domains",
|
||||
"save_domain": "Save domain",
|
||||
"final": "Final step",
|
||||
"11": "Create server",
|
||||
"create_server": "Create server",
|
||||
"what": "What does it mean?",
|
||||
"13": "Server rebooted. Waiting for the last verification...",
|
||||
"14": "Server started. It will be validated and rebooted now...",
|
||||
"15": "Server created. DNS checks and server boot in progress...",
|
||||
"16": "Until the next check: ",
|
||||
"17": "Check",
|
||||
"18": "How to obtain Hetzner API Token:'",
|
||||
"19": "1 Go via this link ",
|
||||
"20": "\n",
|
||||
"21": "One more restart to apply your security certificates.",
|
||||
"22": "Create master account",
|
||||
"23": "Enter a nickname and strong password",
|
||||
"server_rebooted": "Server rebooted. Waiting for the last verification...",
|
||||
"server_started": "Server started. It will be validated and rebooted now...",
|
||||
"server_created": "Server created. DNS checks and server boot in progress...",
|
||||
"until_the_next_check": "Until the next check: ",
|
||||
"check": "Check",
|
||||
"one_more_restart": "One more restart to apply your security certificates.",
|
||||
"create_master_account": "Create master account",
|
||||
"enter_nickname_and_password": "Enter a nickname and strong password",
|
||||
"finish": "Everything is initialized",
|
||||
"checks": "Checks have been completed \n{} out of {}"
|
||||
},
|
||||
|
@ -451,19 +367,16 @@
|
|||
"generation_error": "Couldn't generate a recovery key. {}"
|
||||
},
|
||||
"modals": {
|
||||
"_comment": "messages in modals",
|
||||
"1": "Server with such name, already exist.",
|
||||
"1_1": "Unexpected error during placement from the provider side.",
|
||||
"2": "Destroy server and create a new one?",
|
||||
"2_2": "Try again?",
|
||||
"3": "Are you sure?",
|
||||
"4": "Purge all authentication keys?",
|
||||
"5": "Yes, purge all my tokens",
|
||||
"6": "Delete the server and volume?",
|
||||
"7": "Yes",
|
||||
"8": "Remove task",
|
||||
"9": "Reboot",
|
||||
"10": "You cannot use this API for domains with such TLD.",
|
||||
"already_exists": "Such server already exists.",
|
||||
"unexpected_error": "Unexpected error during placement from the provider side.",
|
||||
"destroy_server": "Destroy the server and create a new one?",
|
||||
"try_again": "Try again?",
|
||||
"are_you_sure": "Are you sure?",
|
||||
"purge_all_keys": "Purge all authentication keys?",
|
||||
"purge_all_keys_confirm": "Yes, purge all my tokens",
|
||||
"delete_server_volume": "Delete the server and volume?",
|
||||
"reboot": "Reboot",
|
||||
"you_cant_use_this_api": "You cannot use this API for domains with such TLD.",
|
||||
"yes": "Yes",
|
||||
"no": "No"
|
||||
},
|
||||
|
@ -471,27 +384,26 @@
|
|||
"sec": "{} sec"
|
||||
},
|
||||
"jobs": {
|
||||
"_comment": "Jobs list",
|
||||
"title": "Jobs list",
|
||||
"start": "Start",
|
||||
"empty": "No jobs",
|
||||
"createUser": "Create user",
|
||||
"deleteUser": "Delete user",
|
||||
"serviceTurnOff": "Turn off",
|
||||
"serviceTurnOn": "Turn on",
|
||||
"jobAdded": "Job added",
|
||||
"runJobs": "Run jobs",
|
||||
"rebootSuccess": "Server is rebooting",
|
||||
"rebootFailed": "Couldn't reboot the server. Check the app logs.",
|
||||
"configPullFailed": "Failed to pull configuration upgrade. Started software upgrade anyways.",
|
||||
"upgradeSuccess": "Server upgrade started",
|
||||
"upgradeFailed": "Failed to upgrade server",
|
||||
"upgradeServer": "Upgrade server",
|
||||
"rebootServer": "Reboot server",
|
||||
"create_user": "Create user",
|
||||
"delete_user": "Delete user",
|
||||
"service_turn_off": "Turn off",
|
||||
"service_turn_on": "Turn on",
|
||||
"job_added": "Job added",
|
||||
"run_jobs": "Run jobs",
|
||||
"reboot_success": "Server is rebooting",
|
||||
"reboot_failed": "Couldn't reboot the server. Check the app logs.",
|
||||
"config_pull_failed": "Failed to pull configuration upgrade. Started software upgrade anyways.",
|
||||
"upgrade_success": "Server upgrade started",
|
||||
"upgrade_failed": "Failed to upgrade server",
|
||||
"upgrade_server": "Upgrade server",
|
||||
"reboot_server": "Reboot server",
|
||||
"create_ssh_key": "Create SSH key for {}",
|
||||
"delete_ssh_key": "Delete SSH key for {}",
|
||||
"server_jobs": "Jobs on the server",
|
||||
"resetUserPassword": "Reset password of user"
|
||||
"reset_user_password": "Reset password of user"
|
||||
},
|
||||
"validations": {
|
||||
"required": "Required.",
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"test": "ru-test",
|
||||
"locale": "ru",
|
||||
"basis": {
|
||||
"_comment": "базовые элементы интерфейса",
|
||||
"providers": "Провайдеры",
|
||||
"providers_title": "Ваш Дата Центр",
|
||||
"services": "Сервисы",
|
||||
"services_title": "Ваши личные, приватные и независимые сервисы.",
|
||||
"users": "Пользователи",
|
||||
"more": "Ещё",
|
||||
"next": "Далее",
|
||||
|
@ -29,41 +30,38 @@
|
|||
"wait": "Загрузка",
|
||||
"remove": "Удалить",
|
||||
"apply": "Подать",
|
||||
"done": "Готово"
|
||||
"done": "Готово",
|
||||
"continue": "Продолжить"
|
||||
},
|
||||
"more": {
|
||||
"_comment": "вкладка ещё",
|
||||
"more_page": {
|
||||
"configuration_wizard": "Мастер Подключения",
|
||||
"about_project": "О проекте SelfPrivacy",
|
||||
"about_app": "О приложении",
|
||||
"about_application": "О приложении",
|
||||
"onboarding": "Приветствие",
|
||||
"console": "Консоль",
|
||||
"create_ssh_key": "Создать ssh ключ",
|
||||
"generate_key": "Сгенерировать ключ",
|
||||
"generate_key_text": "Вы сможете сгенерировать ключ",
|
||||
"remove": "Отключить",
|
||||
"enable": "Включить",
|
||||
"ok": "ok",
|
||||
"continue": "Продолжить",
|
||||
"ssh_key_exist_text": "У Вас уже есть сгенерированный ssh ключ",
|
||||
"yes_delete": "Да, удалить",
|
||||
"share": "Поделиться",
|
||||
"copy_buffer": "Копировать в буфер",
|
||||
"copied_ssh": "SSH ключ cкопирован в буфер",
|
||||
"delete_ssh_text": "Удалить SSH ключ?",
|
||||
"about_app_page": {
|
||||
"application_settings": "Настройки приложения"
|
||||
},
|
||||
"console_page": {
|
||||
"title": "Консоль",
|
||||
"waiting": "Ждём инициализации..."
|
||||
},
|
||||
"about_us_page": {
|
||||
"title": "О проекте SelfPrivacy"
|
||||
},
|
||||
"about_application_page": {
|
||||
"title": "О приложении",
|
||||
"application_version_text": "Версия приложения v.{}",
|
||||
"api_version_text": "Версия API сервера v.{}"
|
||||
},
|
||||
"settings": {
|
||||
"application_settings": {
|
||||
"title": "Настройки приложения",
|
||||
"1": "Тёмная тема",
|
||||
"2": "Сменить цветовую тему.",
|
||||
"3": "Сброс настроек",
|
||||
"4": "Сбросить API ключи а также root пользвателя.",
|
||||
"5": "Удалить сервер",
|
||||
"6": "Действие приведет к удалению сервера. После этого он будет недоступен."
|
||||
}
|
||||
"dark_theme_title": "Тёмная тема",
|
||||
"dark_theme_description": "Сменить цветовую тему.",
|
||||
"reset_config_title": "Сброс настроек",
|
||||
"reset_config_description": "Сбросить API ключи а также root пользвателя.",
|
||||
"delete_server_title": "Удалить сервер",
|
||||
"delete_server_description": "Действие приведет к удалению сервера. После этого он будет недоступен."
|
||||
},
|
||||
"ssh": {
|
||||
"title": "SSH ключи",
|
||||
|
@ -73,31 +71,17 @@
|
|||
"subtitle_with_keys": "Ключей: {}",
|
||||
"subtitle_without_keys": "Ключей нет",
|
||||
"no_key_name": "Безымянный ключ",
|
||||
"root": {
|
||||
"title": "Это ключи суперпользователя",
|
||||
"subtitle": "Владельцы указанных здесь ключей получают полный доступ к данным и настройкам сервера. Добавляйте исключительно свои ключи."
|
||||
},
|
||||
"root_title": "Это ключи суперпользователя",
|
||||
"root_subtitle": "Владельцы указанных здесь ключей получают полный доступ к данным и настройкам сервера. Добавляйте исключительно свои ключи.",
|
||||
"input_label": "Публичный ED25519 или RSA ключ"
|
||||
},
|
||||
"onboarding": {
|
||||
"_comment": "страницы онбординга",
|
||||
"page1_title": "Цифровая независимость доступна каждому",
|
||||
"page1_text": "Почта, VPN, Мессенджер, социальная сеть и многое другое на Вашем личном сервере, под Вашим полным контролем.",
|
||||
"page2_title": "SelfPrivacy — это не облако, а Ваш личный дата-центр",
|
||||
"page2_text": "SelfPrivacy работает только с вашими сервис-провайдерами: Hetzner, Cloudflare, Backblaze. Если у Вас нет учётных записей, мы поможем их создать."
|
||||
},
|
||||
"providers": {
|
||||
"_comment": "вкладка провайдеры",
|
||||
"page_title": "Ваш Дата-центр",
|
||||
"server": {
|
||||
"card_title": "Сервер",
|
||||
"status": "Статус — в норме",
|
||||
"bottom_sheet": {
|
||||
"1": "Это виртуальный компьютер на котором работают все Ваши сервисы.",
|
||||
"2": "Общая информация",
|
||||
"3": "Размещение"
|
||||
},
|
||||
"chart": {
|
||||
"resource_chart": {
|
||||
"month": "Месяц",
|
||||
"day": "День",
|
||||
"hour": "Час",
|
||||
|
@ -106,19 +90,21 @@
|
|||
"in": "Получено",
|
||||
"out": "Отправлено"
|
||||
},
|
||||
"settings": {
|
||||
"server": {
|
||||
"card_title": "Сервер",
|
||||
"description": "Это виртуальный компьютер на котором работают все Ваши сервисы.",
|
||||
"general_information": "Общая информация",
|
||||
"resource_usage": "Потребление ресурсов",
|
||||
"allow_autoupgrade": "Разрешить авто-обноления",
|
||||
"allow_autoupgrade_hint": "Разрешить автоматичесую установку обновлений на сервер",
|
||||
"reboot_after_upgrade": "Перезагружать после обновлений",
|
||||
"reboot_after_upgrade_hint": "Автоматически перезагружать сервер после применения обновлений",
|
||||
"server_timezone": "Часовой пояс сервера",
|
||||
"select_timezone": "Выберите часовой пояс"
|
||||
},
|
||||
"info": {
|
||||
"select_timezone": "Выберите часовой пояс",
|
||||
"server_id": "ID сервера",
|
||||
"status": "Статус",
|
||||
"cpu": "Процессор",
|
||||
"ram": "Операивная память",
|
||||
"ram": "Оперативная память",
|
||||
"disk": "Диск",
|
||||
"monthly_cost": "Ежемесячная стоимость",
|
||||
"location": "Размещение",
|
||||
|
@ -129,23 +115,8 @@
|
|||
"many": "{} ядер",
|
||||
"other": "{} ядер"
|
||||
}
|
||||
}
|
||||
},
|
||||
"domain": {
|
||||
"card_title": "Домен",
|
||||
"status": "Статус — в норме",
|
||||
"bottom_sheet": {
|
||||
"1": "Это ваш личный адрес в интернете, который будет указывать на сервер и другие ваши сервисы."
|
||||
},
|
||||
"screen_title": "Домен и DNS",
|
||||
"states": {
|
||||
"ok": "Записи в норме",
|
||||
"error": "Обнаружены проблемы",
|
||||
"error_subtitle": "Нажмите здесь, чтобы исправить",
|
||||
"refreshing": "Обновление данных...",
|
||||
"uninitialized": "Данные ещё не получены"
|
||||
},
|
||||
"record_description": {
|
||||
"record": {
|
||||
"root": "Корневой домен",
|
||||
"api": "SelfPrivacy API",
|
||||
"cloud": "Файловое облако",
|
||||
|
@ -159,28 +130,26 @@
|
|||
"spf": "SPF запись",
|
||||
"dkim": "DKIM ключ"
|
||||
},
|
||||
"cards": {
|
||||
"services": {
|
||||
"title": "Сервисы",
|
||||
"subtitle": "Записи типа “A” необходимые для работы сервисов."
|
||||
},
|
||||
"email": {
|
||||
"title": "Электронная почта",
|
||||
"subtitle": "Записи необходимые для безопасного обмена электронной почтой."
|
||||
}
|
||||
}
|
||||
"domain": {
|
||||
"card_title": "Домен",
|
||||
"screen_title": "Домен и DNS",
|
||||
"ok": "Записи в норме",
|
||||
"error": "Обнаружены проблемы",
|
||||
"error_subtitle": "Нажмите здесь, чтобы исправить",
|
||||
"refreshing": "Обновление данных...",
|
||||
"uninitialized": "Данные ещё не получены",
|
||||
"services_title": "Сервисы",
|
||||
"services_subtitle": "Записи типа “A” необходимые для работы сервисов.",
|
||||
"email_title": "Электронная почта",
|
||||
"email_subtitle": "Записи необходимые для безопасного обмена электронной почтой."
|
||||
},
|
||||
"backup": {
|
||||
"card_title": "Резервное копирование",
|
||||
"status": "Статус — в норме",
|
||||
"bottom_sheet": {
|
||||
"1": "Выручит Вас в любой ситуации: хакерская атака, удаление сервера и т.д.",
|
||||
"2": "Использовано 3Gb из бесплатых 10Gb. Последнее копирование была сделано вчера в {}."
|
||||
},
|
||||
"reuploadKey": "Принудительно обновить ключ",
|
||||
"reuploadedKey": "Ключ на сервере обновлён",
|
||||
"description": "Выручит Вас в любой ситуации: хакерская атака, удаление сервера и т.д.",
|
||||
"reupload_key": "Принудительно обновить ключ",
|
||||
"reuploaded_key": "Ключ на сервере обновлён",
|
||||
"initialize": "Настроить",
|
||||
"waitingForRebuild": "Через несколько минут можно будет создать первую копию.",
|
||||
"waiting_for_rebuild": "Через несколько минут можно будет создать первую копию.",
|
||||
"restore": "Восстановить из копии",
|
||||
"no_backups": "Резервных копий пока нет",
|
||||
"create_new": "Создать новую копию",
|
||||
|
@ -189,8 +158,8 @@
|
|||
"error_pending": "Сервер вернул ошибку: проверьте её ниже.",
|
||||
"restore_alert": "Вы собираетесь восстановить из копии созданной {}. Все текущие данные будут потеряны. Вы уверены?",
|
||||
"refresh": "Обновить статус",
|
||||
"refetchBackups": "Обновить список копий",
|
||||
"refetchingList": "Через несколько минут список будет обновлён"
|
||||
"refetch_backups": "Обновить список копий",
|
||||
"refetching_list": "Через несколько минут список будет обновлён"
|
||||
},
|
||||
"storage": {
|
||||
"card_title": "Хранилище",
|
||||
|
@ -213,18 +182,13 @@
|
|||
"start_migration_button": "Начать миграцию",
|
||||
"migration_process": "Мигрируем...",
|
||||
"migration_done": "Завершить"
|
||||
}
|
||||
},
|
||||
"not_ready_card": {
|
||||
"_comment": "Карточка показывающая когда человек скипнул настройку, на карте текст из 3 блоков, средний содержит ссыку на мастер подключения",
|
||||
"1": "Завершите настройку приложения используя ",
|
||||
"2": "@:more.configuration_wizard",
|
||||
"3": " для продолжения работы",
|
||||
"begin": "Завершите настройку приложения используя ",
|
||||
"insertion": "@:more.configuration_wizard",
|
||||
"end": " для продолжения работы",
|
||||
"in_menu": "Сервер ещё не настроен, воспользуйтесь мастером подключения."
|
||||
},
|
||||
"services": {
|
||||
"_comment": "Вкладка сервисы",
|
||||
"title": "Ваши личные, приватные и независимые сервисы:",
|
||||
"service_page": {
|
||||
"open_in_browser": "Открыть в браузере",
|
||||
"restart": "Перезапустить сервис",
|
||||
|
@ -236,122 +200,84 @@
|
|||
"mail": {
|
||||
"title": "Почта",
|
||||
"subtitle": "Электронная почта для семьи или компании.",
|
||||
"login_info": "Используйте логин и пароль из вкладки пользователей. IMAP порт: 143, STARTTLS. SMTP порт: 587, STARTTLS.",
|
||||
"bottom_sheet": {
|
||||
"1": "Для подключения почтового ящика используйте {} и профиль, который Вы создали. Так же приглашайте",
|
||||
"2": "новых пользователей."
|
||||
}
|
||||
},
|
||||
"messenger": {
|
||||
"title": "Мессенджер",
|
||||
"subtitle": "Telegram и Signal не так приватны, как Delta.Chat — он использует Ваш личный сервер.",
|
||||
"login_info": "Используйте те же логин и пароль, что и для почты.",
|
||||
"bottom_sheet": {
|
||||
"1": "Для подключения используйте {} и логин пароль, который Вы создали."
|
||||
}
|
||||
"login_info": "Используйте логин и пароль из вкладки пользователей. IMAP порт: 143, STARTTLS. SMTP порт: 587, STARTTLS."
|
||||
},
|
||||
"password_manager": {
|
||||
"title": "Менеджер паролей",
|
||||
"subtitle": "Это фундамент Вашей безопасности. Создавать, хранить, копировать пароли между устройствами и вбивать их в формы поможет Bitwarden.",
|
||||
"login_info": "Аккаунт нужно создать на сайте.",
|
||||
"bottom_sheet": {
|
||||
"1": "Подключиться к серверу и создать пользователя можно по адресу:."
|
||||
}
|
||||
"login_info": "Аккаунт нужно создать на сайте."
|
||||
},
|
||||
"video": {
|
||||
"title": "Видеоконференция",
|
||||
"subtitle": "Jitsi meet — отличный аналог Zoom и Google meet который помимо удобства ещё и гарантирует Вам защищённые высококачественные видеоконференции.",
|
||||
"login_info": "Аккаунт не требуется.",
|
||||
"bottom_sheet": {
|
||||
"1": "Для использования просто перейдите по ссылке:."
|
||||
}
|
||||
"login_info": "Аккаунт не требуется."
|
||||
},
|
||||
"cloud": {
|
||||
"title": "Файловое облако",
|
||||
"subtitle": "Не позволяйте облачным сервисам просматривать ваши данные. Используйте NextCloud — надёжный дом для всех Ваших данных.",
|
||||
"login_info": "Логин администратора: admin, пароль такой же как у основного пользователя. Создавайте новых пользователей в интерфейсе администратора NextCloud.",
|
||||
"bottom_sheet": {
|
||||
"1": "Подключиться к серверу и создать пользователя можно по адресу:."
|
||||
}
|
||||
"login_info": "Логин администратора: admin, пароль такой же как у основного пользователя. Создавайте новых пользователей в интерфейсе администратора NextCloud."
|
||||
},
|
||||
"social_network": {
|
||||
"title": "Социальная сеть",
|
||||
"subtitle": "Сложно поверить, но стало возможным создать свою собственную социальную сеть, со своими правилами и аудиторией.",
|
||||
"login_info": "Аккаунт нужно создать на сайте.",
|
||||
"bottom_sheet": {
|
||||
"1": "Подключиться к серверу и создать пользователя можно по адресу:."
|
||||
}
|
||||
"login_info": "Аккаунт нужно создать на сайте."
|
||||
},
|
||||
"git": {
|
||||
"title": "Git-сервер",
|
||||
"subtitle": "Приватная альтернатива Github, которая принадлежит вам, а не Microsoft.",
|
||||
"login_info": "Аккаунт нужно создать на сайте. Первый зарегистрированный пользователь становится администратором.",
|
||||
"bottom_sheet": {
|
||||
"1": "Подключиться к серверу и создать пользователя можно по адресу:."
|
||||
}
|
||||
"login_info": "Аккаунт нужно создать на сайте. Первый зарегистрированный пользователь становится администратором."
|
||||
},
|
||||
"vpn": {
|
||||
"title": "VPN сервер",
|
||||
"subtitle": "Закрытый VPN сервер",
|
||||
"bottom_sheet": {
|
||||
"1": "Создать подключиться к VPN-серверу. Движок для безопасной и масштабируемой инфраструктуры VPN"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"up_and_running": "Запущен и работает",
|
||||
"resource_usage": "Потребление ресурсов",
|
||||
"disk_used": "{} использовано места на диске",
|
||||
"users": "Пользователи",
|
||||
"controlled_by": "Контролируется {}",
|
||||
"apps": "Приложения",
|
||||
"settings": "Настройки"
|
||||
}
|
||||
"subtitle": "Закрытый VPN сервер"
|
||||
},
|
||||
"users": {
|
||||
"_comment": "'Users' tab",
|
||||
"add_new_user": "Добавьте первого пользователя.",
|
||||
"new_user": "Новый пользователь",
|
||||
"delete_user": "Удалить пользователя",
|
||||
"not_ready": "Подключите сервер, домен и DNS в разделе Провайдеры чтобы добавить первого пользователя",
|
||||
"nobody_here": "Здесь будут отображаться пользователи.",
|
||||
"login": "Логин",
|
||||
"onboarding": "Приветствие",
|
||||
"console": "Консоль разработчика",
|
||||
"new_user_info_note": "Новый пользователь автоматически получит доступ ко всем сервисам.",
|
||||
"delete_confirm_question": "Вы действительно хотите удалить учетную запись?",
|
||||
"reset_password": "Сбросить пароль",
|
||||
"account": "Учетная запись",
|
||||
"send_registration_data": "Поделиться реквизитами"
|
||||
"send_registration_data": "Поделиться реквизитами",
|
||||
"could_not_fetch_users": "Не удалось получить пользователей",
|
||||
"could_not_fetch_description": "Проверьте интернет соединение и попробуйте снова",
|
||||
"refresh_users": "Обновить список пользователей",
|
||||
"could_not_create_user": "Не удалось создать пользователя",
|
||||
"could_not_delete_user": "Не удалось стереть пользователя",
|
||||
"could_not_add_ssh_key": "Не удалось создать SSH ключить",
|
||||
"email_login": "Авторизация по Email",
|
||||
"no_ssh_notice": "Для этого пользователя созданы только SSH и Email аккаунты. Единая авторизация для всех сервисов ещё не реализована."
|
||||
},
|
||||
"initializing": {
|
||||
"_comment": "initializing page",
|
||||
"1": "Подключите сервер",
|
||||
"2": "Здесь будут жить наши данные и SelfPrivacy-сервисы",
|
||||
"connect_to_server": "Подключите сервер",
|
||||
"place_where_data": "Здесь будут жить наши данные и SelfPrivacy-сервисы",
|
||||
"how": "Как получить API Token",
|
||||
"hetzner_bad_key_error": "Hetzner API ключ неверен",
|
||||
"cloudflare_bad_key_error": "Cloudflare API ключ неверен",
|
||||
"backblaze_bad_key_error": "Информация о Backblaze хранилище неверна",
|
||||
"3": "Подключите CloudFlare",
|
||||
"4": "Для управления DNS вашего домена",
|
||||
"5": "CloudFlare API Token",
|
||||
"6": "Подключите облачное хранилище Backblaze",
|
||||
"7": "На данный момент подлюченных доменов нет",
|
||||
"8": "Загружаем список доменов",
|
||||
"9": "Найдено больше одного домена, для вашей безопастности, просим Вам удалить не нужные домены",
|
||||
"10": "Сохранить домен",
|
||||
"connect_cloudflare": "Подключите CloudFlare",
|
||||
"manage_domain_dns": "Для управления DNS вашего домена",
|
||||
"cloudflare_api_token": "CloudFlare API Token",
|
||||
"connect_backblaze_storage": "Подключите облачное хранилище Backblaze",
|
||||
"no_connected_domains": "На данный момент подлюченных доменов нет",
|
||||
"loading_domain_list": "Загружаем список доменов",
|
||||
"found_more_domains": "Найдено больше одного домена, для вашей безопастности, просим Вам удалить не нужные домены",
|
||||
"save_domain": "Сохранить домен",
|
||||
"final": "Последний шаг",
|
||||
"11": "Создать сервер",
|
||||
"create_server": "Создать сервер",
|
||||
"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 даём нашему токену название (это может быть любое название, которое Вам нравиться, сути оно не меняет.",
|
||||
"21": "Сейчас будет дополнительная перезагрузка для активации сертификатов безопастности",
|
||||
"22": "Создайте главную учетную запись",
|
||||
"23": "Введите никнейм и сложный пароль",
|
||||
"server_rebooted": "Сервер презагружен, ждем последнюю проверку.",
|
||||
"server_started": "Cервер запущен, сейчас он будет проверен и перезагружен.",
|
||||
"server_created": "Cервер создан, идет проверка ДНС адресов и запуск сервера.",
|
||||
"until_the_next_check": "До следующей проверки: ",
|
||||
"check": "Проверка",
|
||||
"one_more_restart": "Сейчас будет дополнительная перезагрузка для активации сертификатов безопастности",
|
||||
"create_master_account": "Создайте главную учетную запись",
|
||||
"enter_nickname_and_password": "Введите никнейм и сложный пароль",
|
||||
"finish": "Всё инициализировано.",
|
||||
"checks": "Проверок выполнено: \n{} / {}"
|
||||
},
|
||||
|
@ -444,19 +370,16 @@
|
|||
"generation_error": "Не удалось сгенерировать ключ. {}"
|
||||
},
|
||||
"modals": {
|
||||
"_comment": "messages in modals",
|
||||
"1": "Сервер с таким именем уже существует.",
|
||||
"1.1": "Непредвиденная ошибка при создании со стороны провайдера.",
|
||||
"2": "Уничтожить сервер и создать новый?",
|
||||
"2.2": "Попробовать ещё раз?",
|
||||
"3": "Подтвердите",
|
||||
"4": "Сбросить все ключи?",
|
||||
"5": "Да, сбросить",
|
||||
"6": "Удалить сервер и диск?",
|
||||
"7": "Да, удалить",
|
||||
"8": "Удалить задачу",
|
||||
"9": "Перезагрузить",
|
||||
"10": "API не поддерживает домены с таким TLD.",
|
||||
"already_exists": "Такой сервер уже существует.",
|
||||
"unexpected_error": "Непредвиденная ошибка со стороны провайдера.",
|
||||
"destroy_server": "Уничтожить сервер и создать новый?",
|
||||
"try_again": "Попробовать ещё раз?",
|
||||
"are_you_sure": "Вы уверены?",
|
||||
"purge_all_keys": "Стереть все ключи авторизации?",
|
||||
"purge_all_keys_confirm": "Да, стереть все ключи!",
|
||||
"delete_server_volume": "Удалить сервер и хранилище?",
|
||||
"reboot": "Перезагрузить",
|
||||
"you_cant_use_this_api": "Нельзя использовать этот API для доменом с подобным TLD.",
|
||||
"yes": "Да",
|
||||
"no": "Нет"
|
||||
},
|
||||
|
@ -464,27 +387,26 @@
|
|||
"sec": "{} сек"
|
||||
},
|
||||
"jobs": {
|
||||
"_comment": "Jobs list",
|
||||
"title": "Задачи",
|
||||
"start": "Начать выполенение",
|
||||
"empty": "Пусто.",
|
||||
"createUser": "Создать пользователя",
|
||||
"deleteUser": "Удалить пользователя",
|
||||
"serviceTurnOff": "Остановить",
|
||||
"serviceTurnOn": "Запустить",
|
||||
"jobAdded": "Задача добавленна",
|
||||
"runJobs": "Запустите задачи",
|
||||
"rebootSuccess": "Сервер перезагружается",
|
||||
"rebootFailed": "Не удалось перезагрузить сервер, проверьте логи",
|
||||
"configPullFailed": "Не удалось обновить конфигурацию сервера. Обновление ПО запущено.",
|
||||
"upgradeSuccess": "Запущено обновление сервера",
|
||||
"upgradeFailed": "Обновить сервер не вышло",
|
||||
"upgradeServer": "Обновить сервер",
|
||||
"rebootServer": "Перезагрузить сервер",
|
||||
"create_user": "Создать пользователя",
|
||||
"delete_user": "Удалить пользователя",
|
||||
"service_turn_off": "Остановить",
|
||||
"service_turn_on": "Запустить",
|
||||
"job_added": "Задача добавленна",
|
||||
"run_jobs": "Запустите задачи",
|
||||
"reboot_success": "Сервер перезагружается",
|
||||
"reboot_failed": "Не удалось перезагрузить сервер, проверьте логи",
|
||||
"config_pull_failed": "Не удалось обновить конфигурацию сервера. Обновление ПО запущено.",
|
||||
"upgrade_success": "Запущено обновление сервера",
|
||||
"upgrade_failed": "Обновить сервер не вышло",
|
||||
"upgrade_server": "Обновить сервер",
|
||||
"reboot_server": "Перезагрузить сервер",
|
||||
"create_ssh_key": "Создать SSH ключ для {}",
|
||||
"delete_ssh_key": "Удалить SSH ключ для {}",
|
||||
"server_jobs": "Задачи на сервере",
|
||||
"resetUserPassword": "Сбросить пароль пользователя"
|
||||
"reset_user_password": "Сбросить пароль пользователя"
|
||||
},
|
||||
"validations": {
|
||||
"required": "Обязательное поле.",
|
||||
|
|
|
@ -51,55 +51,55 @@ extension ServiceTypesExt on ServiceTypes {
|
|||
String get title {
|
||||
switch (this) {
|
||||
case ServiceTypes.mailserver:
|
||||
return 'services.mail.title'.tr();
|
||||
return 'mail.title'.tr();
|
||||
case ServiceTypes.bitwarden:
|
||||
return 'services.password_manager.title'.tr();
|
||||
return 'password_manager.title'.tr();
|
||||
case ServiceTypes.jitsi:
|
||||
return 'services.video.title'.tr();
|
||||
return 'video.title'.tr();
|
||||
case ServiceTypes.nextcloud:
|
||||
return 'services.cloud.title'.tr();
|
||||
return 'cloud.title'.tr();
|
||||
case ServiceTypes.pleroma:
|
||||
return 'services.social_network.title'.tr();
|
||||
return 'social_network.title'.tr();
|
||||
case ServiceTypes.gitea:
|
||||
return 'services.git.title'.tr();
|
||||
return 'git.title'.tr();
|
||||
case ServiceTypes.ocserv:
|
||||
return 'services.vpn.title'.tr();
|
||||
return 'vpn.title'.tr();
|
||||
}
|
||||
}
|
||||
|
||||
String get subtitle {
|
||||
switch (this) {
|
||||
case ServiceTypes.mailserver:
|
||||
return 'services.mail.subtitle'.tr();
|
||||
return 'mail.subtitle'.tr();
|
||||
case ServiceTypes.bitwarden:
|
||||
return 'services.password_manager.subtitle'.tr();
|
||||
return 'password_manager.subtitle'.tr();
|
||||
case ServiceTypes.jitsi:
|
||||
return 'services.video.subtitle'.tr();
|
||||
return 'video.subtitle'.tr();
|
||||
case ServiceTypes.nextcloud:
|
||||
return 'services.cloud.subtitle'.tr();
|
||||
return 'cloud.subtitle'.tr();
|
||||
case ServiceTypes.pleroma:
|
||||
return 'services.social_network.subtitle'.tr();
|
||||
return 'social_network.subtitle'.tr();
|
||||
case ServiceTypes.gitea:
|
||||
return 'services.git.subtitle'.tr();
|
||||
return 'git.subtitle'.tr();
|
||||
case ServiceTypes.ocserv:
|
||||
return 'services.vpn.subtitle'.tr();
|
||||
return 'vpn.subtitle'.tr();
|
||||
}
|
||||
}
|
||||
|
||||
String get loginInfo {
|
||||
switch (this) {
|
||||
case ServiceTypes.mailserver:
|
||||
return 'services.mail.login_info'.tr();
|
||||
return 'mail.login_info'.tr();
|
||||
case ServiceTypes.bitwarden:
|
||||
return 'services.password_manager.login_info'.tr();
|
||||
return 'password_manager.login_info'.tr();
|
||||
case ServiceTypes.jitsi:
|
||||
return 'services.video.login_info'.tr();
|
||||
return 'video.login_info'.tr();
|
||||
case ServiceTypes.nextcloud:
|
||||
return 'services.cloud.login_info'.tr();
|
||||
return 'cloud.login_info'.tr();
|
||||
case ServiceTypes.pleroma:
|
||||
return 'services.social_network.login_info'.tr();
|
||||
return 'social_network.login_info'.tr();
|
||||
case ServiceTypes.gitea:
|
||||
return 'services.git.login_info'.tr();
|
||||
return 'git.login_info'.tr();
|
||||
case ServiceTypes.ocserv:
|
||||
return '';
|
||||
}
|
||||
|
|
|
@ -135,7 +135,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
|||
} else {
|
||||
await api.uploadBackblazeConfig(bucket);
|
||||
emit(state.copyWith(isInitialized: true, preventActions: false));
|
||||
getIt<NavigationService>().showSnackBar('providers.backup.reuploadedKey');
|
||||
getIt<NavigationService>().showSnackBar('backup.reuploaded_key');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -173,8 +173,7 @@ class BackupsCubit extends ServerInstallationDependendCubit<BackupsState> {
|
|||
Future<void> forceUpdateBackups() async {
|
||||
emit(state.copyWith(preventActions: true));
|
||||
await api.forceBackupListReload();
|
||||
getIt<NavigationService>()
|
||||
.showSnackBar('providers.backup.refetchingList'.tr());
|
||||
getIt<NavigationService>().showSnackBar('backup.refetching_list'.tr());
|
||||
emit(state.copyWith(preventActions: false));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
newJobsList.addAll(jobsState.clientJobList);
|
||||
}
|
||||
newJobsList.add(job);
|
||||
getIt<NavigationService>().showSnackBar('jobs.jobAdded'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.job_added'.tr());
|
||||
emit(JobsStateWithJobs(newJobsList));
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,7 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
removeJob(removingJob.id);
|
||||
} else {
|
||||
newJobsList.add(job);
|
||||
getIt<NavigationService>().showSnackBar('jobs.jobAdded'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.job_added'.tr());
|
||||
emit(JobsStateWithJobs(newJobsList));
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
newJobsList.any((final el) => el is CreateSSHKeyJob);
|
||||
if (!isExistInJobList) {
|
||||
newJobsList.add(job);
|
||||
getIt<NavigationService>().showSnackBar('jobs.jobAdded'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.job_added'.tr());
|
||||
emit(JobsStateWithJobs(newJobsList));
|
||||
}
|
||||
}
|
||||
|
@ -76,9 +76,9 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
emit(JobsStateLoading());
|
||||
final bool isSuccessful = await api.reboot();
|
||||
if (isSuccessful) {
|
||||
getIt<NavigationService>().showSnackBar('jobs.rebootSuccess'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.reboot_success'.tr());
|
||||
} else {
|
||||
getIt<NavigationService>().showSnackBar('jobs.rebootFailed'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.reboot_failed'.tr());
|
||||
}
|
||||
emit(JobsStateEmpty());
|
||||
}
|
||||
|
@ -89,12 +89,12 @@ class JobsCubit extends Cubit<JobsState> {
|
|||
final bool isSuccessful = await api.upgrade();
|
||||
if (isSuccessful) {
|
||||
if (!isPullSuccessful) {
|
||||
getIt<NavigationService>().showSnackBar('jobs.configPullFailed'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.config_pull_failed'.tr());
|
||||
} else {
|
||||
getIt<NavigationService>().showSnackBar('jobs.upgradeSuccess'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.upgrade_success'.tr());
|
||||
}
|
||||
} else {
|
||||
getIt<NavigationService>().showSnackBar('jobs.upgradeFailed'.tr());
|
||||
getIt<NavigationService>().showSnackBar('jobs.upgrade_failed'.tr());
|
||||
}
|
||||
emit(JobsStateEmpty());
|
||||
}
|
||||
|
|
|
@ -51,8 +51,7 @@ class DnsRecordsCubit
|
|||
_getDesiredDnsRecords(domain.domainName, ipAddress, dkimPublicKey);
|
||||
final List<DesiredDnsRecord> foundRecords = [];
|
||||
for (final DesiredDnsRecord record in desiredRecords) {
|
||||
if (record.description ==
|
||||
'providers.domain.record_description.dkim') {
|
||||
if (record.description == 'record.dkim') {
|
||||
final DnsRecord foundRecord = records.firstWhere(
|
||||
(final r) => r.name == record.name && r.type == record.type,
|
||||
orElse: () => DnsRecord(
|
||||
|
@ -146,61 +145,61 @@ class DnsRecordsCubit
|
|||
DesiredDnsRecord(
|
||||
name: domainName,
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.root',
|
||||
description: 'record.root',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: 'api.$domainName',
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.api',
|
||||
description: 'record.api',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: 'cloud.$domainName',
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.cloud',
|
||||
description: 'record.cloud',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: 'git.$domainName',
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.git',
|
||||
description: 'record.git',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: 'meet.$domainName',
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.meet',
|
||||
description: 'record.meet',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: 'social.$domainName',
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.social',
|
||||
description: 'record.social',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: 'password.$domainName',
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.password',
|
||||
description: 'record.password',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: 'vpn.$domainName',
|
||||
content: ipAddress,
|
||||
description: 'providers.domain.record_description.vpn',
|
||||
description: 'record.vpn',
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: domainName,
|
||||
content: domainName,
|
||||
description: 'providers.domain.record_description.mx',
|
||||
description: 'record.mx',
|
||||
type: 'MX',
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: '_dmarc.$domainName',
|
||||
content: 'v=DMARC1; p=none',
|
||||
description: 'providers.domain.record_description.dmarc',
|
||||
description: 'record.dmarc',
|
||||
type: 'TXT',
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
DesiredDnsRecord(
|
||||
name: domainName,
|
||||
content: 'v=spf1 a mx ip4:$ipAddress -all',
|
||||
description: 'providers.domain.record_description.spf',
|
||||
description: 'record.spf',
|
||||
type: 'TXT',
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
|
@ -208,7 +207,7 @@ class DnsRecordsCubit
|
|||
DesiredDnsRecord(
|
||||
name: 'selector._domainkey.$domainName',
|
||||
content: dkimPublicKey,
|
||||
description: 'providers.domain.record_description.dkim',
|
||||
description: 'record.dkim',
|
||||
type: 'TXT',
|
||||
category: DnsRecordsCategory.email,
|
||||
),
|
||||
|
|
|
@ -86,7 +86,7 @@ class ApiProviderVolumeCubit
|
|||
|
||||
if (!resized) {
|
||||
getIt<NavigationService>().showSnackBar(
|
||||
'providers.storage.extending_volume_error'.tr(),
|
||||
'storage.extending_volume_error'.tr(),
|
||||
);
|
||||
emit(state.copyWith(isResizing: false));
|
||||
return false;
|
||||
|
|
|
@ -250,8 +250,8 @@ class ServerInstallationRepository {
|
|||
final NavigationService nav = getIt.get<NavigationService>();
|
||||
nav.showPopUpDialog(
|
||||
BrandAlert(
|
||||
title: 'modals.1'.tr(),
|
||||
contentText: 'modals.2'.tr(),
|
||||
title: 'modals.already_exists'.tr(),
|
||||
contentText: 'modals.destroy_server'.tr(),
|
||||
actions: [
|
||||
ActionButton(
|
||||
text: 'basis.delete'.tr(),
|
||||
|
@ -291,11 +291,11 @@ class ServerInstallationRepository {
|
|||
final NavigationService nav = getIt.get<NavigationService>();
|
||||
nav.showPopUpDialog(
|
||||
BrandAlert(
|
||||
title: 'modals.1_1'.tr(),
|
||||
contentText: 'modals.2_2'.tr(),
|
||||
title: 'modals.unexpected_error'.tr(),
|
||||
contentText: 'modals.try_again'.tr(),
|
||||
actions: [
|
||||
ActionButton(
|
||||
text: 'modals.7'.tr(),
|
||||
text: 'modals.yes'.tr(),
|
||||
isRed: true,
|
||||
onPressed: () async {
|
||||
ServerHostingDetails? serverDetails;
|
||||
|
@ -353,9 +353,9 @@ class ServerInstallationRepository {
|
|||
nav.showPopUpDialog(
|
||||
BrandAlert(
|
||||
title: e.response!.data['errors'][0]['code'] == 1038
|
||||
? 'modals.10'.tr()
|
||||
: 'providers.domain.states.error'.tr(),
|
||||
contentText: 'modals.6'.tr(),
|
||||
? 'modals.you_cant_use_this_api'.tr()
|
||||
: 'domain.states.error'.tr(),
|
||||
contentText: 'modals.delete_server_volume'.tr(),
|
||||
actions: [
|
||||
ActionButton(
|
||||
text: 'basis.delete'.tr(),
|
||||
|
|
|
@ -28,11 +28,11 @@ class DiskSize {
|
|||
if (byte < 1024) {
|
||||
return '${byte.toStringAsFixed(0)} ${tr('bytes')}';
|
||||
} else if (byte < 1024 * 1024) {
|
||||
return 'providers.storage.kb'.tr(args: [kibibyte.toStringAsFixed(1)]);
|
||||
return 'storage.kb'.tr(args: [kibibyte.toStringAsFixed(1)]);
|
||||
} else if (byte < 1024 * 1024 * 1024) {
|
||||
return 'providers.storage.mb'.tr(args: [mebibyte.toStringAsFixed(1)]);
|
||||
return 'storage.mb'.tr(args: [mebibyte.toStringAsFixed(1)]);
|
||||
} else {
|
||||
return 'providers.storage.gb'.tr(args: [gibibyte.toStringAsFixed(1)]);
|
||||
return 'storage.gb'.tr(args: [gibibyte.toStringAsFixed(1)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ class RebuildServerJob extends ClientJob {
|
|||
class CreateUserJob extends ClientJob {
|
||||
CreateUserJob({
|
||||
required this.user,
|
||||
}) : super(title: '${"jobs.createUser".tr()} ${user.login}');
|
||||
}) : super(title: '${"jobs.create_user".tr()} ${user.login}');
|
||||
|
||||
final User user;
|
||||
|
||||
|
@ -41,7 +41,7 @@ class CreateUserJob extends ClientJob {
|
|||
class ResetUserPasswordJob extends ClientJob {
|
||||
ResetUserPasswordJob({
|
||||
required this.user,
|
||||
}) : super(title: '${"jobs.resetUserPassword".tr()} ${user.login}');
|
||||
}) : super(title: '${"jobs.reset_user_password".tr()} ${user.login}');
|
||||
|
||||
final User user;
|
||||
|
||||
|
@ -52,7 +52,7 @@ class ResetUserPasswordJob extends ClientJob {
|
|||
class DeleteUserJob extends ClientJob {
|
||||
DeleteUserJob({
|
||||
required this.user,
|
||||
}) : super(title: '${"jobs.deleteUser".tr()} ${user.login}');
|
||||
}) : super(title: '${"jobs.delete_user".tr()} ${user.login}');
|
||||
|
||||
final User user;
|
||||
|
||||
|
@ -78,7 +78,7 @@ class ServiceToggleJob extends ToggleJob {
|
|||
required this.needToTurnOn,
|
||||
}) : super(
|
||||
title:
|
||||
'${needToTurnOn ? "jobs.serviceTurnOn".tr() : "jobs.serviceTurnOff".tr()} ${type.title}',
|
||||
'${needToTurnOn ? "jobs.service_turn_on".tr() : "jobs.service_turn_off".tr()} ${type.title}',
|
||||
);
|
||||
|
||||
final bool needToTurnOn;
|
||||
|
|
|
@ -43,7 +43,7 @@ class JobsContent extends StatelessWidget {
|
|||
const SizedBox(height: 80),
|
||||
BrandButton.rised(
|
||||
onPressed: () => context.read<JobsCubit>().upgradeServer(),
|
||||
text: 'jobs.upgradeServer'.tr(),
|
||||
text: 'jobs.upgrade_server'.tr(),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BrandButton.text(
|
||||
|
@ -51,8 +51,8 @@ class JobsContent extends StatelessWidget {
|
|||
final NavigationService nav = getIt<NavigationService>();
|
||||
nav.showPopUpDialog(
|
||||
BrandAlert(
|
||||
title: 'jobs.rebootServer'.tr(),
|
||||
contentText: 'modals.3'.tr(),
|
||||
title: 'jobs.reboot_server'.tr(),
|
||||
contentText: 'modals.are_you_sure'.tr(),
|
||||
actions: [
|
||||
ActionButton(
|
||||
text: 'basis.cancel'.tr(),
|
||||
|
@ -60,13 +60,13 @@ class JobsContent extends StatelessWidget {
|
|||
ActionButton(
|
||||
onPressed: () =>
|
||||
{context.read<JobsCubit>().rebootServer()},
|
||||
text: 'modals.9'.tr(),
|
||||
text: 'modals.reboot'.tr(),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
title: 'jobs.rebootServer'.tr(),
|
||||
title: 'jobs.reboot_server'.tr(),
|
||||
),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ class NotReadyCard extends StatelessWidget {
|
|||
text: TextSpan(
|
||||
children: [
|
||||
TextSpan(
|
||||
text: 'not_ready_card.1'.tr(),
|
||||
text: 'not_ready_card.begin'.tr(),
|
||||
style: const TextStyle(color: BrandColors.white),
|
||||
),
|
||||
WidgetSpan(
|
||||
|
@ -32,7 +32,7 @@ class NotReadyCard extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
child: Text(
|
||||
'not_ready_card.2'.tr(),
|
||||
'not_ready_card.insertion'.tr(),
|
||||
style: body1Style.copyWith(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
@ -44,7 +44,7 @@ class NotReadyCard extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
TextSpan(
|
||||
text: 'not_ready_card.3'.tr(),
|
||||
text: 'not_ready_card.end'.tr(),
|
||||
style: const TextStyle(color: BrandColors.white),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -17,12 +17,12 @@ class ServerStorageListItem extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(final BuildContext context) => ConsumptionListItem(
|
||||
title: 'providers.storage.disk_usage'.tr(
|
||||
title: 'storage.disk_usage'.tr(
|
||||
args: [
|
||||
volume.sizeUsed.toString(),
|
||||
],
|
||||
),
|
||||
subtitle: 'providers.storage.disk_total'.tr(
|
||||
subtitle: 'storage.disk_total'.tr(
|
||||
args: [
|
||||
volume.sizeTotal.toString(),
|
||||
volume.displayName,
|
||||
|
|
|
@ -46,8 +46,8 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
|
||||
return BrandHeroScreen(
|
||||
heroIcon: BrandIcons.save,
|
||||
heroTitle: 'providers.backup.card_title'.tr(),
|
||||
heroSubtitle: 'providers.backup.bottom_sheet.1'.tr(),
|
||||
heroTitle: 'backup.card_title'.tr(),
|
||||
heroSubtitle: 'backup.description'.tr(),
|
||||
children: [
|
||||
if (isReady && !isBackupInitialized)
|
||||
BrandButton.rised(
|
||||
|
@ -56,10 +56,10 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
: () async {
|
||||
await context.read<BackupsCubit>().createBucket();
|
||||
},
|
||||
text: 'providers.backup.initialize'.tr(),
|
||||
text: 'backup.initialize'.tr(),
|
||||
),
|
||||
if (backupStatus == BackupStatusEnum.initializing)
|
||||
BrandText.body1('providers.backup.waitingForRebuild'.tr()),
|
||||
BrandText.body1('backup.waiting_for_rebuild'.tr()),
|
||||
if (backupStatus != BackupStatusEnum.initializing &&
|
||||
backupStatus != BackupStatusEnum.noKey)
|
||||
OutlinedCard(
|
||||
|
@ -77,14 +77,14 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
Icons.add_circle_outline_rounded,
|
||||
),
|
||||
title: Text(
|
||||
'providers.backup.create_new'.tr(),
|
||||
'backup.create_new'.tr(),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
if (backupStatus == BackupStatusEnum.backingUp)
|
||||
ListTile(
|
||||
title: Text(
|
||||
'providers.backup.creating'.tr(
|
||||
'backup.creating'.tr(
|
||||
args: [(backupProgress * 100).round().toString()],
|
||||
),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
|
@ -97,7 +97,7 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
if (backupStatus == BackupStatusEnum.restoring)
|
||||
ListTile(
|
||||
title: Text(
|
||||
'providers.backup.restoring'.tr(
|
||||
'backup.restoring'.tr(
|
||||
args: [(backupProgress * 100).round().toString()],
|
||||
),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
|
@ -113,7 +113,7 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
color: Theme.of(context).colorScheme.error,
|
||||
),
|
||||
title: Text(
|
||||
'providers.backup.error_pending'.tr(),
|
||||
'backup.error_pending'.tr(),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
|
@ -135,7 +135,7 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
Icons.refresh,
|
||||
),
|
||||
title: Text(
|
||||
'providers.backup.restore'.tr(),
|
||||
'backup.restore'.tr(),
|
||||
style: Theme.of(context).textTheme.headline6,
|
||||
),
|
||||
),
|
||||
|
@ -147,7 +147,7 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
leading: const Icon(
|
||||
Icons.error_outline,
|
||||
),
|
||||
title: Text('providers.backup.no_backups'.tr()),
|
||||
title: Text('backup.no_backups'.tr()),
|
||||
),
|
||||
if (backups.isNotEmpty)
|
||||
Column(
|
||||
|
@ -161,10 +161,8 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
getIt<NavigationService>();
|
||||
nav.showPopUpDialog(
|
||||
BrandAlert(
|
||||
title:
|
||||
'providers.backup.restoring'.tr(),
|
||||
contentText:
|
||||
'providers.backup.restore_alert'.tr(
|
||||
title: 'backup.restoring'.tr(),
|
||||
contentText: 'backup.restore_alert'.tr(
|
||||
args: [backup.time.toString()],
|
||||
),
|
||||
actions: [
|
||||
|
@ -200,7 +198,7 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
children: [
|
||||
ListTile(
|
||||
title: Text(
|
||||
'providers.backup.refresh'.tr(),
|
||||
'backup.refresh'.tr(),
|
||||
),
|
||||
onTap: refreshing
|
||||
? null
|
||||
|
@ -215,7 +213,7 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
),
|
||||
ListTile(
|
||||
title: Text(
|
||||
'providers.backup.refetchBackups'.tr(),
|
||||
'backup.refetch_backups'.tr(),
|
||||
),
|
||||
onTap: preventActions
|
||||
? null
|
||||
|
@ -230,7 +228,7 @@ class _BackupDetailsState extends State<BackupDetails>
|
|||
),
|
||||
ListTile(
|
||||
title: Text(
|
||||
'providers.backup.reuploadKey'.tr(),
|
||||
'backup.reupload_key'.tr(),
|
||||
),
|
||||
onTap: preventActions
|
||||
? null
|
||||
|
|
|
@ -28,7 +28,7 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
bool isError = false;
|
||||
switch (dnsState) {
|
||||
case DnsRecordsStatus.uninitialized:
|
||||
description = 'providers.domain.states.uninitialized'.tr();
|
||||
description = 'domain.states.uninitialized'.tr();
|
||||
icon = const Icon(
|
||||
Icons.refresh,
|
||||
size: 24.0,
|
||||
|
@ -36,7 +36,7 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
isError = false;
|
||||
break;
|
||||
case DnsRecordsStatus.refreshing:
|
||||
description = 'providers.domain.states.refreshing'.tr();
|
||||
description = 'domain.states.refreshing'.tr();
|
||||
icon = const Icon(
|
||||
Icons.refresh,
|
||||
size: 24.0,
|
||||
|
@ -44,7 +44,7 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
isError = false;
|
||||
break;
|
||||
case DnsRecordsStatus.good:
|
||||
description = 'providers.domain.states.ok'.tr();
|
||||
description = 'domain.states.ok'.tr();
|
||||
icon = const Icon(
|
||||
Icons.check_circle_outline,
|
||||
size: 24.0,
|
||||
|
@ -52,8 +52,8 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
isError = false;
|
||||
break;
|
||||
case DnsRecordsStatus.error:
|
||||
description = 'providers.domain.states.error'.tr();
|
||||
subtitle = 'providers.domain.states.error_subtitle'.tr();
|
||||
description = 'domain.states.error'.tr();
|
||||
subtitle = 'domain.states.error_subtitle'.tr();
|
||||
icon = const Icon(
|
||||
Icons.error_outline,
|
||||
size: 24.0,
|
||||
|
@ -93,7 +93,7 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
hasBackButton: true,
|
||||
headerTitle: '',
|
||||
heroIcon: BrandIcons.globe,
|
||||
heroTitle: 'providers.domain.screen_title'.tr(),
|
||||
heroTitle: 'domain.screen_title'.tr(),
|
||||
heroSubtitle: 'not_ready_card.in_menu'.tr(),
|
||||
children: const [],
|
||||
);
|
||||
|
@ -107,7 +107,7 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
hasBackButton: true,
|
||||
heroSubtitle: domain,
|
||||
heroIcon: BrandIcons.globe,
|
||||
heroTitle: 'providers.domain.screen_title'.tr(),
|
||||
heroTitle: 'domain.screen_title'.tr(),
|
||||
children: <Widget>[
|
||||
_getStateCard(dnsCubit.dnsState, () {
|
||||
context.read<DnsRecordsCubit>().fix();
|
||||
|
@ -115,13 +115,13 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
const SizedBox(height: 16.0),
|
||||
ListTile(
|
||||
title: Text(
|
||||
'providers.domain.cards.services.title'.tr(),
|
||||
'domain.services_title'.tr(),
|
||||
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
'providers.domain.cards.services.subtitle'.tr(),
|
||||
'domain.services_subtitle'.tr(),
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
),
|
||||
|
@ -160,13 +160,13 @@ class _DnsDetailsPageState extends State<DnsDetailsPage> {
|
|||
const SizedBox(height: 16.0),
|
||||
ListTile(
|
||||
title: Text(
|
||||
'providers.domain.cards.email.title'.tr(),
|
||||
'domain.email_title'.tr(),
|
||||
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
),
|
||||
),
|
||||
subtitle: Text(
|
||||
'providers.domain.cards.email.subtitle'.tr(),
|
||||
'domain.email_subtitle'.tr(),
|
||||
style: Theme.of(context).textTheme.labelMedium,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -6,16 +6,17 @@ import 'package:selfprivacy/ui/components/brand_text/brand_text.dart';
|
|||
import 'package:package_info/package_info.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
class InfoPage extends StatelessWidget {
|
||||
const InfoPage({final super.key});
|
||||
class AboutApplicationPage extends StatelessWidget {
|
||||
const AboutApplicationPage({final super.key});
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(52),
|
||||
child:
|
||||
BrandHeader(title: 'more.about_app'.tr(), hasBackButton: true),
|
||||
child: BrandHeader(
|
||||
title: 'about_application_page.title'.tr(),
|
||||
hasBackButton: true),
|
||||
),
|
||||
body: ListView(
|
||||
padding: paddingH15V0,
|
||||
|
@ -24,14 +25,14 @@ class InfoPage extends StatelessWidget {
|
|||
FutureBuilder(
|
||||
future: _packageVersion(),
|
||||
builder: (final context, final snapshot) => BrandText.body1(
|
||||
'more.about_app_page.application_version_text'
|
||||
'about_application_page.application_version_text'
|
||||
.tr(args: [snapshot.data.toString()]),
|
||||
),
|
||||
),
|
||||
FutureBuilder(
|
||||
future: _apiVersion(),
|
||||
builder: (final context, final snapshot) => BrandText.body1(
|
||||
'more.about_app_page.api_version_text'
|
||||
'about_application_page.api_version_text'
|
||||
.tr(args: [snapshot.data.toString()]),
|
||||
),
|
||||
),
|
|
@ -4,8 +4,8 @@ import 'package:selfprivacy/ui/components/brand_header/brand_header.dart';
|
|||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:selfprivacy/ui/components/brand_md/brand_md.dart';
|
||||
|
||||
class AboutPage extends StatelessWidget {
|
||||
const AboutPage({final super.key});
|
||||
class AboutUsPage extends StatelessWidget {
|
||||
const AboutUsPage({final super.key});
|
||||
|
||||
@override
|
||||
Widget build(final BuildContext context) => SafeArea(
|
||||
|
@ -13,7 +13,7 @@ class AboutPage extends StatelessWidget {
|
|||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(52),
|
||||
child: BrandHeader(
|
||||
title: 'more.about_project'.tr(),
|
||||
title: 'about_us_page.title'.tr(),
|
||||
hasBackButton: true,
|
||||
),
|
||||
),
|
|
@ -30,7 +30,7 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(52),
|
||||
child: BrandHeader(
|
||||
title: 'more.settings.title'.tr(),
|
||||
title: 'application_settings.title'.tr(),
|
||||
hasBackButton: true,
|
||||
),
|
||||
),
|
||||
|
@ -46,8 +46,9 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
children: [
|
||||
Flexible(
|
||||
child: _TextColumn(
|
||||
title: 'more.settings.1'.tr(),
|
||||
value: 'more.settings.2'.tr(),
|
||||
title: 'application_settings.dark_theme_title'.tr(),
|
||||
value:
|
||||
'application_settings.dark_theme_description'.tr(),
|
||||
hasWarning: false,
|
||||
),
|
||||
),
|
||||
|
@ -70,8 +71,9 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
children: [
|
||||
Flexible(
|
||||
child: _TextColumn(
|
||||
title: 'more.settings.3'.tr(),
|
||||
value: 'more.settings.4'.tr(),
|
||||
title: 'application_settings.reset_config_title'.tr(),
|
||||
value: 'application_settings.reset_config_description'
|
||||
.tr(),
|
||||
hasWarning: false,
|
||||
),
|
||||
),
|
||||
|
@ -91,11 +93,11 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (final _) => BrandAlert(
|
||||
title: 'modals.3'.tr(),
|
||||
contentText: 'modals.4'.tr(),
|
||||
title: 'modals.are_you_sure'.tr(),
|
||||
contentText: 'modals.purge_all_keys'.tr(),
|
||||
actions: [
|
||||
ActionButton(
|
||||
text: 'modals.5'.tr(),
|
||||
text: 'modals.purge_all_keys_confirm'.tr(),
|
||||
isRed: true,
|
||||
onPressed: () {
|
||||
context
|
||||
|
@ -135,8 +137,8 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
children: [
|
||||
Flexible(
|
||||
child: _TextColumn(
|
||||
title: 'more.settings.5'.tr(),
|
||||
value: 'more.settings.6'.tr(),
|
||||
title: 'application_settings.delete_server_title'.tr(),
|
||||
value: 'application_settings.delete_server_description'.tr(),
|
||||
hasWarning: false,
|
||||
),
|
||||
),
|
||||
|
@ -151,11 +153,11 @@ class _AppSettingsPageState extends State<AppSettingsPage> {
|
|||
showDialog(
|
||||
context: context,
|
||||
builder: (final _) => BrandAlert(
|
||||
title: 'modals.3'.tr(),
|
||||
contentText: 'modals.6'.tr(),
|
||||
title: 'modals.are_you_sure'.tr(),
|
||||
contentText: 'modals.delete_server_volume'.tr(),
|
||||
actions: [
|
||||
ActionButton(
|
||||
text: 'modals.7'.tr(),
|
||||
text: 'modals.yes'.tr(),
|
||||
isRed: true,
|
||||
onPressed: () async {
|
||||
showDialog(
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:collection';
|
||||
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:selfprivacy/config/brand_colors.dart';
|
||||
import 'package:selfprivacy/config/get_it_config.dart';
|
||||
|
@ -35,8 +36,11 @@ class _ConsoleState extends State<Console> {
|
|||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(53),
|
||||
child: Column(
|
||||
children: const [
|
||||
BrandHeader(title: 'Console', hasBackButton: true)
|
||||
children: [
|
||||
BrandHeader(
|
||||
title: 'console_page.title'.tr(),
|
||||
hasBackButton: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
@ -90,12 +94,12 @@ class _ConsoleState extends State<Console> {
|
|||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: const [
|
||||
Text('Waiting for initialisation'),
|
||||
SizedBox(
|
||||
children: [
|
||||
Text('console_page.waiting'.tr()),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
CircularProgressIndicator(),
|
||||
const CircularProgressIndicator(),
|
||||
],
|
||||
);
|
||||
}
|
|
@ -17,10 +17,10 @@ import 'package:selfprivacy/ui/pages/root_route.dart';
|
|||
import 'package:selfprivacy/ui/pages/users/users.dart';
|
||||
import 'package:selfprivacy/utils/route_transitions/basic.dart';
|
||||
|
||||
import 'package:selfprivacy/ui/pages/more/about/about.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/about_us.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/app_settings/app_setting.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/console/console.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/info/info.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/console.dart';
|
||||
import 'package:selfprivacy/ui/pages/more/about_application.dart';
|
||||
|
||||
class MorePage extends StatelessWidget {
|
||||
const MorePage({final super.key});
|
||||
|
@ -48,7 +48,7 @@ class MorePage extends StatelessWidget {
|
|||
children: [
|
||||
if (isReady && usesBinds != null && !usesBinds)
|
||||
_MoreMenuItem(
|
||||
title: 'providers.storage.start_migration_button'.tr(),
|
||||
title: 'storage.start_migration_button'.tr(),
|
||||
iconData: Icons.drive_file_move_outline,
|
||||
goTo: ServicesMigrationPage(
|
||||
diskStatus: context
|
||||
|
@ -70,12 +70,12 @@ class MorePage extends StatelessWidget {
|
|||
.toList(),
|
||||
isMigration: true,
|
||||
),
|
||||
subtitle: 'providers.storage.data_migration_notice'.tr(),
|
||||
subtitle: 'storage.data_migration_notice'.tr(),
|
||||
accent: true,
|
||||
),
|
||||
if (!isReady)
|
||||
_MoreMenuItem(
|
||||
title: 'more.configuration_wizard'.tr(),
|
||||
title: 'more_page.configuration_wizard'.tr(),
|
||||
iconData: Icons.change_history_outlined,
|
||||
goTo: const InitializingPage(),
|
||||
subtitle: 'not_ready_card.in_menu'.tr(),
|
||||
|
@ -83,7 +83,7 @@ class MorePage extends StatelessWidget {
|
|||
),
|
||||
if (isReady)
|
||||
_MoreMenuItem(
|
||||
title: 'more.create_ssh_key'.tr(),
|
||||
title: 'more_page.create_ssh_key'.tr(),
|
||||
iconData: Ionicons.key_outline,
|
||||
goTo: const UserDetails(
|
||||
login: 'root',
|
||||
|
@ -102,28 +102,28 @@ class MorePage extends StatelessWidget {
|
|||
title: 'devices.main_screen.header'.tr(),
|
||||
),
|
||||
_MoreMenuItem(
|
||||
title: 'more.settings.title'.tr(),
|
||||
title: 'more_page.application_settings'.tr(),
|
||||
iconData: Icons.settings_outlined,
|
||||
goTo: const AppSettingsPage(),
|
||||
),
|
||||
_MoreMenuItem(
|
||||
title: 'more.about_project'.tr(),
|
||||
title: 'more_page.about_project'.tr(),
|
||||
iconData: BrandIcons.engineer,
|
||||
goTo: const AboutPage(),
|
||||
goTo: const AboutUsPage(),
|
||||
),
|
||||
_MoreMenuItem(
|
||||
title: 'more.about_app'.tr(),
|
||||
title: 'more_page.about_application'.tr(),
|
||||
iconData: BrandIcons.fire,
|
||||
goTo: const InfoPage(),
|
||||
goTo: const AboutApplicationPage(),
|
||||
),
|
||||
if (!isReady)
|
||||
_MoreMenuItem(
|
||||
title: 'more.onboarding'.tr(),
|
||||
title: 'more_page.onboarding'.tr(),
|
||||
iconData: BrandIcons.start,
|
||||
goTo: const OnboardingPage(nextPage: RootPage()),
|
||||
),
|
||||
_MoreMenuItem(
|
||||
title: 'more.console'.tr(),
|
||||
title: 'more_page.console'.tr(),
|
||||
iconData: BrandIcons.terminal,
|
||||
goTo: const Console(),
|
||||
),
|
||||
|
|
|
@ -64,7 +64,7 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(52),
|
||||
child: BrandHeader(
|
||||
title: 'providers.page_title'.tr(),
|
||||
title: 'basis.providers_title'.tr(),
|
||||
),
|
||||
),
|
||||
body: ListView(
|
||||
|
@ -77,10 +77,10 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
_Card(
|
||||
state: getServerStatus(),
|
||||
icon: BrandIcons.server,
|
||||
title: 'providers.server.card_title'.tr(),
|
||||
title: 'server.card_title'.tr(),
|
||||
subtitle: diskStatus.isDiskOkay
|
||||
? 'providers.storage.status_ok'.tr()
|
||||
: 'providers.storage.status_error'.tr(),
|
||||
? 'storage.status_ok'.tr()
|
||||
: 'storage.status_error'.tr(),
|
||||
onTap: () => Navigator.of(context)
|
||||
.push(materialRoute(const ServerDetailsScreen())),
|
||||
),
|
||||
|
@ -88,7 +88,7 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
_Card(
|
||||
state: getDnsStatus(),
|
||||
icon: BrandIcons.globe,
|
||||
title: 'providers.domain.screen_title'.tr(),
|
||||
title: 'domain.screen_title'.tr(),
|
||||
subtitle: appConfig.isDomainSelected
|
||||
? appConfig.serverDomain!.domainName
|
||||
: '',
|
||||
|
@ -106,10 +106,8 @@ class _ProvidersPageState extends State<ProvidersPage> {
|
|||
? StateType.stable
|
||||
: StateType.uninitialized,
|
||||
icon: BrandIcons.save,
|
||||
title: 'providers.backup.card_title'.tr(),
|
||||
subtitle: isBackupInitialized
|
||||
? 'providers.backup.card_subtitle'.tr()
|
||||
: '',
|
||||
title: 'backup.card_title'.tr(),
|
||||
subtitle: isBackupInitialized ? 'backup.card_subtitle'.tr() : '',
|
||||
onTap: () => Navigator.of(context)
|
||||
.push(materialRoute(const BackupDetails())),
|
||||
),
|
||||
|
|
|
@ -17,7 +17,7 @@ class _Chart extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'providers.server.chart.cpu_title'.tr(),
|
||||
'resource_chart.cpu_title'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
|
@ -50,7 +50,7 @@ class _Chart extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
'providers.server.chart.network_title'.tr(),
|
||||
'resource_chart.network_title'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color:
|
||||
Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
|
@ -59,12 +59,12 @@ class _Chart extends StatelessWidget {
|
|||
const Spacer(),
|
||||
Legend(
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
text: 'providers.server.chart.in'.tr(),
|
||||
text: 'resource_chart.in'.tr(),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
Legend(
|
||||
color: Theme.of(context).colorScheme.tertiary,
|
||||
text: 'providers.server.chart.out'.tr(),
|
||||
text: 'resource_chart.out'.tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -111,9 +111,9 @@ class _Chart extends StatelessWidget {
|
|||
}
|
||||
},
|
||||
titles: [
|
||||
'providers.server.chart.month'.tr(),
|
||||
'providers.server.chart.day'.tr(),
|
||||
'providers.server.chart.hour'.tr()
|
||||
'resource_chart.month'.tr(),
|
||||
'resource_chart.day'.tr(),
|
||||
'resource_chart.hour'.tr()
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
|
@ -51,7 +51,7 @@ class NetworkChart extends StatelessWidget {
|
|||
|
||||
res.add(
|
||||
LineTooltipItem(
|
||||
'${timeShown ? '' : DateFormat('HH:mm dd.MM.yyyy').format(date)} ${spot.barIndex == 0 ? 'providers.server.chart.in'.tr() : 'providers.server.chart.out'.tr()} ${DiskSize(byte: value.toInt()).toString()}',
|
||||
'${timeShown ? '' : DateFormat('HH:mm dd.MM.yyyy').format(date)} ${spot.barIndex == 0 ? 'resource_chart.in'.tr() : 'resource_chart.out'.tr()} ${DiskSize(byte: value.toInt()).toString()}',
|
||||
TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface,
|
||||
fontWeight: FontWeight.bold,
|
||||
|
|
|
@ -70,7 +70,7 @@ class _ServerDetailsScreenState extends State<ServerDetailsScreen>
|
|||
if (!isReady) {
|
||||
return BrandHeroScreen(
|
||||
heroIcon: BrandIcons.server,
|
||||
heroTitle: 'providers.server.card_title'.tr(),
|
||||
heroTitle: 'server.card_title'.tr(),
|
||||
heroSubtitle: 'not_ready_card.in_menu'.tr(),
|
||||
children: const [],
|
||||
);
|
||||
|
@ -80,8 +80,8 @@ class _ServerDetailsScreenState extends State<ServerDetailsScreen>
|
|||
create: (final context) => context.read<ServerDetailsCubit>()..check(),
|
||||
child: BrandHeroScreen(
|
||||
heroIcon: BrandIcons.server,
|
||||
heroTitle: 'providers.server.card_title'.tr(),
|
||||
heroSubtitle: 'providers.server.bottom_sheet.1'.tr(),
|
||||
heroTitle: 'server.card_title'.tr(),
|
||||
heroSubtitle: 'server.description'.tr(),
|
||||
children: [
|
||||
StorageCard(
|
||||
diskStatus: context.watch<ApiServerVolumeCubit>().state.diskStatus,
|
||||
|
@ -90,7 +90,7 @@ class _ServerDetailsScreenState extends State<ServerDetailsScreen>
|
|||
const _ServerSettings(),
|
||||
const Divider(height: 32),
|
||||
Text(
|
||||
'providers.server.resource_usage'.tr(),
|
||||
'server.resource_usage'.tr(),
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
|
|
@ -34,7 +34,7 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
onChanged: (final switched) {
|
||||
if (didSomethingChange == false) {
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgradeServer'.tr()),
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
}
|
||||
context
|
||||
|
@ -51,9 +51,9 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
didSomethingChange = true;
|
||||
});
|
||||
},
|
||||
title: Text('providers.server.settings.allow_autoupgrade'.tr()),
|
||||
title: Text('server.allow_autoupgrade'.tr()),
|
||||
subtitle: Text(
|
||||
'providers.server.settings.allow_autoupgrade_hint'.tr(),
|
||||
'server.allow_autoupgrade_hint'.tr(),
|
||||
),
|
||||
activeColor: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
|
@ -62,7 +62,7 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
onChanged: (final switched) {
|
||||
if (didSomethingChange == false) {
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgradeServer'.tr()),
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
}
|
||||
context
|
||||
|
@ -79,21 +79,21 @@ class _ServerSettingsState extends State<_ServerSettings> {
|
|||
didSomethingChange = true;
|
||||
});
|
||||
},
|
||||
title: Text('providers.server.settings.reboot_after_upgrade'.tr()),
|
||||
title: Text('server.reboot_after_upgrade'.tr()),
|
||||
subtitle: Text(
|
||||
'providers.server.settings.reboot_after_upgrade_hint'.tr(),
|
||||
'server.reboot_after_upgrade_hint'.tr(),
|
||||
),
|
||||
activeColor: Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
ListTile(
|
||||
title: Text('providers.server.settings.server_timezone'.tr()),
|
||||
title: Text('server.server_timezone'.tr()),
|
||||
subtitle: Text(
|
||||
serverDetailsState.serverTimezone.toString(),
|
||||
),
|
||||
onTap: () {
|
||||
if (didSomethingChange == false) {
|
||||
context.read<JobsCubit>().addJob(
|
||||
RebuildServerJob(title: 'jobs.upgradeServer'.tr()),
|
||||
RebuildServerJob(title: 'jobs.upgrade_server'.tr()),
|
||||
);
|
||||
}
|
||||
setState(() {
|
||||
|
|
|
@ -18,7 +18,7 @@ class _TextDetails extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: Text(
|
||||
'providers.server.bottom_sheet.2'.tr(),
|
||||
'server.general_information'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
),
|
||||
|
@ -27,34 +27,33 @@ class _TextDetails extends StatelessWidget {
|
|||
ListTileOnSurfaceVariant(
|
||||
leadingIcon: Icons.numbers_outlined,
|
||||
title: data.id.toString(),
|
||||
subtitle: 'providers.server.info.server_id'.tr(),
|
||||
subtitle: 'server.server_id'.tr(),
|
||||
),
|
||||
ListTileOnSurfaceVariant(
|
||||
leadingIcon: Icons.mode_standby_outlined,
|
||||
title: data.status.toString().split('.')[1].capitalize(),
|
||||
subtitle: 'providers.server.info.status'.tr(),
|
||||
subtitle: 'server.status'.tr(),
|
||||
),
|
||||
ListTileOnSurfaceVariant(
|
||||
leadingIcon: Icons.memory_outlined,
|
||||
title: 'providers.server.info.core_count'
|
||||
.plural(data.serverType.cores),
|
||||
subtitle: 'providers.server.info.cpu'.tr(),
|
||||
title: 'server.core_count'.plural(data.serverType.cores),
|
||||
subtitle: 'server.cpu'.tr(),
|
||||
),
|
||||
ListTileOnSurfaceVariant(
|
||||
leadingIcon: Icons.memory_outlined,
|
||||
title: '${data.serverType.memory.toString()} GB',
|
||||
subtitle: 'providers.server.info.ram'.tr(),
|
||||
subtitle: 'server.ram'.tr(),
|
||||
),
|
||||
ListTileOnSurfaceVariant(
|
||||
leadingIcon: Icons.euro_outlined,
|
||||
title: data.serverType.prices[1].monthly.toStringAsFixed(2),
|
||||
subtitle: 'providers.server.info.monthly_cost'.tr(),
|
||||
subtitle: 'server.monthly_cost'.tr(),
|
||||
),
|
||||
// Server location
|
||||
ListTileOnSurfaceVariant(
|
||||
leadingIcon: Icons.location_on_outlined,
|
||||
title: '${data.location.city}, ${data.location.country}',
|
||||
subtitle: 'providers.server.info.location'.tr(),
|
||||
subtitle: 'server.location'.tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
@ -50,7 +50,7 @@ class _SelectTimezoneState extends State<SelectTimezone> {
|
|||
appBar: PreferredSize(
|
||||
preferredSize: const Size.fromHeight(52),
|
||||
child: BrandHeader(
|
||||
title: 'providers.server.settings.select_timezone'.tr(),
|
||||
title: 'server.select_timezone'.tr(),
|
||||
hasBackButton: true,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -53,7 +53,7 @@ class _MigrationProcessPageState extends State<MigrationProcessPage> {
|
|||
if (job.finishedAt != null) const SizedBox(height: 16),
|
||||
if (job.finishedAt != null)
|
||||
FilledButton(
|
||||
title: 'providers.storage.migration_done'.tr(),
|
||||
title: 'storage.migration_done'.tr(),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
materialRoute(const RootPage()),
|
||||
|
@ -65,7 +65,7 @@ class _MigrationProcessPageState extends State<MigrationProcessPage> {
|
|||
}
|
||||
return BrandHeroScreen(
|
||||
hasBackButton: false,
|
||||
heroTitle: 'providers.storage.migration_process'.tr(),
|
||||
heroTitle: 'storage.migration_process'.tr(),
|
||||
heroSubtitle: subtitle,
|
||||
children: [
|
||||
BrandLinearIndicator(
|
||||
|
|
|
@ -100,7 +100,7 @@ class _ServicesMigrationPageState extends State<ServicesMigrationPage> {
|
|||
child: Column(
|
||||
children: [
|
||||
BrandHeader(
|
||||
title: 'providers.storage.data_migration_title'.tr(),
|
||||
title: 'storage.data_migration_title'.tr(),
|
||||
hasBackButton: true,
|
||||
),
|
||||
Padding(
|
||||
|
@ -158,13 +158,13 @@ class _ServicesMigrationPageState extends State<ServicesMigrationPage> {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: InfoBox(
|
||||
text: 'providers.storage.data_migration_notice'.tr(),
|
||||
text: 'storage.data_migration_notice'.tr(),
|
||||
isWarning: true,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
title: 'providers.storage.start_migration_button'.tr(),
|
||||
title: 'storage.start_migration_button'.tr(),
|
||||
onPressed: () {
|
||||
if (widget.isMigration) {
|
||||
context.read<ServerJobsCubit>().migrateToBinds(
|
||||
|
|
|
@ -57,9 +57,8 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
if (!snapshot.hasData) {
|
||||
return BrandHeroScreen(
|
||||
hasBackButton: true,
|
||||
heroTitle: 'providers.storage.extending_volume_title'.tr(),
|
||||
heroSubtitle:
|
||||
'providers.storage.extending_volume_description'.tr(),
|
||||
heroTitle: 'storage.extending_volume_title'.tr(),
|
||||
heroSubtitle: 'storage.extending_volume_description'.tr(),
|
||||
children: const [
|
||||
SizedBox(height: 16),
|
||||
Center(
|
||||
|
@ -84,8 +83,8 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
|
||||
return BrandHeroScreen(
|
||||
hasBackButton: true,
|
||||
heroTitle: 'providers.storage.extending_volume_title'.tr(),
|
||||
heroSubtitle: 'providers.storage.extending_volume_description'.tr(),
|
||||
heroTitle: 'storage.extending_volume_title'.tr(),
|
||||
heroSubtitle: 'storage.extending_volume_description'.tr(),
|
||||
children: [
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
|
@ -104,7 +103,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
errorText: _isError ? ' ' : null,
|
||||
labelText: 'providers.storage.size'.tr(),
|
||||
labelText: 'storage.size'.tr(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -120,7 +119,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
errorText: _isError ? ' ' : null,
|
||||
labelText: 'providers.storage.euro'.tr(),
|
||||
labelText: 'storage.euro'.tr(),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -140,7 +139,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
title: 'providers.storage.extend_volume_button.title'.tr(),
|
||||
title: 'storage.extend_volume_button.title'.tr(),
|
||||
onPressed: _isError
|
||||
? null
|
||||
: () {
|
||||
|
@ -169,7 +168,7 @@ class _ExtendingVolumePageState extends State<ExtendingVolumePage> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text('providers.storage.extending_volume_price_info'.tr()),
|
||||
Text('storage.extending_volume_price_info'.tr()),
|
||||
const SizedBox(height: 16),
|
||||
],
|
||||
);
|
||||
|
|
|
@ -32,14 +32,14 @@ class _ServerStoragePageState extends State<ServerStoragePage> {
|
|||
if (!isReady) {
|
||||
return BrandHeroScreen(
|
||||
hasBackButton: true,
|
||||
heroTitle: 'providers.storage.card_title'.tr(),
|
||||
heroTitle: 'storage.card_title'.tr(),
|
||||
children: const [],
|
||||
);
|
||||
}
|
||||
|
||||
return BrandHeroScreen(
|
||||
hasBackButton: true,
|
||||
heroTitle: 'providers.storage.card_title'.tr(),
|
||||
heroTitle: 'storage.card_title'.tr(),
|
||||
children: [
|
||||
// ...sections,
|
||||
...widget.diskStatus.diskVolumes
|
||||
|
@ -101,7 +101,7 @@ class ServerStorageSection extends StatelessWidget {
|
|||
if (volume.isResizable) ...[
|
||||
const SizedBox(height: 16),
|
||||
BrandOutlinedButton(
|
||||
title: 'providers.storage.extend_volume_button.title'.tr(),
|
||||
title: 'storage.extend_volume_button.title'.tr(),
|
||||
onPressed: () => Navigator.of(context).push(
|
||||
materialRoute(
|
||||
ExtendingVolumePage(
|
||||
|
|
|
@ -65,14 +65,14 @@ class StorageCard extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'providers.storage.card_title'.tr(),
|
||||
'storage.card_title'.tr(),
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
if (state != StateType.uninitialized)
|
||||
Text(
|
||||
diskStatus.isDiskOkay
|
||||
? 'providers.storage.status_ok'.tr()
|
||||
: 'providers.storage.status_error'.tr(),
|
||||
? 'storage.status_ok'.tr()
|
||||
: 'storage.status_error'.tr(),
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
),
|
||||
],
|
||||
|
|
|
@ -74,7 +74,7 @@ class _ServicePageState extends State<ServicePage> {
|
|||
onTap: () => _launchURL(service.url),
|
||||
leading: const Icon(Icons.open_in_browser),
|
||||
title: Text(
|
||||
'services.service_page.open_in_browser'.tr(),
|
||||
'service_page.open_in_browser'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
subtitle: Text(
|
||||
|
@ -92,7 +92,7 @@ class _ServicePageState extends State<ServicePage> {
|
|||
},
|
||||
leading: const Icon(Icons.restart_alt_outlined),
|
||||
title: Text(
|
||||
'services.service_page.restart'.tr(),
|
||||
'service_page.restart'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
enabled: !serviceDisabled && !serviceLocked,
|
||||
|
@ -110,8 +110,8 @@ class _ServicePageState extends State<ServicePage> {
|
|||
leading: const Icon(Icons.power_settings_new),
|
||||
title: Text(
|
||||
serviceDisabled
|
||||
? 'services.service_page.enable'.tr()
|
||||
: 'services.service_page.disable'.tr(),
|
||||
? 'service_page.enable'.tr()
|
||||
: 'service_page.disable'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
enabled: !serviceLocked,
|
||||
|
@ -132,11 +132,11 @@ class _ServicePageState extends State<ServicePage> {
|
|||
),
|
||||
leading: const Icon(Icons.drive_file_move_outlined),
|
||||
title: Text(
|
||||
'services.service_page.move'.tr(),
|
||||
'service_page.move'.tr(),
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
subtitle: Text(
|
||||
'services.service_page.uses'.tr(
|
||||
'service_page.uses'.tr(
|
||||
namedArgs: {
|
||||
'usage': service.storageUsage.used.toString(),
|
||||
'volume': context
|
||||
|
|
|
@ -67,7 +67,7 @@ class _ServicesPageState extends State<ServicesPage> {
|
|||
child: ListView(
|
||||
padding: paddingH15V0,
|
||||
children: [
|
||||
BrandText.body1('services.title'.tr()),
|
||||
BrandText.body1('basis.services_title'.tr()),
|
||||
const SizedBox(height: 24),
|
||||
if (!isReady) ...[const NotReadyCard(), const SizedBox(height: 24)],
|
||||
...ServiceTypes.values
|
||||
|
@ -218,7 +218,7 @@ class _Card extends StatelessWidget {
|
|||
sigmaY: 2,
|
||||
),
|
||||
child: BrandText.h2(
|
||||
'jobs.runJobs'.tr(),
|
||||
'jobs.run_jobs'.tr(),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
|
|
|
@ -154,9 +154,9 @@ class InitializingPage extends StatelessWidget {
|
|||
width: 150,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BrandText.h2('initializing.1'.tr()),
|
||||
BrandText.h2('initializing.connect_to_server'.tr()),
|
||||
const SizedBox(height: 10),
|
||||
BrandText.body2('initializing.2'.tr()),
|
||||
BrandText.body2('initializing.place_where_data'.tr()),
|
||||
const Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: context.read<ProviderFormCubit>().apiKey,
|
||||
|
@ -211,16 +211,16 @@ class InitializingPage extends StatelessWidget {
|
|||
width: 150,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BrandText.h2('initializing.3'.tr()),
|
||||
BrandText.h2('initializing.connect_cloudflare'.tr()),
|
||||
const SizedBox(height: 10),
|
||||
BrandText.body2('initializing.4'.tr()),
|
||||
BrandText.body2('initializing.manage_domain_dns'.tr()),
|
||||
const Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: context.read<DnsProviderFormCubit>().apiKey,
|
||||
textAlign: TextAlign.center,
|
||||
scrollPadding: const EdgeInsets.only(bottom: 70),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'initializing.5'.tr(),
|
||||
hintText: 'initializing.cloudflare_api_token'.tr(),
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
|
@ -260,7 +260,7 @@ class InitializingPage extends StatelessWidget {
|
|||
height: 50,
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
BrandText.h2('initializing.6'.tr()),
|
||||
BrandText.h2('initializing.connect_backblaze_storage'.tr()),
|
||||
const SizedBox(height: 10),
|
||||
const Spacer(),
|
||||
CubitFormTextField(
|
||||
|
@ -321,16 +321,17 @@ class InitializingPage extends StatelessWidget {
|
|||
const SizedBox(height: 30),
|
||||
BrandText.h2('basis.domain'.tr()),
|
||||
const SizedBox(height: 10),
|
||||
if (state is Empty) BrandText.body2('initializing.7'.tr()),
|
||||
if (state is Empty)
|
||||
BrandText.body2('initializing.no_connected_domains'.tr()),
|
||||
if (state is Loading)
|
||||
BrandText.body2(
|
||||
state.type == LoadingTypes.loadingDomain
|
||||
? 'initializing.8'.tr()
|
||||
? 'initializing.loading_domain_list'.tr()
|
||||
: 'basis.saving'.tr(),
|
||||
),
|
||||
if (state is MoreThenOne)
|
||||
BrandText.body2(
|
||||
'initializing.9'.tr(),
|
||||
'initializing.found_more_domains'.tr(),
|
||||
),
|
||||
if (state is Loaded) ...[
|
||||
const SizedBox(height: 10),
|
||||
|
@ -387,7 +388,7 @@ class InitializingPage extends StatelessWidget {
|
|||
BrandButton.rised(
|
||||
onPressed: () =>
|
||||
context.read<DomainSetupCubit>().saveDomain(),
|
||||
text: 'initializing.10'.tr(),
|
||||
text: 'initializing.save_domain'.tr(),
|
||||
),
|
||||
],
|
||||
const SizedBox(
|
||||
|
@ -411,9 +412,10 @@ class InitializingPage extends StatelessWidget {
|
|||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
BrandText.h2('initializing.22'.tr()),
|
||||
BrandText.h2('initializing.create_master_account'.tr()),
|
||||
const SizedBox(height: 10),
|
||||
BrandText.body2('initializing.23'.tr()),
|
||||
BrandText.body2(
|
||||
'initializing.enter_nickname_and_password'.tr()),
|
||||
const Spacer(),
|
||||
CubitFormTextField(
|
||||
formFieldCubit: context.read<RootUserFormCubit>().userName,
|
||||
|
@ -477,12 +479,14 @@ class InitializingPage extends StatelessWidget {
|
|||
const Spacer(flex: 2),
|
||||
BrandText.h2('initializing.final'.tr()),
|
||||
const SizedBox(height: 10),
|
||||
BrandText.body2('initializing.11'.tr()),
|
||||
BrandText.body2('initializing.create_server'.tr()),
|
||||
const Spacer(),
|
||||
BrandButton.rised(
|
||||
onPressed:
|
||||
isLoading ? null : appConfigCubit.createServerAndSetDnsRecords,
|
||||
text: isLoading ? 'basis.loading'.tr() : 'initializing.11'.tr(),
|
||||
text: isLoading
|
||||
? 'basis.loading'.tr()
|
||||
: 'initializing.create_server'.tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
@ -498,16 +502,16 @@ class InitializingPage extends StatelessWidget {
|
|||
late int doneCount;
|
||||
late String? text;
|
||||
if (state.isServerResetedSecondTime) {
|
||||
text = 'initializing.13'.tr();
|
||||
text = 'initializing.server_rebooted'.tr();
|
||||
doneCount = 3;
|
||||
} else if (state.isServerResetedFirstTime) {
|
||||
text = 'initializing.21'.tr();
|
||||
text = 'initializing.one_more_restart'.tr();
|
||||
doneCount = 2;
|
||||
} else if (state.isServerStarted) {
|
||||
text = 'initializing.14'.tr();
|
||||
text = 'initializing.server_started'.tr();
|
||||
doneCount = 1;
|
||||
} else if (state.isServerCreated) {
|
||||
text = 'initializing.15'.tr();
|
||||
text = 'initializing.server_created'.tr();
|
||||
doneCount = 0;
|
||||
}
|
||||
return Builder(
|
||||
|
@ -542,14 +546,14 @@ class InitializingPage extends StatelessWidget {
|
|||
if (!state.isLoading)
|
||||
Row(
|
||||
children: [
|
||||
BrandText.body2('initializing.16'.tr()),
|
||||
BrandText.body2('initializing.until_the_next_check'.tr()),
|
||||
BrandTimer(
|
||||
startDateTime: state.timerStart!,
|
||||
duration: state.duration!,
|
||||
)
|
||||
],
|
||||
),
|
||||
if (state.isLoading) BrandText.body2('initializing.17'.tr()),
|
||||
if (state.isLoading) BrandText.body2('initializing.check'.tr()),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
@ -73,7 +73,7 @@ class RecoverByNewDeviceKeyInput extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
title: 'more.continue'.tr(),
|
||||
title: 'basis.continue'.tr(),
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () =>
|
||||
|
|
|
@ -83,7 +83,7 @@ class RecoverByOldToken extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
title: 'more.continue'.tr(),
|
||||
title: 'basis.continue'.tr(),
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<RecoveryDeviceFormCubit>().trySubmit(),
|
||||
|
|
|
@ -44,7 +44,7 @@ class RecoverByRecoveryKey extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
title: 'more.continue'.tr(),
|
||||
title: 'basis.continue'.tr(),
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<RecoveryDeviceFormCubit>().trySubmit(),
|
||||
|
|
|
@ -38,7 +38,7 @@ class RecoveryConfirmCloudflare extends StatelessWidget {
|
|||
formFieldCubit: context.read<DnsProviderFormCubit>().apiKey,
|
||||
decoration: InputDecoration(
|
||||
border: const OutlineInputBorder(),
|
||||
labelText: 'initializing.5'.tr(),
|
||||
labelText: 'initializing.cloudflare_api_token'.tr(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
|
|
|
@ -45,7 +45,7 @@ class RecoveryHetznerConnected extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
title: 'more.continue'.tr(),
|
||||
title: 'basis.continue'.tr(),
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () => context.read<ProviderFormCubit>().trySubmit(),
|
||||
|
|
|
@ -127,7 +127,7 @@ class SelectDomainToRecover extends StatelessWidget {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton(
|
||||
title: 'more.continue'.tr(),
|
||||
title: 'basis.continue'.tr(),
|
||||
onPressed: formCubitState.isSubmitting
|
||||
? null
|
||||
: () =>
|
||||
|
|
|
@ -25,8 +25,8 @@ class UserDetails extends StatelessWidget {
|
|||
if (user.type == UserType.root) {
|
||||
return BrandHeroScreen(
|
||||
hasBackButton: true,
|
||||
heroTitle: 'ssh.root.title'.tr(),
|
||||
heroSubtitle: 'ssh.root.subtitle'.tr(),
|
||||
heroTitle: 'ssh.root_title'.tr(),
|
||||
heroSubtitle: 'ssh.root_subtitle'.tr(),
|
||||
children: [
|
||||
_SshKeysCard(user: user),
|
||||
],
|
||||
|
@ -64,7 +64,7 @@ class UserDetails extends StatelessWidget {
|
|||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: InfoBox(
|
||||
text: 'users.no_sso_notice'.tr(),
|
||||
text: 'users.no_ssh_notice'.tr(),
|
||||
isWarning: true,
|
||||
),
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue