Compare commits

...

133 Commits

Author SHA1 Message Date
RiotRobot
ad337b1f7c v1.7.32 2021-07-05 16:55:20 +01:00
RiotRobot
8d380fe533 Prepare changelog for v1.7.32 2021-07-05 16:55:19 +01:00
David Baker
6e7913c7d1 Merge pull request #224 from vector-im/dbkr/fix_rootdir
Fix the build: make the rootDir correct
2021-07-01 17:33:36 +01:00
David Baker
9cb171f953 Fix the build: make the rootDir correct 2021-07-01 17:18:26 +01:00
David Baker
44310712f3 Merge pull request #223 from vector-im/t3chguy/ts/10
Fix i18n in Element Desktop
2021-07-01 15:51:31 +01:00
Michael Telatynski
9b65962d26 Update scripts/copy-res.js
Co-authored-by: J. Ryan Stinnett <jryans@gmail.com>
2021-07-01 15:48:07 +01:00
Michael Telatynski
8302e284a3 delint 2021-07-01 12:03:38 +01:00
Michael Telatynski
390e2306d0 Fix i18n in Element Desktop 2021-07-01 11:32:09 +01:00
Michael Telatynski
60e61415ea Merge pull request #222 from vector-im/t3chguy/ts/10 2021-07-01 09:26:42 +01:00
Michael Telatynski
f4be51959b disable require lint rule in couple more places 2021-07-01 09:24:02 +01:00
Michael Telatynski
397bc66522 fix ts linting and delint the world 2021-07-01 09:22:57 +01:00
Michael Telatynski
4db0a0ac0c Make eslint happy 2021-07-01 09:16:49 +01:00
Michael Telatynski
d353c68a75 Convert preload.js to Typescript so that it gets copied to lib where we expect it 2021-07-01 09:11:42 +01:00
David Baker
0143b4b114 Merge pull request #221 from vector-im/dbkr/lib_not_src
Bundle the `lib` dir now, not `src`
2021-06-30 19:14:40 +01:00
David Baker
93dd8aa2ba Bbundle the lib dir now, not src 2021-06-30 18:56:48 +01:00
Michael Telatynski
140b0b8c29 Merge pull request #219 from vector-im/t3chguy/ts/d 2021-06-30 17:55:25 +01:00
David Baker
744050d8f4 Electron 12.0.12 2021-06-29 14:16:52 +01:00
David Baker
39f3e3b9c2 Merge pull request #220 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-06-29 14:14:43 +01:00
Weblate
43c8b13d75 Merge branch 'origin/develop' into Weblate. 2021-06-29 13:08:43 +00:00
Michael Telatynski
2d568f9688 iterate ts support 2021-06-29 11:41:08 +01:00
J. Ryan Stinnett
3f49046980 Merge pull request #218 from vector-im/jryans/aarch64-apple-darwin
Fix Windows target arch in native build
2021-06-25 14:36:05 +01:00
Michael Telatynski
53e7100033 Initial Typescripting for Element Desktop 2021-06-25 14:35:58 +01:00
J. Ryan Stinnett
b8cb53e11b Fix Windows target arch in native build 2021-06-25 13:10:08 +01:00
J. Ryan Stinnett
c751470abf Merge pull request #217 from vector-im/jryans/libera-chat
Add libera.chat to default room directory
2021-06-25 11:24:16 +01:00
J. Ryan Stinnett
9860ac6b75 Add libera.chat to default room directory 2021-06-25 10:59:16 +01:00
J. Ryan Stinnett
6e76d658b1 Merge pull request #216 from vector-im/jryans/aarch64-apple-darwin
Add update and native build support for Apple silicon
2021-06-24 15:37:02 +01:00
J. Ryan Stinnett
3aff9cb9eb Add generated file warning 2021-06-24 15:20:24 +01:00
J. Ryan Stinnett
6579ba80b4 More copyright headers 2021-06-24 15:11:57 +01:00
J. Ryan Stinnett
37410e6bc4 Log update URL 2021-06-24 14:45:35 +01:00
J. Ryan Stinnett
b036113786 Revert "Prefer machine's native arch on macOS"
This reverts commit ebcd68428e.
2021-06-24 14:44:59 +01:00
Ridhubharan
c579031afc Translated using Weblate (Tamil)
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ta/
2021-06-23 19:34:45 +00:00
J. Ryan Stinnett
ebcd68428e Prefer machine's native arch on macOS
This uses `uname` to check the machine's native architecture, and tries to
prefer builds for that, rather than continuing to use emulation.
2021-06-23 16:42:00 +01:00
J. Ryan Stinnett
f63436a2cb Send the current arch when updating
This depends on further builder changes to actually place updates at this new
location for both architectures.
2021-06-23 16:18:10 +01:00
J. Ryan Stinnett
c5dd6195f2 Fix copy command log 2021-06-23 16:18:10 +01:00
J. Ryan Stinnett
c3a36bb17d Cross-compile matrix-seshat for aarch64-apple-darwin 2021-06-23 16:18:09 +01:00
J. Ryan Stinnett
f3c1db3313 Cross-compile SQLCipher for aarch64-apple-darwin 2021-06-23 16:18:09 +01:00
J. Ryan Stinnett
c57a173649 Check for Rust host and target support 2021-06-23 16:18:09 +01:00
J. Ryan Stinnett
48dc1ab396 Print rejections that reach the root handler 2021-06-23 16:18:09 +01:00
J. Ryan Stinnett
997f2c21bf Use targets in hak environment for cross-compiling
This arranges the hak environment target info around target IDs that come from
the builder, which simplifies cross-compiling. The `target.js` module is a
generated copy of the builder's `target.ts`.
2021-06-23 16:18:09 +01:00
J. Ryan Stinnett
a171fa417b Borrow target definition from electron-builder
A bit hacky, but for now we paste in the JS generated version of the builder's
`target.ts` module. It's quite unlikely to change often, so this is perhaps
enough for now.
2021-06-23 16:18:09 +01:00
J. Ryan Stinnett
115f25165a Rename hak target to runtime version
The hak environment's `target` is more like a runtime version, so this renames
to call it that, especially since we're about to add more traditional target
strings. `npm_config_target` remains, since that's what `npm` expects.
2021-06-23 16:18:09 +01:00
J. Ryan Stinnett
c1ca909c7c Limit macOS updates to x86_64 temporarily
As a temporary measure, this limits the updater on macOS to only supporting the
`x86_64` / `x64` architecture. This ensures `aarch64` users are not
inadvertently kicked back to `x86_64`.
2021-06-23 16:18:09 +01:00
Travis Ralston
f61370505b Merge pull request #203 from dogancelik/numpad-zoom
Add numpad accelerators for zooming
2021-06-22 19:42:49 -06:00
Travis Ralston
02d0999b18 Merge pull request #201 from aaronraimist/invalid-config
Add warning dialog when custom config.json is invalid
2021-06-22 14:16:24 -06:00
Ridhubharan
5b15bc9b5d Added translation using Weblate (Tamil) 2021-06-22 17:30:41 +00:00
Michael Telatynski
6b4e6f6be6 Merge pull request #215 from alarsyo/develop 2021-06-22 15:43:27 +01:00
Antoine Martin
10a11242ff Don't show Quit warning on keyUp residual event
The warning triggered whenever the app got focus after another window
was closed with a Ctrl+Q shortcut and the keys were then released.

Hitting the 'Close Element' button didn't even close the app in this
case, as only the warning handler was triggered, not the actual quit
shortcut (which does discriminate between key press and key release).

Actually checking for 'keyDown' should prevent this from occurring
again.

Fixes vector-im/element-web#17714

