Commit 21ca5d69 authored by Luke Schoen's avatar Luke Schoen Committed by Thibaut Sardan
Browse files

feat: Relates to #402. Internationalisation. German Language Support (#464)

* chore: Update to latest React 16.8.3 to requirements of react-i18next

* feat: Scaffold basic translation with English and German

* feat: Relates to #402. German translation fully working

* fix: Switch back to English by default

* fix: Allow user to switch between languages in preferences of context menu

* feat: Translate the context menus

* refactor: Remove German language. Add as separate PR

* refactor: Remove blank line

* feat: Add German language using Google Translate only

* fix: Fix Fether menu German language translation after review from @Robbepop (native German speaker)

* docs: Update Readme with Internationalisation Add New language instructions

* docs: Update Readme with Known Issues and Usage instructions

* review-fix: Disabled tooltip Please fill out this field. Add High and Low tx speed

* review-fix: Update license headers to be 2019 instead of 2018

* review-fix: Change ns1 to fether-electron and fether-react. Use pino.debug

* fix: Add missing i18n conversion for macOS Edit menu

* review-fix: Remove unused i18next browser languagedetector dependency

* merge latest from master and fix conflicts

* merge latest master and fix conflicts. TODO do not expose remote

* fix: Do not expose remote. Only expose add and remove listener, and reload via bridge

