lbry-desktop/ui/i18n.js

107 lines
3.3 KiB
JavaScript
Raw Normal View History

import { getDefaultLanguage, resolveLanguageAlias } from './util/default-languages';
// @if TARGET='app'
let fs = require('fs');
// @endif
const isProduction = process.env.NODE_ENV === 'production';
let knownMessages = null;
let localStorageAvailable;
try {
localStorageAvailable = Boolean(window.localStorage);
} catch (e) {
localStorageAvailable = false;
}
window.i18n_messages = window.i18n_messages || {};
// @if TARGET='app'
2020-12-08 22:50:10 +01:00
function saveMessageDesktop(message) {
const messagesFilePath = __static + '/app-strings.json';
if (knownMessages === null) {
try {
knownMessages = JSON.parse(fs.readFileSync(messagesFilePath, 'utf-8'));
} catch (err) {
Support for multiple string context + "About" as initial example. ## Issue 4796 - i18n: Allow support for string overloading (multiple contexts) ## Approach - Minimal code and process change. - Handle on a case-by-case basis when reported by translators. - Split the affected key in the string json by appending the context. - Translators need to be aware of the new format and not translate context itself. Code is added to detect bad translations and will revert to English. Sample in json: "About --[About section in Help Page]--": "About", "About --[tab title in Channel Page]--": "About", Sample in client code: title={__('About --[About section in Help Page]--')} - "--[ ]--" was chosen as it's unique enough (unlikely for real strings to use it) and hopefully not that distracting in the client code. - In the key itself, spaces are allowed after the string (i.e. before '--[') for neatness. It will be trimmed by the system. ## First example "About" is used in 3 places: - Channel Page - Help Page - Footer (in Odysee branch) For Russian, the word "About" is "O" and is usually not used standalone, but requires something behind it. A translator said so, and seems to be the case in other sites as well. "O xxx" "O yyy" ## Other languages For other languages that are not impacted, they can just clone the same translation for each of the split keys, just like in English. ## Possible enhancement in Transifex I see that Transifex's API includes a `context` entry. It might be possible to move the context-metadata there during the upload, so translators will never see the "--[]--" messiness (it will be shown as "Context: xxx" in the Transifex GUI). I'm not sure how to test the Transifex side, so I did not investigate further.
2020-10-09 07:38:03 +02:00
throw new Error('Error parsing i18n messages file: ' + messagesFilePath + ' err: ' + err);
}
}
if (!knownMessages[message]) {
const END = '--end--';
delete knownMessages[END];
Support for multiple string context + "About" as initial example. ## Issue 4796 - i18n: Allow support for string overloading (multiple contexts) ## Approach - Minimal code and process change. - Handle on a case-by-case basis when reported by translators. - Split the affected key in the string json by appending the context. - Translators need to be aware of the new format and not translate context itself. Code is added to detect bad translations and will revert to English. Sample in json: "About --[About section in Help Page]--": "About", "About --[tab title in Channel Page]--": "About", Sample in client code: title={__('About --[About section in Help Page]--')} - "--[ ]--" was chosen as it's unique enough (unlikely for real strings to use it) and hopefully not that distracting in the client code. - In the key itself, spaces are allowed after the string (i.e. before '--[') for neatness. It will be trimmed by the system. ## First example "About" is used in 3 places: - Channel Page - Help Page - Footer (in Odysee branch) For Russian, the word "About" is "O" and is usually not used standalone, but requires something behind it. A translator said so, and seems to be the case in other sites as well. "O xxx" "O yyy" ## Other languages For other languages that are not impacted, they can just clone the same translation for each of the split keys, just like in English. ## Possible enhancement in Transifex I see that Transifex's API includes a `context` entry. It might be possible to move the context-metadata there during the upload, so translators will never see the "--[]--" messiness (it will be shown as "Context: xxx" in the Transifex GUI). I'm not sure how to test the Transifex side, so I did not investigate further.
2020-10-09 07:38:03 +02:00
knownMessages[message] = removeContextMetadata(message);
knownMessages[END] = END;
fs.writeFile(messagesFilePath, JSON.stringify(knownMessages, null, 2) + '\n', 'utf-8', (err) => {
if (err) {
throw err;
}
});
}
}
// @endif
/*
I dislike the below code (and note that it ships all the way to the distributed app),
but this seems better than silently having this limitation and future devs not knowing.
*/
// @if TARGET='web'
2020-12-08 22:50:10 +01:00
function saveMessageWeb(message) {
if (!isProduction && knownMessages === null) {
2020-12-08 22:50:10 +01:00
console.log('Note that i18n messages are not saved in web dev mode.'); // eslint-disable-line
knownMessages = {};
}
}
// @endif
Support for multiple string context + "About" as initial example. ## Issue 4796 - i18n: Allow support for string overloading (multiple contexts) ## Approach - Minimal code and process change. - Handle on a case-by-case basis when reported by translators. - Split the affected key in the string json by appending the context. - Translators need to be aware of the new format and not translate context itself. Code is added to detect bad translations and will revert to English. Sample in json: "About --[About section in Help Page]--": "About", "About --[tab title in Channel Page]--": "About", Sample in client code: title={__('About --[About section in Help Page]--')} - "--[ ]--" was chosen as it's unique enough (unlikely for real strings to use it) and hopefully not that distracting in the client code. - In the key itself, spaces are allowed after the string (i.e. before '--[') for neatness. It will be trimmed by the system. ## First example "About" is used in 3 places: - Channel Page - Help Page - Footer (in Odysee branch) For Russian, the word "About" is "O" and is usually not used standalone, but requires something behind it. A translator said so, and seems to be the case in other sites as well. "O xxx" "O yyy" ## Other languages For other languages that are not impacted, they can just clone the same translation for each of the split keys, just like in English. ## Possible enhancement in Transifex I see that Transifex's API includes a `context` entry. It might be possible to move the context-metadata there during the upload, so translators will never see the "--[]--" messiness (it will be shown as "Context: xxx" in the Transifex GUI). I'm not sure how to test the Transifex side, so I did not investigate further.
2020-10-09 07:38:03 +02:00
function removeContextMetadata(message) {
// Example string entries with context-metadata:
// "About --[About section in Help Page]--": "About",
// "About --[tab title in Channel Page]--": "About",
const CONTEXT_BEGIN = '--[';
const CONTEXT_FINAL = ']--';
// If the resolved string still contains the context-metadata, then it's one of the following:
// 1. In development mode, where 'en.json' in the server hasn't been updated with the string yet.
// 2. Translator made a mistake of not ignoring the context string.
// In either case, we'll revert to the English version.
const begin = message.lastIndexOf(CONTEXT_BEGIN);
if (begin > 0 && message.endsWith(CONTEXT_FINAL)) {
// Strip away context:
message = message.substring(0, begin);
// No trailing spaces should be allowed in the string database anyway, because that is hard to translate
// (can't see in Transifex; might not make sense in other languages; etc.).
// With that, we can add a space before the context-metadata to make it neat, and trim both cases here:
message = message.trimEnd();
}
return message;
}
export function __(message, tokens) {
if (!message) {
return '';
}
const language = resolveLanguageAlias(
localStorageAvailable ? window.localStorage.getItem('language') || 'en' : getDefaultLanguage() || 'en'
);
if (!isProduction) {
2020-12-08 22:50:10 +01:00
IS_WEB ? saveMessageWeb(message) : saveMessageDesktop(message);
}
Support for multiple string context + "About" as initial example. ## Issue 4796 - i18n: Allow support for string overloading (multiple contexts) ## Approach - Minimal code and process change. - Handle on a case-by-case basis when reported by translators. - Split the affected key in the string json by appending the context. - Translators need to be aware of the new format and not translate context itself. Code is added to detect bad translations and will revert to English. Sample in json: "About --[About section in Help Page]--": "About", "About --[tab title in Channel Page]--": "About", Sample in client code: title={__('About --[About section in Help Page]--')} - "--[ ]--" was chosen as it's unique enough (unlikely for real strings to use it) and hopefully not that distracting in the client code. - In the key itself, spaces are allowed after the string (i.e. before '--[') for neatness. It will be trimmed by the system. ## First example "About" is used in 3 places: - Channel Page - Help Page - Footer (in Odysee branch) For Russian, the word "About" is "O" and is usually not used standalone, but requires something behind it. A translator said so, and seems to be the case in other sites as well. "O xxx" "O yyy" ## Other languages For other languages that are not impacted, they can just clone the same translation for each of the split keys, just like in English. ## Possible enhancement in Transifex I see that Transifex's API includes a `context` entry. It might be possible to move the context-metadata there during the upload, so translators will never see the "--[]--" messiness (it will be shown as "Context: xxx" in the Transifex GUI). I'm not sure how to test the Transifex side, so I did not investigate further.
2020-10-09 07:38:03 +02:00
let translatedMessage = window.i18n_messages[language] ? window.i18n_messages[language][message] || message : message;
translatedMessage = removeContextMetadata(translatedMessage);
if (!tokens) {
return translatedMessage;
}
return translatedMessage.replace(/%([^%]+)%/g, ($1, $2) => {
2019-12-17 04:50:43 +01:00
return tokens.hasOwnProperty($2) ? tokens[$2] : $2;
});
}