From b1a625a036f8fd748e2efd6ffdf8cd6677c65f2a Mon Sep 17 00:00:00 2001
From: Noah <130611693+upupnoah@users.noreply.github.com>
Date: Thu, 19 Sep 2024 22:33:41 +0700
Subject: [PATCH] feat(i18n): add Finnish language support (#401)
* feat(i18n): add Finnish language support
Added Finnish translations to the application, including localization for app content, common phrases, external resources, language settings, and shortcuts.
* Update default-resource.ts
* feat: support lang/*.json
* fix: tsfile format
* fix: format
---
apps/renderer/src/@types/constants.ts | 1 +
apps/renderer/src/@types/default-resource.ts | 3 +
locales/app/fi.json | 207 +++++++++++++++++++
locales/common/fi.json | 28 +++
locales/external/fi.json | 42 ++++
locales/lang/ar-dz.json | 14 ++
locales/lang/ar-ma.json | 14 ++
locales/lang/ar-sa.json | 14 ++
locales/lang/en.json | 1 +
locales/lang/es.json | 1 +
locales/lang/fi.json | 14 ++
locales/lang/fr.json | 1 +
locales/lang/ja.json | 1 +
locales/lang/pt.json | 1 +
locales/lang/zh-CN.json | 1 +
locales/lang/zh-TW.json | 1 +
locales/settings/fi.json | 195 +++++++++++++++++
locales/shortcuts/fi.json | 24 +++
18 files changed, 563 insertions(+)
create mode 100644 locales/app/fi.json
create mode 100644 locales/common/fi.json
create mode 100644 locales/external/fi.json
create mode 100644 locales/lang/ar-dz.json
create mode 100644 locales/lang/ar-ma.json
create mode 100644 locales/lang/ar-sa.json
create mode 100644 locales/lang/fi.json
create mode 100644 locales/settings/fi.json
create mode 100644 locales/shortcuts/fi.json
diff --git a/apps/renderer/src/@types/constants.ts b/apps/renderer/src/@types/constants.ts
index 2dc5d19c4..1dbfb300b 100644
--- a/apps/renderer/src/@types/constants.ts
+++ b/apps/renderer/src/@types/constants.ts
@@ -4,6 +4,7 @@ export const dayjsLocaleImportMap = {
en: ["en", () => import("dayjs/locale/en")],
["zh-CN"]: ["zh-cn", () => import("dayjs/locale/zh-cn")],
["ja"]: ["ja", () => import("dayjs/locale/ja")],
+ ["fi"]: ["fi", () => import("dayjs/locale/fi")],
["it"]: ["it", () => import("dayjs/locale/it")],
["ar-DZ"]: ["ar-dz", () => import("dayjs/locale/ar-dz")],
["ar-SA"]: ["ar-sa", () => import("dayjs/locale/ar-sa")],
diff --git a/apps/renderer/src/@types/default-resource.ts b/apps/renderer/src/@types/default-resource.ts
index e65cf0110..d225fae54 100644
--- a/apps/renderer/src/@types/default-resource.ts
+++ b/apps/renderer/src/@types/default-resource.ts
@@ -4,6 +4,7 @@ import common_arma from "../../../../locales/common/ar-MA.json"
import common_arsa from "../../../../locales/common/ar-SA.json"
import common_en from "../../../../locales/common/en.json"
import common_es from "../../../../locales/common/es.json"
+import common_fi from "../../../../locales/common/fi.json"
import common_fr from "../../../../locales/common/fr.json"
import common_it from "../../../../locales/common/it.json"
import common_ja from "../../../../locales/common/ja.json"
@@ -17,6 +18,7 @@ import lang_arma from "../../../../locales/lang/ar-MA.json"
import lang_arsa from "../../../../locales/lang/ar-SA.json"
import lang_en from "../../../../locales/lang/en.json"
import lang_es from "../../../../locales/lang/es.json"
+import lang_fi from "../../../../locales/lang/fi.json"
import lang_fr from "../../../../locales/lang/fr.json"
import lang_it from "../../../../locales/lang/it.json"
import lang_ja from "../../../../locales/lang/ja.json"
@@ -50,6 +52,7 @@ export const defaultResources = {
lang: lang_ja,
common: common_ja,
},
+ fi: { lang: lang_fi, common: common_fi },
it: { lang: lang_it, common: common_it },
"ar-DZ": { lang: lang_ardz, common: common_ardz },
"ar-SA": { lang: lang_arsa, common: common_arsa },
diff --git a/locales/app/fi.json b/locales/app/fi.json
new file mode 100644
index 000000000..11dba1ad4
--- /dev/null
+++ b/locales/app/fi.json
@@ -0,0 +1,207 @@
+{
+ "ai_daily.title": "Pääuutiset - {{title}}",
+ "ai_daily.tooltip.content": "Tässä ovat uutiset, jotka AI on valinnut aikajanaltasi ( - ), ja jotka saattavat olla sinulle tärkeitä.",
+ "ai_daily.tooltip.update_schedule": "Päivitetään päivittäin klo 8 ja klo 20.",
+ "app.app_name": "SOVELLUKSEN_NIMI",
+ "app.copy_logo_svg": "Kopioi Logo SVG",
+ "app.toggle_sidebar": "Vaihda sivupalkki",
+ "discover.any_url_or_keyword": "Mikä tahansa URL tai avainsana",
+ "discover.default_option": " (oletus)",
+ "discover.feed_description": "Tämän syötteen kuvaus on seuraava, ja voit täyttää lomakkeen vastaavilla tiedoilla.",
+ "discover.feed_maintainers": "Tämän syötteen tarjoaa RSSHub, kiitos ",
+ "discover.import.click_to_upload": "Klikkaa ladataksesi OPML-tiedosto",
+ "discover.popular": "Suosittu",
+ "discover.preview": "Esikatselu",
+ "discover.rss_hub_route": "RSSHub-reitti",
+ "discover.rss_url": "RSS-URL",
+ "discover.select_placeholder": "Valitse",
+ "early_access": "Varhainen pääsy",
+ "entry_actions.copy_link": "Kopioi linkki",
+ "entry_actions.failed_to_save_to_eagle": "Tallennus Eagleen epäonnistui.",
+ "entry_actions.failed_to_save_to_instapaper": "Tallennus Instapaperiin epäonnistui.",
+ "entry_actions.failed_to_save_to_readwise": "Tallennus Readwiseen epäonnistui.",
+ "entry_actions.link_copied": "Linkki kopioitu leikepöydälle.",
+ "entry_actions.mark_as_read": "Merkitse luetuksi",
+ "entry_actions.mark_as_unread": "Merkitse lukemattomaksi",
+ "entry_actions.open_in_browser": "Avaa selaimessa",
+ "entry_actions.save_media_to_eagle": "Tallenna media Eagleen",
+ "entry_actions.save_to_instapaper": "Tallenna Instapaperiin",
+ "entry_actions.save_to_readwise": "Tallenna Readwiseen",
+ "entry_actions.saved_to_eagle": "Tallennettu Eagleen.",
+ "entry_actions.saved_to_instapaper": "Tallennettu Instapaperiin.",
+ "entry_actions.saved_to_readwise": "Tallennettu Readwiseen.",
+ "entry_actions.share": "Jaa",
+ "entry_actions.star": "Tähtää",
+ "entry_actions.starred": "Tähdätään.",
+ "entry_actions.tip": "Tippi",
+ "entry_actions.unstar": "Poista tähti",
+ "entry_actions.unstarred": "Tähti poistettu.",
+ "entry_column.refreshing": "Päivitetään uusia merkintöjä...",
+ "entry_content.ai_summary": "AI-yhteenveto",
+ "entry_content.fetching_content": "Noudetaan alkuperäistä sisältöä ja käsitellään...",
+ "entry_content.header.play_tts": "Toista TTS",
+ "entry_content.header.readability": "Luettavuus",
+ "entry_content.no_content": "Ei sisältöä",
+ "entry_content.readability_notice": "Tämä sisältö on saatavilla Readabilityn kautta. Jos huomaat typografisia ongelmia, käy lähdesivustolla katsomassa alkuperäinen sisältö.",
+ "entry_content.render_error": "Renderointivirhe:",
+ "entry_content.report_issue": "Ilmoita ongelmasta",
+ "entry_content.web_app_notice": "Verkkosovellus ei ehkä tue tätä sisältötyyppiä. Voit kuitenkin ladata työpöytäsovelluksen.",
+ "entry_list.zero_unread": "Ei lukemattomia",
+ "entry_list_header.daily_report": "Päivittäinen raportti",
+ "entry_list_header.hide_no_image_items": "Piilota merkinnät ilman kuvia",
+ "entry_list_header.items": "kohteet",
+ "entry_list_header.new_entries_available": "Uusia merkintöjä saatavilla",
+ "entry_list_header.refetch": "Päivitä",
+ "entry_list_header.refresh": "Virkistä",
+ "entry_list_header.show_all": "Näytä kaikki",
+ "entry_list_header.show_all_items": "Näytä kaikki merkintäkohteet",
+ "entry_list_header.show_unread_only": "Näytä vain lukemattomat",
+ "entry_list_header.switch_to_grid": "Vaihda ruudukkonäkymään",
+ "entry_list_header.switch_to_masonry": "Vaihda tiilinäkymään",
+ "entry_list_header.unread": "lukematon",
+ "feed_claim_modal.choose_verification_method": "Valittavana on kolme tapaa, voit valita yhden niistä vahvistaaksesi.",
+ "feed_claim_modal.claim_button": "Vahvista",
+ "feed_claim_modal.content_instructions": "Kopioi alla oleva sisältö ja julkaise se viimeisimpään RSS-syötteeseesi.",
+ "feed_claim_modal.description_current": "Nykyinen kuvaus:",
+ "feed_claim_modal.description_instructions": "Kopioi seuraava sisältö ja liitä se RSS-syötteen -kenttään.",
+ "feed_claim_modal.failed_to_load": "Vahvistusviestin lataus epäonnistui",
+ "feed_claim_modal.rss_format_choice": "RSS-generaattoreilla on yleensä kaksi valittavaa muotoa. Kopioi alla olevat XML- ja JSON-muodot tarpeen mukaan.",
+ "feed_claim_modal.rss_instructions": "Kopioi alla oleva koodi ja liitä se RSS-generaattoriisi.",
+ "feed_claim_modal.rss_json_format": "JSON-muoto",
+ "feed_claim_modal.rss_xml_format": "XML-muoto",
+ "feed_claim_modal.rsshub_notice": "Tämän syötteen tarjoaa RSSHub 1 tunnin välimuistilla. Muutosten näkyminen voi kestää jopa tunnin julkaisun jälkeen.",
+ "feed_claim_modal.tab_content": "Sisältö",
+ "feed_claim_modal.tab_description": "Kuvaus",
+ "feed_claim_modal.tab_rss": "RSS-tagi",
+ "feed_claim_modal.verify_ownership": "Vahvistaaksesi tämän syötteen omistajuuden sinun on vahvistettava omistusoikeus.",
+ "feed_form.add_follow": "Lisää seuraaminen",
+ "feed_form.category": "Kategoria",
+ "feed_form.category_description": "Oletuksena seuraamasi sivustot ryhmitellään verkkosivuston mukaan.",
+ "feed_form.error_fetching_feed": "Virhe syötteen noutamisessa.",
+ "feed_form.feed_not_found": "Syötettä ei löytynyt.",
+ "feed_form.feedback": "Palaute",
+ "feed_form.follow": "Seuraa",
+ "feed_form.followed": "🎉 Seurattu.",
+ "feed_form.private_follow": "Yksityinen seuraaminen",
+ "feed_form.private_follow_description": "Onko tämä seuranta julkisesti näkyvillä profiilisivullasi.",
+ "feed_form.retry": "Yritä uudelleen",
+ "feed_form.title": "Otsikko",
+ "feed_form.title_description": "Mukautettu otsikko tälle syötteelle. Jätä tyhjäksi käyttääksesi oletusotsikkoa.",
+ "feed_form.unfollow": "Lopeta seuraaminen",
+ "feed_form.update": "Päivitä",
+ "feed_form.update_follow": "Päivitä seuranta",
+ "feed_form.updated": "🎉 Päivitetty.",
+ "feed_form.view": "Näytä",
+ "feed_item.claimed_by_owner": "Tämän syötteen on vahvistanut",
+ "feed_item.claimed_by_unknown": "omistaja.",
+ "feed_item.claimed_by_you": "Sinun vahvistama syöte",
+ "feed_item.claimed_feed": "Vahvistettu syöte",
+ "feed_item.error_since": "Virhe alkaen",
+ "feed_item.not_publicly_visible": "Ei julkisesti näkyvissä profiilisivullasi",
+ "feed_view_type.articles": "Artikkelit",
+ "feed_view_type.audios": "Äänitteet",
+ "feed_view_type.notifications": "Ilmoitukset",
+ "feed_view_type.pictures": "Kuvat",
+ "feed_view_type.social_media": "Sosiaalinen media",
+ "feed_view_type.videos": "Videot",
+ "mark_all_read_button.auto_confirm_info": "Vahvistetaan automaattisesti 3 sekunnin kuluttua.",
+ "mark_all_read_button.confirm": "Vahvista",
+ "mark_all_read_button.confirm_mark_all": "Merkitäänkö {{which}} luetuksi?",
+ "mark_all_read_button.confirm_mark_all_info": "Vahvista kaikki merkinnät luetuiksi?",
+ "mark_all_read_button.mark_all_as_read": "Merkitse kaikki luetuiksi",
+ "mark_all_read_button.mark_as_read": "Merkitse {{which}} luetuksi",
+ "mark_all_read_button.undo": "Kumoa",
+ "player.back_10s": "Takaisin 10 sekuntia",
+ "player.close": "Sulje",
+ "player.download": "Lataa",
+ "player.exit_full_screen": "Poistu koko näytöstä",
+ "player.forward_10s": "Eteenpäin 10 sekuntia",
+ "player.full_screen": "Koko näyttö",
+ "player.mute": "Mykistä",
+ "player.open_entry": "Avaa merkintä",
+ "player.pause": "Tauko",
+ "player.play": "Toista",
+ "player.playback_rate": "Toistonopeus",
+ "player.unmute": "Poista mykistys",
+ "player.volume": "Äänenvoimakkuus",
+ "search.empty.no_results": "Ei tuloksia.",
+ "search.group.entries": "Merkinnät",
+ "search.group.feeds": "Syötteet",
+ "search.options.all": "Kaikki",
+ "search.options.entries": "Merkinnät",
+ "search.options.feeds": "Syötteet",
+ "search.options.search_type": "Hakutyyppi",
+ "search.placeholder": "Hae...",
+ "search.result_count_local_mode": "(Paikallinen tila)",
+ "search.tooltip.local_search": "Tämä haku kattaa paikallisesti saatavilla olevan datan. Kokeile päivittämistä sisällyttääksesi uusimmat tiedot.",
+ "shortcuts.guide.title": "Pikanäppäimet",
+ "sidebar.category_remove_dialog.cancel": "Peruuta",
+ "sidebar.category_remove_dialog.continue": "Jatka",
+ "sidebar.category_remove_dialog.description": "Tämä toiminto poistaa kategoriat, mutta niiden sisältämät syötteet säilyvät ja ryhmitellään verkkosivuston mukaan.",
+ "sidebar.category_remove_dialog.title": "Poista kategoria",
+ "sidebar.feed_actions.claim": "Vahvista",
+ "sidebar.feed_actions.claim_feed": "Vahvista syöte",
+ "sidebar.feed_actions.copy_feed_id": "Kopioi syötteen ID",
+ "sidebar.feed_actions.copy_feed_url": "Kopioi syötteen URL",
+ "sidebar.feed_actions.edit": "Muokkaa",
+ "sidebar.feed_actions.edit_feed": "Muokkaa syötettä",
+ "sidebar.feed_actions.feed_owned_by_you": "Tämä syöte on sinun omistuksessasi",
+ "sidebar.feed_actions.mark_all_as_read": "Merkitse kaikki luetuiksi",
+ "sidebar.feed_actions.navigate_to_feed": "Siirry syötteeseen",
+ "sidebar.feed_actions.open_feed_in_browser": "Avaa syöte selaimessa",
+ "sidebar.feed_actions.open_site_in_browser": "Avaa sivusto selaimessa",
+ "sidebar.feed_actions.unfollow": "Lopeta seuraaminen",
+ "sidebar.feed_actions.unfollow_feed": "Lopeta syötteen seuraaminen",
+ "sidebar.feed_column.context_menu.change_to_other_view": "Vaihda toiseen näkymään",
+ "sidebar.feed_column.context_menu.delete_category": "Poista kategoria",
+ "sidebar.feed_column.context_menu.delete_category_confirmation": "Poistetaanko kategoria {{folderName}}?",
+ "sidebar.feed_column.context_menu.mark_as_read": "Merkitse luetuksi",
+ "sidebar.feed_column.context_menu.rename_category": "Nimeä kategoria uudelleen",
+ "sidebar.select_sort_method": "Valitse lajittelutapa",
+ "signin.continue_with_github": "Jatka GitHubilla",
+ "signin.continue_with_google": "Jatka Googlella",
+ "signin.sign_in_to": "Kirjaudu sisään",
+ "sync_indicator.disabled": "Tietoturvasyistä synkronointi on poistettu käytöstä.",
+ "sync_indicator.offline": "Offline",
+ "sync_indicator.synced": "Synkronoitu palvelimen kanssa",
+ "tip_modal.amount": "Määrä",
+ "tip_modal.claim_feed": "Vahvista tämä syöte",
+ "tip_modal.create_wallet": "Luo ilmainen lompakko",
+ "tip_modal.feed_owner": "Syötteen omistaja",
+ "tip_modal.low_balance": "Saldosi ei riitä tämän tipin kattamiseen. Säädä summaa.",
+ "tip_modal.no_wallet": "Sinulla ei ole vielä lompakkoa. Luo lompakko tippiä varten.",
+ "tip_modal.tip_amount_sent": "on lähetetty kirjoittajalle.",
+ "tip_modal.tip_now": "Tiputa nyt",
+ "tip_modal.tip_sent": "Tiputus onnistui! Kiitos tuestasi.",
+ "tip_modal.tip_support": "⭐ Tiputa näyttääksesi tukesi!",
+ "tip_modal.unclaimed_feed": "Kukaan ei ole vielä vahvistanut tätä syötettä. Saatu Power tallennetaan turvallisesti lohkoketjun sopimukseen, kunnes se vahvistetaan.",
+ "user_button.account": "Tili",
+ "user_button.download_desktop_app": "Lataa työpöytäsovellus",
+ "user_button.log_out": "Kirjaudu ulos",
+ "user_button.power": "Power",
+ "user_button.preferences": "Asetukset",
+ "user_button.profile": "Profiili",
+ "user_profile.close": "Sulje",
+ "user_profile.edit": "Muokkaa",
+ "user_profile.loading": "Ladataan",
+ "user_profile.share": "Jaa",
+ "user_profile.toggle_item_style": "Vaihda kohteiden tyyliä",
+ "words.add": "Lisää",
+ "words.confirm": "Vahvista",
+ "words.discover": "Löydä",
+ "words.email": "Sähköposti",
+ "words.import": "Tuo",
+ "words.items": "Kohteet",
+ "words.language": "Kieli",
+ "words.load_archived_entries": "Lataa arkistoidut merkinnät",
+ "words.login": "Kirjaudu sisään",
+ "words.rss": "RSS",
+ "words.rss3": "RSS3",
+ "words.rsshub": "RSSHub",
+ "words.search": "Hae",
+ "words.starred": "Tähdät",
+ "words.unread": "Lukematon",
+ "words.user": "Käyttäjä",
+ "words.which.all": "kaikki",
+ "words.zero_items": "Ei kohteita"
+}
diff --git a/locales/common/fi.json b/locales/common/fi.json
new file mode 100644
index 000000000..06c594ab2
--- /dev/null
+++ b/locales/common/fi.json
@@ -0,0 +1,28 @@
+{
+ "app.copied_to_clipboard": "Kopioitu leikepöydälle",
+ "cancel": "Peruuta",
+ "confirm": "Vahvista",
+ "ok": "OK",
+ "quantifier.piece": "",
+ "time.last_night": "Viime yö",
+ "time.the_night_before_last": "Toissa yö",
+ "time.today": "Tänään",
+ "time.yesterday": "Eilen",
+ "tips.load-lng-error": "Kielipaketin lataaminen epäonnistui",
+ "words.back": "Takaisin",
+ "words.copy": "Kopioi",
+ "words.edit": "Muokkaa",
+ "words.entry": "Merkintä",
+ "words.id": "ID",
+ "words.items_one": "Kohde",
+ "words.items_other": "Kohteet",
+ "words.local": "paikallinen",
+ "words.record": "tietue",
+ "words.record_one": "tietue",
+ "words.record_other": "tietueet",
+ "words.result": "tulos",
+ "words.result_one": "tulos",
+ "words.result_other": "tulokset",
+ "words.space": " ",
+ "words.which.all": "Kaikki"
+}
diff --git a/locales/external/fi.json b/locales/external/fi.json
new file mode 100644
index 000000000..e596c13c7
--- /dev/null
+++ b/locales/external/fi.json
@@ -0,0 +1,42 @@
+{
+ "feed": {
+ "follow_one": "seuraa",
+ "follow_other": "seuraajat",
+ "followsAndReads": "{{subscriptionCount}} {{subscriptionNoun}} ja {{readCount}} {{readNoun}} palvelussa {{appName}}",
+ "read_one": "lue",
+ "read_other": "lukee"
+ },
+ "header": {
+ "app": "Sovellus",
+ "download": "Lataa"
+ },
+ "invitation": {
+ "activate": "Aktivoi",
+ "codeOptions": {
+ "1": "Etsi mikä tahansa alpha-testaaja kutsumaan sinut.",
+ "2": "Liity Discord-palvelimeemme satunnaisia arvontoja varten.",
+ "3": "Seuraa X-tiliämme satunnaisia arvontoja varten."
+ },
+ "earlyAccess": "Follow on tällä hetkellä varhaisessa käytössä ja vaatii kutsukoodin.",
+ "earlyAccessMessage": "😰 Pahoittelut, Follow on tällä hetkellä varhaisessa käytössä ja vaatii kutsukoodin.",
+ "generateButton": "Luo uusi koodi",
+ "generateCost": "Voit käyttää {{INVITATION_PRICE}} Poweria luodaksesi kutsukoodin ystävillesi.",
+ "getCodeMessage": "Voit saada kutsukoodin seuraavilla tavoilla:",
+ "title": "Kutsukoodi"
+ },
+ "login": {
+ "backToWebApp": "Takaisin verkkosovellukseen",
+ "continueWithGitHub": "Jatka GitHubilla",
+ "continueWithGoogle": "Jatka Googlella",
+ "logInTo": "Kirjaudu sisään ",
+ "openApp": "Avaa sovellus",
+ "redirecting": "Uudelleenohjataan",
+ "welcomeTo": "Tervetuloa "
+ },
+ "redirect": {
+ "continueInBrowser": "Jatka selaimessa",
+ "instruction": "Nyt on aika avata {{APP_NAME}} ja sulkea tämä sivu turvallisesti.",
+ "openApp": "Avaa {{APP_NAME}}",
+ "successMessage": "Olet onnistuneesti yhdistänyt {{APP_NAME}}-tilisi."
+ }
+}
diff --git a/locales/lang/ar-dz.json b/locales/lang/ar-dz.json
new file mode 100644
index 000000000..5de2332c3
--- /dev/null
+++ b/locales/lang/ar-dz.json
@@ -0,0 +1,14 @@
+{
+ "langs.ar-DZ": "العربية (الجزائر)",
+ "langs.ar-MA": "العربية (المغرب)",
+ "langs.ar-SA": "العربية (السعودية)",
+ "langs.en": "English",
+ "langs.es": "Español",
+ "langs.fr": "Français",
+ "langs.ja": "日本語",
+ "langs.pt": "Português",
+ "langs.zh-CN": "简体中文",
+ "langs.zh-HK": "繁體中文(香港)",
+ "langs.zh-TW": "繁體中文(台灣)",
+ "name": "العربية (الجزائر)"
+}
diff --git a/locales/lang/ar-ma.json b/locales/lang/ar-ma.json
new file mode 100644
index 000000000..570a057d2
--- /dev/null
+++ b/locales/lang/ar-ma.json
@@ -0,0 +1,14 @@
+{
+ "langs.ar-DZ": "العربية (الجزائر)",
+ "langs.ar-MA": "العربية (المغرب)",
+ "langs.ar-SA": "العربية (السعودية)",
+ "langs.en": "English",
+ "langs.es": "Español",
+ "langs.fr": "Français",
+ "langs.ja": "日本語",
+ "langs.pt": "Português",
+ "langs.zh-CN": "简体中文",
+ "langs.zh-HK": "繁體中文(香港)",
+ "langs.zh-TW": "繁體中文(台灣)",
+ "name": "العربية (المغرب)"
+}
diff --git a/locales/lang/ar-sa.json b/locales/lang/ar-sa.json
new file mode 100644
index 000000000..fd3a99524
--- /dev/null
+++ b/locales/lang/ar-sa.json
@@ -0,0 +1,14 @@
+{
+ "langs.ar-DZ": "العربية (الجزائر)",
+ "langs.ar-MA": "العربية (المغرب)",
+ "langs.ar-SA": "العربية (السعودية)",
+ "langs.en": "English",
+ "langs.es": "Español",
+ "langs.fr": "Français",
+ "langs.ja": "日本語",
+ "langs.pt": "Português",
+ "langs.zh-CN": "简体中文",
+ "langs.zh-HK": "繁體中文(香港)",
+ "langs.zh-TW": "繁體中文(台灣)",
+ "name": "العربية (السعودية)"
+}
diff --git a/locales/lang/en.json b/locales/lang/en.json
index 5f3543e77..134bdbaf0 100644
--- a/locales/lang/en.json
+++ b/locales/lang/en.json
@@ -4,6 +4,7 @@
"langs.ar-SA": "العربية (السعودية)",
"langs.en": "English",
"langs.es": "Español",
+ "langs.fi": "Suomi",
"langs.fr": "Français",
"langs.it": "Italiano",
"langs.ja": "日本語",
diff --git a/locales/lang/es.json b/locales/lang/es.json
index e047abf07..18b6c5492 100644
--- a/locales/lang/es.json
+++ b/locales/lang/es.json
@@ -4,6 +4,7 @@
"langs.ar-SA": "العربية (السعودية)",
"langs.en": "English",
"langs.es": "Español",
+ "langs.fi": "Suomi",
"langs.fr": "Français",
"langs.it": "Italiano",
"langs.ja": "日本語",
diff --git a/locales/lang/fi.json b/locales/lang/fi.json
new file mode 100644
index 000000000..072495f88
--- /dev/null
+++ b/locales/lang/fi.json
@@ -0,0 +1,14 @@
+{
+ "langs.ar-dz": "العربية (الجزائر)",
+ "langs.ar-ma": "العربية (المغرب)",
+ "langs.ar-sa": "العربية (السعودية)",
+ "langs.en": "English",
+ "langs.es": "Español",
+ "langs.fi": "Suomi",
+ "langs.fr": "Français",
+ "langs.ja": "日本語",
+ "langs.pt": "Português",
+ "langs.zh-CN": "简体中文",
+ "langs.zh-TW": "繁體中文(台灣)",
+ "name": "Suomi"
+}
diff --git a/locales/lang/fr.json b/locales/lang/fr.json
index d9afb444d..d4222a8d1 100644
--- a/locales/lang/fr.json
+++ b/locales/lang/fr.json
@@ -4,6 +4,7 @@
"langs.ar-SA": "العربية (السعودية)",
"langs.en": "English",
"langs.es": "Español",
+ "langs.fi": "Suomi",
"langs.fr": "Français",
"langs.it": "Italiano",
"langs.ja": "日本語",
diff --git a/locales/lang/ja.json b/locales/lang/ja.json
index 84bc61408..3e646b787 100644
--- a/locales/lang/ja.json
+++ b/locales/lang/ja.json
@@ -4,6 +4,7 @@
"langs.ar-SA": "العربية (السعودية)",
"langs.en": "English",
"langs.es": "Español",
+ "langs.fi": "Suomi",
"langs.fr": "Français",
"langs.it": "Italiano",
"langs.ja": "日本語",
diff --git a/locales/lang/pt.json b/locales/lang/pt.json
index e73e59365..507664d37 100644
--- a/locales/lang/pt.json
+++ b/locales/lang/pt.json
@@ -4,6 +4,7 @@
"langs.ar-SA": "العربية (السعودية)",
"langs.en": "English",
"langs.es": "Español",
+ "langs.fi": "Suomi",
"langs.fr": "Français",
"langs.it": "Italiano",
"langs.ja": "日本語",
diff --git a/locales/lang/zh-CN.json b/locales/lang/zh-CN.json
index a647fd08b..bc796f7a9 100644
--- a/locales/lang/zh-CN.json
+++ b/locales/lang/zh-CN.json
@@ -4,6 +4,7 @@
"langs.ar-SA": "العربية (السعودية)",
"langs.en": "English",
"langs.es": "Español",
+ "langs.fi": "Suomi",
"langs.fr": "Français",
"langs.it": "Italiano",
"langs.ja": "日本語",
diff --git a/locales/lang/zh-TW.json b/locales/lang/zh-TW.json
index 842347a65..c39bd792f 100644
--- a/locales/lang/zh-TW.json
+++ b/locales/lang/zh-TW.json
@@ -4,6 +4,7 @@
"langs.ar-SA": "العربية (السعودية)",
"langs.en": "English",
"langs.es": "Español",
+ "langs.fi": "Suomi",
"langs.fr": "Français",
"langs.it": "Italiano",
"langs.ja": "日本語",
diff --git a/locales/settings/fi.json b/locales/settings/fi.json
new file mode 100644
index 000000000..9c65e2f16
--- /dev/null
+++ b/locales/settings/fi.json
@@ -0,0 +1,195 @@
+{
+ "about.changelog": "Muutosloki",
+ "about.feedbackInfo": "{{appName}} ({{commitSha}}) on kehityksen alkuvaiheessa. Jos sinulla on palautetta tai ehdotuksia, voit vapaasti avata ongelmaraportin GitHubissamme.",
+ "about.iconLibrary": "Käytetty kuvakekirjasto on tekijänoikeuden alainen , eikä sitä saa levittää uudelleen.",
+ "about.licenseInfo": "{{appName}} on ja tulee aina olemaan ilmainen ja avoimen lähdekoodin projekti. Se on lisensoitu {{license}}-lisenssillä.",
+ "about.sidebar_title": "Tietoa",
+ "about.socialMedia": "Sosiaalinen media",
+ "actions.actionName": "Toiminto {{number}}",
+ "actions.action_card.add": "Lisää",
+ "actions.action_card.all": "Kaikki",
+ "actions.action_card.block_rules": "Estosäännöt",
+ "actions.action_card.custom_filters": "Mukautetut suodattimet",
+ "actions.action_card.enable_readability": "Ota luettavuus käyttöön",
+ "actions.action_card.entry_options.all": "Kaikki",
+ "actions.action_card.entry_options.author": "Tekijä",
+ "actions.action_card.entry_options.content": "Sisältö",
+ "actions.action_card.entry_options.order": "Järjestys",
+ "actions.action_card.entry_options.title": "Otsikko",
+ "actions.action_card.entry_options.url": "URL",
+ "actions.action_card.feed_options.category": "Kategoria",
+ "actions.action_card.feed_options.feed_url": "Syötteen URL",
+ "actions.action_card.feed_options.site_url": "Sivuston URL",
+ "actions.action_card.feed_options.title": "Otsikko",
+ "actions.action_card.feed_options.view": "Näkymä",
+ "actions.action_card.field": "Kenttä",
+ "actions.action_card.from": "Lähde",
+ "actions.action_card.generate_summary": "Luo yhteenveto tekoälyn avulla",
+ "actions.action_card.name": "Nimi",
+ "actions.action_card.operation_options.contains": "sisältää",
+ "actions.action_card.operation_options.does_not_contain": "ei sisällä",
+ "actions.action_card.operation_options.is_equal_to": "on yhtä suuri kuin",
+ "actions.action_card.operation_options.is_greater_than": "on suurempi kuin",
+ "actions.action_card.operation_options.is_less_than": "on pienempi kuin",
+ "actions.action_card.operation_options.is_not_equal_to": "ei ole yhtä suuri kuin",
+ "actions.action_card.operation_options.matches_regex": "vastaa regexiä",
+ "actions.action_card.operator": "Operaattori",
+ "actions.action_card.rewrite_rules": "Uudelleenkirjoitussäännöt",
+ "actions.action_card.then_do": "Sitten tee…",
+ "actions.action_card.to": "Kohde",
+ "actions.action_card.translate_into": "Käännä kielelle",
+ "actions.action_card.value": "Arvo",
+ "actions.action_card.when_feeds_match": "Kun syötteet täsmäävät…",
+ "actions.newRule": "Uusi sääntö",
+ "actions.save": "Tallenna",
+ "actions.saveSuccess": "🎉 Toiminnot tallennettu.",
+ "actions.sidebar_title": "Toiminnot",
+ "actions.title": "Toiminnot",
+ "appearance.code_highlight_theme": "Koodin korostusteema",
+ "appearance.content": "Sisältö",
+ "appearance.content_font": "Sisällön fontti",
+ "appearance.custom_font": "Mukautettu fontti",
+ "appearance.fonts": "Fontit",
+ "appearance.general": "Yleiset",
+ "appearance.guess_code_language.description": "Tärkeimmät ohjelmointikielet, jotka käyttävät malleja tunnistamaan merkitsemättömiä koodilohkoja",
+ "appearance.guess_code_language.label": "Arvaa koodin kieli",
+ "appearance.misc": "Sekalaista",
+ "appearance.modal_overlay.description": "Näytä modaalinen peite",
+ "appearance.modal_overlay.label": "Näytä modaalinen peite",
+ "appearance.opaque_sidebars.label": "Läpinäkymättömät sivupalkit",
+ "appearance.reader_render_inline_style.description": "Mahdollistaa alkuperäisen HTML:n inline-tyylin renderöinnin.",
+ "appearance.reader_render_inline_style.label": "Renderöi inline-tyyli",
+ "appearance.reduce_motion.description": "Vähentää elementtien liikettä parantaakseen suorituskykyä ja vähentääkseen energiankulutusta",
+ "appearance.reduce_motion.label": "Vähennä liikettä",
+ "appearance.save": "Tallenna",
+ "appearance.show_dock_badge.label": "Näytä Dock-merkin yhteydessä",
+ "appearance.sidebar_show_unread_count.label": "Näytä sivupalkissa",
+ "appearance.sidebar_title": "Ulkoasu",
+ "appearance.text_size": "Tekstin koko",
+ "appearance.theme.dark": "Tumma",
+ "appearance.theme.label": "Teema",
+ "appearance.theme.light": "Vaalea",
+ "appearance.theme.system": "Järjestelmä",
+ "appearance.title": "Ulkoasu",
+ "appearance.ui_font": "Käyttöliittymän fontti",
+ "appearance.unread_count": "Lukemattomien määrä",
+ "general.app": "Sovellus",
+ "general.data_persist.description": "Säilytä dataa paikallisesti mahdollistamaan offline-käyttö ja paikallinen haku.",
+ "general.data_persist.label": "Säilytä dataa offline-käyttöä varten",
+ "general.group_by_date.description": "Ryhmittele merkinnät päivämäärän mukaan.",
+ "general.group_by_date.label": "Ryhmittele päivämäärän mukaan",
+ "general.language": "Kieli",
+ "general.launch_at_login": "Käynnistä kirjautumisen yhteydessä",
+ "general.mark_as_read.hover.description": "Merkitse merkinnät automaattisesti luetuiksi, kun niiden päällä leijuu.",
+ "general.mark_as_read.hover.label": "Merkitse luetuksi leijuttaessa",
+ "general.mark_as_read.render.description": "Merkitse yksitasoiset merkinnät (esim. sosiaalisen median julkaisut, kuvat, videot) automaattisesti luetuiksi, kun ne tulevat näkyviin.",
+ "general.mark_as_read.render.label": "Merkitse luetuksi, kun näkyvissä",
+ "general.mark_as_read.scroll.description": "Merkitse merkinnät automaattisesti luetuiksi, kun ne vieritetään pois näkymästä.",
+ "general.mark_as_read.scroll.label": "Merkitse luetuksi vierittäessä",
+ "general.privacy_data": "Yksityisyys ja data",
+ "general.rebuild_database.button": "Rakenna uudelleen",
+ "general.rebuild_database.description": "Jos kohtaat renderöintiongelmia, tietokannan uudelleenrakentaminen saattaa ratkaista ne.",
+ "general.rebuild_database.label": "Rakenna tietokanta uudelleen",
+ "general.rebuild_database.title": "Rakenna tietokanta uudelleen",
+ "general.rebuild_database.warning.line1": "Tietokannan uudelleenrakentaminen tyhjentää kaikki paikalliset tietosi.",
+ "general.rebuild_database.warning.line2": "Haluatko varmasti jatkaa?",
+ "general.send_anonymous_data.description": "Valitsemalla anonyymien telemetriatietojen lähettämisen autat parantamaan Follow'n yleistä käyttäjäkokemusta.",
+ "general.send_anonymous_data.label": "Lähetä anonyymejä tietoja",
+ "general.show_unread_on_launch.description": "Näytä lukematon sisältö käynnistyksessä",
+ "general.show_unread_on_launch.label": "Näytä lukematon sisältö käynnistyksessä",
+ "general.sidebar_title": "Yleiset",
+ "general.timeline": "Aikajana",
+ "general.unread": "Lukematon",
+ "general.voices": "Äänet",
+ "integration.eagle.enable.description": "Näytä 'Tallenna media Eagleen' -painike, kun saatavilla.",
+ "integration.eagle.enable.label": "Ota käyttöön",
+ "integration.eagle.title": "Eagle",
+ "integration.instapaper.enable.description": "Näytä 'Tallenna Instapaperiin' -painike, kun saatavilla.",
+ "integration.instapaper.enable.label": "Ota käyttöön",
+ "integration.instapaper.password.label": "Instapaper-salasana",
+ "integration.instapaper.title": "Instapaper",
+ "integration.instapaper.username.label": "Instapaper-käyttäjänimi",
+ "integration.readwise.enable.description": "Näytä 'Tallenna Readwiseen' -painike, kun saatavilla.",
+ "integration.readwise.enable.label": "Ota käyttöön",
+ "integration.readwise.title": "Readwise",
+ "integration.readwise.token.description": "Voit saada sen täältä: readwise.io/access_token.",
+ "integration.readwise.token.label": "Readwise Access Token",
+ "integration.sidebar_title": "Integraatiot",
+ "integration.tip": "Vinkki: Arkaluontoiset tietosi tallennetaan paikallisesti eikä niitä lähetetä palvelimelle.",
+ "integration.title": "Integraatiot",
+ "invitation.activate": "Aktivoi",
+ "invitation.codeOptions.betaUser": "1. Etsi beta-käyttäjä, joka kutsuu sinut.",
+ "invitation.codeOptions.discord": "2. Liity Discord-palvelimellemme satunnaisia lahjoja varten.",
+ "invitation.codeOptions.xAccount": "3. Seuraa X-tiliämme ja saat ajoittain lahjoja.",
+ "invitation.confirmModal.cancel": "Peruuta",
+ "invitation.confirmModal.confirm": "Haluatko jatkaa?",
+ "invitation.confirmModal.continue": "Jatka",
+ "invitation.confirmModal.message": "Kutsukoodin luominen maksaa sinulle {{INVITATION_PRICE}} Poweria.",
+ "invitation.confirmModal.title": "Vahvista",
+ "invitation.earlyAccess": "Follow on tällä hetkellä varhaisessa käytössä ja vaatii kutsukoodin.",
+ "invitation.earlyAccessMessage": "😰 Pahoittelut, Follow on tällä hetkellä varhaisessa käytössä ja vaatii kutsukoodin.",
+ "invitation.generateButton": "Luo uusi koodi",
+ "invitation.generateCost": "Voit käyttää {{INVITATION_PRICE}} Poweria luodaksesi kutsukoodin ystävillesi.",
+ "invitation.getCodeMessage": "Voit saada kutsukoodin seuraavilla tavoilla:",
+ "invitation.newInvitationSuccess": "🎉 Uusi kutsu luotu, kutsukoodi kopioitu",
+ "invitation.noInvitations": "Ei kutsuja",
+ "invitation.notUsed": "Ei käytetty",
+ "invitation.sidebar_title": "Kutsut",
+ "invitation.tableHeaders.code": "Koodi",
+ "invitation.tableHeaders.creationTime": "Luomisaika",
+ "invitation.tableHeaders.usedBy": "Käyttänyt",
+ "invitation.title": "Kutsukoodi",
+ "profile.avatar.label": "Avatar",
+ "profile.handle.description": "Yksilöllinen tunnisteesi.",
+ "profile.handle.label": "Käyttäjänimi",
+ "profile.name.description": "Julkinen näyttönimesi.",
+ "profile.name.label": "Näyttönimi",
+ "profile.sidebar_title": "Profiili",
+ "profile.submit": "Lähetä",
+ "profile.title": "Profiiliasetukset",
+ "profile.updateSuccess": "Profiili päivitetty.",
+ "titles.about": "Tietoa",
+ "titles.actions": "Toiminnot",
+ "titles.appearance": "Ulkoasu",
+ "titles.general": "Yleiset",
+ "titles.integration": "Integraatiot",
+ "titles.invitations": "Kutsut",
+ "titles.power": "Power",
+ "titles.profile": "Profiili",
+ "titles.shortcuts": "Pikanäppäimet",
+ "wallet.address.title": "Osoitteesi",
+ "wallet.balance.title": "Saldosi",
+ "wallet.balance.withdrawable": "Nostettavissa",
+ "wallet.balance.withdrawableTooltip": "Nostettavissa oleva Power sisältää sekä saamasi tipit että lataamasi Powerin.",
+ "wallet.claim.button.claim": "Vahvista päivittäinen Power",
+ "wallet.claim.button.claimed": "Vahvistettu tänään",
+ "wallet.claim.tooltip.alreadyClaimed": "Olet jo vahvistanut tänään.",
+ "wallet.claim.tooltip.canClaim": "Vahvista {{amount}} päivittäinen Powerisi nyt!",
+ "wallet.create.button": "Luo lompakko",
+ "wallet.create.description": "Luo ilmainen lompakko vastaanottaaksesi Poweria, jota voit käyttää palkitaksesi tekijöitä ja saadaksesi palkintoja sisällön tuottamisesta.",
+ "wallet.power.dailyClaim": "Voit vahvistaa {{amount}} ilmaista Poweria päivittäin, jota voit käyttää tipataksesi RSS-merkintöjä Follow'ssa.",
+ "wallet.power.description": "Power on ERC-20-token {{blockchainName}}-lohkoketjussa.",
+ "wallet.sidebar_title": "Power",
+ "wallet.transactions.amount": "Määrä",
+ "wallet.transactions.date": "Päivämäärä",
+ "wallet.transactions.from": "Lähettäjä",
+ "wallet.transactions.noTransactions": "Ei tapahtumia",
+ "wallet.transactions.title": "Tapahtumat",
+ "wallet.transactions.to": "Vastaanottaja",
+ "wallet.transactions.tx": "Tx",
+ "wallet.transactions.type": "Tyyppi",
+ "wallet.transactions.types.burn": "poltto",
+ "wallet.transactions.types.mint": "lyönti",
+ "wallet.transactions.types.purchase": "osto",
+ "wallet.transactions.types.tip": "tippi",
+ "wallet.transactions.types.withdraw": "nosto",
+ "wallet.transactions.you": "Sinä",
+ "wallet.withdraw.addressLabel": "Ethereum-osoitteesi",
+ "wallet.withdraw.amountLabel": "Määrä",
+ "wallet.withdraw.availableBalance": "Sinulla on nostettavissa olevaa Poweria lompakossasi.",
+ "wallet.withdraw.button": "Nosta",
+ "wallet.withdraw.error": "Nosto epäonnistui: {{error}}",
+ "wallet.withdraw.modalTitle": "Nosta Poweria",
+ "wallet.withdraw.submitButton": "Lähetä",
+ "wallet.withdraw.success": "Nosto onnistui!"
+}
diff --git a/locales/shortcuts/fi.json b/locales/shortcuts/fi.json
new file mode 100644
index 000000000..4dc488e61
--- /dev/null
+++ b/locales/shortcuts/fi.json
@@ -0,0 +1,24 @@
+{
+ "keys.audio.playPause": "Toista/Tauko (Kun äänisoitin on auki)",
+ "keys.entries.markAllAsRead": "Merkitse kaikki luetuiksi",
+ "keys.entries.next": "Seuraava merkintä",
+ "keys.entries.previous": "Edellinen merkintä",
+ "keys.entries.refetch": "Päivitä",
+ "keys.entries.toggleUnreadOnly": "Näytä vain lukemattomat",
+ "keys.entry.copyLink": "Kopioi linkki",
+ "keys.entry.openInBrowser": "Avaa selaimessa",
+ "keys.entry.openInNewTab": "Avaa uudessa välilehdessä",
+ "keys.entry.scrollDown": "Vieritä alas",
+ "keys.entry.scrollUp": "Vieritä ylös",
+ "keys.entry.share": "Jaa",
+ "keys.entry.tip": "Anna Power-tip",
+ "keys.entry.toggleRead": "Vaihda luettu tila",
+ "keys.entry.toggleStarred": "Vaihda suosikkitila",
+ "keys.entry.tts": "Toista TTS",
+ "keys.feeds.add": "Lisää tilaus",
+ "keys.feeds.switchBetweenViews": "Vaihda näkymien välillä",
+ "keys.feeds.switchToView": "Vaihda näkymään",
+ "keys.layout.showShortcuts": "Näytä/Piilota pikanäppäimet",
+ "keys.layout.toggleSidebar": "Näytä/Piilota syötteen sivupalkki",
+ "sidebar_title": "Pikanäppäimet"
+}