* feat: Convert new release available text to i18n
parent 649d6bf0
Pipeline #35470 passed with stages
in 10 minutes
......@@ -10,12 +10,16 @@ import settings from 'electron-settings';
import { name } from '../../../../../package.json';
import Pino from '../../utils/pino';
import { en } from './locales';
import { en, de } from './locales';
let { app } = electron;
const pino = Pino();
let resourceEnglishNS = {};
let resourceGermanNS = {};
resourceEnglishNS[name] = en;
resourceGermanNS[name] = de;
const packageNS = Object.keys(resourceEnglishNS)[0].toString();
const moduleNS = 'i18n';
const menuNS = `${packageNS}-${moduleNS}`;
......@@ -26,22 +30,21 @@ i18n
.init({
debug: true,
defaultNS: packageNS,
fallbackLng: ['en-US', 'en'],
fallbackLng: ['en-US', 'en', 'de-DE', 'de'],
interpolation: {
escapeValue: false
},
lng: settings.get('fether-language') || 'en',
ns: [packageNS],
resources: {
en: resourceEnglishNS
en: resourceEnglishNS,
de: resourceGermanNS
},
saveMissing: true
})
.then(() => pino.info(`${menuNS}: success`))
.catch(error => pino.info(`${menuNS}: failure`, error));
// FIXME i18n - convert all text below to i18n
// https://www.i18next.com/overview/api#changelanguage
i18n.changeLanguage(app.getLocale(), (err, t) => {
if (err) {
......
{
"menu": {
"file": {
"submenu_name": "Datei",
"about": "Über",
"preferences": {
"submenu_name": "Einstellungen",
"languages": {
"submenu_name": "Sprachen",
"language": "Sprache",
"english": "Englisch",
"german": "Deutsch"
}
},
"services": "Dienstleistungen",
"hide": "Verbergen",
"hide_others": "Andere Ausblenden",
"unhide": "Einblenden",
"quit": "Verlassen"
},
"edit": {
"submenu_name": "Bearbeiten",
"undo": "Rückgängig Machen",
"redo": "Wiederholen",
"cut": "Ausschneiden",
"copy": "Kopieren",
"paste": "Einfügen",
"delete": "Löschen",
"select_all": "Alle Auswählen",
"speech": {
"submenu_name": "Reden",
"start_speaking": "Beginnen Sie zu Sprechen",
"stop_speaking": "Hör auf zu Sprechen"
}
},
"view": {
"submenu_name": "Ansicht",
"reload": "Neu Laden",
"toggle_developer_tools": "Entwicklerwerkzeuge"
},
"window": {
"submenu_name": "Fenster",
"close": "Schließen",
"minimize": "Minimieren",
"zoom": "Zoomen",
"bring_all_to_front": "Alle Nach Vorne Bringen"
},
"help": {
"submenu_name": "Hilfe",
"search": "Suchen",
"learn_more": "Weitere Informationen"
},
"show_hide_fether": "Fether Anzeigen/Ausblenden"
}
}
import en from './en.json';
import de from './de.json';
export { en };
export { en, de };
......@@ -28,6 +28,19 @@ const getPreferences = fetherApp => {
// Frontend change language
fetherApp.win.webContents.emit('set-language', 'en');
}
},
{
label: i18n.t('menu.file.preferences.languages.german'),
type: 'radio',
checked: settings.get('fether-language') === 'de',
click () {
// Backend menu change language
i18n.changeLanguage('de');
settings.set('fether-language', 'de');
fetherApp.setupMenu(fetherApp);
// Frontend change language
fetherApp.win.webContents.emit('set-language', 'de');
}
}
]
};
......
......@@ -10,11 +10,14 @@ import store from 'store';
import { name } from '../../package.json';
import Debug from '../utils/debug';
import { en } from './locales';
import { en, de } from './locales';
const LANG_LS_KEY = 'fether-language';
let resourceEnglishNS = {};
let resourceGermanNS = {};
resourceEnglishNS[name] = en;
resourceGermanNS[name] = de;
const packageNS = Object.keys(resourceEnglishNS)[0].toString();
const moduleNS = 'i18n';
const menuNS = `${packageNS}-${moduleNS}`;
......@@ -26,7 +29,7 @@ i18n
.init({
debug: true,
defaultNS: packageNS,
fallbackLng: ['en-US', 'en'],
fallbackLng: ['en-US', 'en', 'de-DE', 'de'],
interpolation: {
escapeValue: false
},
......@@ -40,15 +43,14 @@ i18n
nsMode: 'default'
},
resources: {
en: resourceEnglishNS
en: resourceEnglishNS,
de: resourceGermanNS
},
saveMissing: true
})
.then(() => debug('success'))
.catch(error => debug('failure', error));
// FIXME i18n - convert all text below to i18n
// https://www.i18next.com/overview/api#changelanguage
i18n.changeLanguage(navigator.language, (err, t) => {
if (err) {
......
{
"account": {
"create": {
"change_icon": "Generieren Sie ein anderes Symbol",
"label_name_msg": "Bitte geben Sie diesem Konto einen Namen:",
"label_name": "Name",
"title": "Ein neues Konto erstellen",
"copy_phrase": {
"msg1": "Bitte schreibe deinen geheimen Satz auf ein Blatt Papier:",
"msg2": "Behalte es sicher und geheim.",
"msg3": "Wenn Sie Ihren geheimen Satz verlieren, kann Ihre Brieftasche nicht wiederhergestellt werden.",
"msg4": "Wenn jemand Ihren geheimen Satz ergreift, kann er Ihr Konto belasten."
}
},
"existing": {
"no_name": "(kein Name}"
},
"backup": {
"label_msg_password_unlock": "Entsperren Sie Ihr Konto, um die JSON-Keystore-Datei zu verschlüsseln:",
"label_password_unlock": "Passwort",
"button_confirm": "Bestätigen Sie die Sicherung"
},
"import": {
"error_msg_existing_address": "Konto {{address}} bereits aufgeführt",
"signer": {
"error_msg_signer_imported": "Ungültiger QR-Code",
"label_msg_recover_signer": "Erholen Sie sich von Parity Signer",
"label_button_recover_signer_scan": "QR-Code scannen",
"label_msg_recover_signer_scan": "QR-Code des Parity Signer-Kontos scannen"
},
"json": {
"error_msg_change_json_file": "Ungültige Datei. Bitte überprüfen Sie, ob dies Ihre aktuelle Parity-Backup-JSON-Schlüsseldatei ist, und versuchen Sie es erneut.",
"label_msg_recover_json": "Stellen Sie die JSON-Schlüsseldatei wieder her",
"label_recover_json": "JSON-Sicherungsschlüsseldatei"
},
"phrase": {
"error_msg_submit_phrase": "Die Passphrase wurde nicht erkannt. Bitte vergewissern Sie sich, dass Sie Ihre Passphrase richtig eingegeben haben.",
"label_msg_recover_phrase": "Erholen Sie sich von der Seed Phrase",
"label_recover_phrase": "Wiederherstellungssatz"
},
"question": "Hast du schon ein Konto?",
"title": "Konto importieren"
},
"password": {
"common": {
"label_password": "Passwort",
"label_password_confirm": "Bestätigen",
"error_msg_password_incorrect": "Bitte überprüfen Sie Ihr Passwort und versuchen Sie es erneut.",
"button_confirm": "Konto bestätigen {{postfix}}",
"button_confirm_opt1": "einführen",
"button_confirm_opt2": "Schaffung"
},
"create": {
"error_msg_password_confirmation_no_match": "Passwortbestätigung stimmt nicht überein.",
"label_msg_password": "Sichern Sie sich Ihr Konto mit einem Passwort:"
},
"import": {
"label_msg_unlock_json": "Entsperren Sie Ihr Konto, um Ihre JSON-Keystore-Datei zu entschlüsseln:"
}
},
"phrase_rewrite": {
"label_msg_rewrite_phrase": "Geben Sie Ihren geheimen Satz ein, um zu bestätigen, dass Sie ihn korrekt aufgeschrieben haben:",
"label_rewrite_phrase": "Wiederherstellungssatz"
}
},
"accounts_list": {
"header": "Konten",
"hint": {
"exist": "Klicken Sie auf das + Symbol, um ein neues Konto hinzuzufügen.",
"none": "Keine Konten vorhanden!"
}
},
"feedback": {
"title": "Feedback"
},
"health": {
"status": {
"title": {
"launching": "Knoten starten...",
"no_internet_no_node_connected": "Kein Internet. Kein Knoten verbunden",
"internet_no_node_connected": "Verbindung zum Knoten...",
"no_internet_node_connected": "Kein Internet. Verbindung zum Knoten",
"no_clock_sync": "Uhr des Hosts nicht synchron",
"no_peers": "Verbindung zu Netzwerkkollegen...",
"syncing": "Synchronisieren...",
"synced": "Synchronisiert"
},
"description": {
"no_internet": "Bitte verbinden Sie sich mit dem Internet",
"no_clock_sync": "Mac: Systemeinstellungen -> Datum und Uhrzeit -> Deaktivieren Sie das Kontrollkästchen 'Datum und Uhrzeit automatisch festlegen'. Windows: Systemsteuerung -> 'Uhrzeit, Sprache und Region' -> 'Datum und Uhrzeit' -> Deaktivieren Sie das Kontrollkästchen 'Datum einstellen' und Zeit automatisch",
"no_peers": "Verbindung zu Netzwerkkollegen...",
"syncing": "Synchronisieren..."
}
},
"overlay": {
"error_status_invalid": "Der Status muss einer von sein 'node-internet|node|sync': "
}
},
"onboarding": {
"header": "Nutzungsbedingungen",
"instructions": "Bitte aufmerksam lesen",
"button_accept": "Akzeptieren"
},
"navigation": {
"back": "Zurück",
"go_back": "Geh zurück",
"close": "Schließen",
"next": "Weiter",
"next_step": "Nächster Schritt"
},
"releases": {
"new_release_title": "Neue Version verfügbar",
"new_release_description": "{{release_name}} wurde veröffentlicht!"
},
"search_tokens": {
"add": "Hinzufügen",
"clear": "Klar",
"placeholder": "Token nach Namen oder Symbol suchen",
"remove": "Löschen",
"title": "Suchmarken"
},
"scanner": {
"error_security": "Der Zugriff auf die Webcam wurde abgelehnt",
"error_overcontrained": "Keine Webcam auf dem Gerät gefunden.",
"error_not_readable": "Webcam-Hardwarefehler. Starten Sie Ihren Computer neu",
"error_unknown": "Unbekannter Fehler."
},
"tx": {
"header_send_prefix": "Senden {{token}}",
"header_sending": "Senden Sie Ihre Transaktion...",
"blockscout": "Siehe auf BlockScout",
"form": {
"button_checking": "Überprüfung...",
"button_scan": "Scan",
"button_send": "Senden",
"button_max": "Max",
"button_confirm_tx": "Transaktion bestätigen",
"label_unlock": "Konto entsperren:",
"field": {
"to": "Zu",
"amount": "Menge",
"tx_speed": "Transaktionsgeschwindigkeit",
"password": "Passwort"
},
"details": {
"details": "Einzelheiten",
"hide": "Verbergen",
"missing_fields": "Fehlende Eingabefelder...",
"gas_limit": "Gaslimit: {{gas_limit}}",
"fee": "Gebühr: {{fee}} ETH (Gaslimit * Gaspreis)",
"total_amount": "Gesamtmenge: {{total_amount}} ETH",
"title": "Transaktionsdetails:"
},
"warning": {
"title_same_sender_receiver": "WARNUNG:",
"body_same_sender_receiver": "Die Absender- und Empfängeradressen sind gleich."
},
"validation": {
"amount_invalid": "Bitte geben Sie einen gültigen Betrag ein",
"eth_balance_too_low_for_gas": "ETH-Bilanz zu niedrig, um für Gas zu zahlen.",
"eth_balance_too_low": "Sie haben nicht genug ETH-Balance",
"fetching_chain_id": "Abrufen der Ketten-ID",
"fetching_eth_balance": "Ether-Balance abrufen",
"fetching_tx_count": "Transaktionsanzahl für Nonce abrufen",
"non_zero_amount": "Bitte geben Sie einen Betrag ungleich Null ein",
"positive_amount": "Bitte geben Sie einen positiven Betrag ein",
"min_wei": "Bitte geben Sie mindestens 1 Wei ein",
"min_decimals": "Bitte geben Sie einen {{token_name}} Wert mit weniger als {{token_decimals}} Dezimalstellen",
"token_balance_too_low": "Sie haben nicht genug {{token_symbol}} Gleichgewicht",
"invalid_eth_address": "Bitte geben Sie eine gültige Ethereum-Adresse ein",
"prevent_send_zero_account": "Sie dürfen nicht mit Token {{token_name}} an das Nullkonto (0x0)",
"unable_estimate_gas": "Gas kann nicht geschätzt werden...",
"estimating_gas": "Gas schätzen...",
"error_estimating_balance": "Fehler beim Schätzen des Guthabens, bitte versuchen Sie es erneut",
"valid_tx": "Die Transaktion scheint gültig zu sein"
}
},
"scan": {
"msg_qr_scan": "Bitte scannen Sie den QR-Code der Transaktion in Parity Signer"
},
"scan_signed": {
"error_qr_tx_invalid": "Der QR-Code scheint keine gültige Transaktion zu sein.",
"label_msg_qr_tx": "Zeigt den signierten Transaktions-QR-Code an"
},
"sent": {
"waiting_confirmations_receiving": "Warten {{progress}} auf Bestätigungen: ",
"waiting_confirmed": "Warten auf Bestätigungen...",
"confirmed": "Transaktion bestätigt",
"submitted": "Eingereicht",
"error": "Error"
}
},
"tokens": {
"tokens": {
"menu_items": {
"backup_account": "Sicherungskonto",
"add_tokens": "Token hinzufügen"
}
}
},
"ui": {
"click_to_copy": {
"card": {
"label": "Klicken Sie hier, um die Adresse zu kopieren"
},
"header": {
"label": "Adresse kopieren"
},
"copied": "Kopiert"
},
"form_input_file": {
"select_file": "Datei aussuchen"
}
},
"utils": {
"blockscout_chain": "Kettenname wird noch nicht unterstützt. Bitte öffnen Sie eine Github-Ausgabe unter https://github.com/paritytech/fether/issues/new"
}
}
import en from './en.json';
import de from './de.json';
export { en };
export { en, de };
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment