-
Notifications
You must be signed in to change notification settings - Fork 349
Add internationalisation support #188
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
658304c
Wrap all strings in _td function for i18n
germain-gg 1050707
Make application react to element-web language change
germain-gg e950303
stop using experimental class private methods
germain-gg 00ba421
Add labels to role-only menu item to have consistent languages in menu
germain-gg d59384f
Add internationalisation documentation
germain-gg c56aa91
appease max line length linting rule
germain-gg b9510d0
use _t over _td for consistency with element-web
germain-gg ae0213b
Move i18n scripts in its own module
germain-gg de16099
Add required weblate basefile
turt2live 72483a6
Add diff-i18n script for CI
germain-gg 20ce3d1
add missing copyright header
germain-gg 8f4c827
change translate widget project ID
germain-gg 8ae641b
Set appropriate appMenu submenu role
germain-gg 46b1015
Fix typo in _t function declaration
germain-gg e64e6e6
Upgrade matrix-web-i18n to use matrix prefixed binaries
germain-gg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| { | ||
| "Cancel": "Cancel", | ||
| "Close Element": "Close Element", | ||
| "Are you sure you want to quit?": "Are you sure you want to quit?", | ||
| "Show/Hide": "Show/Hide", | ||
| "Quit": "Quit", | ||
| "Edit": "Edit", | ||
| "Undo": "Undo", | ||
| "Redo": "Redo", | ||
| "Cut": "Cut", | ||
| "Copy": "Copy", | ||
| "Paste": "Paste", | ||
| "Paste and Match Style": "Paste and Match Style", | ||
| "Delete": "Delete", | ||
| "Select All": "Select All", | ||
| "View": "View", | ||
| "Actual Size": "Actual Size", | ||
| "Zoom In": "Zoom In", | ||
| "Zoom Out": "Zoom Out", | ||
| "Preferences": "Preferences", | ||
| "Toggle Full Screen": "Toggle Full Screen", | ||
| "Toggle Developer Tools": "Toggle Developer Tools", | ||
| "Window": "Window", | ||
| "Minimize": "Minimize", | ||
| "Close": "Close", | ||
| "Help": "Help", | ||
| "Element Help": "Element Help", | ||
| "About": "About", | ||
| "Services": "Services", | ||
| "Hide": "Hide", | ||
| "Hide Others": "Hide Others", | ||
| "Unhide": "Unhide", | ||
| "Speech": "Speech", | ||
| "Start Speaking": "Start Speaking", | ||
| "Stop Speaking": "Stop Speaking", | ||
| "Zoom": "Zoom", | ||
| "Bring All to Front": "Bring All to Front", | ||
| "File": "File", | ||
| "Copy image": "Copy image", | ||
| "Copy email address": "Copy email address", | ||
| "Copy link address": "Copy link address", | ||
| "Save image as...": "Save image as...", | ||
| "Failed to save image": "Failed to save image", | ||
| "The image failed to save": "The image failed to save", | ||
| "Add to dictionary": "Add to dictionary" | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| /* | ||
| Copyright 2021 New Vector Ltd | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| */ | ||
|
|
||
| const counterpart = require('counterpart'); | ||
germain-gg marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const DEFAULT_LOCALE = "en"; | ||
|
|
||
| function _td(text) { | ||
| return text; | ||
| } | ||
|
|
||
| function _t(text, variables = {}) { | ||
| const args = Object.assign({ interpolate: false }, variables); | ||
|
|
||
| const { count } = args; | ||
|
|
||
| // Horrible hack to avoid https://github.com/vector-im/element-web/issues/4191 | ||
| // The interpolation library that counterpart uses does not support undefined/null | ||
| // values and instead will throw an error. This is a problem since everywhere else | ||
| // in JS land passing undefined/null will simply stringify instead, and when converting | ||
| // valid ES6 template strings to i18n strings it's extremely easy to pass undefined/null | ||
| // if there are no existing null guards. To avoid this making the app completely inoperable, | ||
| // we'll check all the values for undefined/null and stringify them here. | ||
| Object.keys(args).forEach((key) => { | ||
| if (args[key] === undefined) { | ||
| console.warn("safeCounterpartTranslate called with undefined interpolation name: " + key); | ||
| args[key] = 'undefined'; | ||
| } | ||
| if (args[key] === null) { | ||
| console.warn("safeCounterpartTranslate called with null interpolation name: " + key); | ||
| args[key] = 'null'; | ||
| } | ||
| }); | ||
| let translated = counterpart.translate(text, args); | ||
| if (translated === undefined && count !== undefined) { | ||
| // counterpart does not do fallback if no pluralisation exists | ||
| // in the preferred language, so do it here | ||
| translated = counterpart.translate(text, Object.assign({}, args, {locale: DEFAULT_LOCALE})); | ||
| } | ||
|
|
||
| // The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution) | ||
| return translated; | ||
| } | ||
|
|
||
| class AppLocalization { | ||
| static STORE_KEY = "locale" | ||
| store = null | ||
|
|
||
| constructor({ store, components = [] }) { | ||
| counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN")); | ||
| counterpart.setFallbackLocale('en'); | ||
| counterpart.setSeparator('|'); | ||
|
|
||
| if (Array.isArray(components)) { | ||
| this.localizedComponents = new Set(components); | ||
| } | ||
|
|
||
| this.store = store; | ||
| if (this.store.has(AppLocalization.STORE_KEY)) { | ||
| const locales = this.store.get(AppLocalization.STORE_KEY); | ||
| this.setAppLocale(locales); | ||
| } | ||
|
|
||
| this.resetLocalizedUI(); | ||
| } | ||
|
|
||
| fetchTranslationJson(locale) { | ||
| try { | ||
| console.log("Fetching translation json for locale: " + locale); | ||
| return require(`./i18n/strings/${locale}.json`); | ||
| } catch (e) { | ||
| console.log(`Could not fetch translation json for locale: '${locale}'`, e); | ||
| return null; | ||
| } | ||
| } | ||
|
|
||
| get languageTranslationJson() { | ||
| return this.translationJsonMap.get(this.language); | ||
| } | ||
|
|
||
| setAppLocale(locales) { | ||
| console.log(`Changing application language to ${locales}`); | ||
|
|
||
| if (!Array.isArray(locales)) { | ||
| locales = [locales]; | ||
| } | ||
|
|
||
| locales.forEach(locale => { | ||
| const translations = this.fetchTranslationJson(locale); | ||
| if (translations !== null) { | ||
| counterpart.registerTranslations(locale, translations); | ||
| } | ||
| }); | ||
|
|
||
| counterpart.setLocale(locales); | ||
| this.store.set(AppLocalization.STORE_KEY, locales); | ||
|
|
||
| this.resetLocalizedUI(); | ||
| } | ||
|
|
||
| resetLocalizedUI() { | ||
| console.log("Resetting the UI components after locale change"); | ||
| this.localizedComponents.forEach(componentSetup => { | ||
| if (typeof componentSetup === "function") { | ||
| componentSetup(); | ||
| } | ||
| }); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| module.exports = { | ||
| AppLocalization, | ||
| _t, | ||
| _td, | ||
| }; | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.