mirror of
https://github.com/element-hq/element-desktop.git
synced 2026-01-03 13:07:55 -05:00
Compare commits
74 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f6f947254 | ||
|
|
bebed00200 | ||
|
|
d74631a555 | ||
|
|
944bb3c717 | ||
|
|
7fad439078 | ||
|
|
f98d1672af | ||
|
|
debeef6ee6 | ||
|
|
28096f3a22 | ||
|
|
5efc4528a2 | ||
|
|
75b41d65c1 | ||
|
|
cc5dc4d801 | ||
|
|
7e34425d78 | ||
|
|
5f09505056 | ||
|
|
9def502c95 | ||
|
|
e09b01f303 | ||
|
|
32aacbdd9a | ||
|
|
e1554cbbe0 | ||
|
|
2b8c378773 | ||
|
|
fe7bf57565 | ||
|
|
cbaad79515 | ||
|
|
a7a8115b17 | ||
|
|
e694a8e30e | ||
|
|
cda4f8ccb4 | ||
|
|
4369b3a5ad | ||
|
|
933d0b80bf | ||
|
|
043e006f3b | ||
|
|
2a1acf0525 | ||
|
|
820e32e250 | ||
|
|
20e4459bb5 | ||
|
|
913c954eeb | ||
|
|
b5fdeddec3 | ||
|
|
38dab479b1 | ||
|
|
f385b1f1d5 | ||
|
|
298ccbe16c | ||
|
|
b8c99c6186 | ||
|
|
ca70486323 | ||
|
|
4bee175f16 | ||
|
|
628b37a2d1 | ||
|
|
9daf5ae413 | ||
|
|
19c8c5f580 | ||
|
|
989b4df6c6 | ||
|
|
21c40b796f | ||
|
|
ccb302b951 | ||
|
|
7d29046cba | ||
|
|
9c3e557333 | ||
|
|
6a7735247e | ||
|
|
c0f5ed15e2 | ||
|
|
56d9a86152 | ||
|
|
82def5ce37 | ||
|
|
5ec91d3a53 | ||
|
|
8b69982023 | ||
|
|
7e69c81e62 | ||
|
|
e64e6e642c | ||
|
|
7f24661357 | ||
|
|
46b1015478 | ||
|
|
8ae641bc59 | ||
|
|
8f4c827089 | ||
|
|
20ce3d10a3 | ||
|
|
72483a60cb | ||
|
|
de16099360 | ||
|
|
ae0213b663 | ||
|
|
b9510d0a0b | ||
|
|
c56aa9100f | ||
|
|
d59384f3e7 | ||
|
|
00ba42186b | ||
|
|
e950303966 | ||
|
|
105070716e | ||
|
|
3b4eb5c18e | ||
|
|
658304cc51 | ||
|
|
b7dd4e53a3 | ||
|
|
1fa6671a17 | ||
|
|
3f9495f19d | ||
|
|
14a65fb0af | ||
|
|
cdbda52d9a |
38
CHANGELOG.md
38
CHANGELOG.md
@@ -1,3 +1,41 @@
|
||||
Changes in [1.7.28](https://github.com/vector-im/element-desktop/releases/tag/v1.7.28) (2021-05-17)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.28-rc.1...v1.7.28)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.28-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.28-rc.1) (2021-05-11)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.27...v1.7.28-rc.1)
|
||||
|
||||
* Add Windows native module requirements
|
||||
[\#190](https://github.com/vector-im/element-desktop/pull/190)
|
||||
* Prevent black screen when closing window while in full screen mode on macOS
|
||||
[\#192](https://github.com/vector-im/element-desktop/pull/192)
|
||||
|
||||
Changes in [1.7.27](https://github.com/vector-im/element-desktop/releases/tag/v1.7.27) (2021-05-10)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.27-rc.1...v1.7.27)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.27-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.27-rc.1) (2021-05-04)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.26...v1.7.27-rc.1)
|
||||
|
||||
* Translations update from Weblate
|
||||
[\#191](https://github.com/vector-im/element-desktop/pull/191)
|
||||
* Bump ssri from 6.0.1 to 6.0.2
|
||||
[\#187](https://github.com/vector-im/element-desktop/pull/187)
|
||||
* Disables HardwareMediaKeyHandling
|
||||
[\#180](https://github.com/vector-im/element-desktop/pull/180)
|
||||
* Translations update from Weblate
|
||||
[\#189](https://github.com/vector-im/element-desktop/pull/189)
|
||||
* Add internationalisation support
|
||||
[\#188](https://github.com/vector-im/element-desktop/pull/188)
|
||||
* Fix event index passphrase change process
|
||||
[\#186](https://github.com/vector-im/element-desktop/pull/186)
|
||||
|
||||
Changes in [1.7.26](https://github.com/vector-im/element-desktop/releases/tag/v1.7.26) (2021-04-26)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.26-rc.1...v1.7.26)
|
||||
|
||||
11
README.md
11
README.md
@@ -65,7 +65,7 @@ yarn run build:native
|
||||
```
|
||||
|
||||
On Windows, this will automatically determine the architecture to build for based
|
||||
on the environment (ie. set up by vcvarsall.bat).
|
||||
on the environment. Make sure that you have all the [tools required to perform the native modules build](docs/windows-requirements.md)
|
||||
|
||||
Now you can build the package:
|
||||
|
||||
@@ -148,6 +148,15 @@ $PROFILE` in which case it becomes `Element-$PROFILE`, or it is using one of
|
||||
the above created by a pre-1.7 install, in which case it will be `Riot` or
|
||||
`Riot-$PROFILE`.
|
||||
|
||||
Translations
|
||||
==========================
|
||||
|
||||
To add a new translation, head to the [translating doc](https://github.com/vector-im/element-web/blob/develop/docs/translating.md).
|
||||
|
||||
For a developer guide, see the [translating dev doc](https://github.com/vector-im/element-web/blob/develop/docs/translating-dev.md).
|
||||
|
||||
[<img src="https://translate.element.io/widgets/element-desktop/-/multi-auto.svg" alt="translationsstatus" width="340">](https://translate.element.io/engage/element-desktop/?utm_source=widget)
|
||||
|
||||
Report bugs & give feedback
|
||||
==========================
|
||||
|
||||
|
||||
26
docs/windows-requirements.md
Normal file
26
docs/windows-requirements.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Windows
|
||||
|
||||
## Requirements to build native modules
|
||||
|
||||
If you want to build native modules, make sure that the following tools are installed on your system.
|
||||
|
||||
- [Node 14](https://nodejs.org)
|
||||
- [Python 3](https://www.python.org/downloads/)
|
||||
- [Strawberry Perl](https://strawberryperl.com/)
|
||||
- [Rust](https://rustup.rs/)
|
||||
- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019) with the following configuration:
|
||||
- On the Workloads tab:
|
||||
- Desktop & Mobile -> C++ build tools
|
||||
- On the Individual components tab:
|
||||
- MSVC VS 2019 C++ build tools
|
||||
- Windows 10 SDK (latest version available)
|
||||
- C++ CMake tools for Windows
|
||||
|
||||
Once installed make sure all those utilities are accessible in your `PATH`.
|
||||
In order to load all the C++ utilities installed by Visual Studio you can run the following in a terminal window.
|
||||
|
||||
```
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
|
||||
```
|
||||
|
||||
You can replace `amd64` with `x86` depending on your CPU architecture.
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "element-desktop",
|
||||
"productName": "Element",
|
||||
"main": "src/electron-main.js",
|
||||
"version": "1.7.26",
|
||||
"version": "1.7.28",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "Element",
|
||||
"repository": {
|
||||
@@ -12,6 +12,9 @@
|
||||
"license": "Apache-2.0",
|
||||
"files": [],
|
||||
"scripts": {
|
||||
"i18n": "matrix-gen-i18n",
|
||||
"prunei18n": "matrix-prune-i18n",
|
||||
"diff-i18n": "cp src/i18n/strings/en_EN.json src/i18n/strings/en_EN_orig.json && matrix-gen-i18n && matrix-compare-i18n-files src/i18n/strings/en_EN_orig.json src/i18n/strings/en_EN.json",
|
||||
"mkdirs": "mkdirp packages deploys",
|
||||
"fetch": "yarn run mkdirs && node scripts/fetch-package.js",
|
||||
"asar-webapp": "asar p webapp webapp.asar",
|
||||
@@ -31,6 +34,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"auto-launch": "^5.0.5",
|
||||
"counterpart": "^0.18.6",
|
||||
"electron-store": "^6.0.1",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"minimist": "^1.2.3",
|
||||
@@ -48,6 +52,7 @@
|
||||
"find-npm-prefix": "^1.0.2",
|
||||
"fs-extra": "^8.1.0",
|
||||
"glob": "^7.1.6",
|
||||
"matrix-web-i18n": "github:matrix-org/matrix-web-i18n",
|
||||
"mkdirp": "^1.0.3",
|
||||
"needle": "^2.5.0",
|
||||
"node-pre-gyp": "^0.15.0",
|
||||
|
||||
@@ -34,7 +34,7 @@ const AutoLaunch = require('auto-launch');
|
||||
const path = require('path');
|
||||
|
||||
const tray = require('./tray');
|
||||
const vectorMenu = require('./vectormenu');
|
||||
const buildMenuTemplate = require('./vectormenu');
|
||||
const webContentsHandler = require('./webcontents-handler');
|
||||
const updater = require('./updater');
|
||||
const {getProfileFromDeeplink, protocolInit, recordSSOSession} = require('./protocol');
|
||||
@@ -57,13 +57,13 @@ try {
|
||||
}
|
||||
}
|
||||
|
||||
const { _t, AppLocalization } = require('./language-helper');
|
||||
|
||||
let seshatSupported = false;
|
||||
let Seshat;
|
||||
let SeshatRecovery;
|
||||
let ReindexError;
|
||||
|
||||
const seshatDefaultPassphrase = "DEFAULT_PASSPHRASE";
|
||||
|
||||
try {
|
||||
const seshatModule = require('matrix-seshat');
|
||||
Seshat = seshatModule.Seshat;
|
||||
@@ -86,6 +86,7 @@ let vectorConfig;
|
||||
let iconPath;
|
||||
let trayConfig;
|
||||
let launcher;
|
||||
let appLocalization;
|
||||
|
||||
if (argv["help"]) {
|
||||
console.log("Options:");
|
||||
@@ -268,8 +269,8 @@ const warnBeforeExit = (event, input) => {
|
||||
if (shouldWarnBeforeExit && exitShortcutPressed) {
|
||||
const shouldCancelCloseRequest = dialog.showMessageBoxSync(mainWindow, {
|
||||
type: "question",
|
||||
buttons: ["Cancel", "Close Element"],
|
||||
message: "Are you sure you want to quit?",
|
||||
buttons: [_t("Cancel"), _t("Close Element")],
|
||||
message: _t("Are you sure you want to quit?"),
|
||||
defaultId: 1,
|
||||
cancelId: 0,
|
||||
}) === 0;
|
||||
@@ -366,6 +367,9 @@ ipcMain.on('ipcCall', async function(ev, payload) {
|
||||
launcher.disable();
|
||||
}
|
||||
break;
|
||||
case 'setLanguage':
|
||||
appLocalization.setAppLocale(args[0]);
|
||||
break;
|
||||
case 'shouldWarnBeforeExit':
|
||||
ret = store.get('warnBeforeExit', true);
|
||||
break;
|
||||
@@ -495,6 +499,27 @@ ipcMain.on('ipcCall', async function(ev, payload) {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
const seshatDefaultPassphrase = "DEFAULT_PASSPHRASE";
|
||||
async function getOrCreatePassphrase(key) {
|
||||
if (keytar) {
|
||||
try {
|
||||
const storedPassphrase = await keytar.getPassword("element.io", key);
|
||||
if (storedPassphrase !== null) {
|
||||
return storedPassphrase;
|
||||
} else {
|
||||
const newPassphrase = await randomArray(32);
|
||||
await keytar.setPassword("element.io", key, newPassphrase);
|
||||
return newPassphrase;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error getting the event index passphrase out of the secret store", e);
|
||||
}
|
||||
} else {
|
||||
return seshatDefaultPassphrase;
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.on('seshat', async function(ev, payload) {
|
||||
if (!mainWindow) return;
|
||||
|
||||
@@ -523,82 +548,38 @@ ipcMain.on('seshat', async function(ev, payload) {
|
||||
const deviceId = args[1];
|
||||
const passphraseKey = `seshat|${userId}|${deviceId}`;
|
||||
|
||||
let changePassphrase = false;
|
||||
let passphrase = seshatDefaultPassphrase;
|
||||
|
||||
if (keytar) {
|
||||
try {
|
||||
// Try to get a passphrase for seshat.
|
||||
const storedPassphrase = await keytar.getPassword("element.io", passphraseKey);
|
||||
|
||||
// If no passphrase was found mark that we should change
|
||||
// it, if one is found, use that one.
|
||||
if (storedPassphrase === null) {
|
||||
changePassphrase = true;
|
||||
} else {
|
||||
passphrase = storedPassphrase;
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error getting the event index passphrase out of the secret store", e);
|
||||
}
|
||||
}
|
||||
|
||||
const openSeshat = async () => {
|
||||
try {
|
||||
await afs.mkdir(eventStorePath, {recursive: true});
|
||||
return new Seshat(eventStorePath, {passphrase});
|
||||
} catch (e) {
|
||||
if (e instanceof ReindexError) {
|
||||
// If this is a reindex error, the index schema
|
||||
// changed. Try to open the database in recovery mode,
|
||||
// reindex the database and finally try to open the
|
||||
// database again.
|
||||
const recoveryIndex = new SeshatRecovery(eventStorePath, {
|
||||
passphrase,
|
||||
});
|
||||
|
||||
const userVersion = await recoveryIndex.getUserVersion();
|
||||
|
||||
// If our user version is 0 we'll delete the db
|
||||
// anyways so reindexing it is a waste of time.
|
||||
if (userVersion === 0) {
|
||||
await recoveryIndex.shutdown();
|
||||
|
||||
try {
|
||||
await deleteContents(eventStorePath);
|
||||
} catch (e) {
|
||||
}
|
||||
} else {
|
||||
await recoveryIndex.reindex();
|
||||
}
|
||||
|
||||
return new Seshat(eventStorePath, {passphrase});
|
||||
} else {
|
||||
throw (e);
|
||||
}
|
||||
}
|
||||
};
|
||||
const passphrase = await getOrCreatePassphrase(passphraseKey);
|
||||
|
||||
try {
|
||||
eventIndex = await openSeshat();
|
||||
await afs.mkdir(eventStorePath, {recursive: true});
|
||||
eventIndex = new Seshat(eventStorePath, {passphrase});
|
||||
} catch (e) {
|
||||
sendError(payload.id, e);
|
||||
return;
|
||||
}
|
||||
if (e instanceof ReindexError) {
|
||||
// If this is a reindex error, the index schema
|
||||
// changed. Try to open the database in recovery mode,
|
||||
// reindex the database and finally try to open the
|
||||
// database again.
|
||||
const recoveryIndex = new SeshatRecovery(eventStorePath, {
|
||||
passphrase,
|
||||
});
|
||||
|
||||
if (changePassphrase) {
|
||||
try {
|
||||
// Generate a new random passphrase.
|
||||
const newPassphrase = await randomArray(32);
|
||||
await keytar.setPassword("element.io", passphraseKey, newPassphrase);
|
||||
const userVersion = await recoveryIndex.getUserVersion();
|
||||
|
||||
// Set the new passphrase, this will close the event
|
||||
// index.
|
||||
await eventIndex.changePassphrase(newPassphrase);
|
||||
// If our user version is 0 we'll delete the db
|
||||
// anyways so reindexing it is a waste of time.
|
||||
if (userVersion === 0) {
|
||||
await recoveryIndex.shutdown();
|
||||
|
||||
// Re-open the event index with the new passphrase.
|
||||
eventIndex = new Seshat(eventStorePath, {newPassphrase});
|
||||
} catch (e) {
|
||||
try {
|
||||
await deleteContents(eventStorePath);
|
||||
} catch (e) {
|
||||
}
|
||||
} else {
|
||||
await recoveryIndex.reindex();
|
||||
}
|
||||
|
||||
eventIndex = new Seshat(eventStorePath, {passphrase});
|
||||
} else {
|
||||
sendError(payload.id, e);
|
||||
return;
|
||||
}
|
||||
@@ -822,6 +803,9 @@ protocol.registerSchemesAsPrivileged([{
|
||||
// transition into the user's browser.
|
||||
app.enableSandbox();
|
||||
|
||||
// We disable media controls here. We do this because calls use audio and video elements and they sometimes capture the media keys. See https://github.com/vector-im/element-web/issues/15704
|
||||
app.commandLine.appendSwitch('disable-features', 'HardwareMediaKeyHandling,MediaSessionService');
|
||||
|
||||
app.on('ready', async () => {
|
||||
try {
|
||||
await setupGlobals();
|
||||
@@ -940,7 +924,6 @@ app.on('ready', async () => {
|
||||
},
|
||||
});
|
||||
mainWindow.loadURL('vector://vector/webapp/');
|
||||
Menu.setApplicationMenu(vectorMenu);
|
||||
|
||||
// Handle spellchecker
|
||||
// For some reason spellCheckerEnabled isn't persisted so we have to use the store here
|
||||
@@ -972,7 +955,15 @@ app.on('ready', async () => {
|
||||
// (this is generally how single-window Mac apps
|
||||
// behave, eg. Mail.app)
|
||||
e.preventDefault();
|
||||
mainWindow.hide();
|
||||
|
||||
if (mainWindow.isFullScreen()) {
|
||||
mainWindow.once('leave-full-screen', () => mainWindow.hide());
|
||||
|
||||
mainWindow.setFullScreen(false);
|
||||
} else {
|
||||
mainWindow.hide();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
@@ -989,6 +980,14 @@ app.on('ready', async () => {
|
||||
}
|
||||
|
||||
webContentsHandler(mainWindow.webContents);
|
||||
|
||||
appLocalization = new AppLocalization({
|
||||
store,
|
||||
components: [
|
||||
() => tray.initApplicationMenu(),
|
||||
() => Menu.setApplicationMenu(buildMenuTemplate()),
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
|
||||
1
src/i18n/strings/basefile.json
Normal file
1
src/i18n/strings/basefile.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
46
src/i18n/strings/de.json
Normal file
46
src/i18n/strings/de.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Speech": "Sprache",
|
||||
"Paste and Match Style": "Einfügen und Formatierung beibehalten",
|
||||
"Stop Speaking": "Aufnahme beenden",
|
||||
"Start Speaking": "Aufnahme starten",
|
||||
"Services": "Dienste",
|
||||
"Are you sure you want to quit?": "Wirklich beenden?",
|
||||
"Add to dictionary": "Wörterbuch hinzufügen",
|
||||
"The image failed to save": "Das Bild konnte nicht gespeichert werden",
|
||||
"Failed to save image": "Bild kann nicht gespeichert werden",
|
||||
"Save image as...": "Bild speichern unter...",
|
||||
"Copy link address": "Link-Adresse kopieren",
|
||||
"Copy email address": "Email-Adresse kopieren",
|
||||
"Copy image": "Bild kopieren",
|
||||
"File": "Datei",
|
||||
"Bring All to Front": "Alles in den Vordergrund",
|
||||
"Zoom": "Zoom",
|
||||
"Unhide": "Wieder anzeigen",
|
||||
"Hide Others": "Andere verstecken",
|
||||
"Hide": "Verstecken",
|
||||
"About": "Über",
|
||||
"Element Help": "Hilfe zu Element",
|
||||
"Help": "Hilfe",
|
||||
"Close": "Schließen",
|
||||
"Minimize": "Minimieren",
|
||||
"Window": "Fenster",
|
||||
"Toggle Developer Tools": "Developer-Tools an/aus",
|
||||
"Toggle Full Screen": "Vollbildschirm an/aus",
|
||||
"Preferences": "Einstellungen",
|
||||
"Zoom Out": "Verkleinern",
|
||||
"Zoom In": "Vergrößern",
|
||||
"Actual Size": "Tatsächliche Größe",
|
||||
"View": "Ansicht",
|
||||
"Select All": "Alles auswählen",
|
||||
"Delete": "Löschen",
|
||||
"Paste": "Einfügen",
|
||||
"Copy": "Kopieren",
|
||||
"Cut": "Ausschneiden",
|
||||
"Redo": "Wiederherstellen",
|
||||
"Undo": "Rückgängig",
|
||||
"Edit": "Bearbeiten",
|
||||
"Quit": "Beenden",
|
||||
"Show/Hide": "Anzeigen/Ausblenden",
|
||||
"Close Element": "Element schließen",
|
||||
"Cancel": "Abbrechen"
|
||||
}
|
||||
46
src/i18n/strings/en_EN.json
Normal file
46
src/i18n/strings/en_EN.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Cancel": "Cancel",
|
||||
"Close Element": "Close Element",
|
||||
"Are you sure you want to quit?": "Are you sure you want to quit?",
|
||||
"Show/Hide": "Show/Hide",
|
||||
"Quit": "Quit",
|
||||
"Edit": "Edit",
|
||||
"Undo": "Undo",
|
||||
"Redo": "Redo",
|
||||
"Cut": "Cut",
|
||||
"Copy": "Copy",
|
||||
"Paste": "Paste",
|
||||
"Paste and Match Style": "Paste and Match Style",
|
||||
"Delete": "Delete",
|
||||
"Select All": "Select All",
|
||||
"View": "View",
|
||||
"Actual Size": "Actual Size",
|
||||
"Zoom In": "Zoom In",
|
||||
"Zoom Out": "Zoom Out",
|
||||
"Preferences": "Preferences",
|
||||
"Toggle Full Screen": "Toggle Full Screen",
|
||||
"Toggle Developer Tools": "Toggle Developer Tools",
|
||||
"Window": "Window",
|
||||
"Minimize": "Minimize",
|
||||
"Close": "Close",
|
||||
"Help": "Help",
|
||||
"Element Help": "Element Help",
|
||||
"About": "About",
|
||||
"Services": "Services",
|
||||
"Hide": "Hide",
|
||||
"Hide Others": "Hide Others",
|
||||
"Unhide": "Unhide",
|
||||
"Speech": "Speech",
|
||||
"Start Speaking": "Start Speaking",
|
||||
"Stop Speaking": "Stop Speaking",
|
||||
"Zoom": "Zoom",
|
||||
"Bring All to Front": "Bring All to Front",
|
||||
"File": "File",
|
||||
"Copy image": "Copy image",
|
||||
"Copy email address": "Copy email address",
|
||||
"Copy link address": "Copy link address",
|
||||
"Save image as...": "Save image as...",
|
||||
"Failed to save image": "Failed to save image",
|
||||
"The image failed to save": "The image failed to save",
|
||||
"Add to dictionary": "Add to dictionary"
|
||||
}
|
||||
46
src/i18n/strings/es.json
Normal file
46
src/i18n/strings/es.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Add to dictionary": "Añadir al diccionario",
|
||||
"The image failed to save": "La imagen no se ha podido guardar",
|
||||
"Failed to save image": "No se ha podido guardar la imagen",
|
||||
"Save image as...": "Guardar imagen como...",
|
||||
"Copy link address": "Copiar dirección de enlace",
|
||||
"Copy email address": "Copiar dirección de correo",
|
||||
"Copy image": "Copiar imagen",
|
||||
"File": "Archivo",
|
||||
"Bring All to Front": "Traer todas al primer plano",
|
||||
"Zoom": "Zoom",
|
||||
"Start Speaking": "Empezar a hablar",
|
||||
"Stop Speaking": "Parar de hablar",
|
||||
"Speech": "Dictado",
|
||||
"Unhide": "Mostrar",
|
||||
"Hide Others": "Ocultar otros",
|
||||
"Hide": "Ocultar",
|
||||
"Services": "Servicios",
|
||||
"About": "Acerca de",
|
||||
"Element Help": "Ayuda de Element",
|
||||
"Help": "Ayuda",
|
||||
"Close": "Cerrar",
|
||||
"Minimize": "Minimizar",
|
||||
"Window": "Ventana",
|
||||
"Toggle Developer Tools": "Abrir/cerrar herramientas de desarrollo",
|
||||
"Toggle Full Screen": "Entrar/salir de pantalla completa",
|
||||
"Preferences": "Preferencias",
|
||||
"Zoom Out": "Alejar",
|
||||
"Zoom In": "Acercar",
|
||||
"Actual Size": "Tamaño real",
|
||||
"View": "Ver",
|
||||
"Select All": "Seleccionar todo",
|
||||
"Delete": "Eliminar",
|
||||
"Paste and Match Style": "Pegar manteniendo estilo",
|
||||
"Paste": "Pegar",
|
||||
"Copy": "Copiar",
|
||||
"Cut": "Cortar",
|
||||
"Redo": "Rehacer",
|
||||
"Undo": "Deshacer",
|
||||
"Edit": "Editar",
|
||||
"Quit": "Salir",
|
||||
"Show/Hide": "Ver/Ocultar",
|
||||
"Are you sure you want to quit?": "¿Quieres salir?",
|
||||
"Close Element": "Cerrar Element",
|
||||
"Cancel": "Cancelar"
|
||||
}
|
||||
46
src/i18n/strings/et.json
Normal file
46
src/i18n/strings/et.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Element Help": "Rakenduse Element abiteave",
|
||||
"About": "Rakenduse teave",
|
||||
"The image failed to save": "Seda pilti ei õnnestunud salvestada",
|
||||
"Add to dictionary": "Lisa sõnastikku",
|
||||
"Failed to save image": "Pildi salvestamine ei õnnestunud",
|
||||
"Save image as...": "Salvesta pilt kui...",
|
||||
"Copy link address": "Kopeeri lingi aadress",
|
||||
"Copy email address": "Kopeeri e-posti aadress",
|
||||
"Copy image": "Kopeeri pilt",
|
||||
"File": "Fail",
|
||||
"Bring All to Front": "Too kõik esiplaanile",
|
||||
"Zoom": "Suumi",
|
||||
"Stop Speaking": "Lõpeta rääkimine",
|
||||
"Start Speaking": "Alusta rääkimist",
|
||||
"Speech": "Kõne",
|
||||
"Unhide": "Näita uuesti",
|
||||
"Hide Others": "Peida muud",
|
||||
"Hide": "Peida",
|
||||
"Services": "Teenused",
|
||||
"Help": "Abiteave",
|
||||
"Close": "Sulge",
|
||||
"Minimize": "Vähenda",
|
||||
"Window": "Aken",
|
||||
"Toggle Developer Tools": "Arendaja töövahendid sisse/välja",
|
||||
"Toggle Full Screen": "Täisekraanivaade sisse/välja",
|
||||
"Preferences": "Seadistused",
|
||||
"Zoom Out": "Vähenda",
|
||||
"Zoom In": "Suurenda",
|
||||
"Actual Size": "Näita tavasuuruses",
|
||||
"View": "Vaata",
|
||||
"Select All": "Vali kõik",
|
||||
"Delete": "Kustuta",
|
||||
"Paste and Match Style": "Aseta kasutades sama stiili",
|
||||
"Paste": "Aseta",
|
||||
"Copy": "Kopeeri",
|
||||
"Cut": "Lõika",
|
||||
"Redo": "Tee uuesti",
|
||||
"Undo": "Võta tagasi",
|
||||
"Edit": "Muuda",
|
||||
"Quit": "Välju",
|
||||
"Show/Hide": "Näita/peida",
|
||||
"Are you sure you want to quit?": "Kas sa kindlasti soovid rakendusest väljuda?",
|
||||
"Close Element": "Sulge Element",
|
||||
"Cancel": "Tühista"
|
||||
}
|
||||
46
src/i18n/strings/fi.json
Normal file
46
src/i18n/strings/fi.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Paste": "Liitä",
|
||||
"Paste and Match Style": "Liitä ja sovita tyyli",
|
||||
"Add to dictionary": "Lisää sanakirjaan",
|
||||
"The image failed to save": "Kuvan tallennus epäonnistui",
|
||||
"Failed to save image": "Kuvan tallennus epäonnistui",
|
||||
"Save image as...": "Tallenna kuva nimellä...",
|
||||
"Copy link address": "Kopioi linkin osoite",
|
||||
"Copy email address": "Kopioi sähköpostiosoite",
|
||||
"Copy image": "Kopioi kuva",
|
||||
"File": "Tiedosto",
|
||||
"Bring All to Front": "Tuo kaikki eteen",
|
||||
"Zoom": "Suurennus",
|
||||
"Stop Speaking": "Lopeta puhe",
|
||||
"Start Speaking": "Aloita puhe",
|
||||
"Speech": "Puhe",
|
||||
"Unhide": "Palauta näkyviin",
|
||||
"Hide Others": "Piilota muut",
|
||||
"Hide": "Piilota",
|
||||
"Services": "Palvelut",
|
||||
"About": "Tietoja",
|
||||
"Element Help": "Elementin ohjeet",
|
||||
"Help": "Apua",
|
||||
"Close": "Sulje",
|
||||
"Minimize": "Pienennä",
|
||||
"Window": "Ikkuna",
|
||||
"Toggle Developer Tools": "Näytä tai piilota kehittäjätyökalut",
|
||||
"Toggle Full Screen": "Vaihda koko näyttö-tilaa",
|
||||
"Preferences": "Asetukset",
|
||||
"Zoom Out": "Pienennä",
|
||||
"Zoom In": "Suurenna",
|
||||
"Actual Size": "Alkuperäinen koko",
|
||||
"View": "Näytä",
|
||||
"Select All": "Valitse kaikki",
|
||||
"Delete": "Poista",
|
||||
"Copy": "Kopioi",
|
||||
"Cut": "Leikkaa",
|
||||
"Redo": "Tee uudestaan",
|
||||
"Undo": "Peru",
|
||||
"Edit": "Muokkaa",
|
||||
"Quit": "Lopeta",
|
||||
"Show/Hide": "Näytä/Piilota",
|
||||
"Are you sure you want to quit?": "Oletko varma että haluat poistua?",
|
||||
"Close Element": "Sulje Element",
|
||||
"Cancel": "Peruuta"
|
||||
}
|
||||
45
src/i18n/strings/fr.json
Normal file
45
src/i18n/strings/fr.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"Undo": "Annuler",
|
||||
"Edit": "Modifier",
|
||||
"Quit": "Quitter",
|
||||
"Show/Hide": "Afficher/Masquer",
|
||||
"Are you sure you want to quit?": "Êtes-vous sûr de vouloir quitter ?",
|
||||
"Close Element": "Fermer Element",
|
||||
"Cancel": "Annuler",
|
||||
"Unhide": "Dé-masquer",
|
||||
"Hide Others": "Masquer les autres",
|
||||
"Hide": "Masquer",
|
||||
"Services": "Services",
|
||||
"About": "À propos",
|
||||
"Element Help": "Aide d’Element",
|
||||
"Help": "Aide",
|
||||
"Close": "Fermer",
|
||||
"Minimize": "Minimiser",
|
||||
"Window": "Fenêtre",
|
||||
"Toggle Developer Tools": "Basculer les outils de développement",
|
||||
"Toggle Full Screen": "Basculer le plein écran",
|
||||
"Preferences": "Préférences",
|
||||
"Zoom Out": "Dé-zoomer",
|
||||
"Zoom In": "Zoomer",
|
||||
"Actual Size": "Taille réelle",
|
||||
"View": "Afficher",
|
||||
"Select All": "Tout sélectionner",
|
||||
"Delete": "Supprimer",
|
||||
"Paste and Match Style": "Copier avec le style de destination",
|
||||
"Paste": "Coller",
|
||||
"Copy": "Copier",
|
||||
"Cut": "Couper",
|
||||
"Speech": "Dictée",
|
||||
"Add to dictionary": "Ajouter au dictionnaire",
|
||||
"The image failed to save": "L’image n’a pas pu être sauvegardée",
|
||||
"Failed to save image": "Échec de la sauvegarde de l’image",
|
||||
"Save image as...": "Enregistrer l’image sous…",
|
||||
"Copy link address": "Copier l’adresse du lien",
|
||||
"Copy email address": "Copier l’adresse e-mail",
|
||||
"Copy image": "Copier l’image",
|
||||
"File": "Fichier",
|
||||
"Bring All to Front": "Tout amener au premier plan",
|
||||
"Zoom": "Zoom",
|
||||
"Stop Speaking": "Arrêter la dictée",
|
||||
"Start Speaking": "Commencer la dictée"
|
||||
}
|
||||
46
src/i18n/strings/gl.json
Normal file
46
src/i18n/strings/gl.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Add to dictionary": "Engadir ao dicionario",
|
||||
"The image failed to save": "Non se gardou a imaxe",
|
||||
"Failed to save image": "Fallou o gardado da imaxe",
|
||||
"Save image as...": "Gardar imaxe como...",
|
||||
"Copy link address": "Copiar enderezo da ligazón",
|
||||
"Copy email address": "Copiar enderezo de email",
|
||||
"Copy image": "Copiar imaxe",
|
||||
"File": "Ficheiro",
|
||||
"Bring All to Front": "Traer todo á fronte",
|
||||
"Zoom": "Aumento",
|
||||
"Stop Speaking": "Deixa de falar",
|
||||
"Start Speaking": "Comeza a falar",
|
||||
"Speech": "Falar",
|
||||
"Unhide": "Desagochar",
|
||||
"Hide Others": "Agochar outras",
|
||||
"Hide": "Agochar",
|
||||
"Services": "Servizos",
|
||||
"About": "Acerca de",
|
||||
"Element Help": "Axuda de Element",
|
||||
"Help": "Axuda",
|
||||
"Close": "Pechar",
|
||||
"Minimize": "Minimizar",
|
||||
"Window": "Ventá",
|
||||
"Toggle Developer Tools": "Activar ferramentas de desenvolvemento",
|
||||
"Toggle Full Screen": "Activar pantalla completa",
|
||||
"Preferences": "Preferencias",
|
||||
"Zoom Out": "Diminuir",
|
||||
"Zoom In": "Aumentar",
|
||||
"Actual Size": "Tamaño real",
|
||||
"View": "Ver",
|
||||
"Select All": "Elexir todo",
|
||||
"Delete": "Eliminar",
|
||||
"Paste and Match Style": "Pegar e imitar estilo",
|
||||
"Paste": "Pegar",
|
||||
"Copy": "Copiar",
|
||||
"Cut": "Cortar",
|
||||
"Redo": "Refacer",
|
||||
"Undo": "Desfacer",
|
||||
"Edit": "Editar",
|
||||
"Quit": "Saír",
|
||||
"Show/Hide": "Mostrar/Agochar",
|
||||
"Are you sure you want to quit?": "Tes a certeza de que queres saír?",
|
||||
"Close Element": "Pechar Element",
|
||||
"Cancel": "Cancelar"
|
||||
}
|
||||
46
src/i18n/strings/hu.json
Normal file
46
src/i18n/strings/hu.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Add to dictionary": "Hozzáadás a szótárhoz",
|
||||
"The image failed to save": "A kép mentése sikertelen",
|
||||
"Failed to save image": "Kép mentése sikertelen",
|
||||
"Save image as...": "Kép mentése másként...",
|
||||
"Copy link address": "Hivatkozás másolása",
|
||||
"Copy email address": "E-mail cím másolása",
|
||||
"Copy image": "Kép másolása",
|
||||
"File": "Fájl",
|
||||
"Bring All to Front": "Mindent előtérbe hoz",
|
||||
"Zoom": "Nagyítás",
|
||||
"Stop Speaking": "Fejezze be a beszédet",
|
||||
"Start Speaking": "Kezdjen beszélni",
|
||||
"Speech": "Beszéd",
|
||||
"Unhide": "Felfed",
|
||||
"Hide Others": "Minden mást eltakar",
|
||||
"Hide": "Eltakar",
|
||||
"Services": "Szolgáltatás",
|
||||
"About": "Névjegy",
|
||||
"Element Help": "Element segítség",
|
||||
"Help": "Segítség",
|
||||
"Close": "Bezár",
|
||||
"Minimize": "Lecsukás",
|
||||
"Window": "Ablak",
|
||||
"Toggle Developer Tools": "Fejlesztői eszközök",
|
||||
"Toggle Full Screen": "Teljes képernyő",
|
||||
"Preferences": "Beállítások",
|
||||
"Zoom Out": "Kicsinyít",
|
||||
"Zoom In": "Nagyít",
|
||||
"Actual Size": "Jelenlegi méret",
|
||||
"View": "Nézet",
|
||||
"Select All": "Mind kijelölése",
|
||||
"Delete": "Töröl",
|
||||
"Paste and Match Style": "Beillesztés formázással",
|
||||
"Paste": "Beillesztés",
|
||||
"Copy": "Másol",
|
||||
"Cut": "Kivág",
|
||||
"Redo": "Újra",
|
||||
"Undo": "Visszavon",
|
||||
"Edit": "Szerkeszt",
|
||||
"Quit": "Kilép",
|
||||
"Show/Hide": "Megmutat/Elrejt",
|
||||
"Are you sure you want to quit?": "Biztos, hogy kilép?",
|
||||
"Close Element": "Element bezárása",
|
||||
"Cancel": "Mégsem"
|
||||
}
|
||||
44
src/i18n/strings/it.json
Normal file
44
src/i18n/strings/it.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"Add to dictionary": "Aggiungi al dizionario",
|
||||
"The image failed to save": "Non è stato possibile salvare l'immagine",
|
||||
"Failed to save image": "Salvataggio immagine fallito",
|
||||
"Save image as...": "Salva immagine come...",
|
||||
"Copy link address": "Copia indirizzo collegamento",
|
||||
"Copy email address": "Copia indirizzo email",
|
||||
"Copy image": "Copia immagine",
|
||||
"File": "File",
|
||||
"Bring All to Front": "Porta tutto in primo piano",
|
||||
"Zoom": "Zoom",
|
||||
"Start Speaking": "Inizia a parlare",
|
||||
"Unhide": "Mostra",
|
||||
"Hide Others": "Nascondi gli altri",
|
||||
"Hide": "Nascondi",
|
||||
"Services": "Servizi",
|
||||
"About": "Al riguardo",
|
||||
"Element Help": "Aiuto di Element",
|
||||
"Help": "Aiuto",
|
||||
"Close": "Chiudi",
|
||||
"Minimize": "Riduci",
|
||||
"Window": "Finestra",
|
||||
"Toggle Developer Tools": "Attiva strumenti per sviluppatori",
|
||||
"Toggle Full Screen": "Passa a schermo intero",
|
||||
"Preferences": "Preferenze",
|
||||
"Zoom Out": "Rimpicciolisci",
|
||||
"Zoom In": "Ingrandisci",
|
||||
"Actual Size": "Dimensione effettiva",
|
||||
"View": "Vedi",
|
||||
"Select All": "Seleziona tutto",
|
||||
"Delete": "Elimina",
|
||||
"Paste and Match Style": "Incolla e abbina lo stile",
|
||||
"Paste": "Incolla",
|
||||
"Copy": "Copia",
|
||||
"Cut": "Taglia",
|
||||
"Redo": "Ripeti",
|
||||
"Undo": "Annulla",
|
||||
"Edit": "Modifica",
|
||||
"Quit": "Esci",
|
||||
"Show/Hide": "Mostra/Nascondi",
|
||||
"Are you sure you want to quit?": "Vuoi veramente uscire?",
|
||||
"Close Element": "Chiudi Element",
|
||||
"Cancel": "Annulla"
|
||||
}
|
||||
3
src/i18n/strings/nb_NO.json
Normal file
3
src/i18n/strings/nb_NO.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"Toggle Developer Tools": "Veksle Utvikleralternativer"
|
||||
}
|
||||
46
src/i18n/strings/ru.json
Normal file
46
src/i18n/strings/ru.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"Edit": "Изменить",
|
||||
"Quit": "Выйти",
|
||||
"Close Element": "Закрыть Element",
|
||||
"Cancel": "Отмена",
|
||||
"Show/Hide": "Показать/скрыть",
|
||||
"Are you sure you want to quit?": "Вы уверены, что хотите выйти?",
|
||||
"Copy email address": "Копировать адрес почты",
|
||||
"Copy image": "Копировать изображение",
|
||||
"File": "Файл",
|
||||
"Zoom": "Масштаб",
|
||||
"Unhide": "Показать",
|
||||
"Hide": "Скрыть",
|
||||
"Services": "Сервисы",
|
||||
"About": "О программе",
|
||||
"Element Help": "Справка Element",
|
||||
"Help": "Справка",
|
||||
"Close": "Закрыть",
|
||||
"Minimize": "Свернуть",
|
||||
"Window": "Окно",
|
||||
"Toggle Developer Tools": "Переключить инструменты разработчика",
|
||||
"Toggle Full Screen": "Переключить полноэкранный режим",
|
||||
"Preferences": "Параметры",
|
||||
"Zoom Out": "Уменьшить",
|
||||
"Zoom In": "Увеличить",
|
||||
"Actual Size": "Фактический размер",
|
||||
"View": "Просмотр",
|
||||
"Select All": "Выбрать все",
|
||||
"Delete": "Удалить",
|
||||
"Paste": "Вставить",
|
||||
"Copy": "Копировать",
|
||||
"Cut": "Вырезать",
|
||||
"Redo": "Повторить",
|
||||
"Undo": "Отменить",
|
||||
"Save image as...": "Сохранить изображение как...",
|
||||
"Copy link address": "Копировать ссылку",
|
||||
"Add to dictionary": "Добавить в словарь",
|
||||
"The image failed to save": "Не удалось сохранить изображение",
|
||||
"Failed to save image": "Не удалось сохранить изображение",
|
||||
"Bring All to Front": "Вынести всё вперёд",
|
||||
"Stop Speaking": "Перестаньте говорить",
|
||||
"Start Speaking": "Говорите",
|
||||
"Speech": "Голос",
|
||||
"Hide Others": "Скрыть прочие",
|
||||
"Paste and Match Style": "Вставить с тем же стилем"
|
||||
}
|
||||
41
src/i18n/strings/sv.json
Normal file
41
src/i18n/strings/sv.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"Save image as...": "Spara bild som...",
|
||||
"Copy link address": "Kopiera länkadress",
|
||||
"Copy email address": "Kopiera e-postadress",
|
||||
"Copy image": "Kopiera bild",
|
||||
"File": "Arkiv",
|
||||
"Bring All to Front": "Lägg alla överst",
|
||||
"Stop Speaking": "Sluta tala",
|
||||
"Start Speaking": "Börja tala",
|
||||
"Speech": "Tal",
|
||||
"Hide Others": "Göm övriga",
|
||||
"Hide": "Göm",
|
||||
"Services": "Tjänster",
|
||||
"About": "Om",
|
||||
"Element Help": "Element Hjälp",
|
||||
"Help": "Hjälp",
|
||||
"Close": "Stäng",
|
||||
"Minimize": "Minimera",
|
||||
"Window": "Fönster",
|
||||
"Preferences": "Inställningar",
|
||||
"Actual Size": "Verklig storlek",
|
||||
"View": "Visa",
|
||||
"Select All": "Markera allt",
|
||||
"Delete": "Radera",
|
||||
"Paste and Match Style": "Klistra in och matcha stilen",
|
||||
"Paste": "Klistra in",
|
||||
"Copy": "Kopiera",
|
||||
"Cut": "Klipp ut",
|
||||
"Redo": "Gör om",
|
||||
"Undo": "Ångra",
|
||||
"Edit": "Redigera",
|
||||
"Quit": "Avsluta",
|
||||
"Cancel": "Avbryt",
|
||||
"Zoom": "Zooma",
|
||||
"Toggle Developer Tools": "Växla utvecklarverktyg",
|
||||
"Toggle Full Screen": "Växla helskärm",
|
||||
"Unhide": "Göm inte",
|
||||
"Zoom Out": "Zooma ut",
|
||||
"Zoom In": "Zooma in",
|
||||
"Close Element": "Stäng Element"
|
||||
}
|
||||
129
src/language-helper.js
Normal file
129
src/language-helper.js
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright 2021 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
const counterpart = require('counterpart');
|
||||
|
||||
const DEFAULT_LOCALE = "en";
|
||||
|
||||
function _td(text) {
|
||||
return text;
|
||||
}
|
||||
|
||||
function _t(text, variables = {}) {
|
||||
const args = Object.assign({ interpolate: false }, variables);
|
||||
|
||||
const { count } = args;
|
||||
|
||||
// Horrible hack to avoid https://github.com/vector-im/element-web/issues/4191
|
||||
// The interpolation library that counterpart uses does not support undefined/null
|
||||
// values and instead will throw an error. This is a problem since everywhere else
|
||||
// in JS land passing undefined/null will simply stringify instead, and when converting
|
||||
// valid ES6 template strings to i18n strings it's extremely easy to pass undefined/null
|
||||
// if there are no existing null guards. To avoid this making the app completely inoperable,
|
||||
// we'll check all the values for undefined/null and stringify them here.
|
||||
Object.keys(args).forEach((key) => {
|
||||
if (args[key] === undefined) {
|
||||
console.warn("safeCounterpartTranslate called with undefined interpolation name: " + key);
|
||||
args[key] = 'undefined';
|
||||
}
|
||||
if (args[key] === null) {
|
||||
console.warn("safeCounterpartTranslate called with null interpolation name: " + key);
|
||||
args[key] = 'null';
|
||||
}
|
||||
});
|
||||
let translated = counterpart.translate(text, args);
|
||||
if (translated === undefined && count !== undefined) {
|
||||
// counterpart does not do fallback if no pluralisation exists
|
||||
// in the preferred language, so do it here
|
||||
translated = counterpart.translate(text, Object.assign({}, args, {locale: DEFAULT_LOCALE}));
|
||||
}
|
||||
|
||||
// The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution)
|
||||
return translated;
|
||||
}
|
||||
|
||||
class AppLocalization {
|
||||
static STORE_KEY = "locale"
|
||||
store = null
|
||||
|
||||
constructor({ store, components = [] }) {
|
||||
counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN"));
|
||||
counterpart.setFallbackLocale('en');
|
||||
counterpart.setSeparator('|');
|
||||
|
||||
if (Array.isArray(components)) {
|
||||
this.localizedComponents = new Set(components);
|
||||
}
|
||||
|
||||
this.store = store;
|
||||
if (this.store.has(AppLocalization.STORE_KEY)) {
|
||||
const locales = this.store.get(AppLocalization.STORE_KEY);
|
||||
this.setAppLocale(locales);
|
||||
}
|
||||
|
||||
this.resetLocalizedUI();
|
||||
}
|
||||
|
||||
fetchTranslationJson(locale) {
|
||||
try {
|
||||
console.log("Fetching translation json for locale: " + locale);
|
||||
return require(`./i18n/strings/${locale}.json`);
|
||||
} catch (e) {
|
||||
console.log(`Could not fetch translation json for locale: '${locale}'`, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
get languageTranslationJson() {
|
||||
return this.translationJsonMap.get(this.language);
|
||||
}
|
||||
|
||||
setAppLocale(locales) {
|
||||
console.log(`Changing application language to ${locales}`);
|
||||
|
||||
if (!Array.isArray(locales)) {
|
||||
locales = [locales];
|
||||
}
|
||||
|
||||
locales.forEach(locale => {
|
||||
const translations = this.fetchTranslationJson(locale);
|
||||
if (translations !== null) {
|
||||
counterpart.registerTranslations(locale, translations);
|
||||
}
|
||||
});
|
||||
|
||||
counterpart.setLocale(locales);
|
||||
this.store.set(AppLocalization.STORE_KEY, locales);
|
||||
|
||||
this.resetLocalizedUI();
|
||||
}
|
||||
|
||||
resetLocalizedUI() {
|
||||
console.log("Resetting the UI components after locale change");
|
||||
this.localizedComponents.forEach(componentSetup => {
|
||||
if (typeof componentSetup === "function") {
|
||||
componentSetup();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports = {
|
||||
AppLocalization,
|
||||
_t,
|
||||
_td,
|
||||
};
|
||||
62
src/tray.js
62
src/tray.js
@@ -19,6 +19,7 @@ const {app, Tray, Menu, nativeImage} = require('electron');
|
||||
const pngToIco = require('png-to-ico');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const { _t } = require('./language-helper');
|
||||
|
||||
let trayIcon = null;
|
||||
|
||||
@@ -33,39 +34,24 @@ exports.destroy = function() {
|
||||
}
|
||||
};
|
||||
|
||||
const toggleWin = function() {
|
||||
if (global.mainWindow.isVisible() && !global.mainWindow.isMinimized()) {
|
||||
global.mainWindow.hide();
|
||||
} else {
|
||||
if (global.mainWindow.isMinimized()) global.mainWindow.restore();
|
||||
if (!global.mainWindow.isVisible()) global.mainWindow.show();
|
||||
global.mainWindow.focus();
|
||||
}
|
||||
};
|
||||
|
||||
exports.create = function(config) {
|
||||
// no trays on darwin
|
||||
if (process.platform === 'darwin' || trayIcon) return;
|
||||
|
||||
const toggleWin = function() {
|
||||
if (global.mainWindow.isVisible() && !global.mainWindow.isMinimized()) {
|
||||
global.mainWindow.hide();
|
||||
} else {
|
||||
if (global.mainWindow.isMinimized()) global.mainWindow.restore();
|
||||
if (!global.mainWindow.isVisible()) global.mainWindow.show();
|
||||
global.mainWindow.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: `Show/Hide ${config.brand}`,
|
||||
click: toggleWin,
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Quit',
|
||||
click: function() {
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const defaultIcon = nativeImage.createFromPath(config.icon_path);
|
||||
|
||||
trayIcon = new Tray(defaultIcon);
|
||||
trayIcon.setToolTip(config.brand);
|
||||
trayIcon.setContextMenu(contextMenu);
|
||||
initApplicationMenu();
|
||||
trayIcon.on('click', toggleWin);
|
||||
|
||||
let lastFavicon = null;
|
||||
@@ -104,3 +90,27 @@ exports.create = function(config) {
|
||||
trayIcon.setToolTip(title);
|
||||
});
|
||||
};
|
||||
|
||||
function initApplicationMenu() {
|
||||
if (!trayIcon) {
|
||||
return;
|
||||
}
|
||||
|
||||
const contextMenu = Menu.buildFromTemplate([
|
||||
{
|
||||
label: _t('Show/Hide'),
|
||||
click: toggleWin,
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: _t('Quit'),
|
||||
click: function() {
|
||||
app.quit();
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
trayIcon.setContextMenu(contextMenu);
|
||||
}
|
||||
|
||||
exports.initApplicationMenu = initApplicationMenu;
|
||||
|
||||
@@ -15,129 +15,212 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
const {app, shell, Menu} = require('electron');
|
||||
const { _t } = require('./language-helper');
|
||||
|
||||
// Menu template from http://electron.atom.io/docs/api/menu/, edited
|
||||
const template = [
|
||||
{
|
||||
label: '&Edit',
|
||||
submenu: [
|
||||
{ role: 'undo' },
|
||||
{ role: 'redo' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'cut' },
|
||||
{ role: 'copy' },
|
||||
{ role: 'paste' },
|
||||
{ role: 'pasteandmatchstyle' },
|
||||
{ role: 'delete' },
|
||||
{ role: 'selectall' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '&View',
|
||||
submenu: [
|
||||
{ type: 'separator' },
|
||||
{ role: 'resetzoom' },
|
||||
{ role: 'zoomin', accelerator: 'CommandOrControl+=' },
|
||||
{ role: 'zoomout' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: 'Preferences',
|
||||
accelerator: 'Command+,', // Mac-only accelerator
|
||||
click() { global.mainWindow.webContents.send('preferences'); },
|
||||
},
|
||||
{ role: 'togglefullscreen' },
|
||||
{ role: 'toggledevtools' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '&Window',
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{ role: 'minimize' },
|
||||
{ role: 'close' },
|
||||
],
|
||||
},
|
||||
{
|
||||
label: '&Help',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: 'Element Help',
|
||||
click() { shell.openExternal('https://element.io/help'); },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
// macOS has specific menu conventions...
|
||||
if (process.platform === 'darwin') {
|
||||
template.unshift({
|
||||
// first macOS menu is the name of the app
|
||||
label: app.name,
|
||||
submenu: [
|
||||
{ role: 'about' },
|
||||
{ type: 'separator' },
|
||||
{
|
||||
role: 'services',
|
||||
submenu: [],
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{ role: 'hide' },
|
||||
{ role: 'hideothers' },
|
||||
{ role: 'unhide' },
|
||||
{ type: 'separator' },
|
||||
{ role: 'quit' },
|
||||
],
|
||||
});
|
||||
// Edit menu.
|
||||
// This has a 'speech' section on macOS
|
||||
template[1].submenu.push(
|
||||
{ type: 'separator' },
|
||||
function buildMenuTemplate() {
|
||||
// Menu template from http://electron.atom.io/docs/api/menu/, edited
|
||||
const template = [
|
||||
{
|
||||
label: 'Speech',
|
||||
label: _t('Edit'),
|
||||
accelerator: 'e',
|
||||
submenu: [
|
||||
{ role: 'startspeaking' },
|
||||
{ role: 'stopspeaking' },
|
||||
{
|
||||
role: 'undo',
|
||||
label: _t('Undo'),
|
||||
},
|
||||
{
|
||||
role: 'redo',
|
||||
label: _t('Redo'),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
role: 'cut',
|
||||
label: _t('Cut'),
|
||||
},
|
||||
{
|
||||
role: 'copy',
|
||||
label: _t('Copy'),
|
||||
},
|
||||
{
|
||||
role: 'paste',
|
||||
label: _t('Paste'),
|
||||
},
|
||||
{
|
||||
role: 'pasteandmatchstyle',
|
||||
label: _t('Paste and Match Style'),
|
||||
},
|
||||
{
|
||||
role: 'delete',
|
||||
label: _t('Delete'),
|
||||
},
|
||||
{
|
||||
role: 'selectall',
|
||||
label: _t('Select All'),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Window menu.
|
||||
// This also has specific functionality on macOS
|
||||
template[3].submenu = [
|
||||
{
|
||||
label: 'Close',
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
role: 'close',
|
||||
},
|
||||
{
|
||||
label: 'Minimize',
|
||||
accelerator: 'CmdOrCtrl+M',
|
||||
role: 'minimize',
|
||||
label: _t('View'),
|
||||
accelerator: 'V',
|
||||
submenu: [
|
||||
{ type: 'separator' },
|
||||
{
|
||||
role: 'resetzoom',
|
||||
label: _t('Actual Size'),
|
||||
},
|
||||
{
|
||||
role: 'zoomin',
|
||||
accelerator: 'CommandOrControl+=',
|
||||
label: _t('Zoom In'),
|
||||
},
|
||||
{
|
||||
role: 'zoomout',
|
||||
label: _t('Zoom Out'),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: _t('Preferences'),
|
||||
accelerator: 'Command+,', // Mac-only accelerator
|
||||
click() { global.mainWindow.webContents.send('preferences'); },
|
||||
},
|
||||
{
|
||||
role: 'togglefullscreen',
|
||||
label: _t('Toggle Full Screen'),
|
||||
},
|
||||
{
|
||||
role: 'toggledevtools',
|
||||
label: _t('Toggle Developer Tools'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Zoom',
|
||||
role: 'zoom',
|
||||
label: _t('Window'),
|
||||
accelerator: 'w',
|
||||
role: 'window',
|
||||
submenu: [
|
||||
{
|
||||
role: 'minimize',
|
||||
label: _t('Minimize'),
|
||||
},
|
||||
{
|
||||
role: 'close',
|
||||
label: _t('Close'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
label: 'Bring All to Front',
|
||||
role: 'front',
|
||||
label: _t('Help'),
|
||||
accelerator: 'h',
|
||||
role: 'help',
|
||||
submenu: [
|
||||
{
|
||||
label: _t('Element Help'),
|
||||
click() { shell.openExternal('https://element.io/help'); },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
} else {
|
||||
template.unshift({
|
||||
label: '&File',
|
||||
submenu: [
|
||||
// For some reason, 'about' does not seem to work on windows.
|
||||
/*{
|
||||
role: 'about'
|
||||
},*/
|
||||
{ role: 'quit' },
|
||||
],
|
||||
});
|
||||
|
||||
// macOS has specific menu conventions...
|
||||
if (process.platform === 'darwin') {
|
||||
template.unshift({
|
||||
// first macOS menu is the name of the app
|
||||
role: 'appMenu',
|
||||
label: app.name,
|
||||
submenu: [
|
||||
{
|
||||
role: 'about',
|
||||
label: _t('About'),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
role: 'services',
|
||||
label: _t('Services'),
|
||||
submenu: [],
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
role: 'hide',
|
||||
label: _t('Hide'),
|
||||
},
|
||||
{
|
||||
role: 'hideothers',
|
||||
label: _t('Hide Others'),
|
||||
},
|
||||
{
|
||||
role: 'unhide',
|
||||
label: _t('Unhide'),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
role: 'quit',
|
||||
label: _t('Quit'),
|
||||
},
|
||||
],
|
||||
});
|
||||
// Edit menu.
|
||||
// This has a 'speech' section on macOS
|
||||
template[1].submenu.push(
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: _t('Speech'),
|
||||
submenu: [
|
||||
{
|
||||
role: 'startspeaking',
|
||||
label: _t('Start Speaking'),
|
||||
},
|
||||
{
|
||||
role: 'stopspeaking',
|
||||
label: _t('Stop Speaking'),
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
// Window menu.
|
||||
// This also has specific functionality on macOS
|
||||
template[3].submenu = [
|
||||
{
|
||||
label: _t('Close'),
|
||||
accelerator: 'CmdOrCtrl+W',
|
||||
role: 'close',
|
||||
},
|
||||
{
|
||||
label: _t('Minimize'),
|
||||
accelerator: 'CmdOrCtrl+M',
|
||||
role: 'minimize',
|
||||
},
|
||||
{
|
||||
label: _t('Zoom'),
|
||||
role: 'zoom',
|
||||
},
|
||||
{
|
||||
type: 'separator',
|
||||
},
|
||||
{
|
||||
label: _t('Bring All to Front'),
|
||||
role: 'front',
|
||||
},
|
||||
];
|
||||
} else {
|
||||
template.unshift({
|
||||
label: _t('File'),
|
||||
accelerator: 'f',
|
||||
submenu: [
|
||||
// For some reason, 'about' does not seem to work on windows.
|
||||
/*{
|
||||
role: 'about',
|
||||
label: _t('About'),
|
||||
},*/
|
||||
{
|
||||
role: 'quit',
|
||||
label: _t('Quit'),
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return Menu.buildFromTemplate(template);
|
||||
}
|
||||
|
||||
module.exports = Menu.buildFromTemplate(template);
|
||||
module.exports = buildMenuTemplate;
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ const url = require('url');
|
||||
const fs = require('fs');
|
||||
const request = require('request');
|
||||
const path = require('path');
|
||||
const { _t } = require('./language-helper');
|
||||
|
||||
const MAILTO_PREFIX = "mailto:";
|
||||
|
||||
@@ -73,7 +74,8 @@ function onLinkContextMenu(ev, params) {
|
||||
|
||||
if (params.hasImageContents) {
|
||||
popupMenu.append(new MenuItem({
|
||||
label: '&Copy image',
|
||||
label: _t('Copy image'),
|
||||
accelerator: 'c',
|
||||
click() {
|
||||
ev.sender.copyImageAt(params.x, params.y);
|
||||
},
|
||||
@@ -85,14 +87,16 @@ function onLinkContextMenu(ev, params) {
|
||||
// Special-case e-mail URLs to strip the `mailto:` like modern browsers do
|
||||
if (url.startsWith(MAILTO_PREFIX)) {
|
||||
popupMenu.append(new MenuItem({
|
||||
label: 'Copy email &address',
|
||||
label: _t('Copy email address'),
|
||||
accelerator: 'a',
|
||||
click() {
|
||||
clipboard.writeText(url.substr(MAILTO_PREFIX.length));
|
||||
},
|
||||
}));
|
||||
} else {
|
||||
popupMenu.append(new MenuItem({
|
||||
label: 'Copy link &address',
|
||||
label: _t('Copy link address'),
|
||||
accelerator: 'a',
|
||||
click() {
|
||||
clipboard.writeText(url);
|
||||
},
|
||||
@@ -104,7 +108,8 @@ function onLinkContextMenu(ev, params) {
|
||||
// only the renderer can resolve them so don't give the user an option to.
|
||||
if (params.hasImageContents && !url.startsWith('blob:')) {
|
||||
popupMenu.append(new MenuItem({
|
||||
label: 'Sa&ve image as...',
|
||||
label: _t('Save image as...'),
|
||||
accelerator: 'a',
|
||||
async click() {
|
||||
const targetFileName = params.titleText || "image.png";
|
||||
const {filePath} = await dialog.showSaveDialog({
|
||||
@@ -123,8 +128,8 @@ function onLinkContextMenu(ev, params) {
|
||||
console.error(err);
|
||||
dialog.showMessageBox({
|
||||
type: "error",
|
||||
title: "Failed to save image",
|
||||
message: "The image failed to save",
|
||||
title: _t("Failed to save image"),
|
||||
message: _t("The image failed to save"),
|
||||
});
|
||||
}
|
||||
},
|
||||
@@ -151,7 +156,7 @@ function _CutCopyPasteSelectContextMenus(params) {
|
||||
options.push({
|
||||
type: 'separator',
|
||||
}, {
|
||||
label: 'Add to dictionary',
|
||||
label: _t('Add to dictionary'),
|
||||
click: (menuItem, browserWindow) => {
|
||||
browserWindow.webContents.session.addWordToSpellCheckerDictionary(params.misspelledWord);
|
||||
},
|
||||
@@ -162,22 +167,26 @@ function _CutCopyPasteSelectContextMenus(params) {
|
||||
|
||||
options.push({
|
||||
role: 'cut',
|
||||
label: 'Cu&t',
|
||||
label: _t('Cut'),
|
||||
accelerator: 't',
|
||||
enabled: params.editFlags.canCut,
|
||||
}, {
|
||||
role: 'copy',
|
||||
label: '&Copy',
|
||||
label: _t('Copy'),
|
||||
accelerator: 'c',
|
||||
enabled: params.editFlags.canCopy,
|
||||
}, {
|
||||
role: 'paste',
|
||||
label: '&Paste',
|
||||
label: _t('Paste'),
|
||||
accelerator: 'p',
|
||||
enabled: params.editFlags.canPaste,
|
||||
}, {
|
||||
role: 'pasteandmatchstyle',
|
||||
enabled: params.editFlags.canPaste,
|
||||
}, {
|
||||
role: 'selectall',
|
||||
label: "Select &All",
|
||||
label: _t("Select All"),
|
||||
accelerator: 'a',
|
||||
enabled: params.editFlags.canSelectAll,
|
||||
});
|
||||
return options;
|
||||
|
||||
172
yarn.lock
172
yarn.lock
@@ -26,6 +26,13 @@
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.10.4"
|
||||
|
||||
"@babel/code-frame@^7.12.13":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.13.tgz#dcfc826beef65e75c50e21d3837d7d95798dd658"
|
||||
integrity sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==
|
||||
dependencies:
|
||||
"@babel/highlight" "^7.12.13"
|
||||
|
||||
"@babel/generator@^7.10.5":
|
||||
version "7.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.5.tgz#1b903554bc8c583ee8d25f1e8969732e6b829a69"
|
||||
@@ -35,6 +42,15 @@
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/generator@^7.13.16":
|
||||
version "7.13.16"
|
||||
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.16.tgz#0befc287031a201d84cdfc173b46b320ae472d14"
|
||||
integrity sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.13.16"
|
||||
jsesc "^2.5.1"
|
||||
source-map "^0.5.0"
|
||||
|
||||
"@babel/helper-function-name@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a"
|
||||
@@ -44,6 +60,15 @@
|
||||
"@babel/template" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-function-name@^7.12.13":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz#93ad656db3c3c2232559fd7b2c3dbdcbe0eb377a"
|
||||
integrity sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==
|
||||
dependencies:
|
||||
"@babel/helper-get-function-arity" "^7.12.13"
|
||||
"@babel/template" "^7.12.13"
|
||||
"@babel/types" "^7.12.13"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2"
|
||||
@@ -51,6 +76,13 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-get-function-arity@^7.12.13":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583"
|
||||
integrity sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.12.13"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1"
|
||||
@@ -58,11 +90,23 @@
|
||||
dependencies:
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/helper-split-export-declaration@^7.12.13":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz#e9430be00baf3e88b0e13e6f9d4eaf2136372b05"
|
||||
integrity sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==
|
||||
dependencies:
|
||||
"@babel/types" "^7.12.13"
|
||||
|
||||
"@babel/helper-validator-identifier@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2"
|
||||
integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==
|
||||
|
||||
"@babel/helper-validator-identifier@^7.12.11":
|
||||
version "7.12.11"
|
||||
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed"
|
||||
integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==
|
||||
|
||||
"@babel/highlight@^7.0.0":
|
||||
version "7.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540"
|
||||
@@ -81,11 +125,25 @@
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/highlight@^7.12.13":
|
||||
version "7.13.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.13.10.tgz#a8b2a66148f5b27d666b15d81774347a731d52d1"
|
||||
integrity sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.12.11"
|
||||
chalk "^2.0.0"
|
||||
js-tokens "^4.0.0"
|
||||
|
||||
"@babel/parser@^7.10.4", "@babel/parser@^7.10.5", "@babel/parser@^7.7.0":
|
||||
version "7.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.5.tgz#e7c6bf5a7deff957cec9f04b551e2762909d826b"
|
||||
integrity sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ==
|
||||
|
||||
"@babel/parser@^7.12.13", "@babel/parser@^7.13.16":
|
||||
version "7.13.16"
|
||||
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.16.tgz#0f18179b0448e6939b1f3f5c4c355a3a9bcdfd37"
|
||||
integrity sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==
|
||||
|
||||
"@babel/runtime@^7.7.2":
|
||||
version "7.11.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736"
|
||||
@@ -102,6 +160,29 @@
|
||||
"@babel/parser" "^7.10.4"
|
||||
"@babel/types" "^7.10.4"
|
||||
|
||||
"@babel/template@^7.12.13":
|
||||
version "7.12.13"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327"
|
||||
integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.12.13"
|
||||
"@babel/parser" "^7.12.13"
|
||||
"@babel/types" "^7.12.13"
|
||||
|
||||
"@babel/traverse@^7.13.17":
|
||||
version "7.13.17"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.17.tgz#c85415e0c7d50ac053d758baec98b28b2ecfeea3"
|
||||
integrity sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==
|
||||
dependencies:
|
||||
"@babel/code-frame" "^7.12.13"
|
||||
"@babel/generator" "^7.13.16"
|
||||
"@babel/helper-function-name" "^7.12.13"
|
||||
"@babel/helper-split-export-declaration" "^7.12.13"
|
||||
"@babel/parser" "^7.13.16"
|
||||
"@babel/types" "^7.13.17"
|
||||
debug "^4.1.0"
|
||||
globals "^11.1.0"
|
||||
|
||||
"@babel/traverse@^7.7.0":
|
||||
version "7.10.5"
|
||||
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.5.tgz#77ce464f5b258be265af618d8fddf0536f20b564"
|
||||
@@ -126,6 +207,14 @@
|
||||
lodash "^4.17.19"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@babel/types@^7.12.13", "@babel/types@^7.13.16", "@babel/types@^7.13.17":
|
||||
version "7.13.17"
|
||||
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.17.tgz#48010a115c9fba7588b4437dd68c9469012b38b4"
|
||||
integrity sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==
|
||||
dependencies:
|
||||
"@babel/helper-validator-identifier" "^7.12.11"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@develar/schema-utils@~2.6.5":
|
||||
version "2.6.5"
|
||||
resolved "https://registry.yarnpkg.com/@develar/schema-utils/-/schema-utils-2.6.5.tgz#3ece22c5838402419a6e0425f85742b961d9b6c6"
|
||||
@@ -1597,6 +1686,17 @@ core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
counterpart@^0.18.6:
|
||||
version "0.18.6"
|
||||
resolved "https://registry.yarnpkg.com/counterpart/-/counterpart-0.18.6.tgz#cf6b60d8ef99a4b44b8bf6445fa99b4bd1b2f9dd"
|
||||
integrity sha512-cAIDAYbC3x8S2DDbvFEJ4TzPtPYXma25/kfAkfmprNLlkPWeX4SdUp1c2xklfphqCU3HnDaivR4R3BrAYf5OMA==
|
||||
dependencies:
|
||||
date-names "^0.1.11"
|
||||
except "^0.1.3"
|
||||
extend "^3.0.0"
|
||||
pluralizers "^0.1.7"
|
||||
sprintf-js "^1.0.3"
|
||||
|
||||
crc-32@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208"
|
||||
@@ -1683,6 +1783,11 @@ dashdash@^1.12.0:
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
date-names@^0.1.11:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/date-names/-/date-names-0.1.13.tgz#c4358f6f77c8056e2f5ea68fdbb05f0bf1e53bd0"
|
||||
integrity sha512-IxxoeD9tdx8pXVcmqaRlPvrXIsSrSrIZzfzlOkm9u+hyzKp5Wk/odt9O/gd7Ockzy8n/WHeEpTVJ2bF3mMV4LA==
|
||||
|
||||
debounce-fn@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/debounce-fn/-/debounce-fn-4.0.0.tgz#ed76d206d8a50e60de0dd66d494d82835ffe61c7"
|
||||
@@ -1711,14 +1816,14 @@ debug@^3.1.0, debug@^3.2.6:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
||||
debug@^4.0.1, debug@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.3.1:
|
||||
debug@^4.1.0, debug@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||
@@ -2472,6 +2577,13 @@ esutils@^2.0.2:
|
||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||
|
||||
except@^0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/except/-/except-0.1.3.tgz#98261c91958551536b44482238e9783fb73d292a"
|
||||
integrity sha1-mCYckZWFUVNrREgiOOl4P7c9KSo=
|
||||
dependencies:
|
||||
indexof "0.0.1"
|
||||
|
||||
execa@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
|
||||
@@ -2495,7 +2607,7 @@ exit-on-epipe@~1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692"
|
||||
integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==
|
||||
|
||||
extend@~3.0.2:
|
||||
extend@^3.0.0, extend@~3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
|
||||
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
|
||||
@@ -2540,9 +2652,9 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6:
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
||||
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
||||
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
|
||||
integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==
|
||||
|
||||
figures@^3.0.0:
|
||||
version "3.2.0"
|
||||
@@ -2611,6 +2723,11 @@ flush-write-stream@^1.0.0:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
foreachasync@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/foreachasync/-/foreachasync-3.0.0.tgz#5502987dc8714be3392097f32e0071c9dee07cf6"
|
||||
integrity sha1-VQKYfchxS+M5IJfzLgBxyd7gfPY=
|
||||
|
||||
forever-agent@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
|
||||
@@ -3123,6 +3240,11 @@ imurmurhash@^0.1.4:
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
||||
|
||||
indexof@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d"
|
||||
integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=
|
||||
|
||||
infer-owner@^1.0.3, infer-owner@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467"
|
||||
@@ -3975,6 +4097,14 @@ make-fetch-happen@^5.0.0:
|
||||
socks-proxy-agent "^4.0.0"
|
||||
ssri "^6.0.0"
|
||||
|
||||
"matrix-web-i18n@github:matrix-org/matrix-web-i18n":
|
||||
version "1.1.2"
|
||||
resolved "https://codeload.github.com/matrix-org/matrix-web-i18n/tar.gz/63f9119bc0bc304e83d4e8e22364caa7850e7671"
|
||||
dependencies:
|
||||
"@babel/parser" "^7.13.16"
|
||||
"@babel/traverse" "^7.13.17"
|
||||
walk "^2.3.14"
|
||||
|
||||
meant@^1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/meant/-/meant-1.0.3.tgz#67769af9de1d158773e928ae82c456114903554c"
|
||||
@@ -4140,11 +4270,16 @@ ms@2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
|
||||
ms@2.1.2, ms@^2.0.0, ms@^2.1.1:
|
||||
ms@2.1.2, ms@^2.0.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
|
||||
|
||||
mute-stream@0.0.8, mute-stream@~0.0.4:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
@@ -4948,6 +5083,11 @@ plist@^3.0.1:
|
||||
xmlbuilder "^9.0.7"
|
||||
xmldom "^0.5.0"
|
||||
|
||||
pluralizers@^0.1.7:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/pluralizers/-/pluralizers-0.1.7.tgz#8d38dd0a1b660e739b10ab2eab10b684c9d50142"
|
||||
integrity sha512-mw6AejUiCaMQ6uPN9ObjJDTnR5AnBSmnHHy3uVTbxrSFSxO5scfwpTs8Dxyb6T2v7GSulhvOq+pm9y+hXUvtOA==
|
||||
|
||||
png-to-ico@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/png-to-ico/-/png-to-ico-2.1.1.tgz#35be46f93c1ac8d77025f6f4b60c1fa567c1d47c"
|
||||
@@ -5708,6 +5848,11 @@ split-on-first@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f"
|
||||
integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==
|
||||
|
||||
sprintf-js@^1.0.3:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
|
||||
integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
@@ -5729,9 +5874,9 @@ sshpk@^1.7.0:
|
||||
tweetnacl "~0.14.0"
|
||||
|
||||
ssri@^6.0.0, ssri@^6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8"
|
||||
integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==
|
||||
version "6.0.2"
|
||||
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
|
||||
integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==
|
||||
dependencies:
|
||||
figgy-pudding "^3.5.1"
|
||||
|
||||
@@ -6402,6 +6547,13 @@ version-range@^1.0.0:
|
||||
dependencies:
|
||||
version-compare "^1.0.0"
|
||||
|
||||
walk@^2.3.14:
|
||||
version "2.3.14"
|
||||
resolved "https://registry.yarnpkg.com/walk/-/walk-2.3.14.tgz#60ec8631cfd23276ae1e7363ce11d626452e1ef3"
|
||||
integrity sha512-5skcWAUmySj6hkBdH6B6+3ddMjVQYH5Qy9QGbPmN8kVmLteXk+yVXg+yfk1nbX30EYakahLrr8iPcCxJQSCBeg==
|
||||
dependencies:
|
||||
foreachasync "^3.0.0"
|
||||
|
||||
wcwidth@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
|
||||
|
||||
Reference in New Issue
Block a user