Signed-off-by: Antoine Martin <antoine@alarsyo.net>
2021-06-22 16:35:36 +02:00
Michael Telatynski
e59a2588ec Merge pull request #213 from vector-im/t3chguy/fix/17631
Fix accelerator for save-image-as clashing with copy-link-address
2021-06-22 09:27:18 +01:00
RiotRobot
a7938ae514 v1.7.31 2021-06-21 17:10:17 +01:00
RiotRobot
cf3112a9a9 Prepare changelog for v1.7.31 2021-06-21 17:10:17 +01:00
RiotRobot
b23048c5ce v1.7.31-rc.1 2021-06-15 17:35:25 +01:00
RiotRobot
c689529641 Prepare changelog for v1.7.31-rc.1 2021-06-15 17:35:24 +01:00
J. Ryan Stinnett
7b6ead738e Merge pull request #211 from xvenge00/electron-12.0.11
Upgrade to Electron 12.0.11
2021-06-15 15:44:37 +01:00
J. Ryan Stinnett
b6b5547ad0 Merge pull request #214 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-06-15 15:42:56 +01:00
Weblate
e28390fddb Merge branch 'origin/develop' into Weblate. 2021-06-15 14:42:37 +00:00
Michael Telatynski
b18bcd9bed Fix accelerator for save-image-as clashing with copy-link-address 2021-06-14 22:38:37 +01:00
J. Ryan Stinnett
b470657cdb Merge pull request #212 from vector-im/jryans/node-14
Upgrade to Node 14
2021-06-14 13:46:25 +01:00
J. Ryan Stinnett
fc51063f7a Upgrade to Node 14 2021-06-14 12:17:15 +01:00
lvre
099ecc468a Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/pt_BR/
2021-06-13 00:33:52 +00:00
Adam Venger
99b5947d7d Upgrade to Electron 12.0.11
Signed-off-by: Adam Venger <jawe1222@gmail.com>
2021-06-12 21:55:23 +02:00
lvre
7418161475 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (44 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/pt_BR/
2021-06-11 22:08:08 +00:00
J. Ryan Stinnett
40be024c9f Merge pull request #210 from vector-im/dependabot/npm_and_yarn/npm-registry-fetch-4.0.7
Bump npm-registry-fetch from 4.0.2 to 4.0.7
2021-06-11 13:41:42 +01:00
J. Ryan Stinnett
b2f09570f7 Merge pull request #204 from pavlukivan/update-electron-builder
Update electron-builder for Node 16 compatibility
2021-06-11 13:40:54 +01:00
dependabot[bot]
c3f150f9f0 Bump npm-registry-fetch from 4.0.2 to 4.0.7
Bumps [npm-registry-fetch](https://github.com/npm/npm-registry-fetch) from 4.0.2 to 4.0.7.
- [Release notes](https://github.com/npm/npm-registry-fetch/releases)
- [Changelog](https://github.com/npm/npm-registry-fetch/blob/v4.0.7/CHANGELOG.md)
- [Commits](https://github.com/npm/npm-registry-fetch/compare/v4.0.2...v4.0.7)

---
updated-dependencies:
- dependency-name: npm-registry-fetch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 12:40:41 +00:00
J. Ryan Stinnett
8a90a12683 Merge pull request #209 from vector-im/dependabot/npm_and_yarn/hosted-git-info-2.8.9
Bump hosted-git-info from 2.8.5 to 2.8.9
2021-06-11 13:40:04 +01:00
J. Ryan Stinnett
e7bc785ae4 Merge pull request #206 from vector-im/dependabot/npm_and_yarn/glob-parent-5.1.2
Bump glob-parent from 5.1.1 to 5.1.2
2021-06-11 13:39:54 +01:00
J. Ryan Stinnett
d1cb3092e8 Merge pull request #208 from vector-im/dependabot/npm_and_yarn/dot-prop-4.2.1
Bump dot-prop from 4.2.0 to 4.2.1
2021-06-11 13:39:48 +01:00
J. Ryan Stinnett
a136ccbf4c Merge pull request #207 from vector-im/dependabot/npm_and_yarn/y18n-3.2.2
Bump y18n from 3.2.1 to 3.2.2
2021-06-11 13:39:38 +01:00
dependabot[bot]
231db351ec Bump hosted-git-info from 2.8.5 to 2.8.9
Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.5 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.5...v2.8.9)

---
updated-dependencies:
- dependency-name: hosted-git-info
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 12:27:54 +00:00
dependabot[bot]
06b0f0fe01 Bump dot-prop from 4.2.0 to 4.2.1
Bumps [dot-prop](https://github.com/sindresorhus/dot-prop) from 4.2.0 to 4.2.1.
- [Release notes](https://github.com/sindresorhus/dot-prop/releases)
- [Commits](https://github.com/sindresorhus/dot-prop/compare/v4.2.0...v4.2.1)

---
updated-dependencies:
- dependency-name: dot-prop
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 12:27:52 +00:00
dependabot[bot]
4b71142a87 Bump glob-parent from 5.1.1 to 5.1.2
Bumps [glob-parent](https://github.com/gulpjs/glob-parent) from 5.1.1 to 5.1.2.
- [Release notes](https://github.com/gulpjs/glob-parent/releases)
- [Changelog](https://github.com/gulpjs/glob-parent/blob/main/CHANGELOG.md)
- [Commits](https://github.com/gulpjs/glob-parent/compare/v5.1.1...v5.1.2)

---
updated-dependencies:
- dependency-name: glob-parent
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 12:27:51 +00:00
dependabot[bot]
9726be5754 Bump y18n from 3.2.1 to 3.2.2
Bumps [y18n](https://github.com/yargs/y18n) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/yargs/y18n/releases)
- [Changelog](https://github.com/yargs/y18n/blob/master/CHANGELOG.md)
- [Commits](https://github.com/yargs/y18n/commits)

---
updated-dependencies:
- dependency-name: y18n
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-11 12:27:51 +00:00
J. Ryan Stinnett
2293b6794c Merge pull request #205 from vector-im/dependabot/npm_and_yarn/normalize-url-4.5.1
Bump normalize-url from 4.5.0 to 4.5.1
2021-06-11 13:27:23 +01:00
Ivan Pavluk
492bbcbe06 update electron-builder-squirrel-windows 2021-06-11 00:30:11 +07:00
dependabot[bot]
9cc1d91011 Bump normalize-url from 4.5.0 to 4.5.1
Bumps [normalize-url](https://github.com/sindresorhus/normalize-url) from 4.5.0 to 4.5.1.
- [Release notes](https://github.com/sindresorhus/normalize-url/releases)
- [Commits](https://github.com/sindresorhus/normalize-url/commits)

---
updated-dependencies:
- dependency-name: normalize-url
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2021-06-10 17:18:11 +00:00
Zachinquarantine
c08b62015e Translated using Weblate (Croatian)
Currently translated at 25.0% (11 of 44 strings)

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/hr/
2021-06-08 18:34:39 +00:00
Zachinquarantine
03abf9f9d0 Added translation using Weblate (Croatian) 2021-06-07 18:26:19 +00:00
RiotRobot
69e4ec7287 Merge branch 'master' into develop 2021-06-07 17:54:39 +01:00
RiotRobot
cf5e1eb4d4 v1.7.30 2021-06-07 17:54:24 +01:00
RiotRobot
dd494103de Prepare changelog for v1.7.30 2021-06-07 17:54:24 +01:00
Ivan Pavlyuk
57ba22f874 Update electron-builder (Node 16 compat) 2021-06-07 23:25:13 +07:00
Doğan Çelik
225456b8e0 Add numpad accelerators for zooming
Signed-off-by: Doğan Çelik <dogancelik93@gmail.com>
2021-06-05 16:29:26 +03:00
Aaron Raimist
03e59aa60c Remove translation
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-06-04 17:18:02 -05:00
Michael Telatynski
330e230f2c Merge pull request #200 from aaronraimist/macos-preferences 2021-06-04 09:53:30 +01:00
Michael Telatynski
dee2ecdf6c Merge pull request #202 from aaronraimist/zoomin 2021-06-04 09:50:18 +01:00
Aaron Raimist
f109065606 lint
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-06-04 00:23:02 -05:00
Aaron Raimist
344800d835 Remove accelerator
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-06-04 00:16:51 -05:00
Aaron Raimist
8c99f0ad12 Switch zoomIn accelerator to CommandOrControl+Plus
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-06-04 00:07:05 -05:00
Aaron Raimist
bc0e3bb317 Add warning dialog when custom config.json is invalid
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-06-03 23:39:33 -05:00
Aaron Raimist
b7e4e9e075 Follow HIG: use ellipsis for Preferences menu item, add app name to About menu item
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-06-03 23:07:28 -05:00
Aaron Raimist
5055ad0aec Put Preferences menu item in correct location on macOS
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-06-03 22:56:06 -05:00
RiotRobot
8a1a315938 v1.7.30-rc.1 2021-06-01 16:32:41 +01:00
RiotRobot
5958166348 Prepare changelog for v1.7.30-rc.1 2021-06-01 16:32:41 +01:00
J. Ryan Stinnett
767445e6f6 Merge pull request #199 from RiotTranslateBot/weblate-element-desktop-element-desktop
Translations update from Weblate
2021-06-01 15:56:37 +01:00
Weblate
99a3a132b3 Merge branch 'origin/develop' into Weblate. 2021-06-01 14:52:58 +00:00
Percy
1b1c869419 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (44 of 44 strings)

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

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

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

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

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

Translation: Element Desktop/element-desktop
Translate-URL: https://translate.element.io/projects/element-desktop/element-desktop/ar/
2021-05-06 00:34:28 +00:00
J. Ryan Stinnett
75b41d65c1 Merge pull request #192 from aaronraimist/close-fullscreen-macos
Prevent black screen when closing window while in full screen mode on macOS
2021-05-05 16:54:48 +01:00
Aaron Raimist
cc5dc4d801 Prevent black screen when closing window while in full screen mode on macOS
Signed-off-by: Aaron Raimist <aaron@raim.ist>
2021-05-04 21:55:32 -05:00
zer0-x
c4aeaadfbd Added translation using Weblate (Arabic) 2021-05-04 23:59:48 +00:00
Germain Souquet
b5fdeddec3 Add Windows native module requirements 2021-04-29 15:36:10 +01:00
41 changed files with 2091 additions and 1507 deletions

View File

@@ -1,6 +1,10 @@
module.exports = {
plugins: ["matrix-org"],
extends: [
"plugin:matrix-org/javascript",
],
parserOptions: {
ecmaVersion: 8,
ecmaVersion: 2021,
},
env: {
es6: true,
@@ -8,15 +12,24 @@ 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",
"no-async-promise-executor": "off",
}
}
},
overrides: [{
files: ["src/**/*.{ts,tsx}"],
extends: [
"plugin:matrix-org/typescript",
],
rules: {
// Things we do that break the ideal style
"prefer-promise-reject-errors": "off",
"quotes": "off",
// We disable this while we're transitioning
"@typescript-eslint/no-explicit-any": "off",
},
}],
};

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
/dist
/lib
/webapp
/webapp.asar
/packages

View File

@@ -1,3 +1,116 @@
Changes in [1.7.32](https://github.com/vector-im/element-desktop/releases/tag/v1.7.32) (2021-07-05)
===================================================================================================
[Full Changelog](https://github.com/vector-im/element-desktop/compare/v1.7.31...v1.7.32)
* Fix the build: make the rootDir correct
[\#224](https://github.com/vector-im/element-desktop/pull/224)
* Fix i18n in Element Desktop
[\#223](https://github.com/vector-im/element-desktop/pull/223)
* Convert preload.js to Typescript so that it gets copied to `lib`
[\#222](https://github.com/vector-im/element-desktop/pull/222)
* Bundle the `lib` dir now, not `src`
[\#221](https://github.com/vector-im/element-desktop/pull/221)
* Initial Typescripting for Element Desktop
[\#219](https://github.com/vector-im/element-desktop/pull/219)
* Translations update from Weblate
[\#220](https://github.com/vector-im/element-desktop/pull/220)
* Fix Windows target arch in native build
[\#218](https://github.com/vector-im/element-desktop/pull/218)
* Add libera.chat to default room directory
[\#217](https://github.com/vector-im/element-desktop/pull/217)
* Add update and native build support for Apple silicon
[\#216](https://github.com/vector-im/element-desktop/pull/216)
* Add numpad accelerators for zooming
[\#203](https://github.com/vector-im/element-desktop/pull/203)
* Add warning dialog when custom config.json is invalid
[\#201](https://github.com/vector-im/element-desktop/pull/201)
* Don't show Quit warning on keyUp residual event
[\#215](https://github.com/vector-im/element-desktop/pull/215)
* Fix accelerator for save-image-as clashing with copy-link-address
[\#213](https://github.com/vector-im/element-desktop/pull/213)
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)

View File

@@ -65,7 +65,7 @@ yarn run build:native
```
On Windows, this will automatically determine the architecture to build for based
on the environment (ie. set up by vcvarsall.bat).
on the environment. Make sure that you have all the [tools required to perform the native modules build](docs/windows-requirements.md)
Now you can build the package:

View File

@@ -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 && \

View File

@@ -0,0 +1,26 @@
# Windows
## Requirements to build native modules
If you want to build native modules, make sure that the following tools are installed on your system.
- [Node 14](https://nodejs.org)
- [Python 3](https://www.python.org/downloads/)
- [Strawberry Perl](https://strawberryperl.com/)
- [Rust](https://rustup.rs/)
- [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019) with the following configuration:
- On the Workloads tab:
- Desktop & Mobile -> C++ build tools
- On the Individual components tab:
- MSVC VS 2019 C++ build tools
- Windows 10 SDK (latest version available)
- C++ CMake tools for Windows
Once installed make sure all those utilities are accessible in your `PATH`.
In order to load all the C++ utilities installed by Visual Studio you can run the following in a terminal window.
```
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
```
You can replace `amd64` with `x86` depending on your CPU architecture.

View File

@@ -22,7 +22,8 @@
"roomDirectory": {
"servers": [
"matrix.org",
"gitter.im"
"gitter.im",
"libera.chat"
]
},
"enable_presence_by_hs_url": {

View File

@@ -16,7 +16,8 @@
"roomDirectory": {
"servers": [
"matrix.org",
"gitter.im"
"gitter.im",
"libera.chat"
]
},
"showLabsSettings": false,

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@ async function buildOpenSslWin(hakEnv, moduleInfo) {
const version = moduleInfo.cfg.dependencies.openssl;
const openSslDir = path.join(moduleInfo.moduleDotHakDir, `openssl-${version}`);
const openSslArch = hakEnv.arch === 'x64' ? 'VC-WIN64A' : 'VC-WIN32';
const openSslArch = hakEnv.getTargetArch() === 'x64' ? 'VC-WIN64A' : 'VC-WIN32';
console.log("Building openssl in " + openSslDir);
await new Promise((resolve, reject) => {
@@ -182,9 +182,36 @@ async function buildSqlCipherUnix(hakEnv, moduleInfo) {
if (hakEnv.isMac()) {
args.push('--with-crypto-lib=commoncrypto');
}
args.push('CFLAGS=-DSQLITE_HAS_CODEC');
if (!hakEnv.isHost()) {
// In the nonsense world of `configure`, it is assumed you are building
// a compiler like `gcc`, so the `host` option actually means the target
// the build output runs on.
args.push(`--host=${hakEnv.getTargetId()}`);
}
const cflags = [
'-DSQLITE_HAS_CODEC',
];
if (!hakEnv.isHost()) {
// `clang` uses more logical option naming.
cflags.push(`--target=${hakEnv.getTargetId()}`);
}
if (cflags.length) {
args.push(`CFLAGS=${cflags.join(' ')}`);
}
const ldflags = [];
if (hakEnv.isMac()) {
args.push('LDFLAGS=-framework Security -framework Foundation');
ldflags.push('-framework Security');
ldflags.push('-framework Foundation');
}
if (ldflags.length) {
args.push(`LDFLAGS=${ldflags.join(' ')}`);
}
await new Promise((resolve, reject) => {
@@ -248,7 +275,11 @@ async function buildMatrixSeshat(hakEnv, moduleInfo) {
// the build scripts since they run on the host, but vcvarsall.bat sets the c
// compiler in the path to be the one for the target, so we just use the matching
// toolchain for the target architecture which makes everything happy.
env.RUSTUP_TOOLCHAIN = hakEnv.arch == 'x64' ? 'stable-x86_64-pc-windows-msvc' : 'stable-i686-pc-windows-msvc';
env.RUSTUP_TOOLCHAIN = `stable-${hakEnv.getTargetId()}`;
}
if (!hakEnv.isHost()) {
env.CARGO_BUILD_TARGET = hakEnv.getTargetId();
}
console.log("Running neon with env", env);

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -34,7 +34,10 @@ module.exports = async function(hakEnv, moduleInfo) {
});
}
const tools = [['python', '--version']]; // node-gyp uses python for reasons beyond comprehension
const tools = [
['rustc', '--version'],
['python', '--version'], // node-gyp uses python for reasons beyond comprehension
];
if (hakEnv.isWin()) {
tools.push(['perl', '--version']); // for openssl configure
tools.push(['patch', '--version']); // to patch sqlcipher Makefile.msc
@@ -57,4 +60,18 @@ module.exports = async function(hakEnv, moduleInfo) {
});
});
}
// Ensure Rust target exists
await new Promise((resolve, reject) => {
childProcess.execFile('rustup', ['target', 'list', '--installed'], (err, out) => {
if (err) {
reject("Can't find rustup");
}
const target = hakEnv.getTargetId();
if (!out.includes(target)) {
reject(`Rust target ${target} not installed`);
}
resolve();
});
});
};

View File

@@ -1,8 +1,8 @@
{
"name": "element-desktop",
"productName": "Element",
"main": "src/electron-main.js",
"version": "1.7.27",
"main": "lib/electron-main.js",
"version": "1.7.32",
"description": "A feature-rich client for Matrix.org",
"author": "Element",
"repository": {
@@ -18,18 +18,22 @@
"mkdirs": "mkdirp packages deploys",
"fetch": "yarn run mkdirs && node scripts/fetch-package.js",
"asar-webapp": "asar p webapp webapp.asar",
"start": "electron .",
"lint": "eslint src/ scripts/ hak/",
"start": "yarn run build:ts && yarn run build:res && electron .",
"lint": "yarn lint:types && yarn lint:js",
"lint:js": "eslint src/ scripts/ hak/",
"lint:types": "tsc --noEmit",
"build:native": "yarn run hak",
"build32": "electron-builder --ia32",
"build64": "electron-builder --x64",
"build": "electron-builder",
"build32": "yarn run build:ts && yarn run build:res && electron-builder --ia32",
"build64": "yarn run build:ts && yarn run build:res && electron-builder --x64",
"build": "yarn run build:ts && yarn run build:res && electron-builder",
"build:ts": "tsc",
"build:res": "node scripts/copy-res.js",
"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",
"debrepo": "scripts/mkrepo.sh",
"clean": "rimraf webapp.asar dist packages deploys",
"clean": "rimraf webapp.asar dist packages deploys lib",
"hak": "node scripts/hak/index.js"
},
"dependencies": {
@@ -42,13 +46,21 @@
"request": "^2.88.2"
},
"devDependencies": {
"@types/auto-launch": "^5.0.1",
"@types/counterpart": "^0.18.1",
"@types/minimist": "^1.2.1",
"@typescript-eslint/eslint-plugin": "^4.17.0",
"@typescript-eslint/parser": "^4.17.0",
"asar": "^2.0.1",
"electron-builder": "22.10.5",
"electron-builder-squirrel-windows": "22.10.5",
"chokidar": "^3.5.2",
"electron": "12.0.11",
"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.3.1",
"eslint-config-matrix-org": "^0.1.2",
"eslint": "7.18.0",
"eslint-config-google": "^0.14.0",
"eslint-plugin-matrix-org": "github:matrix-org/eslint-plugin-matrix-org#main",
"find-npm-prefix": "^1.0.2",
"fs-extra": "^8.1.0",
"glob": "^7.1.6",
@@ -59,7 +71,8 @@
"npm": "^6.14.11",
"rimraf": "^3.0.2",
"semver": "^7.3.4",
"tar": "^6.1.0"
"tar": "^6.1.0",
"typescript": "^4.1.3"
},
"hakDependencies": {
"matrix-seshat": "^2.2.3",
@@ -67,14 +80,14 @@
},
"build": {
"appId": "im.riot.app",
"electronVersion": "12.0.2",
"electronVersion": "12.0.12",
"files": [
"package.json",
{
"from": ".hak/hakModules",
"to": "node_modules"
},
"src/**"
"lib/**"
],
"extraResources": [
{

121
scripts/copy-res.js Executable file
View File

@@ -0,0 +1,121 @@
#!/usr/bin/env node
// copies resources into the lib directory.
const parseArgs = require('minimist');
const chokidar = require('chokidar');
const path = require('path');
const fs = require('fs');
const argv = parseArgs(process.argv.slice(2), {});
const watch = argv.w;
const verbose = argv.v;
function errCheck(err) {
if (err) {
console.error(err.message);
process.exit(1);
}
}
const I18N_BASE_PATH = "src/i18n/strings/";
const INCLUDE_LANGS = fs.readdirSync(I18N_BASE_PATH).filter(fn => fn.endsWith(".json"));
// Ensure lib, lib/i18n and lib/i18n/strings all exist
fs.mkdirSync('lib/i18n/strings', { recursive: true });
function genLangFile(file, dest) {
let translations = {};
[file].forEach(function(f) {
if (fs.existsSync(f)) {
try {
Object.assign(
translations,
JSON.parse(fs.readFileSync(f).toString()),
);
} catch (e) {
console.error("Failed: " + f, e);
throw e;
}
}
});
translations = weblateToCounterpart(translations);
const json = JSON.stringify(translations, null, 4);
const filename = path.basename(file);
fs.writeFileSync(dest + filename, json);
if (verbose) {
console.log("Generated language file: " + filename);
}
}
/*
* Convert translation key from weblate format
* (which only supports a single level) to counterpart
* which requires object values for 'count' translations.
*
* eg.
* "there are %(count)s badgers|one": "a badger",
* "there are %(count)s badgers|other": "%(count)s badgers"
* becomes
* "there are %(count)s badgers": {
* "one": "a badger",
* "other": "%(count)s badgers"
* }
*/
function weblateToCounterpart(inTrs) {
const outTrs = {};
for (const key of Object.keys(inTrs)) {
const keyParts = key.split('|', 2);
if (keyParts.length === 2) {
let obj = outTrs[keyParts[0]];
if (obj === undefined) {
obj = {};
outTrs[keyParts[0]] = obj;
}
obj[keyParts[1]] = inTrs[key];
} else {
outTrs[key] = inTrs[key];
}
}
return outTrs;
}
/*
watch the input files for a given language,
regenerate the file, and regenerating languages.json with the new filename
*/
function watchLanguage(file, dest) {
// XXX: Use a debounce because for some reason if we read the language
// file immediately after the FS event is received, the file contents
// appears empty. Possibly https://github.com/nodejs/node/issues/6112
let makeLangDebouncer;
const makeLang = () => {
if (makeLangDebouncer) {
clearTimeout(makeLangDebouncer);
}
makeLangDebouncer = setTimeout(() => {
genLangFile(file, dest);
}, 500);
};
chokidar.watch(file)
.on('add', makeLang)
.on('change', makeLang)
.on('error', errCheck);
}
// language resources
const I18N_DEST = "lib/i18n/strings/";
INCLUDE_LANGS.forEach((file) => {
genLangFile(I18N_BASE_PATH + file, I18N_DEST);
}, {});
if (watch) {
INCLUDE_LANGS.forEach(file => watchLanguage(I18N_BASE_PATH + file, I18N_DEST));
}

View File

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

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -41,8 +41,8 @@ async function copy(hakEnv, moduleInfo) {
if (moduleInfo.cfg.copy) {
console.log(
"Copying " + moduleInfo.cfg.prune + " from " +
moduleInfo.moduleOutDir + " to " + moduleInfo.moduleOutDir,
"Copying files from " +
moduleInfo.moduleBuildDir + " to " + moduleInfo.moduleOutDir,
);
const files = await new Promise(async (resolve, reject) => {
glob(moduleInfo.cfg.copy, {

View File

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

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ const path = require('path');
const os = require('os');
const nodePreGypVersioning = require('node-pre-gyp/lib/util/versioning');
const { TARGETS, getHost, isHostId } = require('./target');
function getElectronVersion(packageJson) {
// should we pick the version of an installed electron
@@ -33,7 +34,7 @@ function getRuntime(packageJson) {
return electronVersion ? 'electron' : 'node-webkit';
}
function getTarget(packageJson) {
function getRuntimeVersion(packageJson) {
const electronVersion = getElectronVersion(packageJson);
if (electronVersion) {
return electronVersion;
@@ -42,30 +43,24 @@ function getTarget(packageJson) {
}
}
function detectArch() {
if (process.platform === 'win32') {
// vcvarsall.bat (the script that sets up the environment for
// visual studio build tools) sets an env var to tell us what
// architecture the active build tools target, so we auto-detect
// this.
const targetArch = process.env.VSCMD_ARG_TGT_ARCH;
if (targetArch === 'x86') {
return 'ia32';
} else if (targetArch === 'x64') {
return 'x64';
}
}
return process.arch;
}
module.exports = class HakEnv {
constructor(prefix, packageJson) {
constructor(prefix, packageJson, targetId) {
let target;
if (targetId) {
target = TARGETS[targetId];
} else {
target = getHost();
}
if (!target) {
throw new Error(`Unknown target ${targetId}!`);
}
Object.assign(this, {
// what we're targeting
runtime: getRuntime(packageJson),
target: getTarget(packageJson),
platform: process.platform,
arch: detectArch(),
runtimeVersion: getRuntimeVersion(packageJson),
target,
// paths
projectRoot: prefix,
@@ -76,34 +71,46 @@ module.exports = class HakEnv {
getRuntimeAbi() {
return nodePreGypVersioning.get_runtime_abi(
this.runtime,
this.target,
this.runtimeVersion,
);
}
// {node_abi}-{platform}-{arch}
getNodeTriple() {
return this.getRuntimeAbi() + '-' + this.platform + '-' + this.arch;
return this.getRuntimeAbi() + '-' + this.target.platform + '-' + this.target.arch;
}
getTargetId() {
return this.target.id;
}
isWin() {
return this.platform === 'win32';
return this.target.platform === 'win32';
}
isMac() {
return this.platform === 'darwin';
return this.target.platform === 'darwin';
}
isLinux() {
return this.platform === 'linux';
return this.target.platform === 'linux';
}
getTargetArch() {
return this.target.arch;
}
isHost() {
return isHostId(this.target.id);
}
makeGypEnv() {
return Object.assign({}, process.env, {
npm_config_target: this.target,
npm_config_arch: this.arch,
npm_config_target_arch: this.arch,
npm_config_arch: this.target.arch,
npm_config_target_arch: this.target.arch,
npm_config_disturl: 'https://atom.io/download/electron',
npm_config_runtime: this.runtime,
npm_config_target: this.runtimeVersion,
npm_config_build_from_source: true,
npm_config_devdir: path.join(os.homedir(), ".electron-gyp"),
});

View File

@@ -1,5 +1,5 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
Copyright 2020-2021 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -53,7 +53,19 @@ async function main() {
process.exit(1);
}
const hakEnv = new HakEnv(prefix, packageJson);
// Apply `--target <target>` option if specified
const targetIndex = process.argv.indexOf('--target');
let targetId;
if (targetIndex >= 0) {
if ((targetIndex + 1) >= process.argv.length) {
console.error("--target option specified without a target");
process.exit(1);
}
// Extract target ID and remove from args
targetId = process.argv.splice(targetIndex, 2)[1];
}
const hakEnv = new HakEnv(prefix, packageJson, targetId);
const deps = {};
@@ -133,4 +145,7 @@ async function main() {
}
}
main().catch(() => process.exit(1));
main().catch(err => {
console.error(err);
process.exit(1);
});

82
scripts/hak/target.js Normal file
View File

@@ -0,0 +1,82 @@
"use strict";
/*
Copyright 2021 The Matrix.org Foundation C.I.C.
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.
*/
/*
* THIS FILE IS GENERATED, NOT MEANT FOR EDITING DIRECTLY
* The original source is `target.ts` in the `element-builder` repo. You can
* edit it over there, run `yarn build`, and paste the changes here. It is
* currently assumed this file will rarely change, so a spearate package is not
* yet warranted.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.isHost = exports.isHostId = exports.getHost = exports.ENABLED_TARGETS = exports.TARGETS = void 0;
const aarch64AppleDarwin = {
id: 'aarch64-apple-darwin',
platform: 'darwin',
arch: 'arm64',
};
const i686PcWindowsMsvc = {
id: 'i686-pc-windows-msvc',
platform: 'win32',
arch: 'ia32',
vcVarsArch: 'x86',
};
const x8664PcWindowsMsvc = {
id: 'x86_64-pc-windows-msvc',
platform: 'win32',
arch: 'x64',
vcVarsArch: 'amd64',
};
const x8664AppleDarwin = {
id: 'x86_64-apple-darwin',
platform: 'darwin',
arch: 'x64',
};
const x8664UnknownLinuxGnu = {
id: 'x86_64-unknown-linux-gnu',
platform: 'linux',
arch: 'x64',
};
exports.TARGETS = {
'aarch64-apple-darwin': aarch64AppleDarwin,
'i686-pc-windows-msvc': i686PcWindowsMsvc,
'x86_64-pc-windows-msvc': x8664PcWindowsMsvc,
'x86_64-apple-darwin': x8664AppleDarwin,
'x86_64-unknown-linux-gnu': x8664UnknownLinuxGnu,
};
// The set of targets we build by default, sorted by increasing complexity so
// that we fail fast when the native host target fails.
exports.ENABLED_TARGETS = [
exports.TARGETS['x86_64-apple-darwin'],
exports.TARGETS['aarch64-apple-darwin'],
exports.TARGETS['x86_64-unknown-linux-gnu'],
exports.TARGETS['i686-pc-windows-msvc'],
];
function getHost() {
return Object.values(exports.TARGETS).find(target => (target.platform === process.platform &&
target.arch === process.arch));
}
exports.getHost = getHost;
function isHostId(id) {
return getHost()?.id === id;
}
exports.isHostId = isHostId;
function isHost(target) {
return getHost()?.id === target.id;
}
exports.isHost = isHost;

View File

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

26
src/@types/global.d.ts vendored Normal file
View File

@@ -0,0 +1,26 @@
/*
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.
*/
import { BrowserWindow } from "electron";
declare global {
namespace NodeJS {
interface Global {
mainWindow: BrowserWindow;
appQuitting: boolean;
}
}
}

View File

@@ -20,34 +20,33 @@ limitations under the License.
// Squirrel on windows starts the app with various flags
// as hooks to tell us when we've been installed/uninstalled
// etc.
const checkSquirrelHooks = require('./squirrelhooks');
if (checkSquirrelHooks()) return;
import { checkSquirrelHooks } from "./squirrelhooks";
if (checkSquirrelHooks()) process.exit(1);
const argv = require('minimist')(process.argv, {
alias: {help: "h"},
import { app, ipcMain, powerSaveBlocker, BrowserWindow, Menu, autoUpdater, protocol, dialog } from "electron";
import AutoLaunch from "auto-launch";
import path from "path";
import windowStateKeeper from 'electron-window-state';
import Store from 'electron-store';
import fs, { promises as afs } from "fs";
import crypto from "crypto";
import { URL } from "url";
import minimist from "minimist";
import * as tray from "./tray";
import { buildMenuTemplate } from './vectormenu';
import webContentsHandler from './webcontents-handler';
import * as updater from './updater';
import { getProfileFromDeeplink, protocolInit, recordSSOSession } from './protocol';
import { _t, AppLocalization } from './language-helper';
const argv = minimist(process.argv, {
alias: { help: "h" },
});
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 buildMenuTemplate = require('./vectormenu');
const webContentsHandler = require('./webcontents-handler');
const updater = require('./updater');
const {getProfileFromDeeplink, protocolInit, recordSSOSession} = require('./protocol');
const windowStateKeeper = require('electron-window-state');
const Store = require('electron-store');
const fs = require('fs');
const afs = fs.promises;
const crypto = require('crypto');
let keytar;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
keytar = require('keytar');
} catch (e) {
if (e.code === "MODULE_NOT_FOUND") {
@@ -57,14 +56,13 @@ try {
}
}
const { _t, AppLocalization } = require('./language-helper');
let seshatSupported = false;
let Seshat;
let SeshatRecovery;
let ReindexError;
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const seshatModule = require('matrix-seshat');
Seshat = seshatModule.Seshat;
SeshatRecovery = seshatModule.SeshatRecovery;
@@ -181,6 +179,7 @@ async function setupGlobals() {
]);
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
vectorConfig = require(asarPath + 'config.json');
} catch (e) {
// it would be nice to check the error code here and bail if the config
@@ -192,6 +191,7 @@ async function setupGlobals() {
try {
// Load local config and use it to override values from the one baked with the build
// eslint-disable-next-line @typescript-eslint/no-var-requires
const localConfig = require(path.join(app.getPath('userData'), 'config.json'));
// If the local config has a homeserver defined, don't use the homeserver from the build
@@ -207,6 +207,16 @@ async function setupGlobals() {
vectorConfig = Object.assign(vectorConfig, localConfig);
} catch (e) {
if (e instanceof SyntaxError) {
dialog.showMessageBox({
type: "error",
title: `Your ${vectorConfig.brand || 'Element'} is misconfigured`,
message: `Your custom ${vectorConfig.brand || 'Element'} configuration contains invalid JSON. ` +
`Please correct the problem and reopen ${vectorConfig.brand || 'Element'}.`,
detail: e.message || "",
});
}
// Could not load local config, this is expected in most cases.
}
@@ -249,7 +259,13 @@ async function moveAutoLauncher() {
}
const eventStorePath = path.join(app.getPath('userData'), 'EventStore');
const store = new Store({ name: "electron-config" });
const store = new Store<{
warnBeforeExit?: boolean;
minimizeToTray?: boolean;
spellCheckerEnabled?: boolean;
autoHideMenuBar?: boolean;
locale?: string | string[];
}>({ name: "electron-config" });
let eventIndex = null;
@@ -264,7 +280,8 @@ const exitShortcuts = [
const warnBeforeExit = (event, input) => {
const shouldWarnBeforeExit = store.get('warnBeforeExit', true);
const exitShortcutPressed = exitShortcuts.some(shortcutFn => shortcutFn(input, process.platform));
const exitShortcutPressed =
input.type === 'keyDown' && exitShortcuts.some(shortcutFn => shortcutFn(input, process.platform));
if (shouldWarnBeforeExit && exitShortcutPressed) {
const shouldCancelCloseRequest = dialog.showMessageBoxSync(mainWindow, {
@@ -499,7 +516,6 @@ ipcMain.on('ipcCall', async function(ev, payload) {
});
});
const seshatDefaultPassphrase = "DEFAULT_PASSPHRASE";
async function getOrCreatePassphrase(key) {
if (keytar) {
@@ -551,8 +567,8 @@ ipcMain.on('seshat', async function(ev, payload) {
const passphrase = await getOrCreatePassphrase(passphraseKey);
try {
await afs.mkdir(eventStorePath, {recursive: true});
eventIndex = new Seshat(eventStorePath, {passphrase});
await afs.mkdir(eventStorePath, { recursive: true });
eventIndex = new Seshat(eventStorePath, { passphrase });
} catch (e) {
if (e instanceof ReindexError) {
// If this is a reindex error, the index schema
@@ -578,7 +594,7 @@ ipcMain.on('seshat', async function(ev, payload) {
await recoveryIndex.reindex();
}
eventIndex = new Seshat(eventStorePath, {passphrase});
eventIndex = new Seshat(eventStorePath, { passphrase });
} else {
sendError(payload.id, e);
return;
@@ -822,6 +838,7 @@ app.on('ready', async () => {
if (argv['devtools']) {
try {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const { default: installExt, REACT_DEVELOPER_TOOLS, REACT_PERF } = require('electron-devtools-installer');
installExt(REACT_DEVELOPER_TOOLS)
.then((name) => console.log(`Added Extension: ${name}`))
@@ -836,17 +853,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;
}
@@ -854,7 +871,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;
}
@@ -866,7 +883,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;
}
@@ -876,7 +893,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);
@@ -955,7 +972,15 @@ app.on('ready', async () => {
// (this is generally how single-window Mac apps
// behave, eg. Mail.app)
e.preventDefault();
mainWindow.hide();
if (mainWindow.isFullScreen()) {
mainWindow.once('leave-full-screen', () => mainWindow.hide());
mainWindow.setFullScreen(false);
} else {
mainWindow.hide();
}
return false;
}
});
@@ -998,7 +1023,7 @@ function beforeQuit() {
}
app.on('before-quit', beforeQuit);
app.on('before-quit-for-update', beforeQuit);
autoUpdater.on('before-quit-for-update', beforeQuit);
app.on('second-instance', (ev, commandLine, workingDirectory) => {
// If other instance launched with --hidden then skip showing window

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

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

13
src/i18n/strings/hr.json Normal file
View 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/is.json Normal file
View File

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

View File

@@ -40,5 +40,7 @@
"Show/Hide": "Mostra/Nascondi",
"Are you sure you want to quit?": "Vuoi veramente uscire?",
"Close Element": "Chiudi Element",
"Cancel": "Annulla"
"Cancel": "Annulla",
"Stop Speaking": "Smetti di parlare",
"Speech": "Dettatura"
}

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

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

View File

@@ -37,5 +37,10 @@
"Unhide": "Göm inte",
"Zoom Out": "Zooma ut",
"Zoom In": "Zooma in",
"Close Element": "Stäng Element"
"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/ta.json Normal file
View File

@@ -0,0 +1,46 @@
{
"Zoom": "பெரிதாக்குதல்",
"Minimize": "சிறிதாக்கு",
"Toggle Developer Tools": "படைப்பாளர் கருவிகளை நிலைமாற்று",
"Toggle Full Screen": "முழு திரையை நிலைமாற்று",
"Paste and Match Style": "ஒட்டு மற்றும் நடையை பொறுத்து",
"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": "அனைத்தையும் முன்னால் கொண்டுவா",
"Stop Speaking": "பேசுவதை நிறுத்து",
"Start Speaking": "பேசத் துவங்கு",
"Speech": "பேச்சு",
"Unhide": "காட்டு",
"Hide Others": "மற்றதை மறை",
"Hide": "மறை",
"Services": "சேவைகள்",
"About": "இதனைப் பற்றி",
"Element Help": "எலிமெண்ட் உதவி",
"Help": "உதவி",
"Close": "மூடு",
"Window": "சாளரம்",
"Preferences": "விருப்பத்தேர்வுகள்",
"Zoom Out": "சிறிதாக்கு",
"Zoom In": "பெரிதாக்கு",
"Actual Size": "உண்மையான அளவு",
"View": "காட்சி",
"Select All": "அனைத்தையும் தெரிவுசெய்",
"Delete": "அழி",
"Paste": "ஒட்டு",
"Copy": "நகலெடு",
"Cut": "வெட்டு",
"Redo": "மீண்டும் செய்",
"Undo": "செயல்தவிர்",
"Edit": "திருத்து",
"Quit": "வெளியேறு",
"Show/Hide": "காட்டு/மறை",
"Are you sure you want to quit?": "நீங்கள் நிச்சயம் வெளியேற விரும்புகிறீர்களா?",
"Close Element": "எலிமெண்ட் ஐ மூடு",
"Cancel": "ரத்துசெய்"
}

View File

@@ -0,0 +1,46 @@
{
"Add to dictionary": "添加到字典",
"The image failed to save": "图片保存失败",
"Failed to save image": "图片保存失败",
"Save image as...": "保存图片为……",
"Copy link address": "复制链接地址",
"Copy email address": "复制邮箱地址",
"Copy image": "复制图片",
"File": "文件",
"Bring All to Front": "置前",
"Zoom": "放大",
"Stop Speaking": "停止讲话",
"Start Speaking": "开始讲话",
"Speech": "讲话",
"Unhide": "显示",
"Hide Others": "隐藏其他",
"Hide": "隐藏",
"Services": "服务",
"About": "关于",
"Element Help": "Element 帮助",
"Help": "帮助",
"Close": "关闭",
"Minimize": "最小化",
"Window": "窗口",
"Toggle Developer Tools": "切换开发工具",
"Toggle Full Screen": "切换全屏",
"Preferences": "外观",
"Zoom Out": "缩小",
"Zoom In": "放大",
"Actual Size": "实际大小",
"View": "查看",
"Select All": "选中全部",
"Delete": "删除",
"Paste and Match Style": "粘贴并匹配样式",
"Paste": "粘贴",
"Copy": "复制",
"Cut": "剪贴",
"Redo": "重做",
"Undo": "撤销",
"Edit": "编辑",
"Quit": "退出",
"Show/Hide": "显示/隐藏",
"Are you sure you want to quit?": "你确定要退出吗?",
"Close Element": "关闭 Element",
"Cancel": "取消"
}

View File

@@ -14,15 +14,23 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const counterpart = require('counterpart');
import counterpart from "counterpart";
import type Store from 'electron-store';
const DEFAULT_LOCALE = "en";
function _td(text) {
export function _td(text: string): string {
return text;
}
function _t(text, variables = {}) {
type SubstitutionValue = number | string;
interface IVariables {
[key: string]: SubstitutionValue;
count?: number;
}
export function _t(text: string, variables: IVariables = {}): string {
const args = Object.assign({ interpolate: false }, variables);
const { count } = args;
@@ -48,18 +56,24 @@ function _t(text, variables = {}) {
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}));
translated = counterpart.translate(text, Object.assign({}, args, { locale: DEFAULT_LOCALE }));
}
// The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution)
return translated;
}
class AppLocalization {
static STORE_KEY = "locale"
store = null
type Component = () => void;
constructor({ store, components = [] }) {
type TypedStore = Store<{ locale?: string | string[] }>;
export class AppLocalization {
private static readonly STORE_KEY = "locale";
private readonly store: TypedStore;
private readonly localizedComponents: Set<Component>;
constructor({ store, components = [] }: { store: TypedStore, components: Component[] }) {
counterpart.registerTranslations("en", this.fetchTranslationJson("en_EN"));
counterpart.setFallbackLocale('en');
counterpart.setSeparator('|');
@@ -77,7 +91,7 @@ class AppLocalization {
this.resetLocalizedUI();
}
fetchTranslationJson(locale) {
public fetchTranslationJson(locale: string): Record<string, string> {
try {
console.log("Fetching translation json for locale: " + locale);
return require(`./i18n/strings/${locale}.json`);
@@ -87,11 +101,7 @@ class AppLocalization {
}
}
get languageTranslationJson() {
return this.translationJsonMap.get(this.language);
}
setAppLocale(locales) {
public setAppLocale(locales: string | string[]): void {
console.log(`Changing application language to ${locales}`);
if (!Array.isArray(locales)) {
@@ -105,13 +115,15 @@ class AppLocalization {
}
});
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - this looks like a bug but is out of scope for this conversion
counterpart.setLocale(locales);
this.store.set(AppLocalization.STORE_KEY, locales);
this.resetLocalizedUI();
}
resetLocalizedUI() {
public resetLocalizedUI(): void {
console.log("Resetting the UI components after locale change");
this.localizedComponents.forEach(componentSetup => {
if (typeof componentSetup === "function") {
@@ -120,10 +132,3 @@ class AppLocalization {
});
}
}
module.exports = {
AppLocalization,
_t,
_td,
};

View File

@@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const { ipcRenderer, desktopCapturer, contextBridge } = require('electron');
import { ipcRenderer, desktopCapturer, contextBridge, IpcRendererEvent, SourcesOptions } from 'electron';
// Expose only expected IPC wrapper APIs to the renderer process to avoid
// handing out generalised messaging access.
@@ -36,26 +36,32 @@ const CHANNELS = [
"userDownloadOpen",
];
interface ISource {
id: string;
name: string;
thumbnailURL: string;
}
contextBridge.exposeInMainWorld(
"electron",
{
on(channel, listener) {
on(channel: string, listener: (event: IpcRendererEvent, ...args: any[]) => void): void {
if (!CHANNELS.includes(channel)) {
console.error(`Unknown IPC channel ${channel} ignored`);
return;
}
ipcRenderer.on(channel, listener);
},
send(channel, ...args) {
send(channel: string, ...args: any[]): void {
if (!CHANNELS.includes(channel)) {
console.error(`Unknown IPC channel ${channel} ignored`);
return;
}
ipcRenderer.send(channel, ...args);
},
async getDesktopCapturerSources(options) {
async getDesktopCapturerSources(options: SourcesOptions): Promise<ISource[]> {
const sources = await desktopCapturer.getSources(options);
const desktopCapturerSources = [];
const desktopCapturerSources: ISource[] = [];
for (const source of sources) {
desktopCapturerSources.push({

View File

@@ -1,102 +0,0 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
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 {app} = require("electron");
const path = require("path");
const fs = require("fs");
const PROTOCOL = "element://";
const SEARCH_PARAM = "element-desktop-ssoid";
const STORE_FILE_NAME = "sso-sessions.json";
// we getPath userData before electron-main changes it, so this is the default value
const storePath = path.join(app.getPath("userData"), STORE_FILE_NAME);
const processUrl = (url) => {
if (!global.mainWindow) return;
console.log("Handling link: ", url);
global.mainWindow.loadURL(url.replace(PROTOCOL, "vector://"));
};
const readStore = () => {
try {
const s = fs.readFileSync(storePath, { encoding: "utf8" });
const o = JSON.parse(s);
return typeof o === "object" ? o : {};
} catch (e) {
return {};
}
};
const writeStore = (data) => {
fs.writeFileSync(storePath, JSON.stringify(data));
};
module.exports = {
recordSSOSession: (sessionID) => {
const userDataPath = app.getPath('userData');
const store = readStore();
for (const key in store) {
// ensure each instance only has one (the latest) session ID to prevent the file growing unbounded
if (store[key] === userDataPath) {
delete store[key];
break;
}
}
store[sessionID] = userDataPath;
writeStore(store);
},
getProfileFromDeeplink: (args) => {
// check if we are passed a profile in the SSO callback url
const deeplinkUrl = args.find(arg => arg.startsWith('element://'));
if (deeplinkUrl && deeplinkUrl.includes(SEARCH_PARAM)) {
const parsedUrl = new URL(deeplinkUrl);
if (parsedUrl.protocol === 'element:') {
const ssoID = parsedUrl.searchParams.get(SEARCH_PARAM);
const store = readStore();
console.log("Forwarding to profile: ", store[ssoID]);
return store[ssoID];
}
}
},
protocolInit: () => {
// get all args except `hidden` as it'd mean the app would not get focused
// XXX: passing args to protocol handlers only works on Windows, so unpackaged deep-linking
// --profile/--profile-dir are passed via the SEARCH_PARAM var in the callback url
const args = process.argv.slice(1).filter(arg => arg !== "--hidden" && arg !== "-hidden");
if (app.isPackaged) {
app.setAsDefaultProtocolClient('element', process.execPath, args);
} else if (process.platform === 'win32') { // on Mac/Linux this would just cause the electron binary to open
// special handler for running without being packaged, e.g `electron .` by passing our app path to electron
app.setAsDefaultProtocolClient('element', process.execPath, [app.getAppPath(), ...args]);
}
if (process.platform === 'darwin') {
// Protocol handler for macos
app.on('open-url', function(ev, url) {
ev.preventDefault();
processUrl(url);
});
} else {
// Protocol handler for win32/Linux
app.on('second-instance', (ev, commandLine) => {
const url = commandLine[commandLine.length - 1];
if (!url.startsWith(PROTOCOL)) return;
processUrl(url);
});
}
},
};

103
src/protocol.ts Normal file
View File

@@ -0,0 +1,103 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
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.
*/
import { app } from "electron";
import { URL } from "url";
import path from "path";
import fs from "fs";
const PROTOCOL = "element://";
const SEARCH_PARAM = "element-desktop-ssoid";
const STORE_FILE_NAME = "sso-sessions.json";
// we getPath userData before electron-main changes it, so this is the default value
const storePath = path.join(app.getPath("userData"), STORE_FILE_NAME);
function processUrl(url: string): void {
if (!global.mainWindow) return;
console.log("Handling link: ", url);
global.mainWindow.loadURL(url.replace(PROTOCOL, "vector://"));
}
function readStore(): object {
try {
const s = fs.readFileSync(storePath, { encoding: "utf8" });
const o = JSON.parse(s);
return typeof o === "object" ? o : {};
} catch (e) {
return {};
}
}
function writeStore(data: object): void {
fs.writeFileSync(storePath, JSON.stringify(data));
}
export function recordSSOSession(sessionID: string): void {
const userDataPath = app.getPath('userData');
const store = readStore();
for (const key in store) {
// ensure each instance only has one (the latest) session ID to prevent the file growing unbounded
if (store[key] === userDataPath) {
delete store[key];
break;
}
}
store[sessionID] = userDataPath;
writeStore(store);
}
export function getProfileFromDeeplink(args): string | undefined {
// check if we are passed a profile in the SSO callback url
const deeplinkUrl = args.find(arg => arg.startsWith('element://'));
if (deeplinkUrl && deeplinkUrl.includes(SEARCH_PARAM)) {
const parsedUrl = new URL(deeplinkUrl);
if (parsedUrl.protocol === 'element:') {
const ssoID = parsedUrl.searchParams.get(SEARCH_PARAM);
const store = readStore();
console.log("Forwarding to profile: ", store[ssoID]);
return store[ssoID];
}
}
}
export function protocolInit(): void {
// get all args except `hidden` as it'd mean the app would not get focused
// XXX: passing args to protocol handlers only works on Windows, so unpackaged deep-linking
// --profile/--profile-dir are passed via the SEARCH_PARAM var in the callback url
const args = process.argv.slice(1).filter(arg => arg !== "--hidden" && arg !== "-hidden");
if (app.isPackaged) {
app.setAsDefaultProtocolClient('element', process.execPath, args);
} else if (process.platform === 'win32') { // on Mac/Linux this would just cause the electron binary to open
// special handler for running without being packaged, e.g `electron .` by passing our app path to electron
app.setAsDefaultProtocolClient('element', process.execPath, [app.getAppPath(), ...args]);
}
if (process.platform === 'darwin') {
// Protocol handler for macos
app.on('open-url', function(ev, url) {
ev.preventDefault();
processUrl(url);
});
} else {
// Protocol handler for win32/Linux
app.on('second-instance', (ev, commandLine) => {
const url = commandLine[commandLine.length - 1];
if (!url.startsWith(PROTOCOL)) return;
processUrl(url);
});
}
}

View File

@@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const path = require('path');
const spawn = require('child_process').spawn;
const {app} = require('electron');
const fsProm = require('fs').promises;
import path from "path";
import { spawn } from "child_process";
import { app } from "electron";
import { promises as fsProm } from "fs";
function runUpdateExe(args) {
function runUpdateExe(args: string[]): Promise<void> {
// Invokes Squirrel's Update.exe which will do things for us like create shortcuts
// Note that there's an Update.exe in the app-x.x.x directory and one in the parent
// directory: we need to run the one in the parent directory, because it discovers
@@ -33,7 +33,7 @@ function runUpdateExe(args) {
});
}
function checkSquirrelHooks() {
export function checkSquirrelHooks(): boolean {
if (process.platform !== 'win32') return false;
const cmd = process.argv[1];
@@ -82,5 +82,3 @@ function checkSquirrelHooks() {
}
return false;
}
module.exports = checkSquirrelHooks;

View File

@@ -15,26 +15,26 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
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');
import { app, Tray, Menu, nativeImage } from "electron";
import pngToIco from "png-to-ico";
import path from "path";
import fs from "fs";
import { _t } from "./language-helper";
let trayIcon = null;
let trayIcon: Tray = null;
exports.hasTray = function hasTray() {
export function hasTray(): boolean {
return (trayIcon !== null);
};
}
exports.destroy = function() {
export function destroy(): void {
if (trayIcon) {
trayIcon.destroy();
trayIcon = null;
}
};
}
const toggleWin = function() {
function toggleWin(): void {
if (global.mainWindow.isVisible() && !global.mainWindow.isMinimized()) {
global.mainWindow.hide();
} else {
@@ -42,9 +42,14 @@ const toggleWin = function() {
if (!global.mainWindow.isVisible()) global.mainWindow.show();
global.mainWindow.focus();
}
};
}
exports.create = function(config) {
interface IConfig {
icon_path: string; // eslint-disable-line camelcase
brand: string;
}
export function create(config: IConfig): void {
// no trays on darwin
if (process.platform === 'darwin' || trayIcon) return;
const defaultIcon = nativeImage.createFromPath(config.icon_path);
@@ -89,9 +94,9 @@ exports.create = function(config) {
global.mainWindow.webContents.on('page-title-updated', function(ev, title) {
trayIcon.setToolTip(title);
});
};
}
function initApplicationMenu() {
export function initApplicationMenu(): void {
if (!trayIcon) {
return;
}
@@ -112,5 +117,3 @@ function initApplicationMenu() {
trayIcon.setContextMenu(contextMenu);
}
exports.initApplicationMenu = initApplicationMenu;

View File

@@ -1,16 +1,32 @@
const { app, autoUpdater, ipcMain } = require('electron');
/*
Copyright 2016-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.
*/
import { app, autoUpdater, ipcMain } from "electron";
const UPDATE_POLL_INTERVAL_MS = 60 * 60 * 1000;
const INITIAL_UPDATE_DELAY_MS = 30 * 1000;
function installUpdate() {
function installUpdate(): void {
// for some reason, quitAndInstall does not fire the
// before-quit event, so we need to set the flag here.
global.appQuitting = true;
autoUpdater.quitAndInstall();
}
function pollForUpdates() {
function pollForUpdates(): void {
try {
autoUpdater.checkForUpdates();
} catch (e) {
@@ -18,8 +34,7 @@ function pollForUpdates() {
}
}
module.exports = {};
module.exports.start = function startAutoUpdate(updateBaseUrl) {
export function start(updateBaseUrl: string): void {
if (updateBaseUrl.slice(-1) !== '/') {
updateBaseUrl = updateBaseUrl + '/';
}
@@ -37,7 +52,7 @@ module.exports.start = function startAutoUpdate(updateBaseUrl) {
// rely on NSURLConnection setting the User-Agent to what we expect,
// and also acts as a convenient cache-buster to ensure that when the
// app updates it always gets a fresh value to avoid update-looping.
url = `${updateBaseUrl}macos/?localVersion=${encodeURIComponent(app.getVersion())}`;
url = `${updateBaseUrl}macos/${process.arch}/?localVersion=${encodeURIComponent(app.getVersion())}`;
} else if (process.platform === 'win32') {
url = `${updateBaseUrl}win32/${process.arch}/`;
} else {
@@ -48,6 +63,7 @@ module.exports.start = function startAutoUpdate(updateBaseUrl) {
}
if (url) {
console.log(`Update URL: ${url}`);
autoUpdater.setFeedURL(url);
// We check for updates ourselves rather than using 'updater' because we need to
// do it in the main process (and we don't really need to check every 10 minutes:
@@ -63,18 +79,25 @@ module.exports.start = function startAutoUpdate(updateBaseUrl) {
// will fail if running in debug mode
console.log('Couldn\'t enable update checking', err);
}
};
}
ipcMain.on('install_update', installUpdate);
ipcMain.on('check_updates', pollForUpdates);
function ipcChannelSendUpdateStatus(status) {
function ipcChannelSendUpdateStatus(status: boolean | string): void {
if (!global.mainWindow) return;
global.mainWindow.webContents.send('check_updates', status);
}
interface ICachedUpdate {
releaseNotes: string;
releaseName: string;
releaseDate: Date;
updateURL: string;
}
// cache the latest update which has been downloaded as electron offers no api to read it
let latestUpdateDownloaded;
let latestUpdateDownloaded: ICachedUpdate;
autoUpdater.on('update-available', function() {
ipcChannelSendUpdateStatus(true);
}).on('update-not-available', function() {

View File

@@ -14,12 +14,14 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
const {app, shell, Menu} = require('electron');
const { _t } = require('./language-helper');
import { app, shell, Menu, MenuItem, MenuItemConstructorOptions } from 'electron';
import { _t } from './language-helper';
function buildMenuTemplate() {
const isMac = process.platform === 'darwin';
export function buildMenuTemplate(): Menu {
// Menu template from http://electron.atom.io/docs/api/menu/, edited
const template = [
const template: Array<(MenuItemConstructorOptions) | (MenuItem)> = [
{
label: _t('Edit'),
accelerator: 'e',
@@ -46,7 +48,7 @@ function buildMenuTemplate() {
label: _t('Paste'),
},
{
role: 'pasteandmatchstyle',
role: 'pasteAndMatchStyle',
label: _t('Paste and Match Style'),
},
{
@@ -54,7 +56,7 @@ function buildMenuTemplate() {
label: _t('Delete'),
},
{
role: 'selectall',
role: 'selectAll',
label: _t('Select All'),
},
],
@@ -65,30 +67,44 @@ function buildMenuTemplate() {
submenu: [
{ type: 'separator' },
{
role: 'resetzoom',
role: 'resetZoom',
accelerator: 'CmdOrCtrl+Num0',
visible: false,
},
{
role: 'zoomIn',
accelerator: 'CmdOrCtrl+NumAdd',
visible: false,
},
{
role: 'zoomOut',
accelerator: 'CmdOrCtrl+NumSub',
visible: false,
},
{
role: 'resetZoom',
label: _t('Actual Size'),
},
{
role: 'zoomin',
accelerator: 'CommandOrControl+=',
role: 'zoomIn',
label: _t('Zoom In'),
},
{
role: 'zoomout',
role: 'zoomOut',
label: _t('Zoom Out'),
},
{ type: 'separator' },
{
// in macOS the Preferences menu item goes in the first menu
...(!isMac ? [{
label: _t('Preferences'),
accelerator: 'Command+,', // Mac-only accelerator
click() { global.mainWindow.webContents.send('preferences'); },
},
}] : []),
{
role: 'togglefullscreen',
label: _t('Toggle Full Screen'),
},
{
role: 'toggledevtools',
role: 'toggleDevTools',
label: _t('Toggle Developer Tools'),
},
],
@@ -122,7 +138,7 @@ function buildMenuTemplate() {
];
// macOS has specific menu conventions...
if (process.platform === 'darwin') {
if (isMac) {
template.unshift({
// first macOS menu is the name of the app
role: 'appMenu',
@@ -130,7 +146,13 @@ function buildMenuTemplate() {
submenu: [
{
role: 'about',
label: _t('About'),
label: _t('About') + ' ' + app.name,
},
{ type: 'separator' },
{
label: _t('Preferences') + '…',
accelerator: 'Command+,', // Mac-only accelerator
click() { global.mainWindow.webContents.send('preferences'); },
},
{ type: 'separator' },
{
@@ -144,7 +166,7 @@ function buildMenuTemplate() {
label: _t('Hide'),
},
{
role: 'hideothers',
role: 'hideOthers',
label: _t('Hide Others'),
},
{
@@ -160,17 +182,17 @@ function buildMenuTemplate() {
});
// Edit menu.
// This has a 'speech' section on macOS
template[1].submenu.push(
(template[1].submenu as MenuItemConstructorOptions[]).push(
{ type: 'separator' },
{
label: _t('Speech'),
submenu: [
{
role: 'startspeaking',
role: 'startSpeaking',
label: _t('Start Speaking'),
},
{
role: 'stopspeaking',
role: 'stopSpeaking',
label: _t('Stop Speaking'),
},
],
@@ -221,6 +243,3 @@ function buildMenuTemplate() {
return Menu.buildFromTemplate(template);
}
module.exports = buildMenuTemplate;

View File

@@ -1,19 +1,49 @@
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');
/*
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.
*/
import {
clipboard,
nativeImage,
Menu,
MenuItem,
shell,
dialog,
ipcMain,
NativeImage,
WebContents,
ContextMenuParams,
DownloadItem,
MenuItemConstructorOptions,
IpcMainEvent,
} from 'electron';
import url from 'url';
import fs from 'fs';
import request from 'request';
import path from 'path';
import { _t } from './language-helper';
const MAILTO_PREFIX = "mailto:";
const PERMITTED_URL_SCHEMES = [
const PERMITTED_URL_SCHEMES: string[] = [
'http:',
'https:',
MAILTO_PREFIX,
];
function safeOpenURL(target) {
function safeOpenURL(target: string): void {
// openExternal passes the target to open/start/xdg-open,
// so put fairly stringent limits on what can be opened
// (for instance, open /bin/sh does indeed open a terminal
@@ -28,7 +58,7 @@ function safeOpenURL(target) {
}
}
function onWindowOrNavigate(ev, target) {
function onWindowOrNavigate(ev: Event, target: string): void {
// always prevent the default: if something goes wrong,
// we don't want to end up opening it in the electron
// app, as we could end up opening any sort of random
@@ -37,7 +67,7 @@ function onWindowOrNavigate(ev, target) {
safeOpenURL(target);
}
function writeNativeImage(filePath, img) {
function writeNativeImage(filePath: string, img: NativeImage): Promise<void> {
switch (filePath.split('.').pop().toLowerCase()) {
case "jpg":
case "jpeg":
@@ -50,8 +80,7 @@ function writeNativeImage(filePath, img) {
}
}
function onLinkContextMenu(ev, params) {
function onLinkContextMenu(ev: Event, params: ContextMenuParams, webContents: WebContents): void {
let url = params.linkURL || params.srcURL;
if (url.startsWith('vector://vector/webapp')) {
@@ -77,7 +106,7 @@ function onLinkContextMenu(ev, params) {
label: _t('Copy image'),
accelerator: 'c',
click() {
ev.sender.copyImageAt(params.x, params.y);
webContents.copyImageAt(params.x, params.y);
},
}));
}
@@ -109,10 +138,10 @@ function onLinkContextMenu(ev, params) {
if (params.hasImageContents && !url.startsWith('blob:')) {
popupMenu.append(new MenuItem({
label: _t('Save image as...'),
accelerator: 'a',
accelerator: 's',
async click() {
const targetFileName = params.titleText || "image.png";
const {filePath} = await dialog.showSaveDialog({
const { filePath } = await dialog.showSaveDialog({
defaultPath: targetFileName,
});
@@ -141,8 +170,8 @@ function onLinkContextMenu(ev, params) {
ev.preventDefault();
}
function _CutCopyPasteSelectContextMenus(params) {
const options = [];
function cutCopyPasteSelectContextMenus(params: ContextMenuParams): MenuItemConstructorOptions[] {
const options: MenuItemConstructorOptions[] = [];
if (params.misspelledWord) {
params.dictionarySuggestions.forEach(word => {
@@ -181,10 +210,10 @@ function _CutCopyPasteSelectContextMenus(params) {
accelerator: 'p',
enabled: params.editFlags.canPaste,
}, {
role: 'pasteandmatchstyle',
role: 'pasteAndMatchStyle',
enabled: params.editFlags.canPaste,
}, {
role: 'selectall',
role: 'selectAll',
label: _t("Select All"),
accelerator: 'a',
enabled: params.editFlags.canSelectAll,
@@ -193,7 +222,7 @@ function _CutCopyPasteSelectContextMenus(params) {
}
function onSelectedContextMenu(ev, params) {
const items = _CutCopyPasteSelectContextMenus(params);
const items = cutCopyPasteSelectContextMenus(params);
const popupMenu = Menu.buildFromTemplate(items);
// popup() requires an options object even for no options
@@ -201,12 +230,13 @@ function onSelectedContextMenu(ev, params) {
ev.preventDefault();
}
function onEditableContextMenu(ev, params) {
const items = [
function onEditableContextMenu(ev: Event, params: ContextMenuParams) {
const items: MenuItemConstructorOptions[] = [
{ role: 'undo' },
{ role: 'redo', enabled: params.editFlags.canRedo },
{ type: 'separator' },
].concat(_CutCopyPasteSelectContextMenus(params));
...cutCopyPasteSelectContextMenus(params),
];
const popupMenu = Menu.buildFromTemplate(items);
@@ -215,20 +245,20 @@ function onEditableContextMenu(ev, params) {
ev.preventDefault();
}
ipcMain.on('userDownloadOpen', function(ev, {path}) {
ipcMain.on('userDownloadOpen', function(ev: IpcMainEvent, { path }) {
shell.openPath(path);
});
module.exports = (webContents) => {
export default (webContents: WebContents): void => {
webContents.on('new-window', onWindowOrNavigate);
webContents.on('will-navigate', (ev, target) => {
webContents.on('will-navigate', (ev: Event, target: string): void => {
if (target.startsWith("vector://")) return;
return onWindowOrNavigate(ev, target);
});
webContents.on('context-menu', function(ev, params) {
webContents.on('context-menu', function(ev: Event, params: ContextMenuParams): void {
if (params.linkURL || params.srcURL) {
onLinkContextMenu(ev, params);
onLinkContextMenu(ev, params, webContents);
} else if (params.selectionText) {
onSelectedContextMenu(ev, params);
} else if (params.isEditable) {
@@ -236,7 +266,7 @@ module.exports = (webContents) => {
}
});
webContents.session.on('will-download', (event, item) => {
webContents.session.on('will-download', (event: Event, item: DownloadItem): void => {
item.once('done', (event, state) => {
if (state === 'completed') {
const savePath = item.getSavePath();

24
tsconfig.json Normal file
View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"resolveJsonModule": true,
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"target": "es2016",
"noImplicitAny": false,
"sourceMap": false,
"outDir": "./lib",
"rootDir": "./src",
"declaration": true,
"types": [
"node"
],
"lib": [
"es2019",
"dom"
]
},
"include": [
"./src/**/*.ts"
]
}

2122
yarn.lock
View File

File diff suppressed because it is too large Load Diff