mirror of
https://github.com/element-hq/element-desktop.git
synced 2026-01-03 21:18:12 -05:00
Compare commits
292 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7938ae514 | ||
|
|
cf3112a9a9 | ||
|
|
b23048c5ce | ||
|
|
c689529641 | ||
|
|
7b6ead738e | ||
|
|
b6b5547ad0 | ||
|
|
e28390fddb | ||
|
|
b470657cdb | ||
|
|
fc51063f7a | ||
|
|
099ecc468a | ||
|
|
99b5947d7d | ||
|
|
7418161475 | ||
|
|
40be024c9f | ||
|
|
b2f09570f7 | ||
|
|
c3f150f9f0 | ||
|
|
8a90a12683 | ||
|
|
e7bc785ae4 | ||
|
|
d1cb3092e8 | ||
|
|
a136ccbf4c | ||
|
|
231db351ec | ||
|
|
06b0f0fe01 | ||
|
|
4b71142a87 | ||
|
|
9726be5754 | ||
|
|
2293b6794c | ||
|
|
492bbcbe06 | ||
|
|
9cc1d91011 | ||
|
|
c08b62015e | ||
|
|
03abf9f9d0 | ||
|
|
69e4ec7287 | ||
|
|
cf5e1eb4d4 | ||
|
|
dd494103de | ||
|
|
57ba22f874 | ||
|
|
330e230f2c | ||
|
|
dee2ecdf6c | ||
|
|
344800d835 | ||
|
|
8c99f0ad12 | ||
|
|
b7e4e9e075 | ||
|
|
5055ad0aec | ||
|
|
8a1a315938 | ||
|
|
5958166348 | ||
|
|
767445e6f6 | ||
|
|
99a3a132b3 | ||
|
|
1b1c869419 | ||
|
|
b67d48d661 | ||
|
|
922bed58ab | ||
|
|
7f28e3f1e2 | ||
|
|
2fca2151b9 | ||
|
|
303a3d46f5 | ||
|
|
8de0368c7c | ||
|
|
950657a364 | ||
|
|
bc0f370821 | ||
|
|
1455687384 | ||
|
|
3efed87d38 | ||
|
|
0c43287f98 | ||
|
|
c539f603dc | ||
|
|
b2d00f6605 | ||
|
|
27bce3b92b | ||
|
|
439ea006bf | ||
|
|
315a2107d3 | ||
|
|
43527fb609 | ||
|
|
3c946967ce | ||
|
|
0a17382901 | ||
|
|
d3508f3039 | ||
|
|
0f6f947254 | ||
|
|
bebed00200 | ||
|
|
40a248a275 | ||
|
|
c86ad29b3d | ||
|
|
8ade746fec | ||
|
|
2733b2ad11 | ||
|
|
d74631a555 | ||
|
|
944bb3c717 | ||
|
|
7fad439078 | ||
|
|
f98d1672af | ||
|
|
debeef6ee6 | ||
|
|
28096f3a22 | ||
|
|
5efc4528a2 | ||
|
|
b216eca07a | ||
|
|
5ad645f024 | ||
|
|
75b41d65c1 | ||
|
|
cc5dc4d801 | ||
|
|
c4aeaadfbd | ||
|
|
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 | ||
|
|
c19baadcd3 | ||
|
|
ada58f826a | ||
|
|
46b1015478 | ||
|
|
8ae641bc59 | ||
|
|
8f4c827089 | ||
|
|
20ce3d10a3 | ||
|
|
72483a60cb | ||
|
|
de16099360 | ||
|
|
ae0213b663 | ||
|
|
b9510d0a0b | ||
|
|
c56aa9100f | ||
|
|
d59384f3e7 | ||
|
|
00ba42186b | ||
|
|
e950303966 | ||
|
|
105070716e | ||
|
|
3b4eb5c18e | ||
|
|
658304cc51 | ||
|
|
b7dd4e53a3 | ||
|
|
1fa6671a17 | ||
|
|
6526127998 | ||
|
|
b640d5e7e4 | ||
|
|
3f9495f19d | ||
|
|
1ff5387f1d | ||
|
|
5ae736e861 | ||
|
|
29d22aefd7 | ||
|
|
11602bb578 | ||
|
|
46ee80837a | ||
|
|
97178f4297 | ||
|
|
cd93f29691 | ||
|
|
48132c9eab | ||
|
|
4f58ba1b22 | ||
|
|
955be8417b | ||
|
|
c136f2cafc | ||
|
|
adfa845d9c | ||
|
|
017cfd70f4 | ||
|
|
d63c27c50a | ||
|
|
7edea00d4e | ||
|
|
ce26e7964d | ||
|
|
14a65fb0af | ||
|
|
cdbda52d9a | ||
|
|
55dffc8c52 | ||
|
|
100f08161d | ||
|
|
d4bf14b47f | ||
|
|
dabca5dc33 | ||
|
|
d11a7e77ac | ||
|
|
adfb4a424a | ||
|
|
5fc871492e | ||
|
|
3c68fe796f | ||
|
|
a996aff19b | ||
|
|
84990559ec | ||
|
|
fdf216ca75 | ||
|
|
f460cfa99a | ||
|
|
d2bc3a8a03 | ||
|
|
6a107f7095 | ||
|
|
ff4ebd4b39 | ||
|
|
76eef82274 | ||
|
|
d986555517 | ||
|
|
939c5b4588 | ||
|
|
f51001a460 | ||
|
|
db2fd9dd53 | ||
|
|
3d18ff16d1 | ||
|
|
9cdea580d3 | ||
|
|
68587e84ed | ||
|
|
58be4c62f7 | ||
|
|
c9c0ceb757 | ||
|
|
a46698559f | ||
|
|
c18b213699 | ||
|
|
b309562244 | ||
|
|
6c6a7d1bd6 | ||
|
|
6bff9f9a20 | ||
|
|
42139ec30d | ||
|
|
6edc4cb965 | ||
|
|
121bba1f35 | ||
|
|
b8adc66898 | ||
|
|
323c42bb72 | ||
|
|
8e51f6299c | ||
|
|
888ce434ff | ||
|
|
a223489511 | ||
|
|
9ca19d7de6 | ||
|
|
dce524f5bc | ||
|
|
48d66c0031 | ||
|
|
36438479fc | ||
|
|
f51acb78e0 | ||
|
|
343215925a | ||
|
|
a535efc1cc | ||
|
|
57496d89e5 | ||
|
|
5dc9ba94ca | ||
|
|
3d519f571f | ||
|
|
d9702e2f92 | ||
|
|
23ecc8573d | ||
|
|
7199a697f4 | ||
|
|
ecbcafe9ea | ||
|
|
8828838e8a | ||
|
|
c7c56f2f97 | ||
|
|
2c619a3a3f | ||
|
|
a4f6d68001 | ||
|
|
d4c48f68ec | ||
|
|
6ce89b667e | ||
|
|
d9bfd239c5 | ||
|
|
030fe38834 | ||
|
|
70c3446339 | ||
|
|
de0e7483a9 | ||
|
|
0b01b32e98 | ||
|
|
f7e5d0aa5f | ||
|
|
21f3847ccc | ||
|
|
e826c04c03 | ||
|
|
39404a62e6 | ||
|
|
4b7a442a73 | ||
|
|
6de76f5b02 | ||
|
|
7058196c25 | ||
|
|
1cd2ce9d34 | ||
|
|
542e2c6891 | ||
|
|
03ce222464 | ||
|
|
00fd261dc1 | ||
|
|
74ebc6cb22 | ||
|
|
a64516483b | ||
|
|
44c8f2c30f | ||
|
|
faa217c767 | ||
|
|
5ad0967b07 | ||
|
|
cda9f3f190 | ||
|
|
2c2addb282 | ||
|
|
19515b614f | ||
|
|
b646f78897 | ||
|
|
3b496c362b | ||
|
|
c4b7e856db | ||
|
|
cb1626cb9f | ||
|
|
a36321b697 | ||
|
|
353f5b35df | ||
|
|
8ae1a518fa | ||
|
|
edea42e30e | ||
|
|
fafd8fb206 | ||
|
|
f9e61d09c9 | ||
|
|
974514e2e6 | ||
|
|
b8d0d990bb | ||
|
|
ed1b9247c1 | ||
|
|
d3adfe3777 | ||
|
|
d45007cd1b | ||
|
|
ed00cfada3 | ||
|
|
3a660b2461 | ||
|
|
c6bbff5ffe | ||
|
|
fa8aef94af | ||
|
|
b7c31f17b5 | ||
|
|
62b6aa26ff | ||
|
|
d69f2a6d44 | ||
|
|
c1ed8ab377 | ||
|
|
df1c7f2498 | ||
|
|
0d00f3ea6c | ||
|
|
2ef3c8c1ab | ||
|
|
e373c03b2a | ||
|
|
99c13923ea | ||
|
|
80cb503c48 | ||
|
|
107efba6f3 | ||
|
|
239bab38ca | ||
|
|
e952b479ac | ||
|
|
231ac2bbb9 | ||
|
|
58543cacc8 | ||
|
|
8582e360b5 | ||
|
|
0e919f9992 | ||
|
|
b0a5003eaa | ||
|
|
6c0d8d5bda | ||
|
|
302f25054a | ||
|
|
82c88ca654 | ||
|
|
b9b7dcb264 | ||
|
|
90d5612548 | ||
|
|
e4583ed752 | ||
|
|
20dace2679 | ||
|
|
bc7231fb00 | ||
|
|
270daf1356 |
@@ -1,8 +0,0 @@
|
||||
steps:
|
||||
- label: ":eslint: Lint"
|
||||
command:
|
||||
- "yarn install"
|
||||
- "yarn lint"
|
||||
plugins:
|
||||
- docker#v3.0.1:
|
||||
image: "node:10"
|
||||
13
.eslintrc.js
13
.eslintrc.js
@@ -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",
|
||||
|
||||
306
CHANGELOG.md
306
CHANGELOG.md
@@ -1,3 +1,307 @@
|
||||
Changes in [1.7.31](https://github.com/vector-im/element-desktop/releases/tag/v1.7.31) (2021-06-21)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.31-rc.1...v1.7.31)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.31-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.31-rc.1) (2021-06-15)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.30...v1.7.31-rc.1)
|
||||
|
||||
* Upgrade to Electron 12.0.11
|
||||
[\#211](https://github.com/vector-im/element-desktop/pull/211)
|
||||
* Translations update from Weblate
|
||||
[\#214](https://github.com/vector-im/element-desktop/pull/214)
|
||||
* Upgrade to Node 14
|
||||
[\#212](https://github.com/vector-im/element-desktop/pull/212)
|
||||
* Bump npm-registry-fetch from 4.0.2 to 4.0.7
|
||||
[\#210](https://github.com/vector-im/element-desktop/pull/210)
|
||||
* Update electron-builder for Node 16 compatibility
|
||||
[\#204](https://github.com/vector-im/element-desktop/pull/204)
|
||||
* Bump hosted-git-info from 2.8.5 to 2.8.9
|
||||
[\#209](https://github.com/vector-im/element-desktop/pull/209)
|
||||
* Bump glob-parent from 5.1.1 to 5.1.2
|
||||
[\#206](https://github.com/vector-im/element-desktop/pull/206)
|
||||
* Bump dot-prop from 4.2.0 to 4.2.1
|
||||
[\#208](https://github.com/vector-im/element-desktop/pull/208)
|
||||
* Bump y18n from 3.2.1 to 3.2.2
|
||||
[\#207](https://github.com/vector-im/element-desktop/pull/207)
|
||||
* Bump normalize-url from 4.5.0 to 4.5.1
|
||||
[\#205](https://github.com/vector-im/element-desktop/pull/205)
|
||||
* Put Preferences menu item in correct location on macOS
|
||||
[\#200](https://github.com/vector-im/element-desktop/pull/200)
|
||||
* Switch zoomIn accelerator to default
|
||||
[\#202](https://github.com/vector-im/element-desktop/pull/202)
|
||||
|
||||
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)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.26-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.26-rc.1) (2021-04-21)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.25...v1.7.26-rc.1)
|
||||
|
||||
* Remove Debian dependency libappindicator3-1
|
||||
[\#170](https://github.com/vector-im/element-desktop/pull/170)
|
||||
* Fix exit shortcuts for non QWERTY keyboards
|
||||
[\#185](https://github.com/vector-im/element-desktop/pull/185)
|
||||
* Fix using yarn run fetch with a specific version
|
||||
[\#182](https://github.com/vector-im/element-desktop/pull/182)
|
||||
* Switch nightly to not-staging Scalar by default
|
||||
[\#181](https://github.com/vector-im/element-desktop/pull/181)
|
||||
|
||||
Changes in [1.7.25](https://github.com/vector-im/element-desktop/releases/tag/v1.7.25) (2021-04-12)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.25-rc.1...v1.7.25)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.25-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.25-rc.1) (2021-04-07)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.24...v1.7.25-rc.1)
|
||||
|
||||
* Fix disabling spellchecker
|
||||
[\#179](https://github.com/vector-im/element-desktop/pull/179)
|
||||
* Upgrade to Electron 12.0.2
|
||||
[\#178](https://github.com/vector-im/element-desktop/pull/178)
|
||||
* Avoid exit listener to hijack other application shortcuts
|
||||
[\#177](https://github.com/vector-im/element-desktop/pull/177)
|
||||
* Migrate native-node-modules docs to element-desktop
|
||||
[\#176](https://github.com/vector-im/element-desktop/pull/176)
|
||||
* Add prompt to warn before quitting the application
|
||||
[\#173](https://github.com/vector-im/element-desktop/pull/173)
|
||||
* Upgrade to Electron 11.4.1
|
||||
[\#172](https://github.com/vector-im/element-desktop/pull/172)
|
||||
* Fix docker:build:native documentation typo
|
||||
[\#174](https://github.com/vector-im/element-desktop/pull/174)
|
||||
|
||||
Changes in [1.7.24](https://github.com/vector-im/element-desktop/releases/tag/v1.7.24) (2021-03-29)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.24-rc.1...v1.7.24)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.24-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.24-rc.1) (2021-03-25)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.23...v1.7.24-rc.1)
|
||||
|
||||
* No changes since 1.7.23
|
||||
|
||||
Changes in [1.7.23](https://github.com/vector-im/element-desktop/releases/tag/v1.7.23) (2021-03-15)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.23-rc.1...v1.7.23)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.23-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.23-rc.1) (2021-03-11)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.22...v1.7.23-rc.1)
|
||||
|
||||
* Fix disabling spell-checker
|
||||
[\#171](https://github.com/vector-im/element-desktop/pull/171)
|
||||
* Add multi language spell check
|
||||
[\#154](https://github.com/vector-im/element-desktop/pull/154)
|
||||
|
||||
Changes in [1.7.22](https://github.com/vector-im/element-desktop/releases/tag/v1.7.22) (2021-03-01)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.22-rc.1...v1.7.22)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.22-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.22-rc.1) (2021-02-24)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.21...v1.7.22-rc.1)
|
||||
|
||||
* Disable Countly
|
||||
[\#169](https://github.com/vector-im/element-desktop/pull/169)
|
||||
* Upgrade to Electron 11.2.3
|
||||
[\#168](https://github.com/vector-im/element-desktop/pull/168)
|
||||
|
||||
Changes in [1.7.21](https://github.com/vector-im/element-desktop/releases/tag/v1.7.21) (2021-02-16)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.21-rc.1...v1.7.21)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.21-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.21-rc.1) (2021-02-10)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.20...v1.7.21-rc.1)
|
||||
|
||||
* Fix desktop Matrix screen sharing
|
||||
[\#161](https://github.com/vector-im/element-desktop/pull/161)
|
||||
|
||||
Changes in [1.7.20](https://github.com/vector-im/element-desktop/releases/tag/v1.7.20) (2021-02-04)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.19...v1.7.20)
|
||||
|
||||
* No changes since 1.7.19
|
||||
|
||||
Changes in [1.7.19](https://github.com/vector-im/element-desktop/releases/tag/v1.7.19) (2021-02-03)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.19-rc.1...v1.7.19)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.19-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.19-rc.1) (2021-01-29)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.18...v1.7.19-rc.1)
|
||||
|
||||
* Remove Buildkite pipeline file
|
||||
[\#167](https://github.com/vector-im/element-desktop/pull/167)
|
||||
* Upgrade deps 2021-01-18
|
||||
[\#166](https://github.com/vector-im/element-desktop/pull/166)
|
||||
* package: Bump our seshat version
|
||||
[\#164](https://github.com/vector-im/element-desktop/pull/164)
|
||||
* Enable context isolation, bridge expected IPC
|
||||
[\#163](https://github.com/vector-im/element-desktop/pull/163)
|
||||
|
||||
Changes in [1.7.18](https://github.com/vector-im/element-desktop/releases/tag/v1.7.18) (2021-01-26)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.17...v1.7.18)
|
||||
|
||||
* No changes since 1.7.17
|
||||
|
||||
Changes in [1.7.17](https://github.com/vector-im/element-desktop/releases/tag/v1.7.17) (2021-01-18)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.17-rc.1...v1.7.17)
|
||||
|
||||
* [Release] package: Bump our seshat version
|
||||
[\#165](https://github.com/vector-im/element-desktop/pull/165)
|
||||
|
||||
Changes in [1.7.17-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.17-rc.1) (2021-01-13)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.16...v1.7.17-rc.1)
|
||||
|
||||
* package: Bump our Seshat version
|
||||
[\#162](https://github.com/vector-im/element-desktop/pull/162)
|
||||
* Upgrade to Electron 10.2.0
|
||||
[\#159](https://github.com/vector-im/element-desktop/pull/159)
|
||||
|
||||
Changes in [1.7.16](https://github.com/vector-im/element-desktop/releases/tag/v1.7.16) (2020-12-21)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.16-rc.1...v1.7.16)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.16-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.16-rc.1) (2020-12-16)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.15...v1.7.16-rc.1)
|
||||
|
||||
* Bump ini from 1.3.5 to 1.3.8
|
||||
[\#158](https://github.com/vector-im/element-desktop/pull/158)
|
||||
* Add gitter.im to room directory
|
||||
[\#157](https://github.com/vector-im/element-desktop/pull/157)
|
||||
|
||||
Changes in [1.7.15](https://github.com/vector-im/element-desktop/releases/tag/v1.7.15) (2020-12-07)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.15-rc.1...v1.7.15)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.15-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.15-rc.1) (2020-12-02)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.14...v1.7.15-rc.1)
|
||||
|
||||
* No changes since 1.7.14
|
||||
|
||||
Changes in [1.7.14](https://github.com/vector-im/element-desktop/releases/tag/v1.7.14) (2020-11-23)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.14-rc.1...v1.7.14)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.14-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.14-rc.1) (2020-11-18)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.13...v1.7.14-rc.1)
|
||||
|
||||
* Correct spelling mistakes
|
||||
[\#151](https://github.com/vector-im/element-desktop/pull/151)
|
||||
|
||||
Changes in [1.7.13](https://github.com/vector-im/element-desktop/releases/tag/v1.7.13) (2020-11-09)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.13-rc.1...v1.7.13)
|
||||
|
||||
* No changes since rc.1
|
||||
|
||||
Changes in [1.7.13-rc.1](https://github.com/vector-im/element-desktop/releases/tag/v1.7.13-rc.1) (2020-11-04)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.12...v1.7.13-rc.1)
|
||||
|
||||
* Add countly experiment to develop/nightly configs
|
||||
[\#150](https://github.com/vector-im/element-desktop/pull/150)
|
||||
|
||||
Changes in [1.7.12](https://github.com/vector-im/element-desktop/releases/tag/v1.7.12) (2020-10-28)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.11...v1.7.12)
|
||||
@@ -383,7 +687,7 @@ Changes in [1.6.0-rc.1](https://github.com/vector-im/riot-desktop/releases/tag/v
|
||||
[\#57](https://github.com/vector-im/riot-desktop/pull/57)
|
||||
* Remove welcome user from config
|
||||
[\#56](https://github.com/vector-im/riot-desktop/pull/56)
|
||||
* electron-main: Immediatelly set the eventIndex variable to null when
|
||||
* electron-main: Immediately set the eventIndex variable to null when
|
||||
closing.
|
||||
[\#55](https://github.com/vector-im/riot-desktop/pull/55)
|
||||
* Enable Seshat on Nightly
|
||||
|
||||
13
README.md
13
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:
|
||||
|
||||
@@ -96,7 +96,7 @@ yarn run docker:setup
|
||||
|
||||
yarn run docker:install
|
||||
# if you want to build the native modules (this will take a while)
|
||||
yarn run docker:buildnative
|
||||
yarn run docker:build:native
|
||||
yarn run docker:build
|
||||
```
|
||||
|
||||
@@ -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
|
||||
==========================
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ ENV LC_ALL C.UTF-8
|
||||
|
||||
ENV DEBUG_COLORS true
|
||||
ENV FORCE_COLOR true
|
||||
ENV NODE_VERSION 12.16.1
|
||||
ENV NODE_VERSION 14.17.0
|
||||
|
||||
# this package is used for snapcraft and we should not clear apt list - to avoid apt-get update during snap build
|
||||
RUN curl -L https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz | tar xz -C /usr/local --strip-components=1 && \
|
||||
|
||||
61
docs/native-node-modules.md
Normal file
61
docs/native-node-modules.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Native Node Modules
|
||||
|
||||
For some features, the desktop version of Element can make use of native Node
|
||||
modules. These allow Element to integrate with the desktop in ways that a browser
|
||||
cannot.
|
||||
|
||||
While native modules enable powerful new features, they must be complied for
|
||||
each operating system. For official Element releases, we will always build these
|
||||
modules from source to ensure we can trust the compiled output. In the future,
|
||||
we may offer a pre-compiled path for those who want to use these features in a
|
||||
custom build of Element without installing the various build tools required.
|
||||
|
||||
Do note that compiling a module for a particular operating system
|
||||
(Linux/macOS/Windows) will need to be done on that operating system.
|
||||
Cross-compiling from a host OS for a different target OS may be possible, but
|
||||
we don't support this flow with Element dependencies at this time.
|
||||
|
||||
The process is automated by [vector-im/element-builder](https://github.com/vector-im/element-builder)
|
||||
when releasing.
|
||||
The following sections explain the manual steps you can use with a custom build of Element to enable
|
||||
these features if you'd like to try them out.
|
||||
It is possible to [build those native modules locally automatically](https://github.com/vector-im/element-desktop#building).
|
||||
|
||||
```
|
||||
yarn run build:native
|
||||
```
|
||||
## Adding Seshat for search in E2E encrypted rooms
|
||||
|
||||
Seshat is a native Node module that adds support for local event indexing and
|
||||
full text search in E2E encrypted rooms.
|
||||
|
||||
Since Seshat is written in Rust, the Rust compiler and related tools need to be
|
||||
installed before installing Seshat itself. To install Rust please consult the
|
||||
official Rust [documentation](https://www.rust-lang.org/tools/install).
|
||||
|
||||
Seshat also depends on the SQLCipher library to store its data in encrypted form
|
||||
on disk. You'll need to install it via your OS package manager.
|
||||
|
||||
After installing the Rust compiler and SQLCipher, Seshat support can be added
|
||||
using yarn at the root of this project:
|
||||
|
||||
yarn add matrix-seshat
|
||||
|
||||
You will have to rebuild the native libraries against electron's version of
|
||||
of node rather than your system node, using the `electron-build-env` tool.
|
||||
This is also needed to when pulling in changes to Seshat using `yarn link`.
|
||||
|
||||
yarn add electron-build-env
|
||||
|
||||
Recompiling Seshat itself can be done like so:
|
||||
|
||||
yarn run electron-build-env -- --electron 6.1.1 -- neon build matrix-seshat --release
|
||||
|
||||
Please make sure to include all the `--` as well as the `--release` command line
|
||||
switch at the end. Modify your electron version accordingly depending on the
|
||||
version that is installed on your system.
|
||||
|
||||
After this is done the Electron version of Element can be run from the main folder
|
||||
as usual using:
|
||||
|
||||
yarn start
|
||||
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,8 +2,8 @@
|
||||
"update_base_url": "https://packages.riot.im/nightly/update/",
|
||||
"default_server_name": "matrix.org",
|
||||
"brand": "Element Nightly",
|
||||
"integrations_ui_url": "https://scalar-staging.vector.im/",
|
||||
"integrations_rest_url": "https://scalar-staging.vector.im/api",
|
||||
"integrations_ui_url": "https://scalar.vector.im/",
|
||||
"integrations_rest_url": "https://scalar.vector.im/api",
|
||||
"integrations_widgets_urls": [
|
||||
"https://scalar.vector.im/_matrix/integrations/v1",
|
||||
"https://scalar.vector.im/api",
|
||||
@@ -21,7 +21,8 @@
|
||||
},
|
||||
"roomDirectory": {
|
||||
"servers": [
|
||||
"matrix.org"
|
||||
"matrix.org",
|
||||
"gitter.im"
|
||||
]
|
||||
},
|
||||
"enable_presence_by_hs_url": {
|
||||
|
||||
@@ -3,7 +3,8 @@ License: Apache-2.0
|
||||
Vendor: support@element.io
|
||||
Architecture: amd64
|
||||
Maintainer: support@element.io
|
||||
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libappindicator3-1, libsecret-1-0, libsqlcipher0
|
||||
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0, libsqlcipher0
|
||||
Recommends: libappindicator3-1
|
||||
Section: net
|
||||
Priority: extra
|
||||
Homepage: https://element.io/
|
||||
|
||||
@@ -15,7 +15,8 @@
|
||||
"bug_report_endpoint_url": "https://element.io/bugreports/submit",
|
||||
"roomDirectory": {
|
||||
"servers": [
|
||||
"matrix.org"
|
||||
"matrix.org",
|
||||
"gitter.im"
|
||||
]
|
||||
},
|
||||
"showLabsSettings": false,
|
||||
|
||||
@@ -3,7 +3,8 @@ License: Apache-2.0
|
||||
Vendor: support@element.io
|
||||
Architecture: amd64
|
||||
Maintainer: support@element.io
|
||||
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libappindicator3-1, libsecret-1-0, libsqlcipher0
|
||||
Depends: libgtk-3-0, libnotify4, libnss3, libxss1, libxtst6, xdg-utils, libatspi2.0-0, libuuid1, libsecret-1-0, libsqlcipher0
|
||||
Recommends: libappindicator3-1
|
||||
Replaces: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0)
|
||||
Breaks: riot-desktop (<< 1.7.0), riot-web (<< 1.7.0)
|
||||
Section: net
|
||||
|
||||
42
package.json
42
package.json
@@ -2,16 +2,19 @@
|
||||
"name": "element-desktop",
|
||||
"productName": "Element",
|
||||
"main": "src/electron-main.js",
|
||||
"version": "1.7.12",
|
||||
"version": "1.7.31",
|
||||
"description": "A feature-rich client for Matrix.org",
|
||||
"author": "Element",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/vector-im/riot-desktop"
|
||||
"url": "https://github.com/vector-im/element-desktop"
|
||||
},
|
||||
"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",
|
||||
@@ -21,7 +24,7 @@
|
||||
"build32": "electron-builder --ia32",
|
||||
"build64": "electron-builder --x64",
|
||||
"build": "electron-builder",
|
||||
"docker:setup": "docker build -t riot-desktop-dockerbuild dockerbuild",
|
||||
"docker:setup": "docker build -t element-desktop-dockerbuild dockerbuild",
|
||||
"docker:build:native": "scripts/in-docker.sh yarn run hak",
|
||||
"docker:build": "scripts/in-docker.sh yarn run build",
|
||||
"docker:install": "scripts/in-docker.sh yarn install",
|
||||
@@ -30,39 +33,42 @@
|
||||
"hak": "node scripts/hak/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"auto-launch": "^5.0.1",
|
||||
"electron-store": "^2.0.0",
|
||||
"electron-window-state": "^4.1.0",
|
||||
"auto-launch": "^5.0.5",
|
||||
"counterpart": "^0.18.6",
|
||||
"electron-store": "^6.0.1",
|
||||
"electron-window-state": "^5.0.3",
|
||||
"minimist": "^1.2.3",
|
||||
"png-to-ico": "^2.1.0",
|
||||
"png-to-ico": "^2.1.1",
|
||||
"request": "^2.88.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"asar": "^2.0.1",
|
||||
"electron-builder": "^22.7.0",
|
||||
"electron-builder-squirrel-windows": "^22.7.0",
|
||||
"electron-devtools-installer": "^2.2.4",
|
||||
"electron-notarize": "^0.2.0",
|
||||
"eslint": "7.3.1",
|
||||
"eslint-config-matrix-org": "^0.1.2",
|
||||
"electron-builder": "22.11.4",
|
||||
"electron-builder-squirrel-windows": "22.11.4",
|
||||
"electron-devtools-installer": "^3.1.1",
|
||||
"electron-notarize": "^1.0.0",
|
||||
"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",
|
||||
"npm": "^6.14.6",
|
||||
"npm": "^6.14.11",
|
||||
"rimraf": "^3.0.2",
|
||||
"semver": "^7.1.3",
|
||||
"tar": "^6.0.1"
|
||||
"semver": "^7.3.4",
|
||||
"tar": "^6.1.0"
|
||||
},
|
||||
"hakDependencies": {
|
||||
"matrix-seshat": "^2.2.1",
|
||||
"matrix-seshat": "^2.2.3",
|
||||
"keytar": "^5.6.0"
|
||||
},
|
||||
"build": {
|
||||
"appId": "im.riot.app",
|
||||
"electronVersion": "10.1.3",
|
||||
"electronVersion": "12.0.11",
|
||||
"files": [
|
||||
"package.json",
|
||||
{
|
||||
|
||||
@@ -11,11 +11,11 @@ const needle = require('needle');
|
||||
|
||||
const riotDesktopPackageJson = require('../package.json');
|
||||
|
||||
const PUB_KEY_URL = "https://packages.riot.im/riot-release-key.asc";
|
||||
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, setDebVersion} = require('./set-version.js');
|
||||
const { setPackageVersion } = require('./set-version.js');
|
||||
|
||||
async function getLatestDevelopUrl(bkToken) {
|
||||
const buildsResult = await needle('get',
|
||||
@@ -55,7 +55,7 @@ async function getLatestDevelopUrl(bkToken) {
|
||||
let dlUrl;
|
||||
let dlFilename;
|
||||
for (const artifact of artifactsResult.body) {
|
||||
if (artifact.filename && /^riot-.*\.tar.gz$/.test(artifact.filename)) {
|
||||
if (artifact.filename && /^element-.*\.tar.gz$/.test(artifact.filename)) {
|
||||
dlUrl = artifact.download_url;
|
||||
dlFilename = artifact.filename;
|
||||
break;
|
||||
@@ -149,7 +149,7 @@ async function main() {
|
||||
|
||||
if (targetVersion === undefined) {
|
||||
targetVersion = 'v' + riotDesktopPackageJson.version;
|
||||
filename = 'riot-' + targetVersion + '.tar.gz';
|
||||
filename = 'element-' + targetVersion + '.tar.gz';
|
||||
url = PACKAGE_URL_PREFIX + targetVersion + '/' + filename;
|
||||
} else if (targetVersion === 'develop') {
|
||||
const buildKiteApiKey = process.env.BUILDKITE_API_KEY;
|
||||
@@ -164,7 +164,7 @@ async function main() {
|
||||
[filename, url] = await getLatestDevelopUrl(buildKiteApiKey);
|
||||
verify = false; // develop builds aren't signed
|
||||
} else {
|
||||
filename = 'riot-' + targetVersion + '.tar.gz';
|
||||
filename = 'element-' + targetVersion + '.tar.gz';
|
||||
url = PACKAGE_URL_PREFIX + targetVersion + '/' + filename;
|
||||
setVersion = true;
|
||||
}
|
||||
@@ -283,7 +283,6 @@ async function main() {
|
||||
const semVer = targetVersion.slice(1);
|
||||
console.log("Updating version to " + semVer);
|
||||
await setPackageVersion(semVer);
|
||||
await setDebVersion(semVer);
|
||||
}
|
||||
|
||||
console.log("Done!");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
docker inspect riot-desktop-dockerbuild 2> /dev/null > /dev/null
|
||||
docker inspect element-desktop-dockerbuild 2> /dev/null > /dev/null
|
||||
if [ $? != 0 ]; then
|
||||
echo "Docker image riot-desktop-dockerbuild not found. Have you run yarn run docker:setup?"
|
||||
echo "Docker image element-desktop-dockerbuild not found. Have you run yarn run docker:setup?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -17,4 +17,4 @@ docker run --rm -ti \
|
||||
-v ${PWD}/docker/.gnupg:/root/.gnupg \
|
||||
-v ~/.cache/electron:/root/.cache/electron \
|
||||
-v ~/.cache/electron-builder:/root/.cache/electron-builder \
|
||||
riot-desktop-dockerbuild "$@"
|
||||
element-desktop-dockerbuild "$@"
|
||||
|
||||
@@ -22,10 +22,10 @@ cp $confdir/conf_distributions $repodir/conf/distributions
|
||||
pushd $repodir
|
||||
for i in `cat conf/distributions | grep Codename | cut -d ' ' -f 2`
|
||||
do
|
||||
reprepro includedeb $i $distdir/riot-desktop_${ver}_amd64.deb
|
||||
reprepro includedeb $i $distdir/element-desktop_${ver}_amd64.deb
|
||||
done
|
||||
|
||||
tar cvzf $distdir/riot-desktop_repo_$ver.tar.gz .
|
||||
tar cvzf $distdir/element-desktop_repo_$ver.tar.gz .
|
||||
|
||||
popd
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/*
|
||||
Copyright 2016 Aviral Dasgupta
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2018, 2019 New Vector Ltd
|
||||
Copyright 2017, 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2018 - 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.
|
||||
@@ -25,18 +24,20 @@ const checkSquirrelHooks = require('./squirrelhooks');
|
||||
if (checkSquirrelHooks()) return;
|
||||
|
||||
const argv = require('minimist')(process.argv, {
|
||||
alias: {help: "h"},
|
||||
alias: { help: "h" },
|
||||
});
|
||||
|
||||
const {app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol} = require('electron');
|
||||
const {
|
||||
app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol, dialog,
|
||||
} = require('electron');
|
||||
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');
|
||||
@@ -56,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;
|
||||
@@ -85,6 +86,7 @@ let vectorConfig;
|
||||
let iconPath;
|
||||
let trayConfig;
|
||||
let launcher;
|
||||
let appLocalization;
|
||||
|
||||
if (argv["help"]) {
|
||||
console.log("Options:");
|
||||
@@ -182,7 +184,7 @@ async function setupGlobals() {
|
||||
vectorConfig = require(asarPath + 'config.json');
|
||||
} catch (e) {
|
||||
// it would be nice to check the error code here and bail if the config
|
||||
// is unparseable, but we get MODULE_NOT_FOUND in the case of a missing
|
||||
// is unparsable, but we get MODULE_NOT_FOUND in the case of a missing
|
||||
// file or invalid json, so node is just very unhelpful.
|
||||
// Continue with the defaults (ie. an empty config)
|
||||
vectorConfig = {};
|
||||
@@ -254,6 +256,30 @@ let eventIndex = null;
|
||||
let mainWindow = null;
|
||||
global.appQuitting = false;
|
||||
|
||||
const exitShortcuts = [
|
||||
(input, platform) => platform !== 'darwin' && input.alt && input.key.toUpperCase() === 'F4',
|
||||
(input, platform) => platform !== 'darwin' && input.control && input.key.toUpperCase() === 'Q',
|
||||
(input, platform) => platform === 'darwin' && input.meta && input.key.toUpperCase() === 'Q',
|
||||
];
|
||||
|
||||
const warnBeforeExit = (event, input) => {
|
||||
const shouldWarnBeforeExit = store.get('warnBeforeExit', true);
|
||||
const exitShortcutPressed = exitShortcuts.some(shortcutFn => shortcutFn(input, process.platform));
|
||||
|
||||
if (shouldWarnBeforeExit && exitShortcutPressed) {
|
||||
const shouldCancelCloseRequest = dialog.showMessageBoxSync(mainWindow, {
|
||||
type: "question",
|
||||
buttons: [_t("Cancel"), _t("Close Element")],
|
||||
message: _t("Are you sure you want to quit?"),
|
||||
defaultId: 1,
|
||||
cancelId: 0,
|
||||
}) === 0;
|
||||
|
||||
if (shouldCancelCloseRequest) {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const deleteContents = async (p) => {
|
||||
for (const entry of await afs.readdir(p)) {
|
||||
@@ -341,6 +367,15 @@ 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;
|
||||
case 'setWarnBeforeExit':
|
||||
store.set('warnBeforeExit', args[0]);
|
||||
break;
|
||||
case 'getMinimizeToTrayEnabled':
|
||||
ret = tray.hasTray();
|
||||
break;
|
||||
@@ -386,50 +421,32 @@ ipcMain.on('ipcCall', async function(ev, payload) {
|
||||
mainWindow.webContents.goForward();
|
||||
}
|
||||
break;
|
||||
case 'setLanguage': {
|
||||
// work around `setSpellCheckerLanguages` being case-sensitive by converting to expected case
|
||||
const caseMap = {};
|
||||
const availableLanguages = mainWindow.webContents.session.availableSpellCheckerLanguages;
|
||||
availableLanguages.forEach(lang => {
|
||||
caseMap[lang.toLowerCase()] = lang;
|
||||
});
|
||||
case 'setSpellCheckLanguages':
|
||||
if (args[0] && args[0].length > 0) {
|
||||
mainWindow.webContents.session.setSpellCheckerEnabled(true);
|
||||
store.set("spellCheckerEnabled", true);
|
||||
|
||||
if (!caseMap["en"]) {
|
||||
// default special-case for `en` as in Riot is actually implies `en-GB`. `en-US` is distinct.
|
||||
// this way if `en` is requested and not available and `en-GB` is available it'll be used.
|
||||
caseMap["en"] = caseMap["en-gb"];
|
||||
}
|
||||
|
||||
const languages = new Set();
|
||||
args[0].forEach(lang => {
|
||||
const lcLang = lang.toLowerCase();
|
||||
if (caseMap[lcLang]) {
|
||||
languages.add(caseMap[lcLang]);
|
||||
return;
|
||||
try {
|
||||
mainWindow.webContents.session.setSpellCheckerLanguages(args[0]);
|
||||
} catch (er) {
|
||||
console.log("There were problems setting the spellcheck languages", er);
|
||||
}
|
||||
|
||||
// as a fallback if the language is unknown check if the language group is known, e.g en for en-AU
|
||||
const langGroup = lcLang.split("-")[0];
|
||||
if (caseMap[langGroup]) {
|
||||
languages.add(caseMap[langGroup]);
|
||||
return;
|
||||
}
|
||||
|
||||
// as a further fallback, pick all other matching variants from the same language group
|
||||
// this means that if we cannot find `ar-dz` or `ar` for example, we will pick `ar-*` to
|
||||
// offer a spellcheck which is least likely to wrongly red underline something.
|
||||
availableLanguages.forEach(availableLang => {
|
||||
if (availableLang.startsWith(langGroup)) {
|
||||
languages.add(availableLang);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (languages.size > 0) {
|
||||
mainWindow.webContents.session.setSpellCheckerLanguages([...languages]);
|
||||
} else {
|
||||
mainWindow.webContents.session.setSpellCheckerEnabled(false);
|
||||
store.set("spellCheckerEnabled", false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'getSpellCheckLanguages':
|
||||
if (store.get("spellCheckerEnabled", true)) {
|
||||
ret = mainWindow.webContents.session.getSpellCheckerLanguages();
|
||||
} else {
|
||||
ret = [];
|
||||
}
|
||||
break;
|
||||
case 'getAvailableSpellCheckLanguages':
|
||||
ret = mainWindow.webContents.session.availableSpellCheckerLanguages;
|
||||
break;
|
||||
|
||||
case 'startSSOFlow':
|
||||
recordSSOSession(args[0]);
|
||||
break;
|
||||
@@ -482,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;
|
||||
|
||||
@@ -510,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;
|
||||
}
|
||||
@@ -809,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();
|
||||
@@ -839,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;
|
||||
}
|
||||
|
||||
@@ -857,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;
|
||||
}
|
||||
|
||||
@@ -869,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;
|
||||
}
|
||||
|
||||
@@ -879,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);
|
||||
@@ -922,17 +918,15 @@ app.on('ready', async () => {
|
||||
nodeIntegration: false,
|
||||
//sandbox: true, // We enable sandboxing from app.enableSandbox() above
|
||||
enableRemoteModule: false,
|
||||
// We don't use this: it's useful for the preload script to
|
||||
// share a context with the main page so we can give select
|
||||
// objects to the main page. The sandbox option isolates the
|
||||
// main page from the background script.
|
||||
contextIsolation: false,
|
||||
contextIsolation: true,
|
||||
webgl: false,
|
||||
spellcheck: true,
|
||||
},
|
||||
});
|
||||
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
|
||||
mainWindow.webContents.session.setSpellCheckerEnabled(store.get("spellCheckerEnabled", true));
|
||||
|
||||
// Create trayIcon icon
|
||||
if (store.get('minimizeToTray', true)) tray.create(trayConfig);
|
||||
@@ -948,17 +942,27 @@ app.on('ready', async () => {
|
||||
}
|
||||
});
|
||||
|
||||
mainWindow.webContents.on('before-input-event', warnBeforeExit);
|
||||
|
||||
mainWindow.on('closed', () => {
|
||||
mainWindow = global.mainWindow = null;
|
||||
});
|
||||
mainWindow.on('close', (e) => {
|
||||
mainWindow.on('close', async (e) => {
|
||||
// If we are not quitting and have a tray icon then minimize to tray
|
||||
if (!global.appQuitting && (tray.hasTray() || process.platform === 'darwin')) {
|
||||
// On Mac, closing the window just hides it
|
||||
// (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;
|
||||
}
|
||||
});
|
||||
@@ -975,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
12
src/i18n/strings/ar.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"File": "مَلَفّ",
|
||||
"Close": "إغلاق",
|
||||
"Actual Size": "الحَجمُ الفِعلي",
|
||||
"View": "الاِطِّلاع",
|
||||
"Select All": "تَحدِيدُ الكُل",
|
||||
"Delete": "حَذف",
|
||||
"Copy": "نَسخ",
|
||||
"Edit": "تَحرير",
|
||||
"Close Element": "إغلَاقُ Element",
|
||||
"Cancel": "إلغَاء"
|
||||
}
|
||||
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"
|
||||
}
|
||||
13
src/i18n/strings/hr.json
Normal file
13
src/i18n/strings/hr.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"Paste": "Zalijepiti",
|
||||
"Copy": "Kopirati",
|
||||
"Cut": "Izrezati",
|
||||
"Redo": "Preurediti",
|
||||
"Undo": "Poništi",
|
||||
"Edit": "Uredi",
|
||||
"Quit": "Prestati",
|
||||
"Show/Hide": "Pokaži/sakrij",
|
||||
"Are you sure you want to quit?": "Jesi li siguran da želiš odustati?",
|
||||
"Close Element": "Zatvori Element",
|
||||
"Cancel": "Otkazati"
|
||||
}
|
||||
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"
|
||||
}
|
||||
46
src/i18n/strings/is.json
Normal file
46
src/i18n/strings/is.json
Normal 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
46
src/i18n/strings/it.json
Normal 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"
|
||||
}
|
||||
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/pt_BR.json
Normal file
46
src/i18n/strings/pt_BR.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"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": "Visualizar",
|
||||
"Select All": "Selecionar Todas",
|
||||
"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 você quer sair?",
|
||||
"Close Element": "Fechar Element",
|
||||
"Cancel": "Cancelar",
|
||||
"Bring All to Front": "Trazer Todas Para Frente",
|
||||
"Hide Others": "Esconder Outras(os)"
|
||||
}
|
||||
1
src/i18n/strings/ro.json
Normal file
1
src/i18n/strings/ro.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
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": "Вставить с тем же стилем"
|
||||
}
|
||||
46
src/i18n/strings/sv.json
Normal file
46
src/i18n/strings/sv.json
Normal 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?"
|
||||
}
|
||||
46
src/i18n/strings/zh_Hans.json
Normal file
46
src/i18n/strings/zh_Hans.json
Normal 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
128
src/language-helper.js
Normal 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,
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2018, 2019 New Vector Ltd
|
||||
Copyright 2018, 2019, 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.
|
||||
@@ -14,7 +14,58 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
const { ipcRenderer } = require('electron');
|
||||
const { ipcRenderer, desktopCapturer, contextBridge } = require('electron');
|
||||
|
||||
// expose ipcRenderer to the renderer process
|
||||
window.ipcRenderer = ipcRenderer;
|
||||
// Expose only expected IPC wrapper APIs to the renderer process to avoid
|
||||
// handing out generalised messaging access.
|
||||
|
||||
const CHANNELS = [
|
||||
"app_onAction",
|
||||
"before-quit",
|
||||
"check_updates",
|
||||
"install_update",
|
||||
"ipcCall",
|
||||
"ipcReply",
|
||||
"loudNotification",
|
||||
"preferences",
|
||||
"seshat",
|
||||
"seshatReply",
|
||||
"setBadgeCount",
|
||||
"update-downloaded",
|
||||
"userDownloadCompleted",
|
||||
"userDownloadOpen",
|
||||
];
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
"electron",
|
||||
{
|
||||
on(channel, listener) {
|
||||
if (!CHANNELS.includes(channel)) {
|
||||
console.error(`Unknown IPC channel ${channel} ignored`);
|
||||
return;
|
||||
}
|
||||
ipcRenderer.on(channel, listener);
|
||||
},
|
||||
send(channel, ...args) {
|
||||
if (!CHANNELS.includes(channel)) {
|
||||
console.error(`Unknown IPC channel ${channel} ignored`);
|
||||
return;
|
||||
}
|
||||
ipcRenderer.send(channel, ...args);
|
||||
},
|
||||
async getDesktopCapturerSources(options) {
|
||||
const sources = await desktopCapturer.getSources(options);
|
||||
const desktopCapturerSources = [];
|
||||
|
||||
for (const source of sources) {
|
||||
desktopCapturerSources.push({
|
||||
id: source.id,
|
||||
name: source.name,
|
||||
thumbnailURL: source.thumbnail.toDataURL(),
|
||||
});
|
||||
}
|
||||
|
||||
return desktopCapturerSources;
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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");
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
64
src/tray.js
64
src/tray.js
@@ -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;
|
||||
|
||||
@@ -14,130 +14,220 @@ 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'); },
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const isMac = process.platform === 'darwin';
|
||||
|
||||
// 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',
|
||||
label: _t('Zoom In'),
|
||||
},
|
||||
{
|
||||
role: 'zoomout',
|
||||
label: _t('Zoom Out'),
|
||||
},
|
||||
{ type: 'separator' },
|
||||
// in macOS the Preferences menu item goes in the first menu
|
||||
...(!isMac ? [{
|
||||
label: _t('Preferences'),
|
||||
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 (isMac) {
|
||||
template.unshift({
|
||||
// first macOS menu is the name of the app
|
||||
role: 'appMenu',
|
||||
label: app.name,
|
||||
submenu: [
|
||||
{
|
||||
role: 'about',
|
||||
label: _t('About') + ' ' + app.name,
|
||||
},
|
||||
{ type: 'separator' },
|
||||
{
|
||||
label: _t('Preferences') + '…',
|
||||
accelerator: 'Command+,', // Mac-only accelerator
|
||||
click() { global.mainWindow.webContents.send('preferences'); },
|
||||
},
|
||||
{ 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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user