diff --git a/locales/app/pt.json b/locales/app/pt.json
new file mode 100644
index 000000000..3b911ea37
--- /dev/null
+++ b/locales/app/pt.json
@@ -0,0 +1,207 @@
+{
+ "ai_daily.title": "Principais Notícias - {{title}}",
+ "ai_daily.tooltip.content": "Aqui estão as notícias selecionadas pela IA da sua linha do tempo ( - ), que podem ser importantes para si.",
+ "ai_daily.tooltip.update_schedule": "Atualizações diárias às 8h00 e às 20h00.",
+ "app.app_name": "NOME_APP",
+ "app.copy_logo_svg": "Copiar Logo SVG",
+ "app.toggle_sidebar": "Alternar Barra Lateral",
+ "discover.any_url_or_keyword": "Qualquer URL ou Palavra-chave",
+ "discover.default_option": " (padrão)",
+ "discover.feed_description": "A descrição deste feed é a seguinte, e pode preencher o formulário de parâmetros com as informações relevantes.",
+ "discover.feed_maintainers": "Este feed é fornecido por RSSHub, com créditos para ",
+ "discover.import.click_to_upload": "Clique para carregar o ficheiro OPML",
+ "discover.popular": "Popular",
+ "discover.preview": "Pré-visualizar",
+ "discover.rss_hub_route": "Rota RSSHub",
+ "discover.rss_url": "URL do RSS",
+ "discover.select_placeholder": "Selecionar",
+ "early_access": "Acesso Antecipado",
+ "entry_actions.copy_link": "Copiar link",
+ "entry_actions.failed_to_save_to_eagle": "Falha ao guardar no Eagle.",
+ "entry_actions.failed_to_save_to_instapaper": "Falha ao guardar no Instapaper.",
+ "entry_actions.failed_to_save_to_readwise": "Falha ao guardar no Readwise.",
+ "entry_actions.link_copied": "Link copiado para a área de transferência.",
+ "entry_actions.mark_as_read": "Marcar como lido",
+ "entry_actions.mark_as_unread": "Marcar como não lido",
+ "entry_actions.open_in_browser": "Abrir no navegador",
+ "entry_actions.save_media_to_eagle": "Guardar mídia no Eagle",
+ "entry_actions.save_to_instapaper": "Guardar no Instapaper",
+ "entry_actions.save_to_readwise": "Guardar no Readwise",
+ "entry_actions.saved_to_eagle": "Guardado no Eagle.",
+ "entry_actions.saved_to_instapaper": "Guardado no Instapaper.",
+ "entry_actions.saved_to_readwise": "Guardado no Readwise.",
+ "entry_actions.share": "Partilhar",
+ "entry_actions.star": "Favorito",
+ "entry_actions.starred": "Favoritado.",
+ "entry_actions.tip": "Dica",
+ "entry_actions.unstar": "Remover favorito",
+ "entry_actions.unstarred": "Favorito removido.",
+ "entry_column.refreshing": "A atualizar entradas...",
+ "entry_content.ai_summary": "Resumo IA",
+ "entry_content.fetching_content": "A obter conteúdo original e a processar...",
+ "entry_content.header.play_tts": "Reproduzir TTS",
+ "entry_content.header.readability": "Legibilidade",
+ "entry_content.no_content": "Sem conteúdo",
+ "entry_content.readability_notice": "Este conteúdo é fornecido pela Readability. Se encontrar erros tipográficos, consulte o site de origem para ver o conteúdo original.",
+ "entry_content.render_error": "Erro ao renderizar:",
+ "entry_content.report_issue": "Relatar problema",
+ "entry_content.web_app_notice": "Talvez a aplicação web não suporte este tipo de conteúdo. Pode fazer o download da aplicação para desktop.",
+ "entry_list.zero_unread": "Sem não lidos",
+ "entry_list_header.daily_report": "Relatório Diário",
+ "entry_list_header.hide_no_image_items": "Ocultar entradas sem imagens",
+ "entry_list_header.items": "itens",
+ "entry_list_header.new_entries_available": "Novas entradas disponíveis",
+ "entry_list_header.refetch": "Recarregar",
+ "entry_list_header.refresh": "Atualizar",
+ "entry_list_header.show_all": "Mostrar tudo",
+ "entry_list_header.show_all_items": "Mostrar todas as entradas",
+ "entry_list_header.show_unread_only": "Mostrar apenas não lidos",
+ "entry_list_header.switch_to_grid": "Mudar para grelha",
+ "entry_list_header.switch_to_masonry": "Mudar para layout de alvenaria",
+ "entry_list_header.unread": "não lidos",
+ "feed_claim_modal.choose_verification_method": "Existem três métodos de verificação. Pode escolher um para confirmar.",
+ "feed_claim_modal.claim_button": "Reivindicar",
+ "feed_claim_modal.content_instructions": "Copie o conteúdo abaixo e publique-o no seu feed RSS mais recente.",
+ "feed_claim_modal.description_current": "Descrição atual:",
+ "feed_claim_modal.description_instructions": "Copie o seguinte conteúdo e cole-o no campo do seu feed RSS.",
+ "feed_claim_modal.failed_to_load": "Falha ao carregar a mensagem de reivindicação",
+ "feed_claim_modal.rss_format_choice": "Os geradores de RSS geralmente têm dois formatos. Por favor, copie os formatos XML e JSON conforme necessário.",
+ "feed_claim_modal.rss_instructions": "Copie o código abaixo e cole-o no seu gerador de RSS.",
+ "feed_claim_modal.rss_json_format": "Formato JSON",
+ "feed_claim_modal.rss_xml_format": "Formato XML",
+ "feed_claim_modal.rsshub_notice": "Este feed é fornecido pelo RSSHub com um tempo de cache de 1 hora. Por favor, aguarde até 1 hora para que as alterações apareçam após a publicação do conteúdo.",
+ "feed_claim_modal.tab_content": "Conteúdo",
+ "feed_claim_modal.tab_description": "Descrição",
+ "feed_claim_modal.tab_rss": "Tag RSS",
+ "feed_claim_modal.verify_ownership": "Para reivindicar este feed como seu, precisa de verificar a propriedade.",
+ "feed_form.add_follow": "Adicionar seguir",
+ "feed_form.category": "Categoria",
+ "feed_form.category_description": "Por padrão, os seus feeds seguidos serão agrupados por site.",
+ "feed_form.error_fetching_feed": "Erro ao obter o feed.",
+ "feed_form.feed_not_found": "Feed não encontrado.",
+ "feed_form.feedback": "Comentários",
+ "feed_form.follow": "Seguir",
+ "feed_form.followed": "🎉 Seguido.",
+ "feed_form.private_follow": "Seguir em privado",
+ "feed_form.private_follow_description": "Se este seguimento será ou não visível publicamente no seu perfil.",
+ "feed_form.retry": "Tentar novamente",
+ "feed_form.title": "Título",
+ "feed_form.title_description": "Título personalizado para este feed. Deixe em branco para usar o padrão.",
+ "feed_form.unfollow": "Deixar de seguir",
+ "feed_form.update": "Atualizar",
+ "feed_form.update_follow": "Atualizar seguir",
+ "feed_form.updated": "🎉 Atualizado.",
+ "feed_form.view": "Ver",
+ "feed_item.claimed_by_owner": "Este feed foi reivindicado por",
+ "feed_item.claimed_by_unknown": "o proprietário.",
+ "feed_item.claimed_by_you": "Reivindicado por si",
+ "feed_item.claimed_feed": "Feed reivindicado",
+ "feed_item.error_since": "Erro desde",
+ "feed_item.not_publicly_visible": "Não visível publicamente no seu perfil",
+ "feed_view_type.articles": "Artigos",
+ "feed_view_type.audios": "Áudios",
+ "feed_view_type.notifications": "Notificações",
+ "feed_view_type.pictures": "Imagens",
+ "feed_view_type.social_media": "Redes Sociais",
+ "feed_view_type.videos": "Vídeos",
+ "mark_all_read_button.auto_confirm_info": "Será confirmado automaticamente após 3 segundos.",
+ "mark_all_read_button.confirm": "Confirmar",
+ "mark_all_read_button.confirm_mark_all": "Marcar {{which}} como lido?",
+ "mark_all_read_button.confirm_mark_all_info": "Confirmar marcar tudo como lido?",
+ "mark_all_read_button.mark_all_as_read": "Marcar tudo como lido",
+ "mark_all_read_button.mark_as_read": "Marcar {{which}} como lido",
+ "mark_all_read_button.undo": "Desfazer",
+ "player.back_10s": "Voltar 10s",
+ "player.close": "Fechar",
+ "player.download": "Download",
+ "player.exit_full_screen": "Sair de ecrã completo",
+ "player.forward_10s": "Avançar 10s",
+ "player.full_screen": "Ecrã completo",
+ "player.mute": "Silenciar",
+ "player.open_entry": "Abrir entrada",
+ "player.pause": "Pausar",
+ "player.play": "Reproduzir",
+ "player.playback_rate": "Velocidade de reprodução",
+ "player.unmute": "Ativar som",
+ "player.volume": "Volume",
+ "search.empty.no_results": "Nenhum resultado encontrado.",
+ "search.group.entries": "Entradas",
+ "search.group.feeds": "Feeds",
+ "search.options.all": "Todos",
+ "search.options.entries": "Entradas",
+ "search.options.feeds": "Feeds",
+ "search.options.search_type": "Tipo de pesquisa",
+ "search.placeholder": "Pesquisar...",
+ "search.result_count_local_mode": "(Modo local)",
+ "search.tooltip.local_search": "Esta pesquisa abrange os dados disponíveis localmente. Tente recarregar para incluir os dados mais recentes.",
+ "shortcuts.guide.title": "Guia de Atalhos",
+ "sidebar.category_remove_dialog.cancel": "Cancelar",
+ "sidebar.category_remove_dialog.continue": "Continuar",
+ "sidebar.category_remove_dialog.description": "Esta operação vai apagar a sua categoria, mas os feeds que ela contém serão mantidos e agrupados por site.",
+ "sidebar.category_remove_dialog.title": "Remover Categoria",
+ "sidebar.feed_actions.claim": "Reivindicar",
+ "sidebar.feed_actions.claim_feed": "Reivindicar Feed",
+ "sidebar.feed_actions.copy_feed_id": "Copiar ID do feed",
+ "sidebar.feed_actions.copy_feed_url": "Copiar URL do feed",
+ "sidebar.feed_actions.edit": "Editar",
+ "sidebar.feed_actions.edit_feed": "Editar feed",
+ "sidebar.feed_actions.feed_owned_by_you": "Este feed pertence a si",
+ "sidebar.feed_actions.mark_all_as_read": "Marcar tudo como lido",
+ "sidebar.feed_actions.navigate_to_feed": "Navegar para o feed",
+ "sidebar.feed_actions.open_feed_in_browser": "Abrir feed no navegador",
+ "sidebar.feed_actions.open_site_in_browser": "Abrir site no navegador",
+ "sidebar.feed_actions.unfollow": "Deixar de seguir",
+ "sidebar.feed_actions.unfollow_feed": "Deixar de seguir feed",
+ "sidebar.feed_column.context_menu.change_to_other_view": "Mudar para outro modo de visualização",
+ "sidebar.feed_column.context_menu.delete_category": "Apagar categoria",
+ "sidebar.feed_column.context_menu.delete_category_confirmation": "Apagar categoria {{folderName}}?",
+ "sidebar.feed_column.context_menu.mark_as_read": "Marcar como lido",
+ "sidebar.feed_column.context_menu.rename_category": "Renomear categoria",
+ "sidebar.select_sort_method": "Selecionar método de ordenação",
+ "signin.continue_with_github": "Continuar com o GitHub",
+ "signin.continue_with_google": "Continuar com o Google",
+ "signin.sign_in_to": "Iniciar sessão em",
+ "sync_indicator.disabled": "Por motivos de segurança, a sincronização está desativada.",
+ "sync_indicator.offline": "Offline",
+ "sync_indicator.synced": "Sincronizado com o servidor",
+ "tip_modal.amount": "Quantia",
+ "tip_modal.claim_feed": "Reivindicar este feed",
+ "tip_modal.create_wallet": "Criar Grátis",
+ "tip_modal.feed_owner": "Proprietário do Feed",
+ "tip_modal.low_balance": "O seu saldo não é suficiente para cobrir esta dica. Por favor, ajuste a quantia.",
+ "tip_modal.no_wallet": "Ainda não tem uma carteira. Por favor, crie uma carteira para enviar dicas.",
+ "tip_modal.tip_amount_sent": "foi enviado ao autor.",
+ "tip_modal.tip_now": "Enviar Dica Agora",
+ "tip_modal.tip_sent": "Dica enviada com sucesso! Obrigado pelo seu apoio.",
+ "tip_modal.tip_support": "⭐ Envie uma dica para mostrar o seu apoio!",
+ "tip_modal.unclaimed_feed": "Ninguém reivindicou este feed ainda. O Power recebido será mantido em segurança no contrato blockchain até ser reivindicado.",
+ "user_button.account": "Conta",
+ "user_button.download_desktop_app": "Descarregar aplicação para desktop",
+ "user_button.log_out": "Terminar sessão",
+ "user_button.power": "Power",
+ "user_button.preferences": "Preferências",
+ "user_button.profile": "Perfil",
+ "user_profile.close": "Fechar",
+ "user_profile.edit": "Editar",
+ "user_profile.loading": "A carregar",
+ "user_profile.share": "Partilhar",
+ "user_profile.toggle_item_style": "Alternar Estilo de Item",
+ "words.add": "Adicionar",
+ "words.confirm": "Confirmar",
+ "words.discover": "Descobrir",
+ "words.email": "E-mail",
+ "words.import": "Importar",
+ "words.items": "Itens",
+ "words.language": "Idioma",
+ "words.load_archived_entries": "Carregar entradas arquivadas",
+ "words.login": "Iniciar sessão",
+ "words.rss": "RSS",
+ "words.rss3": "RSS3",
+ "words.rsshub": "RSSHub",
+ "words.search": "Pesquisar",
+ "words.starred": "Favoritos",
+ "words.unread": "Não lidos",
+ "words.user": "Utilizador",
+ "words.which.all": "todos",
+ "words.zero_items": "Sem itens"
+}
diff --git a/locales/common/pt.json b/locales/common/pt.json
new file mode 100644
index 000000000..ae59627f5
--- /dev/null
+++ b/locales/common/pt.json
@@ -0,0 +1,28 @@
+{
+ "app.copied_to_clipboard": "Copiado para a área de transferência",
+ "cancel": "Cancelar",
+ "confirm": "Confirmar",
+ "ok": "OK",
+ "quantifier.piece": "",
+ "time.last_night": "Ontem à noite",
+ "time.the_night_before_last": "Anteontem à noite",
+ "time.today": "Hoje",
+ "time.yesterday": "Ontem",
+ "tips.load-lng-error": "Falha ao carregar o pacote de idioma",
+ "words.back": "Voltar",
+ "words.copy": "Copiar",
+ "words.edit": "Editar",
+ "words.entry": "Entrada",
+ "words.id": "ID",
+ "words.items_one": "Item",
+ "words.items_other": "Itens",
+ "words.local": "local",
+ "words.record": "registo",
+ "words.record_one": "registo",
+ "words.record_other": "registos",
+ "words.result": "resultado",
+ "words.result_one": "resultado",
+ "words.result_other": "resultados",
+ "words.space": " ",
+ "words.which.all": "Todos"
+}
diff --git a/locales/external/pt.json b/locales/external/pt.json
new file mode 100644
index 000000000..a1bf83f35
--- /dev/null
+++ b/locales/external/pt.json
@@ -0,0 +1,42 @@
+{
+ "feed": {
+ "follow_one": "seguir",
+ "follow_other": "seguimentos",
+ "followsAndReads": "{{subscriptionCount}} {{subscriptionNoun}} com {{readCount}} {{readNoun}} no {{appName}}",
+ "read_one": "leitura",
+ "read_other": "leituras"
+ },
+ "header": {
+ "app": "App",
+ "download": "Descarregar"
+ },
+ "invitation": {
+ "activate": "Ativar",
+ "codeOptions": {
+ "1": "Procure um utilizador de teste alpha que o convide.",
+ "2": "Junte-se ao nosso servidor Discord para receber ofertas ocasionais.",
+ "3": "Siga a nossa conta no X para receber ofertas ocasionais."
+ },
+ "earlyAccess": "O Follow está atualmente em acesso antecipado e requer um código de convite para ser utilizado.",
+ "earlyAccessMessage": "😰 Lamentamos, o Follow está atualmente em acesso antecipado e requer um código de convite.",
+ "generateButton": "Gerar novo código",
+ "generateCost": "Pode gastar {{INVITATION_PRICE}} Power para gerar um código de convite para os seus amigos.",
+ "getCodeMessage": "Pode obter um código de convite das seguintes maneiras:",
+ "title": "Código de Convite"
+ },
+ "login": {
+ "backToWebApp": "Voltar à App Web",
+ "continueWithGitHub": "Continuar com GitHub",
+ "continueWithGoogle": "Continuar com Google",
+ "logInTo": "Iniciar sessão em ",
+ "openApp": "Abrir Aplicação",
+ "redirecting": "A redirecionar",
+ "welcomeTo": "Bem-vindo ao "
+ },
+ "redirect": {
+ "continueInBrowser": "Continuar no Navegador",
+ "instruction": "Agora é o momento de abrir {{APP_NAME}} e fechar esta página com segurança.",
+ "openApp": "Abrir {{APP_NAME}}",
+ "successMessage": "Conectou-se com sucesso à conta {{APP_NAME}}."
+ }
+}
diff --git a/locales/lang/en.json b/locales/lang/en.json
index 795047911..157ca431f 100644
--- a/locales/lang/en.json
+++ b/locales/lang/en.json
@@ -1,6 +1,7 @@
{
"langs.en": "English",
"langs.ja": "日本語",
+ "langs.pt": "Português",
"langs.zh-CN": "简体中文",
"name": "English"
}
diff --git a/locales/lang/ja.json b/locales/lang/ja.json
index cdd1c6e6c..92d8fcf86 100644
--- a/locales/lang/ja.json
+++ b/locales/lang/ja.json
@@ -1,6 +1,7 @@
{
"langs.en": "English",
"langs.ja": "日本語",
+ "langs.pt": "Português",
"langs.zh-CN": "简体中文",
"name": "日本語"
}
diff --git a/locales/lang/pt.json b/locales/lang/pt.json
new file mode 100644
index 000000000..fcb92f119
--- /dev/null
+++ b/locales/lang/pt.json
@@ -0,0 +1,7 @@
+{
+ "langs.en": "English",
+ "langs.ja": "日本語",
+ "langs.pt": "Português",
+ "langs.zh-CN": "简体中文",
+ "name": "Português"
+}
diff --git a/locales/lang/zh-CN.json b/locales/lang/zh-CN.json
index 48ce191a7..aef3b390b 100644
--- a/locales/lang/zh-CN.json
+++ b/locales/lang/zh-CN.json
@@ -1,6 +1,7 @@
{
"langs.en": "English",
"langs.ja": "日本語",
+ "langs.pt": "Português",
"langs.zh-CN": "简体中文",
"name": "简体中文"
}
diff --git a/locales/settings/pt.json b/locales/settings/pt.json
new file mode 100644
index 000000000..8f3514d3b
--- /dev/null
+++ b/locales/settings/pt.json
@@ -0,0 +1,195 @@
+{
+ "about.changelog": "Histórico de Alterações",
+ "about.feedbackInfo": "{{appName}} ({{commitSha}}) está nas fases iniciais de desenvolvimento. Se tiver algum feedback ou sugestão, fique à vontade para abrir uma issue no nosso GitHub.",
+ "about.iconLibrary": "A biblioteca de ícones utilizada é protegida por direitos de autor por e não pode ser redistribuída.",
+ "about.licenseInfo": "{{appName}} é e sempre será um projeto gratuito e de código aberto. Está licenciado sob {{license}}.",
+ "about.sidebar_title": "Sobre",
+ "about.socialMedia": "Redes Sociais",
+ "actions.actionName": "Ação {{number}}",
+ "actions.action_card.add": "Adicionar",
+ "actions.action_card.all": "Tudo",
+ "actions.action_card.block_rules": "Regras de Bloqueio",
+ "actions.action_card.custom_filters": "Filtros Personalizados",
+ "actions.action_card.enable_readability": "Ativar legibilidade",
+ "actions.action_card.entry_options.all": "Tudo",
+ "actions.action_card.entry_options.author": "Autor",
+ "actions.action_card.entry_options.content": "Conteúdo",
+ "actions.action_card.entry_options.order": "Ordem",
+ "actions.action_card.entry_options.title": "Título",
+ "actions.action_card.entry_options.url": "Url",
+ "actions.action_card.feed_options.category": "Categoria",
+ "actions.action_card.feed_options.feed_url": "URL do Feed",
+ "actions.action_card.feed_options.site_url": "URL do Site",
+ "actions.action_card.feed_options.title": "Título",
+ "actions.action_card.feed_options.view": "Visualizar",
+ "actions.action_card.field": "Campo",
+ "actions.action_card.from": "De",
+ "actions.action_card.generate_summary": "Gerar resumo com IA",
+ "actions.action_card.name": "Nome",
+ "actions.action_card.operation_options.contains": "contém",
+ "actions.action_card.operation_options.does_not_contain": "não contém",
+ "actions.action_card.operation_options.is_equal_to": "é igual a",
+ "actions.action_card.operation_options.is_greater_than": "é maior que",
+ "actions.action_card.operation_options.is_less_than": "é menor que",
+ "actions.action_card.operation_options.is_not_equal_to": "não é igual a",
+ "actions.action_card.operation_options.matches_regex": "corresponde ao regex",
+ "actions.action_card.operator": "Operador",
+ "actions.action_card.rewrite_rules": "Reescrever Regras",
+ "actions.action_card.then_do": "Então faz…",
+ "actions.action_card.to": "Para",
+ "actions.action_card.translate_into": "Traduzir para",
+ "actions.action_card.value": "Valor",
+ "actions.action_card.when_feeds_match": "Quando os feeds corresponderem…",
+ "actions.newRule": "Nova Regra",
+ "actions.save": "Guardar",
+ "actions.saveSuccess": "🎉 Ações guardadas.",
+ "actions.sidebar_title": "Ações",
+ "actions.title": "Ações",
+ "appearance.code_highlight_theme": "Tema de destaque de código",
+ "appearance.content": "Conteúdo",
+ "appearance.content_font": "Fonte do conteúdo",
+ "appearance.custom_font": "Fonte personalizada",
+ "appearance.fonts": "Fontes",
+ "appearance.general": "Geral",
+ "appearance.guess_code_language.description": "Principais linguagens de programação que utilizam modelos para inferir blocos de código não rotulados",
+ "appearance.guess_code_language.label": "Adivinhar linguagem de código",
+ "appearance.misc": "Vários",
+ "appearance.modal_overlay.description": "Mostrar sobreposição modal",
+ "appearance.modal_overlay.label": "Mostrar sobreposição modal",
+ "appearance.opaque_sidebars.label": "Barras laterais opacas",
+ "appearance.reader_render_inline_style.description": "Permite renderizar o estilo inline do HTML original.",
+ "appearance.reader_render_inline_style.label": "Renderizar estilo inline",
+ "appearance.reduce_motion.description": "Reduzir o movimento dos elementos para melhorar o desempenho e reduzir o consumo de energia",
+ "appearance.reduce_motion.label": "Reduzir movimento",
+ "appearance.save": "Guardar",
+ "appearance.show_dock_badge.label": "Mostrar como badge no Dock",
+ "appearance.sidebar_show_unread_count.label": "Mostrar na barra lateral",
+ "appearance.sidebar_title": "Aparência",
+ "appearance.text_size": "Tamanho do texto",
+ "appearance.theme.dark": "Escuro",
+ "appearance.theme.label": "Tema",
+ "appearance.theme.light": "Claro",
+ "appearance.theme.system": "Sistema",
+ "appearance.title": "Aparência",
+ "appearance.ui_font": "Fonte da interface",
+ "appearance.unread_count": "Contagem de não lidos",
+ "general.app": "App",
+ "general.data_persist.description": "Guardar os dados localmente para permitir o acesso offline e pesquisa local.",
+ "general.data_persist.label": "Guardar dados para uso offline",
+ "general.group_by_date.description": "Agrupar entradas por data.",
+ "general.group_by_date.label": "Agrupar por data",
+ "general.language": "Idioma",
+ "general.launch_at_login": "Lançar ao iniciar sessão",
+ "general.mark_as_read.hover.description": "Marcar automaticamente as entradas como lidas quando passar o rato sobre elas.",
+ "general.mark_as_read.hover.label": "Marcar como lido ao passar o rato",
+ "general.mark_as_read.render.description": "Marcar automaticamente as entradas de nível único (por exemplo, posts em redes sociais, imagens, vídeos visualizados) como lidas quando aparecerem.",
+ "general.mark_as_read.render.label": "Marcar como lido ao visualizar",
+ "general.mark_as_read.scroll.description": "Marcar automaticamente as entradas como lidas quando saem do campo de visão.",
+ "general.mark_as_read.scroll.label": "Marcar como lido ao rolar a página",
+ "general.privacy_data": "Privacidade & Dados",
+ "general.rebuild_database.button": "Reconstruir",
+ "general.rebuild_database.description": "Se estiver a ter problemas de renderização, reconstruir a base de dados pode resolver.",
+ "general.rebuild_database.label": "Reconstruir Base de Dados",
+ "general.rebuild_database.title": "Reconstruir Base de Dados",
+ "general.rebuild_database.warning.line1": "Reconstruir a base de dados vai apagar todos os seus dados locais.",
+ "general.rebuild_database.warning.line2": "Tem a certeza de que quer continuar?",
+ "general.send_anonymous_data.description": "Ao optar por enviar dados anónimos de telemetria, está a contribuir para a melhoria da experiência do utilizador no Follow.",
+ "general.send_anonymous_data.label": "Enviar dados anónimos",
+ "general.show_unread_on_launch.description": "Mostrar conteúdo não lido ao iniciar",
+ "general.show_unread_on_launch.label": "Mostrar conteúdo não lido ao iniciar",
+ "general.sidebar_title": "Geral",
+ "general.timeline": "Linha do tempo",
+ "general.unread": "Não lidos",
+ "general.voices": "Vozes",
+ "integration.eagle.enable.description": "Exibir o botão 'Guardar mídia no Eagle' quando disponível.",
+ "integration.eagle.enable.label": "Ativar",
+ "integration.eagle.title": "Eagle",
+ "integration.instapaper.enable.description": "Exibir o botão 'Guardar no Instapaper' quando disponível.",
+ "integration.instapaper.enable.label": "Ativar",
+ "integration.instapaper.password.label": "Palavra-passe do Instapaper",
+ "integration.instapaper.title": "Instapaper",
+ "integration.instapaper.username.label": "Nome de utilizador do Instapaper",
+ "integration.readwise.enable.description": "Exibir o botão 'Guardar no Readwise' quando disponível.",
+ "integration.readwise.enable.label": "Ativar",
+ "integration.readwise.title": "Readwise",
+ "integration.readwise.token.description": "Pode obtê-lo aqui: readwise.io/access_token.",
+ "integration.readwise.token.label": "Token de Acesso do Readwise",
+ "integration.sidebar_title": "Integração",
+ "integration.tip": "Dica: Os seus dados sensíveis são armazenados localmente e não são carregados para o servidor.",
+ "integration.title": "Integração",
+ "invitation.activate": "Ativar",
+ "invitation.codeOptions.betaUser": "1. Encontre um utilizador beta que o convide.",
+ "invitation.codeOptions.discord": "2. Junte-se ao nosso servidor Discord e receba presentes ocasionais.",
+ "invitation.codeOptions.xAccount": "3. Siga a nossa conta no X para receber presentes ocasionalmente.",
+ "invitation.confirmModal.cancel": "Cancelar",
+ "invitation.confirmModal.confirm": "Deseja continuar?",
+ "invitation.confirmModal.continue": "Continuar",
+ "invitation.confirmModal.message": "Gerar um código de convite vai custar-lhe {{INVITATION_PRICE}} Power.",
+ "invitation.confirmModal.title": "Confirmar",
+ "invitation.earlyAccess": "O Follow está atualmente em acesso antecipado e requer um código de convite para ser utilizado.",
+ "invitation.earlyAccessMessage": "😰 Desculpe, o Follow está atualmente em acesso antecipado e requer um código de convite para ser utilizado.",
+ "invitation.generateButton": "Gerar novo código",
+ "invitation.generateCost": "Pode gastar {{INVITATION_PRICE}} Power para gerar um código de convite para os seus amigos.",
+ "invitation.getCodeMessage": "Pode obter um código de convite através dos seguintes métodos:",
+ "invitation.newInvitationSuccess": "🎉 Novo convite gerado, o código de convite foi copiado",
+ "invitation.noInvitations": "Sem convites",
+ "invitation.notUsed": "Não utilizado",
+ "invitation.sidebar_title": "Convites",
+ "invitation.tableHeaders.code": "Código",
+ "invitation.tableHeaders.creationTime": "Hora de Criação",
+ "invitation.tableHeaders.usedBy": "Utilizado por",
+ "invitation.title": "Código de Convite",
+ "profile.avatar.label": "Avatar",
+ "profile.handle.description": "O seu identificador único.",
+ "profile.handle.label": "Identificador",
+ "profile.name.description": "O seu nome público visível.",
+ "profile.name.label": "Nome de Exibição",
+ "profile.sidebar_title": "Perfil",
+ "profile.submit": "Submeter",
+ "profile.title": "Configurações de Perfil",
+ "profile.updateSuccess": "Perfil atualizado.",
+ "titles.about": "Sobre",
+ "titles.actions": "Ações",
+ "titles.appearance": "Aparência",
+ "titles.general": "Geral",
+ "titles.integration": "Integração",
+ "titles.invitations": "Convites",
+ "titles.power": "Power",
+ "titles.profile": "Perfil",
+ "titles.shortcuts": "Atalhos",
+ "wallet.address.title": "O Seu Endereço",
+ "wallet.balance.title": "O Seu Saldo",
+ "wallet.balance.withdrawable": "Levantável",
+ "wallet.balance.withdrawableTooltip": "O Power levantável inclui tanto as dicas que recebeu quanto o Power que recarregou.",
+ "wallet.claim.button.claim": "Reivindicar Power Diário",
+ "wallet.claim.button.claimed": "Reivindicado hoje",
+ "wallet.claim.tooltip.alreadyClaimed": "Já reivindicou o seu Power hoje.",
+ "wallet.claim.tooltip.canClaim": "Reivindique agora o seu {{amount}} Power Diário!",
+ "wallet.create.button": "Criar Carteira",
+ "wallet.create.description": "Crie uma carteira gratuita para receber Power, que pode ser utilizado para recompensar criadores e também para ser recompensado pelas suas contribuições de conteúdo.",
+ "wallet.power.dailyClaim": "Pode reivindicar {{amount}} de Power gratuito diariamente, que pode ser usado para dar dicas em entradas de RSS no Follow.",
+ "wallet.power.description": "O Power é um token ERC-20 na blockchain {{blockchainName}}.",
+ "wallet.sidebar_title": "Power",
+ "wallet.transactions.amount": "Quantia",
+ "wallet.transactions.date": "Data",
+ "wallet.transactions.from": "De",
+ "wallet.transactions.noTransactions": "Sem transações",
+ "wallet.transactions.title": "Transações",
+ "wallet.transactions.to": "Para",
+ "wallet.transactions.tx": "Tx",
+ "wallet.transactions.type": "Tipo",
+ "wallet.transactions.types.burn": "queima",
+ "wallet.transactions.types.mint": "cunhagem",
+ "wallet.transactions.types.purchase": "compra",
+ "wallet.transactions.types.tip": "dica",
+ "wallet.transactions.types.withdraw": "levantamento",
+ "wallet.transactions.you": "Você",
+ "wallet.withdraw.addressLabel": "O seu endereço Ethereum",
+ "wallet.withdraw.amountLabel": "Quantia",
+ "wallet.withdraw.availableBalance": "Tem de Power levantável na sua carteira.",
+ "wallet.withdraw.button": "Levantar",
+ "wallet.withdraw.error": "O levantamento falhou: {{error}}",
+ "wallet.withdraw.modalTitle": "Levantar Power",
+ "wallet.withdraw.submitButton": "Submeter",
+ "wallet.withdraw.success": "Levantamento bem-sucedido!"
+}
diff --git a/locales/shortcuts/pt.json b/locales/shortcuts/pt.json
new file mode 100644
index 000000000..85d13c60a
--- /dev/null
+++ b/locales/shortcuts/pt.json
@@ -0,0 +1,24 @@
+{
+ "keys.audio.playPause": "Reproduzir/Pausar (Quando o reprodutor de áudio estiver aberto)",
+ "keys.entries.markAllAsRead": "Marcar Tudo como Lido",
+ "keys.entries.next": "Próxima Entrada",
+ "keys.entries.previous": "Entrada Anterior",
+ "keys.entries.refetch": "Recarregar",
+ "keys.entries.toggleUnreadOnly": "Alternar Apenas Não Lidos",
+ "keys.entry.copyLink": "Copiar Link",
+ "keys.entry.openInBrowser": "Abrir no Navegador",
+ "keys.entry.openInNewTab": "Abrir numa Nova Aba",
+ "keys.entry.scrollDown": "Rolar para Baixo",
+ "keys.entry.scrollUp": "Rolar para Cima",
+ "keys.entry.share": "Partilhar",
+ "keys.entry.tip": "Dar Dica",
+ "keys.entry.toggleRead": "Alternar Leitura",
+ "keys.entry.toggleStarred": "Alternar Favorito",
+ "keys.entry.tts": "Reproduzir TTS",
+ "keys.feeds.add": "Adicionar Subscrição",
+ "keys.feeds.switchBetweenViews": "Alternar Entre Visualizações",
+ "keys.feeds.switchToView": "Mudar para Visualização",
+ "keys.layout.showShortcuts": "Mostrar/Ocultar Atalhos",
+ "keys.layout.toggleSidebar": "Mostrar/Ocultar Barra Lateral de Feed",
+ "sidebar_title": "Atalhos"
+}
diff --git a/src/renderer/src/@types/constants.ts b/src/renderer/src/@types/constants.ts
index 666e864b3..98cc208ba 100644
--- a/src/renderer/src/@types/constants.ts
+++ b/src/renderer/src/@types/constants.ts
@@ -1,9 +1,10 @@
-const langs = ["en", "ja", "zh-CN"]
+const langs = ["en", "ja", "zh-CN", "pt"]
export const currentSupportedLanguages = langs.sort()
export const dayjsLocaleImportMap = {
en: ["en", () => import("dayjs/locale/en")],
["zh-CN"]: ["zh-cn", () => import("dayjs/locale/zh-cn")],
["ja"]: ["ja", () => import("dayjs/locale/ja")],
+ ["pt"]: ["pt", () => import("dayjs/locale/pt")],
}
export const ns = ["app", "common", "lang", "settings", "shortcuts"] as const
export const defaultNS = "app" as const
diff --git a/src/renderer/src/@types/default-resource.ts b/src/renderer/src/@types/default-resource.ts
index 752f765b7..72c1ae03b 100644
--- a/src/renderer/src/@types/default-resource.ts
+++ b/src/renderer/src/@types/default-resource.ts
@@ -1,10 +1,12 @@
import en from "../../../../locales/app/en.json"
import common_en from "../../../../locales/common/en.json"
import common_ja from "../../../../locales/common/ja.json"
+import common_pt from "../../../../locales/common/pt.json"
import common_zhCN from "../../../../locales/common/zh-CN.json"
import external_en from "../../../../locales/external/en.json"
import lang_en from "../../../../locales/lang/en.json"
import lang_ja from "../../../../locales/lang/ja.json"
+import lang_pt from "../../../../locales/lang/pt.json"
import lang_zhCN from "../../../../locales/lang/zh-CN.json"
import settings_en from "../../../../locales/settings/en.json"
import shortcuts_en from "../../../../locales/shortcuts/en.json"
@@ -32,5 +34,6 @@ export const defaultResources = {
lang: lang_ja,
common: common_ja,
},
+ pt: { lang: lang_pt, common: common_pt },
ja: { lang: lang_ja, common: common_ja },
}