i18n: restore ability to retrieve new i18n strings (#607)

This commit is contained in:
infinite-persistence 2022-01-03 10:51:44 +08:00
commit 4dcabd67a7
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
3 changed files with 44 additions and 49 deletions

View file

@ -1,57 +1,34 @@
// @if TARGET='app' // @flow
let fs = require('fs'); import { isLocalStorageAvailable } from 'util/storage';
// @endif
const isProduction = process.env.NODE_ENV === 'production'; const isProduction = process.env.NODE_ENV === 'production';
let knownMessages = null; const localStorageAvailable = isLocalStorageAvailable();
let localStorageAvailable;
try {
localStorageAvailable = Boolean(window.localStorage);
} catch (e) {
localStorageAvailable = false;
}
window.i18n_messages = window.i18n_messages || {}; window.i18n_messages = window.i18n_messages || {};
// @if TARGET='app' /**
function saveMessageDesktop(message) { * Collects new i18n strings encountered during runtime.
const messagesFilePath = __static + '/app-strings.json'; * The output can be retrieved and pasted into app-strings.json.
*
if (knownMessages === null) { * @param message
try {
knownMessages = JSON.parse(fs.readFileSync(messagesFilePath, 'utf-8'));
} catch (err) {
throw new Error('Error parsing i18n messages file: ' + messagesFilePath + ' err: ' + err);
}
}
if (!knownMessages[message]) {
const END = '--end--';
delete knownMessages[END];
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'
function saveMessageWeb(message) { function saveMessageWeb(message) {
if (!isProduction && knownMessages === null) { // @if process.env.NODE_ENV!='production'
console.log('Note that i18n messages are not saved in web dev mode.'); // eslint-disable-line if (!window.app_strings) {
knownMessages = {}; return;
} }
if (!window.new_strings) {
console.log('Copy new i18n to clipboard:%c copy(window.new_strings)', 'color:yellow'); // eslint-disable-line
}
window.new_strings = window.new_strings || {};
if (!window.app_strings[message] && !window.new_strings[message]) {
window.new_strings[message] = removeContextMetadata(message);
}
// @endif
} }
// @endif
function removeContextMetadata(message) { function removeContextMetadata(message) {
// Example string entries with context-metadata: // Example string entries with context-metadata:
@ -78,7 +55,7 @@ function removeContextMetadata(message) {
return message; return message;
} }
export function __(message, tokens) { export function __(message: string, tokens: { [string]: string }) {
if (!message) { if (!message) {
return ''; return '';
} }
@ -86,8 +63,9 @@ export function __(message, tokens) {
const language = localStorageAvailable const language = localStorageAvailable
? window.localStorage.getItem('language') || 'en' ? window.localStorage.getItem('language') || 'en'
: window.navigator.language.slice(0, 2) || 'en'; : window.navigator.language.slice(0, 2) || 'en';
if (!isProduction) { if (!isProduction) {
IS_WEB ? saveMessageWeb(message) : saveMessageDesktop(message); saveMessageWeb(message);
} }
let translatedMessage = window.i18n_messages[language] ? window.i18n_messages[language][message] || message : message; let translatedMessage = window.i18n_messages[language] ? window.i18n_messages[language][message] || message : message;
@ -97,7 +75,7 @@ export function __(message, tokens) {
return translatedMessage; return translatedMessage;
} }
return translatedMessage.replace(/%([^%]+)%/g, function($1, $2) { return translatedMessage.replace(/%([^%]+)%/g, ($1, $2) => {
return tokens.hasOwnProperty($2) ? tokens[$2] : $2; return tokens.hasOwnProperty($2) ? tokens[$2] : $2;
}); });
} }

View file

@ -15,7 +15,7 @@ import { selectPrefsReady } from 'redux/selectors/sync';
import { Lbryio } from 'lbryinc'; import { Lbryio } from 'lbryinc';
import { getDefaultLanguage } from 'util/default-languages'; import { getDefaultLanguage } from 'util/default-languages';
const { DEFAULT_LANGUAGE } = require('config'); const { DEFAULT_LANGUAGE, URL_DEV } = require('config');
const { SDK_SYNC_KEYS } = SHARED_PREFERENCES; const { SDK_SYNC_KEYS } = SHARED_PREFERENCES;
export const IS_MAC = process.platform === 'darwin'; export const IS_MAC = process.platform === 'darwin';
@ -294,6 +294,16 @@ export function doFetchLanguage(language) {
}); });
}); });
} }
// @if process.env.NODE_ENV!='production'
if (!window.app_strings) {
fetch(`${URL_DEV}/app-strings.json`)
.then((r) => r.json())
.then((j) => {
window.app_strings = j;
});
}
// @endif
}; };
} }

View file

@ -100,6 +100,13 @@ if (fs.existsSync(ROBOTS_TXT_PATH)) {
}); });
} }
if (!isProduction) {
copyWebpackCommands.push({
from: `${STATIC_ROOT}/app-strings.json`,
to: `${DIST_ROOT}/app-strings.json`,
});
}
let plugins = [ let plugins = [
new WriteFilePlugin(), new WriteFilePlugin(),
new CopyWebpackPlugin(copyWebpackCommands), new CopyWebpackPlugin(copyWebpackCommands),