[MM-14058] Add support for i18n (#2190)
* Add language files * Add react-intl, mmjstool, setup for adding translations * Translated main module * Translations for renderer * A few minor fixes * More fixes * Add CI, add missing menu translations, other cleanup * Added setting to manually select the language of the app * Force English for E2e * Unit tests * Fix mmjstool * Move set language to before update menu * PR feedback
This commit is contained in:
@@ -33,6 +33,9 @@ jest.mock('main/certificateStore', () => ({
|
||||
add: jest.fn(),
|
||||
save: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/i18nManager', () => ({
|
||||
localizeMessage: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/tray/tray', () => ({}));
|
||||
jest.mock('main/windows/windowManager', () => ({
|
||||
getMainWindow: jest.fn(),
|
||||
|
@@ -8,6 +8,7 @@ import urlUtils from 'common/utils/url';
|
||||
|
||||
import updateManager from 'main/autoUpdater';
|
||||
import CertificateStore from 'main/certificateStore';
|
||||
import {localizeMessage} from 'main/i18nManager';
|
||||
import {destroyTray} from 'main/tray/tray';
|
||||
import WindowManager from 'main/windows/windowManager';
|
||||
|
||||
@@ -96,8 +97,8 @@ export async function handleAppCertificateError(event: Event, webContents: WebCo
|
||||
certificateErrorCallbacks.set(errorID, callback);
|
||||
return;
|
||||
}
|
||||
const extraDetail = CertificateStore.isExisting(origin) ? 'Certificate is different from previous one.\n\n' : '';
|
||||
const detail = `${extraDetail}origin: ${origin}\nError: ${error}`;
|
||||
const extraDetail = CertificateStore.isExisting(origin) ? localizeMessage('main.app.app.handleAppCertificateError.dialog.extraDetail', 'Certificate is different from previous one.\n\n') : '';
|
||||
const detail = localizeMessage('main.app.app.handleAppCertificateError.certError.dialog.detail', '{extraDetail}origin: {origin}\nError: {error}', {extraDetail, origin, error});
|
||||
|
||||
certificateErrorCallbacks.set(errorID, callback);
|
||||
|
||||
@@ -109,21 +110,27 @@ export async function handleAppCertificateError(event: Event, webContents: WebCo
|
||||
|
||||
try {
|
||||
let result = await dialog.showMessageBox(mainWindow, {
|
||||
title: 'Certificate Error',
|
||||
message: 'There is a configuration issue with this Mattermost server, or someone is trying to intercept your connection. You also may need to sign into the Wi-Fi you are connected to using your web browser.',
|
||||
title: localizeMessage('main.app.app.handleAppCertificateError.certError.dialog.title', 'Certificate Error'),
|
||||
message: localizeMessage('main.app.app.handleAppCertificateError.certError.dialog.message', 'There is a configuration issue with this Mattermost server, or someone is trying to intercept your connection. You also may need to sign into the Wi-Fi you are connected to using your web browser.'),
|
||||
type: 'error',
|
||||
detail,
|
||||
buttons: ['More Details', 'Cancel Connection'],
|
||||
buttons: [
|
||||
localizeMessage('main.app.app.handleAppCertificateError.certError.button.moreDetails', 'More Details'),
|
||||
localizeMessage('main.app.app.handleAppCertificateError.certError.button.cancelConnection', 'Cancel Connection'),
|
||||
],
|
||||
cancelId: 1,
|
||||
});
|
||||
|
||||
if (result.response === 0) {
|
||||
result = await dialog.showMessageBox(mainWindow, {
|
||||
title: 'Certificate Not Trusted',
|
||||
message: `Certificate from "${certificate.issuerName}" is not trusted.`,
|
||||
title: localizeMessage('main.app.app.handleAppCertificateError.certNotTrusted.dialog.title', 'Certificate Not Trusted'),
|
||||
message: localizeMessage('main.app.app.handleAppCertificateError.certNotTrusted.dialog.message', 'Certificate from "{issuerName}" is not trusted.', {issuerName: certificate.issuerName}),
|
||||
detail: extraDetail,
|
||||
type: 'error',
|
||||
buttons: ['Trust Insecure Certificate', 'Cancel Connection'],
|
||||
buttons: [
|
||||
localizeMessage('main.app.app.handleAppCertificateError.certNotTrusted.button.trustInsecureCertificate', 'Trust Insecure Certificate'),
|
||||
localizeMessage('main.app.app.handleAppCertificateError.certNotTrusted.button.cancelConnection', 'Cancel Connection'),
|
||||
],
|
||||
cancelId: 1,
|
||||
checkboxChecked: false,
|
||||
checkboxLabel: "Don't ask again",
|
||||
|
@@ -39,6 +39,8 @@ jest.mock('electron', () => ({
|
||||
setAppUserModelId: jest.fn(),
|
||||
getVersion: jest.fn(),
|
||||
whenReady: jest.fn(),
|
||||
getLocale: jest.fn(),
|
||||
getLocaleCountryCode: jest.fn(),
|
||||
},
|
||||
ipcMain: {
|
||||
on: jest.fn(),
|
||||
@@ -54,6 +56,11 @@ jest.mock('electron', () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
jest.mock('main/i18nManager', () => ({
|
||||
localizeMessage: jest.fn(),
|
||||
setLocale: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('electron-devtools-installer', () => {
|
||||
return () => ({
|
||||
REACT_DEVELOPER_TOOLS: 'react-developer-tools',
|
||||
|
@@ -47,6 +47,7 @@ import {setupBadge} from 'main/badge';
|
||||
import CertificateManager from 'main/certificateManager';
|
||||
import {updatePaths} from 'main/constants';
|
||||
import CriticalErrorHandler from 'main/CriticalErrorHandler';
|
||||
import i18nManager, {localizeMessage} from 'main/i18nManager';
|
||||
import {displayDownloadCompleted} from 'main/notifications';
|
||||
import parseArgs from 'main/ParseArgs';
|
||||
import TrustedOriginsStore from 'main/trustedOrigins';
|
||||
@@ -359,7 +360,7 @@ function initializeAfterAppReady() {
|
||||
const filters = [];
|
||||
if (fileElements.length > 1) {
|
||||
filters.push({
|
||||
name: 'All files',
|
||||
name: localizeMessage('main.app.initialize.downloadBox.allFiles', 'All files'),
|
||||
extensions: ['*'],
|
||||
});
|
||||
}
|
||||
@@ -376,6 +377,14 @@ function initializeAfterAppReady() {
|
||||
});
|
||||
});
|
||||
|
||||
// needs to be done after app ready
|
||||
// must be done before update menu
|
||||
if (Config.appLanguage) {
|
||||
i18nManager.setLocale(Config.appLanguage);
|
||||
} else if (!i18nManager.setLocale(app.getLocale())) {
|
||||
i18nManager.setLocale(app.getLocaleCountryCode());
|
||||
}
|
||||
|
||||
handleUpdateMenuEvent();
|
||||
|
||||
ipcMain.emit('update-dict');
|
||||
|
@@ -49,6 +49,9 @@ jest.mock('main/autoUpdater', () => ({}));
|
||||
jest.mock('main/constants', () => ({
|
||||
updatePaths: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/i18nManager', () => ({
|
||||
localizeMessage: jest.fn(),
|
||||
}));
|
||||
jest.mock('main/menus/app', () => ({}));
|
||||
jest.mock('main/menus/tray', () => ({}));
|
||||
jest.mock('main/server/serverInfo', () => ({
|
||||
|
@@ -21,6 +21,7 @@ import Utils from 'common/utils/util';
|
||||
|
||||
import updateManager from 'main/autoUpdater';
|
||||
import {migrationInfoPath, updatePaths} from 'main/constants';
|
||||
import {localizeMessage} from 'main/i18nManager';
|
||||
import {createMenu as createAppMenu} from 'main/menus/app';
|
||||
import {createMenu as createTrayMenu} from 'main/menus/tray';
|
||||
import {ServerInfo} from 'main/server/serverInfo';
|
||||
@@ -224,11 +225,14 @@ export function migrateMacAppStore() {
|
||||
}
|
||||
|
||||
const cancelImport = dialog.showMessageBoxSync({
|
||||
title: 'Mattermost',
|
||||
message: 'Import Existing Configuration',
|
||||
detail: 'It appears that an existing Mattermost configuration exists, would you like to import it? You will be asked to pick the correct configuration directory.',
|
||||
title: app.name,
|
||||
message: localizeMessage('main.app.utils.migrateMacAppStore.dialog.message', 'Import Existing Configuration'),
|
||||
detail: localizeMessage('main.app.utils.migrateMacAppStore.dialog.detail', 'It appears that an existing {appName} configuration exists, would you like to import it? You will be asked to pick the correct configuration directory.', {appName: app.name}),
|
||||
icon: appIcon,
|
||||
buttons: ['Select Directory and Import', 'Don\'t Import'],
|
||||
buttons: [
|
||||
localizeMessage('main.app.utils.migrateMacAppStore.button.selectAndImport', 'Select Directory and Import'),
|
||||
localizeMessage('main.app.utils.migrateMacAppStore.button.dontImport', 'Don\'t Import'),
|
||||
],
|
||||
type: 'info',
|
||||
defaultId: 0,
|
||||
cancelId: 1,
|
||||
|
Reference in New Issue
Block a user