Skip to content

Commit

Permalink
Merge pull request #198 from alephium/translations
Browse files Browse the repository at this point in the history
Set up i18n and integrate extension to Crowdin
  • Loading branch information
h0ngcha0 authored Jun 18, 2024
2 parents a6c7ecb + 21641e5 commit 86e7e46
Show file tree
Hide file tree
Showing 9 changed files with 498 additions and 7 deletions.
36 changes: 36 additions & 0 deletions .github/workflows/translations-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: Sync translations

on:
workflow_dispatch:
push:
paths: ["packages/extension/locales/**"]
branches: [master]

permissions:
contents: write
pull-requests: write

jobs:
sync-translations:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Sync sources and translations
uses: crowdin/github-action@v2
with:
config: "crowdin.yml"
upload_sources: true
upload_translations: true
download_translations: true
export_only_approved: true
localization_branch_name: l10n_crowdin_translations
create_pull_request: true
pull_request_title: "New Crowdin translations"
pull_request_body: "New translations from Crowdin."
pull_request_base_branch_name: "master"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
126 changes: 126 additions & 0 deletions crowdin.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#
# Your Crowdin credentials
#
"project_id_env": "CROWDIN_PROJECT_ID"
"api_token_env": "CROWDIN_PERSONAL_TOKEN"
"base_path": "."
"base_url": "https://api.crowdin.com"

#
# Choose file structure in Crowdin
# e.g. true or false
#
"preserve_hierarchy": true

#
# Files configuration
#
files: [
{
#
# Source files filter
# e.g. "/resources/en/*.json"
#
"source": "/packages/extension/locales/en-US/translation.json",

#
# Where translations will be placed
# e.g. "/resources/%two_letters_code%/%original_file_name%"
#
"translation": "/packages/extension/locales/%locale%/%original_file_name%",
#
# Files or directories for ignore
# e.g. ["/**/?.txt", "/**/[0-9].txt", "/**/*\?*.txt"]
#
# "ignore": [],

#
# The dest allows you to specify a file name in Crowdin
# e.g. "/messages.json"
#
# "dest": "",

#
# File type
# e.g. "json"
#
# "type": "",

#
# The parameter "update_option" is optional. If it is not set, after the files update the translations for changed strings will be removed. Use to fix typos and for minor changes in the source strings
# e.g. "update_as_unapproved" or "update_without_changes"
#
# "update_option": "",

#
# Start block (for XML only)
#

#
# Defines whether to translate tags attributes.
# e.g. 0 or 1 (Default is 1)
#
# "translate_attributes": 1,

#
# Defines whether to translate texts placed inside the tags.
# e.g. 0 or 1 (Default is 1)
#
# "translate_content": 1,

#
# This is an array of strings, where each item is the XPaths to DOM element that should be imported
# e.g. ["/content/text", "/content/text[@value]"]
#
# "translatable_elements": [],

#
# Defines whether to split long texts into smaller text segments
# e.g. 0 or 1 (Default is 1)
#
# "content_segmentation": 1,

#
# End block (for XML only)
#

#
# Start .properties block
#

#
# Defines whether single quote should be escaped by another single quote or backslash in exported translations
# e.g. 0 or 1 or 2 or 3 (Default is 3)
# 0 - do not escape single quote;
# 1 - escape single quote by another single quote;
# 2 - escape single quote by backslash;
# 3 - escape single quote by another single quote only in strings containing variables ( {0} ).
#
# "escape_quotes": 3,

#
# Defines whether any special characters (=, :, ! and #) should be escaped by backslash in exported translations.
# e.g. 0 or 1 (Default is 0)
# 0 - do not escape special characters
# 1 - escape special characters by a backslash
#
# "escape_special_characters": 0
#

#
# End .properties block
#

#
# Does the first line contain header?
# e.g. true or false
#
# "first_line_contains_header": true,

#
# for spreadsheets
# e.g. "identifier,source_phrase,context,uk,ru,fr"
#
# "scheme": "",
},
]
6 changes: 6 additions & 0 deletions packages/extension/locales/en-US/translation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"Welcome to Alephium": "Welcome to Alephium",
"A New Paradigm": "A New Paradigm",
"Create a new wallet": "Create a new wallet",
"Restore an existing wallet": "Restore an existing wallet"
}
2 changes: 2 additions & 0 deletions packages/extension/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
"colord": "^2.9.2",
"cross-env": "^7.0.3",
"ethers": "^5.5.1",
"i18next": "^23.11.5",
"jose": "^4.3.6",
"lodash-es": "^4.17.21",
"lucide-react": "^0.88.0",
Expand All @@ -110,6 +111,7 @@
"react-dom": "^18.0.0",
"react-dropzone": "^14.0.0",
"react-hook-form": "^7.33.0",
"react-i18next": "^14.1.2",
"react-measure": "^2.5.2",
"react-router-dom": "^6.0.1",
"react-select": "^5.4.0",
Expand Down
35 changes: 35 additions & 0 deletions packages/extension/src/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Copyright 2018 - 2024 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import i18next from "i18next"
import { initReactI18next } from "react-i18next"

import en from "../locales/en-US/translation.json"

i18next.use(initReactI18next).init({
resources: {
"en-US": { translation: en },
},
lng: "en-US",
fallbackLng: "en-US",
interpolation: {
escapeValue: false,
},
})

export default i18next
33 changes: 33 additions & 0 deletions packages/extension/src/i18next.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
Copyright 2018 - 2024 The Alephium Authors
This file is part of the alephium project.
The library is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
The library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import "i18next"

import en from "../locales/en-US/translation.json"

type EnglishTranslationKeys = typeof en

export type TranslationKey = keyof EnglishTranslationKeys

declare module "i18next" {
interface CustomTypeOptions {
resources: {
translation: EnglishTranslationKeys
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FC, useEffect, useRef } from "react"
import { useTranslation } from "react-i18next"
import { useNavigate } from "react-router-dom"

import {
Expand All @@ -20,6 +21,7 @@ export const OnboardingStartScreen: FC = () => {
const didRunInit = useRef(false)
const navigate = useNavigate()
usePageTracking("welcome")
const { t } = useTranslation()

useEffect(() => {
const init = async () => {
Expand All @@ -42,21 +44,21 @@ export const OnboardingStartScreen: FC = () => {
<OnboardingScreen
length={4}
currentIndex={0}
title="Welcome to Alephium"
subtitle="A New Paradigm"
title={t("Welcome to Alephium")}
subtitle={t("A New Paradigm")}
>
<Row gap={"12px"} align="stretch">
<RectButton onClick={() => navigate(routes.onboardingPassword())}>
<CreateWalletRectButtonIcon>
<AccountBalanceWalletIcon />
</CreateWalletRectButtonIcon>
Create a new wallet
{t("Create a new wallet")}
</RectButton>
<RectButton onClick={() => navigate(routes.onboardingRestoreSeed())}>
<RestoreWalletRectButtonIcon>
<RefreshIcon />
</RestoreWalletRectButtonIcon>
Restore an existing wallet
{t("Restore an existing wallet")}
</RectButton>
</Row>
</OnboardingScreen>
Expand Down
2 changes: 2 additions & 0 deletions packages/extension/src/ui/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import "../i18n"

import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import { BrowserRouter } from "react-router-dom"
Expand Down
Loading

0 comments on commit 86e7e46

Please sign in to comment.