mirror of
https://github.com/finos/SymphonyElectron.git
synced 2025-02-25 18:55:29 -06:00
ELECTRON-519: support Japanese localization for menus, dialogs and windows (#401)
- add basic localisation implementation for menu items - add more strings to support localisation on menus - add more strings to support localisation on menus - add all menu items for localisation - refactor i18n code - Add localization for screen picker, basic auth and notification settings child windows - Add localization bridge - add i18n support to more strings - update translations - add events to change language and redo menu template - move config update logic to windowMgr - fix linting issues and refactor - add snipping tool messages
This commit is contained in:
committed by
GitHub
parent
fd39d680a0
commit
a26a1d609c
1
.gitignore
vendored
1
.gitignore
vendored
@@ -32,3 +32,4 @@ installer/win/Symphony-x86-SetupFiles
|
|||||||
package-lock.json
|
package-lock.json
|
||||||
library
|
library
|
||||||
*.log
|
*.log
|
||||||
|
js/translation/*_missing.json
|
||||||
@@ -8,6 +8,7 @@ const log = require('../log.js');
|
|||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
const buildNumber = require('../../package.json').buildNumber;
|
const buildNumber = require('../../package.json').buildNumber;
|
||||||
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
||||||
|
const i18n = require('../translation/i18n');
|
||||||
|
|
||||||
let aboutWindow;
|
let aboutWindow;
|
||||||
|
|
||||||
@@ -90,8 +91,8 @@ function openAboutWindow(windowName) {
|
|||||||
aboutWindow.webContents.on('crashed', function () {
|
aboutWindow.webContents.on('crashed', function () {
|
||||||
const options = {
|
const options = {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: 'Renderer Process Crashed',
|
title: i18n.getMessageFor('Renderer Process Crashed'),
|
||||||
message: 'Oops! Looks like we have had a crash.',
|
message: i18n.getMessageFor('Oops! Looks like we have had a crash.'),
|
||||||
buttons: ['Close']
|
buttons: ['Close']
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,12 +2,13 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Authentication Request</title>
|
<title data-i18n-text="Authentication Request"></title>
|
||||||
<style>
|
<style>
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@@ -62,20 +63,20 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<span>Please provide your login credentials for:</span>
|
<span data-i18n-text="Please provide your login credentials for:"></span>
|
||||||
<span id="hostname" class="hostname">hostname</span>
|
<span id="hostname" class="hostname" data-i18n-text="hostname"></span>
|
||||||
<span id="credentialsError" class="credentials-error">Invalid user name/password</span>
|
<span id="credentialsError" class="credentials-error" data-i18n-text="Invalid user name/password"></span>
|
||||||
<form id="basicAuth" name="Basic Auth" action="Login">
|
<form id="basicAuth" name="Basic Auth" action="Login">
|
||||||
<table class="form">
|
<table class="form">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>User name:</td>
|
<td id="username-text" data-i18n-text="User name:"></td>
|
||||||
<td>
|
<td>
|
||||||
<input id="username" name="username" title="Username" required>
|
<input id="username" name="username" title="Username" required>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Password:</td>
|
<td id="password-text" data-i18n-text="Password:"></td>
|
||||||
<td>
|
<td>
|
||||||
<input id="password" type="password" title="Password" required>
|
<input id="password" type="password" title="Password" required>
|
||||||
</td>
|
</td>
|
||||||
@@ -84,10 +85,10 @@
|
|||||||
</table>
|
</table>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<button type="submit" id="login">Log In</button>
|
<button type="submit" id="login" data-i18n-text="Log In"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<button type="button" id="cancel">Cancel</button>
|
<button type="button" id="cancel" data-i18n-text="Cancel"></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ const log = require('../log.js');
|
|||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
const { isMac } = require('../utils/misc');
|
const { isMac } = require('../utils/misc');
|
||||||
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
||||||
|
const i18n = require('../translation/i18n');
|
||||||
|
|
||||||
let basicAuthWindow;
|
let basicAuthWindow;
|
||||||
|
|
||||||
@@ -96,6 +97,8 @@ function openBasicAuthWindow(windowName, hostname, isValidCredentials, clearSett
|
|||||||
});
|
});
|
||||||
|
|
||||||
basicAuthWindow.webContents.on('did-finish-load', () => {
|
basicAuthWindow.webContents.on('did-finish-load', () => {
|
||||||
|
const basicAuthContent = i18n.getMessageFor('BasicAuth');
|
||||||
|
basicAuthWindow.webContents.send('i18n-basic-auth', basicAuthContent);
|
||||||
// initialize crash reporter
|
// initialize crash reporter
|
||||||
initCrashReporterMain({ process: 'basic auth window' });
|
initCrashReporterMain({ process: 'basic auth window' });
|
||||||
initCrashReporterRenderer(basicAuthWindow, { process: 'render | basic auth window' });
|
initCrashReporterRenderer(basicAuthWindow, { process: 'render | basic auth window' });
|
||||||
@@ -106,8 +109,8 @@ function openBasicAuthWindow(windowName, hostname, isValidCredentials, clearSett
|
|||||||
basicAuthWindow.webContents.on('crashed', function () {
|
basicAuthWindow.webContents.on('crashed', function () {
|
||||||
const options = {
|
const options = {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: 'Renderer Process Crashed',
|
title: i18n.getMessageFor('Renderer Process Crashed'),
|
||||||
message: 'Oops! Looks like we have had a crash.',
|
message: i18n.getMessageFor('Oops! Looks like we have had a crash.'),
|
||||||
buttons: ['Close']
|
buttons: ['Close']
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -69,3 +69,15 @@ ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
|||||||
crashReporter.start(arg);
|
crashReporter.start(arg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('i18n-basic-auth', (event, content) => {
|
||||||
|
if (content && typeof content === 'object') {
|
||||||
|
const i18nNodes = document.querySelectorAll('[data-i18n-text]');
|
||||||
|
|
||||||
|
for (let node of i18nNodes) {
|
||||||
|
if (node.attributes['data-i18n-text'] && node.attributes['data-i18n-text'].value) {
|
||||||
|
node.innerText = content[node.attributes['data-i18n-text'].value] || node.attributes['data-i18n-text'].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -9,6 +9,7 @@ const log = require('../log.js');
|
|||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
const { isMac, isWindowsOS } = require('./../utils/misc.js');
|
const { isMac, isWindowsOS } = require('./../utils/misc.js');
|
||||||
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('../crashReporter.js');
|
||||||
|
const i18n = require('../translation/i18n');
|
||||||
|
|
||||||
let screenPickerWindow;
|
let screenPickerWindow;
|
||||||
let preloadWindow;
|
let preloadWindow;
|
||||||
@@ -92,6 +93,8 @@ function openScreenPickerWindow(eventSender, sources, id) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
screenPickerWindow.webContents.on('did-finish-load', () => {
|
screenPickerWindow.webContents.on('did-finish-load', () => {
|
||||||
|
const screenPickerContent = i18n.getMessageFor('ScreenPicker');
|
||||||
|
screenPickerWindow.webContents.send('i18n-screen-picker', screenPickerContent);
|
||||||
// initialize crash reporter
|
// initialize crash reporter
|
||||||
initCrashReporterMain({ process: 'desktop capture window' });
|
initCrashReporterMain({ process: 'desktop capture window' });
|
||||||
initCrashReporterRenderer(screenPickerWindow, { process: 'render | desktop capture window' });
|
initCrashReporterRenderer(screenPickerWindow, { process: 'render | desktop capture window' });
|
||||||
@@ -101,8 +104,8 @@ function openScreenPickerWindow(eventSender, sources, id) {
|
|||||||
screenPickerWindow.webContents.on('crashed', function () {
|
screenPickerWindow.webContents.on('crashed', function () {
|
||||||
const options = {
|
const options = {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: 'Renderer Process Crashed',
|
title: i18n.getMessageFor('Renderer Process Crashed'),
|
||||||
message: 'Oops! Looks like we have had a crash.',
|
message: i18n.getMessageFor('Oops! Looks like we have had a crash.'),
|
||||||
buttons: ['Close']
|
buttons: ['Close']
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const keyCodeEnum = Object.freeze({
|
|||||||
let availableSources;
|
let availableSources;
|
||||||
let selectedSource;
|
let selectedSource;
|
||||||
let currentIndex = -1;
|
let currentIndex = -1;
|
||||||
|
let localizedContent;
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
renderDom();
|
renderDom();
|
||||||
@@ -49,11 +50,15 @@ function renderDom() {
|
|||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
screenTab.addEventListener('click', () => {
|
screenTab.addEventListener('click', () => {
|
||||||
updateShareButtonText('Select Screen');
|
updateShareButtonText(localizedContent && localizedContent[ 'Select Screen' ] ?
|
||||||
|
localizedContent[ 'Select Screen' ] :
|
||||||
|
'Select Screen');
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
applicationTab.addEventListener('click', () => {
|
applicationTab.addEventListener('click', () => {
|
||||||
updateShareButtonText('Select Application');
|
updateShareButtonText(localizedContent && localizedContent[ 'Select Application' ] ?
|
||||||
|
localizedContent[ 'Select Application' ] :
|
||||||
|
'Select Application');
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
document.addEventListener('keyup', handleKeyUpPress.bind(this), true);
|
document.addEventListener('keyup', handleKeyUpPress.bind(this), true);
|
||||||
@@ -164,7 +169,7 @@ function updateUI(source, itemContainer) {
|
|||||||
|
|
||||||
highlightSelectedSource();
|
highlightSelectedSource();
|
||||||
itemContainer.classList.add('selected');
|
itemContainer.classList.add('selected');
|
||||||
shareButton.innerText = 'Share'
|
shareButton.innerText = localizedContent && localizedContent.Share ? localizedContent.Share : 'Share';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -272,3 +277,16 @@ ipcRenderer.on('register-crash-reporter', (event, arg) => {
|
|||||||
crashReporter.start(arg);
|
crashReporter.start(arg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcRenderer.on('i18n-screen-picker', (event, content) => {
|
||||||
|
localizedContent = content;
|
||||||
|
if (content && typeof content === 'object') {
|
||||||
|
const i18nNodes = document.querySelectorAll('[data-i18n-text]');
|
||||||
|
|
||||||
|
for (let node of i18nNodes) {
|
||||||
|
if (node.attributes['data-i18n-text'] && node.attributes['data-i18n-text'].value) {
|
||||||
|
node.innerText = content[node.attributes['data-i18n-text'].value] || node.attributes['data-i18n-text'].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Screen Picker</title>
|
<title data-i18n-text="Screen Picker"></title>
|
||||||
<style>
|
<style>
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="custom-window-title">
|
<div class="custom-window-title">
|
||||||
<span>Choose what you'd like to share</span>
|
<span data-i18n-text="Choose what you'd like to share"></span>
|
||||||
<div id="x-button">
|
<div id="x-button">
|
||||||
<div class="content-button">
|
<div class="content-button">
|
||||||
<i>
|
<i>
|
||||||
@@ -223,13 +223,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="error-content">
|
<div id="error-content">
|
||||||
<span id="error-message">No screens or applications are currently available.</span>
|
<span id="error-message" data-i18n-text="No screens or applications are currently available."></span>
|
||||||
</div>
|
</div>
|
||||||
<div id="main-content">
|
<div id="main-content">
|
||||||
<input id="screen-tab" type="radio" name="tabs" checked>
|
<input id="screen-tab" type="radio" name="tabs" checked>
|
||||||
<label id="screens" for="screen-tab" class="hidden">Screens</label>
|
<label id="screens" for="screen-tab" class="hidden" data-i18n-text="Screens"></label>
|
||||||
<input id="application-tab" type="radio" name="tabs">
|
<input id="application-tab" type="radio" name="tabs">
|
||||||
<label id="applications" for="application-tab" class="hidden">Applications</label>
|
<label id="applications" for="application-tab" class="hidden" data-i18n-text="Applications"></label>
|
||||||
<section id="screen-contents">
|
<section id="screen-contents">
|
||||||
</section>
|
</section>
|
||||||
<section id="application-contents">
|
<section id="application-contents">
|
||||||
@@ -237,8 +237,8 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<button id="cancel" class="cancel-button">Cancel</button>
|
<button id="cancel" class="cancel-button" data-i18n-text="Cancel"></button>
|
||||||
<button id="share" class="share-button-disable">Select Screen</button>
|
<button id="share" class="share-button-disable" data-i18n-text="Select Screen"></button>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const electron = require('electron');
|
|||||||
|
|
||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const i18n = require('../translation/i18n');
|
||||||
|
|
||||||
let ignoreAllCertErrors = false;
|
let ignoreAllCertErrors = false;
|
||||||
|
|
||||||
@@ -33,8 +34,8 @@ electron.app.on('certificate-error', function(event, webContents, url, error,
|
|||||||
defaultId: 1,
|
defaultId: 1,
|
||||||
cancelId: 1,
|
cancelId: 1,
|
||||||
noLink: true,
|
noLink: true,
|
||||||
title: 'Certificate Error',
|
title: i18n.getMessageFor('Certificate Error'),
|
||||||
message: 'Certificate Error: ' + error + '\nURL: ' + url,
|
message: i18n.getMessageFor('Certificate Error') + `: ${error}\nURL: ${url}`,
|
||||||
});
|
});
|
||||||
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ const electron = require('electron');
|
|||||||
|
|
||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
const logLevels = require('../enums/logLevels.js');
|
const logLevels = require('../enums/logLevels.js');
|
||||||
|
const i18n = require('../translation/i18n');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show dialog pinned to given window when loading error occurs
|
* Show dialog pinned to given window when loading error occurs
|
||||||
@@ -17,9 +18,9 @@ const logLevels = require('../enums/logLevels.js');
|
|||||||
function showLoadFailure(win, url, errorDesc, errorCode, retryCallback, showDialog) {
|
function showLoadFailure(win, url, errorDesc, errorCode, retryCallback, showDialog) {
|
||||||
let msg;
|
let msg;
|
||||||
if (url) {
|
if (url) {
|
||||||
msg = 'Error loading URL:\n' + url;
|
msg = i18n.getMessageFor('Error loading URL') + `:\n${url}`;
|
||||||
} else {
|
} else {
|
||||||
msg = 'Error loading window';
|
msg = i18n.getMessageFor('Error loading window');
|
||||||
}
|
}
|
||||||
if (errorDesc) {
|
if (errorDesc) {
|
||||||
msg += '\n\n' + errorDesc;
|
msg += '\n\n' + errorDesc;
|
||||||
@@ -35,7 +36,7 @@ function showLoadFailure(win, url, errorDesc, errorCode, retryCallback, showDial
|
|||||||
defaultId: 0,
|
defaultId: 0,
|
||||||
cancelId: 1,
|
cancelId: 1,
|
||||||
noLink: true,
|
noLink: true,
|
||||||
title: 'Loading Error',
|
title: i18n.getMessageFor('Loading Error'),
|
||||||
message: msg
|
message: msg
|
||||||
}, response);
|
}, response);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ const cmds = keyMirror({
|
|||||||
openScreenPickerWindow: null,
|
openScreenPickerWindow: null,
|
||||||
popupMenu: null,
|
popupMenu: null,
|
||||||
optimizeMemoryConsumption: null,
|
optimizeMemoryConsumption: null,
|
||||||
setIsInMeeting: null
|
setIsInMeeting: null,
|
||||||
|
setLocale: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|||||||
@@ -142,12 +142,13 @@ electron.ipcMain.on(apiName, (event, arg) => {
|
|||||||
openScreenPickerWindow(event.sender, arg.sources, arg.id);
|
openScreenPickerWindow(event.sender, arg.sources, arg.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case apiCmds.popupMenu:
|
case apiCmds.popupMenu: {
|
||||||
var browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
let browserWin = electron.BrowserWindow.fromWebContents(event.sender);
|
||||||
if (browserWin && !browserWin.isDestroyed()) {
|
if (browserWin && !browserWin.isDestroyed()) {
|
||||||
windowMgr.getMenu().popup(browserWin, { x: 20, y: 15, async: true });
|
windowMgr.getMenu().popup(browserWin, {x: 20, y: 15, async: true});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case apiCmds.optimizeMemoryConsumption:
|
case apiCmds.optimizeMemoryConsumption:
|
||||||
if (typeof arg.memory === 'object' && typeof arg.cpuUsage === 'object' && typeof arg.memory.workingSetSize === 'number') {
|
if (typeof arg.memory === 'object' && typeof arg.cpuUsage === 'object' && typeof arg.memory.workingSetSize === 'number') {
|
||||||
optimizeMemory(arg.memory, arg.cpuUsage);
|
optimizeMemory(arg.memory, arg.cpuUsage);
|
||||||
@@ -158,6 +159,11 @@ electron.ipcMain.on(apiName, (event, arg) => {
|
|||||||
setIsInMeeting(arg.isInMeeting);
|
setIsInMeeting(arg.isInMeeting);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case apiCmds.setLocale:
|
||||||
|
if (typeof arg.locale === 'string') {
|
||||||
|
eventEmitter.emit('language-changed', { language: arg.locale });
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const electron = require('electron');
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { updateConfigField, getMultipleConfigField } = require('../config.js');
|
|
||||||
const AutoLaunch = require('auto-launch');
|
const AutoLaunch = require('auto-launch');
|
||||||
|
const electron = require('electron');
|
||||||
|
|
||||||
|
const { updateConfigField, getMultipleConfigField } = require('../config.js');
|
||||||
const { isMac, isWindowsOS, isWindows10 } = require('../utils/misc.js');
|
const { isMac, isWindowsOS, isWindows10 } = require('../utils/misc.js');
|
||||||
const archiveHandler = require('../utils/archiveHandler');
|
const archiveHandler = require('../utils/archiveHandler');
|
||||||
const log = require('../log.js');
|
const log = require('../log.js');
|
||||||
@@ -11,6 +12,7 @@ const logLevels = require('../enums/logLevels.js');
|
|||||||
const eventEmitter = require('../eventEmitter');
|
const eventEmitter = require('../eventEmitter');
|
||||||
const aboutApp = require('../aboutApp');
|
const aboutApp = require('../aboutApp');
|
||||||
const titleBarStyles = require('../enums/titleBarStyles');
|
const titleBarStyles = require('../enums/titleBarStyles');
|
||||||
|
const i18n = require('../translation/i18n');
|
||||||
|
|
||||||
const configFields = [
|
const configFields = [
|
||||||
'minimizeOnClose',
|
'minimizeOnClose',
|
||||||
@@ -62,24 +64,26 @@ if (isMac) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = [{
|
function getTemplate(app) {
|
||||||
label: 'Edit',
|
|
||||||
|
const template = [{
|
||||||
|
label: i18n.getMessageFor('Edit'),
|
||||||
submenu: [
|
submenu: [
|
||||||
buildMenuItem('undo'),
|
buildMenuItem('undo', i18n.getMessageFor('Undo')),
|
||||||
buildMenuItem('redo'),
|
buildMenuItem('redo', i18n.getMessageFor('Redo')),
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
buildMenuItem('cut'),
|
buildMenuItem('cut', i18n.getMessageFor('Cut')),
|
||||||
buildMenuItem('copy'),
|
buildMenuItem('copy', i18n.getMessageFor('Copy')),
|
||||||
buildMenuItem('paste'),
|
buildMenuItem('paste', i18n.getMessageFor('Paste')),
|
||||||
buildMenuItem('pasteandmatchstyle'),
|
buildMenuItem('pasteandmatchstyle', i18n.getMessageFor('Paste and Match Style')),
|
||||||
buildMenuItem('delete'),
|
buildMenuItem('delete', i18n.getMessageFor('Delete')),
|
||||||
buildMenuItem('selectall')
|
buildMenuItem('selectall', i18n.getMessageFor('Select All'))
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'View',
|
label: i18n.getMessageFor('View'),
|
||||||
submenu: [{
|
submenu: [{
|
||||||
label: 'Reload',
|
label: i18n.getMessageFor('Reload'),
|
||||||
accelerator: 'CmdOrCtrl+R',
|
accelerator: 'CmdOrCtrl+R',
|
||||||
click(item, focusedWindow) {
|
click(item, focusedWindow) {
|
||||||
if (focusedWindow) {
|
if (focusedWindow) {
|
||||||
@@ -88,40 +92,46 @@ const template = [{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
buildMenuItem('resetzoom'),
|
buildMenuItem('resetzoom', i18n.getMessageFor('Actual Size')),
|
||||||
buildMenuItem('zoomin'),
|
buildMenuItem('zoomin', i18n.getMessageFor('Zoom In')),
|
||||||
buildMenuItem('zoomout'),
|
buildMenuItem('zoomout', i18n.getMessageFor('Zoom Out')),
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
buildMenuItem('togglefullscreen'),
|
buildMenuItem('togglefullscreen', i18n.getMessageFor('Toggle Full Screen')),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'window',
|
role: 'window',
|
||||||
|
label: i18n.getMessageFor('Window'),
|
||||||
submenu: [
|
submenu: [
|
||||||
buildMenuItem('minimize'),
|
buildMenuItem('minimize', i18n.getMessageFor('Minimize')),
|
||||||
buildMenuItem('close'),
|
buildMenuItem('close', i18n.getMessageFor('Close')),
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'help',
|
role: 'help',
|
||||||
|
label: i18n.getMessageFor('Help'),
|
||||||
submenu:
|
submenu:
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
label: 'Symphony Help',
|
label: i18n.getMessageFor('Symphony Help'),
|
||||||
click() { electron.shell.openExternal('https://support.symphony.com'); }
|
click() {
|
||||||
|
electron.shell.openExternal('https://support.symphony.com');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Learn More',
|
label: i18n.getMessageFor('Learn More'),
|
||||||
click() { electron.shell.openExternal('https://www.symphony.com'); }
|
click() {
|
||||||
|
electron.shell.openExternal('https://www.symphony.com');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Troubleshooting',
|
label: i18n.getMessageFor('Troubleshooting'),
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: isMac ? 'Show Logs in Finder' : 'Show Logs in Explorer',
|
label: isMac ? i18n.getMessageFor('Show Logs in Finder') : i18n.getMessageFor('Show Logs in Explorer'),
|
||||||
click(item, focusedWindow) {
|
click(item, focusedWindow) {
|
||||||
|
|
||||||
const FILE_EXTENSIONS = [ '.log' ];
|
const FILE_EXTENSIONS = ['.log'];
|
||||||
const MAC_LOGS_PATH = '/Library/Logs/Symphony/';
|
const MAC_LOGS_PATH = '/Library/Logs/Symphony/';
|
||||||
const WINDOWS_LOGS_PATH = '\\AppData\\Roaming\\Symphony\\logs';
|
const WINDOWS_LOGS_PATH = '\\AppData\\Roaming\\Symphony\\logs';
|
||||||
|
|
||||||
@@ -129,7 +139,11 @@ const template = [{
|
|||||||
let source = electron.app.getPath('home') + logsPath;
|
let source = electron.app.getPath('home') + logsPath;
|
||||||
|
|
||||||
if (!fs.existsSync(source) && focusedWindow && !focusedWindow.isDestroyed()) {
|
if (!fs.existsSync(source) && focusedWindow && !focusedWindow.isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(focusedWindow, {type: 'error', title: 'Failed!', message: 'No logs are available to share'});
|
electron.dialog.showMessageBox(focusedWindow, {
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor('Failed!'),
|
||||||
|
message: i18n.getMessageFor('No logs are available to share')
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,25 +155,33 @@ const template = [{
|
|||||||
archiveHandler.generateArchiveForDirectory(source, destination, FILE_EXTENSIONS)
|
archiveHandler.generateArchiveForDirectory(source, destination, FILE_EXTENSIONS)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
electron.shell.showItemInFolder(destination);
|
electron.shell.showItemInFolder(destination);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(focusedWindow, {type: 'error', title: 'Failed!', message: `Unable to generate logs due to -> ${err}`});
|
electron.dialog.showMessageBox(focusedWindow, {
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor('Failed!'),
|
||||||
|
message: i18n.getMessageFor('Unable to generate logs due to ') + err
|
||||||
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: isMac ? 'Show crash dump in Finder' : 'Show crash dump in Explorer',
|
label: isMac ? i18n.getMessageFor('Show crash dump in Finder') : i18n.getMessageFor('Show crash dump in Explorer'),
|
||||||
click(item, focusedWindow) {
|
click(item, focusedWindow) {
|
||||||
const FILE_EXTENSIONS = isMac ? [ '.dmp' ] : [ '.dmp', '.txt' ];
|
const FILE_EXTENSIONS = isMac ? ['.dmp'] : ['.dmp', '.txt'];
|
||||||
const crashesDirectory = electron.crashReporter.getCrashesDirectory();
|
const crashesDirectory = electron.crashReporter.getCrashesDirectory();
|
||||||
let source = isMac ? crashesDirectory + '/completed' : crashesDirectory;
|
let source = isMac ? crashesDirectory + '/completed' : crashesDirectory;
|
||||||
|
|
||||||
// TODO: Add support to get diagnostic reports from ~/Library/Logs/DiagnosticReports
|
// TODO: Add support to get diagnostic reports from ~/Library/Logs/DiagnosticReports
|
||||||
if (!fs.existsSync(source) || fs.readdirSync(source).length === 0 && focusedWindow && !focusedWindow.isDestroyed()) {
|
if (!fs.existsSync(source) || fs.readdirSync(source).length === 0 && focusedWindow && !focusedWindow.isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(focusedWindow, {type: 'error', title: 'Failed!', message: 'No crashes available to share'});
|
electron.dialog.showMessageBox(focusedWindow, {
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor('Failed!'),
|
||||||
|
message: i18n.getMessageFor('No crashes available to share')
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,51 +193,60 @@ const template = [{
|
|||||||
archiveHandler.generateArchiveForDirectory(source, destination, FILE_EXTENSIONS)
|
archiveHandler.generateArchiveForDirectory(source, destination, FILE_EXTENSIONS)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
electron.shell.showItemInFolder(destination);
|
electron.shell.showItemInFolder(destination);
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(focusedWindow, {type: 'error', title: 'Failed!', message: `Unable to generate crash reports due to -> ${err}`});
|
electron.dialog.showMessageBox(focusedWindow, {
|
||||||
}
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor('Failed!'),
|
||||||
|
message: i18n.getMessageFor('Unable to generate crash reports due to ') + err
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
function getTemplate(app) {
|
|
||||||
if (isMac && template[0].label !== app.getName()) {
|
if (isMac && template[0].label !== app.getName()) {
|
||||||
template.unshift({
|
template.unshift({
|
||||||
label: app.getName(),
|
label: app.getName(),
|
||||||
submenu: [{
|
submenu: [{
|
||||||
role: 'about'
|
role: 'about',
|
||||||
|
label: i18n.getMessageFor('About Symphony')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'services',
|
role: 'services',
|
||||||
|
label: i18n.getMessageFor('Services'),
|
||||||
submenu: []
|
submenu: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'hide'
|
role: 'hide',
|
||||||
|
label: i18n.getMessageFor('Hide Symphony')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'hideothers'
|
role: 'hideothers',
|
||||||
|
label: i18n.getMessageFor('Hide Others')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'unhide'
|
role: 'unhide',
|
||||||
|
label: i18n.getMessageFor('Show All')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'quit'
|
role: 'quit',
|
||||||
|
label: i18n.getMessageFor('Quit Symphony')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
@@ -223,36 +254,38 @@ function getTemplate(app) {
|
|||||||
template[1].submenu.push({
|
template[1].submenu.push({
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
}, {
|
}, {
|
||||||
label: 'Speech',
|
label: i18n.getMessageFor('Speech'),
|
||||||
submenu: [{
|
submenu: [{
|
||||||
role: 'startspeaking'
|
role: 'startspeaking',
|
||||||
|
label: i18n.getMessageFor('Start Speaking')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'stopspeaking'
|
role: 'stopspeaking',
|
||||||
|
label: i18n.getMessageFor('Stop Speaking')
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
// Window menu.
|
// Window menu.
|
||||||
template[3].submenu = [{
|
template[3].submenu = [{
|
||||||
label: 'Close',
|
|
||||||
accelerator: 'CmdOrCtrl+W',
|
accelerator: 'CmdOrCtrl+W',
|
||||||
role: 'close'
|
role: 'close',
|
||||||
|
label: i18n.getMessageFor('Close')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Minimize',
|
|
||||||
accelerator: 'CmdOrCtrl+M',
|
accelerator: 'CmdOrCtrl+M',
|
||||||
role: 'minimize'
|
role: 'minimize',
|
||||||
|
label: i18n.getMessageFor('Minimize')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Zoom',
|
role: 'zoom',
|
||||||
role: 'zoom'
|
label: i18n.getMessageFor('Zoom')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'separator'
|
type: 'separator'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Bring All to Front',
|
role: 'front',
|
||||||
role: 'front'
|
label: i18n.getMessageFor('Bring All to Front')
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -268,29 +301,37 @@ function getTemplate(app) {
|
|||||||
|
|
||||||
// Window menu -> launchOnStartup.
|
// Window menu -> launchOnStartup.
|
||||||
template[index].submenu.push({
|
template[index].submenu.push({
|
||||||
label: 'Auto Launch On Startup',
|
label: i18n.getMessageFor('Auto Launch On Startup'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: launchOnStartup,
|
checked: launchOnStartup,
|
||||||
click: function(item, focusedWindow) {
|
click: function (item, focusedWindow) {
|
||||||
if (item.checked) {
|
if (item.checked) {
|
||||||
symphonyAutoLauncher.enable()
|
symphonyAutoLauncher.enable()
|
||||||
.catch(function(err) {
|
.catch(function (err) {
|
||||||
let title = 'Error setting AutoLaunch configuration';
|
let title = 'Error setting AutoLaunch configuration';
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||||
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(focusedWindow, {type: 'error', title, message: title + ': ' + err});
|
electron.dialog.showMessageBox(focusedWindow, {
|
||||||
}
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor(title),
|
||||||
|
message: i18n.getMessageFor(title) + ': ' + err
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
symphonyAutoLauncher.disable()
|
symphonyAutoLauncher.disable()
|
||||||
.catch(function(err) {
|
.catch(function (err) {
|
||||||
let title = 'Error setting AutoLaunch configuration';
|
let title = 'Error setting AutoLaunch configuration';
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
log.send(logLevels.ERROR, 'MenuTemplate: ' + title + ': auto launch error ' + err);
|
||||||
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
if (focusedWindow && !focusedWindow.isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(focusedWindow, {type: 'error', title, message: title + ': ' + err});
|
electron.dialog.showMessageBox(focusedWindow, {
|
||||||
}
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor(title),
|
||||||
|
message: i18n.getMessageFor(title) + ': ' + err
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
launchOnStartup = item.checked;
|
launchOnStartup = item.checked;
|
||||||
updateConfigField('launchOnStartup', launchOnStartup);
|
updateConfigField('launchOnStartup', launchOnStartup);
|
||||||
}
|
}
|
||||||
@@ -298,7 +339,7 @@ function getTemplate(app) {
|
|||||||
|
|
||||||
// Window menu -> alwaysOnTop.
|
// Window menu -> alwaysOnTop.
|
||||||
template[index].submenu.push({
|
template[index].submenu.push({
|
||||||
label: 'Always on top',
|
label: i18n.getMessageFor('Always on Top'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: isAlwaysOnTop,
|
checked: isAlwaysOnTop,
|
||||||
click: (item) => {
|
click: (item) => {
|
||||||
@@ -314,10 +355,10 @@ function getTemplate(app) {
|
|||||||
// Window menu -> minimizeOnClose.
|
// Window menu -> minimizeOnClose.
|
||||||
// ToDo: Add behavior on Close.
|
// ToDo: Add behavior on Close.
|
||||||
template[index].submenu.push({
|
template[index].submenu.push({
|
||||||
label: 'Minimize on Close',
|
label: i18n.getMessageFor('Minimize on Close'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: minimizeOnClose,
|
checked: minimizeOnClose,
|
||||||
click: function(item) {
|
click: function (item) {
|
||||||
minimizeOnClose = item.checked;
|
minimizeOnClose = item.checked;
|
||||||
updateConfigField('minimizeOnClose', minimizeOnClose);
|
updateConfigField('minimizeOnClose', minimizeOnClose);
|
||||||
}
|
}
|
||||||
@@ -325,10 +366,10 @@ function getTemplate(app) {
|
|||||||
|
|
||||||
// Window menu -> bringToFront
|
// Window menu -> bringToFront
|
||||||
template[index].submenu.push({
|
template[index].submenu.push({
|
||||||
label: isWindowsOS ? 'Flash Notification in Taskbar' : 'Bring to Front on Notifications',
|
label: isWindowsOS ? i18n.getMessageFor('Flash Notification in Taskbar') : i18n.getMessageFor('Bring to Front on Notifications'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: bringToFront,
|
checked: bringToFront,
|
||||||
click: function(item) {
|
click: function (item) {
|
||||||
bringToFront = item.checked;
|
bringToFront = item.checked;
|
||||||
updateConfigField('bringToFront', bringToFront);
|
updateConfigField('bringToFront', bringToFront);
|
||||||
}
|
}
|
||||||
@@ -341,10 +382,10 @@ function getTemplate(app) {
|
|||||||
|
|
||||||
// Window - View menu -> memoryRefresh
|
// Window - View menu -> memoryRefresh
|
||||||
template[index].submenu.push({
|
template[index].submenu.push({
|
||||||
label: 'Refresh app when idle',
|
label: i18n.getMessageFor('Refresh app when idle'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: memoryRefresh,
|
checked: memoryRefresh,
|
||||||
click: function(item) {
|
click: function (item) {
|
||||||
memoryRefresh = item.checked;
|
memoryRefresh = item.checked;
|
||||||
updateConfigField('memoryRefresh', memoryRefresh);
|
updateConfigField('memoryRefresh', memoryRefresh);
|
||||||
}
|
}
|
||||||
@@ -355,10 +396,10 @@ function getTemplate(app) {
|
|||||||
if (isWindows10()) {
|
if (isWindows10()) {
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
template[index].submenu.push({
|
template[index].submenu.push({
|
||||||
label: 'Title Bar Style',
|
label: i18n.getMessageFor('Title Bar Style'),
|
||||||
submenu: [
|
submenu: [
|
||||||
{
|
{
|
||||||
label: 'Native With Custom',
|
label: i18n.getMessageFor('Native With Custom'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: titleBarStyle === titleBarStyles.NATIVE_WITH_CUSTOM,
|
checked: titleBarStyle === titleBarStyles.NATIVE_WITH_CUSTOM,
|
||||||
click: function (item) {
|
click: function (item) {
|
||||||
@@ -368,7 +409,7 @@ function getTemplate(app) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Custom',
|
label: i18n.getMessageFor('Custom'),
|
||||||
type: 'checkbox',
|
type: 'checkbox',
|
||||||
checked: titleBarStyle === titleBarStyles.CUSTOM,
|
checked: titleBarStyle === titleBarStyles.CUSTOM,
|
||||||
click: function (item) {
|
click: function (item) {
|
||||||
@@ -385,15 +426,15 @@ function getTemplate(app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template[index].submenu.push({
|
template[index].submenu.push({
|
||||||
label: 'Quit Symphony',
|
label: i18n.getMessageFor('Quit Symphony'),
|
||||||
click: function() {
|
click: function () {
|
||||||
app.quit();
|
app.quit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// This adds About Symphony under help menu for windows
|
// This adds About Symphony under help menu for windows
|
||||||
template[3].submenu.push({
|
template[3].submenu.push({
|
||||||
label: 'About Symphony',
|
label: i18n.getMessageFor('About Symphony'),
|
||||||
click(focusedWindow) {
|
click(focusedWindow) {
|
||||||
let windowName = focusedWindow ? focusedWindow.name : '';
|
let windowName = focusedWindow ? focusedWindow.name : '';
|
||||||
aboutApp.openAboutWindow(windowName);
|
aboutApp.openAboutWindow(windowName);
|
||||||
@@ -449,15 +490,19 @@ function setCheckboxValues() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return resolve();
|
return resolve();
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
let title = 'Error loading configuration';
|
let title = 'Error loading configuration';
|
||||||
log.send(logLevels.ERROR, 'MenuTemplate: error reading configuration fields, error: ' + err);
|
log.send(logLevels.ERROR, 'MenuTemplate: error reading configuration fields, error: ' + err);
|
||||||
if (electron.BrowserWindow.getFocusedWindow() && !electron.BrowserWindow.getFocusedWindow().isDestroyed()) {
|
if (electron.BrowserWindow.getFocusedWindow() && !electron.BrowserWindow.getFocusedWindow().isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(electron.BrowserWindow.getFocusedWindow(), {type: 'error', title, message: title + ': ' + err});
|
electron.dialog.showMessageBox(electron.BrowserWindow.getFocusedWindow(), {
|
||||||
|
type: 'error',
|
||||||
|
title: i18n.getMessageFor(title),
|
||||||
|
message: i18n.getMessageFor(title) + ': ' + err
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return resolve();
|
return resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,22 +510,23 @@ function setCheckboxValues() {
|
|||||||
* Sets respective accelerators w.r.t roles for the menu template
|
* Sets respective accelerators w.r.t roles for the menu template
|
||||||
*
|
*
|
||||||
* @param role {String} The action of the menu item
|
* @param role {String} The action of the menu item
|
||||||
*
|
* @param label {String} Menu item name
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
* @return {Object}.role The action of the menu item
|
* @return {Object}.role The action of the menu item
|
||||||
* @return {Object}.accelerator keyboard shortcuts and modifiers
|
* @return {Object}.accelerator keyboard shortcuts and modifiers
|
||||||
*/
|
*/
|
||||||
function buildMenuItem(role) {
|
function buildMenuItem(role, label) {
|
||||||
|
|
||||||
if (isMac) {
|
if (isMac) {
|
||||||
return { role: role }
|
return label ? { role: role, label: label } : { role: role }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isWindowsOS) {
|
if (isWindowsOS) {
|
||||||
return { role: role, accelerator: windowsAccelerator[role] || '' }
|
return label ? { role: role, label: label, accelerator: windowsAccelerator[role] || '' }
|
||||||
|
: { role: role, accelerator: windowsAccelerator[role] || '' }
|
||||||
}
|
}
|
||||||
|
|
||||||
return { role: role }
|
return label ? { role: role, label: label } : { role: role }
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMinimizeOnClose() {
|
function getMinimizeOnClose() {
|
||||||
|
|||||||
@@ -86,3 +86,15 @@ ipc.on('screens', (event, screens) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipc.on('i18n-notification-settings', (event, content) => {
|
||||||
|
if (content && typeof content === 'object') {
|
||||||
|
const i18nNodes = document.querySelectorAll('[data-i18n-text]');
|
||||||
|
|
||||||
|
for (let node of i18nNodes) {
|
||||||
|
if (node.attributes['data-i18n-text'] && node.attributes['data-i18n-text'].value) {
|
||||||
|
node.innerText = content[node.attributes['data-i18n-text'].value] || node.attributes['data-i18n-text'].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -2,45 +2,45 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Symphony - Configure Notification Position</title>
|
<title data-i18n-text="Symphony - Configure Notification Position"></title>
|
||||||
<link rel="stylesheet" type="text/css" href="./configure-notification-position.css">
|
<link rel="stylesheet" type="text/css" href="./configure-notification-position.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<span class="header__title">Notification Settings</span>
|
<span class="header__title" data-i18n-text="Notification Settings"></span>
|
||||||
</header>
|
</header>
|
||||||
<div class="form">
|
<div class="form">
|
||||||
<form>
|
<form>
|
||||||
<label class="label">Monitor</label>
|
<label class="label" data-i18n-text="Monitor"></label>
|
||||||
<div id="screens" class="main">
|
<div id="screens" class="main">
|
||||||
<label>Notification shown on Monitor: </label>
|
<label data-i18n-text="Notification shown on Monitor: "></label>
|
||||||
<select class="selector" id="screen-selector" title="position">
|
<select class="selector" id="screen-selector" title="position">
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<label class="label">Position</label>
|
<label class="label" data-i18n-text="Position"></label>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<div class="first-set">
|
<div class="first-set">
|
||||||
<div class="radio">
|
<div class="radio">
|
||||||
<label class="radio__label"><input id="upper-left" type="radio" name="position" value="upper-left">
|
<label class="radio__label"><input id="upper-left" type="radio" name="position" value="upper-left">
|
||||||
Top Left
|
<span data-i18n-text="Top Left"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="radio">
|
<div class="radio">
|
||||||
<label class="radio__label">
|
<label class="radio__label">
|
||||||
<input id="lower-left" type="radio" name="position" value="lower-left">
|
<input id="lower-left" type="radio" name="position" value="lower-left">
|
||||||
Bottom Left
|
<span data-i18n-text="Bottom Left"></span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="second-set">
|
<div class="second-set">
|
||||||
<div class="radio">
|
<div class="radio">
|
||||||
<label class="radio__label">Top Right
|
<label class="radio__label"><span data-i18n-text="Top Right"></span>
|
||||||
<input id="upper-right" type="radio" name="position" value="upper-right">
|
<input id="upper-right" type="radio" name="position" value="upper-right">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div class="radio">
|
<div class="radio">
|
||||||
<label class="radio__label">Bottom Right
|
<label class="radio__label"><span data-i18n-text="Bottom Right"></span>
|
||||||
<input id="lower-right" type="radio" name="position" value="lower-right">
|
<input id="lower-right" type="radio" name="position" value="lower-right">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -52,8 +52,8 @@
|
|||||||
|
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
<div class="buttonLayout">
|
<div class="buttonLayout">
|
||||||
<button id="cancel" class="buttonDismiss">CANCEL</button>
|
<button id="cancel" class="buttonDismiss" data-i18n-text="CANCEL"></button>
|
||||||
<button id="ok-button" class="button">OK</button>
|
<button id="ok-button" class="button" data-i18n-text="OK"></button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ const log = require('../../log.js');
|
|||||||
const logLevels = require('../../enums/logLevels.js');
|
const logLevels = require('../../enums/logLevels.js');
|
||||||
const notify = require('./../electron-notify');
|
const notify = require('./../electron-notify');
|
||||||
const eventEmitter = require('./../../eventEmitter');
|
const eventEmitter = require('./../../eventEmitter');
|
||||||
|
|
||||||
const { updateConfigField } = require('../../config');
|
const { updateConfigField } = require('../../config');
|
||||||
|
const i18n = require('../../translation/i18n');
|
||||||
|
|
||||||
let configurationWindow;
|
let configurationWindow;
|
||||||
let screens;
|
let screens;
|
||||||
@@ -113,6 +113,8 @@ function openConfigurationWindow(windowName) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
configurationWindow.webContents.on('did-finish-load', () => {
|
configurationWindow.webContents.on('did-finish-load', () => {
|
||||||
|
const notificationSettingsContent = i18n.getMessageFor('NotificationSettings');
|
||||||
|
configurationWindow.webContents.send('i18n-notification-settings', notificationSettingsContent);
|
||||||
if (screens && screens.length >= 0) {
|
if (screens && screens.length >= 0) {
|
||||||
configurationWindow.webContents.send('screens', screens);
|
configurationWindow.webContents.send('screens', screens);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -303,6 +303,18 @@ function createAPI() {
|
|||||||
*/
|
*/
|
||||||
setIsInMeeting: function (isInMeeting) {
|
setIsInMeeting: function (isInMeeting) {
|
||||||
throttledSetIsInMeetingStatus(isInMeeting);
|
throttledSetIsInMeetingStatus(isInMeeting);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the language which updates the application locale
|
||||||
|
* @param {string} locale - language identifier and a region identifier
|
||||||
|
* Ex: en-US, ja-JP
|
||||||
|
*/
|
||||||
|
setLocale: function (locale) {
|
||||||
|
local.ipcRenderer.send(apiName, {
|
||||||
|
cmd: apiCmds.setLocale,
|
||||||
|
locale,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
22
js/translation/i18n.js
Normal file
22
js/translation/i18n.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
const path = require("path");
|
||||||
|
const fs = require('fs');
|
||||||
|
let language;
|
||||||
|
let loadedTranslations = {};
|
||||||
|
|
||||||
|
const getMessageFor = function(phrase) {
|
||||||
|
let translation = loadedTranslations[phrase];
|
||||||
|
if(translation === undefined) {
|
||||||
|
translation = phrase;
|
||||||
|
}
|
||||||
|
return translation;
|
||||||
|
};
|
||||||
|
|
||||||
|
const setLanguage = function(lng) {
|
||||||
|
language = lng ? lng : 'en-US';
|
||||||
|
loadedTranslations = JSON.parse(fs.readFileSync(path.join(__dirname, '..', '..', 'locale', language + '.json'), 'utf8'));
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
setLanguage: setLanguage,
|
||||||
|
getMessageFor: getMessageFor
|
||||||
|
};
|
||||||
@@ -25,6 +25,7 @@ const { isMac, isNodeEnv, isWindows10, isWindowsOS } = require('./utils/misc');
|
|||||||
const { deleteIndexFolder } = require('./search/search.js');
|
const { deleteIndexFolder } = require('./search/search.js');
|
||||||
const { isWhitelisted, parseDomain } = require('./utils/whitelistHandler');
|
const { isWhitelisted, parseDomain } = require('./utils/whitelistHandler');
|
||||||
const { initCrashReporterMain, initCrashReporterRenderer } = require('./crashReporter.js');
|
const { initCrashReporterMain, initCrashReporterRenderer } = require('./crashReporter.js');
|
||||||
|
const i18n = require('./translation/i18n');
|
||||||
|
|
||||||
// show dialog when certificate errors occur
|
// show dialog when certificate errors occur
|
||||||
require('./dialogs/showCertError.js');
|
require('./dialogs/showCertError.js');
|
||||||
@@ -253,8 +254,8 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
mainWindow.webContents.on('crashed', function () {
|
mainWindow.webContents.on('crashed', function () {
|
||||||
const options = {
|
const options = {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: 'Renderer Process Crashed',
|
title: i18n.getMessageFor('Renderer Process Crashed'),
|
||||||
message: 'Oops! Looks like we have had a crash. Please reload or close this window.',
|
message: i18n.getMessageFor('Oops! Looks like we have had a crash. Please reload or close this window.'),
|
||||||
buttons: ['Reload', 'Close']
|
buttons: ['Reload', 'Close']
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -274,10 +275,17 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
addWindowKey(key, mainWindow);
|
addWindowKey(key, mainWindow);
|
||||||
mainWindow.loadURL(url);
|
mainWindow.loadURL(url);
|
||||||
|
|
||||||
menu = electron.Menu.buildFromTemplate(getTemplate(app));
|
getConfigField('locale')
|
||||||
if (!isWindows10()) {
|
.then((language) => {
|
||||||
electron.Menu.setApplicationMenu(menu);
|
const lang = language || app.getLocale();
|
||||||
}
|
log.send(`setting app language to ${lang}`);
|
||||||
|
rebuildMenu(lang);
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
const lang = app.getLocale();
|
||||||
|
log.send(`could not find language settings ${err}, defaulting to system language ${app.getLocale()}`);
|
||||||
|
rebuildMenu(lang);
|
||||||
|
});
|
||||||
|
|
||||||
mainWindow.on('close', function (e) {
|
mainWindow.on('close', function (e) {
|
||||||
if (willQuitApp) {
|
if (willQuitApp) {
|
||||||
@@ -422,8 +430,8 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
let handleChildWindowCrashEvent = (e) => {
|
let handleChildWindowCrashEvent = (e) => {
|
||||||
const options = {
|
const options = {
|
||||||
type: 'error',
|
type: 'error',
|
||||||
title: 'Renderer Process Crashed',
|
title: i18n.getMessageFor('Renderer Process Crashed'),
|
||||||
message: 'Oops! Looks like we have had a crash. Please reload or close this window.',
|
message: i18n.getMessageFor('Oops! Looks like we have had a crash. Please reload or close this window.'),
|
||||||
buttons: ['Reload', 'Close']
|
buttons: ['Reload', 'Close']
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -494,8 +502,8 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
electron.dialog.showMessageBox(mainWindow, {
|
electron.dialog.showMessageBox(mainWindow, {
|
||||||
type: 'warning',
|
type: 'warning',
|
||||||
buttons: ['Ok'],
|
buttons: ['Ok'],
|
||||||
title: 'Not Allowed',
|
title: i18n.getMessageFor('Not Allowed'),
|
||||||
message: `Sorry, you are not allowed to access this website (${navigatedURL}), please contact your administrator for more details`,
|
message: i18n.getMessageFor('Sorry, you are not allowed to access this website') + ' (' + navigatedURL + '), ' + i18n.getMessageFor('please contact your administrator for more details'),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -538,10 +546,10 @@ function doCreateMainWindow(initialUrl, initialBounds, isCustomTitleBar) {
|
|||||||
log.send(logLevels.INFO, 'permission is -> ' + userPermission);
|
log.send(logLevels.INFO, 'permission is -> ' + userPermission);
|
||||||
|
|
||||||
if (!userPermission) {
|
if (!userPermission) {
|
||||||
let fullMessage = `Your administrator has disabled ${message}. Please contact your admin for help.`;
|
let fullMessage = i18n.getMessageFor('Your administrator has disabled') + message + '. ' + i18n.getMessageFor('Please contact your admin for help');
|
||||||
const browserWindow = BrowserWindow.getFocusedWindow();
|
const browserWindow = BrowserWindow.getFocusedWindow();
|
||||||
if (browserWindow && !browserWindow.isDestroyed()) {
|
if (browserWindow && !browserWindow.isDestroyed()) {
|
||||||
electron.dialog.showMessageBox(browserWindow, {type: 'error', title: 'Permission Denied!', message: fullMessage});
|
electron.dialog.showMessageBox(browserWindow, {type: 'error', title: i18n.getMessageFor('Permission Denied') + '!', message: fullMessage});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -835,6 +843,25 @@ eventEmitter.on('notificationSettings', (notificationSettings) => {
|
|||||||
display = notificationSettings.display;
|
display = notificationSettings.display;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
eventEmitter.on('language-changed', (opts) => {
|
||||||
|
const lang = opts && opts.language || app.getLocale();
|
||||||
|
log.send(logLevels.INFO, `language changed to ${lang}. Updating menu and user config`);
|
||||||
|
rebuildMenu(lang);
|
||||||
|
updateConfigField('locale', lang);
|
||||||
|
});
|
||||||
|
|
||||||
|
function rebuildMenu(language) {
|
||||||
|
setLanguage(language);
|
||||||
|
menu = electron.Menu.buildFromTemplate(getTemplate(app));
|
||||||
|
if (!isWindows10()) {
|
||||||
|
electron.Menu.setApplicationMenu(menu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLanguage(lang) {
|
||||||
|
i18n.setLanguage(lang);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that gets invoked when an external display
|
* Method that gets invoked when an external display
|
||||||
* is removed using electron 'display-removed' event.
|
* is removed using electron 'display-removed' event.
|
||||||
|
|||||||
97
locale/en-US.json
Normal file
97
locale/en-US.json
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
{
|
||||||
|
"About Symphony": "About Symphony",
|
||||||
|
"Actual Size": "Actual Size",
|
||||||
|
"Always on Top": "Always on Top",
|
||||||
|
"Auto Launch On Startup": "Auto Launch On Startup",
|
||||||
|
"BasicAuth": {
|
||||||
|
"Authentication Request": "Authentication Request",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"hostname": "hostname",
|
||||||
|
"Invalid user name/password": "Invalid user name/password",
|
||||||
|
"Log In": "Log In",
|
||||||
|
"Password:": "Password:",
|
||||||
|
"Please provide your login credentials for:": "Please provide your login credentials for:",
|
||||||
|
"User name:": "User name:"
|
||||||
|
},
|
||||||
|
"Bring All to Front": "Bring All to Front",
|
||||||
|
"Bring to Front on Notifications": "Bring to Front on Notifications",
|
||||||
|
"Close": "Close",
|
||||||
|
"Copy": "Copy",
|
||||||
|
"Cut": "Cut",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Help": "Help",
|
||||||
|
"Hide Others": "Hide Others",
|
||||||
|
"Hide Symphony": "Hide Symphony",
|
||||||
|
"Learn More": "Learn More",
|
||||||
|
"Minimize": "Minimize",
|
||||||
|
"Minimize on Close": "Minimize on Close",
|
||||||
|
"NotificationSettings": {
|
||||||
|
"Bottom Left": "Bottom Left",
|
||||||
|
"Bottom Right": "Bottom Right",
|
||||||
|
"CANCEL": "CANCEL",
|
||||||
|
"Monitor": "Monitor",
|
||||||
|
"Notification Settings": "Notification Settings",
|
||||||
|
"Notification shown on Monitor: ": "Notification shown on Monitor: ",
|
||||||
|
"OK": "OK",
|
||||||
|
"Position": "Position",
|
||||||
|
"Symphony - Configure Notification Position": "Symphony - Configure Notification Position",
|
||||||
|
"Top Left": "Top Left",
|
||||||
|
"Top Right": "Top Right"
|
||||||
|
},
|
||||||
|
"Paste": "Paste",
|
||||||
|
"Paste and Match Style": "Paste and Match Style",
|
||||||
|
"Quit Symphony": "Quit Symphony",
|
||||||
|
"Redo": "Redo",
|
||||||
|
"Refresh app when idle": "Refresh app when idle",
|
||||||
|
"Reload": "Reload",
|
||||||
|
"ScreenPicker": {
|
||||||
|
"Applications": "Applications",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Choose what you'd like to share": "Choose what you'd like to share",
|
||||||
|
"No screens or applications are currently available.": "No screens or applications are currently available.",
|
||||||
|
"Screen Picker": "Screen Picker",
|
||||||
|
"Screens": "Screens",
|
||||||
|
"Select Application": "Select Application",
|
||||||
|
"Select Screen": "Select Screen",
|
||||||
|
"Share": "Share"
|
||||||
|
},
|
||||||
|
"Select All": "Select All",
|
||||||
|
"Services": "Services",
|
||||||
|
"Show All": "Show All",
|
||||||
|
"Show crash dump in Finder": "Show crash dump in Finder",
|
||||||
|
"Show Logs in Finder": "Show Logs in Finder",
|
||||||
|
"Speech": "Speech",
|
||||||
|
"Start Speaking": "Start Speaking",
|
||||||
|
"Stop Speaking": "Stop Speaking",
|
||||||
|
"Symphony Help": "Symphony Help",
|
||||||
|
"Toggle Full Screen": "Toggle Full Screen",
|
||||||
|
"Troubleshooting": "Troubleshooting",
|
||||||
|
"Undo": "Undo",
|
||||||
|
"View": "View",
|
||||||
|
"Window": "Window",
|
||||||
|
"Zoom": "Zoom",
|
||||||
|
"Zoom In": "Zoom In",
|
||||||
|
"Zoom Out": "Zoom Out",
|
||||||
|
"Renderer Process Crashed": "Renderer Process Crashed",
|
||||||
|
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
||||||
|
"Failed!": "Failed!",
|
||||||
|
"No logs are available to share": "No logs are available to share",
|
||||||
|
"Unable to generate logs due to ": "Unable to generate logs due to ",
|
||||||
|
"Show crash dump in Explorer": "Show crash dump in Explorer",
|
||||||
|
"No crashes available to share": "No crashes available to share",
|
||||||
|
"Unable to generate crash reports due to ": "Unable to generate crash reports due to ",
|
||||||
|
"Error setting AutoLaunch configuration": "Error setting AutoLaunch configuration",
|
||||||
|
"Error loading configuration": "Error loading configuration",
|
||||||
|
"Certificate Error": "Certificate Error",
|
||||||
|
"Error loading URL": "Error loading URL",
|
||||||
|
"Error loading window": "Error loading window",
|
||||||
|
"Loading Error": "Loading Error",
|
||||||
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
||||||
|
"Not Allowed": "Not Allowed",
|
||||||
|
"Sorry, you are not allowed to access this website": "Sorry, you are not allowed to access this website",
|
||||||
|
"please contact your administrator for more details": "please contact your administrator for more details",
|
||||||
|
"Your administrator has disabled": "Your administrator has disabled",
|
||||||
|
"Please contact your admin for help": "Please contact your admin for help",
|
||||||
|
"Permission Denied": "Permission Denied"
|
||||||
|
}
|
||||||
97
locale/en.json
Normal file
97
locale/en.json
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
{
|
||||||
|
"About Symphony": "About Symphony",
|
||||||
|
"Actual Size": "Actual Size",
|
||||||
|
"Always on Top": "Always on Top",
|
||||||
|
"Auto Launch On Startup": "Auto Launch On Startup",
|
||||||
|
"BasicAuth": {
|
||||||
|
"Authentication Request": "Authentication Request",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"hostname": "hostname",
|
||||||
|
"Invalid user name/password": "Invalid user name/password",
|
||||||
|
"Log In": "Log In",
|
||||||
|
"Password:": "Password:",
|
||||||
|
"Please provide your login credentials for:": "Please provide your login credentials for:",
|
||||||
|
"User name:": "User name:"
|
||||||
|
},
|
||||||
|
"Bring All to Front": "Bring All to Front",
|
||||||
|
"Bring to Front on Notifications": "Bring to Front on Notifications",
|
||||||
|
"Close": "Close",
|
||||||
|
"Copy": "Copy",
|
||||||
|
"Cut": "Cut",
|
||||||
|
"Delete": "Delete",
|
||||||
|
"Edit": "Edit",
|
||||||
|
"Help": "Help",
|
||||||
|
"Hide Others": "Hide Others",
|
||||||
|
"Hide Symphony": "Hide Symphony",
|
||||||
|
"Learn More": "Learn More",
|
||||||
|
"Minimize": "Minimize",
|
||||||
|
"Minimize on Close": "Minimize on Close",
|
||||||
|
"NotificationSettings": {
|
||||||
|
"Bottom Left": "Bottom Left",
|
||||||
|
"Bottom Right": "Bottom Right",
|
||||||
|
"CANCEL": "CANCEL",
|
||||||
|
"Monitor": "Monitor",
|
||||||
|
"Notification Settings": "Notification Settings",
|
||||||
|
"Notification shown on Monitor: ": "Notification shown on Monitor: ",
|
||||||
|
"OK": "OK",
|
||||||
|
"Position": "Position",
|
||||||
|
"Symphony - Configure Notification Position": "Symphony - Configure Notification Position",
|
||||||
|
"Top Left": "Top Left",
|
||||||
|
"Top Right": "Top Right"
|
||||||
|
},
|
||||||
|
"Paste": "Paste",
|
||||||
|
"Paste and Match Style": "Paste and Match Style",
|
||||||
|
"Quit Symphony": "Quit Symphony",
|
||||||
|
"Redo": "Redo",
|
||||||
|
"Refresh app when idle": "Refresh app when idle",
|
||||||
|
"Reload": "Reload",
|
||||||
|
"ScreenPicker": {
|
||||||
|
"Applications": "Applications",
|
||||||
|
"Cancel": "Cancel",
|
||||||
|
"Choose what you'd like to share": "Choose what you'd like to share",
|
||||||
|
"No screens or applications are currently available.": "No screens or applications are currently available.",
|
||||||
|
"Screen Picker": "Screen Picker",
|
||||||
|
"Screens": "Screens",
|
||||||
|
"Select Application": "Select Application",
|
||||||
|
"Select Screen": "Select Screen",
|
||||||
|
"Share": "Share"
|
||||||
|
},
|
||||||
|
"Select All": "Select All",
|
||||||
|
"Services": "Services",
|
||||||
|
"Show All": "Show All",
|
||||||
|
"Show crash dump in Finder": "Show crash dump in Finder",
|
||||||
|
"Show Logs in Finder": "Show Logs in Finder",
|
||||||
|
"Speech": "Speech",
|
||||||
|
"Start Speaking": "Start Speaking",
|
||||||
|
"Stop Speaking": "Stop Speaking",
|
||||||
|
"Symphony Help": "Symphony Help",
|
||||||
|
"Toggle Full Screen": "Toggle Full Screen",
|
||||||
|
"Troubleshooting": "Troubleshooting",
|
||||||
|
"Undo": "Undo",
|
||||||
|
"View": "View",
|
||||||
|
"Window": "Window",
|
||||||
|
"Zoom": "Zoom",
|
||||||
|
"Zoom In": "Zoom In",
|
||||||
|
"Zoom Out": "Zoom Out",
|
||||||
|
"Renderer Process Crashed": "Renderer Process Crashed",
|
||||||
|
"Oops! Looks like we have had a crash.": "Oops! Looks like we have had a crash.",
|
||||||
|
"Failed!": "Failed!",
|
||||||
|
"No logs are available to share": "No logs are available to share",
|
||||||
|
"Unable to generate logs due to ": "Unable to generate logs due to ",
|
||||||
|
"Show crash dump in Explorer": "Show crash dump in Explorer",
|
||||||
|
"No crashes available to share": "No crashes available to share",
|
||||||
|
"Unable to generate crash reports due to ": "Unable to generate crash reports due to ",
|
||||||
|
"Error setting AutoLaunch configuration": "Error setting AutoLaunch configuration",
|
||||||
|
"Error loading configuration": "Error loading configuration",
|
||||||
|
"Certificate Error": "Certificate Error",
|
||||||
|
"Error loading URL": "Error loading URL",
|
||||||
|
"Error loading window": "Error loading window",
|
||||||
|
"Loading Error": "Loading Error",
|
||||||
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "Oops! Looks like we have had a crash. Please reload or close this window.",
|
||||||
|
"Not Allowed": "Not Allowed",
|
||||||
|
"Sorry, you are not allowed to access this website": "Sorry, you are not allowed to access this website",
|
||||||
|
"please contact your administrator for more details": "please contact your administrator for more details",
|
||||||
|
"Your administrator has disabled": "Your administrator has disabled",
|
||||||
|
"Please contact your admin for help": "Please contact your admin for help",
|
||||||
|
"Permission Denied": "Permission Denied"
|
||||||
|
}
|
||||||
104
locale/ja-JP.json
Normal file
104
locale/ja-JP.json
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
{
|
||||||
|
"About Symphony": "Symphonyについて",
|
||||||
|
"Actual Size": "実際のサイズ",
|
||||||
|
"Always on Top": "常にトップに表示",
|
||||||
|
"Auto Launch On Startup": "スタートアップ時の自動起動",
|
||||||
|
"BasicAuth": {
|
||||||
|
"Authentication Request": "認証の要求",
|
||||||
|
"Cancel": "キャンセル",
|
||||||
|
"hostname": "ホスト名",
|
||||||
|
"Invalid user name/password": "ユーザー名またはパスワードが無効です",
|
||||||
|
"Log In": "ログイン",
|
||||||
|
"Password:": "パスワード:",
|
||||||
|
"Please provide your login credentials for:": "あなたのログイン資格情報を入力してください:",
|
||||||
|
"User name:": "ユーザー名:"
|
||||||
|
},
|
||||||
|
"Bring All to Front": "すべてを前面に表示",
|
||||||
|
"Bring to Front on Notifications": "通知の前面に表示",
|
||||||
|
"Close": "閉じる",
|
||||||
|
"Copy": "コピー",
|
||||||
|
"Cut": "切り取り",
|
||||||
|
"Delete": "削除",
|
||||||
|
"Edit": "編集",
|
||||||
|
"Help": "ヘルプ",
|
||||||
|
"Hide Others": "他を隠す",
|
||||||
|
"Hide Symphony": "Symphonyを隠す",
|
||||||
|
"Learn More": "詳細を表示",
|
||||||
|
"Minimize": "最小化",
|
||||||
|
"Minimize on Close": "閉じる時に最小化",
|
||||||
|
"NotificationSettings": {
|
||||||
|
"Bottom Left": "左下",
|
||||||
|
"Bottom Right": "右下",
|
||||||
|
"CANCEL": "キャンセル",
|
||||||
|
"Monitor": "モニター",
|
||||||
|
"Notification Settings": "通知設定",
|
||||||
|
"Notification shown on Monitor: ": "モニターに表示される通知:",
|
||||||
|
"OK": "OK",
|
||||||
|
"Position": "位置",
|
||||||
|
"Symphony - Configure Notification Position": "Symphony - 通知位置の設定",
|
||||||
|
"Top Left": "左上",
|
||||||
|
"Top Right": "右上"
|
||||||
|
},
|
||||||
|
"Paste": "ペースト",
|
||||||
|
"Paste and Match Style": "ペーストしてスタイルを合わせる",
|
||||||
|
"Quit Symphony": "Symphonyの終了",
|
||||||
|
"Redo": "やり直し",
|
||||||
|
"Refresh app when idle": "アイドル時にアプリを更新する",
|
||||||
|
"Reload": "再ロード",
|
||||||
|
"ScreenPicker": {
|
||||||
|
"Applications": "アプリケーション",
|
||||||
|
"Cancel": "キャンセル",
|
||||||
|
"Choose what you'd like to share": "共有するものを選択する",
|
||||||
|
"No screens or applications are currently available.": "現在利用可能な画面やアプリケーションはありません。",
|
||||||
|
"Screen Picker": "画面の選択",
|
||||||
|
"Screens": "画面",
|
||||||
|
"Select Application": "アプリケーションの選択",
|
||||||
|
"Select Screen": "画面の選択",
|
||||||
|
"Share": "共有"
|
||||||
|
},
|
||||||
|
"ScreenSnippet": {
|
||||||
|
"Pen": "ペン",
|
||||||
|
"Done": "完了",
|
||||||
|
"Snipping Tool": "スニッピングツール",
|
||||||
|
"Erase": "消去する",
|
||||||
|
"Highlight": "ハイライト"
|
||||||
|
},
|
||||||
|
"Select All": "すべてを選択",
|
||||||
|
"Services": "サービス",
|
||||||
|
"Show All": "すべてを表示",
|
||||||
|
"Show crash dump in Finder": "ファインダーにクラッシュダンプを表示",
|
||||||
|
"Show Logs in Finder": "ファインダーにログを表示",
|
||||||
|
"Speech": "スピーチ",
|
||||||
|
"Start Speaking": "スピーキングを始める",
|
||||||
|
"Stop Speaking": "スピーキングをやめる",
|
||||||
|
"Symphony Help": "Symphonyヘルプ",
|
||||||
|
"Toggle Full Screen": "フルスクリーン切り替え",
|
||||||
|
"Troubleshooting": "トラブルシューティング",
|
||||||
|
"Undo": "元に戻す",
|
||||||
|
"View": "ビュー",
|
||||||
|
"Window": "ウインドウ",
|
||||||
|
"Zoom": "ズーム",
|
||||||
|
"Zoom In": "ズームイン",
|
||||||
|
"Zoom Out": "ズームアウト",
|
||||||
|
"Renderer Process Crashed": "レンダラープロセスがクラッシュしました",
|
||||||
|
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
||||||
|
"Failed!": "失敗!",
|
||||||
|
"No logs are available to share": "共有できるログはありません",
|
||||||
|
"Unable to generate logs due to ": "以下が原因でログを生成できません ",
|
||||||
|
"Show crash dump in Explorer": "Explorerにクラッシュダンプを表示",
|
||||||
|
"No crashes available to share": "共有できるクラッシュはありません",
|
||||||
|
"Unable to generate crash reports due to ": "以下が原因でクラッシュレポートを生成できません ",
|
||||||
|
"Error setting AutoLaunch configuration": "自動起動設定の設定エラー",
|
||||||
|
"Error loading configuration": "設定を読み込む際のエラー",
|
||||||
|
"Certificate Error": "証明エラー",
|
||||||
|
"Error loading URL": "URLの読み込みエラー",
|
||||||
|
"Error loading window": "ウィンドウを読み込む際のエラー",
|
||||||
|
"Loading Error": "読み込みエラー",
|
||||||
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウをリロードしてください。",
|
||||||
|
"Not Allowed": "未許可",
|
||||||
|
"Sorry, you are not allowed to access this website": "申し訳ありませんが、このウェブサイトへのアクセスは許可されていません",
|
||||||
|
"please contact your administrator for more details": "詳細については、管理者にお問い合わせください",
|
||||||
|
"Your administrator has disabled": "管理者が無効にしました",
|
||||||
|
"Please contact your admin for help": "ヘルプについては管理者にお問い合わせください",
|
||||||
|
"Permission Denied": "許可が拒否されました"
|
||||||
|
}
|
||||||
97
locale/ja.json
Normal file
97
locale/ja.json
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
{
|
||||||
|
"About Symphony": "Symphonyについて",
|
||||||
|
"Actual Size": "実際のサイズ",
|
||||||
|
"Always on Top": "常にトップに表示",
|
||||||
|
"Auto Launch On Startup": "スタートアップ時の自動起動",
|
||||||
|
"BasicAuth": {
|
||||||
|
"Authentication Request": "認証の要求",
|
||||||
|
"Cancel": "キャンセル",
|
||||||
|
"hostname": "ホスト名",
|
||||||
|
"Invalid user name/password": "ユーザー名またはパスワードが無効です",
|
||||||
|
"Log In": "ログイン",
|
||||||
|
"Password:": "パスワード:",
|
||||||
|
"Please provide your login credentials for:": "あなたのログイン資格情報を入力してください:",
|
||||||
|
"User name:": "ユーザー名:"
|
||||||
|
},
|
||||||
|
"Bring All to Front": "すべてを前面に表示",
|
||||||
|
"Bring to Front on Notifications": "通知の前面に表示",
|
||||||
|
"Close": "閉じる",
|
||||||
|
"Copy": "コピー",
|
||||||
|
"Cut": "切り取り",
|
||||||
|
"Delete": "削除",
|
||||||
|
"Edit": "編集",
|
||||||
|
"Help": "ヘルプ",
|
||||||
|
"Hide Others": "他を隠す",
|
||||||
|
"Hide Symphony": "Symphonyを隠す",
|
||||||
|
"Learn More": "詳細を表示",
|
||||||
|
"Minimize": "最小化",
|
||||||
|
"Minimize on Close": "閉じる時に最小化",
|
||||||
|
"NotificationSettings": {
|
||||||
|
"Bottom Left": "左下",
|
||||||
|
"Bottom Right": "右下",
|
||||||
|
"CANCEL": "キャンセル",
|
||||||
|
"Monitor": "モニター",
|
||||||
|
"Notification Settings": "通知設定",
|
||||||
|
"Notification shown on Monitor: ": "モニターに表示される通知:",
|
||||||
|
"OK": "OK",
|
||||||
|
"Position": "位置",
|
||||||
|
"Symphony - Configure Notification Position": "Symphony - 通知位置の設定",
|
||||||
|
"Top Left": "左上",
|
||||||
|
"Top Right": "右上"
|
||||||
|
},
|
||||||
|
"Paste": "ペースト",
|
||||||
|
"Paste and Match Style": "ペーストしてスタイルを合わせる",
|
||||||
|
"Quit Symphony": "Symphonyの終了",
|
||||||
|
"Redo": "やり直し",
|
||||||
|
"Refresh app when idle": "アイドル時にアプリを更新する",
|
||||||
|
"Reload": "再ロード",
|
||||||
|
"ScreenPicker": {
|
||||||
|
"Applications": "アプリケーション",
|
||||||
|
"Cancel": "キャンセル",
|
||||||
|
"Choose what you'd like to share": "共有するものを選択する",
|
||||||
|
"No screens or applications are currently available.": "現在利用可能な画面やアプリケーションはありません。",
|
||||||
|
"Screen Picker": "画面の選択",
|
||||||
|
"Screens": "画面",
|
||||||
|
"Select Application": "アプリケーションの選択",
|
||||||
|
"Select Screen": "画面の選択",
|
||||||
|
"Share": "共有"
|
||||||
|
},
|
||||||
|
"Select All": "すべてを選択",
|
||||||
|
"Services": "サービス",
|
||||||
|
"Show All": "すべてを表示",
|
||||||
|
"Show crash dump in Finder": "ファインダーにクラッシュダンプを表示",
|
||||||
|
"Show Logs in Finder": "ファインダーにログを表示",
|
||||||
|
"Speech": "スピーチ",
|
||||||
|
"Start Speaking": "スピーキングを始める",
|
||||||
|
"Stop Speaking": "スピーキングをやめる",
|
||||||
|
"Symphony Help": "Symphonyヘルプ",
|
||||||
|
"Toggle Full Screen": "フルスクリーン切り替え",
|
||||||
|
"Troubleshooting": "トラブルシューティング",
|
||||||
|
"Undo": "元に戻す",
|
||||||
|
"View": "ビュー",
|
||||||
|
"Window": "ウインドウ",
|
||||||
|
"Zoom": "ズーム",
|
||||||
|
"Zoom In": "ズームイン",
|
||||||
|
"Zoom Out": "ズームアウト",
|
||||||
|
"Renderer Process Crashed": "レンダラープロセスがクラッシュしました",
|
||||||
|
"Oops! Looks like we have had a crash.": "おっと!クラッシュしたようです。",
|
||||||
|
"Failed!": "失敗!",
|
||||||
|
"No logs are available to share": "共有できるログはありません",
|
||||||
|
"Unable to generate logs due to ": "以下が原因でログを生成できません ",
|
||||||
|
"Show crash dump in Explorer": "Explorerにクラッシュダンプを表示",
|
||||||
|
"No crashes available to share": "共有できるクラッシュはありません",
|
||||||
|
"Unable to generate crash reports due to ": "以下が原因でクラッシュレポートを生成できません ",
|
||||||
|
"Error setting AutoLaunch configuration": "自動起動設定の設定エラー",
|
||||||
|
"Error loading configuration": "設定を読み込む際のエラー",
|
||||||
|
"Certificate Error": "証明エラー",
|
||||||
|
"Error loading URL": "URLの読み込みエラー",
|
||||||
|
"Error loading window": "ウィンドウを読み込む際のエラー",
|
||||||
|
"Loading Error": "読み込みエラー",
|
||||||
|
"Oops! Looks like we have had a crash. Please reload or close this window.": "おっと!クラッシュしたようです。このウィンドウをリロードしてください。",
|
||||||
|
"Not Allowed": "未許可",
|
||||||
|
"Sorry, you are not allowed to access this website": "申し訳ありませんが、このウェブサイトへのアクセスは許可されていません",
|
||||||
|
"please contact your administrator for more details": "詳細については、管理者にお問い合わせください",
|
||||||
|
"Your administrator has disabled": "管理者が無効にしました",
|
||||||
|
"Please contact your admin for help": "ヘルプについては管理者にお問い合わせください",
|
||||||
|
"Permission Denied": "許可が拒否されました"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user