diff --git a/docs/releases.md b/docs/releases.md
index a28ca239..062563e3 100644
--- a/docs/releases.md
+++ b/docs/releases.md
@@ -4,6 +4,12 @@ and the [ntfy Android app](https://github.com/binwiederhier/ntfy-android/release
diff --git a/web/public/static/langs/pt_BR.json b/web/public/static/langs/pt_BR.json
index 3efd57ce..c5169f14 100644
--- a/web/public/static/langs/pt_BR.json
+++ b/web/public/static/langs/pt_BR.json
@@ -34,5 +34,124 @@
"notifications_attachment_link_expires": "link expira em {{date}}",
"notifications_attachment_copy_url_button": "Copiar URL",
"notifications_attachment_link_expired": "link para transferência expirado",
- "notifications_example": "Exemplo"
+ "notifications_example": "Exemplo",
+ "notifications_more_details": "Para mais informações, confira site ou documentação.",
+ "notifications_loading": "Carregando notificações…",
+ "subscribe_dialog_error_user_anonymous": "anônimo",
+ "prefs_notifications_delete_after_three_hours": "Após três horas",
+ "prefs_notifications_delete_after_one_day": "Após um dia",
+ "prefs_notifications_delete_after_one_week": "Após uma semana",
+ "prefs_notifications_delete_after_one_month": "Após um mês",
+ "notifications_actions_not_supported": "Ação não suportada no aplicativo web",
+ "notifications_actions_http_request_title": "Enviar HTTP {{method}} para {{url}}",
+ "notifications_actions_open_url_title": "Ir para {{url}}",
+ "publish_dialog_title_topic": "Publicar em {{topic}}",
+ "publish_dialog_title_no_topic": "Publicar notificação",
+ "publish_dialog_progress_uploading": "Enviando …",
+ "publish_dialog_progress_uploading_detail": "Fazendo upload de {{loaded}}/{{total}} ({{percent}}%)…",
+ "publish_dialog_message_published": "Notificação publicada",
+ "publish_dialog_attachment_limits_file_reached": "excede o limite de arquivo {{fileSizeLimit}}",
+ "publish_dialog_priority_min": "Prioridade mínima",
+ "publish_dialog_priority_low": "Baixa prioridade",
+ "publish_dialog_priority_default": "Prioridade padrão",
+ "publish_dialog_base_url_label": "URL de serviço",
+ "publish_dialog_base_url_placeholder": "URL de serviço, por exemplo https://example.com",
+ "publish_dialog_topic_label": "Nome do tópico",
+ "publish_dialog_topic_placeholder": "Nome do tópico, por exemplo, phil_alerts",
+ "publish_dialog_title_label": "Título",
+ "publish_dialog_title_placeholder": "Título da notificação, por exemplo Alerta de espaço em disco",
+ "publish_dialog_message_label": "Mensagem",
+ "publish_dialog_message_placeholder": "Digite uma mensagem aqui",
+ "publish_dialog_tags_label": "Etiquetas",
+ "publish_dialog_tags_placeholder": "Lista de etiquetas, separadas por vírgula, por exemplo: srv1-backup",
+ "publish_dialog_priority_label": "Prioridade",
+ "publish_dialog_click_label": "Clique em URL",
+ "publish_dialog_click_placeholder": "URL que é aberto quando a notificação é clicada",
+ "publish_dialog_email_label": "Email",
+ "publish_dialog_email_placeholder": "Email para encaminhar a notificação, por exemplo phil@example.com",
+ "publish_dialog_filename_label": "Nome do arquivo",
+ "publish_dialog_filename_placeholder": "Nome do arquivo anexado",
+ "publish_dialog_delay_label": "Atraso",
+ "publish_dialog_delay_placeholder": "Atraso na entrega, por exemplo {{{unixTimestamp}}, {{relativeTime}}, ou \"{{naturalLanguage}}\" (apenas em inglês)",
+ "publish_dialog_other_features": "Outros recursos:",
+ "publish_dialog_chip_click_label": "Clique em URL",
+ "publish_dialog_chip_attach_file_label": "Anexar arquivo local",
+ "publish_dialog_chip_delay_label": "Atraso na entrega",
+ "publish_dialog_chip_topic_label": "Alterar tópico",
+ "publish_dialog_button_cancel_sending": "Cancelar o envio",
+ "publish_dialog_attached_file_filename_placeholder": "Nome do arquivo anexado",
+ "publish_dialog_drop_file_here": "Solte o arquivo aqui",
+ "emoji_picker_search_placeholder": "Pesquisar emoji",
+ "subscribe_dialog_subscribe_title": "Inscrever no tópico",
+ "subscribe_dialog_subscribe_use_another_label": "Usar outro servidor",
+ "subscribe_dialog_subscribe_description": "Os tópicos podem não ser protegidos por senha, então escolha um nome que não seja fácil de adivinhar. Uma vez inscrito, você pode PUT/POST notificações.",
+ "subscribe_dialog_subscribe_topic_placeholder": "Nome do tópico, por exemplo phil_alerts",
+ "subscribe_dialog_subscribe_button_cancel": "Cancelar",
+ "subscribe_dialog_subscribe_button_subscribe": "Inscrever",
+ "prefs_notifications_min_priority_description_max": "Mostrar notificações se prioridade for 5 (máxima)",
+ "prefs_notifications_min_priority_any": "Qualquer prioridade",
+ "prefs_notifications_min_priority_low_and_higher": "Baixa prioridade e acima",
+ "prefs_notifications_min_priority_default_and_higher": "Prioridade padrão e acima",
+ "subscribe_dialog_login_password_label": "Senha",
+ "subscribe_dialog_login_button_back": "Voltar",
+ "prefs_notifications_min_priority_high_and_higher": "Alta prioridade e acima",
+ "prefs_notifications_min_priority_max_only": "Apenas prioridade máxima",
+ "prefs_notifications_delete_after_title": "Apagar notificações",
+ "prefs_notifications_delete_after_never": "Nunca",
+ "prefs_notifications_delete_after_never_description": "Notificações nunca serão auto excluídas",
+ "prefs_users_description": "Adicionar/remover usuários em seus tópicos protegidos. Note que o usuário e senha são salvos no armazenamento local do navegador.",
+ "prefs_users_add_button": "Adicionar usuário",
+ "prefs_users_table_user_header": "Usuário",
+ "prefs_users_table_base_url_header": "URL de serviço",
+ "prefs_users_dialog_title_add": "Adicionar usuário",
+ "prefs_users_dialog_title_edit": "Editar usuário",
+ "prefs_users_dialog_base_url_label": "URL de serviço, exemplo https://ntfy.sh",
+ "prefs_users_dialog_username_label": "Usuário, por exemplo phil",
+ "prefs_users_dialog_password_label": "Senha",
+ "prefs_users_dialog_button_cancel": "Cancelar",
+ "prefs_users_dialog_button_add": "Adicionar",
+ "prefs_users_dialog_button_save": "Salvar",
+ "prefs_appearance_title": "Aparência",
+ "prefs_appearance_language_title": "LInguagem",
+ "priority_min": "minima",
+ "priority_low": "baixa",
+ "priority_default": "padrão",
+ "priority_high": "alta",
+ "priority_max": "máxima",
+ "error_boundary_title": "Ah não, ntfy parou de funcionar",
+ "error_boundary_gathering_info": "Coletar mais informações …",
+ "error_boundary_description": "Isto obviamente não deveria ter acontecido. Lamentamos muito por isto.
Se tiver um minuto, por favor relate isto no GitHub, ou informe-nos através de Discord ou Matrix.",
+ "error_boundary_button_copy_stack_trace": "Copiar rastreamento de pilha",
+ "error_boundary_stack_trace": "Rastreamento de pilha",
+ "publish_dialog_attachment_limits_file_and_quota_reached": "excede {{fileSizeLimit}} limite de arquivo e cota, {{remainingBytes}} restante",
+ "publish_dialog_attachment_limits_quota_reached": "excede a cota, {{remainingBytes}} restantes",
+ "publish_dialog_priority_high": "Alta prioridade",
+ "publish_dialog_priority_max": "Prioridade máxima",
+ "publish_dialog_button_send": "Enviar",
+ "publish_dialog_attached_file_title": "Arquivo anexado:",
+ "publish_dialog_attach_label": "URL de anexo",
+ "publish_dialog_chip_attach_url_label": "Anexar arquivo por URL",
+ "publish_dialog_attach_placeholder": "Anexar arquivo por URL, por exemplo, https://f-droid.org/F-Droid.apk",
+ "publish_dialog_chip_email_label": "Encaminhar para email",
+ "publish_dialog_checkbox_publish_another": "Publicar outro",
+ "publish_dialog_details_examples_description": "Para obter exemplos e uma descrição detalhada de todos os recursos de envio, consulte a documentação.",
+ "publish_dialog_button_cancel": "Cancelar",
+ "prefs_notifications_delete_after_one_day_description": "Notificações são automaticamente excluídas após um dia",
+ "prefs_notifications_delete_after_one_month_description": "Notificações são automaticamente excluídas após um mês",
+ "prefs_users_title": "Gerenciar usuários",
+ "subscribe_dialog_error_user_not_authorized": "Usuário {{username}} não autorizado",
+ "prefs_notifications_title": "Notificações",
+ "prefs_notifications_sound_no_sound": "Sem som",
+ "subscribe_dialog_login_title": "Login necessário",
+ "prefs_notifications_sound_title": "Som de notificações",
+ "prefs_notifications_min_priority_title": "Mínima prioridade",
+ "prefs_notifications_min_priority_description_any": "Mostrando todas as notificações, independente da prioridade",
+ "prefs_notifications_delete_after_one_week_description": "Notificações são automaticamente excluídas após uma semana",
+ "subscribe_dialog_login_description": "Esse tópico é protegido por senha. Por favor digite o nome de usuário e senha para inscrever.",
+ "subscribe_dialog_login_username_label": "Nome, por exemplo phil",
+ "subscribe_dialog_login_button_login": "Login",
+ "prefs_notifications_sound_description_none": "Notificações não reproduzem nenhum som quando chegam",
+ "prefs_notifications_sound_description_some": "Notificações reproduzem som {{sound}} quando chegam",
+ "prefs_notifications_min_priority_description_x_or_higher": "Mostrar notificações se prioridade for {{number}} ({{name}}) ou acima",
+ "prefs_notifications_delete_after_three_hours_description": "Notificações são automaticamente excluídas após três horas"
}
diff --git a/web/src/components/Preferences.js b/web/src/components/Preferences.js
index 35e6d9de..f679fb42 100644
--- a/web/src/components/Preferences.js
+++ b/web/src/components/Preferences.js
@@ -436,7 +436,7 @@ const Appearance = () => {
const Language = () => {
const { t, i18n } = useTranslation();
const labelId = "prefLanguage";
- const randomFlags = shuffle(["🇬🇧", "🇺🇸", "🇪🇸", "🇫🇷", "🇧🇬", "🇨🇿", "🇩🇪", "🇭🇺", "🇮🇩", "🇯🇵", "🇷🇺", "🇹🇷"]).slice(0, 3);
+ const randomFlags = shuffle(["🇬🇧", "🇺🇸", "🇪🇸", "🇫🇷", "🇧🇬", "🇨🇿", "🇩🇪", "🇭🇺", "🇧🇷", "🇮🇩", "🇯🇵", "🇷🇺", "🇹🇷"]).slice(0, 3);
const title = t("prefs_appearance_language_title") + " " + randomFlags.join(" ");
const lang = i18n.language ?? "en";
@@ -458,6 +458,7 @@ const Language = () => {
+