Compare commits

..

108 Commits

Author SHA1 Message Date
RiotRobot
cf5e1eb4d4 v1.7.30 2021-06-07 17:54:24 +01:00
RiotRobot
dd494103de Prepare changelog for v1.7.30 2021-06-07 17:54:24 +01:00
RiotRobot
8a1a315938 v1.7.30-rc.1 2021-06-01 16:32:41 +01:00
RiotRobot
5958166348 Prepare changelog for v1.7.30-rc.1 2021-06-01 16:32:41 +01:00
J. Ryan Stinnett
767445e6f6 Merge pull request #199 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-06-01 15:56:37 +01:00
Weblate
99a3a132b3 Merge branch 'origin/develop' into Weblate. 2021-06-01 14:52:58 +00:00
Percy
1b1c869419 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/zh_Hans/
2021-05-29 10:34:36 +00:00
Viorel-Cătălin Răpițeanu
b67d48d661 Added translation using Weblate (Romanian) 2021-05-29 09:23:26 +00:00
Percy
922bed58ab Added translation using Weblate (Chinese (Simplified)) 2021-05-28 09:57:13 +00:00
J. Ryan Stinnett
7f28e3f1e2 Merge pull request #197 from vector-im/jryans/rework-linting
Migrate to `eslint-plugin-matrix-org`
2021-05-27 17:39:31 +01:00
J. Ryan Stinnett
2fca2151b9 Add linting deps 2021-05-27 17:35:05 +01:00
J. Ryan Stinnett
303a3d46f5 Upgrade plugin 2021-05-27 17:33:52 +01:00
J. Ryan Stinnett
8de0368c7c Merge pull request #198 from vector-im/jryans/electron-12.0.9
Upgrade to Electron 12.0.9
2021-05-27 15:13:32 +01:00
J. Ryan Stinnett
950657a364 Upgrade to Electron 12.0.9
This is a patch release upgrade only.
2021-05-27 15:11:43 +01:00
J. Ryan Stinnett
bc0f370821 Fall back to instance properties 2021-05-27 14:45:06 +01:00
J. Ryan Stinnett
1455687384 Auto-fix lint errors 2021-05-27 14:45:06 +01:00
J. Ryan Stinnett
3efed87d38 Migrate to eslint-plugin-matrix-org
Switch to the new linting package. It offers a new shared config for native
JavaScript, which this package targets.
2021-05-27 14:35:11 +01:00
RiotRobot
0c43287f98 v1.7.29 2021-05-24 17:49:30 +01:00
RiotRobot
c539f603dc Prepare changelog for v1.7.29 2021-05-24 17:49:30 +01:00
Justas Zabulionis
b2d00f6605 Translated using Weblate (Swedish)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/sv/
2021-05-23 15:34:33 +00:00
RiotRobot
27bce3b92b v1.7.29-rc.1 2021-05-19 15:39:33 +01:00
RiotRobot
439ea006bf Prepare changelog for v1.7.29-rc.1 2021-05-19 15:39:33 +01:00
J. Ryan Stinnett
315a2107d3 Merge pull request #196 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-05-19 13:54:41 +01:00
Weblate
43527fb609 Merge branch 'origin/develop' into Weblate. 2021-05-19 12:54:15 +00:00
lvre
3c946967ce Translated using Weblate (Portuguese (Brazil))
Currently translated at 95.4% (42 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/pt_BR/
2021-05-18 20:34:32 +00:00
lvre
0a17382901 Added translation using Weblate (Portuguese (Brazil)) 2021-05-17 19:29:28 +00:00
RiotRobot
d3508f3039 Merge branch 'master' into develop 2021-05-17 14:06:54 +01:00
RiotRobot
0f6f947254 v1.7.28 2021-05-17 14:06:36 +01:00
RiotRobot
bebed00200 Prepare changelog for v1.7.28 2021-05-17 14:06:35 +01:00
Trendyne
40a248a275 Translated using Weblate (Icelandic)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/is/
2021-05-16 13:34:31 +00:00
Trendyne
c86ad29b3d Added translation using Weblate (Icelandic) 2021-05-15 12:45:22 +00:00
J. Ryan Stinnett
8ade746fec Merge pull request #195 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-05-11 17:47:39 +01:00
Weblate
2733b2ad11 Merge branch 'origin/develop' into Weblate. 2021-05-11 16:47:01 +00:00
RiotRobot
d74631a555 v1.7.28-rc.1 2021-05-11 17:00:25 +01:00
RiotRobot
944bb3c717 Prepare changelog for v1.7.28-rc.1 2021-05-11 17:00:25 +01:00
Germain
7fad439078 Merge pull request #190 from vector-im/gsouquet-windows-requirements 2021-05-11 12:43:46 +01:00
Germain
f98d1672af Suggest installing Build tools rather than Visual Studio
Co-authored-by: J. Ryan Stinnett <jryans@gmail.com>
2021-05-11 12:41:24 +01:00
RiotRobot
debeef6ee6 Merge branch 'master' into develop 2021-05-10 15:39:35 +01:00
RiotRobot
28096f3a22 v1.7.27 2021-05-10 15:39:19 +01:00
RiotRobot
5efc4528a2 Prepare changelog for v1.7.27 2021-05-10 15:39:19 +01:00
random
b216eca07a Translated using Weblate (Italian)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/it/
2021-05-08 08:34:28 +00:00
zer0-x
5ad645f024 Translated using Weblate (Arabic)
Currently translated at 22.7% (10 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ar/
2021-05-06 00:34:28 +00:00
J. Ryan Stinnett
75b41d65c1 Merge pull request #192 from aaronraimist/close-fullscreen-macos
Prevent black screen when closing window while in full screen mode on macOS
2021-05-05 16:54:48 +01:00
Aaron Raimist
cc5dc4d801 Prevent black screen when closing window while in full screen mode on macOS
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-05-04 21:55:32 -05:00
zer0-x
c4aeaadfbd Added translation using Weblate (Arabic) 2021-05-04 23:59:48 +00:00
RiotRobot
7e34425d78 v1.7.27-rc.1 2021-05-04 16:10:00 +01:00
RiotRobot
5f09505056 Prepare changelog for v1.7.27-rc.1 2021-05-04 16:09:59 +01:00
J. Ryan Stinnett
9def502c95 Merge pull request #191 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-05-04 15:34:05 +01:00
J. Ryan Stinnett
e09b01f303 Merge pull request #187 from vector-im/dependabot/npm_and_yarn/ssri-6.0.2
Bump ssri from 6.0.1 to 6.0.2
2021-05-04 15:32:52 +01:00
Weblate
32aacbdd9a Merge branch 'origin/develop' into Weblate. 2021-05-04 14:31:35 +00:00
Ville Ranki
e1554cbbe0 Translated using Weblate (Finnish)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/fi/
2021-05-04 13:34:27 +00:00
Ville Ranki
2b8c378773 Added translation using Weblate (Finnish) 2021-05-03 12:17:56 +00:00
iaiz
fe7bf57565 Translated using Weblate (Spanish)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/es/
2021-05-02 13:34:27 +00:00
Priit Jõerüüt
cbaad79515 Translated using Weblate (Estonian)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/et/
2021-05-02 13:34:27 +00:00
Martin Berg Alstad
a7a8115b17 Translated using Weblate (Norwegian Bokmål)
Currently translated at 2.2% (1 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/nb_NO/
2021-05-02 13:34:27 +00:00
random
e694a8e30e Translated using Weblate (Italian)
Currently translated at 95.4% (42 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/it/
2021-05-02 13:34:27 +00:00
Felicia Jongleur
cda4f8ccb4 Translated using Weblate (Swedish)
Currently translated at 88.6% (39 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/sv/
2021-05-02 13:34:27 +00:00
rkfg
4369b3a5ad Translated using Weblate (Russian)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ru/
2021-05-02 13:34:26 +00:00
iaiz
933d0b80bf Added translation using Weblate (Spanish) 2021-05-01 12:38:39 +00:00
Priit Jõerüüt
043e006f3b Added translation using Weblate (Estonian) 2021-04-30 21:17:27 +00:00
libexus
2a1acf0525 Translated using Weblate (German)
Currently translated at 95.4% (42 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/de/
2021-04-30 14:39:20 +00:00
Martin Berg Alstad
820e32e250 Added translation using Weblate (Norwegian Bokmål) 2021-04-30 13:14:50 +00:00
J. Ryan Stinnett
20e4459bb5 Merge pull request #180 from tomvaneyck/hardware-media
Disables HardwareMediaKeyHandling
2021-04-30 13:01:53 +01:00
libexus
913c954eeb Added translation using Weblate (German) 2021-04-29 15:02:06 +00:00
Germain Souquet
b5fdeddec3 Add Windows native module requirements 2021-04-29 15:36:10 +01:00
random
38dab479b1 Added translation using Weblate (Italian) 2021-04-29 08:15:11 +00:00
XoseM
f385b1f1d5 Translated using Weblate (Galician)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/gl/
2021-04-29 06:34:26 +00:00
Szimszon
298ccbe16c Translated using Weblate (Hungarian)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/hu/
2021-04-29 06:34:26 +00:00
vintergatan
b8c99c6186 Translated using Weblate (Swedish)
Currently translated at 72.7% (32 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/sv/
2021-04-29 06:34:26 +00:00
rkfg
ca70486323 Translated using Weblate (Russian)
Currently translated at 86.3% (38 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ru/
2021-04-29 06:34:25 +00:00
Thibault Martin
4bee175f16 Translated using Weblate (French)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/fr/
2021-04-29 06:34:25 +00:00
XoseM
628b37a2d1 Added translation using Weblate (Galician) 2021-04-28 06:10:32 +00:00
Szimszon
9daf5ae413 Added translation using Weblate (Hungarian) 2021-04-27 17:57:43 +00:00
vintergatan
19c8c5f580 Added translation using Weblate (Swedish) 2021-04-27 16:02:25 +00:00
Travis Ralston
989b4df6c6 Merge pull request #189 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-04-27 09:11:00 -06:00
rkfg
21c40b796f Translated using Weblate (Russian)
Currently translated at 79.5% (35 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ru/
2021-04-27 15:10:33 +00:00
Thibault Martin
ccb302b951 Translated using Weblate (French)
Currently translated at 72.7% (32 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/fr/
2021-04-27 15:10:33 +00:00
rkfg
7d29046cba Translated using Weblate (Russian)
Currently translated at 75.0% (33 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ru/
2021-04-27 15:10:21 +00:00
Thibault Martin
9c3e557333 Translated using Weblate (French)
Currently translated at 70.4% (31 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/fr/
2021-04-27 15:10:21 +00:00
rkfg
6a7735247e Translated using Weblate (Russian)
Currently translated at 13.6% (6 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ru/
2021-04-27 15:06:51 +00:00
Germain
c0f5ed15e2 Translated using Weblate (French)
Currently translated at 18.1% (8 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/fr/
2021-04-27 15:06:51 +00:00
Thibault Martin
56d9a86152 Translated using Weblate (French)
Currently translated at 18.1% (8 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/fr/
2021-04-27 15:06:51 +00:00
rkfg
82def5ce37 Added translation using Weblate (Russian) 2021-04-27 15:05:35 +00:00
Germain
5ec91d3a53 Added translation using Weblate (French) 2021-04-27 15:01:32 +00:00
dependabot[bot]
8b69982023 Bump ssri from 6.0.1 to 6.0.2
Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>
2021-04-27 14:51:39 +00:00
Germain
7e69c81e62 Merge pull request #188 from vector-im/gsouquet-i18n-td 2021-04-27 15:50:19 +01:00
Germain Souquet
e64e6e642c Upgrade matrix-web-i18n to use matrix prefixed binaries 2021-04-27 15:10:20 +01:00
RiotRobot
7f24661357 Merge branch 'master' into develop 2021-04-26 18:13:06 +01:00
Germain Souquet
46b1015478 Fix typo in _t function declaration 2021-04-26 17:14:55 +01:00
Germain Souquet
8ae641bc59 Set appropriate appMenu submenu role 2021-04-26 17:12:13 +01:00
Germain Souquet
8f4c827089 change translate widget project ID 2021-04-26 16:59:24 +01:00
Germain Souquet
20ce3d10a3 add missing copyright header 2021-04-26 16:58:22 +01:00
Germain Souquet
72483a60cb Add diff-i18n script for CI 2021-04-26 16:22:33 +01:00
Travis Ralston
de16099360 Add required weblate basefile 2021-04-26 09:11:30 -06:00
Germain Souquet
ae0213b663 Move i18n scripts in its own module 2021-04-26 16:00:10 +01:00
Germain Souquet
b9510d0a0b use _t over _td for consistency with element-web 2021-04-26 14:50:18 +01:00
Germain Souquet
c56aa9100f appease max line length linting rule 2021-04-26 14:38:00 +01:00
Germain Souquet
d59384f3e7 Add internationalisation documentation 2021-04-26 14:19:48 +01:00
Germain Souquet
00ba42186b Add labels to role-only menu item to have consistent languages in menu 2021-04-26 14:14:35 +01:00
Germain Souquet
e950303966 stop using experimental class private methods 2021-04-26 14:13:32 +01:00
Germain Souquet
105070716e Make application react to element-web language change 2021-04-26 13:58:29 +01:00
Germain
3b4eb5c18e Merge pull request #186 from vector-im/gsouquet-eventindex-freshinstall 2021-04-26 09:43:56 +01:00
Germain Souquet
658304cc51 Wrap all strings in _td function for i18n 2021-04-23 16:56:17 +01:00
Germain Souquet
b7dd4e53a3 Ensure new passphrase is stored in keytar 2021-04-23 15:35:09 +01:00
Germain Souquet
1fa6671a17 Remove change passphrase logic and rely on keytar 2021-04-23 15:17:50 +01:00
Germain Souquet
3f9495f19d Fix event index passphrase change process 2021-04-21 12:20:29 +01:00
Tom Van Eyck
14a65fb0af Clarify HardwareMediaKeyHandling disable flag.
Co-authored-by: Šimon Brandner <simon.bra.ag@gmail.com>
Signed-off-by: Tom Van Eyck <tom.vaneyck@telenet.be>
2021-04-03 14:26:08 +02:00
Tom Van Eyck
cdbda52d9a Disabled HardwareMediaKeyHandling, fixes vector-im/element-web#15704
Signed-off-by: Tom Van Eyck <tom.vaneyck@telenet.be>
2021-04-02 16:52:30 +02:00
34 changed files with 1558 additions and 1139 deletions

View File

@@ -1,6 +1,12 @@
module.exports = {
plugins: [
"matrix-org",
],
extends: [
"plugin:matrix-org/javascript",
],
parserOptions: {
ecmaVersion: 8,
ecmaVersion: 2021,
},
env: {
es6: true,
@@ -8,12 +14,7 @@ module.exports = {
// we also have some browser code (ie. the preload script)
browser: true,
},
extends: ["matrix-org"],
rules: {
// js-sdk uses a babel rule which we can't use because we
// don't use babel, so remove it & put the original back
"babel/no-invalid-this": "off",
"no-invalid-this": "error",
"quotes": "off",
"indent": "off",
"prefer-promise-reject-errors": "off",

View File

@@ -1,3 +1,73 @@
Changes in [1.7.30](https://github.com/vector-im/element-desktop/releases/tag/v1.7.30) (2021-06-07)
===================================================================================================
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.30-rc.1...v1.7.30)
* No changes since rc.1
Changes in [1.7.30-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.30-rc.1) (2021-06-01)
=============================================================================================================
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.29...v1.7.30-rc.1)
* Translations update from Weblate
[\#199](https://github.com/vector-im/element-desktop/pull/199)
* Migrate to `eslint-plugin-matrix-org`
[\#197](https://github.com/vector-im/element-desktop/pull/197)
* Upgrade to Electron 12.0.9
[\#198](https://github.com/vector-im/element-desktop/pull/198)
Changes in [1.7.29](https://github.com/vector-im/element-desktop/releases/tag/v1.7.29) (2021-05-24)
===================================================================================================
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.29-rc.1...v1.7.29)
* No changes since rc.1
Changes in [1.7.29-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.29-rc.1) (2021-05-19)
=============================================================================================================
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.28...v1.7.29-rc.1)
* Translations update from Weblate
[\#196](https://github.com/vector-im/element-desktop/pull/196)
* Translations update from Weblate
[\#195](https://github.com/vector-im/element-desktop/pull/195)
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)

View File

@@ -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
==========================

View 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.

View File

@@ -2,7 +2,7 @@
"name": "element-desktop",
"productName": "Element",
"main": "src/electron-main.js",
"version": "1.7.26",
"version": "1.7.30",
"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",
@@ -43,11 +47,13 @@
"electron-builder-squirrel-windows": "22.10.5",
"electron-devtools-installer": "^3.1.1",
"electron-notarize": "^1.0.0",
"eslint": "7.3.1",
"eslint-config-matrix-org": "^0.1.2",
"eslint": "7.18.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-matrix-org": "github:matrix-org/eslint-plugin-matrix-org#main",
"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",
@@ -62,7 +68,7 @@
},
"build": {
"appId": "im.riot.app",
"electronVersion": "12.0.2",
"electronVersion": "12.0.9",
"files": [
"package.json",
{

View File

@@ -15,7 +15,7 @@ const PUB_KEY_URL = "https://packages.riot.im/element-release-key.asc";
const PACKAGE_URL_PREFIX = "https://github.com/vector-im/element-web/releases/download/";
const ASAR_PATH = 'webapp.asar';
const {setPackageVersion} = require('./set-version.js');
const { setPackageVersion } = require('./set-version.js');
async function getLatestDevelopUrl(bkToken) {
const buildsResult = await needle('get',

View File

@@ -37,7 +37,7 @@ async function fetch(hakEnv, moduleInfo) {
if (haveModuleBuildDir) return;
await new Promise((resolve) => {
npm.load({'loglevel': 'silent'}, resolve);
npm.load({ 'loglevel': 'silent' }, resolve);
});
console.log("Fetching " + moduleInfo.name + " at version " + moduleInfo.version);

View File

@@ -52,4 +52,4 @@ if (require.main === module) {
main(process.argv.slice(2)).then((ret) => process.exit(ret));
}
module.exports = {versionFromAsar, setPackageVersion};
module.exports = { versionFromAsar, setPackageVersion };

View File

@@ -24,7 +24,7 @@ const checkSquirrelHooks = require('./squirrelhooks');
if (checkSquirrelHooks()) return;
const argv = require('minimist')(process.argv, {
alias: {help: "h"},
alias: { help: "h" },
});
const {
@@ -34,10 +34,10 @@ 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');
const { getProfileFromDeeplink, protocolInit, recordSSOSession } = require('./protocol');
const windowStateKeeper = require('electron-window-state');
const Store = require('electron-store');
@@ -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,26 @@ 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 +547,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 +802,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();
@@ -852,17 +835,17 @@ app.on('ready', async () => {
protocol.registerFileProtocol('vector', (request, callback) => {
if (request.method !== 'GET') {
callback({error: -322}); // METHOD_NOT_SUPPORTED from chromium/src/net/base/net_error_list.h
callback({ error: -322 }); // METHOD_NOT_SUPPORTED from chromium/src/net/base/net_error_list.h
return null;
}
const parsedUrl = new URL(request.url);
if (parsedUrl.protocol !== 'vector:') {
callback({error: -302}); // UNKNOWN_URL_SCHEME
callback({ error: -302 }); // UNKNOWN_URL_SCHEME
return;
}
if (parsedUrl.host !== 'vector') {
callback({error: -105}); // NAME_NOT_RESOLVED
callback({ error: -105 }); // NAME_NOT_RESOLVED
return;
}
@@ -870,7 +853,7 @@ app.on('ready', async () => {
// path starts with a '/'
if (target[0] !== '') {
callback({error: -6}); // FILE_NOT_FOUND
callback({ error: -6 }); // FILE_NOT_FOUND
return;
}
@@ -882,7 +865,7 @@ app.on('ready', async () => {
if (target[1] === 'webapp') {
baseDir = asarPath;
} else {
callback({error: -6}); // FILE_NOT_FOUND
callback({ error: -6 }); // FILE_NOT_FOUND
return;
}
@@ -892,7 +875,7 @@ app.on('ready', async () => {
const relTarget = path.normalize(path.join(...target.slice(2)));
if (relTarget.startsWith('..')) {
callback({error: -6}); // FILE_NOT_FOUND
callback({ error: -6 }); // FILE_NOT_FOUND
return;
}
const absTarget = path.join(baseDir, relTarget);
@@ -940,7 +923,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 +954,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 +979,14 @@ app.on('ready', async () => {
}
webContentsHandler(mainWindow.webContents);
appLocalization = new AppLocalization({
store,
components: [
() => tray.initApplicationMenu(),
() => Menu.setApplicationMenu(buildMenuTemplate()),
],
});
});
app.on('window-all-closed', () => {

12
src/i18n/strings/ar.json Normal file
View File

@@ -0,0 +1,12 @@
{
"File": "مَلَفّ",
"Close": "إغلاق",
"Actual Size": "الحَجمُ الفِعلي",
"View": "الاِطِّلاع",
"Select All": "تَحدِيدُ الكُل",
"Delete": "حَذف",
"Copy": "نَسخ",
"Edit": "تَحرير",
"Close Element": "إغلَاقُ Element",
"Cancel": "إلغَاء"
}

View File

@@ -0,0 +1 @@
{}

46
src/i18n/strings/de.json Normal file
View 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"
}

View 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
View 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
View 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
View 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
View 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 dElement",
"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": "Limage na pas pu être sauvegardée",
"Failed to save image": "Échec de la sauvegarde de limage",
"Save image as...": "Enregistrer limage sous…",
"Copy link address": "Copier ladresse du lien",
"Copy email address": "Copier ladresse e-mail",
"Copy image": "Copier limage",
"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
View 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
View 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"
}

46
src/i18n/strings/is.json Normal file
View File

@@ -0,0 +1,46 @@
{
"Add to dictionary": "Bæta við orðabók",
"The image failed to save": "Myndin mistóksts að vista",
"Failed to save image": "Mistókst að vista mynd",
"Save image as...": "Vista mynd sem...",
"Copy link address": "Afrita nethlekk",
"Copy email address": "Afrita tölvupóstfang",
"Copy image": "Afrita mynd",
"File": "Skrá",
"Bring All to Front": "Koma Öllum að Framan",
"Zoom": "Stærð",
"Stop Speaking": "Hætta Tal",
"Start Speaking": "Byrja Tal",
"Speech": "Tal",
"Unhide": "Birta",
"Hide Others": "Fela Aðra",
"Hide": "Fela",
"Services": "Þjónustur",
"About": "Um",
"Element Help": "Element Hjálp",
"Help": "Hjálp",
"Close": "Loka",
"Minimize": "Lágmarka",
"Window": "Gluggi",
"Toggle Developer Tools": "Skipta Framkvæmdaraðilaverkfæri",
"Toggle Full Screen": "Skipta um Fullskjá",
"Preferences": "Stillingar",
"Zoom Out": "Minnka",
"Zoom In": "Stækka",
"Actual Size": "Raunveruleg Stærð",
"View": "Skoða",
"Select All": "Velja Allt",
"Delete": "Eyða",
"Paste and Match Style": "Líma og Passa Stíl",
"Paste": "Líma",
"Copy": "Afrita",
"Cut": "Klippa",
"Redo": "Endurgera",
"Undo": "Afturkalla",
"Edit": "Breyta",
"Quit": "Hætta",
"Show/Hide": "Sýna/Fela",
"Are you sure you want to quit?": "Ertu viss um að þú viljir hætta?",
"Close Element": "Loka Element",
"Cancel": "Hætta við"
}

46
src/i18n/strings/it.json Normal file
View File

@@ -0,0 +1,46 @@
{
"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",
"Stop Speaking": "Smetti di parlare",
"Speech": "Dettatura"
}

View File

@@ -0,0 +1,3 @@
{
"Toggle Developer Tools": "Veksle Utvikleralternativer"
}

View File

@@ -0,0 +1,44 @@
{
"Add to dictionary": "Adicionar a dicionário",
"The image failed to save": "A imagem falhou para salvar",
"Failed to save image": "Falha para salvar imagem",
"Save image as...": "Salvar imagem como...",
"Copy link address": "Copiar endereço de link",
"Copy email address": "Copiar endereço de email",
"Copy image": "Copiar imagem",
"File": "Arquivo",
"Zoom": "Zoom",
"Stop Speaking": "Parar de Falar",
"Start Speaking": "Começar a Falar",
"Speech": "Fala",
"Unhide": "Desesconder",
"Hide": "Esconder",
"Services": "Serviços",
"About": "Sobre",
"Element Help": "Ajuda de Element",
"Help": "Ajuda",
"Close": "Fechar",
"Minimize": "Minimizar",
"Window": "Janela",
"Toggle Developer Tools": "Ativar/Desativar Ferramentas de Desenvolvimento",
"Toggle Full Screen": "Pôr em/Tirar de Tela Cheia",
"Preferences": "Preferências",
"Zoom Out": "Dar Zoom Out",
"Zoom In": "Dar Zoom In",
"Actual Size": "Tamanho de Verdade",
"View": "Ver",
"Select All": "Selecionar Tudo",
"Delete": "Deletar",
"Paste and Match Style": "Colar e Adequar Estilo",
"Paste": "Colar",
"Copy": "Copiar",
"Cut": "Cortar",
"Redo": "Refazer",
"Undo": "Desfazer",
"Edit": "Editar",
"Quit": "Sair",
"Show/Hide": "Mostrar/Esconder",
"Are you sure you want to quit?": "Você tem certeza que quer sair?",
"Close Element": "Fechar Element",
"Cancel": "Cancelar"
}

1
src/i18n/strings/ro.json Normal file
View File

@@ -0,0 +1 @@
{}

46
src/i18n/strings/ru.json Normal file
View 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": "Вставить с тем же стилем"
}

46
src/i18n/strings/sv.json Normal file
View File

@@ -0,0 +1,46 @@
{
"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",
"Show/Hide": "Visa/dölj",
"Add to dictionary": "Lägg till i ordlistan",
"The image failed to save": "Bilden sparades inte",
"Failed to save image": "Misslyckades med att spara bilden",
"Are you sure you want to quit?": "Är du säker att du vill avsluta?"
}

View File

@@ -0,0 +1,46 @@
{
"Add to dictionary": "添加到字典",
"The image failed to save": "图片保存失败",
"Failed to save image": "图片保存失败",
"Save image as...": "保存图片为……",
"Copy link address": "复制链接地址",
"Copy email address": "复制邮箱地址",
"Copy image": "复制图片",
"File": "文件",
"Bring All to Front": "置前",
"Zoom": "放大",
"Stop Speaking": "停止讲话",
"Start Speaking": "开始讲话",
"Speech": "讲话",
"Unhide": "显示",
"Hide Others": "隐藏其他",
"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 and Match Style": "粘贴并匹配样式",
"Paste": "粘贴",
"Copy": "复制",
"Cut": "剪贴",
"Redo": "重做",
"Undo": "撤销",
"Edit": "编辑",
"Quit": "退出",
"Show/Hide": "显示/隐藏",
"Are you sure you want to quit?": "你确定要退出吗?",
"Close Element": "关闭 Element",
"Cancel": "取消"
}

128
src/language-helper.js Normal file
View File

@@ -0,0 +1,128 @@
/*
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 {
constructor({ store, components = [] }) {
// TODO: Should be static field, but that doesn't parse without Babel
this.STORE_KEY = "locale";
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(this.STORE_KEY)) {
const locales = this.store.get(this.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(this.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,
};

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const {app} = require("electron");
const { app } = require("electron");
const path = require("path");
const fs = require("fs");

View File

@@ -16,7 +16,7 @@ limitations under the License.
const path = require('path');
const spawn = require('child_process').spawn;
const {app} = require('electron');
const { app } = require('electron');
const fsProm = require('fs').promises;
function runUpdateExe(args) {

View File

@@ -15,10 +15,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const {app, Tray, Menu, nativeImage} = require('electron');
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;

View File

@@ -14,130 +14,213 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const {app, shell, Menu} = require('electron');
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;

View File

@@ -1,8 +1,9 @@
const {clipboard, nativeImage, Menu, MenuItem, shell, dialog, ipcMain} = require('electron');
const { clipboard, nativeImage, Menu, MenuItem, shell, dialog, ipcMain } = require('electron');
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:";
@@ -49,7 +50,6 @@ function writeNativeImage(filePath, img) {
}
}
function onLinkContextMenu(ev, params) {
let url = params.linkURL || params.srcURL;
@@ -73,7 +73,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 +86,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,10 +107,11 @@ 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({
const { filePath } = await dialog.showSaveDialog({
defaultPath: targetFileName,
});
@@ -123,8 +127,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 +155,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 +166,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;
@@ -206,7 +214,7 @@ function onEditableContextMenu(ev, params) {
ev.preventDefault();
}
ipcMain.on('userDownloadOpen', function(ev, {path}) {
ipcMain.on('userDownloadOpen', function(ev, { path }) {
shell.openPath(path);
});

1190
yarn.lock
View File

File diff suppressed because it is too large Load Diff