mirror of https://github.com/vector-im/riot-web
Compare commits
302 Commits
Author | SHA1 | Date |
---|---|---|
![]() |
b0c04834b6 | |
![]() |
b61d5b4475 | |
![]() |
6c3817fa34 | |
![]() |
e151d9ab53 | |
![]() |
f15b188297 | |
![]() |
ea16928d35 | |
![]() |
4651bf4eb4 | |
![]() |
5442d4050d | |
![]() |
695cc1b28b | |
![]() |
6cf0809064 | |
![]() |
a0eb94704e | |
![]() |
e1e0d37478 | |
![]() |
9039e70990 | |
![]() |
596f297094 | |
![]() |
4f92927a3d | |
![]() |
b77218e65a | |
![]() |
c21e9f6383 | |
![]() |
4f8a8a2543 | |
![]() |
d615e69a86 | |
![]() |
db1d440e3b | |
![]() |
24fafe2588 | |
![]() |
1e06e3083f | |
![]() |
8e9f3a786c | |
![]() |
95f134a7c5 | |
![]() |
50f5c15027 | |
![]() |
65b43d8dc7 | |
![]() |
8dad4f5f10 | |
![]() |
a3a436ad64 | |
![]() |
a9cd567fc9 | |
![]() |
82073aea3e | |
![]() |
9cf7b8b6f6 | |
![]() |
fa5bd19368 | |
![]() |
fb72597fcf | |
![]() |
3ce0d78961 | |
![]() |
361636a3d1 | |
![]() |
0b49a7724b | |
![]() |
2db2cf2b1b | |
![]() |
c38505598f | |
![]() |
7e21f12678 | |
![]() |
4f43c57a96 | |
![]() |
60d3b59076 | |
![]() |
5a7956fd90 | |
![]() |
e193f57ac7 | |
![]() |
30f964447f | |
![]() |
cb9eccebed | |
![]() |
a0ae97c2e3 | |
![]() |
fd62e04bc0 | |
![]() |
e6c0b8d8e5 | |
![]() |
67e78a56a6 | |
![]() |
153d0c36b8 | |
![]() |
18bfe3cb43 | |
![]() |
61ba9b48f9 | |
![]() |
5e02a42ca0 | |
![]() |
89622749e2 | |
![]() |
eced524029 | |
![]() |
c4263b3330 | |
![]() |
68f4a7d4b0 | |
![]() |
7df5028c51 | |
![]() |
4de49c76d0 | |
![]() |
165cbcda89 | |
![]() |
c11bfaf07e | |
![]() |
98babd140e | |
![]() |
575a726361 | |
![]() |
ed2440f8cf | |
![]() |
59592f84fb | |
![]() |
ab690372d2 | |
![]() |
571028f124 | |
![]() |
36391187da | |
![]() |
35f2f5055a | |
![]() |
e2c974f53b | |
![]() |
74172969c1 | |
![]() |
6db392025c | |
![]() |
a61de47bb6 | |
![]() |
bcd5c838e8 | |
![]() |
482b81b0ed | |
![]() |
095c613b69 | |
![]() |
5eed034389 | |
![]() |
7a3bc83a55 | |
![]() |
706f4c6e20 | |
![]() |
f43bb0a9f7 | |
![]() |
64f0bb5460 | |
![]() |
e651330ff1 | |
![]() |
6a6a362a8d | |
![]() |
35046bb7b2 | |
![]() |
a10f2e1258 | |
![]() |
a0d7805484 | |
![]() |
ae77dac66d | |
![]() |
5f1f018a30 | |
![]() |
f2da5fcf2c | |
![]() |
9cce1e060a | |
![]() |
50c8cb7bf0 | |
![]() |
58e5b3959d | |
![]() |
84b6bf9789 | |
![]() |
9efa04da7a | |
![]() |
8ba3f53d2c | |
![]() |
36571edb95 | |
![]() |
3a159beb21 | |
![]() |
6ebe844fc0 | |
![]() |
7359c9bf93 | |
![]() |
02fd35dad0 | |
![]() |
a71b7f0e66 | |
![]() |
f0672082b3 | |
![]() |
2ee54dd4bc | |
![]() |
e852282270 | |
![]() |
80a7ea7649 | |
![]() |
9b988f70de | |
![]() |
27d4e1d990 | |
![]() |
f7132ff139 | |
![]() |
b82100ede8 | |
![]() |
729534401f | |
![]() |
dc85c9fb13 | |
![]() |
2c8b32d2c9 | |
![]() |
011f7465e7 | |
![]() |
4561b2d35d | |
![]() |
5dcaf8ab80 | |
![]() |
ac20fffb40 | |
![]() |
aeef12ef8b | |
![]() |
73f2dba0c3 | |
![]() |
ea56d6774c | |
![]() |
0937c161f4 | |
![]() |
ad31575ddc | |
![]() |
3fc2cdfbab | |
![]() |
ba186a22d0 | |
![]() |
8449bdc5c1 | |
![]() |
686816b8a4 | |
![]() |
6d457e3559 | |
![]() |
91e9891892 | |
![]() |
c8e866e384 | |
![]() |
f5997aaf7c | |
![]() |
9a2066d98a | |
![]() |
6e59f6f413 | |
![]() |
7e8177edb3 | |
![]() |
d3deda62a8 | |
![]() |
f990918e49 | |
![]() |
9ce7b19147 | |
![]() |
786c590dcf | |
![]() |
bbf37ba7cf | |
![]() |
c50556a957 | |
![]() |
4a895f6daf | |
![]() |
7f5af1ccdf | |
![]() |
eac221c2d3 | |
![]() |
c5b98a5e93 | |
![]() |
88c49e7c50 | |
![]() |
3cb5b840ce | |
![]() |
e0deabceb3 | |
![]() |
2e15e5e3c7 | |
![]() |
050e9126d8 | |
![]() |
3b52d375e7 | |
![]() |
a1c6f0a1d2 | |
![]() |
4bd351f167 | |
![]() |
5bed03f37e | |
![]() |
315ee8a64d | |
![]() |
f51622a507 | |
![]() |
ce95e1abcd | |
![]() |
70e480a3e9 | |
![]() |
6ca67ff1ef | |
![]() |
ff63c92c2c | |
![]() |
36ff005d11 | |
![]() |
38ea3312f6 | |
![]() |
8c61026761 | |
![]() |
5d32728f3e | |
![]() |
159ef4cc15 | |
![]() |
8baab4ce8e | |
![]() |
491ad6de17 | |
![]() |
f62076cdc1 | |
![]() |
674650f24d | |
![]() |
9f5bd7bf66 | |
![]() |
fa5a842257 | |
![]() |
a2f1c917bc | |
![]() |
b4bff9f3b2 | |
![]() |
8ce46d3de8 | |
![]() |
2cad731f23 | |
![]() |
1cf08423ad | |
![]() |
b64ac0593e | |
![]() |
f64759e42e | |
![]() |
d0b192dbc8 | |
![]() |
fc90392982 | |
![]() |
180a1a243b | |
![]() |
5246a7824b | |
![]() |
2dffd41c6f | |
![]() |
2f72796ae7 | |
![]() |
364ad021e4 | |
![]() |
a187b54707 | |
![]() |
15c177d8b3 | |
![]() |
773e9bb015 | |
![]() |
dbf2e8c927 | |
![]() |
e794ac5ecb | |
![]() |
f4d64dcb39 | |
![]() |
a1404722ba | |
![]() |
9167d4ac56 | |
![]() |
c3376efa8d | |
![]() |
2ad9c5685e | |
![]() |
0565e614d3 | |
![]() |
1126956d56 | |
![]() |
aec32bbc35 | |
![]() |
424243c064 | |
![]() |
84f293fee2 | |
![]() |
39f51612f5 | |
![]() |
f4155fa7c4 | |
![]() |
c2fdd04681 | |
![]() |
c5da65ba60 | |
![]() |
65165247c0 | |
![]() |
e89ba979cf | |
![]() |
cf605b5e6f | |
![]() |
1984ba3b33 | |
![]() |
43db5a8731 | |
![]() |
7c9f521f65 | |
![]() |
9848bf8246 | |
![]() |
b0d8d4bbdb | |
![]() |
4cd14b58e1 | |
![]() |
2853a23679 | |
![]() |
bd931ebd74 | |
![]() |
e2b5cea7df | |
![]() |
2fb41f19a7 | |
![]() |
0cd36558c5 | |
![]() |
f835c678bf | |
![]() |
44a2666183 | |
![]() |
1b81c276fc | |
![]() |
309bb7eb47 | |
![]() |
44fff3b45c | |
![]() |
7498afcb33 | |
![]() |
9091c074a8 | |
![]() |
50a62f6105 | |
![]() |
ef29e98bdc | |
![]() |
814aa778ea | |
![]() |
2723a23ea7 | |
![]() |
23bc0d7f3d | |
![]() |
573478a630 | |
![]() |
271524e264 | |
![]() |
18446de298 | |
![]() |
a6a901109b | |
![]() |
7effb12bbe | |
![]() |
b625a8f41f | |
![]() |
786cd12636 | |
![]() |
122ecb05c9 | |
![]() |
f07ea3d2cc | |
![]() |
37612eb41a | |
![]() |
24e17182b3 | |
![]() |
7a8a72b1e8 | |
![]() |
926d944c2a | |
![]() |
ddc22578f6 | |
![]() |
8f24d68b53 | |
![]() |
5a97ad33a2 | |
![]() |
954589df1b | |
![]() |
7c9e37a2c6 | |
![]() |
913be315f3 | |
![]() |
830e7c5c45 | |
![]() |
d6671cca75 | |
![]() |
38dbedcd85 | |
![]() |
4e492da1e4 | |
![]() |
5cfacc799d | |
![]() |
31d44b4c46 | |
![]() |
ba2336ac5c | |
![]() |
33ea45301e | |
![]() |
02a315814f | |
![]() |
5fe009d094 | |
![]() |
8082d07e7b | |
![]() |
559c3788ac | |
![]() |
54ba0873da | |
![]() |
28038cc53e | |
![]() |
97c3da3789 | |
![]() |
40a6a4296b | |
![]() |
c5168ad100 | |
![]() |
89e455e9a7 | |
![]() |
b68ff2fd88 | |
![]() |
00abe771bf | |
![]() |
1a2e1474f4 | |
![]() |
d0b87400d1 | |
![]() |
0977c3839a | |
![]() |
cd7bd1b253 | |
![]() |
43467fc7c5 | |
![]() |
7b9d7e37e4 | |
![]() |
072bc7fc8c | |
![]() |
8d04ce4255 | |
![]() |
b97f4b31fa | |
![]() |
a0c90f9657 | |
![]() |
9b01f375e9 | |
![]() |
0539c99cf8 | |
![]() |
842fa767b8 | |
![]() |
aa427ecaf3 | |
![]() |
5e72da399e | |
![]() |
1c562a0d2d | |
![]() |
f01d69f90b | |
![]() |
c9d40992a1 | |
![]() |
986ea30ef5 | |
![]() |
110e5163e0 | |
![]() |
26999ee978 | |
![]() |
ed2d6d68bb | |
![]() |
f530e7e4b4 | |
![]() |
b428f4f483 | |
![]() |
4a6ac5f8d2 | |
![]() |
5360dfa9a4 | |
![]() |
ca93577cd1 | |
![]() |
e5e536a279 | |
![]() |
1f181f1c0a | |
![]() |
3c41b70932 | |
![]() |
d1d909105f | |
![]() |
831eddfbd4 | |
![]() |
4a014ea056 | |
![]() |
64cec89085 | |
![]() |
f502a4049a | |
![]() |
18b9052c57 |
|
@ -88,6 +88,7 @@ module.exports = {
|
||||||
"@typescript-eslint/explicit-function-return-type": "off",
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
"@typescript-eslint/explicit-member-accessibility": "off",
|
"@typescript-eslint/explicit-member-accessibility": "off",
|
||||||
"@typescript-eslint/ban-ts-comment": "off",
|
"@typescript-eslint/ban-ts-comment": "off",
|
||||||
|
"@typescript-eslint/no-floating-promises": "off",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -11,3 +11,6 @@
|
||||||
|
|
||||||
/apple-app-site-association
|
/apple-app-site-association
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
|
/.well-known/assetlinks.json
|
||||||
|
Content-Type: application/json
|
||||||
|
|
|
@ -261,3 +261,6 @@
|
||||||
color: "ededed"
|
color: "ededed"
|
||||||
- name: "Z-t3chguy"
|
- name: "Z-t3chguy"
|
||||||
color: "ededed"
|
color: "ededed"
|
||||||
|
- name: "Z-Flaky-Test-Disabled"
|
||||||
|
description: "The flaking test has been disabled"
|
||||||
|
color: "ededed"
|
||||||
|
|
|
@ -84,14 +84,21 @@ jobs:
|
||||||
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
AWS_ACCESS_KEY_ID: ${{ secrets.CF_R2_ACCESS_KEY_ID }}
|
||||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
AWS_SECRET_ACCESS_KEY: ${{ secrets.CF_R2_TOKEN }}
|
||||||
|
|
||||||
|
# We may be trying to deploy the same webapp bundles again, we need to ensure that the live bundles
|
||||||
|
# are not present in the _redirects file and instead accessed directly from Cloudflare Pages.
|
||||||
|
- name: Trim _redirects
|
||||||
|
working-directory: _deploy
|
||||||
|
run: |
|
||||||
|
find bundles -type d -mindepth 1 -maxdepth 1 -exec sed -i "\:{}:d" _redirects \;
|
||||||
|
|
||||||
- name: Wait for other steps to succeed
|
- name: Wait for other steps to succeed
|
||||||
uses: t3chguy/wait-on-check-action@05861d3a448898eb33dfce34153bd1ecb9422fb9 # fork
|
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.sha }}
|
ref: ${{ github.sha }}
|
||||||
running-workflow-name: "Build & Deploy develop.element.io"
|
running-workflow-name: "Build & Deploy develop.element.io"
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
wait-interval: 10
|
wait-interval: 10
|
||||||
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare).)*$
|
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages).)*$
|
||||||
|
|
||||||
# We keep the latest develop.tar.gz on R2 instead of relying on the github artifact uploaded earlier
|
# We keep the latest develop.tar.gz on R2 instead of relying on the github artifact uploaded earlier
|
||||||
# as the expires after 24h and requires auth to download.
|
# as the expires after 24h and requires auth to download.
|
||||||
|
|
|
@ -7,6 +7,9 @@ on:
|
||||||
# This job can take a while, and we have usage limits, so just publish develop only twice a day
|
# This job can take a while, and we have usage limits, so just publish develop only twice a day
|
||||||
- cron: "0 7/12 * * *"
|
- cron: "0 7/12 * * *"
|
||||||
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
|
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
id-token: write # needed for signing the images with GitHub OIDC Token
|
||||||
jobs:
|
jobs:
|
||||||
buildx:
|
buildx:
|
||||||
name: Docker Buildx
|
name: Docker Buildx
|
||||||
|
@ -26,6 +29,9 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||||
|
|
||||||
|
- name: Install Cosign
|
||||||
|
uses: sigstore/cosign-installer@59acb6260d9c0ba8f4a2f9d9b48431a222b68e20 # v3
|
||||||
|
|
||||||
- name: Prepare
|
- name: Prepare
|
||||||
if: matrix.prepare
|
if: matrix.prepare
|
||||||
run: ${{ matrix.prepare }}
|
run: ${{ matrix.prepare }}
|
||||||
|
@ -34,19 +40,19 @@ jobs:
|
||||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3
|
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3
|
uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3
|
||||||
with:
|
with:
|
||||||
install: true
|
install: true
|
||||||
|
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3
|
uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
|
||||||
- name: Docker meta
|
- name: Docker meta
|
||||||
id: meta
|
id: meta
|
||||||
uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5
|
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5
|
||||||
with:
|
with:
|
||||||
images: |
|
images: |
|
||||||
vectorim/element-web
|
vectorim/element-web
|
||||||
|
@ -58,7 +64,8 @@ jobs:
|
||||||
${{ matrix.flavor }}
|
${{ matrix.flavor }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5
|
id: build-and-push
|
||||||
|
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: true
|
||||||
|
@ -66,6 +73,17 @@ jobs:
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
|
||||||
|
- name: Sign the images with GitHub OIDC Token
|
||||||
|
env:
|
||||||
|
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
||||||
|
TAGS: ${{ steps.meta.outputs.tags }}
|
||||||
|
run: |
|
||||||
|
images=""
|
||||||
|
for tag in ${TAGS}; do
|
||||||
|
images+="${tag}@${DIGEST} "
|
||||||
|
done
|
||||||
|
cosign sign --yes ${images}
|
||||||
|
|
||||||
- name: Update repo description
|
- name: Update repo description
|
||||||
if: matrix.variant == 'vanilla'
|
if: matrix.variant == 'vanilla'
|
||||||
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4
|
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4
|
||||||
|
|
|
@ -55,12 +55,12 @@ jobs:
|
||||||
echo "- [Automations](automations.md)" >> docs/SUMMARY.md
|
echo "- [Automations](automations.md)" >> docs/SUMMARY.md
|
||||||
|
|
||||||
- name: Setup mdBook
|
- name: Setup mdBook
|
||||||
uses: peaceiris/actions-mdbook@v1
|
uses: peaceiris/actions-mdbook@v2
|
||||||
with:
|
with:
|
||||||
mdbook-version: "0.4.10"
|
mdbook-version: "0.4.10"
|
||||||
|
|
||||||
- name: Install mdbook extensions
|
- name: Install mdbook extensions
|
||||||
run: cargo install mdbook-combiner mdbook-mermaid
|
run: cargo install mdbook-combiner@0.1.15 mdbook-mermaid
|
||||||
|
|
||||||
- name: Prepare docs
|
- name: Prepare docs
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
name: Build downstream artifacts
|
|
||||||
on:
|
|
||||||
merge_group:
|
|
||||||
types: [checks_requested]
|
|
||||||
pull_request: {}
|
|
||||||
push:
|
|
||||||
branches: [develop, master]
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
jobs:
|
|
||||||
build-element-web:
|
|
||||||
name: Build element-web
|
|
||||||
uses: matrix-org/matrix-react-sdk/.github/workflows/element-web.yaml@develop
|
|
||||||
with:
|
|
||||||
element-web-sha: ${{ github.sha }}
|
|
||||||
react-sdk-repository: matrix-org/matrix-react-sdk
|
|
|
@ -3,10 +3,11 @@
|
||||||
|
|
||||||
name: matrix-react-sdk End to End Tests
|
name: matrix-react-sdk End to End Tests
|
||||||
on:
|
on:
|
||||||
workflow_run:
|
merge_group:
|
||||||
workflows: ["Build downstream artifacts"]
|
types: [checks_requested]
|
||||||
types:
|
pull_request: {}
|
||||||
- completed
|
push:
|
||||||
|
branches: [develop, master]
|
||||||
|
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
|
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
|
||||||
|
@ -15,44 +16,14 @@ concurrency:
|
||||||
jobs:
|
jobs:
|
||||||
playwright:
|
playwright:
|
||||||
name: Playwright
|
name: Playwright
|
||||||
# We only want to run the playwright tests on merge queue to prevent regressions
|
|
||||||
# from creeping in. They take a long time to run and consume multiple concurrent runners.
|
|
||||||
if: github.event.workflow_run.event == 'merge_group'
|
|
||||||
uses: matrix-org/matrix-react-sdk/.github/workflows/end-to-end-tests.yaml@develop
|
uses: matrix-org/matrix-react-sdk/.github/workflows/end-to-end-tests.yaml@develop
|
||||||
permissions:
|
permissions:
|
||||||
actions: read
|
actions: read
|
||||||
issues: read
|
issues: read
|
||||||
statuses: write
|
|
||||||
pull-requests: read
|
pull-requests: read
|
||||||
deployments: write
|
|
||||||
with:
|
with:
|
||||||
|
element-web-sha: ${{ github.sha }}
|
||||||
react-sdk-repository: matrix-org/matrix-react-sdk
|
react-sdk-repository: matrix-org/matrix-react-sdk
|
||||||
secrets:
|
# We only want to run the playwright tests on merge queue to prevent regressions
|
||||||
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
# from creeping in. They take a long time to run and consume multiple concurrent runners.
|
||||||
|
skip: ${{ github.event_name != 'merge_group' }}
|
||||||
# We want to make the Playwright tests a required check for the merge queue.
|
|
||||||
#
|
|
||||||
# Unfortunately, github doesn't distinguish between "checks needed for branch
|
|
||||||
# protection" (ie, the things that must pass before the PR will even be added
|
|
||||||
# to the merge queue) and "checks needed in the merge queue". We just have to add
|
|
||||||
# the check to the branch protection list.
|
|
||||||
#
|
|
||||||
# Ergo, if we know we're not going to run the Playwright tests, we need to add a
|
|
||||||
# passing status check manually.
|
|
||||||
mark_skipped:
|
|
||||||
if: github.event.workflow_run.event != 'merge_group'
|
|
||||||
permissions:
|
|
||||||
statuses: write
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: Sibz/github-status-action@071b5370da85afbb16637d6eed8524a06bc2053e # v1
|
|
||||||
with:
|
|
||||||
authToken: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
state: success
|
|
||||||
description: Playwright skipped
|
|
||||||
|
|
||||||
# Keep in step with the `context` that is updated by `Sibz/github-status-action`
|
|
||||||
# in matrix-org/matrix-react-sdk/.github/workflows/end-to-end-tests.yaml.
|
|
||||||
context: "${{ github.workflow }} / end-to-end-tests"
|
|
||||||
|
|
||||||
sha: "${{ github.event.workflow_run.head_sha }}"
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ jobs:
|
||||||
needs: jest
|
needs: jest
|
||||||
steps:
|
steps:
|
||||||
- name: Skip SonarCloud
|
- name: Skip SonarCloud
|
||||||
uses: Sibz/github-status-action@071b5370da85afbb16637d6eed8524a06bc2053e # v1
|
uses: Sibz/github-status-action@faaa4d96fecf273bd762985e0e7f9f933c774918 # v1
|
||||||
with:
|
with:
|
||||||
authToken: ${{ secrets.GITHUB_TOKEN }}
|
authToken: ${{ secrets.GITHUB_TOKEN }}
|
||||||
state: success
|
state: success
|
||||||
|
|
|
@ -6,15 +6,6 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
automate-project-columns:
|
automate-project-columns:
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: alex-page/github-project-automation-plus@303f24a24c67ce7adf565a07e96720faf126fe36
|
|
||||||
with:
|
|
||||||
project: Issue triage
|
|
||||||
column: Incoming
|
|
||||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
|
||||||
|
|
||||||
automate-project-columns-next:
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/add-to-project@main
|
- uses: actions/add-to-project@main
|
||||||
|
|
|
@ -24,8 +24,7 @@ jobs:
|
||||||
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
contains(github.event.issue.labels.*.name, 'A-Video-Rooms') ||
|
||||||
contains(github.event.issue.labels.*.name, 'A-Message-Starring') ||
|
contains(github.event.issue.labels.*.name, 'A-Message-Starring') ||
|
||||||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
||||||
contains(github.event.issue.labels.*.name, 'A-Element-Call') ||
|
contains(github.event.issue.labels.*.name, 'A-Element-Call')
|
||||||
contains(github.event.issue.labels.*.name, 'A-Element-R')
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/github-script@v7
|
- uses: actions/github-script@v7
|
||||||
with:
|
with:
|
||||||
|
@ -61,8 +60,8 @@ jobs:
|
||||||
- uses: konradpabjan/move-labeled-or-milestoned-issue@190352295fe309fcb113b49193bc81d9aaa9cb01
|
- uses: konradpabjan/move-labeled-or-milestoned-issue@190352295fe309fcb113b49193bc81d9aaa9cb01
|
||||||
with:
|
with:
|
||||||
action-token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
|
action-token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
|
||||||
project-url: "https://github.com/element-hq/element-web/projects/27"
|
project-url: "https://github.com/orgs/element-hq/projects/120"
|
||||||
column-name: "Need info"
|
column-name: "Needs info"
|
||||||
label-name: "X-Needs-Info"
|
label-name: "X-Needs-Info"
|
||||||
|
|
||||||
add_priority_design_issues_to_project:
|
add_priority_design_issues_to_project:
|
||||||
|
@ -149,7 +148,7 @@ jobs:
|
||||||
contains(github.event.issue.labels.*.name, 'A-Element-R')
|
contains(github.event.issue.labels.*.name, 'A-Element-R')
|
||||||
steps:
|
steps:
|
||||||
- id: add_to_project
|
- id: add_to_project
|
||||||
uses: actions/add-to-project@v0.5.0
|
uses: actions/add-to-project@v1.0.1
|
||||||
with:
|
with:
|
||||||
project-url: ${{ env.PROJECT_URL }}
|
project-url: ${{ env.PROJECT_URL }}
|
||||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
name: Close stale flaky issues
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 1 * * *"
|
||||||
|
jobs:
|
||||||
|
close:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v9
|
||||||
|
with:
|
||||||
|
only-labels: "Z-Flaky-Test"
|
||||||
|
days-before-stale: 14
|
||||||
|
days-before-close: 0
|
||||||
|
close-issue-message: "This flaky test issue has not been updated in 14 days. It is being closed as presumed resolved."
|
||||||
|
exempt-issue-labels: "Z-Flaky-Test-Disabled"
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
run: "yarn update:jitsi"
|
run: "yarn update:jitsi"
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create Pull Request
|
||||||
uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 # v5
|
uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6
|
||||||
with:
|
with:
|
||||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||||
branch: actions/jitsi-update
|
branch: actions/jitsi-update
|
||||||
|
|
175
CHANGELOG.md
175
CHANGELOG.md
|
@ -1,3 +1,178 @@
|
||||||
|
Changes in [1.11.68](https://github.com/element-hq/element-web/releases/tag/v1.11.68) (2024-06-04)
|
||||||
|
==================================================================================================
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
* Tooltip: Improve accessibility for context menus ([#12462](https://github.com/matrix-org/matrix-react-sdk/pull/12462)). Contributed by @florianduros.
|
||||||
|
* Tooltip: Improve accessibility of space panel ([#12525](https://github.com/matrix-org/matrix-react-sdk/pull/12525)). Contributed by @florianduros.
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* Close the release announcement when a dialog is opened ([#12559](https://github.com/matrix-org/matrix-react-sdk/pull/12559)). Contributed by @florianduros.
|
||||||
|
* Tooltip: close field tooltip when ESC is pressed ([#12553](https://github.com/matrix-org/matrix-react-sdk/pull/12553)). Contributed by @florianduros.
|
||||||
|
* Fix tabbedview breakpoint width ([#12556](https://github.com/matrix-org/matrix-react-sdk/pull/12556)). Contributed by @dbkr.
|
||||||
|
* Fix E2E icon display in room header ([#12545](https://github.com/matrix-org/matrix-react-sdk/pull/12545)). Contributed by @florianduros.
|
||||||
|
* Tooltip: Improve placement for space settings ([#12541](https://github.com/matrix-org/matrix-react-sdk/pull/12541)). Contributed by @florianduros.
|
||||||
|
* Fix deformed avatar in a call in a narrow timeline ([#12538](https://github.com/matrix-org/matrix-react-sdk/pull/12538)). Contributed by @florianduros.
|
||||||
|
* Shown own sent state indicator even when showReadReceipts is disabled ([#12540](https://github.com/matrix-org/matrix-react-sdk/pull/12540)). Contributed by @t3chguy.
|
||||||
|
* Ensure we do not fire the verification mismatch modal multiple times ([#12526](https://github.com/matrix-org/matrix-react-sdk/pull/12526)). Contributed by @t3chguy.
|
||||||
|
* Fix avatar in chat export ([#12537](https://github.com/matrix-org/matrix-react-sdk/pull/12537)). Contributed by @florianduros.
|
||||||
|
* Use `*` for italics as it doesn't break when used mid-word ([#12523](https://github.com/matrix-org/matrix-react-sdk/pull/12523)). Contributed by @t3chguy.
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [1.11.67](https://github.com/element-hq/element-web/releases/tag/v1.11.67) (2024-05-22)
|
||||||
|
==================================================================================================
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
* Tooltip: Improve the accessibility of the composer and the rich text editor ([#12459](https://github.com/matrix-org/matrix-react-sdk/pull/12459)). Contributed by @florianduros.
|
||||||
|
* Allow explicit configuration of OIDC dynamic registration metadata ([#12514](https://github.com/matrix-org/matrix-react-sdk/pull/12514)). Contributed by @t3chguy.
|
||||||
|
* Tooltip: improve accessibility for messages ([#12487](https://github.com/matrix-org/matrix-react-sdk/pull/12487)). Contributed by @florianduros.
|
||||||
|
* Collapse UserSettings tabs to just icons on narrow screens ([#12505](https://github.com/matrix-org/matrix-react-sdk/pull/12505)). Contributed by @dbkr.
|
||||||
|
* Add room topic to right panel room info ([#12503](https://github.com/matrix-org/matrix-react-sdk/pull/12503)). Contributed by @t3chguy.
|
||||||
|
* OIDC: pass `id_token` via `id_token_hint` on Manage Account interaction ([#12499](https://github.com/matrix-org/matrix-react-sdk/pull/12499)). Contributed by @t3chguy.
|
||||||
|
* Tooltip: improve accessibility in room ([#12493](https://github.com/matrix-org/matrix-react-sdk/pull/12493)). Contributed by @florianduros.
|
||||||
|
* Tooltip: improve accessibility for call and voice messages ([#12489](https://github.com/matrix-org/matrix-react-sdk/pull/12489)). Contributed by @florianduros.
|
||||||
|
* Move the active tab in user settings to the dialog title ([#12481](https://github.com/matrix-org/matrix-react-sdk/pull/12481)). Contributed by @dbkr.
|
||||||
|
* Tooltip: improve accessibility of spaces ([#12497](https://github.com/matrix-org/matrix-react-sdk/pull/12497)). Contributed by @florianduros.
|
||||||
|
* Tooltip: improve accessibility of the right panel ([#12490](https://github.com/matrix-org/matrix-react-sdk/pull/12490)). Contributed by @florianduros.
|
||||||
|
* MSC3575 (Sliding Sync) add well-known proxy support ([#12307](https://github.com/matrix-org/matrix-react-sdk/pull/12307)). Contributed by @EdGeraghty.
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* Reuse single PlaybackWorker between Playback instances ([#12520](https://github.com/matrix-org/matrix-react-sdk/pull/12520)). Contributed by @t3chguy.
|
||||||
|
* Fix well-known lookup for sliding sync labs check ([#12519](https://github.com/matrix-org/matrix-react-sdk/pull/12519)). Contributed by @t3chguy.
|
||||||
|
* Fix `element-desktop-ssoid being` included in OIDC Authorization call ([#12495](https://github.com/matrix-org/matrix-react-sdk/pull/12495)). Contributed by @t3chguy.
|
||||||
|
* Fix beta notifications reconciliation for intentional mentions push rules ([#12510](https://github.com/matrix-org/matrix-react-sdk/pull/12510)). Contributed by @t3chguy.
|
||||||
|
* fix avatar stretched on 1:1 call ([#12494](https://github.com/matrix-org/matrix-react-sdk/pull/12494)). Contributed by @I-lander.
|
||||||
|
* Check native sliding sync support against an unstable feature flag ([#12498](https://github.com/matrix-org/matrix-react-sdk/pull/12498)). Contributed by @turt2live.
|
||||||
|
* Use OPTIONS for sliding sync detection poke ([#12492](https://github.com/matrix-org/matrix-react-sdk/pull/12492)). Contributed by @turt2live.
|
||||||
|
* TAC: hide tooltip when the release announcement is displayed ([#12472](https://github.com/matrix-org/matrix-react-sdk/pull/12472)). Contributed by @florianduros.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [1.11.66](https://github.com/element-hq/element-web/releases/tag/v1.11.66) (2024-05-07)
|
||||||
|
==================================================================================================
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
* Use a different error message for UTDs when you weren't in the room. ([#12453](https://github.com/matrix-org/matrix-react-sdk/pull/12453)). Contributed by @uhoreg.
|
||||||
|
* Take the Threads Activity Centre out of labs ([#12439](https://github.com/matrix-org/matrix-react-sdk/pull/12439)). Contributed by @dbkr.
|
||||||
|
* Expected UTDs: use a different message for UTDs sent before login ([#12391](https://github.com/matrix-org/matrix-react-sdk/pull/12391)). Contributed by @richvdh.
|
||||||
|
* Add `Tooltip` to `AccessibleButton` ([#12443](https://github.com/matrix-org/matrix-react-sdk/pull/12443)). Contributed by @florianduros.
|
||||||
|
* Add analytics to activity toggles ([#12418](https://github.com/matrix-org/matrix-react-sdk/pull/12418)). Contributed by @dbkr.
|
||||||
|
* Decrypt events in reverse order without copying the array ([#12445](https://github.com/matrix-org/matrix-react-sdk/pull/12445)). Contributed by @Johennes.
|
||||||
|
* Use new compound tooltip ([#12416](https://github.com/matrix-org/matrix-react-sdk/pull/12416)). Contributed by @florianduros.
|
||||||
|
* Expected UTDs: report a different Posthog code ([#12389](https://github.com/matrix-org/matrix-react-sdk/pull/12389)). Contributed by @richvdh.
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* TAC: Fix accessibility issue when the Release announcement is displayed ([#12484](https://github.com/matrix-org/matrix-react-sdk/pull/12484)). Contributed by @RiotRobot.
|
||||||
|
* TAC: Close Release Announcement when TAC button is clicked ([#12485](https://github.com/matrix-org/matrix-react-sdk/pull/12485)). Contributed by @florianduros.
|
||||||
|
* MenuItem: fix caption usage ([#12455](https://github.com/matrix-org/matrix-react-sdk/pull/12455)). Contributed by @florianduros.
|
||||||
|
* Show the local echo in previews ([#12451](https://github.com/matrix-org/matrix-react-sdk/pull/12451)). Contributed by @langleyd.
|
||||||
|
* Fixed the drag and drop of X #27186 ([#12450](https://github.com/matrix-org/matrix-react-sdk/pull/12450)). Contributed by @asimdelvi.
|
||||||
|
* Move the TAC to above the button ([#12438](https://github.com/matrix-org/matrix-react-sdk/pull/12438)). Contributed by @dbkr.
|
||||||
|
* Use the same logic in previews as the timeline to hide events that should be hidden ([#12434](https://github.com/matrix-org/matrix-react-sdk/pull/12434)). Contributed by @langleyd.
|
||||||
|
* Fix selector so maths support doesn't mangle divs ([#12433](https://github.com/matrix-org/matrix-react-sdk/pull/12433)). Contributed by @uhoreg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [1.11.65](https://github.com/element-hq/element-web/releases/tag/v1.11.65) (2024-04-23)
|
||||||
|
==================================================================================================
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
* Make empty state copy for TAC depend on the value of the setting ([#12419](https://github.com/matrix-org/matrix-react-sdk/pull/12419)). Contributed by @dbkr.
|
||||||
|
* Linkify User Interactive Authentication errors ([#12271](https://github.com/matrix-org/matrix-react-sdk/pull/12271)). Contributed by @t3chguy.
|
||||||
|
* Add support for device dehydration v2 ([#12316](https://github.com/matrix-org/matrix-react-sdk/pull/12316)). Contributed by @uhoreg.
|
||||||
|
* Replace `SecurityCustomisations` with `CryptoSetupExtension` ([#12342](https://github.com/matrix-org/matrix-react-sdk/pull/12342)). Contributed by @thoraj.
|
||||||
|
* Add activity toggle for TAC ([#12413](https://github.com/matrix-org/matrix-react-sdk/pull/12413)). Contributed by @dbkr.
|
||||||
|
* Humanize spell check language labels ([#12409](https://github.com/matrix-org/matrix-react-sdk/pull/12409)). Contributed by @t3chguy.
|
||||||
|
* Call Guest Access, give user the option to change the acces level so they can generate a call link. ([#12401](https://github.com/matrix-org/matrix-react-sdk/pull/12401)). Contributed by @toger5.
|
||||||
|
* TAC: Release Announcement ([#12380](https://github.com/matrix-org/matrix-react-sdk/pull/12380)). Contributed by @florianduros.
|
||||||
|
* Show the call and share button if the user can create a guest link. ([#12385](https://github.com/matrix-org/matrix-react-sdk/pull/12385)). Contributed by @toger5.
|
||||||
|
* Add analytics for mark all threads unread ([#12384](https://github.com/matrix-org/matrix-react-sdk/pull/12384)). Contributed by @dbkr.
|
||||||
|
* Add `EventType.RoomEncryption` to the auto approve capabilities of Element Call widgets ([#12386](https://github.com/matrix-org/matrix-react-sdk/pull/12386)). Contributed by @toger5.
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* Fix link modal not shown after access upgrade ([#12411](https://github.com/matrix-org/matrix-react-sdk/pull/12411)). Contributed by @toger5.
|
||||||
|
* Fix thread navigation in timeline ([#12412](https://github.com/matrix-org/matrix-react-sdk/pull/12412)). Contributed by @florianduros.
|
||||||
|
* Fix inability to join a `knock` room via space hierarchy view ([#12404](https://github.com/matrix-org/matrix-react-sdk/pull/12404)). Contributed by @t3chguy.
|
||||||
|
* Focus the thread panel when clicking on an item in the TAC ([#12410](https://github.com/matrix-org/matrix-react-sdk/pull/12410)). Contributed by @dbkr.
|
||||||
|
* Fix space hierarchy tile busy state being stuck after join error ([#12405](https://github.com/matrix-org/matrix-react-sdk/pull/12405)). Contributed by @t3chguy.
|
||||||
|
* Fix room topic in-app links not being handled correctly on topic dialog ([#12406](https://github.com/matrix-org/matrix-react-sdk/pull/12406)). Contributed by @t3chguy.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [1.11.64](https://github.com/element-hq/element-web/releases/tag/v1.11.64) (2024-04-09)
|
||||||
|
==================================================================================================
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
* Mark all threads as read button ([#12378](https://github.com/matrix-org/matrix-react-sdk/pull/12378)). Contributed by @dbkr.
|
||||||
|
* Video call meta space ([#12297](https://github.com/matrix-org/matrix-react-sdk/pull/12297)). Contributed by @toger5.
|
||||||
|
* Add leave room warning for last admin ([#9452](https://github.com/matrix-org/matrix-react-sdk/pull/9452)). Contributed by @Arnei.
|
||||||
|
* Iterate styles around Link new device via QR ([#12356](https://github.com/matrix-org/matrix-react-sdk/pull/12356)). Contributed by @t3chguy.
|
||||||
|
* Improve code-splitting of highlight.js and maplibre-gs libs ([#12349](https://github.com/matrix-org/matrix-react-sdk/pull/12349)). Contributed by @t3chguy.
|
||||||
|
* Use data-mx-color for rainbows ([#12325](https://github.com/matrix-org/matrix-react-sdk/pull/12325)). Contributed by @tulir.
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* Fix external guest access url for unencrypted rooms ([#12345](https://github.com/matrix-org/matrix-react-sdk/pull/12345)). Contributed by @toger5.
|
||||||
|
* Fix video rooms not showing share link button ([#12374](https://github.com/matrix-org/matrix-react-sdk/pull/12374)). Contributed by @toger5.
|
||||||
|
* Fix space topic jumping on hover/focus ([#12377](https://github.com/matrix-org/matrix-react-sdk/pull/12377)). Contributed by @t3chguy.
|
||||||
|
* Allow popping out a Jitsi widget to respect Desktop `web_base_url` config ([#12376](https://github.com/matrix-org/matrix-react-sdk/pull/12376)). Contributed by @t3chguy.
|
||||||
|
* Remove the Lazy Loading `InvalidStoreError` Dialogs ([#12358](https://github.com/matrix-org/matrix-react-sdk/pull/12358)). Contributed by @langleyd.
|
||||||
|
* Improve readability of badges and pills ([#12360](https://github.com/matrix-org/matrix-react-sdk/pull/12360)). Contributed by @robintown.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [1.11.63](https://github.com/element-hq/element-web/releases/tag/v1.11.63) (2024-03-28)
|
||||||
|
==================================================================================================
|
||||||
|
This is a hotfix release to fix a couple of issues: one where the client would sometimes call the client/server API to set a push rule in a loop, and one where authentication was not sent for widgets when it should have been.
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* Revert "Make EC widget theme reactive - Update widget url when the theme changes" ([#12383](https://github.com/matrix-org/matrix-react-sdk/pull/12383)) in order to fix widgets that require authentication.
|
||||||
|
* Update to hotfixed js-sdk to fix an issue where Element could try to set a push rule in a loop.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [1.11.62](https://github.com/element-hq/element-web/releases/tag/v1.11.62) (2024-03-26)
|
||||||
|
==================================================================================================
|
||||||
|
## ✨ Features
|
||||||
|
|
||||||
|
* Change user permission by using a new apply button ([#12346](https://github.com/matrix-org/matrix-react-sdk/pull/12346)). Contributed by @florianduros.
|
||||||
|
* Mark as Unread ([#12254](https://github.com/matrix-org/matrix-react-sdk/pull/12254)). Contributed by @dbkr.
|
||||||
|
* Refine the colors of some more components ([#12343](https://github.com/matrix-org/matrix-react-sdk/pull/12343)). Contributed by @robintown.
|
||||||
|
* TAC: Order rooms by most recent after notification level ([#12329](https://github.com/matrix-org/matrix-react-sdk/pull/12329)). Contributed by @florianduros.
|
||||||
|
* Make EC widget theme reactive - Update widget url when the theme changes ([#12295](https://github.com/matrix-org/matrix-react-sdk/pull/12295)). Contributed by @toger5.
|
||||||
|
* Refine styles of menus, toasts, popovers, and modals ([#12332](https://github.com/matrix-org/matrix-react-sdk/pull/12332)). Contributed by @robintown.
|
||||||
|
* Element Call: fix widget shown while its still loading (`waitForIframeLoad=false`) ([#12292](https://github.com/matrix-org/matrix-react-sdk/pull/12292)). Contributed by @toger5.
|
||||||
|
* Improve Forward Dialog a11y by switching to roving tab index interactions ([#12306](https://github.com/matrix-org/matrix-react-sdk/pull/12306)). Contributed by @t3chguy.
|
||||||
|
* Call guest access link creation to join calls as a non registered user via the EC SPA ([#12259](https://github.com/matrix-org/matrix-react-sdk/pull/12259)). Contributed by @toger5.
|
||||||
|
* Use `strong` element to semantically denote visually emphasised content ([#12320](https://github.com/matrix-org/matrix-react-sdk/pull/12320)). Contributed by @t3chguy.
|
||||||
|
* Handle up/down arrow keys as well as left/right for horizontal toolbars for improved a11y ([#12305](https://github.com/matrix-org/matrix-react-sdk/pull/12305)). Contributed by @t3chguy.
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* [Backport staging] Remove the glass border from modal spinners ([#12369](https://github.com/matrix-org/matrix-react-sdk/pull/12369)). Contributed by @RiotRobot.
|
||||||
|
* Fix incorrect check for private read receipt support ([#12348](https://github.com/matrix-org/matrix-react-sdk/pull/12348)). Contributed by @tulir.
|
||||||
|
* TAC: Fix hover state when expanded ([#12337](https://github.com/matrix-org/matrix-react-sdk/pull/12337)). Contributed by @florianduros.
|
||||||
|
* Fix the image view ([#12341](https://github.com/matrix-org/matrix-react-sdk/pull/12341)). Contributed by @robintown.
|
||||||
|
* Use correct push rule to evaluate room-wide mentions ([#12318](https://github.com/matrix-org/matrix-react-sdk/pull/12318)). Contributed by @t3chguy.
|
||||||
|
* Reset power selector on API failure to prevent state mismatch ([#12319](https://github.com/matrix-org/matrix-react-sdk/pull/12319)). Contributed by @t3chguy.
|
||||||
|
* Fix spotlight opening in TAC ([#12315](https://github.com/matrix-org/matrix-react-sdk/pull/12315)). Contributed by @florianduros.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Changes in [1.11.61](https://github.com/element-hq/element-web/releases/tag/v1.11.61) (2024-03-14)
|
||||||
|
==================================================================================================
|
||||||
|
* No changes
|
||||||
|
|
||||||
|
## 🐛 Bug Fixes
|
||||||
|
|
||||||
|
* Update `@vector-im/compound-design-tokens` in package.json ([#12340](https://github.com/matrix-org/matrix-react-sdk/pull/12340)).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changes in [1.11.60](https://github.com/element-hq/element-web/releases/tag/v1.11.60) (2024-03-12)
|
Changes in [1.11.60](https://github.com/element-hq/element-web/releases/tag/v1.11.60) (2024-03-12)
|
||||||
==================================================================================================
|
==================================================================================================
|
||||||
## ✨ Features
|
## ✨ Features
|
||||||
|
|
|
@ -225,6 +225,12 @@ Unless otherwise specified, the following applies to all code:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
37. Avoid functions whose fundamental behaviour varies with different parameter types.
|
||||||
|
Multiple return types are fine, but if the function's behaviour is going to change significantly,
|
||||||
|
have two separate functions. For example, `SDKConfig.get()` with a string param which returns the
|
||||||
|
type according to the param given is ok, but `SDKConfig.get()` with no args returning the whole
|
||||||
|
config object would not be: this should just be a separate function.
|
||||||
|
|
||||||
## React
|
## React
|
||||||
|
|
||||||
Inheriting all the rules of TypeScript, the following additionally apply:
|
Inheriting all the rules of TypeScript, the following additionally apply:
|
||||||
|
|
|
@ -250,17 +250,60 @@ When Element is deployed alongside a homeserver with SSO-only login, some option
|
||||||
user can be sent to in order to log them out of that system too, making logout symmetric between Element and the SSO system.
|
user can be sent to in order to log them out of that system too, making logout symmetric between Element and the SSO system.
|
||||||
2. `sso_redirect_options`: Options to define how to handle unauthenticated users. If the object contains `"immediate": true`, then
|
2. `sso_redirect_options`: Options to define how to handle unauthenticated users. If the object contains `"immediate": true`, then
|
||||||
all unauthenticated users will be automatically redirected to the SSO system to start their login. If instead you'd only like to
|
all unauthenticated users will be automatically redirected to the SSO system to start their login. If instead you'd only like to
|
||||||
have users which land on the welcome page to be redirected, use `"on_welcome_page": true`. As an example:
|
have users which land on the welcome page to be redirected, use `"on_welcome_page": true`. Additionally, there is an option to
|
||||||
|
redirect anyone landing on the login page, by using `"on_login_page": true`. As an example:
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"sso_redirect_options": {
|
"sso_redirect_options": {
|
||||||
"immediate": false,
|
"immediate": false,
|
||||||
"on_welcome_page": true
|
"on_welcome_page": true,
|
||||||
|
"on_login_page": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
It is most common to use the `immediate` flag instead of `on_welcome_page`.
|
It is most common to use the `immediate` flag instead of `on_welcome_page`.
|
||||||
|
|
||||||
|
## Native OIDC
|
||||||
|
|
||||||
|
Native OIDC support is currently in labs and is subject to change.
|
||||||
|
|
||||||
|
Static OIDC Client IDs are preferred and can be specified under `oidc_static_clients` as a mapping from `issuer` to configuration object containing `client_id`.
|
||||||
|
Issuer must have a trailing forward slash. As an example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"oidc_static_clients": {
|
||||||
|
"https://auth.example.com/": {
|
||||||
|
"client_id": "example-client-id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If a matching static client is not found, the app will attempt to dynamically register a client using metadata specified under `oidc_metadata`.
|
||||||
|
The app has sane defaults for the metadata properties below but on stricter policy identity providers they may not pass muster, e.g. `contacts` may be required.
|
||||||
|
The following subproperties are available:
|
||||||
|
|
||||||
|
1. `client_uri`: This is the base URI for the OIDC client registration, typically `logo_uri`, `tos_uri`, and `policy_uri` must be either on the same domain or a subdomain of this URI.
|
||||||
|
2. `logo_uri`: Optional URI for the client logo.
|
||||||
|
3. `tos_uri`: Optional URI for the client's terms of service.
|
||||||
|
4. `policy_uri`: Optional URI for the client's privacy policy.
|
||||||
|
5. `contacts`: Optional list of contact emails for the client.
|
||||||
|
|
||||||
|
As an example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"oidc_metadata": {
|
||||||
|
"client_uri": "https://example.com",
|
||||||
|
"logo_uri": "https://example.com/logo.png",
|
||||||
|
"tos_uri": "https://example.com/tos",
|
||||||
|
"policy_uri": "https://example.com/policy",
|
||||||
|
"contacts": ["support@example.com"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## VoIP / Jitsi calls
|
## VoIP / Jitsi calls
|
||||||
|
|
||||||
Currently, Element uses Jitsi to offer conference calls in rooms, with an experimental Element Call implementation in the works.
|
Currently, Element uses Jitsi to offer conference calls in rooms, with an experimental Element Call implementation in the works.
|
||||||
|
@ -344,6 +387,12 @@ The VoIP and Jitsi options are:
|
||||||
this number is exceeded, the user will not be able to join a given call.
|
this number is exceeded, the user will not be able to join a given call.
|
||||||
- `brand`: Optional name for the app. Defaults to `Element Call`. This is
|
- `brand`: Optional name for the app. Defaults to `Element Call`. This is
|
||||||
used throughout the application in various strings/locations.
|
used throughout the application in various strings/locations.
|
||||||
|
- `guest_spa_url`: Optional URL for an Element Call single-page app (SPA),
|
||||||
|
for guest links. If this is set, Element Web will expose a "join" link
|
||||||
|
for public video rooms, which can then be shared to non-matrix users.
|
||||||
|
The target Element Call SPA is typically set up to use a homeserver that
|
||||||
|
allows users to register without email ("passwordless guest users") and to
|
||||||
|
federate.
|
||||||
|
|
||||||
## Bug reporting
|
## Bug reporting
|
||||||
|
|
||||||
|
|
|
@ -14,10 +14,9 @@
|
||||||
|
|
||||||
## How to check if your language already is being translated
|
## How to check if your language already is being translated
|
||||||
|
|
||||||
Go to https://localazy.com/p/element-web
|
Go to https://localazy.com/p/element-web. If your language is listed then you can get started. Have a read
|
||||||
If your language is listed then you can get started, have a read of https://localazy.com/docs/general/translating-strings
|
of https://localazy.com/docs/general/translating-strings if you need help getting started. If your language is not yet
|
||||||
if you need help getting started. If your language is not yet listed please express your wishes to start translating it in
|
listed please express your wishes to start translating it in the general discussion room linked above.
|
||||||
the general discussion room linked above.
|
|
||||||
|
|
||||||
### What are `%(something)s`?
|
### What are `%(something)s`?
|
||||||
|
|
||||||
|
|
|
@ -43,5 +43,8 @@
|
||||||
"api_host": "https://posthog.element.io"
|
"api_host": "https://posthog.element.io"
|
||||||
},
|
},
|
||||||
"privacy_policy_url": "https://element.io/cookie-policy",
|
"privacy_policy_url": "https://element.io/cookie-policy",
|
||||||
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx"
|
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
|
||||||
|
"setting_defaults": {
|
||||||
|
"RustCrypto.staged_rollout_percent": 60
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
},
|
},
|
||||||
"privacy_policy_url": "https://element.io/cookie-policy",
|
"privacy_policy_url": "https://element.io/cookie-policy",
|
||||||
"features": {
|
"features": {
|
||||||
|
"threadsActivityCentre": true,
|
||||||
"feature_video_rooms": true,
|
"feature_video_rooms": true,
|
||||||
"feature_new_room_decoration_ui": true,
|
"feature_new_room_decoration_ui": true,
|
||||||
"feature_element_call_video_rooms": true
|
"feature_element_call_video_rooms": true
|
||||||
|
|
55
package.json
55
package.json
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "element-web",
|
"name": "element-web",
|
||||||
"version": "1.11.60",
|
"version": "1.11.68",
|
||||||
"description": "A feature-rich client for Matrix.org",
|
"description": "A feature-rich client for Matrix.org",
|
||||||
"author": "New Vector Ltd.",
|
"author": "New Vector Ltd.",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
@ -67,26 +67,25 @@
|
||||||
"update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js"
|
"update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"@types/react-dom": "17.0.21",
|
"@types/react-dom": "17.0.25",
|
||||||
"@types/react": "17.0.68"
|
"@types/react": "17.0.80"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@matrix-org/olm": "3.2.15",
|
"@matrix-org/olm": "3.2.15",
|
||||||
"@matrix-org/react-sdk-module-api": "^2.3.0",
|
"@matrix-org/react-sdk-module-api": "^2.3.0",
|
||||||
"gfm.css": "^1.1.2",
|
|
||||||
"jsrsasign": "^11.0.0",
|
"jsrsasign": "^11.0.0",
|
||||||
"katex": "^0.16.0",
|
"katex": "^0.16.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"matrix-js-sdk": "31.5.0",
|
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
|
||||||
"matrix-react-sdk": "3.94.0",
|
"matrix-react-sdk": "github:matrix-org/matrix-react-sdk#develop",
|
||||||
"matrix-widget-api": "^1.3.1",
|
"matrix-widget-api": "^1.3.1",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
"react-dom": "17.0.2",
|
"react-dom": "17.0.2",
|
||||||
"ua-parser-js": "^1.0.0"
|
"ua-parser-js": "^1.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@action-validator/cli": "^0.5.3",
|
"@action-validator/cli": "^0.6.0",
|
||||||
"@action-validator/core": "^0.5.3",
|
"@action-validator/core": "^0.6.0",
|
||||||
"@babel/core": "^7.12.10",
|
"@babel/core": "^7.12.10",
|
||||||
"@babel/eslint-parser": "^7.12.10",
|
"@babel/eslint-parser": "^7.12.10",
|
||||||
"@babel/eslint-plugin": "^7.12.10",
|
"@babel/eslint-plugin": "^7.12.10",
|
||||||
|
@ -107,7 +106,7 @@
|
||||||
"@casualbot/jest-sonar-reporter": "2.2.7",
|
"@casualbot/jest-sonar-reporter": "2.2.7",
|
||||||
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
|
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
|
||||||
"@sentry/webpack-plugin": "^2.7.1",
|
"@sentry/webpack-plugin": "^2.7.1",
|
||||||
"@svgr/webpack": "^5.5.0",
|
"@svgr/webpack": "^8.0.0",
|
||||||
"@testing-library/react": "^12.1.5",
|
"@testing-library/react": "^12.1.5",
|
||||||
"@types/commonmark": "^0.27.9",
|
"@types/commonmark": "^0.27.9",
|
||||||
"@types/content-type": "^1.1.8",
|
"@types/content-type": "^1.1.8",
|
||||||
|
@ -127,12 +126,13 @@
|
||||||
"@types/node-fetch": "^2.6.4",
|
"@types/node-fetch": "^2.6.4",
|
||||||
"@types/pako": "^2.0.3",
|
"@types/pako": "^2.0.3",
|
||||||
"@types/qrcode": "^1.5.5",
|
"@types/qrcode": "^1.5.5",
|
||||||
"@types/react": "17.0.68",
|
"@types/react": "17.0.80",
|
||||||
"@types/react-beautiful-dnd": "^13.1.7",
|
"@types/react-beautiful-dnd": "^13.1.7",
|
||||||
"@types/react-dom": "17.0.21",
|
"@types/react-dom": "17.0.25",
|
||||||
"@types/react-transition-group": "^4.4.9",
|
"@types/react-transition-group": "^4.4.9",
|
||||||
"@types/sanitize-html": "^2.9.5",
|
"@types/sanitize-html": "^2.9.5",
|
||||||
"@types/sdp-transform": "^2.4.9",
|
"@types/sdp-transform": "^2.4.9",
|
||||||
|
"@types/semver": "^7.5.8",
|
||||||
"@types/tar-js": "^0.3.5",
|
"@types/tar-js": "^0.3.5",
|
||||||
"@types/ua-parser-js": "^0.7.36",
|
"@types/ua-parser-js": "^0.7.36",
|
||||||
"@types/uuid": "^9.0.7",
|
"@types/uuid": "^9.0.7",
|
||||||
|
@ -146,19 +146,19 @@
|
||||||
"concurrently": "^8.0.0",
|
"concurrently": "^8.0.0",
|
||||||
"copy-webpack-plugin": "^12.0.0",
|
"copy-webpack-plugin": "^12.0.0",
|
||||||
"cronstrue": "^2.41.0",
|
"cronstrue": "^2.41.0",
|
||||||
"css-loader": "^6.0.0",
|
"css-loader": "^7.0.0",
|
||||||
"css-minimizer-webpack-plugin": "^6.0.0",
|
"css-minimizer-webpack-plugin": "^7.0.0",
|
||||||
"dotenv": "^16.0.2",
|
"dotenv": "^16.0.2",
|
||||||
"eslint": "8.56.0",
|
"eslint": "8.57.0",
|
||||||
"eslint-config-google": "^0.14.0",
|
"eslint-config-google": "^0.14.0",
|
||||||
"eslint-config-prettier": "^9.0.0",
|
"eslint-config-prettier": "^9.0.0",
|
||||||
"eslint-plugin-deprecate": "0.8.4",
|
"eslint-plugin-deprecate": "0.8.5",
|
||||||
"eslint-plugin-import": "^2.26.0",
|
"eslint-plugin-import": "^2.26.0",
|
||||||
"eslint-plugin-matrix-org": "^1.0.0",
|
"eslint-plugin-matrix-org": "^1.0.0",
|
||||||
"eslint-plugin-react": "^7.28.0",
|
"eslint-plugin-react": "^7.28.0",
|
||||||
"eslint-plugin-react-hooks": "^4.3.0",
|
"eslint-plugin-react-hooks": "^4.3.0",
|
||||||
"eslint-plugin-unicorn": "^51.0.0",
|
"eslint-plugin-unicorn": "^53.0.0",
|
||||||
"fake-indexeddb": "^5.0.0",
|
"fake-indexeddb": "^6.0.0",
|
||||||
"fetch-mock": "9.11.0",
|
"fetch-mock": "9.11.0",
|
||||||
"fetch-mock-jest": "^1.5.1",
|
"fetch-mock-jest": "^1.5.1",
|
||||||
"file-loader": "^6.0.0",
|
"file-loader": "^6.0.0",
|
||||||
|
@ -170,41 +170,40 @@
|
||||||
"jest-raw-loader": "^1.0.1",
|
"jest-raw-loader": "^1.0.1",
|
||||||
"matrix-mock-request": "^2.5.0",
|
"matrix-mock-request": "^2.5.0",
|
||||||
"matrix-web-i18n": "^3.2.1",
|
"matrix-web-i18n": "^3.2.1",
|
||||||
"mini-css-extract-plugin": "^2.7.6",
|
"mini-css-extract-plugin": "2.8.0",
|
||||||
"minimist": "^1.2.6",
|
"minimist": "^1.2.6",
|
||||||
"mkdirp": "^3.0.0",
|
"mkdirp": "^3.0.0",
|
||||||
"modernizr": "^3.12.0",
|
"modernizr": "^3.12.0",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
"postcss": "8.4.33",
|
"postcss": "8.4.33",
|
||||||
"postcss-easings": "^2.0.0",
|
"postcss-easings": "^4.0.0",
|
||||||
"postcss-hexrgba": "2.0.1",
|
"postcss-hexrgba": "2.1.0",
|
||||||
"postcss-import": "16.0.0",
|
"postcss-import": "16.0.0",
|
||||||
"postcss-loader": "^8.1.0",
|
"postcss-loader": "8.1.0",
|
||||||
"postcss-mixins": "^6.2.3",
|
"postcss-mixins": "^10.0.0",
|
||||||
"postcss-nested": "^4.2.3",
|
"postcss-nested": "^6.0.0",
|
||||||
"postcss-preset-env": "^9.3.0",
|
"postcss-preset-env": "^9.3.0",
|
||||||
"postcss-scss": "^4.0.4",
|
"postcss-scss": "^4.0.4",
|
||||||
"postcss-simple-vars": "^7.0.1",
|
"postcss-simple-vars": "^7.0.1",
|
||||||
"prettier": "3.2.5",
|
"prettier": "3.3.2",
|
||||||
"process": "^0.11.10",
|
"process": "^0.11.10",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
"rimraf": "^5.0.0",
|
"rimraf": "^5.0.0",
|
||||||
"semver": "^7.5.2",
|
"semver": "^7.5.2",
|
||||||
"setimmediate": "^1.0.5",
|
|
||||||
"string-replace-loader": "3",
|
"string-replace-loader": "3",
|
||||||
"style-loader": "3",
|
"style-loader": "4",
|
||||||
"stylelint": "^16.1.0",
|
"stylelint": "^16.1.0",
|
||||||
"stylelint-config-standard": "^36.0.0",
|
"stylelint-config-standard": "^36.0.0",
|
||||||
"stylelint-scss": "^6.0.0",
|
"stylelint-scss": "^6.0.0",
|
||||||
"terser-webpack-plugin": "^5.3.9",
|
"terser-webpack-plugin": "^5.3.9",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"ts-prune": "^0.10.3",
|
"ts-prune": "^0.10.3",
|
||||||
"typescript": "5.3.3",
|
"typescript": "5.4.5",
|
||||||
"util": "^0.12.5",
|
"util": "^0.12.5",
|
||||||
"webpack": "^5.89.0",
|
"webpack": "^5.89.0",
|
||||||
"webpack-bundle-analyzer": "^4.8.0",
|
"webpack-bundle-analyzer": "^4.8.0",
|
||||||
"webpack-cli": "^5.0.0",
|
"webpack-cli": "^5.0.0",
|
||||||
"webpack-dev-server": "^4.15.1",
|
"webpack-dev-server": "^5.0.0",
|
||||||
"yaml": "^2.3.3"
|
"yaml": "^2.3.3"
|
||||||
},
|
},
|
||||||
"@casualbot/jest-sonar-reporter": {
|
"@casualbot/jest-sonar-reporter": {
|
||||||
|
|
|
@ -38,7 +38,7 @@ module.exports.pitch = function pitch(request) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
}
|
}
|
||||||
if (entries[0]) {
|
if (entries[0]) {
|
||||||
return cb(null, `module.exports = __webpack_public_path__ + ${JSON.stringify(entries[0].files[0])};`);
|
return cb(null, `module.exports = __webpack_public_path__ + ${JSON.stringify([...entries[0].files][0])};`);
|
||||||
}
|
}
|
||||||
return cb(null, null);
|
return cb(null, null);
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
|
"target": {
|
||||||
|
"namespace": "android_app",
|
||||||
|
"package_name": "im.vector.app.debug",
|
||||||
|
"sha256_cert_fingerprints": [
|
||||||
|
"B0:B0:51:DC:56:5C:81:2F:E1:7F:6F:3E:94:5B:4D:79:04:71:23:AB:0D:A6:12:86:76:9E:B2:94:91:97:13:0E"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
|
"target": {
|
||||||
|
"namespace": "android_app",
|
||||||
|
"package_name": "im.vector.app.nightly",
|
||||||
|
"sha256_cert_fingerprints": [
|
||||||
|
"CA:D3:85:16:84:3A:05:CC:EB:00:AB:7B:D3:80:0F:01:BA:8F:E0:4B:38:86:F3:97:D8:F7:9A:1B:C4:54:E4:0F"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
|
"target": {
|
||||||
|
"namespace": "android_app",
|
||||||
|
"package_name": "im.vector.app",
|
||||||
|
"sha256_cert_fingerprints": [
|
||||||
|
"F3:FF:38:D2:E5:A6:38:84:86:4A:4E:0D:45:C5:3B:19:8E:7E:39:C0:50:5B:D9:63:F5:55:D6:53:2D:EA:BF:5F"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
|
"target": {
|
||||||
|
"namespace": "android_app",
|
||||||
|
"package_name": "io.element.android.x.debug",
|
||||||
|
"sha256_cert_fingerprints": [
|
||||||
|
"B0:B0:51:DC:56:5C:81:2F:E1:7F:6F:3E:94:5B:4D:79:04:71:23:AB:0D:A6:12:86:76:9E:B2:94:91:97:13:0E"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
|
"target": {
|
||||||
|
"namespace": "android_app",
|
||||||
|
"package_name": "io.element.android.x.nightly",
|
||||||
|
"sha256_cert_fingerprints": [
|
||||||
|
"CA:D3:85:16:84:3A:05:CC:EB:00:AB:7B:D3:80:0F:01:BA:8F:E0:4B:38:86:F3:97:D8:F7:9A:1B:C4:54:E4:0F"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"relation": ["delegate_permission/common.handle_all_urls"],
|
||||||
|
"target": {
|
||||||
|
"namespace": "android_app",
|
||||||
|
"package_name": "io.element.android.x",
|
||||||
|
"sha256_cert_fingerprints": [
|
||||||
|
"C6:DB:9B:9C:8C:BD:D6:5D:16:E8:EC:8C:8B:91:C8:31:B9:EF:C9:5C:BF:98:AE:41:F6:A9:D8:35:15:1A:7E:16"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
|
@ -194,9 +194,9 @@ export default class Favicon {
|
||||||
}
|
}
|
||||||
|
|
||||||
private setIcon(canvas: HTMLCanvasElement): void {
|
private setIcon(canvas: HTMLCanvasElement): void {
|
||||||
setImmediate(() => {
|
setTimeout(() => {
|
||||||
this.setIconSrc(canvas.toDataURL("image/png"));
|
this.setIconSrc(canvas.toDataURL("image/png"));
|
||||||
});
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private setIconSrc(url: string): void {
|
private setIconSrc(url: string): void {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"error": {
|
"error": {
|
||||||
"app_launch_unexpected_error": "שגיאה לא צפויה במהלך טעינת האפליקציה. ראו קונסול לפרטים נוספים.",
|
"app_launch_unexpected_error": "שגיאה לא צפויה במהלך טעינת האפליקציה. ראו קונסול לפרטים נוספים.",
|
||||||
"cannot_load_config": "לא ניתן לטעון את קובץ ההגדרות: יש לרענן את הדף כדי לנסות שנית.",
|
"cannot_load_config": "לא ניתן לטעון את קובץ ההגדרות: יש לרענן את הדף כדי לנסות שנית.",
|
||||||
|
"invalid_configuration_mixed_server": "Invalid configuration: a default_hs_url can't be specified along with default_server_name or default_server_config",
|
||||||
"invalid_configuration_no_server": "תצורה שגויה: לא צוין שרת ברירת מחדל.",
|
"invalid_configuration_no_server": "תצורה שגויה: לא צוין שרת ברירת מחדל.",
|
||||||
"invalid_json": "האלמנט מכיל הגדרת JSON שגויה, אנא תקנו את הבעיה ואתחלו את הדף.",
|
"invalid_json": "האלמנט מכיל הגדרת JSON שגויה, אנא תקנו את הבעיה ואתחלו את הדף.",
|
||||||
"invalid_json_detail": "ההודעה מהמנתח היא: %(message)s",
|
"invalid_json_detail": "ההודעה מהמנתח היא: %(message)s",
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
"summary": "您的瀏覽器無法執行 %(brand)s",
|
"summary": "您的瀏覽器無法執行 %(brand)s",
|
||||||
"title": "不支援的瀏覽器"
|
"title": "不支援的瀏覽器"
|
||||||
},
|
},
|
||||||
|
"powered_by_matrix": "由Matrix支持",
|
||||||
"powered_by_matrix_with_logo": "由 $matrixLogo 驅動的去中心化、加密的聊天與協作工具",
|
"powered_by_matrix_with_logo": "由 $matrixLogo 驅動的去中心化、加密的聊天與協作工具",
|
||||||
"unknown_device": "未知裝置",
|
"unknown_device": "未知裝置",
|
||||||
"use_brand_on_mobile": "在行動裝置上使用 %(brand)s",
|
"use_brand_on_mobile": "在行動裝置上使用 %(brand)s",
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
Copyright 2024 New Vector Ltd
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { idbLoad } from "matrix-react-sdk/src/utils/StorageAccess";
|
||||||
|
import { ACCESS_TOKEN_IV, tryDecryptToken } from "matrix-react-sdk/src/utils/tokens/tokens";
|
||||||
|
import { buildAndEncodePickleKey } from "matrix-react-sdk/src/utils/tokens/pickling";
|
||||||
|
|
||||||
|
const serverSupportMap: {
|
||||||
|
[serverUrl: string]: {
|
||||||
|
supportsAuthedMedia: boolean;
|
||||||
|
cacheExpiryTimeMs: number;
|
||||||
|
};
|
||||||
|
} = {};
|
||||||
|
|
||||||
|
self.addEventListener("install", (event) => {
|
||||||
|
// We skipWaiting() to update the service worker more frequently, particularly in development environments.
|
||||||
|
// @ts-expect-error - service worker types are not available. See 'fetch' event handler.
|
||||||
|
event.waitUntil(skipWaiting());
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener("activate", (event) => {
|
||||||
|
// We force all clients to be under our control, immediately. This could be old tabs.
|
||||||
|
// @ts-expect-error - service worker types are not available. See 'fetch' event handler.
|
||||||
|
event.waitUntil(clients.claim());
|
||||||
|
});
|
||||||
|
|
||||||
|
// @ts-expect-error - the service worker types conflict with the DOM types available through TypeScript. Many hours
|
||||||
|
// have been spent trying to convince the type system that there's no actual conflict, but it has yet to work. Instead
|
||||||
|
// of trying to make it do the thing, we force-cast to something close enough where we can (and ignore errors otherwise).
|
||||||
|
self.addEventListener("fetch", (event: FetchEvent) => {
|
||||||
|
// This is the authenticated media (MSC3916) check, proxying what was unauthenticated to the authenticated variants.
|
||||||
|
|
||||||
|
if (event.request.method !== "GET") {
|
||||||
|
return; // not important to us
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: ideally we'd keep the request headers etc, but in practice we can't even see those details.
|
||||||
|
// See https://stackoverflow.com/a/59152482
|
||||||
|
let url = event.request.url;
|
||||||
|
|
||||||
|
// We only intercept v3 download and thumbnail requests as presumably everything else is deliberate.
|
||||||
|
// For example, `/_matrix/media/unstable` or `/_matrix/media/v3/preview_url` are something well within
|
||||||
|
// the control of the application, and appear to be choices made at a higher level than us.
|
||||||
|
if (!url.includes("/_matrix/media/v3/download") && !url.includes("/_matrix/media/v3/thumbnail")) {
|
||||||
|
return; // not a URL we care about
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to call respondWith synchronously, otherwise we may never execute properly. This means
|
||||||
|
// later on we need to proxy the request through if it turns out the server doesn't support authentication.
|
||||||
|
event.respondWith(
|
||||||
|
(async (): Promise<Response> => {
|
||||||
|
let accessToken: string | undefined;
|
||||||
|
try {
|
||||||
|
// Figure out which homeserver we're communicating with
|
||||||
|
const csApi = url.substring(0, url.indexOf("/_matrix/media/v3"));
|
||||||
|
|
||||||
|
// Add jitter to reduce request spam, particularly to `/versions` on initial page load
|
||||||
|
await new Promise<void>((resolve) => setTimeout(() => resolve(), Math.random() * 10));
|
||||||
|
|
||||||
|
// Locate our access token, and populate the fetchConfig with the authentication header.
|
||||||
|
// @ts-expect-error - service worker types are not available. See 'fetch' event handler.
|
||||||
|
const client = await self.clients.get(event.clientId);
|
||||||
|
accessToken = await getAccessToken(client);
|
||||||
|
|
||||||
|
// Update or populate the server support map using a (usually) authenticated `/versions` call.
|
||||||
|
await tryUpdateServerSupportMap(csApi, accessToken);
|
||||||
|
|
||||||
|
// If we have server support (and a means of authentication), rewrite the URL to use MSC3916 endpoints.
|
||||||
|
if (serverSupportMap[csApi].supportsAuthedMedia && accessToken) {
|
||||||
|
url = url.replace(/\/media\/v3\/(.*)\//, "/client/v1/media/$1/");
|
||||||
|
} // else by default we make no changes
|
||||||
|
} catch (err) {
|
||||||
|
console.error("SW: Error in request rewrite.", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add authentication and send the request. We add authentication even if MSC3916 endpoints aren't
|
||||||
|
// being used to ensure patches like this work:
|
||||||
|
// https://github.com/matrix-org/synapse/commit/2390b66bf0ec3ff5ffb0c7333f3c9b239eeb92bb
|
||||||
|
return fetch(url, fetchConfigForToken(accessToken));
|
||||||
|
})(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
async function tryUpdateServerSupportMap(clientApiUrl: string, accessToken?: string): Promise<void> {
|
||||||
|
// only update if we don't know about it, or if the data is stale
|
||||||
|
if (serverSupportMap[clientApiUrl]?.cacheExpiryTimeMs > new Date().getTime()) {
|
||||||
|
return; // up to date
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = fetchConfigForToken(accessToken);
|
||||||
|
const versions = await (await fetch(`${clientApiUrl}/_matrix/client/versions`, config)).json();
|
||||||
|
|
||||||
|
serverSupportMap[clientApiUrl] = {
|
||||||
|
supportsAuthedMedia: Boolean(versions?.versions?.includes("v1.11")),
|
||||||
|
cacheExpiryTimeMs: new Date().getTime() + 2 * 60 * 60 * 1000, // 2 hours from now
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ideally we'd use the `Client` interface for `client`, but since it's not available (see 'fetch' listener), we use
|
||||||
|
// unknown for now and force-cast it to something close enough later.
|
||||||
|
async function getAccessToken(client: unknown): Promise<string | undefined> {
|
||||||
|
// Access tokens are encrypted at rest, so while we can grab the "access token", we'll need to do work to get the
|
||||||
|
// real thing.
|
||||||
|
const encryptedAccessToken = await idbLoad("account", "mx_access_token");
|
||||||
|
|
||||||
|
// We need to extract a user ID and device ID from localstorage, which means calling WebPlatform for the
|
||||||
|
// read operation. Service workers can't access localstorage.
|
||||||
|
const { userId, deviceId } = await askClientForUserIdParams(client);
|
||||||
|
|
||||||
|
// ... and this is why we need the user ID and device ID: they're index keys for the pickle key table.
|
||||||
|
const pickleKeyData = await idbLoad("pickleKey", [userId, deviceId]);
|
||||||
|
if (pickleKeyData && (!pickleKeyData.encrypted || !pickleKeyData.iv || !pickleKeyData.cryptoKey)) {
|
||||||
|
console.error("SW: Invalid pickle key loaded - ignoring");
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, try decrypting the thing and return that. This may fail, but that's okay.
|
||||||
|
try {
|
||||||
|
const pickleKey = await buildAndEncodePickleKey(pickleKeyData, userId, deviceId);
|
||||||
|
return tryDecryptToken(pickleKey, encryptedAccessToken, ACCESS_TOKEN_IV);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("SW: Error decrypting access token.", e);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ideally we'd use the `Client` interface for `client`, but since it's not available (see 'fetch' listener), we use
|
||||||
|
// unknown for now and force-cast it to something close enough inside the function.
|
||||||
|
async function askClientForUserIdParams(client: unknown): Promise<{ userId: string; deviceId: string }> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Dev note: this uses postMessage, which is a highly insecure channel. postMessage is typically visible to other
|
||||||
|
// tabs, windows, browser extensions, etc, making it far from ideal for sharing sensitive information. This is
|
||||||
|
// why our service worker calculates/decrypts the access token manually: we don't want the user's access token
|
||||||
|
// to be available to (potentially) malicious listeners. We do require some information for that decryption to
|
||||||
|
// work though, and request that in the least sensitive way possible.
|
||||||
|
//
|
||||||
|
// We could also potentially use some version of TLS to encrypt postMessage, though that feels way more involved
|
||||||
|
// than just reading IndexedDB ourselves.
|
||||||
|
|
||||||
|
// Avoid stalling the tab in case something goes wrong.
|
||||||
|
const timeoutId = setTimeout(() => reject(new Error("timeout in postMessage")), 1000);
|
||||||
|
|
||||||
|
// We don't need particularly good randomness here - we just use this to generate a request ID, so we know
|
||||||
|
// which postMessage reply is for our active request.
|
||||||
|
const responseKey = Math.random().toString(36);
|
||||||
|
|
||||||
|
// Add the listener first, just in case the tab is *really* fast.
|
||||||
|
const listener = (event: MessageEvent): void => {
|
||||||
|
if (event.data?.responseKey !== responseKey) return; // not for us
|
||||||
|
clearTimeout(timeoutId); // do this as soon as possible, avoiding a race between resolve and reject.
|
||||||
|
resolve(event.data); // "unblock" the remainder of the thread, if that were such a thing in JavaScript.
|
||||||
|
self.removeEventListener("message", listener); // cleanup, since we're not going to do anything else.
|
||||||
|
};
|
||||||
|
self.addEventListener("message", listener);
|
||||||
|
|
||||||
|
// Ask the tab for the information we need. This is handled by WebPlatform.
|
||||||
|
(client as Window).postMessage({ responseKey, type: "userinfo" });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchConfigForToken(accessToken?: string): RequestInit | undefined {
|
||||||
|
if (!accessToken) {
|
||||||
|
return undefined; // no headers/config to specify
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${accessToken}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
|
@ -89,9 +89,14 @@ export async function loadApp(fragParams: {}, matrixChatRef: React.Ref<MatrixCha
|
||||||
// XXX: This path matching is a bit brittle, but better to do it early instead of in the app code.
|
// XXX: This path matching is a bit brittle, but better to do it early instead of in the app code.
|
||||||
const isWelcomeOrLanding =
|
const isWelcomeOrLanding =
|
||||||
window.location.hash === "#/welcome" || window.location.hash === "#" || window.location.hash === "";
|
window.location.hash === "#/welcome" || window.location.hash === "#" || window.location.hash === "";
|
||||||
|
const isLoginPage = window.location.hash === "#/login";
|
||||||
|
|
||||||
if (!autoRedirect && ssoRedirects.on_welcome_page && isWelcomeOrLanding) {
|
if (!autoRedirect && ssoRedirects.on_welcome_page && isWelcomeOrLanding) {
|
||||||
autoRedirect = true;
|
autoRedirect = true;
|
||||||
}
|
}
|
||||||
|
if (!autoRedirect && ssoRedirects.on_login_page && isLoginPage) {
|
||||||
|
autoRedirect = true;
|
||||||
|
}
|
||||||
if (!hasPossibleToken && !isReturningFromSso && autoRedirect) {
|
if (!hasPossibleToken && !isReturningFromSso && autoRedirect) {
|
||||||
logger.log("Bypassing app load to redirect to SSO");
|
logger.log("Bypassing app load to redirect to SSO");
|
||||||
const tempCli = createClient({
|
const tempCli = createClient({
|
||||||
|
|
|
@ -25,13 +25,9 @@ import { extractErrorMessageFromError } from "matrix-react-sdk/src/components/vi
|
||||||
import { parseQsFromFragment } from "./url_utils";
|
import { parseQsFromFragment } from "./url_utils";
|
||||||
import "./modernizr";
|
import "./modernizr";
|
||||||
|
|
||||||
// Make setImmediate available in bundle
|
|
||||||
import "setimmediate";
|
|
||||||
|
|
||||||
// Require common CSS here; this will make webpack process it into bundle.css.
|
// Require common CSS here; this will make webpack process it into bundle.css.
|
||||||
// Our own CSS (which is themed) is imported via separate webpack entry points
|
// Our own CSS (which is themed) is imported via separate webpack entry points
|
||||||
// in webpack.config.js
|
// in webpack.config.js
|
||||||
require("gfm.css/gfm.css");
|
|
||||||
require("katex/dist/katex.css");
|
require("katex/dist/katex.css");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,7 +176,7 @@ async function start(): Promise<void> {
|
||||||
// error handling begins here
|
// error handling begins here
|
||||||
// ##########################
|
// ##########################
|
||||||
if (!acceptBrowser) {
|
if (!acceptBrowser) {
|
||||||
await new Promise<void>((resolve) => {
|
await new Promise<void>((resolve, reject) => {
|
||||||
logger.error("Browser is missing required features.");
|
logger.error("Browser is missing required features.");
|
||||||
// take to a different landing page to AWOOOOOGA at the user
|
// take to a different landing page to AWOOOOOGA at the user
|
||||||
showIncompatibleBrowser(() => {
|
showIncompatibleBrowser(() => {
|
||||||
|
@ -189,7 +185,7 @@ async function start(): Promise<void> {
|
||||||
}
|
}
|
||||||
logger.log("User accepts the compatibility risks.");
|
logger.log("User accepts the compatibility risks.");
|
||||||
resolve();
|
resolve();
|
||||||
});
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -138,7 +138,7 @@ export async function loadLanguage(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadTheme(): Promise<void> {
|
export async function loadTheme(): Promise<void> {
|
||||||
setTheme();
|
return setTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadApp(fragParams: {}): Promise<void> {
|
export async function loadApp(fragParams: {}): Promise<void> {
|
||||||
|
|
|
@ -177,17 +177,17 @@ const setupCompleted = (async (): Promise<string | void> => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await widgetApi!.transport.reply(ev.detail, response);
|
widgetApi!.transport.reply(ev.detail, response);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
handleAction(ElementWidgetActions.JoinCall, async ({ audioInput, videoInput }) => {
|
handleAction(ElementWidgetActions.JoinCall, async ({ audioInput, videoInput }) => {
|
||||||
joinConference(audioInput as string | null, videoInput as string | null);
|
void joinConference(audioInput as string | null, videoInput as string | null);
|
||||||
});
|
});
|
||||||
handleAction(ElementWidgetActions.HangupCall, async ({ force }) => {
|
handleAction(ElementWidgetActions.HangupCall, async ({ force }) => {
|
||||||
if (force === true) {
|
if (force === true) {
|
||||||
meetApi?.dispose();
|
meetApi?.dispose();
|
||||||
notifyHangup();
|
void notifyHangup();
|
||||||
meetApi = undefined;
|
meetApi = undefined;
|
||||||
closeConference();
|
closeConference();
|
||||||
} else {
|
} else {
|
||||||
|
@ -297,7 +297,7 @@ function toggleConferenceVisibility(inConference: boolean): void {
|
||||||
|
|
||||||
function skipToJitsiSplashScreen(): void {
|
function skipToJitsiSplashScreen(): void {
|
||||||
// really just a function alias for self-documenting code
|
// really just a function alias for self-documenting code
|
||||||
joinConference();
|
void joinConference();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -500,8 +500,8 @@ const onVideoConferenceJoined = (): void => {
|
||||||
if (widgetApi) {
|
if (widgetApi) {
|
||||||
// ignored promise because we don't care if it works
|
// ignored promise because we don't care if it works
|
||||||
// noinspection JSIgnoredPromiseFromCall
|
// noinspection JSIgnoredPromiseFromCall
|
||||||
widgetApi.setAlwaysOnScreen(true);
|
void widgetApi.setAlwaysOnScreen(true);
|
||||||
widgetApi.transport.send(ElementWidgetActions.JoinCall, {});
|
void widgetApi.transport.send(ElementWidgetActions.JoinCall, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Video rooms should start in tile mode
|
// Video rooms should start in tile mode
|
||||||
|
@ -509,7 +509,7 @@ const onVideoConferenceJoined = (): void => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVideoConferenceLeft = (): void => {
|
const onVideoConferenceLeft = (): void => {
|
||||||
notifyHangup();
|
void notifyHangup();
|
||||||
meetApi = undefined;
|
meetApi = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ const onErrorOccurred = ({ error }: Parameters<ExternalAPIEventCallbacks["errorO
|
||||||
if (error.isFatal) {
|
if (error.isFatal) {
|
||||||
// We got disconnected. Since Jitsi Meet might send us back to the
|
// 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.
|
// prejoin screen, we're forced to act as if we hung up entirely.
|
||||||
notifyHangup(error.message);
|
void notifyHangup(error.message);
|
||||||
meetApi = undefined;
|
meetApi = undefined;
|
||||||
closeConference();
|
closeConference();
|
||||||
}
|
}
|
||||||
|
@ -525,7 +525,7 @@ const onErrorOccurred = ({ error }: Parameters<ExternalAPIEventCallbacks["errorO
|
||||||
|
|
||||||
const onAudioMuteStatusChanged = ({ muted }: AudioMuteStatusChangedEvent): void => {
|
const onAudioMuteStatusChanged = ({ muted }: AudioMuteStatusChangedEvent): void => {
|
||||||
const action = muted ? ElementWidgetActions.MuteAudio : ElementWidgetActions.UnmuteAudio;
|
const action = muted ? ElementWidgetActions.MuteAudio : ElementWidgetActions.UnmuteAudio;
|
||||||
widgetApi?.transport.send(action, {});
|
void widgetApi?.transport.send(action, {});
|
||||||
};
|
};
|
||||||
|
|
||||||
const onVideoMuteStatusChanged = ({ muted }: VideoMuteStatusChangedEvent): void => {
|
const onVideoMuteStatusChanged = ({ muted }: VideoMuteStatusChangedEvent): void => {
|
||||||
|
@ -535,15 +535,15 @@ const onVideoMuteStatusChanged = ({ muted }: VideoMuteStatusChangedEvent): void
|
||||||
// otherwise the React SDK will mistakenly think the user turned off
|
// otherwise the React SDK will mistakenly think the user turned off
|
||||||
// their video by hand
|
// their video by hand
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (meetApi) widgetApi?.transport.send(ElementWidgetActions.MuteVideo, {});
|
if (meetApi) void widgetApi?.transport.send(ElementWidgetActions.MuteVideo, {});
|
||||||
}, 200);
|
}, 200);
|
||||||
} else {
|
} else {
|
||||||
widgetApi?.transport.send(ElementWidgetActions.UnmuteVideo, {});
|
void widgetApi?.transport.send(ElementWidgetActions.UnmuteVideo, {});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateParticipants = (): void => {
|
const updateParticipants = (): void => {
|
||||||
widgetApi?.transport.send(ElementWidgetActions.CallParticipants, {
|
void widgetApi?.transport.send(ElementWidgetActions.CallParticipants, {
|
||||||
participants: meetApi?.getParticipantsInfo(),
|
participants: meetApi?.getParticipantsInfo(),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,4 +120,4 @@ async function initPage(): Promise<void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
initPage();
|
void initPage();
|
||||||
|
|
|
@ -167,15 +167,14 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
window.electron.on("openDesktopCapturerSourcePicker", () => {
|
window.electron.on("openDesktopCapturerSourcePicker", async () => {
|
||||||
const { finished } = Modal.createDialog(DesktopCapturerSourcePicker);
|
const { finished } = Modal.createDialog(DesktopCapturerSourcePicker);
|
||||||
finished.then(([source]) => {
|
const [source] = await finished;
|
||||||
if (!source) return;
|
// getDisplayMedia promise does not return if no dummy is passed here as source
|
||||||
this.ipc.call("callDisplayMediaCallback", source);
|
await this.ipc.call("callDisplayMediaCallback", source ?? { id: "", name: "", thumbnailURL: "" });
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.ipc.call("startSSOFlow", this.ssoID);
|
void this.ipc.call("startSSOFlow", this.ssoID);
|
||||||
|
|
||||||
BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
||||||
}
|
}
|
||||||
|
@ -195,7 +194,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
),
|
),
|
||||||
initial: getInitialLetter(r.name),
|
initial: getInitialLetter(r.name),
|
||||||
}));
|
}));
|
||||||
this.ipc.call("breadcrumbs", rooms);
|
void this.ipc.call("breadcrumbs", rooms);
|
||||||
};
|
};
|
||||||
|
|
||||||
private onUpdateDownloaded = async (ev: Event, { releaseNotes, releaseName }: SquirrelUpdate): Promise<void> => {
|
private onUpdateDownloaded = async (ev: Event, { releaseNotes, releaseName }: SquirrelUpdate): Promise<void> => {
|
||||||
|
@ -261,7 +260,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
const handler = notification.onclick as Function;
|
const handler = notification.onclick as Function;
|
||||||
notification.onclick = (): void => {
|
notification.onclick = (): void => {
|
||||||
handler?.();
|
handler?.();
|
||||||
this.ipc.call("focusWindow");
|
void this.ipc.call("focusWindow");
|
||||||
};
|
};
|
||||||
|
|
||||||
return notification;
|
return notification;
|
||||||
|
@ -399,7 +398,7 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
}
|
}
|
||||||
|
|
||||||
public navigateForwardBack(back: boolean): void {
|
public navigateForwardBack(back: boolean): void {
|
||||||
this.ipc.call(back ? "navigateBack" : "navigateForward");
|
void this.ipc.call(back ? "navigateBack" : "navigateForward");
|
||||||
}
|
}
|
||||||
|
|
||||||
public overrideBrowserShortcuts(): boolean {
|
public overrideBrowserShortcuts(): boolean {
|
||||||
|
@ -444,20 +443,29 @@ export default class ElectronPlatform extends VectorBasePlatform {
|
||||||
return (SdkConfig.get() as unknown as Record<string, string>)["web_base_url"] ?? "https://app.element.io";
|
return (SdkConfig.get() as unknown as Record<string, string>)["web_base_url"] ?? "https://app.element.io";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get defaultOidcClientUri(): string {
|
||||||
|
// Default to element.io as our scheme `io.element.desktop` is within its scope on default MAS policies
|
||||||
|
return "https://element.io";
|
||||||
|
}
|
||||||
|
|
||||||
public async getOidcClientMetadata(): Promise<OidcRegistrationClientMetadata> {
|
public async getOidcClientMetadata(): Promise<OidcRegistrationClientMetadata> {
|
||||||
const baseMetadata = await super.getOidcClientMetadata();
|
const baseMetadata = await super.getOidcClientMetadata();
|
||||||
const redirectUri = this.getSSOCallbackUrl();
|
|
||||||
redirectUri.searchParams.delete(SSO_ID_KEY); // it will be shuttled via the state param instead
|
|
||||||
return {
|
return {
|
||||||
...baseMetadata,
|
...baseMetadata,
|
||||||
applicationType: "native",
|
applicationType: "native",
|
||||||
redirectUris: [redirectUri.href],
|
|
||||||
// XXX: This should be overridable in config
|
|
||||||
clientUri: "https://element.io",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getOidcClientState(): string {
|
public getOidcClientState(): string {
|
||||||
return `:${SSO_ID_KEY}:${this.ssoID}`;
|
return `:${SSO_ID_KEY}:${this.ssoID}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The URL to return to after a successful OIDC authentication
|
||||||
|
*/
|
||||||
|
public getOidcCallbackUrl(): URL {
|
||||||
|
const url = super.getOidcCallbackUrl();
|
||||||
|
url.protocol = "io.element.desktop";
|
||||||
|
return url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2016 Aviral Dasgupta
|
Copyright 2016 Aviral Dasgupta
|
||||||
Copyright 2016 OpenMarket Ltd
|
Copyright 2016 OpenMarket Ltd
|
||||||
Copyright 2017-2020 New Vector Ltd
|
Copyright 2017-2020, 2024 New Vector Ltd
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -44,9 +44,41 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
|
|
||||||
public constructor() {
|
public constructor() {
|
||||||
super();
|
super();
|
||||||
// Register service worker if available on this platform
|
|
||||||
if ("serviceWorker" in navigator) {
|
// Register the service worker in the background
|
||||||
navigator.serviceWorker.register("sw.js");
|
this.tryRegisterServiceWorker().catch((e) => console.error("Error registering/updating service worker:", e));
|
||||||
|
}
|
||||||
|
|
||||||
|
private async tryRegisterServiceWorker(): Promise<void> {
|
||||||
|
if (!("serviceWorker" in navigator)) {
|
||||||
|
return; // not available on this platform - don't try to register the service worker
|
||||||
|
}
|
||||||
|
|
||||||
|
// sw.js is exported by webpack, sourced from `/src/serviceworker/index.ts`
|
||||||
|
const registration = await navigator.serviceWorker.register("sw.js");
|
||||||
|
if (!registration) {
|
||||||
|
// Registration didn't work for some reason - assume failed and ignore.
|
||||||
|
// This typically happens in Jest.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await registration.update();
|
||||||
|
navigator.serviceWorker.addEventListener("message", this.onServiceWorkerPostMessage.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private onServiceWorkerPostMessage(event: MessageEvent): void {
|
||||||
|
try {
|
||||||
|
if (event.data?.["type"] === "userinfo" && event.data?.["responseKey"]) {
|
||||||
|
const userId = localStorage.getItem("mx_user_id");
|
||||||
|
const deviceId = localStorage.getItem("mx_device_id");
|
||||||
|
event.source!.postMessage({
|
||||||
|
responseKey: event.data["responseKey"],
|
||||||
|
userId,
|
||||||
|
deviceId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error responding to service worker: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,10 +113,10 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
// annoyingly, the latest spec says this returns a
|
// annoyingly, the latest spec says this returns a
|
||||||
// promise, but this is only supported in Chrome 46
|
// promise, but this is only supported in Chrome 46
|
||||||
// and Firefox 47, so adapt the callback API.
|
// and Firefox 47, so adapt the callback API.
|
||||||
return new Promise(function (resolve) {
|
return new Promise(function (resolve, reject) {
|
||||||
window.Notification.requestPermission((result) => {
|
window.Notification.requestPermission((result) => {
|
||||||
resolve(result);
|
resolve(result);
|
||||||
});
|
}).catch(reject);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,7 +148,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
// Ideally, loading an old copy would be impossible with the
|
// Ideally, loading an old copy would be impossible with the
|
||||||
// cache-control: nocache HTTP header set, but Firefox doesn't always obey it :/
|
// cache-control: nocache HTTP header set, but Firefox doesn't always obey it :/
|
||||||
console.log("startUpdater, current version is " + getNormalizedAppVersion(WebPlatform.VERSION));
|
console.log("startUpdater, current version is " + getNormalizedAppVersion(WebPlatform.VERSION));
|
||||||
this.pollForUpdate((version: string, newVersion: string) => {
|
void this.pollForUpdate((version: string, newVersion: string) => {
|
||||||
const query = parseQs(location);
|
const query = parseQs(location);
|
||||||
if (query.updated) {
|
if (query.updated) {
|
||||||
console.log("Update reloaded but still on an old version, stopping");
|
console.log("Update reloaded but still on an old version, stopping");
|
||||||
|
@ -175,7 +207,7 @@ export default class WebPlatform extends VectorBasePlatform {
|
||||||
|
|
||||||
public startUpdateCheck(): void {
|
public startUpdateCheck(): void {
|
||||||
super.startUpdateCheck();
|
super.startUpdateCheck();
|
||||||
this.pollForUpdate(showUpdateToast, hideUpdateToast).then((updateState) => {
|
void this.pollForUpdate(showUpdateToast, hideUpdateToast).then((updateState) => {
|
||||||
dis.dispatch<CheckUpdatesPayload>({
|
dis.dispatch<CheckUpdatesPayload>({
|
||||||
action: Action.CheckUpdates,
|
action: Action.CheckUpdates,
|
||||||
...updateState,
|
...updateState,
|
||||||
|
|
|
@ -35,7 +35,7 @@ export function initRageshake(): Promise<void> {
|
||||||
// we manually check persistence for rageshakes ourselves
|
// we manually check persistence for rageshakes ourselves
|
||||||
const prom = rageshake.init(/*setUpPersistence=*/ false);
|
const prom = rageshake.init(/*setUpPersistence=*/ false);
|
||||||
prom.then(
|
prom.then(
|
||||||
() => {
|
async () => {
|
||||||
logger.log("Initialised rageshake.");
|
logger.log("Initialised rageshake.");
|
||||||
logger.log(
|
logger.log(
|
||||||
"To fix line numbers in Chrome: " +
|
"To fix line numbers in Chrome: " +
|
||||||
|
@ -48,7 +48,7 @@ export function initRageshake(): Promise<void> {
|
||||||
rageshake.flush();
|
rageshake.flush();
|
||||||
});
|
});
|
||||||
|
|
||||||
rageshake.cleanup();
|
await rageshake.cleanup();
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
logger.error("Failed to initialise rageshake: " + err);
|
logger.error("Failed to initialise rageshake: " + err);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
"./node_modules/matrix-react-sdk/src/@types/opus-recorder.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/png-chunks-extract.d.ts",
|
||||||
"./node_modules/matrix-react-sdk/src/@types/sanitize-html.d.ts",
|
"./node_modules/matrix-react-sdk/src/@types/sanitize-html.d.ts",
|
||||||
|
"./node_modules/matrix-react-sdk/src/@types/matrix-js-sdk.d.ts",
|
||||||
"./src/**/*.ts",
|
"./src/**/*.ts",
|
||||||
"./src/**/*.tsx",
|
"./src/**/*.tsx",
|
||||||
"./test/**/*.ts",
|
"./test/**/*.ts",
|
||||||
|
|
|
@ -153,6 +153,10 @@ module.exports = (env, argv) => {
|
||||||
mobileguide: "./src/vector/mobile_guide/index.ts",
|
mobileguide: "./src/vector/mobile_guide/index.ts",
|
||||||
jitsi: "./src/vector/jitsi/index.ts",
|
jitsi: "./src/vector/jitsi/index.ts",
|
||||||
usercontent: "./node_modules/matrix-react-sdk/src/usercontent/index.ts",
|
usercontent: "./node_modules/matrix-react-sdk/src/usercontent/index.ts",
|
||||||
|
serviceworker: {
|
||||||
|
import: "./src/serviceworker/index.ts",
|
||||||
|
filename: "sw.js", // update WebPlatform if this changes
|
||||||
|
},
|
||||||
...(useHMR ? {} : cssThemes),
|
...(useHMR ? {} : cssThemes),
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -543,10 +547,20 @@ module.exports = (env, argv) => {
|
||||||
// props set on the svg will override defaults
|
// props set on the svg will override defaults
|
||||||
expandProps: "end",
|
expandProps: "end",
|
||||||
svgoConfig: {
|
svgoConfig: {
|
||||||
plugins: {
|
plugins: [
|
||||||
|
{
|
||||||
|
name: "preset-default",
|
||||||
|
params: {
|
||||||
|
overrides: {
|
||||||
|
removeViewBox: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
// generates a viewbox if missing
|
// generates a viewbox if missing
|
||||||
removeDimensions: true,
|
{ name: "removeDimensions" },
|
||||||
},
|
// https://github.com/facebook/docusaurus/issues/8297
|
||||||
|
{ name: "prefixIds" },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
/**
|
/**
|
||||||
* Forwards the React ref to the root SVG element
|
* Forwards the React ref to the root SVG element
|
||||||
|
@ -643,8 +657,8 @@ module.exports = (env, argv) => {
|
||||||
|
|
||||||
// This exports our CSS using the splitChunks and loaders above.
|
// This exports our CSS using the splitChunks and loaders above.
|
||||||
new MiniCssExtractPlugin({
|
new MiniCssExtractPlugin({
|
||||||
filename: useHMR ? "bundles/[name].css" : "bundles/[hash]/[name].css",
|
filename: useHMR ? "bundles/[name].css" : "bundles/[fullhash]/[name].css",
|
||||||
chunkFilename: useHMR ? "bundles/[name].css" : "bundles/[hash]/[name].css",
|
chunkFilename: useHMR ? "bundles/[name].css" : "bundles/[fullhash]/[name].css",
|
||||||
ignoreOrder: false, // Enable to remove warnings about conflicting order
|
ignoreOrder: false, // Enable to remove warnings about conflicting order
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -656,7 +670,7 @@ module.exports = (env, argv) => {
|
||||||
// HtmlWebpackPlugin will screw up our formatting like the names
|
// HtmlWebpackPlugin will screw up our formatting like the names
|
||||||
// of the themes and which chunks we actually care about.
|
// of the themes and which chunks we actually care about.
|
||||||
inject: false,
|
inject: false,
|
||||||
excludeChunks: ["mobileguide", "usercontent", "jitsi"],
|
excludeChunks: ["mobileguide", "usercontent", "jitsi", "serviceworker"],
|
||||||
minify: false,
|
minify: false,
|
||||||
templateParameters: {
|
templateParameters: {
|
||||||
og_image_url: ogImageUrl,
|
og_image_url: ogImageUrl,
|
||||||
|
@ -726,10 +740,10 @@ module.exports = (env, argv) => {
|
||||||
new CopyWebpackPlugin({
|
new CopyWebpackPlugin({
|
||||||
patterns: [
|
patterns: [
|
||||||
"res/apple-app-site-association",
|
"res/apple-app-site-association",
|
||||||
|
{ from: ".well-known/**", context: path.resolve(__dirname, "res") },
|
||||||
"res/jitsi_external_api.min.js",
|
"res/jitsi_external_api.min.js",
|
||||||
"res/jitsi_external_api.min.js.LICENSE.txt",
|
"res/jitsi_external_api.min.js.LICENSE.txt",
|
||||||
"res/manifest.json",
|
"res/manifest.json",
|
||||||
"res/sw.js",
|
|
||||||
"res/welcome.html",
|
"res/welcome.html",
|
||||||
{ from: "welcome/**", context: path.resolve(__dirname, "res") },
|
{ from: "welcome/**", context: path.resolve(__dirname, "res") },
|
||||||
{ from: "themes/**", context: path.resolve(__dirname, "res") },
|
{ from: "themes/**", context: path.resolve(__dirname, "res") },
|
||||||
|
@ -760,9 +774,9 @@ module.exports = (env, argv) => {
|
||||||
// directory and symlink it into place - this allows users who loaded
|
// directory and symlink it into place - this allows users who loaded
|
||||||
// an older version of the application to continue to access webpack
|
// an older version of the application to continue to access webpack
|
||||||
// chunks even after the app is redeployed.
|
// chunks even after the app is redeployed.
|
||||||
filename: "bundles/[hash]/[name].js",
|
filename: "bundles/[fullhash]/[name].js",
|
||||||
chunkFilename: "bundles/[hash]/[name].js",
|
chunkFilename: "bundles/[fullhash]/[name].js",
|
||||||
webassemblyModuleFilename: "bundles/[hash]/[modulehash].wasm",
|
webassemblyModuleFilename: "bundles/[fullhash]/[modulehash].wasm",
|
||||||
},
|
},
|
||||||
|
|
||||||
// configuration for the webpack-dev-server
|
// configuration for the webpack-dev-server
|
||||||
|
|
Loading…
Reference in New Issue