Compare commits

...

200 Commits

Author SHA1 Message Date
Michael Telatynski
83cd189984 Call Navigator::setAppBadge in Electron for Windows badges 2023-05-24 11:34:55 +01:00
renovate[bot]
0a5173f258 Update all non-major dependencies (#25387)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-16 16:39:15 +01:00
renovate[bot]
a68c535eb8 Update dependency @types/node to v16.18.30 (#25385)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-16 16:23:14 +01:00
renovate[bot]
11a8fb31a4 Update dependency eslint-plugin-unicorn to v47 (#25389)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-16 15:59:32 +01:00
renovate[bot]
bb52c1311a Update typescript-eslint monorepo to v5.59.5 (#25386)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-16 15:59:10 +01:00
Element Translate Bot
23bfce81a4 Translations update from Weblate (#25382)
Co-authored-by: raspin0 <marcinekk13@interia.pl>
Co-authored-by: Weblate <translate@riot.im>
Co-authored-by: someone1611 <hahahahacker2009@outlook.com>
2023-05-16 12:10:38 +01:00
Michael Telatynski
122d4d3503 Increase yarn timeout (#25377) 2023-05-16 09:43:02 +01:00
Michael Telatynski
88c5395349 Fix analyse:webpack-bundles script (#25353) 2023-05-15 09:12:45 +01:00
Michael Telatynski
d01eabd340 Remove old ansible comments (#25352) 2023-05-12 12:48:36 +00:00
Michael Telatynski
d7a98fe392 Handle trailing dot FQDNs for domain-specific config.json files (#25351) 2023-05-12 13:46:49 +01:00
Michael Telatynski
9457af27f6 Improve bundle size and add webpack-bundle-analyzer (#25337) 2023-05-12 12:13:10 +01:00
Michael Telatynski
cc5914a7dc Allow welcome.html logo to be replaced by config (#25339) 2023-05-12 09:44:47 +01:00
RiotRobot
1e7d001cd3 Reset matrix-react-sdk back to develop branch 2023-05-10 14:15:37 +01:00
RiotRobot
6e73a2b01c Reset matrix-js-sdk back to develop branch 2023-05-10 14:15:18 +01:00
RiotRobot
8274ad6394 Merge branch 'master' into develop 2023-05-10 14:14:43 +01:00
RiotRobot
df8f8415bf v1.11.31 2023-05-10 14:10:42 +01:00
RiotRobot
e902a0bd59 Prepare changelog for v1.11.31 2023-05-10 14:10:42 +01:00
RiotRobot
81397ffbf4 Upgrade matrix-react-sdk to 3.72.0 2023-05-10 14:06:03 +01:00
RiotRobot
96cf7053bc Upgrade matrix-js-sdk to 25.1.0 2023-05-10 14:05:17 +01:00
Michael Weimann
b25a7ef505 Add error notification audio (#25312) 2023-05-10 08:02:55 +02:00
renovate[bot]
99b68eedae Update peter-evans/dockerhub-description digest to 579f64c (#25137)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-10 12:54:59 +12:00
renovate[bot]
aa1538ea09 Update babel monorepo (#25254)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-10 12:53:47 +12:00
Michael Telatynski
1941097fed Fix _redirects file for develop.element.io going over 100 entries (#25286) 2023-05-09 08:51:02 +01:00
renovate[bot]
b633be382e Update dependency stylelint-config-standard to v33 (#25144)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-09 17:53:58 +12:00
RiotRobot
9860f4befc v1.11.31-rc.2 2023-05-05 15:27:49 +01:00
RiotRobot
349f7ee27a Prepare changelog for v1.11.31-rc.2 2023-05-05 15:27:48 +01:00
RiotRobot
17c65f1a0c Upgrade matrix-react-sdk to 3.72.0-rc.2 2023-05-05 15:26:18 +01:00
Andy Balaam
1fb03c82fe Ensure we actually wait for the login form to appear in loading-test (#25287) 2023-05-05 12:53:12 +01:00
Andy Balaam
f00c742ebc Wait for login screen to appear in loading-test (#25276) 2023-05-05 11:56:35 +01:00
Michael Telatynski
9e6467c684 Improve quality of Typescripting (#25232) 2023-05-05 09:08:36 +01:00
renovate[bot]
c0e070934a Update typescript-eslint monorepo to v5.59.1 (#25257)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-04 09:36:09 +12:00
renovate[bot]
5f9baed93e Update all non-major dependencies (#25253)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-04 09:29:30 +12:00
renovate[bot]
2bcfb257ea Update Node.js to v20 (#25258)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-03 12:11:57 +00:00
renovate[bot]
87a2060282 Update jest (#25140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-03 08:04:21 +00:00
renovate[bot]
09bfb8ad2a Update dependency stylelint-scss to v5 (#25259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Kerry <kerrya@element.io>
2023-05-02 21:00:28 +00:00
renovate[bot]
024ad5311f Update dependency @types/node to v16.18.25 (#25255)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-05-02 14:58:05 +01:00
RiotRobot
71c491db62 v1.11.31-rc.1 2023-05-02 11:45:49 +01:00
RiotRobot
0ae3cfdcdd Prepare changelog for v1.11.31-rc.1 2023-05-02 11:45:48 +01:00
RiotRobot
15ef05791f Upgrade matrix-react-sdk to 3.72.0-rc.1 2023-05-02 11:44:06 +01:00
RiotRobot
152923306f Upgrade matrix-js-sdk to 25.1.0-rc.1 2023-05-02 11:43:41 +01:00
Element Translate Bot
86ab757571 Translations update from Weblate (#25251)
* Translated using Weblate (Norwegian Bokmål)

Currently translated at 96.6% (29 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/nb_NO/

* Translated using Weblate (Portuguese)

Currently translated at 93.3% (28 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/pt/

---------

Co-authored-by: Thor Arne Johansen <tajcon@gmail.com>
Co-authored-by: Pedro costa <c.pedro@live.com.pt>
2023-05-02 11:22:43 +01:00
Michael Telatynski
a722b71b6c Remove unused property (#25213) 2023-04-28 10:07:48 +01:00
Michael Telatynski
6e8f76e93c Document UIFeature.locationSharing to hide location sharing (#25219) 2023-04-28 08:46:31 +01:00
Michael Telatynski
ed15578eed Enable ES2020 to match matrix-react-sdk (#25223) 2023-04-28 08:44:10 +01:00
Michael Telatynski
f5452fb097 Delabs reaction message previews (#25109) 2023-04-27 15:29:55 +01:00
Kat Gerasimova
2b17090855 Update issue automation (#25209)
Move from using GraphQL to actions

Remove automation for Delight, voice messages, polls, WTFs and FTUEs
2023-04-26 18:16:50 +00:00
Michael Telatynski
afab95288e Improve Content-Security-Policy (#25210) 2023-04-26 14:49:35 +01:00
renovate[bot]
59b6285458 Update typescript-eslint monorepo to v5.59.0 (#25141)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Janne Mareike Koschinski <janne@kuschku.de>
2023-04-26 12:41:55 +00:00
renovate[bot]
1709b3e9ba Update docker/metadata-action digest to c4ee3ad (#25136)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Janne Mareike Koschinski <janne@kuschku.de>
2023-04-26 12:41:42 +00:00
Michael Telatynski
3eddc939ce s/unset/reset/ 2023-04-26 11:12:57 +01:00
RiotRobot
e558661a77 Reset matrix-react-sdk back to develop branch 2023-04-25 11:12:06 +01:00
RiotRobot
506a1b6dc7 Reset matrix-js-sdk back to develop branch 2023-04-25 11:11:52 +01:00
RiotRobot
0035580aef Merge branch 'master' into develop 2023-04-25 11:11:36 +01:00
RiotRobot
f59d4c9574 v1.11.30 2023-04-25 11:07:44 +01:00
RiotRobot
ba5e8670a4 Prepare changelog for v1.11.30 2023-04-25 11:07:43 +01:00
RiotRobot
50d44864b0 Upgrade matrix-react-sdk to 3.71.1 2023-04-25 11:04:42 +01:00
RiotRobot
2dc54ec80b Upgrade matrix-js-sdk to 25.0.0 2023-04-25 11:04:07 +01:00
Michael Telatynski
f5b8bccb65 Conform more of the codebase with noImplicitAny and strictNullChecks (#25174
* Conform more of the codebase with `noImplicitAny` and `strictNullChecks`

* Fix tests

* Update src/vector/app.tsx
2023-04-25 09:36:17 +01:00
dependabot[bot]
a2da1eb79d Bump yaml from 2.2.1 to 2.2.2 (#25200)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-04-25 09:35:44 +01:00
Richard van der Hoff
40f95a6c06 Deprecate $spacing variables (#25175)
Per https://github.com/matrix-org/matrix-react-sdk/pull/10686, these don't make
much sense at the moment.
2023-04-21 15:12:08 +01:00
Michael Weimann
ece117b33f Improve CSS class naming style guide (#25173) 2023-04-21 12:54:57 +02:00
Michael Telatynski
66c86a6397 Revert "Strip data-testid in production builds" (#25163
This reverts commit a0791ff48f.
2023-04-20 08:58:07 +01:00
Michael Telatynski
a0791ff48f Strip data-testid in production builds (#25152) 2023-04-19 16:30:41 +01:00
Michael Telatynski
1a04705960 Update config.yml 2023-04-19 15:11:10 +01:00
renovate[bot]
2dc3f523aa Update all non-major dependencies (#25139)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Kerry <kerrya@element.io>
2023-04-19 03:12:35 +00:00
renovate[bot]
ac33b4a428 Update dependency rimraf to v5 (#25143)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-19 09:32:19 +12:00
renovate[bot]
5557487ef2 Update dependency mkdirp to v3 (#25142)
* Update dependency mkdirp to v3

* Iterate

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2023-04-18 16:01:10 +00:00
renovate[bot]
fa4d1addd3 Update dependency @types/react to v17.0.58 (#25138)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-18 13:05:20 +00:00
RiotRobot
77074cce44 v1.11.30-rc.1 2023-04-18 12:04:48 +01:00
RiotRobot
e447f6d6dd Prepare changelog for v1.11.30-rc.1 2023-04-18 12:04:47 +01:00
RiotRobot
22996fd55a Upgrade matrix-react-sdk to 3.71.0-rc.1 2023-04-18 12:03:16 +01:00
RiotRobot
b3b834cab2 Upgrade matrix-js-sdk to 25.0.0-rc.1 2023-04-18 12:02:51 +01:00
Andy Balaam
b31aa17253 Merge pull request #25133 from RiotTranslateBot/weblate-element-web-element-web
Translations update from Weblate
2023-04-18 10:49:21 +01:00
Weblate
f7c9bdcd97 Merge branch 'origin/develop' into Weblate. 2023-04-17 12:51:37 +00:00
Michael Telatynski
fc49190efe Add missing rel noreferrer noopener attributes (#25125) 2023-04-17 13:51:30 +01:00
Bjørn I.Svindseth
acc9b4c1d4 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 100.0% (30 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/nn/
2023-04-15 09:33:52 +00:00
Weblate
447b9dc661 Merge branch 'origin/develop' into Weblate. 2023-04-12 10:48:33 +00:00
Michael Telatynski
38dbd66474 Fix github actions deprecations warnings (#25096) 2023-04-12 10:48:28 +00:00
Weblate
3015b90a6e Merge branch 'origin/develop' into Weblate. 2023-04-12 09:47:34 +00:00
Richard van der Hoff
a1176ce66d Improve output in github actions for jest tests (#25084)
Configure the Github Actions Reporter with silent: false, keeping it from swallowing failure reasons.

Much the same as matrix-org/matrix-js-sdk#3269.
2023-04-12 10:47:27 +01:00
Weblate
c0ba077d06 Merge branch 'origin/develop' into Weblate. 2023-04-11 17:59:02 +00:00
Michael Telatynski
586309e851 Update build_develop.yml 2023-04-11 18:58:55 +01:00
Weblate
decbd0aa04 Merge branch 'origin/develop' into Weblate. 2023-04-11 13:26:47 +00:00
RiotRobot
cdabefa285 Reset matrix-js-sdk back to develop branch 2023-04-11 14:26:21 +01:00
RiotRobot
8b1d3a1265 Reset matrix-react-sdk back to develop branch 2023-04-11 14:25:55 +01:00
Weblate
dcb9dec749 Merge branch 'origin/develop' into Weblate. 2023-04-11 13:24:20 +00:00
RiotRobot
b9fd456bf4 Merge branch 'master' into develop
# Conflicts:
#	yarn.lock
2023-04-11 14:21:47 +01:00
RiotRobot
c1371fee27 v1.11.29 2023-04-11 14:13:24 +01:00
RiotRobot
a4b10a8766 Prepare changelog for v1.11.29 2023-04-11 14:13:23 +01:00
RiotRobot
80b9f7baab Upgrade matrix-react-sdk to 3.70.0 2023-04-11 14:11:26 +01:00
RiotRobot
d26d56e579 Upgrade matrix-js-sdk to 24.1.0 2023-04-11 14:11:08 +01:00
Weblate
ddc65d5cff Merge branch 'origin/develop' into Weblate. 2023-04-11 11:22:55 +00:00
renovate[bot]
22e3ebd89a Lock file maintenance (#25075)
* Lock file maintenance

* Lock file maintenance

* Pin jest-canvas-mock

* Pin jest-canvas-mock

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2023-04-11 12:22:49 +01:00
Weblate
8a54f74589 Merge branch 'origin/develop' into Weblate. 2023-04-06 12:17:55 +00:00
renovate[bot]
1ebe574ab1 Update dependency typescript to v5 (#25050)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2023-04-06 13:17:51 +01:00
Weblate
0714d74956 Merge branch 'origin/develop' into Weblate. 2023-04-06 11:45:44 +00:00
renovate[bot]
6cfa1eea7b Update all non-major dependencies (#25045)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-06 11:45:39 +00:00
Weblate
892ee3a707 Merge branch 'origin/develop' into Weblate. 2023-04-06 11:18:41 +00:00
renovate[bot]
2df33458a1 Update dependency stylelint-config-standard to v32 (#25049)
* Update dependency stylelint-config-standard to v32

* Iterate

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
2023-04-06 12:18:35 +01:00
Weblate
27dc1fb1ef Merge branch 'origin/develop' into Weblate. 2023-04-06 10:44:07 +00:00
renovate[bot]
88ade4a995 Update dependency @types/react to v17.0.55 (#25044)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-06 10:44:01 +00:00
Weblate
7899cd3077 Merge branch 'origin/develop' into Weblate. 2023-04-06 09:57:15 +00:00
renovate[bot]
3182508238 Update definitelyTyped (#25043)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-06 09:57:10 +00:00
Weblate
1237e73c1b Merge branch 'origin/develop' into Weblate. 2023-04-06 09:41:36 +00:00
Michael Telatynski
04f2a55500 Update pull_request.yaml 2023-04-06 10:41:32 +01:00
Weblate
04cf98d0e5 Merge branch 'origin/develop' into Weblate. 2023-04-06 09:13:22 +00:00
renovate[bot]
1a34ded0a1 Update typescript-eslint monorepo to v5.57.0 (#25046)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-06 10:13:16 +01:00
Weblate
79de2f6262 Merge branch 'origin/develop' into Weblate. 2023-04-06 09:11:49 +00:00
Christian Phyo
508d562040 Translated using Weblate (Burmese)
Currently translated at 3.3% (1 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/my/
2023-04-06 09:11:49 +00:00
renovate[bot]
12a380a08e Update babel monorepo (#25042)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-06 10:11:43 +01:00
Christian Phyo
407891073d Added translation using Weblate (Burmese) 2023-04-06 04:02:19 +00:00
renovate[bot]
8df1d67a83 Update dependency concurrently to v8 (#25048)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-05 17:18:20 +01:00
RiotRobot
6d241c8ce0 v1.11.29-rc.1 2023-04-04 12:11:33 +01:00
RiotRobot
34662d13c8 Prepare changelog for v1.11.29-rc.1 2023-04-04 12:11:32 +01:00
RiotRobot
a79fba39de Upgrade matrix-react-sdk to 3.70.0-rc.1 2023-04-04 12:08:43 +01:00
RiotRobot
7b191b90df Upgrade matrix-js-sdk to 24.1.0-rc.1 2023-04-04 12:08:22 +01:00
Andy Balaam
472518fcc9 Merge pull request #25029 from RiotTranslateBot/weblate-element-web-element-web
Translations update from Weblate
2023-04-04 11:25:18 +01:00
Weblate
4cf671d005 Merge branch 'origin/develop' into Weblate. 2023-03-31 14:52:34 +00:00
Michael Telatynski
ddc2932541 Use frozen lockfile instead of pure lockfile on yarn install (#25009) 2023-03-31 14:52:29 +00:00
Weblate
ea6056fa59 Merge branch 'origin/develop' into Weblate. 2023-03-31 14:27:33 +00:00
RiotRobot
b3c88f7a16 Reset matrix-react-sdk back to develop branch 2023-03-31 15:27:26 +01:00
RiotRobot
95f166ad61 Reset matrix-js-sdk back to develop branch 2023-03-31 15:27:12 +01:00
Weblate
1a7c5a294b Merge branch 'origin/develop' into Weblate. 2023-03-31 14:27:02 +00:00
RiotRobot
569e5cb0c1 Merge branch 'master' into develop 2023-03-31 15:26:56 +01:00
RiotRobot
f2160391c2 v1.11.28 2023-03-31 15:23:07 +01:00
RiotRobot
62fa62dc3a Prepare changelog for v1.11.28 2023-03-31 15:23:06 +01:00
Weblate
e0aa7754b1 Merge branch 'origin/develop' into Weblate. 2023-03-31 10:41:23 +00:00
Janne Mareike Koschinski
89054a50ac Replace newTranslatableError with UserFriendlyError (#25002)
* Apply user-friendly-error changes to element-web as well
* Update i18n library
2023-03-31 12:41:15 +02:00
Weblate
f833c57348 Merge branch 'origin/develop' into Weblate. 2023-03-31 09:50:07 +00:00
RiotRobot
1a63a7ff2e Reset matrix-react-sdk back to develop branch 2023-03-31 10:49:42 +01:00
RiotRobot
a66df9d434 Reset matrix-js-sdk back to develop branch 2023-03-31 10:49:21 +01:00
Weblate
c0cd678542 Merge branch 'origin/develop' into Weblate. 2023-03-31 09:48:45 +00:00
RiotRobot
b9837cc771 Merge branch 'master' into develop 2023-03-31 10:48:17 +01:00
RiotRobot
9faa625551 v1.11.27 2023-03-31 10:27:10 +01:00
RiotRobot
ebda5f4d31 Prepare changelog for v1.11.27 2023-03-31 10:27:09 +01:00
RiotRobot
145564719f Upgrade matrix-react-sdk to 3.69.1 2023-03-31 10:23:03 +01:00
Weblate
166d88058c Merge branch 'origin/develop' into Weblate. 2023-03-30 12:55:17 +00:00
Michael Telatynski
60d5ab427a Fix concurrency conflict (#24989) 2023-03-30 13:55:09 +01:00
Weblate
bcc5bd8e54 Merge branch 'origin/develop' into Weblate. 2023-03-30 11:28:27 +00:00
Richard van der Hoff
b9b52c8c06 code_style.md: Add notes on comments (#24990) 2023-03-30 12:28:22 +01:00
Weblate
3210ff2e9c Merge branch 'origin/develop' into Weblate. 2023-03-29 14:32:10 +00:00
Andy Balaam
7cbd8e04c2 Update changelog for v1.11.26 now the security issue is public (#24975) 2023-03-29 15:32:02 +01:00
Weblate
86c2cb7649 Merge branch 'origin/develop' into Weblate. 2023-03-29 14:08:05 +00:00
Michael Telatynski
84242fc81f Delete .sentryclirc (#24978) 2023-03-29 15:07:56 +01:00
Weblate
48e845575a Merge branch 'origin/develop' into Weblate. 2023-03-29 07:30:22 +00:00
Michael Telatynski
39061f9b8c Update docker base images (#24966) 2023-03-29 08:30:16 +01:00
Weblate
41d025bf48 Merge branch 'origin/develop' into Weblate. 2023-03-28 13:48:14 +00:00
Weblate
581beee0b2 Merge branch 'origin/develop' into Weblate. 2023-03-28 13:47:22 +00:00
RiotRobot
9ec10a274e Reset matrix-react-sdk back to develop branch 2023-03-28 14:47:11 +01:00
RiotRobot
c848295b8b Reset matrix-js-sdk back to develop branch 2023-03-28 14:46:52 +01:00
RiotRobot
b472f34d63 Merge branch 'master' into develop 2023-03-28 14:45:38 +01:00
Weblate
dfaeb6368b Merge branch 'origin/develop' into Weblate. 2023-03-27 20:01:42 +00:00
Kerry
f033becebb remove makeType utility from loading-test (#24958) 2023-03-28 09:01:33 +13:00
Weblate
f10171b6bc Merge branch 'origin/develop' into Weblate. 2023-03-22 16:49:51 +00:00
Johannes Marbach
dcc0cb74fe Merge pull request #24895 from vector-im/Johennes-patch-1 2023-03-22 17:49:46 +01:00
Johannes Marbach
389f55c261 Update config.yml 2023-03-22 16:25:20 +01:00
Weblate
1716a7f9ca Merge branch 'origin/develop' into Weblate. 2023-03-22 14:05:16 +00:00
emrah
2575322360 Use a newly generated access_token while joining Jitsi (#24646)
Fixes: #24687
Signed-off-by: Emrah Eryilmaz emrah.com@gmail.com
2023-03-22 14:05:10 +00:00
Weblate
ab19f5654c Merge branch 'origin/develop' into Weblate. 2023-03-22 09:22:57 +00:00
Michael Telatynski
b9b0b096a4 Allow desktop app to expose recent rooms in UI integrations (#16940) 2023-03-22 09:22:51 +00:00
Weblate
b391109469 Merge branch 'origin/develop' into Weblate. 2023-03-21 10:25:35 +00:00
Robin
50f8be4a62 Update matrix-widget-api (#24872) 2023-03-21 10:25:26 +00:00
Weblate
d35f3df621 Merge branch 'origin/develop' into Weblate. 2023-03-20 08:21:23 +00:00
renovate[bot]
4121f72593 Update typescript-eslint monorepo to v5.55.0 (#24788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-20 09:21:14 +01:00
Weblate
6a1a47aae1 Merge branch 'origin/develop' into Weblate. 2023-03-17 09:04:59 +00:00
Michael Telatynski
4440315cfb Update apple-app-site-association (#24847) 2023-03-17 09:04:52 +00:00
Weblate
b2a7d65fc9 Merge branch 'origin/develop' into Weblate. 2023-03-16 11:32:46 +00:00
Germain
c8b3f5d512 Update safari support policy (#24842) 2023-03-16 11:32:39 +00:00
Weblate
21a2a028a5 Merge branch 'origin/develop' into Weblate. 2023-03-15 15:53:11 +00:00
Michael Telatynski
77e7bad4f1 Clear electron data when logging out (#24827) 2023-03-15 15:53:02 +00:00
Weblate
292449369e Merge branch 'origin/develop' into Weblate. 2023-03-15 13:04:24 +00:00
RiotRobot
e7be53fe85 Reset matrix-react-sdk back to develop branch 2023-03-15 13:04:17 +00:00
RiotRobot
310b478b75 Reset matrix-js-sdk back to develop branch 2023-03-15 13:04:04 +00:00
Weblate
86ab455b54 Merge branch 'origin/develop' into Weblate. 2023-03-15 13:03:59 +00:00
RiotRobot
a66f5e7530 Merge branch 'master' into develop 2023-03-15 13:03:52 +00:00
Weblate
7059420be8 Merge branch 'origin/develop' into Weblate. 2023-03-15 12:50:47 +00:00
Dominik Henneke
afe2ac2ae6 Add API params to mute audio and/or video in Jitsi calls by default (#24820)
Signed-off-by: Dominik Henneke <dominik.henneke@nordeck.net>
2023-03-15 13:50:39 +01:00
Weblate
8122b85567 Merge branch 'origin/develop' into Weblate. 2023-03-14 11:27:13 +00:00
Michael Telatynski
4a18ab6d1b Update README.md 2023-03-14 11:27:05 +00:00
Weblate
714ba20b41 Merge branch 'origin/develop' into Weblate. 2023-03-14 08:25:43 +00:00
Michael Telatynski
93d2112bfe Update build_develop.yml 2023-03-14 08:25:40 +00:00
Weblate
e8bfd38865 Merge branch 'origin/develop' into Weblate. 2023-03-14 08:19:27 +00:00
Michael Telatynski
f43e6fddfc Use forked wait-on-check-action (#24809) 2023-03-14 08:19:19 +00:00
Weblate
b2f8875175 Merge branch 'origin/develop' into Weblate. 2023-03-13 12:23:42 +00:00
renovate[bot]
eb31df7d1d Update all non-major dependencies (#24791)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-13 12:23:36 +00:00
Weblate
2b8a819d3d Merge branch 'origin/develop' into Weblate. 2023-03-13 11:51:20 +00:00
renovate[bot]
a36b76faf0 Update definitelyTyped (#24787)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-13 11:51:16 +00:00
Weblate
f9edd3668f Merge branch 'origin/develop' into Weblate. 2023-03-13 11:42:25 +00:00
Open Culture Foundation
f5bb7a2513 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (30 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/zh_Hant/
2023-03-13 11:42:24 +00:00
renovate[bot]
9371737104 Update cloudflare/pages-action digest to 61eafe7 (#24801)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-13 11:42:16 +00:00
Weblate
764e1a01cc Merge branch 'origin/develop' into Weblate. 2023-03-12 19:42:47 +00:00
renovate[bot]
3d7d82ab2a Update dependency eslint-plugin-unicorn to v46 (#24794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-13 08:42:39 +13:00
Open Culture Foundation
9b571e12a7 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (30 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/zh_Hant/
2023-03-12 16:33:41 +00:00
Peter Chen
bc785e9860 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (30 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/zh_Hant/
2023-03-11 01:33:41 +00:00
lunarna-gh
e2a9da1020 Translated using Weblate (Polish)
Currently translated at 100.0% (30 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/pl/
2023-03-11 01:33:41 +00:00
Janne Mareike Koschinski
c85eb81ed0 Pin versions of third-party github actions (#24786) 2023-03-10 13:56:30 +01:00
Michael Telatynski
23d496d0e8 Remove unused dev dependency (#24766) 2023-03-10 10:21:35 +13:00
Janne Mareike Koschinski
6a4986ee06 Use full commit hashes for third party actions (#24777) 2023-03-09 11:53:52 +01:00
Michael Telatynski
296d1e2b75 Enable some tsc strict flags (#24772) 2023-03-08 16:38:56 +00:00
Michael Telatynski
2bfa2edd60 Remove deprecated stylelint rules which are handled by prettier (#24767) 2023-03-08 14:18:21 +00:00
62 changed files with 2276 additions and 1851 deletions

View File

@@ -87,6 +87,7 @@ module.exports = {
// We don't need super strict typing in test utilities
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/ban-ts-comment": "off",
},
},
],

View File

@@ -23,7 +23,7 @@ jobs:
)
)
steps:
- uses: tibdex/backport@v2
- uses: tibdex/backport@2e217641d82d02ba0603f46b1aeedefb258890ac # v2
with:
labels_template: "<%= JSON.stringify([...labels, 'X-Release-Blocker']) %>"
# We can't use GITHUB_TOKEN here or CI won't run on the new PR

View File

@@ -18,7 +18,7 @@ jobs:
environment: develop
env:
R2_BUCKET: "element-web-develop"
R2_URL: ${{ secrets.CF_R2_S3_API }}
R2_URL: ${{ vars.CF_R2_S3_API }}
R2_PUBLIC_URL: "https://element-web-develop.element.io"
steps:
- uses: actions/checkout@v3
@@ -68,20 +68,25 @@ jobs:
run: cp .github/cfp_headers _deploy/_headers
# Redirect requests for the develop tarball and the historical bundles to R2
# We find the latest 100 bundle.css files and add their bundles to the redirects file
# S3 has no sane way to get the age of a directory as they don't really exist
- name: Populate _redirects
run: |
{
echo "/develop.tar.gz $R2_PUBLIC_URL/develop.tar.gz 301"
for bundle in $(aws s3 ls s3://$R2_BUCKET/bundles/ --endpoint-url $R2_URL --region=auto | awk '{print $2}'); do
echo "/bundles/${bundle}* $R2_PUBLIC_URL/bundles/${bundle}:splat 301"
done
echo "/develop.tar.gz $R2_PUBLIC_URL/develop.tar.gz 301"
RESULTS=$(aws s3api --region auto --endpoint-url $R2_URL list-objects-v2 --bucket $R2_BUCKET \
--query "sort_by(Contents[?ends_with(Key, '/bundle.css')], &LastModified)[-100:].Key"
--prefix "bundles/" | jq -r '.[]' | grep -oE '[^\"].*\/\s*')
for bundle in "$RESULTS"; do
echo "/${path}* $R2_PUBLIC_URL/${path}:splat 301"
done
} | tee _deploy/_redirects
env:
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
- name: Wait for other steps to succeed
uses: lewagon/wait-on-check-action@v1.3.1
uses: t3chguy/wait-on-check-action@05861d3a448898eb33dfce34153bd1ecb9422fb9 # fork
with:
ref: ${{ github.sha }}
running-workflow-name: "Build & Deploy develop.element.io"
@@ -102,7 +107,7 @@ jobs:
- name: Deploy to Cloudflare Pages
id: cfp
uses: cloudflare/pages-action@1
uses: cloudflare/pages-action@61eafe73baad0195ab582cb447b2c6e15a0df9ce # v1
with:
apiToken: ${{ secrets.CF_PAGES_TOKEN }}
accountId: ${{ secrets.CF_PAGES_ACCOUNT_ID }}

View File

@@ -6,7 +6,7 @@ on:
schedule:
# This job can take a while, and we have usage limits, so just publish develop only twice a day
- cron: "0 7/12 * * *"
concurrency: ${{ github.ref_name }}
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
jobs:
buildx:
name: Docker Buildx
@@ -18,22 +18,22 @@ jobs:
fetch-depth: 0 # needed for docker-package to be able to calculate the version
- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@e81a89b1732b9c48d79cd809d8d81d79c4647a18 # v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@4b4e9c3e2d4531116a6f8ba8e71fc6e2cb6e6c8c # v2
with:
install: true
- name: Login to Docker Hub
uses: docker/login-action@v2
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a # v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@c4ee3adeed93b1fa6a762f209fb01608c1a22f1e # v4
with:
images: |
vectorim/element-web
@@ -44,7 +44,7 @@ jobs:
latest=${{ contains(github.ref_name, '-rc.') && 'false' || 'auto' }}
- name: Build and push
uses: docker/build-push-action@v4
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671 # v4
with:
context: .
push: true
@@ -53,7 +53,7 @@ jobs:
labels: ${{ steps.meta.outputs.labels }}
- name: Update repo description
uses: peter-evans/dockerhub-description@v3
uses: peter-evans/dockerhub-description@579f64ca0abced29dbbc44ab4c6a0b9e33ab3588 # v3
continue-on-error: true
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}

View File

@@ -2,7 +2,6 @@ name: Pull Request
on:
pull_request_target:
types: [opened, edited, labeled, unlabeled, synchronize]
concurrency: ${{ github.workflow }}-${{ github.event.pull_request.head.ref }}
jobs:
action:
uses: matrix-org/matrix-js-sdk/.github/workflows/pull_request.yaml@develop

View File

@@ -41,13 +41,13 @@ jobs:
- name: Get diff lines
id: diff
uses: Equip-Collaboration/diff-line-numbers@v1.0.0
uses: Equip-Collaboration/diff-line-numbers@df70b4b83e05105c15f20dc6cc61f1463411b2a6 # v1.0.0
with:
include: '["\\.tsx?$"]'
- name: Detecting files changed
id: files
uses: futuratrepadeira/changed-files@v4.0.0
uses: futuratrepadeira/changed-files@0239328a3a6268aad16af7c3e4efc78e32d6c0f0 # v4.0.1
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
pattern: '^.*\.tsx?$'
@@ -80,7 +80,7 @@ jobs:
# Does not need branch matching as only analyses this layer
- name: Install Deps
run: "yarn install --pure-lockfile"
run: "yarn install --frozen-lockfile"
- name: Run Linter
run: "yarn run lint:js"

View File

@@ -27,10 +27,10 @@ jobs:
- name: Get number of CPU cores
id: cpu-cores
uses: SimenB/github-actions-cpu-cores@v1
uses: SimenB/github-actions-cpu-cores@410541432439795d30db6501fb1d8178eb41e502 # v1
- name: Run tests with coverage
run: "yarn coverage --ci --reporters github-actions --max-workers ${{ steps.cpu-cores.outputs.count }}"
run: "yarn coverage --ci --max-workers ${{ steps.cpu-cores.outputs.count }}"
- name: Upload Artifact
uses: actions/upload-artifact@v3

View File

@@ -12,20 +12,7 @@ jobs:
contains(github.event.issue.assignees.*.login, 'andybalaam') ||
contains(github.event.issue.assignees.*.login, 'justjanne')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AKjJS"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/67
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}

View File

@@ -72,23 +72,10 @@ jobs:
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
contains(github.event.issue.labels.*.name, 'A11y'))
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc0sUA"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/18
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
add_product_issues:
name: X-Needs-Product to product project board
@@ -96,23 +83,10 @@ jobs:
if: >
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AAg6N"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/28
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
Search_issues_to_board:
name: Search issues to project board
@@ -120,114 +94,10 @@ jobs:
if: >
contains(github.event.issue.labels.*.name, 'A-New-Search-Experience')
steps:
- uses: octokit/graphql-action@v2.x
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4ADtaO"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_voice-message_issues:
name: A-Voice Messages to voice message board
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'A-Voice Messages')
steps:
- uses: octokit/graphql-action@v2.x
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc2KCw"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_message_bubbles_issues:
name: A-Message-Bubbles to Message bubbles board
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles')
steps:
- uses: octokit/graphql-action@v2.x
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc3m-g"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_ftue_issues:
name: Z-FTUE issues to the FTUE project board
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'Z-FTUE')
steps:
- uses: octokit/graphql-action@v2.x
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AAqVx"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_WTF_issues:
name: Z-WTF issues to the WTF project board
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'Z-WTF')
steps:
- uses: octokit/graphql-action@v2.x
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AArk0"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/48
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
ps_features1:
name: Add labelled issues to PS features team 1
@@ -240,23 +110,10 @@ jobs:
(contains(github.event.issue.labels.*.name, 'A-Session-Mgmt') &&
contains(github.event.issue.labels.*.name, 'A-User-Settings'))
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AHJKF"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/56
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
ps_features2:
name: Add labelled issues to PS features team 2
@@ -265,23 +122,10 @@ jobs:
contains(github.event.issue.labels.*.name, 'A-DM-Start') ||
contains(github.event.issue.labels.*.name, 'A-Broadcast')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AHJKd"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/58
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
ps_features3:
name: Add labelled issues to PS features team 3
@@ -289,23 +133,10 @@ jobs:
if: >
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AHJKW"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/57
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
voip:
name: Add labelled issues to VoIP project board
@@ -313,23 +144,10 @@ jobs:
if: >
contains(github.event.issue.labels.*.name, 'Team: VoIP')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4ABMIk"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/41
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
verticals_feature:
name: Add labelled issues to Verticals Feature project
@@ -337,20 +155,7 @@ jobs:
if: >
contains(github.event.issue.labels.*.name, 'Team: Verticals Feature')
steps:
- uses: octokit/graphql-action@v2.x
id: add_to_project
- uses: actions/add-to-project@main
with:
headers: '{"GraphQL-Features": "projects_next_graphql"}'
query: |
mutation add_to_project($projectid:ID!,$contentid:ID!) {
addProjectV2ItemById(input: {projectId: $projectid contentId: $contentid}) {
item {
id
}
}
}
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PVT_kwDOAM0swc4AHJKW"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
project-url: https://github.com/orgs/vector-im/projects/57
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}

View File

@@ -43,11 +43,11 @@ jobs:
# If either a reviewer matches a team member, or a team matches our team, say "true"
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
echo "::set-output name=match::true"
echo "match=true" >> $GITHUB_OUTPUT
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
echo "::set-output name=match::true"
echo "match=true" >> $GITHUB_OUTPUT
else
echo "::set-output name=match::false"
echo "match=false" >> $GITHUB_OUTPUT
fi
env:
TEAM: "design"
@@ -110,11 +110,11 @@ jobs:
# If either a reviewer matches a team member, or a team matches our team, say "true"
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
echo "::set-output name=match::true"
echo "match=true" >> $GITHUB_OUTPUT
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
echo "::set-output name=match::true"
echo "match=true" >> $GITHUB_OUTPUT
else
echo "::set-output name=match::false"
echo "match=false" >> $GITHUB_OUTPUT
fi
env:
TEAM: "product"

View File

View File

@@ -1,4 +1,4 @@
module.exports = {
...require("matrix-react-sdk/.stylelintrc.js"),
extends: ["stylelint-config-standard", "stylelint-config-prettier"],
extends: ["stylelint-config-standard"],
};

View File

@@ -1,9 +1,185 @@
Changes in [1.11.26](https://github.com/vector-im/element-web/releases/tag/v1.11.26) (2023-03-28)
Changes in [1.11.31](https://github.com/vector-im/element-web/releases/tag/v1.11.31) (2023-05-10)
=================================================================================================
## ✨ Features
* Improve Content-Security-Policy ([\#25210](https://github.com/vector-im/element-web/pull/25210)).
* Add UIFeature.locationSharing to hide location sharing ([\#10727](https://github.com/matrix-org/matrix-react-sdk/pull/10727)).
* Memoize field validation results ([\#10714](https://github.com/matrix-org/matrix-react-sdk/pull/10714)).
* Commands for plain text editor ([\#10567](https://github.com/matrix-org/matrix-react-sdk/pull/10567)). Contributed by @alunturner.
* Allow 16 lines of text in the rich text editors ([\#10670](https://github.com/matrix-org/matrix-react-sdk/pull/10670)). Contributed by @alunturner.
* Bail out of `RoomSettingsDialog` when room is not found ([\#10662](https://github.com/matrix-org/matrix-react-sdk/pull/10662)). Contributed by @kerryarchibald.
* Element-R: Populate device list for right-panel ([\#10671](https://github.com/matrix-org/matrix-react-sdk/pull/10671)). Contributed by @florianduros.
* Make existing and new issue URLs configurable ([\#10710](https://github.com/matrix-org/matrix-react-sdk/pull/10710)). Fixes #24424.
* Fix usages of ARIA tabpanel ([\#10628](https://github.com/matrix-org/matrix-react-sdk/pull/10628)). Fixes #25016.
* Element-R: Starting a DMs with a user ([\#10673](https://github.com/matrix-org/matrix-react-sdk/pull/10673)). Contributed by @florianduros.
* ARIA Accessibility improvements ([\#10675](https://github.com/matrix-org/matrix-react-sdk/pull/10675)).
* ARIA Accessibility improvements ([\#10674](https://github.com/matrix-org/matrix-react-sdk/pull/10674)).
* Add arrow key controls to emoji and reaction pickers ([\#10637](https://github.com/matrix-org/matrix-react-sdk/pull/10637)). Fixes #17189.
* Translate credits in help about section ([\#10676](https://github.com/matrix-org/matrix-react-sdk/pull/10676)).
## 🐛 Bug Fixes
* Fix: reveal images when image previews are disabled ([\#10781](https://github.com/matrix-org/matrix-react-sdk/pull/10781)). Fixes #25271. Contributed by @kerryarchibald.
* Fix autocomplete not resetting properly on message send ([\#10741](https://github.com/matrix-org/matrix-react-sdk/pull/10741)). Fixes #25170.
* Fix start_sso not working with guests disabled ([\#10720](https://github.com/matrix-org/matrix-react-sdk/pull/10720)). Fixes #16624.
* Fix soft crash with Element call widgets ([\#10684](https://github.com/matrix-org/matrix-react-sdk/pull/10684)).
* Send correct receipt when marking a room as read ([\#10730](https://github.com/matrix-org/matrix-react-sdk/pull/10730)). Fixes #25207.
* Offload some more waveform processing onto a worker ([\#9223](https://github.com/matrix-org/matrix-react-sdk/pull/9223)). Fixes #19756.
* Consolidate login errors ([\#10722](https://github.com/matrix-org/matrix-react-sdk/pull/10722)). Fixes #17520.
* Fix all rooms search generating permalinks to wrong room id ([\#10625](https://github.com/matrix-org/matrix-react-sdk/pull/10625)). Fixes #25115.
* Posthog properly handle Analytics ID changing from under us ([\#10702](https://github.com/matrix-org/matrix-react-sdk/pull/10702)). Fixes #25187.
* Fix Clock being read as an absolute time rather than duration ([\#10706](https://github.com/matrix-org/matrix-react-sdk/pull/10706)). Fixes #22582.
* Properly translate errors in `ChangePassword.tsx` so they show up translated to the user but not in our logs ([\#10615](https://github.com/matrix-org/matrix-react-sdk/pull/10615)). Fixes #9597. Contributed by @MadLittleMods.
* Honour feature toggles in guest mode ([\#10651](https://github.com/matrix-org/matrix-react-sdk/pull/10651)). Fixes #24513. Contributed by @andybalaam.
* Fix default content in devtools event sender ([\#10699](https://github.com/matrix-org/matrix-react-sdk/pull/10699)). Contributed by @tulir.
* Fix a crash when a call ends while you're in it ([\#10681](https://github.com/matrix-org/matrix-react-sdk/pull/10681)). Fixes #25153.
* Fix lack of screen reader indication when triggering auto complete ([\#10664](https://github.com/matrix-org/matrix-react-sdk/pull/10664)). Fixes #11011.
* Fix typing tile duplicating users ([\#10678](https://github.com/matrix-org/matrix-react-sdk/pull/10678)). Fixes #25165.
* Fix wrong room topic tooltip position ([\#10667](https://github.com/matrix-org/matrix-react-sdk/pull/10667)). Fixes #25158.
* Fix create subspace dialog not working ([\#10652](https://github.com/matrix-org/matrix-react-sdk/pull/10652)). Fixes #24882.
Changes in [1.11.30](https://github.com/vector-im/element-web/releases/tag/v1.11.30) (2023-04-25)
=================================================================================================
## 🔒 Security
* Fixes for [CVE-2023-30609](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=CVE-2023-30609) / GHSA-xv83-x443-7rmw
## ✨ Features
* Pick sensible default option for phone country dropdown ([\#10627](https://github.com/matrix-org/matrix-react-sdk/pull/10627)). Fixes #3528.
* Relate field validation tooltip via aria-describedby ([\#10522](https://github.com/matrix-org/matrix-react-sdk/pull/10522)). Fixes #24963.
* Handle more completion types in rte autocomplete ([\#10560](https://github.com/matrix-org/matrix-react-sdk/pull/10560)). Contributed by @alunturner.
* Show a tile for an unloaded predecessor room if it has via_servers ([\#10483](https://github.com/matrix-org/matrix-react-sdk/pull/10483)). Contributed by @andybalaam.
* Exclude message timestamps from aria live region ([\#10584](https://github.com/matrix-org/matrix-react-sdk/pull/10584)). Fixes #5696.
* Make composer format bar an aria toolbar ([\#10583](https://github.com/matrix-org/matrix-react-sdk/pull/10583)). Fixes #11283.
* Improve accessibility of font slider ([\#10473](https://github.com/matrix-org/matrix-react-sdk/pull/10473)). Fixes #20168 and #24962.
* fix file size display from kB to KB ([\#10561](https://github.com/matrix-org/matrix-react-sdk/pull/10561)). Fixes #24866. Contributed by @NSV1991.
* Handle /me in rte ([\#10558](https://github.com/matrix-org/matrix-react-sdk/pull/10558)). Contributed by @alunturner.
* bind html with switch for manage extension setting option ([\#10553](https://github.com/matrix-org/matrix-react-sdk/pull/10553)). Contributed by @NSV1991.
* Handle command completions in RTE ([\#10521](https://github.com/matrix-org/matrix-react-sdk/pull/10521)). Contributed by @alunturner.
* Add room and user avatars to rte ([\#10497](https://github.com/matrix-org/matrix-react-sdk/pull/10497)). Contributed by @alunturner.
* Support for MSC3882 revision 1 ([\#10443](https://github.com/matrix-org/matrix-react-sdk/pull/10443)). Contributed by @hughns.
* Check profiles before starting a DM ([\#10472](https://github.com/matrix-org/matrix-react-sdk/pull/10472)). Fixes #24830.
* Quick settings: Change the copy / labels on the options ([\#10427](https://github.com/matrix-org/matrix-react-sdk/pull/10427)). Fixes #24522. Contributed by @justjanne.
* Update rte autocomplete styling ([\#10503](https://github.com/matrix-org/matrix-react-sdk/pull/10503)). Contributed by @alunturner.
## 🐛 Bug Fixes
* Fix create subspace dialog not working ([\#10652](https://github.com/matrix-org/matrix-react-sdk/pull/10652)). Fixes vector-im/element-web#24882
* Fix multiple accessibility defects identified by AXE ([\#10606](https://github.com/matrix-org/matrix-react-sdk/pull/10606)).
* Fix view source from edit history dialog always showing latest event ([\#10626](https://github.com/matrix-org/matrix-react-sdk/pull/10626)). Fixes #21859.
* #21451 Fix WebGL disabled error message ([\#10589](https://github.com/matrix-org/matrix-react-sdk/pull/10589)). Contributed by @rashmitpankhania.
* Properly translate errors in `AddThreepid.ts` so they show up translated to the user but not in our logs ([\#10432](https://github.com/matrix-org/matrix-react-sdk/pull/10432)). Contributed by @MadLittleMods.
* Fix overflow on auth pages ([\#10605](https://github.com/matrix-org/matrix-react-sdk/pull/10605)). Fixes #19548.
* Fix incorrect avatar background colour when using a custom theme ([\#10598](https://github.com/matrix-org/matrix-react-sdk/pull/10598)). Contributed by @jdauphant.
* Remove dependency on `org.matrix.e2e_cross_signing` unstable feature ([\#10593](https://github.com/matrix-org/matrix-react-sdk/pull/10593)).
* Update setting description to match reality ([\#10600](https://github.com/matrix-org/matrix-react-sdk/pull/10600)). Fixes #25106.
* Fix no identity server in help & about settings ([\#10563](https://github.com/matrix-org/matrix-react-sdk/pull/10563)). Fixes #25077.
* Fix: Images no longer reserve their space in the timeline correctly ([\#10571](https://github.com/matrix-org/matrix-react-sdk/pull/10571)). Fixes #25082. Contributed by @kerryarchibald.
* Fix issues with inhibited accessible focus outlines ([\#10579](https://github.com/matrix-org/matrix-react-sdk/pull/10579)). Fixes #19742.
* Fix read receipts falling from sky ([\#10576](https://github.com/matrix-org/matrix-react-sdk/pull/10576)). Fixes #25081.
* Fix avatar text issue in rte ([\#10559](https://github.com/matrix-org/matrix-react-sdk/pull/10559)). Contributed by @alunturner.
* fix resizer only work with left mouse click ([\#10546](https://github.com/matrix-org/matrix-react-sdk/pull/10546)). Contributed by @NSV1991.
* Fix send two join requests when joining a room from spotlight search ([\#10534](https://github.com/matrix-org/matrix-react-sdk/pull/10534)). Fixes #25054.
* Highlight event when any version triggered a highlight ([\#10502](https://github.com/matrix-org/matrix-react-sdk/pull/10502)). Fixes #24923 and #24970. Contributed by @kerryarchibald.
* Fix spacing of headings of integration manager on General settings tab ([\#10232](https://github.com/matrix-org/matrix-react-sdk/pull/10232)). Fixes #24085. Contributed by @luixxiul.
Changes in [1.11.29](https://github.com/vector-im/element-web/releases/tag/v1.11.29) (2023-04-11)
=================================================================================================
## ✨ Features
* Allow desktop app to expose recent rooms in UI integrations ([\#16940](https://github.com/vector-im/element-web/pull/16940)).
* Add API params to mute audio and/or video in Jitsi calls by default ([\#24820](https://github.com/vector-im/element-web/pull/24820)). Contributed by @dhenneke.
* Style mentions as pills in rich text editor ([\#10448](https://github.com/matrix-org/matrix-react-sdk/pull/10448)). Contributed by @alunturner.
* Show room create icon if "UIComponent.roomCreation" is enabled ([\#10364](https://github.com/matrix-org/matrix-react-sdk/pull/10364)). Contributed by @maheichyk.
* Mentions as links rte ([\#10463](https://github.com/matrix-org/matrix-react-sdk/pull/10463)). Contributed by @alunturner.
* Better error handling in jump to date ([\#10405](https://github.com/matrix-org/matrix-react-sdk/pull/10405)). Contributed by @MadLittleMods.
* Show "Invite" menu option if "UIComponent.sendInvites" is enabled. ([\#10363](https://github.com/matrix-org/matrix-react-sdk/pull/10363)). Contributed by @maheichyk.
* Added `UserProfilesStore`, `LruCache` and user permalink profile caching ([\#10425](https://github.com/matrix-org/matrix-react-sdk/pull/10425)). Fixes #10559.
* Mentions as links rte ([\#10422](https://github.com/matrix-org/matrix-react-sdk/pull/10422)). Contributed by @alunturner.
* Implement MSC3952: intentional mentions ([\#9983](https://github.com/matrix-org/matrix-react-sdk/pull/9983)).
* Implement MSC3973: Search users in the user directory with the Widget API ([\#10269](https://github.com/matrix-org/matrix-react-sdk/pull/10269)). Contributed by @dhenneke.
* Permalinks to message are now displayed as pills ([\#10392](https://github.com/matrix-org/matrix-react-sdk/pull/10392)). Fixes #24751 and #24706.
* Show search,dial,explore in filterContainer if "UIComponent.filterContainer" is enabled ([\#10381](https://github.com/matrix-org/matrix-react-sdk/pull/10381)). Contributed by @maheichyk.
* Increase space panel collapse clickable area ([\#6084](https://github.com/matrix-org/matrix-react-sdk/pull/6084)). Fixes #17379. Contributed by @jaiwanth-v.
* Add fallback for replies to Polls ([\#10380](https://github.com/matrix-org/matrix-react-sdk/pull/10380)). Fixes #24197. Contributed by @kerryarchibald.
* Permalinks to rooms and users are now pillified ([\#10388](https://github.com/matrix-org/matrix-react-sdk/pull/10388)). Fixes #24825.
* Poll history - access poll history from room settings ([\#10356](https://github.com/matrix-org/matrix-react-sdk/pull/10356)). Contributed by @kerryarchibald.
* Add API params to mute audio and/or video in Jitsi calls by default ([\#10376](https://github.com/matrix-org/matrix-react-sdk/pull/10376)). Contributed by @dhenneke.
* Notifications: inline error message on notifications saving error ([\#10288](https://github.com/matrix-org/matrix-react-sdk/pull/10288)). Contributed by @kerryarchibald.
* Support dynamic room predecessor in SpaceProvider ([\#10348](https://github.com/matrix-org/matrix-react-sdk/pull/10348)). Contributed by @andybalaam.
* Support dynamic room predecessors for RoomProvider ([\#10346](https://github.com/matrix-org/matrix-react-sdk/pull/10346)). Contributed by @andybalaam.
* Support dynamic room predecessors in OwnBeaconStore ([\#10339](https://github.com/matrix-org/matrix-react-sdk/pull/10339)). Contributed by @andybalaam.
* Support dynamic room predecessors in ForwardDialog ([\#10344](https://github.com/matrix-org/matrix-react-sdk/pull/10344)). Contributed by @andybalaam.
* Support dynamic room predecessors in SpaceHierarchy ([\#10341](https://github.com/matrix-org/matrix-react-sdk/pull/10341)). Contributed by @andybalaam.
* Support dynamic room predecessors in AddExistingToSpaceDialog ([\#10342](https://github.com/matrix-org/matrix-react-sdk/pull/10342)). Contributed by @andybalaam.
* Support dynamic room predecessors in leave-behaviour ([\#10340](https://github.com/matrix-org/matrix-react-sdk/pull/10340)). Contributed by @andybalaam.
* Support dynamic room predecessors in StopGapWidgetDriver ([\#10338](https://github.com/matrix-org/matrix-react-sdk/pull/10338)). Contributed by @andybalaam.
* Support dynamic room predecessors in WidgetLayoutStore ([\#10326](https://github.com/matrix-org/matrix-react-sdk/pull/10326)). Contributed by @andybalaam.
* Support dynamic room predecessors in SpaceStore ([\#10332](https://github.com/matrix-org/matrix-react-sdk/pull/10332)). Contributed by @andybalaam.
* Sync polls push rules on changes to account_data ([\#10287](https://github.com/matrix-org/matrix-react-sdk/pull/10287)). Contributed by @kerryarchibald.
* Support dynamic room predecessors in BreadcrumbsStore ([\#10295](https://github.com/matrix-org/matrix-react-sdk/pull/10295)). Contributed by @andybalaam.
* Improved a11y for Field feedback and Secure Phrase input ([\#10320](https://github.com/matrix-org/matrix-react-sdk/pull/10320)). Contributed by @Sebbones.
* Support dynamic room predecessors in RoomNotificationStateStore ([\#10297](https://github.com/matrix-org/matrix-react-sdk/pull/10297)). Contributed by @andybalaam.
## 🐛 Bug Fixes
* Use a newly generated access_token while joining Jitsi ([\#24646](https://github.com/vector-im/element-web/pull/24646)). Fixes #24687. Contributed by @emrahcom.
* Fix cloudflare action pointing at commit hash instead of tag ([\#24777](https://github.com/vector-im/element-web/pull/24777)). Contributed by @justjanne.
* Allow editing with RTE to overflow for autocomplete visibility ([\#10499](https://github.com/matrix-org/matrix-react-sdk/pull/10499)). Contributed by @alunturner.
* Added auto focus to Github URL on opening of debug logs modal ([\#10479](https://github.com/matrix-org/matrix-react-sdk/pull/10479)). Contributed by @ShivamSpm.
* Fix detection of encryption for all users in a room ([\#10487](https://github.com/matrix-org/matrix-react-sdk/pull/10487)). Fixes #24995.
* Properly generate mentions when editing a reply with MSC3952 ([\#10486](https://github.com/matrix-org/matrix-react-sdk/pull/10486)). Fixes #24924. Contributed by @kerryarchibald.
* Improve performance of rendering a room with many hidden events ([\#10131](https://github.com/matrix-org/matrix-react-sdk/pull/10131)). Contributed by @andybalaam.
* Prevent future date selection in jump to date ([\#10419](https://github.com/matrix-org/matrix-react-sdk/pull/10419)). Fixes #20800. Contributed by @MadLittleMods.
* Add aria labels to message search bar to improve accessibility ([\#10476](https://github.com/matrix-org/matrix-react-sdk/pull/10476)). Fixes #24921.
* Fix decryption failure bar covering the timeline ([\#10360](https://github.com/matrix-org/matrix-react-sdk/pull/10360)). Fixes #24780 #24074 and #24183. Contributed by @luixxiul.
* Improve profile picture settings accessibility ([\#10470](https://github.com/matrix-org/matrix-react-sdk/pull/10470)). Fixes #24919.
* Handle group call redaction ([\#10465](https://github.com/matrix-org/matrix-react-sdk/pull/10465)).
* Display relative timestamp for threads on the same calendar day ([\#10399](https://github.com/matrix-org/matrix-react-sdk/pull/10399)). Fixes #24841. Contributed by @kerryarchibald.
* Fix timeline list and paragraph display issues ([\#10424](https://github.com/matrix-org/matrix-react-sdk/pull/10424)). Fixes #24602. Contributed by @alunturner.
* Use unique keys for voice broadcast pips ([\#10457](https://github.com/matrix-org/matrix-react-sdk/pull/10457)). Fixes #24959.
* Fix "show read receipts sent by other users" not applying to threads ([\#10445](https://github.com/matrix-org/matrix-react-sdk/pull/10445)). Fixes #24910.
* Fix joining public rooms without aliases in search dialog ([\#10437](https://github.com/matrix-org/matrix-react-sdk/pull/10437)). Fixes #23937.
* Add input validation for `m.direct` in `DMRoomMap` ([\#10436](https://github.com/matrix-org/matrix-react-sdk/pull/10436)). Fixes #24909.
* Reduce height reserved for "collapse" button's line on IRC layout ([\#10211](https://github.com/matrix-org/matrix-react-sdk/pull/10211)). Fixes #24605. Contributed by @luixxiul.
* Fix `creatorUserId is required` error when opening sticker picker ([\#10423](https://github.com/matrix-org/matrix-react-sdk/pull/10423)).
* Fix block/inline Element descendants error noise in `NewRoomIntro.tsx` ([\#10412](https://github.com/matrix-org/matrix-react-sdk/pull/10412)). Contributed by @MadLittleMods.
* Fix profile resizer to make first character of a line selectable in IRC layout ([\#10396](https://github.com/matrix-org/matrix-react-sdk/pull/10396)). Fixes #14764. Contributed by @luixxiul.
* Ensure space between wrapped lines of room name on IRC layout ([\#10188](https://github.com/matrix-org/matrix-react-sdk/pull/10188)). Fixes #24742. Contributed by @luixxiul.
* Remove unreadable alt attribute from the room status bar warning icon (nonsense to screenreaders) ([\#10402](https://github.com/matrix-org/matrix-react-sdk/pull/10402)). Contributed by @MadLittleMods.
* Fix big date separators when jump to date is enabled ([\#10404](https://github.com/matrix-org/matrix-react-sdk/pull/10404)). Fixes #22969. Contributed by @MadLittleMods.
* Fixes user authentication when registering via the module API ([\#10257](https://github.com/matrix-org/matrix-react-sdk/pull/10257)). Contributed by @maheichyk.
* Handle more edge cases in Space Hierarchy ([\#10280](https://github.com/matrix-org/matrix-react-sdk/pull/10280)). Contributed by @justjanne.
* Further improve performance with lots of hidden events ([\#10353](https://github.com/matrix-org/matrix-react-sdk/pull/10353)). Fixes #24480. Contributed by @andybalaam.
* Respect user cancelling upload flow by dismissing spinner ([\#10373](https://github.com/matrix-org/matrix-react-sdk/pull/10373)). Fixes #24667.
* When starting a DM, the end-to-end encryption status icon does now only appear if the DM can be encrypted ([\#10394](https://github.com/matrix-org/matrix-react-sdk/pull/10394)). Fixes #24397.
* Fix `[object Object]` in feedback metadata ([\#10390](https://github.com/matrix-org/matrix-react-sdk/pull/10390)).
* Fix pinned messages card saying nothing pinned while loading ([\#10385](https://github.com/matrix-org/matrix-react-sdk/pull/10385)). Fixes #24615.
* Fix import e2e key dialog staying disabled after paste ([\#10375](https://github.com/matrix-org/matrix-react-sdk/pull/10375)). Fixes #24818.
* Show all labs even if incompatible, with appropriate tooltip explaining requirements ([\#10369](https://github.com/matrix-org/matrix-react-sdk/pull/10369)). Fixes #24813.
* Fix UIFeature.Registration not applying to all paths ([\#10371](https://github.com/matrix-org/matrix-react-sdk/pull/10371)). Fixes #24814.
* Clicking on a user pill does now only open the profile in the right panel and no longer navigates to the home view. ([\#10359](https://github.com/matrix-org/matrix-react-sdk/pull/10359)). Fixes #24797.
* Fix start DM with pending third party invite ([\#10347](https://github.com/matrix-org/matrix-react-sdk/pull/10347)). Fixes #24781.
* Fix long display name overflowing reply tile on IRC layout ([\#10343](https://github.com/matrix-org/matrix-react-sdk/pull/10343)). Fixes #24738. Contributed by @luixxiul.
* Display redacted body on ThreadView in the same way as normal messages ([\#9016](https://github.com/matrix-org/matrix-react-sdk/pull/9016)). Fixes #24729. Contributed by @luixxiul.
* Handle more edge cases in ACL updates ([\#10279](https://github.com/matrix-org/matrix-react-sdk/pull/10279)). Contributed by @justjanne.
* Allow parsing png files to fail if thumbnailing is successful ([\#10308](https://github.com/matrix-org/matrix-react-sdk/pull/10308)).
Changes in [1.11.28](https://github.com/vector-im/element-web/releases/tag/v1.11.28) (2023-03-31)
=================================================================================================
## 🐛 Bug Fixes
* Changes for matrix-js-sdk v24.0.0
* Changes for matrix-react-sdk v3.69.0
* (No changes, version bumped to sync with element-desktop.)
Changes in [1.11.27](https://github.com/vector-im/element-web/releases/tag/v1.11.27) (2023-03-31)
=================================================================================================
## 🐛 Bug Fixes
* Fix detection of encryption for all users in a room ([\#10487](https://github.com/matrix-org/matrix-react-sdk/pull/10487)). Fixes #24995.
Changes in [1.11.26](https://github.com/vector-im/element-web/releases/tag/v1.11.26) (2023-03-28)
=================================================================================================
## 🔒 Security
* Fixes for [CVE-2023-28427](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=CVE-2023-28427) / GHSA-mwq8-fjpf-c2gr
* Fixes for [CVE-2023-28103](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=CVE-2023-28103) / GHSA-6g43-88cp-w5gv
Changes in [1.11.25](https://github.com/vector-im/element-web/releases/tag/v1.11.25) (2023-03-15)
=================================================================================================

View File

@@ -1,5 +1,5 @@
# Builder
FROM --platform=$BUILDPLATFORM node:16-buster as builder
FROM --platform=$BUILDPLATFORM node:20-bullseye as builder
# Support custom branches of the react-sdk and js-sdk. This also helps us build
# images of element-web develop.
@@ -15,7 +15,7 @@ WORKDIR /src
COPY . /src
RUN dos2unix /src/scripts/docker-link-repos.sh && bash /src/scripts/docker-link-repos.sh
RUN yarn --network-timeout=100000 install
RUN yarn --network-timeout=200000 install
RUN dos2unix /src/scripts/docker-package.sh && bash /src/scripts/docker-package.sh
@@ -23,7 +23,7 @@ RUN dos2unix /src/scripts/docker-package.sh && bash /src/scripts/docker-package.
RUN cp /src/config.sample.json /src/webapp/config.json
# App
FROM nginx:alpine
FROM nginx:alpine-slim
COPY --from=builder /src/webapp /app

View File

@@ -18,7 +18,8 @@ Element has several tiers of support for different environments:
- Supported
- Definition: Issues **actively triaged**, regressions **block** the release
- Last 2 major versions of Chrome, Firefox, Safari, and Edge on desktop OSes
- Last 2 major versions of Chrome, Firefox, and Edge on desktop OSes
- Last 2 versions of Safari
- Latest release of official Element Desktop app on desktop OSes
- Desktop OSes means macOS, Windows, and Linux versions for desktop devices
that are actively supported by the OS vendor and receive security updates
@@ -85,7 +86,7 @@ your web server configuration when hosting Element Web:
- The `X-Frame-Options: SAMEORIGIN` header, to prevent Element Web from being
framed and protect from [clickjacking][owasp-clickjacking].
- The `frame-ancestors 'none'` directive to your `Content-Security-Policy`
- The `frame-ancestors 'self'` directive to your `Content-Security-Policy`
header, as the modern replacement for `X-Frame-Options` (though both should be
included since not all browsers support it yet, see
[this][owasp-clickjacking-csp]).
@@ -113,7 +114,7 @@ For Apache, the configuration looks like:
Header set X-Frame-Options SAMEORIGIN
Header set X-Content-Type-Options nosniff
Header set X-XSS-Protection "1; mode=block"
Header set Content-Security-Policy "frame-ancestors 'none'"
Header set Content-Security-Policy "frame-ancestors 'self'"
```
Note: In case you are already setting a `Content-Security-Policy` header

View File

@@ -59,20 +59,21 @@ Unless otherwise specified, the following applies to all code:
6. Lines are trimmed of all excess whitespace, including blank lines.
7. Long lines are broken up for readability.
## TypeScript / JavaScript {#typescript-javascript}
## TypeScript / JavaScript
1. Write TypeScript. Turn JavaScript into TypeScript when working in the area.
2. Use named exports.
3. Use semicolons for block/line termination.
2. Use [TSDoc](https://tsdoc.org/) to document your code. See [Comments](#comments) below.
3. Use named exports.
4. Use semicolons for block/line termination.
1. Except when defining interfaces, classes, and non-arrow functions specifically.
4. When a statement's body is a single line, it must be written without curly braces, so long as the body is placed on
5. When a statement's body is a single line, it must be written without curly braces, so long as the body is placed on
the same line as the statement.
```typescript
if (x) doThing();
```
5. Blocks for `if`, `for`, `switch` and so on must have a space surrounding the condition, but not
6. Blocks for `if`, `for`, `switch` and so on must have a space surrounding the condition, but not
within the condition.
```typescript
@@ -81,17 +82,17 @@ Unless otherwise specified, the following applies to all code:
}
```
6. lowerCamelCase is used for function and variable naming.
7. UpperCamelCase is used for general naming.
8. Interface names should not be marked with an uppercase `I`.
9. One variable declaration per line.
10. If a variable is not receiving a value on declaration, its type must be defined.
7. lowerCamelCase is used for function and variable naming.
8. UpperCamelCase is used for general naming.
9. Interface names should not be marked with an uppercase `I`.
10. One variable declaration per line.
11. If a variable is not receiving a value on declaration, its type must be defined.
```typescript
let errorMessage: Optional<string>;
```
11. Objects can use shorthand declarations, including mixing of types.
12. Objects can use shorthand declarations, including mixing of types.
```typescript
{
@@ -102,7 +103,7 @@ Unless otherwise specified, the following applies to all code:
{ room, prop: this.prop }
```
12. Object keys should always be non-strings when possible.
13. Object keys should always be non-strings when possible.
```typescript
{
@@ -112,23 +113,28 @@ Unless otherwise specified, the following applies to all code:
}
```
13. Explicitly cast to a boolean.
14. Explicitly cast to a boolean, rather than relying on implicit truthiness of non-boolean values:
```typescript
!!stringVar || Boolean(stringVar);
const isRealUser = !!userId && ...;
// ... or ...
const isRealUser = Boolean(userId) && ...;
// but *not*:
const isRealUser = userId && ...; // invalid implicit cast
```
14. Use `switch` statements when checking against more than a few enum-like values.
15. Use `const` for constants, `let` for mutability.
16. Describe types exhaustively (ensure noImplictAny would pass).
15. Use `switch` statements when checking against more than a few enum-like values.
16. Use `const` for constants, `let` for mutability.
17. Describe types exhaustively (ensure noImplictAny would pass).
1. Notable exceptions are arrow functions used as parameters, when a void return type is
obvious, and when declaring and assigning a variable in the same line.
17. Declare member visibility (public/private/protected).
18. Private members are private and not prefixed unless required for naming conflicts.
18. Declare member visibility (public/private/protected).
19. Private members are private and not prefixed unless required for naming conflicts.
1. Convention is to use an underscore or the word "internal" to denote conflicted member names.
2. "Conflicted" typically refers to a getter which wants the same name as the underlying variable.
19. Prefer readonly members over getters backed by a variable, unless an internal setter is required.
20. Prefer Interfaces for object definitions, and types for parameter-value-only declarations.
20. Prefer readonly members over getters backed by a variable, unless an internal setter is required.
21. Prefer Interfaces for object definitions, and types for parameter-value-only declarations.
1. Note that an explicit type is optional if not expected to be used outside of the function call,
unlike in this example:
@@ -145,9 +151,9 @@ Unless otherwise specified, the following applies to all code:
}
```
21. Variables/properties which are `public static` should also be `readonly` when possible.
22. Interface and type properties are terminated with semicolons, not commas.
23. Prefer arrow formatting when declaring functions for interfaces/types:
22. Variables/properties which are `public static` should also be `readonly` when possible.
23. Interface and type properties are terminated with semicolons, not commas.
24. Prefer arrow formatting when declaring functions for interfaces/types:
```typescript
interface Test {
@@ -155,13 +161,13 @@ Unless otherwise specified, the following applies to all code:
}
```
24. Prefer a type definition over an inline type. For example, define an interface.
25. Always prefer to add types or declare a type over the use of `any`. Prefer inferred types
25. Prefer a type definition over an inline type. For example, define an interface.
26. Always prefer to add types or declare a type over the use of `any`. Prefer inferred types
when they are not `any`.
1. When using `any`, a comment explaining why must be present.
26. `import` should be used instead of `require`, as `require` does not have types.
27. Export only what can be reused.
28. Prefer a type like `Optional<X>` (`type Optional<T> = T | null | undefined`) instead
27. `import` should be used instead of `require`, as `require` does not have types.
28. Export only what can be reused.
29. Prefer a type like `Optional<X>` (`type Optional<T> = T | null | undefined`) instead
of truly optional parameters.
1. A notable exception is when the likelihood of a bug is minimal, such as when a function
@@ -179,12 +185,12 @@ Unless otherwise specified, the following applies to all code:
}
```
29. There should be approximately one interface, class, or enum per file unless the file is named
30. There should be approximately one interface, class, or enum per file unless the file is named
"types.ts", "global.d.ts", or ends with "-types.ts".
1. The file name should match the interface, class, or enum name.
30. Bulk functions can be declared in a single file, though named as "foo-utils.ts" or "utils/foo.ts".
31. Imports are grouped by external module imports first, then by internal imports.
32. File ordering is not strict, but should generally follow this sequence:
31. Bulk functions can be declared in a single file, though named as "foo-utils.ts" or "utils/foo.ts".
32. Imports are grouped by external module imports first, then by internal imports.
33. File ordering is not strict, but should generally follow this sequence:
1. Licence header
2. Imports
3. Constants
@@ -199,16 +205,16 @@ Unless otherwise specified, the following applies to all code:
5. Protected and abstract functions
6. Public/private functions
7. Public/protected/private static functions
33. Variable names should be noticeably unique from their types. For example, "str: string" instead
34. Variable names should be noticeably unique from their types. For example, "str: string" instead
of "string: string".
34. Use double quotes to enclose strings. You may use single quotes if the string contains double quotes.
35. Use double quotes to enclose strings. You may use single quotes if the string contains double quotes.
```typescript
const example1 = "simple string";
const example2 = 'string containing "double quotes"';
```
35. Prefer async-await to promise-chaining
36. Prefer async-await to promise-chaining
```typescript
async function () {
@@ -255,7 +261,7 @@ Inheriting all the rules of TypeScript, the following additionally apply:
if at all possible.
11. A component should only use CSS class names in line with the component name.
1. When knowingly using a class name from another component, document it.
1. When knowingly using a class name from another component, document it with a [comment](#comments).
12. Curly braces within JSX should be padded with a space, however properties on those components should not.
See above code example.
@@ -275,11 +281,15 @@ Inheriting all the rules of TypeScript, the following additionally apply:
Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, but actually it is not.
1. Class names must be prefixed with "mx\_".
2. Class names should denote the component which defines them, followed by any context:
1. mx_MyFoo
2. mx_MyFoo_avatar
3. mx_MyFoo_avatar--user
3. Use the `$font` and `$spacing` variables instead of manual values.
2. Class names must denote the component which defines them, followed by any context.
The context is not further specified here in terms of meaning or syntax.
Use whatever is appropriate for your implementation use case.
Some examples:
1. `mx_MyFoo`
2. `mx_MyFoo_avatar`
3. `mx_MyFoo_avatarUser`
4. `mx_MyFoo_avatar--user`
3. Use the `$font` variables instead of manual values.
4. Keep indentation/nesting to a minimum. Maximum suggested nesting is 5 layers.
5. Use the whole class name instead of shortcuts:
@@ -304,7 +314,7 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
7. Non-shared variables should use $lowerCamelCase. Shared variables use $dashed-naming.
8. Overrides to Z indexes, adjustments of dimensions/padding with pixels, and so on should all be
documented for what the values mean:
[documented](#comments) for what the values mean:
```scss
.mx_MyFoo {
@@ -314,7 +324,7 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
}
```
9. Avoid the use of `!important`. If necessary, add a comment.
9. Avoid the use of `!important`. If `!important` is necessary, add a [comment](#comments) explaining why.
## Tests
@@ -358,3 +368,38 @@ Note: We use PostCSS + some plugins to process our styles. It looks like SCSS, b
});
});
```
## Comments
1. As a general principle: be liberal with comments. This applies to all files: stylesheets as well as
JavaScript/TypeScript.
Good comments not only help future readers understand and maintain the code; they can also encourage good design
by clearly setting out how different parts of the codebase interact where that would otherwise be implicit and
subject to interpretation.
2. Aim to document all types, methods, class properties, functions, etc, with [TSDoc](https://tsdoc.org/) doc comments.
This is _especially_ important for public interfaces in `matrix-js-sdk`, but is good practice in general.
Even very simple interfaces can often benefit from a doc-comment, both as a matter of consistency, and because simple
interfaces have a habit of becoming more complex over time.
3. React components should be documented in the same way as other classes or functions. The documentation should give
a brief description of how the component should be used, and, especially for more complex components, each of its
properties should be clearly documented.
4. Inside a function, there is no need to comment every line, but consider:
- before a particular multiline section of code within the function, give an overview of what it does,
to make it easier for a reader to follow the flow through the function as a whole.
- if it is anything less than obvious, explain _why_ we are doing a particular operation, with particular emphasis
on how this function interacts with other parts of the codebase.
5. When making changes to existing code, authors are expected to read existing comments and make any necessary changes
to ensure they remain accurate.
6. Reviewers are encouraged to consider whether more comments would be useful, and to ask the author to add them.
It is natural for an author to feel that the code they have just written is "obvious" and that comments would be
redundant, whereas in reality it would take some time for reader unfamiliar with the code to understand it. A
reviewer is well-placed to make a more objective judgement.

View File

@@ -508,6 +508,7 @@ Currently, the following UI feature flags are supported:
timeline for recent messages. When false day dates will be used.
- `UIFeature.BulkUnverifiedSessionsReminder` - Display popup reminders to verify or remove unverified sessions. Defaults
to true.
- `UIFeature.locationSharing` - Whether or not location sharing menus will be shown.
## Undocumented / developer options

View File

@@ -100,12 +100,6 @@ theme definition.
For some sample themes, check out [aaronraimist/element-themes](https://github.com/aaronraimist/element-themes).
## Message preview tweaks
To enable message previews in the left panel for reactions in all rooms, enable `feature_roomlist_preview_reactions_all`.
To enable message previews for reactions in DMs only, enable `feature_roomlist_preview_reactions_dms`. This is ignored when it is enabled for all rooms.
## Dehydrated devices (`feature_dehydration`)
Allows users to receive encrypted messages by creating a device that is stored

57
jest.config.ts Normal file
View File

@@ -0,0 +1,57 @@
/*
Copyright 2023 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 { env } from "process";
import type { Config } from "jest";
const config: Config = {
testEnvironment: "jsdom",
testEnvironmentOptions: {
url: "http://localhost/",
},
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)"],
setupFiles: ["jest-canvas-mock"],
setupFilesAfterEnv: ["<rootDir>/node_modules/matrix-react-sdk/test/setupTests.js"],
moduleNameMapper: {
"\\.(css|scss|pcss)$": "<rootDir>/__mocks__/cssMock.js",
"\\.(gif|png|ttf|woff2)$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/imageMock.js",
"\\.svg$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/svg.js",
"\\$webapp/i18n/languages.json": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/languages.json",
"^react$": "<rootDir>/node_modules/react",
"^react-dom$": "<rootDir>/node_modules/react-dom",
"^matrix-js-sdk$": "<rootDir>/node_modules/matrix-js-sdk/src",
"^matrix-react-sdk$": "<rootDir>/node_modules/matrix-react-sdk/src",
"decoderWorker\\.min\\.js": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"decoderWorker\\.min\\.wasm": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"waveWorker\\.min\\.js": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"context-filter-polyfill": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"FontManager.ts": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/FontManager.js",
"workers/(.+)\\.worker\\.ts": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/workerMock.js",
"^!!raw-loader!.*": "jest-raw-loader",
"RecorderWorklet": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
},
transformIgnorePatterns: ["/node_modules/(?!matrix-js-sdk).+$", "/node_modules/(?!matrix-react-sdk).+$"],
coverageReporters: ["text-summary", "lcov"],
testResultsProcessor: "@casualbot/jest-sonar-reporter",
};
// if we're running under GHA, enable the GHA reporter
if (env["GITHUB_ACTIONS"] !== undefined) {
config.reporters = [["github-actions", { silent: false }], "summary"];
}
export default config;

View File

@@ -1,6 +1,6 @@
{
"name": "element-web",
"version": "1.11.26",
"version": "1.11.31",
"description": "A feature-rich client for Matrix.org",
"author": "New Vector Ltd.",
"repository": {
@@ -26,6 +26,9 @@
"contribute.json"
],
"style": "bundle.css",
"matrix_i18n_extra_translation_funcs": [
"UserFriendlyError"
],
"scripts": {
"i18n": "matrix-gen-i18n",
"prunei18n": "matrix-prune-i18n",
@@ -58,21 +61,22 @@
"lint:style": "stylelint \"res/css/**/*.pcss\"",
"test": "jest",
"coverage": "yarn test --coverage",
"analyse:unused-exports": "node ./scripts/analyse_unused_exports.js"
"analyse:unused-exports": "node ./scripts/analyse_unused_exports.js",
"analyse:webpack-bundles": "webpack-bundle-analyzer webpack-stats.json webapp"
},
"resolutions": {
"@types/react-dom": "17.0.19",
"@types/react": "17.0.53"
"@types/react": "17.0.58"
},
"dependencies": {
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.12.tgz",
"@matrix-org/react-sdk-module-api": "^0.0.4",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz",
"@matrix-org/react-sdk-module-api": "^0.0.5",
"gfm.css": "^1.1.2",
"jsrsasign": "^10.5.25",
"katex": "^0.16.0",
"matrix-js-sdk": "24.0.0",
"matrix-react-sdk": "3.69.0",
"matrix-widget-api": "^1.1.1",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"matrix-react-sdk": "github:matrix-org/matrix-react-sdk#develop",
"matrix-widget-api": "^1.3.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"sanitize-html": "^2.3.2",
@@ -100,12 +104,12 @@
"@sentry/webpack-plugin": "^1.18.1",
"@svgr/webpack": "^5.5.0",
"@testing-library/react": "^12.1.5",
"@types/flux": "^3.1.9",
"@types/jest": "^29.0.0",
"@types/jitsi-meet": "^2.0.2",
"@types/jsrsasign": "^10.5.4",
"@types/modernizr": "^3.5.3",
"@types/node": "^16",
"@types/react": "17.0.53",
"@types/react": "17.0.58",
"@types/react-dom": "17.0.19",
"@types/sanitize-html": "^2.3.1",
"@types/ua-parser-js": "^0.7.36",
@@ -115,11 +119,11 @@
"babel-jest": "^29.0.0",
"babel-loader": "^8.2.2",
"chokidar": "^3.5.1",
"concurrently": "^7.0.0",
"concurrently": "^8.0.0",
"cpx": "^1.5.0",
"css-loader": "^4",
"dotenv": "^16.0.2",
"eslint": "8.35.0",
"eslint": "8.40.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-deprecate": "^0.7.0",
@@ -127,7 +131,7 @@
"eslint-plugin-matrix-org": "^1.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-unicorn": "^45.0.0",
"eslint-plugin-unicorn": "^47.0.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0",
"fake-indexeddb": "^4.0.0",
"fetch-mock-jest": "^1.5.1",
@@ -135,17 +139,17 @@
"fs-extra": "^11.0.0",
"html-webpack-plugin": "^4.5.2",
"jest": "^29.0.0",
"jest-canvas-mock": "^2.3.0",
"jest-canvas-mock": "2.4.0",
"jest-environment-jsdom": "^29.0.0",
"jest-mock": "^29.0.0",
"jest-raw-loader": "^1.0.1",
"json-loader": "^0.5.7",
"loader-utils": "^3.0.0",
"matrix-mock-request": "^2.5.0",
"matrix-web-i18n": "^1.3.0",
"matrix-web-i18n": "^1.4.0",
"mini-css-extract-plugin": "^1",
"minimist": "^1.2.6",
"mkdirp": "^2.0.0",
"mkdirp": "^3.0.0",
"modernizr": "^3.12.0",
"node-fetch": "^2.6.7",
"optimize-css-assets-webpack-plugin": "^6.0.0",
@@ -159,69 +163,28 @@
"postcss-preset-env": "^6.7.0",
"postcss-scss": "^4.0.4",
"postcss-simple-vars": "^5.0.2",
"prettier": "2.8.4",
"prettier": "2.8.8",
"raw-loader": "^4.0.2",
"rimraf": "^3.0.2",
"rimraf": "^5.0.0",
"semver": "^7.3.7",
"simple-proxy-agent": "^1.1.0",
"string-replace-loader": "3",
"style-loader": "2",
"stylelint": "^15.0.0",
"stylelint-config-prettier": "^9.0.4",
"stylelint-config-standard": "^30.0.0",
"stylelint-scss": "^4.2.0",
"stylelint": "^15.3.0",
"stylelint-config-standard": "^33.0.0",
"stylelint-scss": "^5.0.0",
"terser-webpack-plugin": "^4.0.0",
"ts-node": "^10.9.1",
"ts-prune": "^0.10.3",
"typescript": "4.9.5",
"typescript": "5.0.4",
"webpack": "^4.46.0",
"webpack-bundle-analyzer": "^4.8.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.2",
"worker-loader": "^3.0.0",
"worklet-loader": "^2.0.0",
"yaml": "^2.0.1"
},
"jest": {
"testEnvironment": "jsdom",
"testEnvironmentOptions": {
"url": "http://localhost/"
},
"testMatch": [
"<rootDir>/test/**/*-test.[tj]s?(x)"
],
"setupFiles": [
"jest-canvas-mock"
],
"setupFilesAfterEnv": [
"<rootDir>/node_modules/matrix-react-sdk/test/setupTests.js"
],
"moduleNameMapper": {
"\\.(css|scss|pcss)$": "<rootDir>/__mocks__/cssMock.js",
"\\.(gif|png|ttf|woff2)$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/imageMock.js",
"\\.svg$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/svg.js",
"\\$webapp/i18n/languages.json": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/languages.json",
"^react$": "<rootDir>/node_modules/react",
"^react-dom$": "<rootDir>/node_modules/react-dom",
"^matrix-js-sdk$": "<rootDir>/node_modules/matrix-js-sdk/src",
"^matrix-react-sdk$": "<rootDir>/node_modules/matrix-react-sdk/src",
"decoderWorker\\.min\\.js": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"decoderWorker\\.min\\.wasm": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"waveWorker\\.min\\.js": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"context-filter-polyfill": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js",
"FontManager.ts": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/FontManager.js",
"workers/(.+)\\.worker\\.ts": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/workerMock.js",
"^!!raw-loader!.*": "jest-raw-loader",
"RecorderWorklet": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/empty.js"
},
"transformIgnorePatterns": [
"/node_modules/(?!matrix-js-sdk).+$",
"/node_modules/(?!matrix-react-sdk).+$"
],
"coverageReporters": [
"text-summary",
"lcov"
],
"testResultsProcessor": "@casualbot/jest-sonar-reporter"
},
"@casualbot/jest-sonar-reporter": {
"outputDirectory": "coverage",
"outputName": "jest-sonar-report.xml",

View File

@@ -3,7 +3,12 @@
"apps": [],
"details": [
{
"appID": "7J4U792NQT.im.vector.app",
"appIDs":[
"7J4U792NQT.im.vector.app",
"7J4U792NQT.io.element.elementx",
"7J4U792NQT.io.element.elementx.nightly",
"7J4U792NQT.io.element.elementx.pr"
],
"paths": [
"*"
]
@@ -12,7 +17,10 @@
},
"webcredentials": {
"apps": [
"7J4U792NQT.im.vector.app"
"7J4U792NQT.im.vector.app",
"7J4U792NQT.io.element.elementx",
"7J4U792NQT.io.element.elementx.nightly",
"7J4U792NQT.io.element.elementx.pr"
]
}
}

View File

@@ -167,7 +167,7 @@ we don't have an account and should hide them. No account == no guest account ei
<div class="mx_Parent">
<a href="https://element.io" target="_blank" rel="noopener">
<img src="welcome/images/logo.svg" alt="" class="mx_Logo" />
<img src="$logoUrl" alt="" class="mx_Logo" />
</a>
<h1 class="mx_Header_title">_t("Welcome to Element")</h1>
<!-- XXX: Our translations system isn't smart enough to recognize variables in the HTML, so we manually do it -->
@@ -181,11 +181,6 @@ we don't have an account and should hide them. No account == no guest account ei
<div class="mx_ButtonLabel">_t("Create Account")</div>
</a>
</div>
<!-- The comments below are meant to be used by Ansible as a quick way
to strip out the marked content when desired.
See https://github.com/vector-im/element-web/issues/8622.
TODO: Strip out these comments and rely on the guest flag -->
<!-- BEGIN Ansible: Remove these lines when guest access is disabled -->
<div class="mx_ButtonRow mx_WelcomePage_guestFunctions">
<div>
<a href="#/directory" class="mx_ButtonParent mx_SecondaryButton mx_Button_iconRoomDirectory">
@@ -193,6 +188,5 @@ we don't have an account and should hide them. No account == no guest account ei
</a>
</div>
</div>
<!-- END Ansible: Remove these lines when guest access is disabled -->
</div>
</div>

View File

@@ -1,7 +0,0 @@
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M100 200C155.228 200 200 155.228 200 100C200 44.7715 155.228 0 100 0C44.7715 0 0 44.7715 0 100C0 155.228 44.7715 200 100 200Z" fill="#0DBD8B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M81.7169 46.5946C81.7169 42.5581 84.9959 39.2859 89.0408 39.2859C116.456 39.2859 138.681 61.4642 138.681 88.8225C138.681 92.859 135.401 96.1312 131.357 96.1312C127.312 96.1312 124.033 92.859 124.033 88.8225C124.033 69.5372 108.366 53.9033 89.0408 53.9033C84.9959 53.9033 81.7169 50.6311 81.7169 46.5946Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M153.39 81.5137C157.435 81.5137 160.714 84.7859 160.714 88.8224C160.714 116.181 138.49 138.359 111.075 138.359C107.03 138.359 103.751 135.087 103.751 131.05C103.751 127.014 107.03 123.742 111.075 123.742C130.4 123.742 146.066 108.108 146.066 88.8224C146.066 84.7859 149.345 81.5137 153.39 81.5137Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M118.398 153.405C118.398 157.442 115.119 160.714 111.074 160.714C83.6592 160.714 61.4347 138.536 61.4347 111.177C61.4347 107.141 64.7138 103.869 68.7587 103.869C72.8035 103.869 76.0826 107.141 76.0826 111.177C76.0826 130.463 91.7489 146.097 111.074 146.097C115.119 146.097 118.398 149.369 118.398 153.405Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.6097 118.486C42.5648 118.486 39.2858 115.214 39.2858 111.178C39.2858 83.8193 61.5102 61.6409 88.9255 61.6409C92.9704 61.6409 96.2494 64.9132 96.2494 68.9497C96.2494 72.9862 92.9704 76.2584 88.9255 76.2584C69.6 76.2584 53.9337 91.8922 53.9337 111.178C53.9337 115.214 50.6546 118.486 46.6097 118.486Z" fill="white"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -5,12 +5,12 @@
const fs = require("fs");
const path = require("path");
const mkdirp = require("mkdirp");
const { mkdirpSync } = require("mkdirp");
const fetch = require("node-fetch");
const ProxyAgent = require("simple-proxy-agent");
console.log("Making webapp directory");
mkdirp.sync("webapp");
mkdirpSync("webapp");
// curl -s https://meet.element.io/libs/external_api.min.js > ./webapp/jitsi_external_api.min.js
console.log("Downloading Jitsi script");

View File

@@ -77,7 +77,7 @@ dodep matrix-org matrix-js-sdk
pushd matrix-js-sdk
yarn link
yarn install --pure-lockfile
yarn install --frozen-lockfile
popd
yarn link matrix-js-sdk
@@ -91,7 +91,7 @@ dodep matrix-org matrix-react-sdk
pushd matrix-react-sdk
yarn link
yarn link matrix-js-sdk
yarn install --pure-lockfile
yarn install --frozen-lockfile
popd
yarn link matrix-react-sdk

View File

@@ -14,7 +14,7 @@ set -ex
# for the primary repo (element-web in this case).
# Install dependencies, as we'll be using fetchdep.sh from matrix-react-sdk
yarn install --pure-lockfile
yarn install --frozen-lockfile
# Pass appropriate repo to fetchdep.sh
export PR_ORG=vector-im
@@ -24,7 +24,7 @@ export PR_REPO=element-web
node_modules/matrix-react-sdk/scripts/fetchdep.sh matrix-org matrix-js-sdk
pushd matrix-js-sdk
yarn link
yarn install --pure-lockfile
yarn install --frozen-lockfile
popd
# Also set up matrix-analytics-events so we get the latest from
@@ -32,7 +32,7 @@ popd
node_modules/matrix-react-sdk/scripts/fetchdep.sh matrix-org matrix-analytics-events main
pushd matrix-analytics-events
yarn link
yarn install --pure-lockfile
yarn install --frozen-lockfile
yarn build:ts
popd
@@ -42,7 +42,7 @@ pushd matrix-react-sdk
yarn link
yarn link matrix-js-sdk
yarn link @matrix-org/analytics-events
yarn install --pure-lockfile
yarn install --frozen-lockfile
popd
# Link the layers into element-web

29
src/@types/jitsi-meet.d.ts vendored Normal file
View File

@@ -0,0 +1,29 @@
/*
Copyright 2023 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 "jitsi-meet";
declare module "jitsi-meet" {
interface ExternalAPIEventCallbacks {
errorOccurred: (e: { error: Error & { isFatal?: boolean } }) => void;
}
interface JitsiMeetExternalAPI {
executeCommand(command: "setTileView", value: boolean): void;
}
}
export as namespace Jitsi;

View File

@@ -17,10 +17,10 @@ limitations under the License.
import * as React from "react";
import { _t } from "matrix-react-sdk/src/languageHandler";
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
// directly import the style here as this layer does not support rethemedex at this time so no matrix-react-sdk
// PostCSS variables will be accessible.
import "../../../res/css/structures/ErrorView.pcss";
import { ReactNode } from "react";
interface IProps {
onAccept(): void;
@@ -30,7 +30,7 @@ const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
const brand = SdkConfig.get("brand");
const mobileBuilds = SdkConfig.get("mobile_builds");
let ios = null;
let ios: JSX.Element | undefined;
const iosCustomUrl = mobileBuilds?.ios;
if (iosCustomUrl !== null) {
// could be undefined or a string
@@ -42,6 +42,7 @@ const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
<a
href={iosCustomUrl || "https://apps.apple.com/app/vector/id1083446067"}
target="_blank"
rel="noreferrer noopener"
className="mx_ClearDecoration"
>
<img height="48" src="themes/element/img/download/apple.svg" alt="Apple App Store" />
@@ -63,6 +64,7 @@ const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
<a
href={andCustomUrl || "https://play.google.com/store/apps/details?id=im.vector.app"}
target="_blank"
rel="noreferrer noopener"
className="mx_ClearDecoration"
key="android"
>
@@ -76,6 +78,7 @@ const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
<a
href={fdroidCustomUrl || "https://f-droid.org/repository/browse/?fdid=im.vector.app"}
target="_blank"
rel="noreferrer noopener"
className="mx_ClearDecoration"
key="fdroid"
>
@@ -88,7 +91,7 @@ const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
android = [];
}
let mobileHeader = <h2 id="step2_heading">{_t("Use %(brand)s on mobile", { brand })}</h2>;
let mobileHeader: ReactNode = <h2 id="step2_heading">{_t("Use %(brand)s on mobile", { brand })}</h2>;
if (!android.length && !ios) {
mobileHeader = null;
}

View File

@@ -27,7 +27,7 @@ const VectorAuthFooter = (): ReactElement => {
{ text: "GitHub", url: "https://github.com/vector-im/element-web" },
];
const authFooterLinks = [];
const authFooterLinks: JSX.Element[] = [];
for (const linkEntry of links) {
authFooterLinks.push(
<a href={linkEntry.url} key={linkEntry.text} target="_blank" rel="noreferrer noopener">

View File

@@ -20,7 +20,7 @@ import SdkConfig from "matrix-react-sdk/src/SdkConfig";
import VectorAuthFooter from "./VectorAuthFooter";
export default class VectorAuthPage extends React.PureComponent {
private static welcomeBackgroundUrl;
private static welcomeBackgroundUrl?: string;
// cache the url as a static to prevent it changing without refreshing
private static getWelcomeBackgroundUrl(): string {

View File

@@ -49,7 +49,7 @@ export default class Favicon {
private readonly params: IParams;
private readonly canvas: HTMLCanvasElement;
private readonly baseImage: HTMLImageElement;
private context: CanvasRenderingContext2D;
private context!: CanvasRenderingContext2D;
private icons: HTMLLinkElement[];
private isReady = false;
@@ -72,14 +72,14 @@ export default class Favicon {
// get height and width of the favicon
this.canvas.height = this.baseImage.height > 0 ? this.baseImage.height : 32;
this.canvas.width = this.baseImage.width > 0 ? this.baseImage.width : 32;
this.context = this.canvas.getContext("2d");
this.context = this.canvas.getContext("2d")!;
this.ready();
};
this.baseImage.setAttribute("src", lastIcon.getAttribute("href"));
this.baseImage.setAttribute("src", lastIcon.getAttribute("href")!);
} else {
this.canvas.height = this.baseImage.height = 32;
this.canvas.width = this.baseImage.width = 32;
this.context = this.canvas.getContext("2d");
this.context = this.canvas.getContext("2d")!;
this.ready();
}
}
@@ -152,7 +152,7 @@ export default class Favicon {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.context.drawImage(this.baseImage, 0, 0, this.canvas.width, this.canvas.height);
this.context.beginPath();
const fontSize = Math.floor(opt.h * (opt.n > 99 ? 0.85 : 1)) + "px";
const fontSize = Math.floor(opt.h * (typeof opt.n === "number" && opt.n > 99 ? 0.85 : 1)) + "px";
this.context.font = `${params.fontWeight} ${fontSize} ${params.fontFamily}`;
this.context.textAlign = "center";
@@ -239,7 +239,7 @@ export default class Favicon {
const icons: HTMLLinkElement[] = [];
const links = window.document.getElementsByTagName("head")[0].getElementsByTagName("link");
for (const link of links) {
if (/(^|\s)icon(\s|$)/i.test(link.getAttribute("rel"))) {
if (link.hasAttribute("rel") && /(^|\s)icon(\s|$)/i.test(link.getAttribute("rel")!)) {
icons.push(link);
}
}

3
src/i18n/strings/my.json Normal file
View File

@@ -0,0 +1,3 @@
{
"Invalid configuration: no default server specified.": "ဖွဲ့စည်းပုံ မမှန်ပါ။ default ဆာဗာကို သတ်မှတ်ထားခြင်း မရှိပါ။"
}

View File

@@ -25,5 +25,8 @@
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Vennligst installer <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, eller <safariLink>Safari</safariLink> for den beste opplevelsen.",
"%(brand)s uses advanced browser features which aren't supported by your current browser.": "%(brand)s bruker avanserte nettleserfunksjoner som ikke støttes av din nåværende nettleser.",
"Open": "Åpne",
"Use %(brand)s on mobile": "Bruk %(brand)s på mobil"
"Use %(brand)s on mobile": "Bruk %(brand)s på mobil",
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "Desentralisert, kryptert chat & samhandling basert på $matrixLogo",
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s: %(browserName)s på %(osName)s",
"%(brand)s Desktop: %(platformName)s": "%(brand)s Desktop: %(platformName)s"
}

View File

@@ -25,5 +25,8 @@
"Your Element is misconfigured": "Element er feilkonfigurert",
"Failed to start": "Klarte ikkje å starta",
"Open": "Opna",
"Download Completed": "Nedlasting Fullført"
"Download Completed": "Nedlasting Fullført",
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "Desentralisertd kryptert chatt &amp; samarbeid som vert drive av $matrixLogo",
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s: %(browserName)s på %(osName)s",
"%(brand)s Desktop: %(platformName)s": "%(brand)s Skrivebord: %(platformName)s"
}

View File

@@ -1,5 +1,5 @@
{
"Dismiss": "Zamknij",
"Dismiss": "Pomiń",
"Unknown device": "Nieznane urządzenie",
"Welcome to Element": "Witamy w Element",
"Create Account": "Utwórz konto",
@@ -11,20 +11,22 @@
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Błędna konfiguracja. Akceptowalne wartości to: default_server_config, default_server_name, default_hs_url.",
"Invalid configuration: no default server specified.": "Błędna konfiguracja: nie wybrano domyślnego serwera.",
"Go to your browser to complete Sign In": "Aby dokończyć proces rejestracji, przejdź do swojej przeglądarki",
"Unable to load config file: please refresh the page to try again.": "Nie udało się załadować pliku konfiguracyjnego: odśwież stronę aby spróbować ponownie.",
"Unable to load config file: please refresh the page to try again.": "Nie udało się załadować pliku konfiguracyjnego: odśwież stronę, aby spróbować ponownie.",
"Unsupported browser": "Niewspierana przeglądarka",
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Zainstaluj <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, lub <safariLink>Safari</safariLink> w celu zapewnienia najlepszego działania.",
"You can continue using your current browser, but some or all features may not work and the look and feel of the application may be incorrect.": "Możesz kontynuować używając obecnej przeglądarki, lecz niektóre lub wszystkie funkcje mogą nie działać oraz wygląd aplikacji może być niepoprawny.",
"I understand the risks and wish to continue": "Rozumiem ryzyko i chcę kontynuować",
"Go to element.io": "Przejdź do element.io",
"Failed to start": "Nie udało się wystartować",
"Download Completed": "Pobieranie Zakończone",
"Download Completed": "Pobieranie zakończone",
"Open": "Otwórz",
"Your browser can't run %(brand)s": "Twoja przeglądarka nie obsługuje %(brand)s",
"%(brand)s uses advanced browser features which aren't supported by your current browser.": "%(brand)s używa zaawansowanych funkcji które nie są dostępne w obecnej przeglądarce.",
"Your Element configuration contains invalid JSON. Please correct the problem and reload the page.": "Twoja konfiguracja Elementa zawiera niepoprawny JSON. Rozwiąż problem i odśwież stronę.",
"%(brand)s uses advanced browser features which aren't supported by your current browser.": "%(brand)s używa funkcji zaawansowanych, które nie są dostępne w Twojej przeglądarce.",
"Your Element configuration contains invalid JSON. Please correct the problem and reload the page.": "Twoja konfiguracja Elementa zawiera nieprawidłowy JSON. Rozwiąż problem i odśwież stronę.",
"Your Element is misconfigured": "Twój Element jest nieprawidłowo skonfigurowany",
"Powered by Matrix": "Zasilane przez Matrix",
"Use %(brand)s on mobile": "Użyj %(brand)s w telefonie",
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "Zdecentralizowany, szyfrowany czat i współpraca oparte na $matrixLogo"
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "Zdecentralizowany, szyfrowany czat i współpraca oparte na $matrixLogo",
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s: %(browserName)s na %(osName)s",
"%(brand)s Desktop: %(platformName)s": "Komputer %(brand)s: %(platformName)s"
}

View File

@@ -25,5 +25,6 @@
"Failed to start": "Erro ao iniciar",
"%(brand)s uses advanced browser features which aren't supported by your current browser.": "%(brand)s utiliza funções avançadas que não são suportadas pelo teu atual browser.",
"Your browser can't run %(brand)s": "O teu browser não consegue executar %(brand)s",
"Use %(brand)s on mobile": "Usar %(brand)s no telemóvel"
"Use %(brand)s on mobile": "Usar %(brand)s no telemóvel",
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "Chat descentralizado e encriptado &amp; colaboração alimentada por $matrixLogo"
}

View File

@@ -6,14 +6,14 @@
"The message from the parser is: %(message)s": "Thông báo của trình xử lý là: %(message)s",
"Invalid JSON": "JSON không hợp lệ",
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Thiết lập không hợp lệ: chỉ có thể điền một trong số sau default_server_config, default_server_name, hoặc default_hs_url.",
"Invalid configuration: no default server specified.": "Cấu hình không hợp lệ: chưa chỉ định máy chủ mặc định.",
"Invalid configuration: no default server specified.": "Thiết lập không hợp lệ: chưa chỉ định máy chủ mặc định.",
"Sign In": "Đăng nhập",
"Create Account": "Tạo tài khoản",
"Explore rooms": "Khám phá phòng chat",
"Explore rooms": "Khám phá các phòng",
"Download Completed": "Tải xuống hoàn tất",
"Go to element.io": i đến element.io",
"I understand the risks and wish to continue": "Tôi hiểu các rủi ro và muốn tiếp tục",
"You can continue using your current browser, but some or all features may not work and the look and feel of the application may be incorrect.": "Bạn có thể tiếp tục sử dụng trình duyệt hiện tại, tuy nhiên một số hoặc tất cả tính năng có thể sẽ không hoạt động và trải nghiệm ứng dụng có thể sẽ không được tốt.",
"Go to element.io": "Đến element.io",
"I understand the risks and wish to continue": "Tôi hiểu rủi ro và muốn tiếp tục",
"You can continue using your current browser, but some or all features may not work and the look and feel of the application may be incorrect.": "Bạn có thể tiếp tục sử dụng trình duyệt hiện tại, tuy nhiên các tính năng có thể sẽ không hoạt động và trải nghiệm ứng dụng có thể sẽ không được tốt.",
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.": "Hãy cài đặt <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, hoặc <safariLink>Safari</safariLink> để có trải nghiệm tốt nhất.",
"%(brand)s uses advanced browser features which aren't supported by your current browser.": "%(brand)s sử dụng một số tính năng nâng cao mà trình duyệt của bạn không thể đáp ứng.",
"Your browser can't run %(brand)s": "Trình duyệt của bạn không thể chạy %(brand)s",
@@ -21,10 +21,12 @@
"Go to your browser to complete Sign In": "Mở trình duyệt web để hoàn thành đăng nhập",
"Open": "Mở",
"Unable to load config file: please refresh the page to try again.": "Không thể tải tệp cấu hình: hãy tải lại trang để thử lại.",
"Failed to start": "Khởi động thất bại",
"Failed to start": "Không khởi động được",
"Use %(brand)s on mobile": "Sử dụng %(brand)s trên di động",
"Powered by Matrix": "Được chạy trên giao thức Matrix",
"Your Element configuration contains invalid JSON. Please correct the problem and reload the page.": "Thiết lập Element của bạn chứa JSON không hợp lệ. Vui lòng sửa vấn đề và tải lại trang.",
"Your Element is misconfigured": "Element của bạn bị thiết lập sai",
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "Dịch vụ chat &amp; liên lạc đã được mã hóa, phi tập trung. Được cung cấp bởi $matrixLogo"
"Your Element configuration contains invalid JSON. Please correct the problem and reload the page.": "Thiết lập Element của bạn đang chứa JSON không hợp lệ. Vui lòng sửa lại và tải lại trang.",
"Your Element is misconfigured": "Element đang bị thiết lập sai",
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "Dịch vụ nhắn tin &amp; liên lạc được mã hóa, phi tập trung. Được cung cấp bởi $matrixLogo",
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s: %(browserName)s trên %(osName)s",
"%(brand)s Desktop: %(platformName)s": "%(brand)s máy tính: %(platformName)s"
}

View File

@@ -1,7 +1,7 @@
{
"Dismiss": "關閉",
"Unknown device": "未知裝置",
"Welcome to Element": "歡迎來到 Element",
"Welcome to Element": "歡迎使用 Element",
"Sign In": "登入",
"Create Account": "建立帳號",
"Explore rooms": "探索聊天室",
@@ -20,13 +20,13 @@
"Failed to start": "啟動失敗",
"Download Completed": "下載完成",
"Open": "開啟",
"Your Element is misconfigured": "您的 Element 配置錯誤",
"Your Element configuration contains invalid JSON. Please correct the problem and reload the page.": "您的 Element 的配置中包含無效 JSON更正錯誤並重新加載網頁。",
"Your Element is misconfigured": "您的 Element 設定錯誤",
"Your Element configuration contains invalid JSON. Please correct the problem and reload the page.": "您的 Element 設定中包含無效 JSON修正後重新載入網頁。",
"Your browser can't run %(brand)s": "您的瀏覽器無法執行 %(brand)s",
"%(brand)s uses advanced browser features which aren't supported by your current browser.": "%(brand)s 使用了您目前瀏覽器不支援的進階功能。",
"Powered by Matrix": " Matrix 驅動",
"Powered by Matrix": "Powered by Matrix",
"Use %(brand)s on mobile": "在行動裝置上使用 %(brand)s",
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "去中心化、加密的聊天與協作,由 $matrixLogo 驅動",
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s%(browserName)s 位於 %(osName)s",
"%(brand)s Desktop: %(platformName)s": "%(brand)s 桌面:%(platformName)s"
"Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo": "由 $matrixLogo 驅動的去中心化、加密的聊天與協作工具",
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s%(osName)s %(browserName)s",
"%(brand)s Desktop: %(platformName)s": "%(brand)s 桌面%(platformName)s"
}

View File

@@ -23,9 +23,9 @@ import "matrix-js-sdk/src/browser-index";
import React, { ReactElement } from "react";
import PlatformPeg from "matrix-react-sdk/src/PlatformPeg";
import { _td, newTranslatableError } from "matrix-react-sdk/src/languageHandler";
import { UserFriendlyError } from "matrix-react-sdk/src/languageHandler";
import AutoDiscoveryUtils from "matrix-react-sdk/src/utils/AutoDiscoveryUtils";
import { AutoDiscovery } from "matrix-js-sdk/src/autodiscovery";
import { AutoDiscovery, ClientConfig } from "matrix-js-sdk/src/autodiscovery";
import * as Lifecycle from "matrix-react-sdk/src/Lifecycle";
import SdkConfig, { parseSsoRedirectOptions } from "matrix-react-sdk/src/SdkConfig";
import { IConfigOptions } from "matrix-react-sdk/src/IConfigOptions";
@@ -33,6 +33,8 @@ import { logger } from "matrix-js-sdk/src/logger";
import { createClient } from "matrix-js-sdk/src/matrix";
import { SnakedObject } from "matrix-react-sdk/src/utils/SnakedObject";
import MatrixChat from "matrix-react-sdk/src/components/structures/MatrixChat";
import { ValidatedServerConfig } from "matrix-react-sdk/src/utils/ValidatedServerConfig";
import { QueryDict, encodeParams } from "matrix-js-sdk/src/utils";
import { parseQs } from "./url_utils";
import VectorBasePlatform from "./platform/VectorBasePlatform";
@@ -55,24 +57,19 @@ window.matrixLogger = logger;
// If we're in electron, we should never pass through a file:// URL otherwise
// the identity server will try to 302 the browser to it, which breaks horribly.
// so in that instance, hardcode to use app.element.io for now instead.
function makeRegistrationUrl(params: object): string {
let url;
function makeRegistrationUrl(params: QueryDict): string {
let url: string;
if (window.location.protocol === "vector:") {
url = "https://app.element.io/#/register";
} else {
url = window.location.protocol + "//" + window.location.host + window.location.pathname + "#/register";
}
const keys = Object.keys(params);
for (let i = 0; i < keys.length; ++i) {
if (i === 0) {
url += "?";
} else {
url += "&";
}
const k = keys[i];
url += k + "=" + encodeURIComponent(params[k]);
const encodedParams = encodeParams(params);
if (encodedParams) {
url += "?" + encodedParams;
}
return url;
}
@@ -117,18 +114,19 @@ export async function loadApp(fragParams: {}): Promise<ReactElement> {
if (!hasPossibleToken && !isReturningFromSso && autoRedirect) {
logger.log("Bypassing app load to redirect to SSO");
const tempCli = createClient({
baseUrl: config.validated_server_config.hsUrl,
idBaseUrl: config.validated_server_config.isUrl,
baseUrl: config.validated_server_config!.hsUrl,
idBaseUrl: config.validated_server_config!.isUrl,
});
PlatformPeg.get().startSingleSignOn(tempCli, "sso", `/${getScreenFromLocation(window.location).screen}`);
PlatformPeg.get()!.startSingleSignOn(tempCli, "sso", `/${getScreenFromLocation(window.location).screen}`);
// We return here because startSingleSignOn() will asynchronously redirect us. We don't
// care to wait for it, and don't want to show any UI while we wait (not even half a welcome
// page). As such, just don't even bother loading the MatrixChat component.
return;
return <React.Fragment />;
}
const defaultDeviceName = snakedConfig.get("default_device_display_name") ?? platform.getDefaultDeviceDisplayName();
const defaultDeviceName =
snakedConfig.get("default_device_display_name") ?? platform?.getDefaultDeviceDisplayName();
return (
<MatrixChat
@@ -146,7 +144,7 @@ export async function loadApp(fragParams: {}): Promise<ReactElement> {
}
async function verifyServerConfig(): Promise<IConfigOptions> {
let validatedConfig;
let validatedConfig: ValidatedServerConfig;
try {
logger.log("Verifying homeserver configuration");
@@ -168,16 +166,14 @@ async function verifyServerConfig(): Promise<IConfigOptions> {
const incompatibleOptions = [wkConfig, serverName, hsUrl].filter((i) => !!i);
if (incompatibleOptions.length > 1) {
// noinspection ExceptionCaughtLocallyJS
throw newTranslatableError(
_td(
"Invalid configuration: can only specify one of default_server_config, default_server_name, " +
"or default_hs_url.",
),
throw new UserFriendlyError(
"Invalid configuration: can only specify one of default_server_config, default_server_name, " +
"or default_hs_url.",
);
}
if (incompatibleOptions.length < 1) {
// noinspection ExceptionCaughtLocallyJS
throw newTranslatableError(_td("Invalid configuration: no default server specified."));
throw new UserFriendlyError("Invalid configuration: no default server specified.");
}
if (hsUrl) {
@@ -199,7 +195,7 @@ async function verifyServerConfig(): Promise<IConfigOptions> {
}
}
let discoveryResult = null;
let discoveryResult: ClientConfig | undefined;
if (wkConfig) {
logger.log("Config uses a default_server_config - validating object");
discoveryResult = await AutoDiscovery.fromDiscoveryConfig(wkConfig);

View File

@@ -18,16 +18,22 @@ import type { IConfigOptions } from "matrix-react-sdk/src/IConfigOptions";
// Load the config file. First try to load up a domain-specific config of the
// form "config.$domain.json" and if that fails, fall back to config.json.
export async function getVectorConfig(relativeLocation = ""): Promise<IConfigOptions> {
export async function getVectorConfig(relativeLocation = ""): Promise<IConfigOptions | undefined> {
if (relativeLocation !== "" && !relativeLocation.endsWith("/")) relativeLocation += "/";
const specificConfigPromise = getConfig(`${relativeLocation}config.${document.domain}.json`);
// Handle trailing dot FQDNs
let domain = window.location.hostname.trimEnd();
if (domain[domain.length - 1] === ".") {
domain = domain.slice(0, -1);
}
const specificConfigPromise = getConfig(`${relativeLocation}config.${domain}.json`);
const generalConfigPromise = getConfig(relativeLocation + "config.json");
try {
const configJson = await specificConfigPromise;
// 404s succeed with an empty json config, so check that there are keys
if (Object.keys(configJson).length === 0) {
if (!configJson || Object.keys(configJson).length === 0) {
throw new Error(); // throw to enter the catch
}
return configJson;
@@ -36,7 +42,7 @@ export async function getVectorConfig(relativeLocation = ""): Promise<IConfigOpt
}
}
async function getConfig(configJsonFilename: string): Promise<IConfigOptions> {
async function getConfig(configJsonFilename: string): Promise<IConfigOptions | undefined> {
const url = new URL(configJsonFilename, window.location.href);
url.searchParams.set("cachebuster", Date.now().toString());
const res = await fetch(url, {

View File

@@ -26,7 +26,7 @@
<meta http-equiv="Content-Security-Policy" content="
default-src 'none';
style-src 'self' 'unsafe-inline' <%= csp_extra_source %>;
script-src 'self' 'unsafe-eval' https://www.recaptcha.net https://www.gstatic.com <%= csp_extra_source %>;
script-src 'self' 'wasm-unsafe-eval' https://www.recaptcha.net/recaptcha/ https://www.gstatic.com/recaptcha/ <%= csp_extra_source %>;
img-src * blob: data:;
connect-src *;
font-src 'self' data: <%= csp_extra_source %>;
@@ -93,6 +93,10 @@
<source src="media/busy.ogg" type="audio/ogg" />
<source src="media/busy.mp3" type="audio/mpeg" />
</audio>
<audio id="errorAudio">
<source src="media/error.ogg" type="audio/ogg" />
<source src="media/error.mp3" type="audio/mpeg" />
</audio>
<audio id="remoteAudio"></audio>
<!-- let CSS themes pass constants to the app -->
<div id="mx_theme_accentColor"></div><div id="mx_theme_secondaryAccentColor"></div><div id="mx_theme_tertiaryAccentColor"></div>

View File

@@ -19,6 +19,7 @@ limitations under the License.
*/
import { logger } from "matrix-js-sdk/src/logger";
import { extractErrorMessageFromError } from "matrix-react-sdk/src/components/views/dialogs/ErrorDialog";
// These are things that can run before the skin loads - be careful not to reference the react-sdk though.
import { parseQsFromFragment } from "./url_utils";
@@ -71,7 +72,7 @@ function checkBrowserFeatures(): boolean {
// ES2019: http://262.ecma-international.org/10.0/#sec-object.fromentries
window.Modernizr.addTest("objectfromentries", () => typeof window.Object?.fromEntries === "function");
const featureList = Object.keys(window.Modernizr);
const featureList = Object.keys(window.Modernizr) as Array<keyof ModernizrStatic>;
let featureComplete = true;
for (const feature of featureList) {
@@ -194,7 +195,7 @@ async function start(): Promise<void> {
await loadConfigPromise;
} catch (error) {
// Now that we've loaded the theme (CSS), display the config syntax error if needed.
if (error.err && error.err instanceof SyntaxError) {
if (error instanceof SyntaxError) {
// This uses the default brand since the app config is unavailable.
return showError(_t("Your Element is misconfigured"), [
_t(
@@ -202,7 +203,7 @@ async function start(): Promise<void> {
"Please correct the problem and reload the page.",
),
_t("The message from the parser is: %(message)s", {
message: error.err.message || _t("Invalid JSON"),
message: error.message || _t("Invalid JSON"),
}),
]);
}
@@ -231,7 +232,7 @@ async function start(): Promise<void> {
// Like the compatibility page, AWOOOOOGA at the user
// This uses the default brand since the app config is unavailable.
await showError(_t("Your Element is misconfigured"), [
err.translatedMessage || _t("Unexpected error preparing the app. See console for details."),
extractErrorMessageFromError(err, _t("Unexpected error preparing the app. See console for details.")),
]);
}
}
@@ -240,7 +241,7 @@ start().catch((err) => {
logger.error(err);
// show the static error in an iframe to not lose any context / console data
// with some basic styling to make the iframe full page
delete document.body.style.height;
document.body.style.removeProperty("height");
const iframe = document.createElement("iframe");
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - typescript seems to only like the IE syntax for iframe sandboxing
@@ -254,5 +255,5 @@ start().catch((err) => {
iframe.style.right = "0";
iframe.style.bottom = "0";
iframe.style.border = "0";
document.getElementById("matrixchat").appendChild(iframe);
document.getElementById("matrixchat")?.appendChild(iframe);
});

View File

@@ -67,11 +67,11 @@ export async function loadConfig(): Promise<void> {
// granular settings are loaded correctly and to avoid duplicating the override logic for the theme.
//
// Note: this isn't called twice for some wrappers, like the Jitsi wrapper.
const platformConfig = await PlatformPeg.get().getConfig();
const platformConfig = await PlatformPeg.get()?.getConfig();
if (platformConfig) {
SdkConfig.put(platformConfig);
} else {
SdkConfig.unset(); // clears the config (sets to empty object)
SdkConfig.reset();
}
}
@@ -119,7 +119,7 @@ export function loadOlm(): Promise<void> {
export async function loadLanguage(): Promise<void> {
const prefLang = SettingsStore.getValue("language", null, /*excludeDefault=*/ true);
let langs = [];
let langs: string[] = [];
if (!prefLang) {
languageHandler.getLanguagesFromBrowser().forEach((l) => {
@@ -163,7 +163,7 @@ export async function showError(title: string, messages?: string[]): Promise<voi
);
}
export async function showIncompatibleBrowser(onAccept): Promise<void> {
export async function showIncompatibleBrowser(onAccept: () => void): Promise<void> {
const CompatibilityView = (
await import(
/* webpackChunkName: "compatibility-view" */

View File

@@ -30,6 +30,14 @@ import { IConfigOptions } from "matrix-react-sdk/src/IConfigOptions";
import { SnakedObject } from "matrix-react-sdk/src/utils/SnakedObject";
import { ElementWidgetCapabilities } from "matrix-react-sdk/src/stores/widgets/ElementWidgetCapabilities";
import type {
JitsiMeetExternalAPIConstructor,
ExternalAPIEventCallbacks,
JitsiMeetExternalAPI as _JitsiMeetExternalAPI,
AudioMuteStatusChangedEvent,
LogEvent,
VideoMuteStatusChangedEvent,
} from "jitsi-meet";
import { getVectorConfig } from "../getconfig";
// We have to trick webpack into loading our CSS for us.
@@ -40,7 +48,7 @@ const JITSI_OPENIDTOKEN_JWT_AUTH = "openidtoken-jwt";
// Dev note: we use raw JS without many dependencies to reduce bundle size.
// We do not need all of React to render a Jitsi conference.
declare let JitsiMeetExternalAPI: any;
declare let JitsiMeetExternalAPI: JitsiMeetExternalAPIConstructor;
let inConference = false;
@@ -52,15 +60,16 @@ let avatarUrl: string;
let userId: string;
let jitsiAuth: string;
let roomId: string;
let openIdToken: IOpenIDCredentials;
let roomName: string;
let startAudioOnly: boolean;
let startWithAudioMuted: boolean | undefined;
let startWithVideoMuted: boolean | undefined;
let isVideoChannel: boolean;
let supportsScreensharing: boolean;
let language: string;
let widgetApi: WidgetApi;
let meetApi: any; // JitsiMeetExternalAPI
let widgetApi: WidgetApi | undefined;
let meetApi: _JitsiMeetExternalAPI | undefined;
let skipOurWelcomeScreen = false;
const setupCompleted = (async (): Promise<string | void> => {
@@ -80,6 +89,13 @@ const setupCompleted = (async (): Promise<string | void> => {
}
return vals[0];
};
const parseBooleanOrUndefined = (value: string | undefined): boolean | undefined => {
if (value === undefined) {
return undefined;
}
return value === "true";
};
// If we have these params, expect a widget API to be available (ie. to be in an iframe
// inside a matrix client). Otherwise, assume we're on our own, eg. have been popped
@@ -94,12 +110,12 @@ const setupCompleted = (async (): Promise<string | void> => {
}
// Set this up as early as possible because Element will be hitting it almost immediately.
let widgetApiReady: Promise<void>;
let widgetApiReady: Promise<void> | undefined;
if (parentUrl && widgetId) {
const parentOrigin = new URL(qsParam("parentUrl")).origin;
widgetApi = new WidgetApi(qsParam("widgetId"), parentOrigin);
widgetApiReady = new Promise<void>((resolve) => widgetApi.once("ready", resolve));
widgetApiReady = new Promise<void>((resolve) => widgetApi!.once("ready", resolve));
widgetApi.requestCapabilities(VideoConferenceCapabilities);
// jitsi cannot work in a popup if auth token is provided because widgetApi is not available there
@@ -114,7 +130,7 @@ const setupCompleted = (async (): Promise<string | void> => {
action: WidgetApiAction,
handler: (request: IWidgetApiRequestData) => Promise<void>,
): void => {
widgetApi.on(`action:${action}`, async (ev: CustomEvent<IWidgetApiRequest>) => {
widgetApi!.on(`action:${action}`, async (ev: CustomEvent<IWidgetApiRequest>) => {
ev.preventDefault();
await setupCompleted;
@@ -130,7 +146,7 @@ const setupCompleted = (async (): Promise<string | void> => {
}
}
await widgetApi.transport.reply(ev.detail, response);
await widgetApi!.transport.reply(ev.detail, response);
});
};
@@ -141,7 +157,7 @@ const setupCompleted = (async (): Promise<string | void> => {
if (force === true) {
meetApi?.dispose();
notifyHangup();
meetApi = null;
meetApi = undefined;
closeConference();
} else {
meetApi?.executeCommand("hangup");
@@ -197,14 +213,17 @@ const setupCompleted = (async (): Promise<string | void> => {
roomId = qsParam("roomId", true);
roomName = qsParam("roomName", true);
startAudioOnly = qsParam("isAudioOnly", true) === "true";
startWithAudioMuted = parseBooleanOrUndefined(qsParam("startWithAudioMuted", true));
startWithVideoMuted = parseBooleanOrUndefined(qsParam("startWithVideoMuted", true));
isVideoChannel = qsParam("isVideoChannel", true) === "true";
supportsScreensharing = qsParam("supportsScreensharing", true) === "true";
// We've reached the point where we have to wait for the config, so do that then parse it.
const instanceConfig = new SnakedObject<IConfigOptions>((await configPromise) ?? <IConfigOptions>{});
const jitsiConfig = instanceConfig.get("jitsi_widget") ?? {};
skipOurWelcomeScreen =
new SnakedObject<IConfigOptions["jitsi_widget"]>(jitsiConfig).get("skip_built_in_welcome_screen") ?? false;
const jitsiConfig = instanceConfig.get("jitsi_widget");
if (jitsiConfig) {
skipOurWelcomeScreen = new SnakedObject(jitsiConfig).get("skip_built_in_welcome_screen") ?? false;
}
// Either reveal the prejoin screen, or skip straight to Jitsi depending on the config.
// We don't set up the call yet though as this might lead to failure without the widget API.
@@ -212,13 +231,6 @@ const setupCompleted = (async (): Promise<string | void> => {
if (widgetApi) {
await widgetApiReady;
// See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) {
// Request credentials, give callback to continue when received
openIdToken = await widgetApi.requestOpenIDConnectToken();
logger.log("Got OpenID Connect token");
}
}
// Now that everything should be set up, skip to the Jitsi splash screen if needed
@@ -229,12 +241,12 @@ const setupCompleted = (async (): Promise<string | void> => {
enableJoinButton(); // always enable the button
} catch (e) {
logger.error("Error setting up Jitsi widget", e);
document.getElementById("widgetActionContainer").innerText = "Failed to load Jitsi widget";
document.getElementById("widgetActionContainer")!.innerText = "Failed to load Jitsi widget";
}
})();
function enableJoinButton(): void {
document.getElementById("joinButton").onclick = (): void => joinConference();
document.getElementById("joinButton")!.onclick = (): Promise<void> => joinConference();
}
function switchVisibleContainers(): void {
@@ -248,9 +260,9 @@ function switchVisibleContainers(): void {
}
function toggleConferenceVisibility(inConference: boolean): void {
document.getElementById("jitsiContainer").style.visibility = inConference ? "unset" : "hidden";
document.getElementById("jitsiContainer")!.style.visibility = inConference ? "unset" : "hidden";
// Video rooms have a separate UI for joining, so they should never show our join button
document.getElementById("joinButtonContainer").style.visibility =
document.getElementById("joinButtonContainer")!.style.visibility =
inConference || isVideoChannel ? "hidden" : "unset";
}
@@ -260,11 +272,11 @@ function skipToJitsiSplashScreen(): void {
}
/**
* Create a JWT token fot jitsi openidtoken-jwt auth
* Create a JWT token for jitsi openidtoken-jwt auth
*
* See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
*/
function createJWTToken(): string {
function createJWTToken(openIdToken: IOpenIDCredentials): string {
// Header
const header = { alg: "HS256", typ: "JWT" };
// Payload
@@ -308,7 +320,7 @@ async function notifyHangup(errorMessage?: string): Promise<void> {
function closeConference(): void {
switchVisibleContainers();
document.getElementById("jitsiContainer").innerHTML = "";
document.getElementById("jitsiContainer")!.innerHTML = "";
if (skipOurWelcomeScreen) {
skipToJitsiSplashScreen();
@@ -345,17 +357,21 @@ function mapLanguage(language: string): string {
// audio input it can find, while an input of null instructs it to start muted,
// and a non-nullish input specifies the label of a specific device to use.
// Same for video inputs.
function joinConference(audioInput?: string | null, videoInput?: string | null): void {
let jwt;
async function joinConference(audioInput?: string | null, videoInput?: string | null): Promise<void> {
let jwt: string | undefined;
if (jitsiAuth === JITSI_OPENIDTOKEN_JWT_AUTH) {
// See https://github.com/matrix-org/prosody-mod-auth-matrix-user-verification
const openIdToken = await widgetApi?.requestOpenIDConnectToken();
logger.log("Got OpenID Connect token");
if (!openIdToken?.access_token) {
// eslint-disable-line camelcase
// We've failing to get a token, don't try to init conference
logger.warn("Expected to have an OpenID credential, cannot initialize widget.");
document.getElementById("widgetActionContainer").innerText = "Failed to load Jitsi widget";
document.getElementById("widgetActionContainer")!.innerText = "Failed to load Jitsi widget";
return;
}
jwt = createJWTToken();
jwt = createJWTToken(openIdToken);
}
switchVisibleContainers();
@@ -369,7 +385,7 @@ function joinConference(audioInput?: string | null, videoInput?: string | null):
const options = {
width: "100%",
height: "100%",
parentNode: document.querySelector("#jitsiContainer"),
parentNode: document.querySelector("#jitsiContainer") ?? undefined,
roomName: conferenceId,
devices: {
audioInput,
@@ -388,8 +404,8 @@ function joinConference(audioInput?: string | null, videoInput?: string | null):
configOverwrite: {
subject: roomName,
startAudioOnly,
startWithAudioMuted: audioInput === null,
startWithVideoMuted: videoInput === null,
startWithAudioMuted: audioInput === null ? true : startWithAudioMuted,
startWithVideoMuted: videoInput === null ? true : startWithVideoMuted,
// Request some log levels for inclusion in rageshakes
// Ideally we would capture all possible log levels, but this can
// cause Jitsi Meet to try to post various circular data structures
@@ -427,13 +443,13 @@ function joinConference(audioInput?: string | null, videoInput?: string | null):
// (regardless of video on or off)
meetApi.on("videoConferenceJoined", onVideoConferenceJoined);
meetApi.on("videoConferenceLeft", onVideoConferenceLeft);
meetApi.on("readyToClose", closeConference);
meetApi.on("readyToClose", closeConference as ExternalAPIEventCallbacks["readyToClose"]);
meetApi.on("errorOccurred", onErrorOccurred);
meetApi.on("audioMuteStatusChanged", onAudioMuteStatusChanged);
meetApi.on("videoMuteStatusChanged", onVideoMuteStatusChanged);
["videoConferenceJoined", "participantJoined", "participantLeft"].forEach((event) => {
meetApi.on(event, updateParticipants);
(["videoConferenceJoined", "participantJoined", "participantLeft"] as const).forEach((event) => {
meetApi!.on(event, updateParticipants);
});
// Patch logs into rageshakes
@@ -449,9 +465,9 @@ const onVideoConferenceJoined = (): void => {
// We can't just use these commands immediately after creating the
// iframe, because there's *another* bug where they can crash Jitsi by
// racing with its startup process.
if (displayName) meetApi.executeCommand("displayName", displayName);
if (displayName) meetApi?.executeCommand("displayName", displayName);
// This doesn't have a userInfo equivalent, so has to be set via commands
if (avatarUrl) meetApi.executeCommand("avatarUrl", avatarUrl);
if (avatarUrl) meetApi?.executeCommand("avatarUrl", avatarUrl);
if (widgetApi) {
// ignored promise because we don't care if it works
@@ -461,30 +477,30 @@ const onVideoConferenceJoined = (): void => {
}
// Video rooms should start in tile mode
if (isVideoChannel) meetApi.executeCommand("setTileView", true);
if (isVideoChannel) meetApi?.executeCommand("setTileView", true);
};
const onVideoConferenceLeft = (): void => {
notifyHangup();
meetApi = null;
meetApi = undefined;
};
const onErrorOccurred = ({ error }): void => {
const onErrorOccurred = ({ error }: Parameters<ExternalAPIEventCallbacks["errorOccurred"]>[0]): void => {
if (error.isFatal) {
// We got disconnected. Since Jitsi Meet might send us back to the
// prejoin screen, we're forced to act as if we hung up entirely.
notifyHangup(error.message);
meetApi = null;
meetApi = undefined;
closeConference();
}
};
const onAudioMuteStatusChanged = ({ muted }): void => {
const onAudioMuteStatusChanged = ({ muted }: AudioMuteStatusChangedEvent): void => {
const action = muted ? ElementWidgetActions.MuteAudio : ElementWidgetActions.UnmuteAudio;
widgetApi?.transport.send(action, {});
};
const onVideoMuteStatusChanged = ({ muted }): void => {
const onVideoMuteStatusChanged = ({ muted }: VideoMuteStatusChangedEvent): void => {
if (muted) {
// Jitsi Meet always sends a "video muted" event directly before
// hanging up, which we need to ignore by padding the timeout here,
@@ -500,8 +516,9 @@ const onVideoMuteStatusChanged = ({ muted }): void => {
const updateParticipants = (): void => {
widgetApi?.transport.send(ElementWidgetActions.CallParticipants, {
participants: meetApi.getParticipantsInfo(),
participants: meetApi?.getParticipantsInfo(),
});
};
const onLog = ({ logLevel, args }): void => (parent as unknown as typeof global).mx_rage_logger?.log(logLevel, ...args);
const onLog = ({ logLevel, args }: LogEvent): void =>
(parent as unknown as typeof global).mx_rage_logger?.log(logLevel, ...args);

View File

@@ -31,17 +31,17 @@ function renderConfigError(message: string): void {
}
async function initPage(): Promise<void> {
document.getElementById("back_to_element_button").onclick = onBackToElementClick;
document.getElementById("back_to_element_button")!.onclick = onBackToElementClick;
const config = await getVectorConfig("..");
// We manually parse the config similar to how validateServerConfig works because
// calling that function pulls in roughly 4mb of JS we don't use.
const wkConfig = config["default_server_config"]; // overwritten later under some conditions
const serverName = config["default_server_name"];
const defaultHsUrl = config["default_hs_url"];
const defaultIsUrl = config["default_is_url"];
const wkConfig = config?.["default_server_config"]; // overwritten later under some conditions
const serverName = config?.["default_server_name"];
const defaultHsUrl = config?.["default_hs_url"];
const defaultIsUrl = config?.["default_is_url"];
const incompatibleOptions = [wkConfig, serverName, defaultHsUrl].filter((i) => !!i);
if (incompatibleOptions.length > 1) {
@@ -54,13 +54,13 @@ async function initPage(): Promise<void> {
return renderConfigError("Invalid configuration: no default server specified.");
}
let hsUrl = "";
let isUrl = "";
let hsUrl: string | undefined;
let isUrl: string | undefined;
if (wkConfig && wkConfig["m.homeserver"]) {
if (typeof wkConfig?.["m.homeserver"]?.["base_url"] === "string") {
hsUrl = wkConfig["m.homeserver"]["base_url"];
if (wkConfig["m.identity_server"]) {
if (typeof wkConfig["m.identity_server"]?.["base_url"] === "string") {
isUrl = wkConfig["m.identity_server"]["base_url"];
}
}
@@ -96,17 +96,19 @@ async function initPage(): Promise<void> {
if (isUrl && !isUrl.endsWith("/")) isUrl += "/";
if (hsUrl !== "https://matrix.org/") {
(document.getElementById("configure_element_button") as HTMLAnchorElement).href =
"https://mobile.element.io?hs_url=" + encodeURIComponent(hsUrl) + "&is_url=" + encodeURIComponent(isUrl);
document.getElementById("step1_heading").innerHTML = "1: Install the app";
document.getElementById("step2_container").style.display = "block";
document.getElementById("hs_url").innerText = hsUrl;
let url = "https://mobile.element.io?hs_url=" + encodeURIComponent(hsUrl);
if (isUrl) {
document.getElementById("custom_is").style.display = "block";
document.getElementById("is_url").style.display = "block";
document.getElementById("is_url").innerText = isUrl;
document.getElementById("custom_is")!.style.display = "block";
document.getElementById("is_url")!.style.display = "block";
document.getElementById("is_url")!.innerText = isUrl;
url += "&is_url=" + encodeURIComponent(isUrl ?? "");
}
(document.getElementById("configure_element_button") as HTMLAnchorElement).href = url;
document.getElementById("step1_heading")!.innerHTML = "1: Install the app";
document.getElementById("step2_container")!.style.display = "block";
document.getElementById("hs_url")!.innerText = hsUrl;
}
}

View File

@@ -40,11 +40,21 @@ import ToastStore from "matrix-react-sdk/src/stores/ToastStore";
import GenericExpiringToast from "matrix-react-sdk/src/components/views/toasts/GenericExpiringToast";
import { logger } from "matrix-js-sdk/src/logger";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { BreadcrumbsStore } from "matrix-react-sdk/src/stores/BreadcrumbsStore";
import { UPDATE_EVENT } from "matrix-react-sdk/src/stores/AsyncStore";
import { avatarUrlForRoom, getInitialLetter } from "matrix-react-sdk/src/Avatar";
import VectorBasePlatform from "./VectorBasePlatform";
import { SeshatIndexManager } from "./SeshatIndexManager";
import { IPCManager } from "./IPCManager";
interface SquirrelUpdate {
releaseNotes: string;
releaseName: string;
releaseDate: Date;
updateURL: string;
}
const isMac = navigator.platform.toUpperCase().includes("MAC");
function platformFriendlyName(): string {
@@ -69,7 +79,7 @@ function platformFriendlyName(): string {
function onAction(payload: ActionPayload): void {
// Whitelist payload actions, no point sending most across
if (["call_state"].includes(payload.action)) {
window.electron.send("app_onAction", payload);
window.electron!.send("app_onAction", payload);
}
}
@@ -95,6 +105,10 @@ export default class ElectronPlatform extends VectorBasePlatform {
public constructor() {
super();
if (!window.electron) {
throw new Error("Cannot instantiate ElectronPlatform, window.electron is not set");
}
dis.register(onAction);
/*
IPC Call `check_updates` returns:
@@ -125,12 +139,12 @@ export default class ElectronPlatform extends VectorBasePlatform {
const key = `DOWNLOAD_TOAST_${id}`;
const onAccept = (): void => {
window.electron.send("userDownloadAction", { id, open: true });
window.electron!.send("userDownloadAction", { id, open: true });
ToastStore.sharedInstance().dismissToast(key);
};
const onDismiss = (): void => {
window.electron.send("userDownloadAction", { id });
window.electron!.send("userDownloadAction", { id });
};
ToastStore.sharedInstance().addOrReplaceToast({
@@ -150,13 +164,29 @@ export default class ElectronPlatform extends VectorBasePlatform {
});
this.ipc.call("startSSOFlow", this.ssoID);
BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
}
public async getConfig(): Promise<IConfigOptions> {
public async getConfig(): Promise<IConfigOptions | undefined> {
return this.ipc.call("getConfig");
}
private onUpdateDownloaded = async (ev, { releaseNotes, releaseName }): Promise<void> => {
private onBreadcrumbsUpdate = (): void => {
const rooms = BreadcrumbsStore.instance.rooms.slice(0, 7).map((r) => ({
roomId: r.roomId,
avatarUrl: avatarUrlForRoom(
r,
Math.floor(60 * window.devicePixelRatio),
Math.floor(60 * window.devicePixelRatio),
"crop",
),
initial: getInitialLetter(r.name),
}));
this.ipc.call("breadcrumbs", rooms);
};
private onUpdateDownloaded = async (ev: Event, { releaseNotes, releaseName }: SquirrelUpdate): Promise<void> => {
dis.dispatch<CheckUpdatesPayload>({
action: Action.CheckUpdates,
status: UpdateCheckStatus.Ready,
@@ -186,7 +216,11 @@ export default class ElectronPlatform extends VectorBasePlatform {
if (this.notificationCount === count) return;
super.setNotificationCount(count);
window.electron.send("setBadgeCount", count);
window.electron!.send("setBadgeCount", count);
// Windows doesn't support app badgeCount so we have to call this too
navigator.setAppBadge?.(count).catch((e) => {
logger.error("Failed to update app badge", e);
});
}
public supportsNotifications(): boolean {
@@ -226,7 +260,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
}
public loudNotification(ev: MatrixEvent, room: Room): void {
window.electron.send("loudNotification");
window.electron!.send("loudNotification");
}
public needsUrlTooltips(): boolean {
@@ -262,14 +296,14 @@ export default class ElectronPlatform extends VectorBasePlatform {
public startUpdateCheck(): void {
super.startUpdateCheck();
window.electron.send("check_updates");
window.electron!.send("check_updates");
}
public installUpdate(): void {
// IPC to the main process to install the update, since quitAndInstall
// doesn't fire the before-quit event so the main process needs to know
// it should exit.
window.electron.send("install_update");
window.electron!.send("install_update");
}
public getDefaultDeviceDisplayName(): string {
@@ -389,4 +423,11 @@ export default class ElectronPlatform extends VectorBasePlatform {
await this.ipc.call("destroyPickleKey", userId, deviceId);
} catch (e) {}
}
public async clearStorage(): Promise<void> {
try {
await super.clearStorage();
await this.ipc.call("clearStorage");
} catch (e) {}
}
}

View File

@@ -33,6 +33,9 @@ export class IPCManager {
private readonly sendChannel: ElectronChannel = "ipcCall",
private readonly recvChannel: ElectronChannel = "ipcReply",
) {
if (!window.electron) {
throw new Error("Cannot instantiate ElectronPlatform, window.electron is not set");
}
window.electron.on(this.recvChannel, this.onIpcReply);
}
@@ -42,7 +45,7 @@ export class IPCManager {
const deferred = defer<any>();
this.pendingIpcCalls[ipcCallId] = deferred;
// Maybe add a timeout to these? Probably not necessary.
window.electron.send(this.sendChannel, { id: ipcCallId, name, args });
window.electron!.send(this.sendChannel, { id: ipcCallId, name, args });
return deferred.promise;
}

View File

@@ -19,6 +19,7 @@ import BaseEventIndexManager, {
IEventAndProfile,
IIndexStats,
ISearchArgs,
ILoadArgs,
} from "matrix-react-sdk/src/indexing/BaseEventIndexManager";
import { IMatrixProfile, IEventWithRoomId as IMatrixEvent, IResultRoomEvents } from "matrix-js-sdk/src/@types/search";
@@ -75,7 +76,7 @@ export class SeshatIndexManager extends BaseEventIndexManager {
return this.ipc.call("removeCrawlerCheckpoint", checkpoint);
}
public async loadFileEvents(args): Promise<IEventAndProfile[]> {
public async loadFileEvents(args: ILoadArgs): Promise<IEventAndProfile[]> {
return this.ipc.call("loadFileEvents", args);
}

View File

@@ -28,9 +28,9 @@ import Favicon from "../../favicon";
* Vector-specific extensions to the BasePlatform template
*/
export default abstract class VectorBasePlatform extends BasePlatform {
protected _favicon: Favicon;
protected _favicon?: Favicon;
public async getConfig(): Promise<IConfigOptions> {
public async getConfig(): Promise<IConfigOptions | undefined> {
return getVectorConfig();
}

View File

@@ -40,6 +40,8 @@ function getNormalizedAppVersion(version: string): string {
}
export default class WebPlatform extends VectorBasePlatform {
private static readonly VERSION = process.env.VERSION!; // baked in by Webpack
public constructor() {
super();
// Register service worker if available on this platform
@@ -101,7 +103,7 @@ export default class WebPlatform extends VectorBasePlatform {
}
public getAppVersion(): Promise<string> {
return Promise.resolve(getNormalizedAppVersion(process.env.VERSION));
return Promise.resolve(getNormalizedAppVersion(WebPlatform.VERSION));
}
public startUpdater(): void {
@@ -113,7 +115,7 @@ export default class WebPlatform extends VectorBasePlatform {
//
// Ideally, loading an old copy would be impossible with the
// cache-control: nocache HTTP header set, but Firefox doesn't always obey it :/
console.log("startUpdater, current version is " + getNormalizedAppVersion(process.env.VERSION));
console.log("startUpdater, current version is " + getNormalizedAppVersion(WebPlatform.VERSION));
this.pollForUpdate((version: string, newVersion: string) => {
const query = parseQs(location);
if (query.updated) {
@@ -144,7 +146,7 @@ export default class WebPlatform extends VectorBasePlatform {
): Promise<UpdateStatus> => {
return this.getMostRecentVersion().then(
(mostRecentVersion) => {
const currentVersion = getNormalizedAppVersion(process.env.VERSION);
const currentVersion = getNormalizedAppVersion(WebPlatform.VERSION);
if (currentVersion !== mostRecentVersion) {
if (this.shouldShowUpdate(mostRecentVersion)) {

View File

@@ -22,7 +22,7 @@ import MatrixChatType from "matrix-react-sdk/src/components/structures/MatrixCha
import { parseQsFromFragment } from "./url_utils";
let lastLocationHashSet: string = null;
let lastLocationHashSet: string | null = null;
export function getScreenFromLocation(location: Location): { screen: string; params: QueryDict } {
const fragparts = parseQsFromFragment(location);

View File

@@ -25,10 +25,11 @@ import { MatrixClientPeg } from "matrix-react-sdk/src/MatrixClientPeg";
import MatrixChat from "matrix-react-sdk/src/components/structures/MatrixChat";
import dis from "matrix-react-sdk/src/dispatcher/dispatcher";
import MockHttpBackend from "matrix-mock-request";
import { makeType } from "matrix-react-sdk/src/utils/TypeUtils";
import { ValidatedServerConfig } from "matrix-react-sdk/src/utils/ValidatedServerConfig";
import { IndexedDBCryptoStore } from "matrix-js-sdk/src/crypto/store/indexeddb-crypto-store";
import { QueryDict, sleep } from "matrix-js-sdk/src/utils";
import { IConfigOptions } from "matrix-react-sdk/src/IConfigOptions";
import { ActionPayload } from "matrix-react-sdk/src/dispatcher/payloads";
import "../jest-mocks";
import WebPlatform from "../../src/vector/platform/WebPlatform";
@@ -39,29 +40,24 @@ const DEFAULT_HS_URL = "http://my_server";
const DEFAULT_IS_URL = "http://my_is";
describe("loading:", function () {
let parentDiv;
let httpBackend;
let httpBackend: MockHttpBackend;
// an Object simulating the window.location
let windowLocation;
let windowLocation: Location | undefined;
// the mounted MatrixChat
let matrixChat: RenderResult;
let matrixChat: RenderResult | undefined;
// a promise which resolves when the MatrixChat calls onTokenLoginCompleted
let tokenLoginCompletePromise;
let tokenLoginCompletePromise: Promise<void> | undefined;
beforeEach(function () {
httpBackend = new MockHttpBackend();
// @ts-ignore
window.fetch = httpBackend.fetchFn;
parentDiv = document.createElement("div");
// uncomment this to actually add the div to the UI, to help with
// debugging (but slow things down)
// document.body.appendChild(parentDiv);
windowLocation = null;
matrixChat = null;
windowLocation = undefined;
matrixChat = undefined;
});
afterEach(async function () {
@@ -81,8 +77,13 @@ describe("loading:", function () {
* TODO: it would be nice to factor some of this stuff out of index.js so
* that we can test it rather than our own implementation of it.
*/
function loadApp(opts?): void {
opts = opts || {};
function loadApp(
opts: {
queryString?: string;
uriFragment?: string;
config?: IConfigOptions;
} = {},
): void {
const queryString = opts.queryString || "";
const uriFragment = opts.uriFragment || "";
@@ -92,18 +93,18 @@ describe("loading:", function () {
toString: function (): string {
return this.search + this.hash;
},
};
} as Location;
function onNewScreen(screen): void {
function onNewScreen(screen: string): void {
console.log(Date.now() + " newscreen " + screen);
const hash = "#/" + screen;
windowLocation.hash = hash;
windowLocation!.hash = hash;
console.log(Date.now() + " browser URI now " + windowLocation);
}
// Parse the given window.location and return parameters that can be used when calling
// MatrixChat.showScreen(screen, params)
function getScreenFromLocation(location): { screen: string; params: QueryDict } {
function getScreenFromLocation(location: Location): { screen: string; params: QueryDict } {
const fragparts = parseQsFromFragment(location);
return {
screen: fragparts.location.substring(1),
@@ -113,22 +114,20 @@ describe("loading:", function () {
const fragParts = parseQsFromFragment(windowLocation);
const config = Object.assign(
{
default_hs_url: DEFAULT_HS_URL,
default_is_url: DEFAULT_IS_URL,
validated_server_config: makeType(ValidatedServerConfig, {
hsUrl: DEFAULT_HS_URL,
hsName: "TEST_ENVIRONMENT",
hsNameIsDifferent: false, // yes, we lie
isUrl: DEFAULT_IS_URL,
}),
embeddedPages: {
homeUrl: "data:text/html;charset=utf-8;base64,PGh0bWw+PC9odG1sPg==",
},
const config = {
default_hs_url: DEFAULT_HS_URL,
default_is_url: DEFAULT_IS_URL,
validated_server_config: {
hsUrl: DEFAULT_HS_URL,
hsName: "TEST_ENVIRONMENT",
hsNameIsDifferent: false, // yes, we lie
isUrl: DEFAULT_IS_URL,
} as ValidatedServerConfig,
embedded_pages: {
home_url: "data:text/html;charset=utf-8;base64,PGh0bWw+PC9odG1sPg==",
},
opts.config || {},
);
...(opts.config ?? {}),
} as IConfigOptions;
PlatformPeg.set(new WebPlatform());
@@ -138,18 +137,16 @@ describe("loading:", function () {
matrixChat = render(
<MatrixChat
onNewScreen={onNewScreen}
config={config}
serverConfig={config.validated_server_config}
config={config!}
realQueryParams={params}
startingFragmentQueryParams={fragParts.params}
enableGuest={true}
onTokenLoginCompleted={resolve}
initialScreenAfterLogin={getScreenFromLocation(windowLocation)}
initialScreenAfterLogin={getScreenFromLocation(windowLocation!)}
makeRegistrationUrl={(): string => {
throw new Error("Not implemented");
}}
/>,
parentDiv,
);
});
}
@@ -158,15 +155,15 @@ describe("loading:", function () {
// http requests until we do.
//
// returns a promise resolving to the received request
async function expectAndAwaitSync(opts?): Promise<any> {
let syncRequest = null;
async function expectAndAwaitSync(opts?: { isGuest?: boolean }): Promise<any> {
let syncRequest: (typeof MockHttpBackend.prototype.requests)[number] | null = null;
httpBackend.when("GET", "/_matrix/client/versions").respond(200, {
versions: ["r0.3.0"],
unstable_features: {
"m.lazy_load_members": true,
},
});
const isGuest = opts && opts.isGuest;
const isGuest = opts?.isGuest;
if (!isGuest) {
// the call to create the LL filter
httpBackend.when("POST", "/filter").respond(200, { filter_id: "llfid" });
@@ -184,7 +181,7 @@ describe("loading:", function () {
if (syncRequest) {
return syncRequest;
}
await httpBackend.flush();
await httpBackend.flush(undefined);
}
throw new Error("Gave up waiting for /sync");
}
@@ -202,18 +199,18 @@ describe("loading:", function () {
httpBackend
.when("POST", "/register")
.check(function (req) {
expect(req.queryParams.kind).toEqual("guest");
expect(req.queryParams?.kind).toEqual("guest");
})
.respond(403, "Guest access is disabled");
return httpBackend.flush();
return httpBackend.flush(undefined);
})
.then(() => {
// Wait for another trip around the event loop for the UI to update
return awaitWelcomeComponent(matrixChat);
})
.then(() => {
return waitFor(() => expect(windowLocation.hash).toEqual("#/welcome"));
return waitFor(() => expect(windowLocation?.hash).toEqual("#/welcome"));
});
});
@@ -235,11 +232,11 @@ describe("loading:", function () {
httpBackend
.when("POST", "/register")
.check(function (req) {
expect(req.queryParams.kind).toEqual("guest");
expect(req.queryParams?.kind).toEqual("guest");
})
.respond(403, "Guest access is disabled");
return httpBackend.flush();
return httpBackend.flush(undefined);
})
.then(() => {
// Wait for another trip around the event loop for the UI to update
@@ -249,7 +246,7 @@ describe("loading:", function () {
return moveFromWelcomeToLogin(matrixChat);
})
.then(() => {
return completeLogin(matrixChat);
return completeLogin(matrixChat!);
})
.then(() => {
// once the sync completes, we should have a room view
@@ -257,7 +254,7 @@ describe("loading:", function () {
})
.then(() => {
httpBackend.verifyNoOutstandingExpectation();
expect(windowLocation.hash).toEqual("#/room/!room:id");
expect(windowLocation?.hash).toEqual("#/room/!room:id");
// and the localstorage should have been updated
expect(localStorage.getItem("mx_user_id")).toEqual("@user:id");
@@ -294,11 +291,11 @@ describe("loading:", function () {
throw new Error(`Unexpected HTTP request to ${req}`);
}
return completeLogin(matrixChat);
return completeLogin(matrixChat!);
})
.then(() => {
expect(matrixChat.container.querySelector(".mx_HomePage")).toBeTruthy();
expect(windowLocation.hash).toEqual("#/home");
expect(matrixChat?.container.querySelector(".mx_HomePage")).toBeTruthy();
expect(windowLocation?.hash).toEqual("#/home");
});
});
});
@@ -319,7 +316,7 @@ describe("loading:", function () {
it("shows the last known room by default", function () {
loadApp();
return awaitLoggedIn(matrixChat)
return awaitLoggedIn(matrixChat!)
.then(() => {
// we are logged in - let the sync complete
return expectAndAwaitSync();
@@ -330,7 +327,7 @@ describe("loading:", function () {
})
.then(() => {
httpBackend.verifyNoOutstandingExpectation();
expect(windowLocation.hash).toEqual("#/room/!last_room:id");
expect(windowLocation?.hash).toEqual("#/room/!last_room:id");
});
});
@@ -339,7 +336,7 @@ describe("loading:", function () {
loadApp();
return awaitLoggedIn(matrixChat)
return awaitLoggedIn(matrixChat!)
.then(() => {
// we are logged in - let the sync complete
return expectAndAwaitSync();
@@ -347,8 +344,8 @@ describe("loading:", function () {
.then(() => {
// once the sync completes, we should have a home page
httpBackend.verifyNoOutstandingExpectation();
expect(matrixChat.container.querySelector(".mx_HomePage")).toBeTruthy();
expect(windowLocation.hash).toEqual("#/home");
expect(matrixChat?.container.querySelector(".mx_HomePage")).toBeTruthy();
expect(windowLocation?.hash).toEqual("#/home");
});
});
@@ -357,7 +354,7 @@ describe("loading:", function () {
uriFragment: "#/room/!room:id",
});
return awaitLoggedIn(matrixChat)
return awaitLoggedIn(matrixChat!)
.then(() => {
// we are logged in - let the sync complete
return expectAndAwaitSync();
@@ -368,7 +365,7 @@ describe("loading:", function () {
})
.then(() => {
httpBackend.verifyNoOutstandingExpectation();
expect(windowLocation.hash).toEqual("#/room/!room:id");
expect(windowLocation?.hash).toEqual("#/room/!room:id");
});
});
@@ -404,17 +401,17 @@ describe("loading:", function () {
httpBackend
.when("POST", "/register")
.check(function (req) {
expect(req.queryParams.kind).toEqual("guest");
expect(req.queryParams?.kind).toEqual("guest");
})
.respond(200, {
user_id: "@guest:localhost",
access_token: "secret_token",
});
return httpBackend.flush();
return httpBackend.flush(undefined);
})
.then(() => {
return awaitLoggedIn(matrixChat);
return awaitLoggedIn(matrixChat!);
})
.then(() => {
// we are logged in - let the sync complete
@@ -423,8 +420,8 @@ describe("loading:", function () {
.then(() => {
// once the sync completes, we should have a welcome page
httpBackend.verifyNoOutstandingExpectation();
expect(matrixChat.container.querySelector(".mx_Welcome")).toBeTruthy();
expect(windowLocation.hash).toEqual("#/welcome");
expect(matrixChat?.container.querySelector(".mx_Welcome")).toBeTruthy();
expect(windowLocation?.hash).toEqual("#/welcome");
});
});
@@ -441,17 +438,17 @@ describe("loading:", function () {
.when("POST", "/register")
.check(function (req) {
expect(req.path.startsWith(DEFAULT_HS_URL)).toBe(true);
expect(req.queryParams.kind).toEqual("guest");
expect(req.queryParams?.kind).toEqual("guest");
})
.respond(200, {
user_id: "@guest:localhost",
access_token: "secret_token",
});
return httpBackend.flush();
return httpBackend.flush(undefined);
})
.then(() => {
return awaitLoggedIn(matrixChat);
return awaitLoggedIn(matrixChat!);
})
.then(() => {
return expectAndAwaitSync({ isGuest: true });
@@ -461,8 +458,8 @@ describe("loading:", function () {
// once the sync completes, we should have a welcome page
httpBackend.verifyNoOutstandingExpectation();
expect(matrixChat.container.querySelector(".mx_Welcome")).toBeTruthy();
expect(windowLocation.hash).toEqual("#/welcome");
expect(matrixChat?.container.querySelector(".mx_Welcome")).toBeTruthy();
expect(windowLocation?.hash).toEqual("#/welcome");
expect(MatrixClientPeg.get().baseUrl).toEqual(DEFAULT_HS_URL);
expect(MatrixClientPeg.get().idBaseUrl).toEqual(DEFAULT_IS_URL);
});
@@ -481,17 +478,17 @@ describe("loading:", function () {
httpBackend
.when("POST", "/register")
.check(function (req) {
expect(req.queryParams.kind).toEqual("guest");
expect(req.queryParams?.kind).toEqual("guest");
})
.respond(200, {
user_id: "@guest:localhost",
access_token: "secret_token",
});
return httpBackend.flush();
return httpBackend.flush(undefined);
})
.then(() => {
return awaitLoggedIn(matrixChat);
return awaitLoggedIn(matrixChat!);
})
.then(() => {
return expectAndAwaitSync({ isGuest: true });
@@ -502,7 +499,7 @@ describe("loading:", function () {
})
.then(() => {
httpBackend.verifyNoOutstandingExpectation();
expect(windowLocation.hash).toEqual("#/room/!room:id");
expect(windowLocation?.hash).toEqual("#/room/!room:id");
});
});
@@ -514,7 +511,7 @@ describe("loading:", function () {
httpBackend
.when("POST", "/register")
.check(function (req) {
expect(req.queryParams.kind).toEqual("guest");
expect(req.queryParams?.kind).toEqual("guest");
})
.respond(200, {
user_id: "@guest:localhost",
@@ -522,9 +519,9 @@ describe("loading:", function () {
});
return httpBackend
.flush()
.flush(undefined)
.then(() => {
return awaitLoggedIn(matrixChat);
return awaitLoggedIn(matrixChat!);
})
.then(() => {
// we got a sync spinner - let the sync complete
@@ -532,7 +529,7 @@ describe("loading:", function () {
})
.then(async () => {
// once the sync completes, we should have a home page
await waitFor(() => matrixChat.container.querySelector(".mx_HomePage"));
await waitFor(() => matrixChat?.container.querySelector(".mx_HomePage"));
// we simulate a click on the 'login' button by firing off
// the relevant dispatch.
@@ -554,7 +551,7 @@ describe("loading:", function () {
await screen.findByRole("main");
screen.getAllByText("Sign in");
expect(windowLocation.hash).toEqual("#/login");
expect(windowLocation?.hash).toEqual("#/login");
});
});
});
@@ -585,7 +582,7 @@ describe("loading:", function () {
access_token: "access_token",
});
return httpBackend.flush();
return httpBackend.flush(undefined);
})
.then(() => {
// at this point, MatrixChat should fire onTokenLoginCompleted, which
@@ -612,11 +609,7 @@ describe("loading:", function () {
// When we switch to the login component, it'll hit the login endpoint
// for proof of life and to get flows. We'll only give it one option.
httpBackend.when("GET", "/login").respond(200, { flows: [{ type: "m.login.password" }] });
httpBackend.flush(); // We already would have tried the GET /login request
// Give the component some time to finish processing the login flows before
// continuing.
await sleep(100);
httpBackend.flush(undefined); // We already would have tried the GET /login request
httpBackend
.when("POST", "/login")
@@ -631,12 +624,17 @@ describe("loading:", function () {
device_id: "DEVICE_ID",
access_token: "access_token",
});
fireEvent.change(matrixChat.container.querySelector("#mx_LoginForm_username"), { target: { value: "user" } });
fireEvent.change(matrixChat.container.querySelector("#mx_LoginForm_password"), { target: { value: "pass" } });
// Give the component some time to finish processing the login flows before continuing.
await waitFor(() => expect(matrixChat?.container.querySelector("#mx_LoginForm_username")).toBeTruthy());
// Enter login details
fireEvent.change(matrixChat.container.querySelector("#mx_LoginForm_username")!, { target: { value: "user" } });
fireEvent.change(matrixChat.container.querySelector("#mx_LoginForm_password")!, { target: { value: "pass" } });
fireEvent.click(screen.getByText("Sign in", { selector: ".mx_Login_submit" }));
return httpBackend
.flush()
.flush(undefined)
.then(() => {
// Wait for another trip around the event loop for the UI to update
return sleep(1);
@@ -661,7 +659,7 @@ async function awaitLoggedIn(matrixChat: RenderResult): Promise<void> {
if (matrixChat.container.querySelector(".mx_MatrixChat_wrapper")) return; // already logged in
return new Promise((resolve) => {
const onAction = ({ action }): void => {
const onAction = ({ action }: ActionPayload): void => {
if (action !== "on_logged_in") {
return;
}
@@ -674,19 +672,19 @@ async function awaitLoggedIn(matrixChat: RenderResult): Promise<void> {
});
}
async function awaitRoomView(matrixChat: RenderResult): Promise<void> {
await waitFor(() => matrixChat.container.querySelector(".mx_RoomView"));
async function awaitRoomView(matrixChat?: RenderResult): Promise<void> {
await waitFor(() => matrixChat?.container.querySelector(".mx_RoomView"));
}
async function awaitLoginComponent(matrixChat: RenderResult): Promise<void> {
await waitFor(() => matrixChat.container.querySelector(".mx_AuthPage"));
async function awaitLoginComponent(matrixChat?: RenderResult): Promise<void> {
await waitFor(() => matrixChat?.container.querySelector(".mx_AuthPage"));
}
async function awaitWelcomeComponent(matrixChat: RenderResult): Promise<void> {
await waitFor(() => matrixChat.container.querySelector(".mx_Welcome"));
async function awaitWelcomeComponent(matrixChat?: RenderResult): Promise<void> {
await waitFor(() => matrixChat?.container.querySelector(".mx_Welcome"));
}
function moveFromWelcomeToLogin(matrixChat: RenderResult): Promise<void> {
function moveFromWelcomeToLogin(matrixChat?: RenderResult): Promise<void> {
dis.dispatch({ action: "start_login" });
return awaitLoginComponent(matrixChat);
}

View File

@@ -29,7 +29,7 @@ describe("Favicon", () => {
it("should create a link element if one doesn't yet exist", () => {
const favicon = new Favicon();
expect(favicon).toBeTruthy();
const link = window.document.querySelector("link");
const link = window.document.querySelector("link")!;
expect(link.rel).toContain("icon");
});

View File

@@ -21,7 +21,6 @@ import { getVectorConfig } from "../../../src/vector/getconfig";
fetchMock.config.overwriteRoutes = true;
describe("getVectorConfig()", () => {
const prevDocumentDomain = document.domain;
const elementDomain = "app.element.io";
const now = 1234567890;
const specificConfig = {
@@ -32,7 +31,10 @@ describe("getVectorConfig()", () => {
};
beforeEach(() => {
document.domain = elementDomain;
Object.defineProperty(window, "location", {
value: { href: `https://${elementDomain}`, hostname: elementDomain },
writable: true,
});
// stable value for cachebuster
jest.spyOn(Date, "now").mockReturnValue(now);
@@ -41,7 +43,6 @@ describe("getVectorConfig()", () => {
});
afterAll(() => {
document.domain = prevDocumentDomain;
jest.spyOn(Date, "now").mockRestore();
});
@@ -107,6 +108,6 @@ describe("getVectorConfig()", () => {
// We can't assert it'll be a SyntaxError as node-fetch behaves differently
// https://github.com/wheresrhys/fetch-mock/issues/270
await expect(getVectorConfig()).rejects.toThrow("Unexpected token } in JSON at position 19");
await expect(getVectorConfig()).rejects.toThrow("in JSON at position 19");
});
});

View File

@@ -20,6 +20,7 @@ import { UpdateCheckStatus } from "matrix-react-sdk/src/BasePlatform";
import { Action } from "matrix-react-sdk/src/dispatcher/actions";
import dispatcher from "matrix-react-sdk/src/dispatcher/dispatcher";
import * as rageshake from "matrix-react-sdk/src/rageshake/rageshake";
import { BreadcrumbsStore } from "matrix-react-sdk/src/stores/BreadcrumbsStore";
import ElectronPlatform from "../../../../src/vector/platform/ElectronPlatform";
@@ -43,12 +44,10 @@ describe("ElectronPlatform", () => {
const userId = "@alice:server.org";
const deviceId = "device-id";
window.electron = mockElectron;
beforeEach(() => {
window.electron = mockElectron;
jest.clearAllMocks();
delete window.navigator;
window.navigator = { userAgent: defaultUserAgent } as unknown as Navigator;
Object.defineProperty(window, "navigator", { value: { userAgent: defaultUserAgent }, writable: true });
});
const getElectronEventHandlerCall = (eventType: string): [type: string, handler: Function] | undefined =>
@@ -56,7 +55,7 @@ describe("ElectronPlatform", () => {
it("flushes rageshake before quitting", () => {
new ElectronPlatform();
const [event, handler] = getElectronEventHandlerCall("before-quit");
const [event, handler] = getElectronEventHandlerCall("before-quit")!;
// correct event bound
expect(event).toBeTruthy();
@@ -68,7 +67,7 @@ describe("ElectronPlatform", () => {
it("dispatches view settings action on preferences event", () => {
new ElectronPlatform();
const [event, handler] = getElectronEventHandlerCall("preferences");
const [event, handler] = getElectronEventHandlerCall("preferences")!;
// correct event bound
expect(event).toBeTruthy();
@@ -80,7 +79,7 @@ describe("ElectronPlatform", () => {
describe("updates", () => {
it("dispatches on check updates action", () => {
new ElectronPlatform();
const [event, handler] = getElectronEventHandlerCall("check_updates");
const [event, handler] = getElectronEventHandlerCall("check_updates")!;
// correct event bound
expect(event).toBeTruthy();
@@ -93,7 +92,7 @@ describe("ElectronPlatform", () => {
it("dispatches on check updates action when update not available", () => {
new ElectronPlatform();
const [, handler] = getElectronEventHandlerCall("check_updates");
const [, handler] = getElectronEventHandlerCall("check_updates")!;
handler({}, false);
expect(dispatchSpy).toHaveBeenCalledWith({
@@ -138,8 +137,7 @@ describe("ElectronPlatform", () => {
["Mozilla/5.0 (X11; SunOS i686; rv:21.0) Gecko/20100101 Firefox/21.0", "Element Desktop: SunOS"],
["custom user agent", "Element Desktop: Unknown"],
])("%s = %s", (userAgent, result) => {
delete window.navigator;
window.navigator = { userAgent } as unknown as Navigator;
Object.defineProperty(window, "navigator", { value: { userAgent }, writable: true });
const platform = new ElectronPlatform();
expect(platform.getDefaultDeviceDisplayName()).toEqual(result);
});
@@ -260,4 +258,20 @@ describe("ElectronPlatform", () => {
expect(mockElectron.send).toHaveBeenCalledWith("install_update");
});
});
describe("breacrumbs", () => {
it("should send breadcrumb updates over the IPC", () => {
const spy = jest.spyOn(BreadcrumbsStore.instance, "on");
new ElectronPlatform();
const cb = spy.mock.calls[0][1];
cb();
expect(mockElectron.send).toHaveBeenCalledWith(
"ipcCall",
expect.objectContaining({
name: "breadcrumbs",
}),
);
});
});
});

View File

@@ -33,7 +33,6 @@ describe("WebPlatform", () => {
});
it("registers service worker", () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - mocking readonly object
navigator.serviceWorker = { register: jest.fn() };
new WebPlatform();
@@ -41,10 +40,7 @@ describe("WebPlatform", () => {
});
it("should call reload on window location object", () => {
delete window.location;
window.location = {
reload: jest.fn(),
} as unknown as Location;
Object.defineProperty(window, "location", { value: { reload: jest.fn() }, writable: true });
const platform = new WebPlatform();
expect(window.location.reload).not.toHaveBeenCalled();
@@ -53,10 +49,7 @@ describe("WebPlatform", () => {
});
it("should call reload to install update", () => {
delete window.location;
window.location = {
reload: jest.fn(),
} as unknown as Location;
Object.defineProperty(window, "location", { value: { reload: jest.fn() }, writable: true });
const platform = new WebPlatform();
expect(window.location.reload).not.toHaveBeenCalled();
@@ -73,10 +66,8 @@ describe("WebPlatform", () => {
"develop.element.io: Chrome on macOS",
],
])("%s & %s = %s", (url, userAgent, result) => {
delete window.navigator;
window.navigator = { userAgent } as unknown as Navigator;
delete window.location;
window.location = { href: url } as unknown as Location;
Object.defineProperty(window, "navigator", { value: { userAgent }, writable: true });
Object.defineProperty(window, "location", { value: { href: url }, writable: true });
const platform = new WebPlatform();
expect(platform.getDefaultDeviceDisplayName()).toEqual(result);
});
@@ -88,14 +79,12 @@ describe("WebPlatform", () => {
permission: "notGranted",
};
beforeEach(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.Notification = mockNotification;
mockNotification.permission = "notGranted";
});
it("supportsNotifications returns false when platform does not support notifications", () => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
window.Notification = undefined;
expect(new WebPlatform().supportsNotifications()).toBe(false);
@@ -132,7 +121,8 @@ describe("WebPlatform", () => {
});
afterAll(() => {
process.env.VERSION = envVersion;
// @ts-ignore
WebPlatform.VERSION = envVersion;
});
it("should return true from canSelfUpdate()", async () => {
@@ -142,18 +132,21 @@ describe("WebPlatform", () => {
});
it("getAppVersion returns normalized app version", async () => {
process.env.VERSION = prodVersion;
// @ts-ignore
WebPlatform.VERSION = prodVersion;
const platform = new WebPlatform();
const version = await platform.getAppVersion();
expect(version).toEqual(prodVersion);
process.env.VERSION = `v${prodVersion}`;
// @ts-ignore
WebPlatform.VERSION = `v${prodVersion}`;
const version2 = await platform.getAppVersion();
// v prefix removed
expect(version2).toEqual(prodVersion);
process.env.VERSION = `version not like semver`;
// @ts-ignore
WebPlatform.VERSION = `version not like semver`;
const notSemverVersion = await platform.getAppVersion();
expect(notSemverVersion).toEqual(`version not like semver`);
});
@@ -163,7 +156,8 @@ describe("WebPlatform", () => {
"should return not available and call showNoUpdate when current version " +
"matches most recent version",
async () => {
process.env.VERSION = prodVersion;
// @ts-ignore
WebPlatform.VERSION = prodVersion;
fetchMock.getOnce("/version", prodVersion);
const platform = new WebPlatform();
@@ -178,7 +172,8 @@ describe("WebPlatform", () => {
);
it("should strip v prefix from versions before comparing", async () => {
process.env.VERSION = prodVersion;
// @ts-ignore
WebPlatform.VERSION = prodVersion;
fetchMock.getOnce("/version", `v${prodVersion}`);
const platform = new WebPlatform();
@@ -195,7 +190,8 @@ describe("WebPlatform", () => {
it(
"should return ready and call showUpdate when current version " + "differs from most recent version",
async () => {
process.env.VERSION = "0.0.0"; // old version
// @ts-ignore
WebPlatform.VERSION = "0.0.0"; // old version
fetchMock.getOnce("/version", prodVersion);
const platform = new WebPlatform();
@@ -210,7 +206,8 @@ describe("WebPlatform", () => {
);
it("should return ready without showing update when user registered in last 24", async () => {
process.env.VERSION = "0.0.0"; // old version
// @ts-ignore
WebPlatform.VERSION = "0.0.0"; // old version
jest.spyOn(MatrixClientPeg, "userRegisteredWithinLastHours").mockReturnValue(true);
fetchMock.getOnce("/version", prodVersion);
const platform = new WebPlatform();

View File

@@ -18,24 +18,28 @@ import { onNewScreen } from "../../../src/vector/routing";
describe("onNewScreen", () => {
it("should replace history if stripping via fields", () => {
delete window.location;
window.location = {
hash: "#/room/!room:server?via=abc",
replace: jest.fn(),
assign: jest.fn(),
} as unknown as Location;
Object.defineProperty(window, "location", {
value: {
hash: "#/room/!room:server?via=abc",
replace: jest.fn(),
assign: jest.fn(),
},
writable: true,
});
onNewScreen("room/!room:server");
expect(window.location.assign).not.toHaveBeenCalled();
expect(window.location.replace).toHaveBeenCalled();
});
it("should not replace history if changing rooms", () => {
delete window.location;
window.location = {
hash: "#/room/!room1:server?via=abc",
replace: jest.fn(),
assign: jest.fn(),
} as unknown as Location;
Object.defineProperty(window, "location", {
value: {
hash: "#/room/!room1:server?via=abc",
replace: jest.fn(),
assign: jest.fn(),
},
writable: true,
});
onNewScreen("room/!room2:server");
expect(window.location.assign).toHaveBeenCalled();
expect(window.location.replace).not.toHaveBeenCalled();

View File

@@ -17,7 +17,6 @@ limitations under the License.
import { parseQsFromFragment, parseQs } from "../../../src/vector/url_utils";
describe("url_utils.ts", function () {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const location: Location = {
hash: "",

View File

@@ -13,7 +13,20 @@
"outDir": "./lib",
"declaration": true,
"jsx": "react",
"lib": ["es2019", "dom", "dom.iterable"]
"lib": ["es2020", "dom", "dom.iterable"],
"alwaysStrict": true,
"strictBindCallApply": true,
"noImplicitThis": true
},
"include": ["./src/**/*.ts", "./src/**/*.tsx", "./test/**/*.ts", "./test/**/*.tsx"]
"include": [
"./node_modules/matrix-js-sdk/src/@types/*.d.ts",
"./node_modules/matrix-react-sdk/src/@types/diff-dom.d.ts",
"./node_modules/matrix-react-sdk/src/@types/opus-recorder.d.ts",
"./node_modules/matrix-react-sdk/src/@types/png-chunks-extract.d.ts",
"./node_modules/matrix-react-sdk/src/@types/sanitize-html.d.ts",
"./src/**/*.ts",
"./src/**/*.tsx",
"./test/**/*.ts",
"./test/**/*.tsx"
]
}

View File

@@ -4,7 +4,7 @@
"jsx": "preserve",
"declaration": false,
"outDir": "./lib/module_system",
"lib": ["es2019"],
"lib": ["es2020"],
"types": ["node"]
},
"include": ["./module_system/**/*.ts"]

View File

@@ -99,8 +99,8 @@ module.exports = (env, argv) => {
const development = {};
if (devMode) {
// High quality, embedded source maps for dev builds
development["devtool"] = "eval-source-map";
// Embedded source maps for dev builds, can't use eval-source-map due to CSP
development["devtool"] = "inline-source-map";
} else {
if (process.env.CI_PACKAGE) {
// High quality source maps in separate .map files which include the source. This doesn't bulk up the .js
@@ -207,8 +207,10 @@ module.exports = (env, argv) => {
// Same goes for js/react-sdk - we don't need two copies.
"matrix-js-sdk": path.resolve(__dirname, "node_modules/matrix-js-sdk"),
"matrix-react-sdk": path.resolve(__dirname, "node_modules/matrix-react-sdk"),
// and sanitize-html
// and sanitize-html & matrix-events-sdk & matrix-widget-api
"sanitize-html": path.resolve(__dirname, "node_modules/sanitize-html"),
"matrix-events-sdk": path.resolve(__dirname, "node_modules/matrix-events-sdk"),
"matrix-widget-api": path.resolve(__dirname, "node_modules/matrix-widget-api"),
// Define a variable so the i18n stuff can load
"$webapp": path.resolve(__dirname, "webapp"),

2513
yarn.lock

File diff suppressed because it is too large Load Diff