Compare commits

..

1 commit

Author SHA1 Message Date
David Baker
77a8cafa0f Add timeout to pending reviews automation
Although it might not actually help with the job that got stuck for 17h
because that got stuck before it got started, but this is probably
not a bad idea in general.
2024-04-05 10:02:40 +01:00
120 changed files with 4674 additions and 6313 deletions

View file

@ -88,7 +88,6 @@ module.exports = {
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-member-accessibility": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-floating-promises": "off",
},
},
],

3
.github/cfp_headers vendored
View file

@ -11,6 +11,3 @@
/apple-app-site-association
Content-Type: application/json
/.well-known/assetlinks.json
Content-Type: application/json

3
.github/labels.yml vendored
View file

@ -261,6 +261,3 @@
color: "ededed"
- name: "Z-t3chguy"
color: "ededed"
- name: "Z-Flaky-Test-Disabled"
description: "The flaking test has been disabled"
color: "ededed"

View file

@ -37,7 +37,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
# Workaround for yarn install timeouts, especially on Windows
- run: yarn config set network-timeout 300000

View file

@ -26,7 +26,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
- name: Install Dependencies
run: "./scripts/layered.sh"
@ -93,13 +92,13 @@ jobs:
find bundles -type d -mindepth 1 -maxdepth 1 -exec sed -i "\:{}:d" _redirects \;
- name: Wait for other steps to succeed
uses: t3chguy/wait-on-check-action@18541021811b56544d90e0f073401c2b99e249d6 # fork
uses: t3chguy/wait-on-check-action@05861d3a448898eb33dfce34153bd1ecb9422fb9 # fork
with:
ref: ${{ github.sha }}
running-workflow-name: "Build & Deploy develop.element.io"
repo-token: ${{ secrets.GITHUB_TOKEN }}
wait-interval: 10
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare|GitHub Pages).)*$
check-regexp: ^((?!SonarCloud|SonarQube|issue|board|label|Release|prepare).)*$
# 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.

View file

@ -7,9 +7,6 @@ on:
# This job can take a while, and we have usage limits, so just publish develop only twice a day
- cron: "0 7/12 * * *"
concurrency: ${{ github.workflow }}-${{ github.ref_name }}
permissions:
id-token: write # needed for signing the images with GitHub OIDC Token
jobs:
buildx:
name: Docker Buildx
@ -29,23 +26,20 @@ jobs:
with:
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
if: matrix.prepare
run: ${{ matrix.prepare }}
- name: Set up QEMU
uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@aa33708b10e362ff993539393ff100fa93ed6a27 # v3
uses: docker/setup-buildx-action@2b51285047da1547ffb1b2203d8be4c0af6b1f20 # v3
with:
install: true
- name: Login to Docker Hub
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3
uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@ -64,8 +58,7 @@ jobs:
${{ matrix.flavor }}
- name: Build and push
id: build-and-push
uses: docker/build-push-action@5176d81f87c23d6fc96624dfdbcd9f3830bbe445 # v6
uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5
with:
context: .
push: true
@ -73,17 +66,6 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
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
if: matrix.variant == 'vanilla'
uses: peter-evans/dockerhub-description@e98e4d1628a5f3be2be7c231e50981aee98723ae # v4

View file

@ -46,7 +46,6 @@ jobs:
with:
cache: "yarn"
cache-dependency-path: element-web/yarn.lock
node-version: "lts/*"
- name: Generate automations docs
working-directory: element-web
@ -56,7 +55,7 @@ jobs:
echo "- [Automations](automations.md)" >> docs/SUMMARY.md
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v2
uses: peaceiris/actions-mdbook@v1
with:
mdbook-version: "0.4.10"

View file

@ -0,0 +1,17 @@
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

View file

@ -3,11 +3,10 @@
name: matrix-react-sdk End to End Tests
on:
merge_group:
types: [checks_requested]
pull_request: {}
push:
branches: [develop, master]
workflow_run:
workflows: ["Build downstream artifacts"]
types:
- completed
concurrency:
group: ${{ github.workflow }}-${{ github.event.workflow_run.head_branch || github.run_id }}
@ -16,14 +15,44 @@ concurrency:
jobs:
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
permissions:
actions: read
issues: read
statuses: write
pull-requests: read
deployments: write
with:
element-web-sha: ${{ github.sha }}
react-sdk-repository: matrix-org/matrix-react-sdk
# 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.
skip: ${{ github.event_name != 'merge_group' }}
secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
# 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@faaa4d96fecf273bd762985e0e7f9f933c774918 # 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 }}"

View file

@ -9,6 +9,7 @@ jobs:
name: Pending reviews bot
runs-on: ubuntu-latest
environment: Matrix
timeout-minutes: 1
env:
URL: "https://github.com/pulls?q=is%3Apr+is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+review-requested%3A%40me+sort%3Aupdated-desc+"
RELEASE_BLOCKERS_URL: "https://github.com/pulls?q=is%3Aopen+repo%3Amatrix-org%2Fmatrix-js-sdk+repo%3Amatrix-org%2Fmatrix-react-sdk+repo%3Aelement-hq%2Felement-web+repo%3Aelement-hq%2Felement-desktop+sort%3Aupdated-desc+label%3AX-Release-Blocker+"

View file

@ -20,6 +20,7 @@ jobs:
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
with:
final: ${{ inputs.mode == 'final' }}
include-changes: matrix-react-sdk
gpg-fingerprint: ${{ vars.GPG_FINGERPRINT }}
asset-path: dist/*.tar.gz
expected-asset-count: 3
@ -30,13 +31,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Notify element-desktop repo that element-web release has completed to re-trigger release-drafter
uses: benc-uk/workflow-dispatch@25b02cc069be46d637e8fe2f1e8484008e9e9609 # v1
uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3
with:
workflow: release-drafter.yml
repo: element-hq/element-desktop
ref: staging
# Required when using the `repo` option. Either a PAT or a token generated from the GitHub app or CLI
token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
repository: element-hq/element-desktop
event-type: upstream-release-notify
check:
name: Post release checks

View file

@ -21,7 +21,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
- name: Install Dependencies
run: "./scripts/layered.sh"
@ -44,7 +43,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
# Does not need branch matching as only analyses this layer
- name: Install Deps
@ -62,7 +60,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
# Needs branch matching as it inherits .stylelintrc.js from matrix-react-sdk
- name: Install Dependencies
@ -80,7 +77,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
# Does not need branch matching as only analyses this layer
- name: Install Deps
@ -98,7 +94,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
- name: Install Deps
run: "scripts/layered.sh"

View file

@ -23,7 +23,6 @@ jobs:
uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
- name: Install Dependencies
run: "./scripts/layered.sh"

View file

@ -56,48 +56,13 @@ jobs:
move_needs_info_issues:
name: X-Needs-Info issues to Need info column on triage board
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
steps:
- id: add_to_project
uses: actions/add-to-project@v1.0.2
- uses: konradpabjan/move-labeled-or-milestoned-issue@190352295fe309fcb113b49193bc81d9aaa9cb01
with:
project-url: ${{ env.PROJECT_URL }}
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
- id: set_fields
uses: titoportas/update-project-fields@421a54430b3cdc9eefd8f14f9ce0142ab7678751 # v0.1.0
with:
project-url: ${{ env.PROJECT_URL }}
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
item-id: ${{ steps.add_to_project.outputs.itemId }} # Use the item-id output of the previous step
field-keys: Status
field-values: "Needs info"
env:
PROJECT_URL: https://github.com/orgs/element-hq/projects/120
move_flakey_test_issues:
name: Z-Flaky-Test issues to Sized for maintainer column on triage board
runs-on: ubuntu-latest
if: >
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
steps:
- id: add_to_project
uses: actions/add-to-project@v1.0.2
with:
project-url: ${{ env.PROJECT_URL }}
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
- id: set_fields
uses: titoportas/update-project-fields@421a54430b3cdc9eefd8f14f9ce0142ab7678751 # v0.1.0
with:
project-url: ${{ env.PROJECT_URL }}
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
item-id: ${{ steps.add_to_project.outputs.itemId }} # Use the item-id output of the previous step
field-keys: Status
field-values: "Sized for maintainer"
env:
PROJECT_URL: https://github.com/orgs/element-hq/projects/120
action-token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
project-url: "https://github.com/element-hq/element-web/projects/120"
column-name: "Needs info"
label-name: "X-Needs-Info"
add_priority_design_issues_to_project:
name: P1 X-Needs-Design to Design project board
@ -183,7 +148,7 @@ jobs:
contains(github.event.issue.labels.*.name, 'A-Element-R')
steps:
- id: add_to_project
uses: actions/add-to-project@v1.0.2
uses: actions/add-to-project@v1.0.0
with:
project-url: ${{ env.PROJECT_URL }}
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}

View file

@ -1,17 +0,0 @@
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"

View file

@ -13,7 +13,6 @@ jobs:
- uses: actions/setup-node@v4
with:
cache: "yarn"
node-version: "lts/*"
- name: Install Deps
run: "yarn install --frozen-lockfile"
@ -22,7 +21,7 @@ jobs:
run: "yarn update:jitsi"
- name: Create Pull Request
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6
uses: peter-evans/create-pull-request@70a41aba780001da0a30141984ae2a0c95d8704e # v6
with:
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
branch: actions/jitsi-update

View file

@ -1,4 +0,0 @@
#!/usr/bin/env sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged --concurrent false

View file

@ -1,7 +0,0 @@
{
"*": "prettier --write",
"src/**/*.(ts|tsx)": ["eslint --fix"],
"scripts/**/*.(ts|tsx)": ["eslint --fix"],
"module_system/**/*.(ts|tsx)": ["eslint --fix --config .eslintrc-module_system.js module_system"],
"*.pcss": ["stylelint --fix"]
}

View file

@ -1,5 +1,5 @@
{
"minify": false,
"minify": true,
"enableClasses": false,
"feature-detects": [
"test/css/animations",
@ -31,7 +31,6 @@
"test/json",
"test/network/fetch",
"test/storage/localstorage",
"test/window/resizeobserver",
"test/audio/webaudio"
"test/window/resizeobserver"
]
}

View file

@ -1,152 +1,3 @@
Changes in [1.11.69](https://github.com/element-hq/element-web/releases/tag/v1.11.69) (2024-06-18)
==================================================================================================
## ✨ Features
* Change avatar setting component to use a menu ([#12585](https://github.com/matrix-org/matrix-react-sdk/pull/12585)). Contributed by @dbkr.
* New user profile UI in User Settings ([#12548](https://github.com/matrix-org/matrix-react-sdk/pull/12548)). Contributed by @dbkr.
* MSC4108 support OIDC QR code login ([#12370](https://github.com/matrix-org/matrix-react-sdk/pull/12370)). Contributed by @t3chguy.
## 🐛 Bug Fixes
* Fix image upload preview size ([#12612](https://github.com/matrix-org/matrix-react-sdk/pull/12612)). Contributed by @RiotRobot.
* Fix screen sharing in recent Chrome (https://github.com/matrix-org/matrix-js-sdk/pull/4243).
* Fix roving tab index crash `compareDocumentPosition` ([#12594](https://github.com/matrix-org/matrix-react-sdk/pull/12594)). Contributed by @t3chguy.
* Keep dialog glass border on narrow screens ([#12591](https://github.com/matrix-org/matrix-react-sdk/pull/12591)). Contributed by @dbkr.
* Add missing a11y label to dismiss onboarding button in room list ([#12587](https://github.com/matrix-org/matrix-react-sdk/pull/12587)). Contributed by @t3chguy.
* Add hover / active state on avatar setting upload button ([#12590](https://github.com/matrix-org/matrix-react-sdk/pull/12590)). Contributed by @dbkr.
* Fix EditInPlace button styles ([#12589](https://github.com/matrix-org/matrix-react-sdk/pull/12589)). Contributed by @dbkr.
* Fix incorrect assumptions about required fields in /search response ([#12575](https://github.com/matrix-org/matrix-react-sdk/pull/12575)). Contributed by @t3chguy.
* Fix display of no avatar in avatar setting controls ([#12558](https://github.com/matrix-org/matrix-react-sdk/pull/12558)). Contributed by @dbkr.
* Element-R: pass pickleKey in as raw key for indexeddb encryption ([#12543](https://github.com/matrix-org/matrix-react-sdk/pull/12543)). Contributed by @richvdh.
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.

View file

@ -17,30 +17,20 @@ React SDK](https://github.com/matrix-org/matrix-react-sdk).
Element has several tiers of support for different environments:
- Supported
- Definition:
- Issues **actively triaged**, regressions **block** the release
- Definition: Issues **actively triaged**, regressions **block** the release
- Last 2 major versions of Chrome, Firefox, and Edge on desktop OSes
- Last 2 versions of Safari
- Latest release of official Element Desktop app on desktop OSes
- Desktop OSes means macOS, Windows, and Linux versions for desktop devices
that are actively supported by the OS vendor and receive security updates
- Best effort
- Definition:
- Issues **accepted**, regressions **do not block** the release
- The wider Element Products(including Element Call and the Enterprise Server Suite) do still not officially support these browsers.
- The element web project and its contributors should keep the client functioning and gracefully degrade where other sibling features (E.g. Element Call) may not function.
- Last major release of Firefox ESR and Chrome/Edge Extended Stable
- Community Supported
- Definition:
- Issues **accepted**, regressions **do not block** the release
- Community contributions are welcome to support these issues
- Experimental
- Definition: Issues **accepted**, regressions **do not block** the release
- Element as an installed PWA via current stable version of Chrome
- Mobile web for current stable version of Chrome, Firefox, and Safari on Android, iOS, and iPadOS
- Not supported
- Definition: Issues only affecting unsupported environments are **closed**
- Everything else
The period of support for these tiers should last until the releases specified above, plus 1 app release cycle(2 weeks). In the case of Firefox ESR this is extended further to allow it land in Debian Stable.
For accessing Element on an Android or iOS device, we currently recommend the
native apps [element-android](https://github.com/element-hq/element-android)
and [element-ios](https://github.com/element-hq/element-ios).

View file

@ -10,24 +10,24 @@ module.exports = {
"last 2 Safari versions",
"last 2 Edge versions",
],
include: ["@babel/plugin-transform-class-properties"],
},
],
["@babel/preset-typescript", { allowDeclareFields: true }],
"@babel/preset-typescript",
"@babel/preset-react",
],
plugins: [
"@babel/plugin-proposal-export-default-from",
"@babel/plugin-transform-numeric-separator",
"@babel/plugin-transform-object-rest-spread",
"@babel/plugin-transform-optional-chaining",
"@babel/plugin-transform-nullish-coalescing-operator",
"@babel/plugin-proposal-numeric-separator",
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-nullish-coalescing-operator",
// transform logical assignment (??=, ||=, &&=). preset-env doesn't
// normally bother with these (presumably because all the target
// browsers support it natively), but they make our webpack version (or
// something downstream of babel, at least) fall over.
"@babel/plugin-transform-logical-assignment-operators",
"@babel/plugin-proposal-logical-assignment-operators",
"@babel/plugin-syntax-dynamic-import",
"@babel/plugin-transform-runtime",

View file

@ -225,12 +225,6 @@ 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
Inheriting all the rules of TypeScript, the following additionally apply:

View file

@ -167,10 +167,6 @@ Starting with `desktop_builds`, the following subproperties are available:
1. `available`: Required. When `true`, the desktop app can be downloaded from somewhere.
2. `logo`: Required. A URL to a logo (SVG), intended to be shown at 24x24 pixels.
3. `url`: Required. The download URL for the app. This is used as a hyperlink.
4. `url_macos`: Optional. Direct link to download macOS desktop app.
5. `url_win32`: Optional. Direct link to download Windows 32-bit desktop app.
6. `url_win64`: Optional. Direct link to download Windows 64-bit desktop app.
7. `url_linux`: Optional. Direct link to download Linux desktop app.
When `desktop_builds` is not specified at all, the app will assume desktop downloads are available from https://element.io
@ -254,60 +250,17 @@ 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.
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
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:
have users which land on the welcome page to be redirected, use `"on_welcome_page": true`. As an example:
```json
{
"sso_redirect_options": {
"immediate": false,
"on_welcome_page": true,
"on_login_page": true
"on_welcome_page": true
}
}
```
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
Currently, Element uses Jitsi to offer conference calls in rooms, with an experimental Element Call implementation in the works.
@ -378,8 +331,8 @@ The VoIP and Jitsi options are:
}
```
The `widget` is the `content` of a normal widget state event. The `layout` is the layout specifier for the widget being created,
as defined by the `io.element.widgets.layout` state event. By default this applies to all rooms, but the behaviour can be skipped for
2-person rooms, causing Element to fall back to 1:1 VoIP, by setting the option `widget_build_url_ignore_dm` to `true`.
as defined by the `io.element.widgets.layout` state event. By default this applies to all rooms, but the behaviour can be skipped for DMs
by setting the option `widget_build_url_ignore_dm` to `true`.
5. `audio_stream_url`: Optional URL to pass to Jitsi to enable live streaming. This option is considered experimental and may be removed
at any time without notice.
6. `element_call`: Optional configuration for native group calls using Element Call, with the following subkeys:

View file

@ -110,6 +110,29 @@ This is useful while we experiment with encryption and to make calling compatibl
Enables rendering of MD / HTML in room topics.
## Use the Rust cryptography implementation (`feature_rust_crypto`) [In Development]
Configures Element to use a new cryptography implementation based on the [matrix-rust-sdk](https://github.com/matrix-org/matrix-rust-sdk).
This setting is (currently) _sticky_ to a user's session: it only takes effect when the user logs in to a new session. Likewise, even after disabling the setting in `config.json`, the Rust implementation will remain in use until users log out.
This configuration value is now set to `true` by default. This means that without any additional configuration
every new login will use the new cryptography implementation.
For administrators looking to transition existing users to the new stack, the `RustCrypto.staged_rollout_percent` configuration is available.
This configuration allows for a phased migration of users, represented as an integer percentage (0 to 100). By default, this value is set to `0`,
which means no existing users will be migrated to the new stack. If you wish to migrate all users, you can adjust this value to `100`.
This configuration should be placed under the `setting_defaults` section as shown:
```
"setting_defaults": {
"RustCrypto.staged_rollout_percent": 20
},
```
By adjusting the `RustCrypto.staged_rollout_percent` value, you can control the migration process according to your deployment strategy.
## New room header & details (`feature_new_room_decoration_ui`) [In Development]
Refactors visually the room header and room sidebar

View file

@ -22,7 +22,7 @@
"uisi_autorageshake_app": "element-auto-uisi",
"show_labs_settings": false,
"room_directory": {
"servers": ["matrix.org", "gitter.im"]
"servers": ["matrix.org", "gitter.im", "libera.chat"]
},
"enable_presence_by_hs_url": {
"https://matrix.org": false,
@ -45,6 +45,6 @@
"privacy_policy_url": "https://element.io/cookie-policy",
"map_style_url": "https://api.maptiler.com/maps/streets/style.json?key=fU3vlMsMn4Jb6dnEIFsx",
"setting_defaults": {
"RustCrypto.staged_rollout_percent": 60
"RustCrypto.staged_rollout_percent": 10
}
}

View file

@ -22,7 +22,7 @@
"uisi_autorageshake_app": "element-auto-uisi",
"show_labs_settings": true,
"room_directory": {
"servers": ["matrix.org", "gitter.im"]
"servers": ["matrix.org", "gitter.im", "libera.chat"]
},
"enable_presence_by_hs_url": {
"https://matrix.org": false,
@ -48,7 +48,6 @@
},
"privacy_policy_url": "https://element.io/cookie-policy",
"features": {
"threadsActivityCentre": true,
"feature_video_rooms": true,
"feature_new_room_decoration_ui": true,
"feature_element_call_video_rooms": true

View file

@ -1,6 +1,6 @@
{
"name": "element-web",
"version": "1.11.69",
"version": "1.11.63",
"description": "A feature-rich client for Matrix.org",
"author": "New Vector Ltd.",
"repository": {
@ -67,18 +67,13 @@
"update:jitsi": "curl -s https://meet.element.io/libs/external_api.min.js > ./res/jitsi_external_api.min.js"
},
"resolutions": {
"@types/react-dom": "17.0.25",
"@types/react": "17.0.80",
"@vector-im/compound-design-tokens": "1.7.0",
"@vector-im/compound-web": "5.5.0",
"@floating-ui/react": "0.26.11",
"@radix-ui/react-id": "1.1.0"
"@types/react-dom": "17.0.21",
"@types/react": "17.0.68"
},
"dependencies": {
"@formatjs/intl-segmenter": "^11.5.7",
"@matrix-org/olm": "3.2.15",
"@matrix-org/react-sdk-module-api": "^2.3.0",
"@vector-im/compound-design-tokens": "^1.6.1",
"@vector-im/compound-web": "^5.5.0",
"gfm.css": "^1.1.2",
"jsrsasign": "^11.0.0",
"katex": "^0.16.0",
"lodash": "^4.17.21",
@ -95,21 +90,21 @@
"@babel/core": "^7.12.10",
"@babel/eslint-parser": "^7.12.10",
"@babel/eslint-plugin": "^7.12.10",
"@babel/plugin-proposal-class-properties": "^7.12.1",
"@babel/plugin-proposal-export-default-from": "^7.12.1",
"@babel/plugin-proposal-logical-assignment-operators": "^7.20.7",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
"@babel/plugin-proposal-numeric-separator": "^7.12.7",
"@babel/plugin-proposal-object-rest-spread": "^7.12.1",
"@babel/plugin-proposal-optional-chaining": "^7.12.7",
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@babel/plugin-transform-class-properties": "^7.12.1",
"@babel/plugin-transform-logical-assignment-operators": "^7.20.7",
"@babel/plugin-transform-nullish-coalescing-operator": "^7.12.1",
"@babel/plugin-transform-numeric-separator": "^7.12.7",
"@babel/plugin-transform-object-rest-spread": "^7.12.1",
"@babel/plugin-transform-optional-chaining": "^7.12.7",
"@babel/plugin-transform-runtime": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"@babel/preset-typescript": "^7.12.7",
"@babel/register": "^7.12.10",
"@babel/runtime": "^7.12.5",
"@casualbot/jest-sonar-reporter": "2.3.1",
"@casualbot/jest-sonar-reporter": "2.2.7",
"@principalstudio/html-webpack-inject-preload": "^1.2.7",
"@sentry/webpack-plugin": "^2.7.1",
"@svgr/webpack": "^8.0.0",
@ -132,16 +127,15 @@
"@types/node-fetch": "^2.6.4",
"@types/pako": "^2.0.3",
"@types/qrcode": "^1.5.5",
"@types/react": "17.0.80",
"@types/react": "17.0.68",
"@types/react-beautiful-dnd": "^13.1.7",
"@types/react-dom": "17.0.25",
"@types/react-dom": "17.0.21",
"@types/react-transition-group": "^4.4.9",
"@types/sanitize-html": "^2.9.5",
"@types/sdp-transform": "^2.4.9",
"@types/semver": "^7.5.8",
"@types/tar-js": "^0.3.5",
"@types/ua-parser-js": "^0.7.36",
"@types/uuid": "^10.0.0",
"@types/uuid": "^9.0.7",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"babel-jest": "^29.0.0",
@ -152,61 +146,60 @@
"concurrently": "^8.0.0",
"copy-webpack-plugin": "^12.0.0",
"cronstrue": "^2.41.0",
"css-loader": "^7.0.0",
"css-minimizer-webpack-plugin": "^7.0.0",
"css-loader": "^6.0.0",
"css-minimizer-webpack-plugin": "^6.0.0",
"dotenv": "^16.0.2",
"eslint": "8.57.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-deprecate": "0.8.5",
"eslint-plugin-deprecate": "0.8.4",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-matrix-org": "^1.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-unicorn": "^54.0.0",
"fake-indexeddb": "^6.0.0",
"eslint-plugin-unicorn": "^51.0.0",
"fake-indexeddb": "^5.0.0",
"fetch-mock": "9.11.0",
"fetch-mock-jest": "^1.5.1",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^5.5.3",
"husky": "^8.0.3",
"jest": "^29.0.0",
"jest-canvas-mock": "2.5.2",
"jest-environment-jsdom": "^29.0.0",
"jest-mock": "^29.0.0",
"jest-raw-loader": "^1.0.1",
"lint-staged": "^15.1.0",
"matrix-mock-request": "^2.5.0",
"matrix-web-i18n": "^3.2.1",
"mini-css-extract-plugin": "2.9.0",
"mini-css-extract-plugin": "2.8.0",
"minimist": "^1.2.6",
"mkdirp": "^3.0.0",
"modernizr": "^3.12.0",
"node-fetch": "^2.6.7",
"postcss": "8.4.38",
"postcss": "8.4.33",
"postcss-easings": "^4.0.0",
"postcss-hexrgba": "2.1.0",
"postcss-import": "16.1.0",
"postcss-loader": "8.1.1",
"postcss-import": "16.0.0",
"postcss-loader": "8.1.0",
"postcss-mixins": "^10.0.0",
"postcss-nested": "^6.0.0",
"postcss-preset-env": "^9.5.14",
"postcss-preset-env": "^9.3.0",
"postcss-scss": "^4.0.4",
"postcss-simple-vars": "^7.0.1",
"prettier": "3.3.3",
"prettier": "3.2.5",
"process": "^0.11.10",
"raw-loader": "^4.0.2",
"rimraf": "^6.0.0",
"rimraf": "^5.0.0",
"semver": "^7.5.2",
"setimmediate": "^1.0.5",
"string-replace-loader": "3",
"style-loader": "4",
"style-loader": "3",
"stylelint": "^16.1.0",
"stylelint-config-standard": "^36.0.0",
"stylelint-scss": "^6.0.0",
"terser-webpack-plugin": "^5.3.9",
"ts-node": "^10.9.1",
"ts-prune": "^0.10.3",
"typescript": "5.5.4",
"typescript": "5.4.3",
"util": "^0.12.5",
"webpack": "^5.89.0",
"webpack-bundle-analyzer": "^4.8.0",
@ -218,8 +211,5 @@
"outputDirectory": "coverage",
"outputName": "jest-sonar-report.xml",
"relativePaths": true
},
"engines": {
"node": ">=20.0.0"
}
}

View file

@ -38,7 +38,7 @@ module.exports.pitch = function pitch(request) {
return cb(err);
}
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);
});

View file

@ -1,62 +0,0 @@
[
{
"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"
]
}
}
]

View file

@ -14,61 +14,94 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
.mx_ErrorView {
--width: 520px;
--cpd-separator-inset: calc(50% - (var(--width) / 2));
--cpd-separator-spacing: var(--cpd-space-8x);
/* import font-size variables manually,
ideally this file would get loaded by the theme which has all variables in context */
@import "../../../node_modules/matrix-react-sdk/res/css/_font-sizes.pcss";
.mx_ErrorView {
background: #c5e0f7;
background: -moz-linear-gradient(top, #c5e0f7 0%, #ffffff 100%);
background: -webkit-linear-gradient(top, #c5e0f7 0%, #ffffff 100%);
background: linear-gradient(to bottom, #c5e0f7 0%, #ffffff 100%);
/* stylelint-disable-next-line function-no-unknown */
filter: progid:dximagetransform.microsoft.gradient(startColorstr='#c5e0f7', endColorstr='#ffffff', GradientType=0);
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
text-align: center;
color: var(--cpd-color-text-primary);
color: #000;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: auto;
padding: var(--cpd-space-20x);
background-color: var(--cpd-color-theme-bg);
background-image: url("../../themes/element/img/compound/fade-arc-light.png");
background-repeat: no-repeat;
background-size: 100% 100%;
.mx_ErrorView_logo {
display: block;
margin: 0 auto;
}
padding: 0 20px;
box-sizing: border-box;
.mx_ErrorView_container {
max-width: var(--width);
margin: 0 auto var(--cpd-space-8x);
max-width: 680px;
margin: auto;
}
.mx_Button {
border: 0;
border-radius: 4px;
font-size: $font-18px;
margin-left: 4px;
margin-right: 4px;
min-width: 80px;
background-color: #03b381;
color: #fff;
cursor: pointer;
padding: 12px 22px;
word-break: break-word;
text-decoration: none;
}
.mx_Center {
justify-content: center;
}
.mx_HomePage_header {
color: #2e2f32;
display: flex;
align-items: center;
justify-content: center;
}
font-size: $font-16px;
h1 {
font-size: $font-32px;
}
h2 {
font-size: $font-24px;
color: #000;
}
.mx_HomePage_col {
display: flex;
flex-direction: row;
}
.mx_HomePage_row {
flex: 1 1 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.mx_HomePage_logo {
margin: auto 20px auto 0;
}
h1,
h2 {
color: var(--cpd-color-text-primary);
font-weight: 600;
margin-bottom: 32px;
}
h2 {
margin: var(--cpd-space-8x) 0;
/* Workaround for heading sm being broken in Compound design tokens */
font-size: var(--cpd-font-size-heading-sm);
line-height: var(--cpd-font-line-height-tight);
font-weight: var(--cpd-font-weight-semibold);
.mx_Spacer {
margin-top: 24px;
}
p {
color: var(--cpd-color-text-secondary);
}
.mx_Flex {
margin: 0 auto;
max-width: max-content;
flex-wrap: wrap;
justify-content: space-evenly;
}
.mx_ErrorView_buttons {
margin-top: var(--cpd-space-6x);
.mx_FooterLink {
color: #368bd6;
text-decoration: none;
}
}

File diff suppressed because one or more lines are too long

1
res/sw.js Normal file
View file

@ -0,0 +1 @@
self.addEventListener("fetch", () => {});

View file

@ -1,3 +0,0 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.4157 2C13.4922 2.92763 13.1763 3.84642 12.535 4.56125C11.9129 5.27979 10.9701 5.69366 9.97726 5.68417C9.91411 4.78324 10.2392 3.89596 10.881 3.21774C11.531 2.53034 12.436 2.09555 13.4157 2ZM16.5554 7.45058C15.4132 8.10257 14.7104 9.25238 14.6932 10.4972C14.6948 11.9055 15.6031 13.1765 17 13.7251C16.7313 14.5354 16.3264 15.3013 15.8001 15.9942C15.0934 16.9759 14.3523 17.935 13.1762 17.9527C12.6168 17.9647 12.2392 17.8153 11.8458 17.6597C11.4354 17.4974 11.0077 17.3282 10.3385 17.3282C9.62875 17.3282 9.18194 17.5028 8.75102 17.6712C8.37862 17.8167 8.01808 17.9576 7.50997 17.9772C6.38987 18.0157 5.53384 16.9294 4.80138 15.9569C3.33741 13.971 2.19745 10.3601 3.72573 7.90322C4.44339 6.70576 5.78524 5.94589 7.26033 5.90164C7.89561 5.8895 8.5052 6.11686 9.03964 6.31619C9.44837 6.46863 9.81314 6.60468 10.1118 6.60468C10.3744 6.60468 10.729 6.474 11.1423 6.32171C11.7932 6.08181 12.5898 5.78827 13.4015 5.86738C14.6627 5.90402 15.8316 6.49076 16.5554 7.45058Z" fill="#1B1D22"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

View file

@ -1,15 +0,0 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_4244_203)">
<path d="M11.0054 17.2033C10.7192 17.3348 10.4074 17.405 10.0911 17.4096C9.62287 17.4048 9.1673 17.2609 8.78524 16.9971C8.65787 17.3144 8.45841 17.5995 8.20182 17.831C7.94524 18.0626 7.63819 18.2344 7.30371 18.3337C7.34816 18.3337 7.39049 18.3337 7.43494 18.3337H12.4213C12.1196 18.2476 11.8387 18.103 11.5954 17.9088C11.3522 17.7147 11.1515 17.4747 11.0054 17.2033Z" fill="black"/>
<path d="M5.59233 13.8942C5.61193 13.8889 5.63053 13.8805 5.64735 13.8694C5.6791 13.5971 5.71508 13.3352 5.7553 13.0856C5.74691 12.9449 5.77002 12.8041 5.82302 12.6731C6.11298 11.0868 6.51722 9.97294 7.07596 9.29637C7.09365 9.27503 7.1193 9.26142 7.14728 9.25851C7.17526 9.25561 7.20328 9.26367 7.22518 9.2809C7.24707 9.29813 7.26104 9.32313 7.26401 9.35041C7.26699 9.37768 7.25873 9.40498 7.24105 9.42631C7.18391 9.49645 7.12676 9.57277 7.07173 9.65322C6.64844 10.272 6.31404 11.2126 6.07277 12.477H6.09816C6.14375 12.4702 6.19014 12.4702 6.23573 12.477C6.40082 12.5121 6.65902 12.6462 7.05692 13.036C7.10771 10.7691 8.44108 8.94158 10.0919 8.94158C11.548 8.94158 12.765 10.371 13.0549 12.2729C13.1926 12.0053 13.4153 11.7882 13.6899 11.654C13.7577 11.6293 13.8293 11.6161 13.9016 11.6149C13.7518 10.9261 13.485 10.2666 13.1121 9.66353C13.0571 9.58308 13.002 9.50676 12.9449 9.43663C12.9357 9.42642 12.9287 9.41445 12.9244 9.40149C12.9201 9.38852 12.9186 9.37484 12.92 9.36128C12.9214 9.34774 12.9256 9.33461 12.9325 9.32273C12.9393 9.31085 12.9486 9.30047 12.9597 9.29224C12.9703 9.28351 12.9826 9.27695 12.9959 9.27294C13.0091 9.26893 13.0232 9.26756 13.0369 9.26891C13.0507 9.27025 13.0641 9.2743 13.0763 9.28078C13.0885 9.28727 13.0992 9.29608 13.1079 9.30668C13.5312 9.82648 13.8825 10.6041 14.145 11.6582C14.7101 11.8644 14.7248 12.7927 14.7375 13.5476C14.7375 13.9065 14.7375 14.2779 14.8243 14.3727C14.9111 14.4676 15.0952 14.447 15.3535 14.3397C15.3831 14.0118 15.3978 13.7209 15.4063 13.4755C15.4063 13.0856 15.4063 12.836 15.4063 12.836V12.574C15.4063 10.5113 12.6846 6.94487 12.6846 6.94487L12.3692 4.26334C12.3692 1.80251 10.0919 1.8252 10.0919 1.8252C10.0919 1.8252 7.80615 1.80251 7.80615 4.25302L7.50138 6.94487C7.50138 6.94487 4.77961 10.5092 4.77961 12.574V12.8319C4.77961 12.8319 4.76902 13.0814 4.77961 13.4713C4.77961 13.5311 4.77961 13.5951 4.77961 13.6611C5.1246 13.7889 5.47804 13.923 5.59233 13.8942ZM10.0813 5.21837C10.7163 5.27613 11.7279 5.42465 11.7745 5.72993C11.8084 5.96507 11.4168 6.41475 11.3385 6.50138C11.1755 6.68084 10.6083 7.26872 10.0962 7.26872C9.58397 7.26872 9.01676 6.68084 8.85591 6.50138C8.7776 6.41475 8.38606 5.96507 8.4178 5.72993C8.4559 5.41846 9.47815 5.27613 10.0813 5.21837Z" fill="black"/>
<path d="M10.0925 7.0621C10.3698 7.0621 10.7952 6.78776 11.174 6.3649C11.464 6.04518 11.5698 5.81003 11.5613 5.7564C11.5084 5.6512 10.8164 5.49237 10.0798 5.42224C9.36657 5.49237 8.67449 5.6512 8.62158 5.76052C8.69778 5.98983 8.83166 6.19689 9.01101 6.36284C9.39197 6.78776 9.81526 7.0621 10.0925 7.0621Z" fill="black"/>
<path d="M10.6623 15.9489C10.4189 13.7769 10.6432 13.3273 10.8337 13.1788C10.8804 13.1432 10.9358 13.1201 10.9945 13.1117C11.0531 13.1035 11.113 13.1102 11.1681 13.1313C11.3598 13.2237 11.5271 13.3577 11.657 13.5232C11.8962 13.7769 12.0634 13.9358 12.2179 13.8491C12.328 13.7852 12.4846 13.4366 12.6412 13.1169C12.7216 12.9456 12.8042 12.7621 12.8952 12.5868C12.6835 10.6457 11.5195 9.14819 10.0993 9.14819C8.53949 9.14819 7.27173 10.9531 7.27173 13.1705C7.27173 13.1973 7.27173 13.2241 7.27173 13.2509C7.52995 13.5149 7.83895 13.8698 8.21567 14.3338C8.36367 14.5155 8.4994 14.7064 8.62204 14.9052C8.79699 15.1841 8.909 15.4961 8.9506 15.8205C8.9922 16.1449 8.96245 16.4741 8.86331 16.7864C9.21862 17.0463 9.64882 17.1907 10.093 17.199C10.3777 17.1979 10.659 17.1382 10.9184 17.0236C10.862 16.9 10.8173 16.7716 10.7851 16.64C10.7302 16.4122 10.6892 16.1815 10.6623 15.9489Z" fill="black"/>
<path d="M8.04303 14.459C7.74673 14.0918 7.49487 13.8009 7.279 13.5658L7.17105 13.4503L7.061 13.3348C6.5721 12.8397 6.31389 12.7037 6.17843 12.681C6.15951 12.678 6.14023 12.678 6.12129 12.681C6.10076 12.6833 6.08122 12.6909 6.06454 12.7028C6.04786 12.7147 6.03461 12.7307 6.02605 12.7489C6.02565 12.7538 6.02565 12.7586 6.02605 12.7634C5.98416 12.8712 5.96753 12.9869 5.97738 13.1017C5.97738 13.1595 5.97738 13.2173 5.97738 13.2749C5.97738 13.3327 5.97738 13.341 5.97738 13.374C6.00594 13.5827 5.96198 13.7947 5.8525 13.9763C5.83155 13.9994 5.80732 14.0196 5.78055 14.0362L5.7361 14.0629C5.70773 14.0774 5.67795 14.0892 5.6472 14.098H5.62393C5.44826 14.1289 5.16254 14.0279 4.80063 13.8917L4.6948 13.8505C4.24188 13.6752 3.71276 13.473 3.32545 13.473C3.23797 13.4644 3.14967 13.4777 3.06893 13.5116C2.98819 13.5455 2.91767 13.599 2.86406 13.6669C2.58046 14.0794 3.2154 14.7271 3.72758 15.2511C4.04294 15.5749 4.29056 15.8286 4.31808 16.0184C4.36675 16.3691 3.99002 16.5031 3.65774 16.6228C3.48628 16.6669 3.32623 16.7457 3.18788 16.8538C3.13709 16.9116 3.1392 16.9508 3.14979 16.9797C3.19635 17.1384 3.57308 17.4871 5.56466 18.0502C5.78512 18.1124 6.00914 18.1621 6.23558 18.1987C6.64453 18.2591 7.06268 18.2065 7.44245 18.0468C7.82223 17.8871 8.14838 17.6267 8.38379 17.2952C8.47591 17.159 8.55187 17.0129 8.61025 16.86L8.65257 16.7589C8.65257 16.7239 8.67163 16.6847 8.68221 16.6496C8.75827 16.3728 8.77591 16.0838 8.73407 15.8002C8.69223 15.5165 8.59179 15.2441 8.43881 14.9994C8.31764 14.812 8.18549 14.6316 8.04303 14.459Z" fill="black"/>
<path d="M16.0589 14.3171C15.8816 14.3336 15.71 14.3863 15.5552 14.4717L15.3245 14.5687C15.0704 14.6635 14.8164 14.7089 14.6513 14.4903C14.6122 14.4329 14.5856 14.3683 14.573 14.3006C14.5437 14.1377 14.5282 13.9728 14.5265 13.8075C14.5265 13.723 14.5265 13.6342 14.5265 13.5393C14.5265 12.9391 14.5054 12.2171 14.2154 11.9346C14.1785 11.8974 14.1346 11.8673 14.0863 11.8459C14.0596 11.8345 14.0321 11.8255 14.0037 11.8191H13.972C13.9001 11.8109 13.8272 11.8208 13.7603 11.8479C13.5106 11.947 13.2926 12.2605 13.1022 12.6277L13.0112 12.8071C12.9772 12.8772 12.9455 12.9453 12.9138 13.0133C12.882 13.0814 12.8545 13.1392 12.827 13.2011C12.6408 13.6136 12.4947 13.9292 12.3254 14.0262C12.0122 14.2056 11.7391 13.9168 11.5 13.6611C11.3921 13.5236 11.2558 13.4098 11.1 13.3269C11.0796 13.3194 11.0582 13.3152 11.0365 13.3145C11.0108 13.3139 10.9859 13.3228 10.9666 13.3393C10.8354 13.4424 10.647 13.9148 10.8735 15.926C10.8978 16.148 10.936 16.3684 10.9878 16.586C11.0166 16.7008 11.0548 16.8133 11.1021 16.9222C11.1169 16.9532 11.1317 16.9841 11.1486 17.015C11.1656 17.0459 11.1762 17.0769 11.1931 17.1079C11.3664 17.4217 11.6184 17.6878 11.9256 17.8813C12.2328 18.0746 12.5853 18.1891 12.9501 18.214C13.3149 18.239 13.6804 18.1735 14.0122 18.0237C14.3441 17.8739 14.6317 17.6448 14.8482 17.3574C14.9843 17.1771 15.1093 16.989 15.2228 16.7943C16.2387 15.0307 16.2578 14.5254 16.1795 14.3809C16.1676 14.3603 16.15 14.3434 16.1286 14.332C16.1073 14.3208 16.0831 14.3155 16.0589 14.3171Z" fill="black"/>
</g>
<defs>
<clipPath id="clip0_4244_203">
<rect width="14.4446" height="16.5081" fill="white" transform="translate(2.63892 1.8252)"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 7 KiB

View file

@ -1,6 +0,0 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="10.4908" y="2" width="7.50926" height="7.50926" fill="#1B1D22"/>
<rect x="2" y="10.4904" width="7.50926" height="7.50926" fill="#1B1D22"/>
<rect x="2" y="2" width="7.50926" height="7.50926" fill="#1B1D22"/>
<rect x="10.4908" y="10.4904" width="7.50926" height="7.50926" fill="#1B1D22"/>
</svg>

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 770 B

After

Width:  |  Height:  |  Size: 434 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 629 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 KiB

After

Width:  |  Height:  |  Size: 974 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 940 B

View file

@ -1,5 +1,5 @@
sonar.projectKey=element-web
sonar.organization=element-hq
sonar.organization=new_vector_ltd_organization
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8
@ -10,5 +10,5 @@ sonar.exclusions=__mocks__,docs,element.io,nginx
sonar.typescript.tsconfigPath=./tsconfig.json
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.coverage.exclusions=test/**/*,res/**/*,src/vector/modernizr.js
sonar.coverage.exclusions=test/**/*,res/**/*
sonar.testExecutionReportPaths=coverage/jest-sonar-report.xml

View file

@ -33,9 +33,7 @@ type ElectronChannel =
| "update-downloaded"
| "userDownloadCompleted"
| "userDownloadAction"
| "openDesktopCapturerSourcePicker"
| "userAccessToken"
| "serverSupportedVersions";
| "openDesktopCapturerSourcePicker";
declare global {
interface Window {

View file

@ -0,0 +1,149 @@
/*
Copyright 2020 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 React, { ReactNode } from "react";
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
import { _t } from "../../languageHandler";
// directly import the style here as this layer does not support rethemedex at this time so no matrix-react-sdk
// PostCSS variables will be accessible.
import "../../../res/css/structures/ErrorView.pcss";
interface IProps {
onAccept(): void;
}
const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
const brand = SdkConfig.get("brand");
const mobileBuilds = SdkConfig.get("mobile_builds");
let ios: JSX.Element | undefined;
const iosCustomUrl = mobileBuilds?.ios;
if (iosCustomUrl !== null) {
// could be undefined or a string
ios = (
<>
<p>
<strong>iOS</strong> (iPhone or iPad)
</p>
<a href={iosCustomUrl} target="_blank" rel="noreferrer noopener" className="mx_ClearDecoration">
<img height="48" src="themes/element/img/download/apple.svg" alt="Apple App Store" />
</a>
</>
);
}
let android = [
<p className="mx_Spacer" key="header">
<strong>Android</strong>
</p>,
];
const andCustomUrl = mobileBuilds?.android;
const fdroidCustomUrl = mobileBuilds?.fdroid;
if (andCustomUrl !== null) {
// undefined or string
android.push(
<a
href={andCustomUrl}
target="_blank"
rel="noreferrer noopener"
className="mx_ClearDecoration"
key="android"
>
<img height="48" src="themes/element/img/download/google.svg" alt="Google Play Store" />
</a>,
);
}
if (fdroidCustomUrl !== null) {
// undefined or string
android.push(
<a
href={fdroidCustomUrl}
target="_blank"
rel="noreferrer noopener"
className="mx_ClearDecoration"
key="fdroid"
>
<img height="48" src="themes/element/img/download/fdroid.svg" alt="F-Droid" />
</a>,
);
}
if (android.length === 1) {
// just a header, meaning no links
android = [];
}
let mobileHeader: ReactNode = <h2 id="step2_heading">{_t("use_brand_on_mobile", { brand })}</h2>;
if (!android.length && !ios) {
mobileHeader = null;
}
return (
<div className="mx_ErrorView">
<div className="mx_ErrorView_container">
<div className="mx_HomePage_header">
<span className="mx_HomePage_logo">
<img height="42" src="themes/element/img/logos/element-logo.svg" alt="Element" />
</span>
<h1>{_t("incompatible_browser|title")}</h1>
</div>
<div className="mx_HomePage_col">
<div className="mx_HomePage_row">
<div>
<h2 id="step1_heading">{_t("incompatible_browser|summary", { brand })}</h2>
<p>{_t("incompatible_browser|features", { brand })}</p>
<p>
{_t(
"incompatible_browser|browser_links",
{},
{
chromeLink: (sub) => <a href="https://www.google.com/chrome">{sub}</a>,
firefoxLink: (sub) => <a href="https://firefox.com">{sub}</a>,
safariLink: (sub) => <a href="https://apple.com/safari">{sub}</a>,
},
)}
</p>
<p>{_t("incompatible_browser|feature_warning")}</p>
<button onClick={onAccept}>{_t("incompatible_browser|continue_warning")}</button>
</div>
</div>
</div>
<div className="mx_HomePage_col">
<div className="mx_HomePage_row">
<div>
{mobileHeader}
{ios}
{android}
</div>
</div>
</div>
<div className="mx_HomePage_row mx_Center mx_Spacer">
<p className="mx_Spacer">
<a href="https://element.io" target="_blank" className="mx_FooterLink">
{_t("go_to_element_io")}
</a>
</p>
</div>
</div>
</div>
);
};
export default CompatibilityView;

View file

@ -14,16 +14,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { ReactNode } from "react";
import { Text, Heading, Button, Separator } from "@vector-im/compound-web";
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
import { Flex } from "matrix-react-sdk/src/components/utils/Flex";
import PopOutIcon from "@vector-im/compound-design-tokens/assets/web/icons/pop-out";
import * as React from "react";
import { _t } from "../../languageHandler";
import { Icon as AppleIcon } from "../../../res/themes/element/img/compound/apple.svg";
import { Icon as MicrosoftIcon } from "../../../res/themes/element/img/compound/microsoft.svg";
import { Icon as LinuxIcon } from "../../../res/themes/element/img/compound/linux.svg";
// directly import the style here as this layer does not support rethemedex at this time so no matrix-react-sdk
// PostCSS variables will be accessible.
@ -33,184 +26,36 @@ interface IProps {
// both of these should already be internationalised
title: string;
messages?: string[];
footer?: ReactNode;
}
export const ErrorView: React.FC<IProps> = ({ title, messages, footer, children }) => {
const ErrorView: React.FC<IProps> = ({ title, messages }) => {
return (
<div className="mx_ErrorView cpd-theme-light">
<img
className="mx_ErrorView_logo"
height="160"
src="themes/element/img/logos/element-app-logo.png"
alt="Element"
/>
<div className="mx_ErrorView">
<div className="mx_ErrorView_container">
<Heading size="md" weight="semibold">
{title}
</Heading>
{messages?.map((message) => (
<Text key={message} size="lg">
{message}
</Text>
))}
{children}
<div className="mx_HomePage_header">
<span className="mx_HomePage_logo">
<img height="42" src="themes/element/img/logos/element-logo.svg" alt="Element" />
</span>
<h1>{_t("failed_to_start")}</h1>
</div>
<div className="mx_HomePage_col">
<div className="mx_HomePage_row">
<div>
<h2 id="step1_heading">{title}</h2>
{messages && messages.map((msg) => <p key={msg}>{msg}</p>)}
</div>
</div>
</div>
<div className="mx_HomePage_row mx_Center mx_Spacer">
<p className="mx_Spacer">
<a href="https://element.io" target="_blank" className="mx_FooterLink">
{_t("go_to_element_io")}
</a>
</p>
</div>
</div>
{footer}
</div>
);
};
const MobileAppLinks: React.FC<{
appleAppStoreUrl?: string;
googlePlayUrl?: string;
fdroidUrl?: string;
}> = ({ appleAppStoreUrl, googlePlayUrl, fdroidUrl }) => (
<Flex gap="var(--cpd-space-6x)">
{appleAppStoreUrl && (
<a href={appleAppStoreUrl} target="_blank" rel="noreferrer noopener">
<img height="64" src="themes/element/img/download/apple.svg" alt="Apple App Store" />
</a>
)}
{googlePlayUrl && (
<a href={googlePlayUrl} target="_blank" rel="noreferrer noopener" key="android">
<img height="64" src="themes/element/img/download/google.svg" alt="Google Play Store" />
</a>
)}
{fdroidUrl && (
<a href={fdroidUrl} target="_blank" rel="noreferrer noopener" key="fdroid">
<img height="64" src="themes/element/img/download/fdroid.svg" alt="F-Droid" />
</a>
)}
</Flex>
);
const DesktopAppLinks: React.FC<{
macOsUrl?: string;
win64Url?: string;
win32Url?: string;
linuxUrl?: string;
}> = ({ macOsUrl, win64Url, win32Url, linuxUrl }) => {
return (
<Flex gap="var(--cpd-space-4x)">
{macOsUrl && (
<Button as="a" href={macOsUrl} kind="secondary" Icon={AppleIcon}>
{_t("incompatible_browser|macos")}
</Button>
)}
{win64Url && (
<Button as="a" href={win64Url} kind="secondary" Icon={MicrosoftIcon}>
{_t("incompatible_browser|windows", { bits: "64" })}
</Button>
)}
{win32Url && (
<Button as="a" href={win32Url} kind="secondary" Icon={MicrosoftIcon}>
{_t("incompatible_browser|windows", { bits: "32" })}
</Button>
)}
{linuxUrl && (
<Button as="a" href={linuxUrl} kind="secondary" Icon={LinuxIcon}>
{_t("incompatible_browser|linux")}
</Button>
)}
</Flex>
);
};
const linkFactory =
(link: string) =>
(text: string): JSX.Element => (
<a href={link} target="_blank" rel="noreferrer noopener">
{text}
</a>
);
export const UnsupportedBrowserView: React.FC<{
onAccept?(): void;
}> = ({ onAccept }) => {
const config = SdkConfig.get();
const brand = config.brand ?? "Element";
const hasDesktopBuilds =
config.desktop_builds?.available &&
(config.desktop_builds?.url_macos ||
config.desktop_builds?.url_win64 ||
config.desktop_builds?.url_win32 ||
config.desktop_builds?.url_linux);
const hasMobileBuilds = Boolean(
config.mobile_builds?.ios || config.mobile_builds?.android || config.mobile_builds?.fdroid,
);
return (
<ErrorView
title={_t("incompatible_browser|title", { brand })}
messages={[
_t("incompatible_browser|description", {
brand,
detail: onAccept
? _t("incompatible_browser|detail_can_continue")
: _t("incompatible_browser|detail_no_continue"),
}),
]}
footer={
<>
{/* We render the apps in the footer as they are wider than the 520px container */}
{(hasDesktopBuilds || hasMobileBuilds) && <Separator />}
{hasDesktopBuilds && (
<>
<Heading as="h2" size="sm" weight="semibold">
{_t("incompatible_browser|use_desktop_heading", { brand })}
</Heading>
<DesktopAppLinks
macOsUrl={config.desktop_builds?.url_macos}
win64Url={config.desktop_builds?.url_win64}
win32Url={config.desktop_builds?.url_win32}
linuxUrl={config.desktop_builds?.url_linux}
/>
</>
)}
{hasMobileBuilds && (
<>
<Heading as="h2" size="sm" weight="semibold">
{hasDesktopBuilds
? _t("incompatible_browser|use_mobile_heading_after_desktop")
: _t("incompatible_browser|use_mobile_heading", { brand })}
</Heading>
<MobileAppLinks
appleAppStoreUrl={config.mobile_builds?.ios ?? undefined}
googlePlayUrl={config.mobile_builds?.android ?? undefined}
fdroidUrl={config.mobile_builds?.fdroid ?? undefined}
/>
</>
)}
</>
}
>
<Text size="lg">
{_t(
"incompatible_browser|supported_browsers",
{},
{
Chrome: linkFactory("https://google.com/chrome"),
Firefox: linkFactory("https://firefox.com"),
Edge: linkFactory("https://microsoft.com/edge"),
Safari: linkFactory("https://apple.com/safari"),
},
)}
</Text>
<Flex gap="var(--cpd-space-4x)" className="mx_ErrorView_buttons">
<Button Icon={PopOutIcon} kind="secondary" size="sm">
{_t("incompatible_browser|learn_more")}
</Button>
{onAccept && (
<Button kind="primary" size="sm" onClick={onAccept}>
{_t("incompatible_browser|continue")}
</Button>
)}
</Flex>
</ErrorView>
);
};
export default ErrorView;

View file

@ -101,7 +101,7 @@ export default class Favicon {
h: number;
} {
const opt = {
n: typeof n === "number" ? Math.abs(n | 0) : n,
n: typeof n === "number" ? Math.abs(n as number | 0) : n,
len: ("" + n).length,
// badge positioning constants as percentages
x: 0.4,
@ -178,7 +178,7 @@ export default class Favicon {
this.context.fillStyle = params.textColor;
if (typeof opt.n === "number" && opt.n > 999) {
const count = (opt.n > 9999 ? 9 : Math.floor(opt.n / 1000)) + "k+";
const count = (opt.n > 9999 ? 9 : Math.floor((opt.n as number) / 1000)) + "k+";
this.context.fillText(count, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
} else {
this.context.fillText("" + opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
@ -194,9 +194,9 @@ export default class Favicon {
}
private setIcon(canvas: HTMLCanvasElement): void {
setTimeout(() => {
setImmediate(() => {
this.setIconSrc(canvas.toDataURL("image/png"));
}, 0);
});
}
private setIconSrc(url: string): void {

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Neplatný JSON",
"misconfigured": "Váš Element je nesprávně nastaven"
},
"failed_to_start": "Nepovedlo se nastartovat",
"go_to_element_io": "Přejít na element.io",
"incompatible_browser": {
"browser_links": "Pro nejlepší zážitek si prosím nainstalujte prohlížeč <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, nebo <safariLink>Safari</safariLink>.",
"continue_warning": "Rozumím a přesto chci pokračovat",
"feature_warning": "Můžete pokračovat v užívání vašeho současného prohlížeče, ale některé (nebo dokonce všechny) funkce nemusí fungovat a vzhled a chování aplikace nemusí být správné.",
"features": "%(brand)s využívá pokročilých funkcí prohlížeče, které ten váš nepodporuje.",
"summary": "Váš prohlížeč nedokáže spustit %(brand)s",
"title": "Nepodporovaný prohlížeč"
},
"powered_by_matrix": "Běží na Matrixu",
"powered_by_matrix_with_logo": "Decentralizovaný, šifrovaný chat a spolupráce na platformě $matrixLogo",
"unknown_device": "Neznámé zařízení",
"use_brand_on_mobile": "Používání %(brand)s v mobilních zařízeních",
"web_default_device_name": "%(appName)s: %(browserName)s na %(osName)s",
"welcome_to_element": "Vítá vás Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Ungültiges JSON",
"misconfigured": "Dein Element ist falsch konfiguriert"
},
"failed_to_start": "Start fehlgeschlagen",
"go_to_element_io": "Gehe zu element.io",
"incompatible_browser": {
"browser_links": "Bitte installiere <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink> oder <safariLink>Safari</safariLink> für das beste Erlebnis.",
"continue_warning": "Ich verstehe die Risiken und möchte fortfahren",
"feature_warning": "Du kannst deinen aktuellen Browser weiterhin verwenden. Es ist aber möglich, dass nicht alles richtig funktioniert oder das Aussehen der App inkorrekt ist.",
"features": "%(brand)s verwendet erweiterte Browserfunktionen, die von deinem Browser nicht unterstützt werden.",
"summary": "Dein Browser kann %(brand)s nicht ausführen",
"title": "Nicht unterstützter Browser"
},
"powered_by_matrix": "Betrieben mit Matrix",
"powered_by_matrix_with_logo": "Dezentralisierter, verschlüsselter Chat &amp; Zusammenarbeit unterstützt von $matrixLogo",
"unknown_device": "Unbekanntes Gerät",
"use_brand_on_mobile": "Verwende %(brand)s am Handy",
"web_default_device_name": "%(appName)s: %(browserName)s auf %(osName)s",
"welcome_to_element": "Willkommen bei Element"
}

View file

@ -19,11 +19,19 @@
"invalid_json_generic": "Μη έγκυρο JSON",
"misconfigured": "Το Element σας δεν εχει ρυθμιστεί σωστά"
},
"failed_to_start": "Αποτυχία έναρξης",
"go_to_element_io": "Πήγαινε στο element.io",
"incompatible_browser": {
"browser_links": "Παρακαλούμε εγκαταστήστε <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, ή <safariLink>Safari</safariLink> για καλύτερη εμπειρία χρήσης.",
"continue_warning": "Κατανοώ τους κινδύνους και επιθυμώ να συνεχίσω",
"feature_warning": "Μπορείτε να συνεχίσετε να χρησιμοποιείτε το τρέχον πρόγραμμα περιήγησής σας, αλλά ορισμένες ή όλες οι λειτουργίες ενδέχεται να μην λειτουργούν και η εμφάνιση και η αίσθηση της εφαρμογής ενδέχεται να είναι λανθασμένη.",
"features": "%(brand)s χρησιμοποιεί προηγμένες δυνατότητες προγράμματος περιήγησης που δεν υποστηρίζονται από το τρέχον πρόγραμμα περιήγησής σας.",
"summary": "Το πρόγραμμα περιήγησής σας δεν μπορεί να εκτελέσει %(brand)s",
"title": "Μη υποστηριζόμενο πρόγραμμα περιήγησης"
},
"powered_by_matrix": "Με την υποστήριξη του Matrix",
"powered_by_matrix_with_logo": "Αποκεντρωμένη, κρυπτογραφημένη συνομιλία και συνεργασία χρησιμοποιώντας το $matrixLogo",
"unknown_device": "Άγνωστη συσκευή",
"use_brand_on_mobile": "Χρήση %(brand)s σε κινητό",
"welcome_to_element": "Καλώς ήλθατε στο Element"
}

View file

@ -21,24 +21,20 @@
"invalid_json_generic": "Invalid JSON",
"misconfigured": "Your Element is misconfigured"
},
"failed_to_start": "Failed to start",
"go_to_element_io": "Go to element.io",
"incompatible_browser": {
"continue": "Continue anyway",
"description": "%(brand)s uses some browser features which are not available in your current browser. %(detail)s",
"detail_can_continue": "If you continue, some features may stop working and there is a risk that you may lose data in the future.",
"detail_no_continue": "Try updating this browser if you're not using the latest version and try again.",
"learn_more": "Learn more",
"linux": "Linux",
"macos": "Mac",
"supported_browsers": "For the best experience, use <Chrome>Chrome</Chrome>, <Firefox>Firefox</Firefox>, <Edge>Edge</Edge>, or <Safari>Safari</Safari>.",
"title": "%(brand)s does not support this browser",
"use_desktop_heading": "Use %(brand)s Desktop instead",
"use_mobile_heading": "Use %(brand)s on mobile instead",
"use_mobile_heading_after_desktop": "Or use our mobile app",
"windows": "Windows (%(bits)s-bit)"
"browser_links": "Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.",
"continue_warning": "I understand the risks and wish to continue",
"feature_warning": "You can continue using your current browser, but some or all features may not work and the look and feel of the application may be incorrect.",
"features": "%(brand)s uses advanced browser features which aren't supported by your current browser.",
"summary": "Your browser can't run %(brand)s",
"title": "Unsupported browser"
},
"powered_by_matrix": "Powered by Matrix",
"powered_by_matrix_with_logo": "Decentralised, encrypted chat &amp; collaboration powered by $matrixLogo",
"unknown_device": "Unknown device",
"use_brand_on_mobile": "Use %(brand)s on mobile",
"web_default_device_name": "%(appName)s: %(browserName)s on %(osName)s",
"welcome_to_element": "Welcome to Element"
}

View file

@ -20,12 +20,20 @@
"invalid_json_generic": "Nevalida JSON",
"misconfigured": "Via Elemento estas misagordita"
},
"failed_to_start": "Malsukcesis starti",
"go_to_element_io": "Iri al element.io",
"incompatible_browser": {
"browser_links": "Bonvolu instali retumilon <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, aŭ <safariLink>Safari</safariLink>, por la plej bona sperto.",
"continue_warning": "Mi komprenas la riskon kaj volas pluiĝi",
"feature_warning": "Vi povas daŭre uzi vian nunan foliumilon, sed iuj (eĉ ĉiuj) funkcioj eble ne funkciu, kaj la aspekto de la aplikaĵo eble ne estu ĝusta.",
"features": "%(brand)s uzas specialajn funkciojn de retumilo, kiujn via nuna retumilo ne subtenas.",
"summary": "Via retumilo ne povas ruli %(brand)s",
"title": "Nesubtenata retumilo"
},
"powered_by_matrix": "Povigata de Matrix",
"powered_by_matrix_with_logo": "Malcentralizita kaj ĉifrita babilejo; kunlaboro danke al $matrixLogo",
"unknown_device": "Nekonata aparato",
"use_brand_on_mobile": "Uzi %(brand)s poŝtelefone",
"web_default_device_name": "%(appName)s: %(browserName)s sur %(osName)s",
"welcome_to_element": "Bonvenon al Element"
}

View file

@ -20,12 +20,20 @@
"invalid_json_generic": "JSON inválido",
"misconfigured": "Tu aplicación Element está mal configurada"
},
"failed_to_start": "Fallo al iniciar",
"go_to_element_io": "Ir a element.io",
"incompatible_browser": {
"browser_links": "Por favor, instale <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, o <safariLink>Safari</safariLink> para la mejor experiencia.",
"continue_warning": "Entiendo los riesgos y quiero continuar",
"feature_warning": "Puedes seguir utilizando tu navegador actual, pero puede que algunas funcionalidades no estén disponibles o que algunas partes de la aplicación se muestren de forma incorrecta.",
"features": "%(brand)s usa funciones avanzadas que su navegador actual no soporta.",
"summary": "Tu navegador no es compatible con %(brand)s",
"title": "Navegador no compatible"
},
"powered_by_matrix": "Funciona con Matrix",
"powered_by_matrix_with_logo": "Conversaciones y colaboración descentralizadas y cifradas gracias a $matrixLogo",
"unknown_device": "Dispositivo desconocido",
"use_brand_on_mobile": "Usar %(brand)s en modo móvil",
"web_default_device_name": "%(appName)s: %(browserName)s en %(osName)s",
"welcome_to_element": "Te damos la bienvenida a Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Vigane JSON",
"misconfigured": "Sinu Element on valesti seadistatud"
},
"failed_to_start": "Käivitamine ei õnnestunud",
"go_to_element_io": "Mine element.io lehele",
"incompatible_browser": {
"browser_links": "Parima kasutuskogemuse jaoks palun paigalda <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink> või <safariLink>Safari</safariLink>.",
"continue_warning": "Ma mõistan riske ja soovin jätkata",
"feature_warning": "Sa võid jätkata praeguse brauseri kasutamist, kuid mõned või kõik funktsionaalsused ei pruugi toimida ning rakenduse välimus võib vigane olla.",
"features": "%(brand)s kasutab mitmeid uusi brauseri-põhiseid tehnoloogiaid, mis ei ole veel sinu veebibrauseris toetatud.",
"summary": "%(brand)s ei toimi sinu brauseris",
"title": "Sellele brauserile puudub tugi"
},
"powered_by_matrix": "Põhineb Matrix'il",
"powered_by_matrix_with_logo": "Hajutatud ja krüpteeritud suhtlus- ning ühistöörakendus, mille aluseks on $matrixLogo",
"unknown_device": "Tundmatu seade",
"use_brand_on_mobile": "Kasuta rakendust %(brand)s nutiseadmes",
"web_default_device_name": "%(appName)s: %(browserName)s operatsioonisüsteemis %(osName)s",
"welcome_to_element": "Tere tulemast kasutama suhtlusrakendust Element"
}

View file

@ -20,12 +20,20 @@
"invalid_json_generic": "JSON اشتباه",
"misconfigured": "Element شما پیکربندی نشده است"
},
"failed_to_start": "خطا در شروع",
"go_to_element_io": "برو به element.io",
"incompatible_browser": {
"browser_links": "لطفا برای تجربه بهتر <chromeLink>کروم</chromeLink>، <firefoxLink>فایرفاکس</firefoxLink>، یا <safariLink>سافاری</safariLink> را نصب کنید.",
"continue_warning": "از خطرات این کار آگاهم و مایلم که ادامه بدهم",
"feature_warning": "شما می توانید با مرورگر فعلی خود ادامه دهید، اما ممکن است عملکرد تمامی یا برخی از قابلیت ها با اشکال روبرو شود و نمایش برنامه صحیح نباشد.",
"features": "%(brand)s از ویژگی های پیشرفته مرورگر استفاده می کند که در مرورگر فعلی شما پشتیبانی نمی شوند.",
"summary": "مرورگر شما نمی تواند %(brand)s را اجرا کند",
"title": "مرورگر پش‬تبانی نمی شود"
},
"powered_by_matrix": "راه اندازی شده با استفاده از ماتریکس",
"powered_by_matrix_with_logo": "همکاری چت غیرمتمرکز و رمزگذاری شده &amp; توسعه یافته با استفاده از $matrixLogo",
"unknown_device": "دستگاه ناشناخته",
"use_brand_on_mobile": "از %(brand)s گوشی استفاده کنید",
"web_default_device_name": "%(appName)s: %(browserName)s: روی %(osName)s",
"welcome_to_element": "به Element خوش‌آمدید"
}

View file

@ -20,12 +20,20 @@
"invalid_json_generic": "Virheellinen JSON",
"misconfigured": "Elementisi asetukset ovat pielessä"
},
"failed_to_start": "Käynnistys ei onnistunut",
"go_to_element_io": "Mene osoitteeseen riot.im",
"incompatible_browser": {
"browser_links": "Asenna <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink> tai <safariLink>Safari</safariLink>, jotta kaikki toimii parhaiten.",
"continue_warning": "Ymmärrän riskit ja haluan jatkaa",
"feature_warning": "Voit käyttää edelleen nykyistä selaintasi, mutta jotkut tai kaikki ominaisuudet eivät ehkä toimi ja sovelluksen ulkoasu voi olla virheellinen.",
"features": "%(brand)s käyttää edistyneitä selaimen ominaisuuksia, joita nykyinen selaimesi ei tue.",
"summary": "%(brand)s ei toimi selaimessasi",
"title": "Selainta ei tueta"
},
"powered_by_matrix": "Moottorina Matrix",
"powered_by_matrix_with_logo": "Hajautettu, salattu keskustelu &amp; yhteistyö, taustavoimana $matrixLogo",
"unknown_device": "Tuntematon laite",
"use_brand_on_mobile": "Käytä %(brand)sia mobiilisti",
"web_default_device_name": "%(appName)s: %(browserName)s käyttöjärjestelmällä %(osName)s",
"welcome_to_element": "Tervetuloa Element-sovellukseen"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "JSON non valide",
"misconfigured": "Votre Element est mal configuré"
},
"failed_to_start": "Échec au démarrage",
"go_to_element_io": "Aller vers element.io",
"incompatible_browser": {
"browser_links": "Veuillez installer <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink> ou <safariLink>Safari</safariLink> pour une expérience optimale.",
"continue_warning": "Je comprends les risques et souhaite continuer",
"feature_warning": "Vous pouvez continuer à utiliser votre navigateur actuel, mais vous risquez de trouver que certaines fonctionnalités et/ou lapparence de lapplication sont incorrectes.",
"features": "%(brand)s nécessite des fonctionnalités avancées que votre navigateur actuel ne prend pas en charge.",
"summary": "Votre navigateur ne peut pas exécuter %(brand)s",
"title": "Navigateur non pris en charge"
},
"powered_by_matrix": "Propulsé par Matrix",
"powered_by_matrix_with_logo": "Messagerie décentralisée, chiffrée &amp; une collaboration alimentée par $matrixLogo",
"unknown_device": "Appareil inconnu",
"use_brand_on_mobile": "Utiliser %(brand)s sur téléphone",
"web_default_device_name": "%(appName)s : %(browserName)s pour %(osName)s",
"welcome_to_element": "Bienvenue sur Element"
}

View file

@ -20,12 +20,20 @@
"invalid_json_generic": "JSON non válido",
"misconfigured": "Element non está ben configurado"
},
"failed_to_start": "Fallou o inicio",
"go_to_element_io": "Ir a element.io",
"incompatible_browser": {
"browser_links": "Instala <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, ou <safariLink>Safari</safariLink> para ter unha mellor experiencia.",
"continue_warning": "Entendo os riscos e desexo continuar",
"feature_warning": "Podes continuar co teu navegador, pero algunhas características poderían non funcionar e o aspecto da aplicación podería non ser o correcto.",
"features": "%(brand)s utiliza características avanzadas do navegador que non están dispoñibles no teu navegador.",
"summary": "O teu navegador non pode executar %(brand)s",
"title": "Navegador non soportado"
},
"powered_by_matrix": "Funciona grazas a Matrix",
"powered_by_matrix_with_logo": "Conversas &amp; colaboración descentralizadas e cifradas grazas a $matrixLogo",
"unknown_device": "Dispositivo descoñecido",
"use_brand_on_mobile": "Utiliza %(brand)s no móbil",
"web_default_device_name": "%(appName)s: %(browserName)s en %(osName)s",
"welcome_to_element": "Benvida/o a Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "JSON לא חוקי",
"misconfigured": "Element אינו מוגדר תקין"
},
"failed_to_start": "כשל בהעלאת התוכנה",
"go_to_element_io": "חזור לאתר הראשי: element.io",
"incompatible_browser": {
"browser_links": "נא התקן את דפדפן <chromeLink>כרום</chromeLink>, <firefoxLink>פיירפוקס</firefoxLink> או <safariLink>סאפרי</safariLink> בשביל החוויה הטובה ביותר.",
"continue_warning": "הסיכונים מובנים לי ואני מעוניינ/ת להמשיך",
"feature_warning": "ניתן להמשיך ולהשתמש בדפדפן זה, אך ייתכן שחלק מן התכונות והמאפיינים לא יעבדו כשורה או ייראו כשגויים.",
"features": "%(brand)s משתמש בתכונות דפדפן מתקדמות שאינן נתמכות בדפדפן הנוכחי שלך.",
"summary": "הדפדפן שלך לא יכול להריץ %(brand)s",
"title": "דפדפן לא נתמך"
},
"powered_by_matrix": "מופעל על ידי מטריקס",
"powered_by_matrix_with_logo": "צ'אט מבוזר ומוצפן &amp; מופעל בשיתוף פעולה ע\"י $matrixLogo",
"unknown_device": "מכשיר לא ידוע",
"use_brand_on_mobile": "השתמש ב-%(brand)s במכשיר הנייד",
"web_default_device_name": "%(appName)s: %(browserName)s עַל %(osName)s",
"welcome_to_element": "ברוכים הבאים ל Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Érvénytelen JSON",
"misconfigured": "Az Element hibásan van beállítva"
},
"failed_to_start": "Az indítás sikertelen",
"go_to_element_io": "Irány az element.io",
"incompatible_browser": {
"browser_links": "A legjobb élmény érdékében telepítsen <chromeLink>Chrome-ot</chromeLink>, <firefoxLink>Firefoxot</firefoxLink> vagy <safariLink>Safarit</safariLink>.",
"continue_warning": "Megértettem a kockázatot és folytatom",
"feature_warning": "Folytathatja a jelenlegi böngészőjével, de néhány vagy az összes funkció használhatatlan lehet, vagy hibák lehetnek az alkalmazás kinézetében és viselkedésében.",
"features": "A(z) %(brand)s speciális böngészőfunkciókat használ, amelyeket a jelenlegi böngészője nem támogat.",
"summary": "A böngészője nem tudja futtatni ezt: %(brand)s",
"title": "Nem támogatott böngésző"
},
"powered_by_matrix": "A gépházban: Matrix",
"powered_by_matrix_with_logo": "Elosztott, titkosított csevegés és együttműködés ezzel: $matrixLogo",
"unknown_device": "Ismeretlen eszköz",
"use_brand_on_mobile": "Mobilon használja ezt: %(brand)s",
"web_default_device_name": "%(appName)s: (%(browserName)s itt: %(osName)s)",
"welcome_to_element": "Üdvözli az Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "JSON tidak absah",
"misconfigured": "Anda salah mengatur Element"
},
"failed_to_start": "Gagal untuk memulai",
"go_to_element_io": "Buka element.io",
"incompatible_browser": {
"browser_links": "Silakan instal <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, atau <safariLink>Safari</safariLink> untuk pengalaman yang terbaik.",
"continue_warning": "Saya memahami risikonya dan ingin melanjutkan",
"feature_warning": "Anda dapat melanjutkan menggunakan peramban Anda saat ini, tetapi beberapa atau semua fitur mungkin tidak berfungsi dan tampilan serta nuansa aplikasi mungkin tidak benar.",
"features": "%(brand)s menggunakan fitur peramban tingkat lanjut yang tidak didukung oleh peramban Anda saat ini.",
"summary": "Peramban Anda tidak dapat menjalankan %(brand)s",
"title": "Peramban tidak didukung"
},
"powered_by_matrix": "Diberdayakan oleh Matrix",
"powered_by_matrix_with_logo": "Obrolan &amp; kolaborasi terdesentralisasi dan terenkripsi diberdayakan oleh $matrixLogo",
"unknown_device": "Perangkat tidak diketahui",
"use_brand_on_mobile": "Gunakan %(brand)s di ponsel",
"web_default_device_name": "%(appName)s: %(browserName)s di %(osName)s",
"welcome_to_element": "Selamat datang di Element"
}

View file

@ -20,12 +20,20 @@
"invalid_json_generic": "Ógilt JSON",
"misconfigured": "Element-tilvikið þitt er rangt stillt"
},
"failed_to_start": "Mistókst að ræsa",
"go_to_element_io": "Fara á element.io",
"incompatible_browser": {
"browser_links": "Þú ættir að setja upp <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, eða <safariLink>Safari</safariLink> til að fá sem besta útkomu.",
"continue_warning": "Ég skil áhættuna og óska að halda áfram",
"feature_warning": "Þú getur haldið áfram að nota núverandi vafra, en sumir eða allir eiginleikar virka mögulega ekki rétt, auk þess sem útlit og hegðun forritsins geta verið röng.",
"features": "%(brand)s notar háþróaða vafraeiginleika sem eru ekki studdir af vafranum þínum.",
"summary": "Vafrinn þinn getur ekki keyrt %(brand)s",
"title": "Óstuddur vafri"
},
"powered_by_matrix": "Keyrt með Matrix",
"powered_by_matrix_with_logo": "Dreifstýrt, dulritað spjall og samskipti keyrt með $matrixLogo",
"unknown_device": "Óþekkt tæki",
"use_brand_on_mobile": "Nota %(brand)s í síma",
"web_default_device_name": "%(appName)s: %(browserName)s á %(osName)s",
"welcome_to_element": "Velkomin í Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "JSON non valido",
"misconfigured": "Il tuo elemento è configurato male"
},
"failed_to_start": "Avvio fallito",
"go_to_element_io": "Vai su element.io",
"incompatible_browser": {
"browser_links": "Installa <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, o <safariLink>Safari</safariLink> per una migliore esperienza.",
"continue_warning": "Capisco i rischi e desidero continuare",
"feature_warning": "Puoi comunque usare il browser attuale, ma alcune o tutte le caratteristiche potrebbero non funzionare e l'aspetto dell'applicazione potrebbe essere sbagliato.",
"features": "%(brand)s usa funzionalità avanzate del browser che non sono supportate dal tuo browser attuale.",
"summary": "Il tuo browser non può eseguire %(brand)s",
"title": "Browser non supportato"
},
"powered_by_matrix": "Offerto da Matrix",
"powered_by_matrix_with_logo": "Chat e collaborazioni criptate e decentralizzate offerte da $matrixLogo",
"unknown_device": "Dispositivo sconosciuto",
"use_brand_on_mobile": "Usa %(brand)s su mobile",
"web_default_device_name": "%(appName)s: %(browserName)s su %(osName)s",
"welcome_to_element": "Benvenuti su Element"
}

View file

@ -20,11 +20,19 @@
"invalid_json_generic": "不正なJSON",
"misconfigured": "Elementの設定が誤っています"
},
"failed_to_start": "起動に失敗しました",
"go_to_element_io": "element.ioへ移動",
"incompatible_browser": {
"browser_links": "最高のユーザー体験を得るためには、<chromeLink>Chrome</chromeLink>か<firefoxLink>Firefox</firefoxLink>、もしくは<safariLink>Safari</safariLink>をインストールしてください。",
"continue_warning": "リスクを理解して続行",
"feature_warning": "現在のブラウザーを使い続けることもできますが、いくつか(もしくは全ての)機能が動作しなかったり、外観が崩れたりする可能性があります。",
"features": "%(brand)sはブラウザーの高度な機能を使う必要がありますが、このブラウザーではその機能がサポートされていないようです。",
"summary": "このブラウザーでは%(brand)sが動きません",
"title": "サポートされていないブラウザー"
},
"powered_by_matrix_with_logo": "$matrixLogo による、分散型で暗号化された会話とコラボレーション",
"unknown_device": "不明な端末",
"use_brand_on_mobile": "携帯端末で%(brand)sを使用できます",
"web_default_device_name": "%(appName)s %(osName)sの%(browserName)s",
"welcome_to_element": "Elementにようこそ"
}

View file

@ -19,11 +19,19 @@
"invalid_json_generic": "JSON ບໍ່ຖືກຕ້ອງ",
"misconfigured": "ການຕັ້ງຄ່າແອັບ Element ຂອງທ່ານບໍ່ຖືກຕ້ອງ"
},
"failed_to_start": "ບໍ່ສາມາດເປີດໄດ້",
"go_to_element_io": "ໄປຫາ element.io",
"incompatible_browser": {
"browser_links": "ກະລຸນາຕິດຕັ້ງ <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> ສຳລັບປະສົບການທີ່ດີທີ່ສຸດ.",
"continue_warning": "ຂ້າພະເຈົ້າເຂົ້າໃຈຄວາມສ່ຽງ ແລະຢາກສືບຕໍ່",
"feature_warning": "ທ່ານສາມາດສືບຕໍ່ນຳໃຊ້ບຣາວເຊີປັດຈຸບັນຂອງເຈົ້າໄດ້, ແຕ່ບາງຄຸນສົມບັດ ຫຼື ທັງໝົດອາດຈະບໍ່ເຮັດວຽກ ແລະ ລັກສະນະ ແລະ ຄວາມຮູ້ສຶກຂອງແອັບພລິເຄຊັນອາດບໍ່ຖືກຕ້ອງ.",
"features": "%(brand)s ໃຊ້ຄຸນສົມບັດຂອງບຣາວເຊີຂັ້ນສູງທີ່ບຼາວເຊີປັດຈຸບັນຂອງທ່ານຍັງບໍ່ຮອງຮັບ.",
"summary": "ບຣາວເຊີຂອງທ່ານບໍ່ສາມາດແລ່ນ %(brand)s ໄດ້",
"title": "ບໍ່ຮັບຮອງເວັບບຣາວເຊີນີ້"
},
"powered_by_matrix": "ສະໜັບສະໜູນໂດຍ Matrix",
"powered_by_matrix_with_logo": "ການສົນທະນາແບບເຂົ້າລະຫັດ ແລະກະຈ່າຍການຄຸ້ມຄອງ &amp; ການຮ່ວມມື້ ແລະສະໜັບສະໜູນໂດຍ $matrixLogo",
"unknown_device": "ທີ່ບໍ່ຮູ້ຈັກອຸປະກອນນີ້",
"use_brand_on_mobile": "ໃຊ້ມືຖື %(brand)s",
"welcome_to_element": "ຍິນດີຕ້ອນຮັບ"
}

View file

@ -20,11 +20,19 @@
"invalid_json_generic": "Klaidingas JSON",
"misconfigured": "Jūsų Element yra neteisingai sukonfigūruotas"
},
"failed_to_start": "Nepavyko paleisti",
"go_to_element_io": "Eiti į element.io",
"incompatible_browser": {
"browser_links": "Geriausiam veikimui suinstaliuokite <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, arba <safariLink>Safari</safariLink>.",
"continue_warning": "Suprantu šią riziką ir noriu tęsti",
"feature_warning": "Jūs galite toliau naudotis savo dabartine naršykle, bet kai kurios arba visos funkcijos gali neveikti ir programos išvaizda bei sąsaja gali būti neteisingai rodoma.",
"features": "%(brand)s naudoja išplėstines naršyklės funkcijas, kurių jūsų dabartinė naršyklė nepalaiko.",
"summary": "Jūsų naršyklė negali paleisti %(brand)s",
"title": "Nepalaikoma naršyklė"
},
"powered_by_matrix": "Veikia su Matrix",
"powered_by_matrix_with_logo": "Decentralizuotas, užšifruotų pokalbių &amp; bendradarbiavimas, paremtas $matrixLogo",
"unknown_device": "Nežinomas įrenginys",
"use_brand_on_mobile": "Naudoti %(brand)s mobiliajame telefone",
"welcome_to_element": "Sveiki atvykę į Element"
}

View file

@ -19,12 +19,20 @@
"invalid_json_generic": "Ongeldige JSON",
"misconfigured": "Jouw Element is verkeerd geconfigureerd"
},
"failed_to_start": "Opstarten mislukt",
"go_to_element_io": "Ga naar element.io",
"incompatible_browser": {
"browser_links": "Installeer <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, of <safariLink>Safari</safariLink> voor de beste gebruikservaring.",
"continue_warning": "Ik begrijp de risico's en wil verder gaan",
"feature_warning": "Je kan je huidige browser blijven gebruiken, maar sommige of alle functies zouden niet kunnen werken en de weergave van het programma kan verkeerd zijn.",
"features": "%(brand)s gebruikt geavanceerde functies die niet ondersteund worden in je huidige browser.",
"summary": "Jouw browser kan %(brand)s niet starten",
"title": "Niet-ondersteunde browser"
},
"powered_by_matrix": "Mogelijk gemaakt door Matrix",
"powered_by_matrix_with_logo": "Gedecentraliseerde, versleutelde chat &amp; samenwerking mogelijk gemaakt door $matrixLogo",
"unknown_device": "Onbekend apparaat",
"use_brand_on_mobile": "Gebruik %(brand)s op je mobiel",
"web_default_device_name": "%(appName)s: %(browserName)s op %(osName)s",
"welcome_to_element": "Welkom bij Element"
}

View file

@ -21,24 +21,20 @@
"invalid_json_generic": "Błędny JSON",
"misconfigured": "Twój Element jest nieprawidłowo skonfigurowany"
},
"failed_to_start": "Nie udało się wystartować",
"go_to_element_io": "Przejdź do element.io",
"incompatible_browser": {
"continue": "Kontynuuj mimo to",
"description": "%(brand)s korzysta z niektórych funkcji, które nie są obecnie dostępne w Twojej przeglądarce. %(detail)s",
"detail_can_continue": "Jeśli kontynuujesz, niektóre funkcje mogą przestać działać, jak i istnieje ryzyko utraty danych w przyszłości.",
"detail_no_continue": "Zaktualizuj przeglądarkę, jeśli jeszcze tego nie zrobiłeś i spróbuj ponownie.",
"learn_more": "Dowiedz się więcej",
"linux": "Linux",
"macos": "Mac",
"supported_browsers": "Dla najlepszego doświadczenia korzystaj z <Chrome>Chrome</Chrome>, <Firefox>Firefox</Firefox>, <Edge>Edge</Edge> lub <Safari>Safari</Safari>.",
"title": "%(brand)s nie wspiera tej przeglądarki",
"use_desktop_heading": "Zamiast tego użyj %(brand)s Desktop",
"use_mobile_heading": "Zamiast tego użyj %(brand)s Mobile",
"use_mobile_heading_after_desktop": "lub skorzystaj z naszej aplikacji mobilnej",
"windows": "Windows (%(bits)s-bit)"
"browser_links": "Zainstaluj <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, lub <safariLink>Safari</safariLink> w celu zapewnienia najlepszego działania.",
"continue_warning": "Rozumiem ryzyko i chcę kontynuować",
"feature_warning": "Możesz kontynuować używając obecnej przeglądarki, lecz niektóre lub wszystkie funkcje mogą nie działać oraz wygląd aplikacji może być niepoprawny.",
"features": "%(brand)s używa funkcji zaawansowanych, które nie są dostępne w Twojej przeglądarce.",
"summary": "Twoja przeglądarka nie obsługuje %(brand)s",
"title": "Niewspierana przeglądarka"
},
"powered_by_matrix": "Zasilane przez Matrix",
"powered_by_matrix_with_logo": "Zdecentralizowany czat szyfrowany i współpraca oparta na $matrixLogo",
"unknown_device": "Nieznane urządzenie",
"use_brand_on_mobile": "Użyj %(brand)s w telefonie",
"web_default_device_name": "%(appName)s: %(browserName)s na %(osName)s",
"welcome_to_element": "Witamy w Element"
}

View file

@ -19,11 +19,19 @@
"invalid_json_generic": "JSON inválido",
"misconfigured": "Seu Element está mal configurado"
},
"failed_to_start": "Falha para iniciar",
"go_to_element_io": "Ir para element.io",
"incompatible_browser": {
"browser_links": "Por favor instale <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, ou <safariLink>Safari</safariLink> para a melhor experiência.",
"continue_warning": "Eu entendo os riscos e desejo continuar",
"feature_warning": "Você pode continuar usando seu browser atual, mas alguma ou toda funcionalidade pode não funcionar e a aparência e sensação do aplicativo pode estar incorretas.",
"features": "%(brand)s usa funcionalidade de browser avançada que não é suportada por seu browser atual.",
"summary": "Seu browser não consegue rodar %(brand)s",
"title": "Browser insuportado"
},
"powered_by_matrix_with_logo": "Chat descentralizado e encriptado & colaboração, powered by $matrixLogo",
"unknown_device": "Dispositivo desconhecido",
"use_brand_on_mobile": "Usar %(brand)s em celular",
"web_default_device_name": "%(appName)s: %(browserName)s em %(osName)s",
"welcome_to_element": "Boas-vindas a Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Неверный JSON",
"misconfigured": "Ваш Element неверно настроен"
},
"failed_to_start": "Старт не удался",
"go_to_element_io": "К element.io",
"incompatible_browser": {
"browser_links": "Пожалуйста поставьте <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, или <safariLink>Safari</safariLink> для лучшей совместимости.",
"continue_warning": "Я понимаю риск и хочу продолжить",
"feature_warning": "Вы можете продолжать пользоваться этим браузером, но некоторые возможности будут недоступны и интерфейс может быть отрисован неправильно.",
"features": "%(brand)s использует расширенные возможности, которые не поддерживаются вашим браузером.",
"summary": "Ваш браузер не может запустить %(brand)s",
"title": "Неподдерживаемый браузер"
},
"powered_by_matrix": "На технологии Matrix",
"powered_by_matrix_with_logo": "Децентрализованное, зашифрованное общение и сотрудничество на основе $matrixLogo",
"unknown_device": "Неизвестное устройство",
"use_brand_on_mobile": "Воспользуйтесь %(brand)s на мобильном телефоне",
"web_default_device_name": "%(appName)s: %(browserName)s на %(osName)s",
"welcome_to_element": "Добро пожаловать в Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Neplatný JSON",
"misconfigured": "Váš Element je nesprávne nastavený"
},
"failed_to_start": "Spustenie zlyhalo",
"go_to_element_io": "Prejsť na element.io",
"incompatible_browser": {
"browser_links": "Prosím, nainštalujte si <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink> alebo <safariLink>Safari</safariLink> pre najlepší zážitok.",
"continue_warning": "Rozumiem riziku a chcem pokračovať",
"feature_warning": "Môžete naďalej používať váš súčasný prehliadač, ale niektoré alebo všetky funkcie nemusia fungovať a zážitok z aplikácie nemusí byť optimálny.",
"features": "%(brand)s používa pokročilé funkcie prehliadača, ktoré nie sú podporované vaším aktuálnym prehliadačom.",
"summary": "Váš prehliadač nedokáže spustiť %(brand)s",
"title": "Nepodporovaný prehliadač"
},
"powered_by_matrix": "používa protokol Matrix",
"powered_by_matrix_with_logo": "Decentralizované, šifrované konverzácie a spolupráca na platforme $matrixLogo",
"unknown_device": "Neznáme zariadenie",
"use_brand_on_mobile": "Používať %(brand)s na mobilnom zariadení",
"web_default_device_name": "%(appName)s: %(browserName)s na %(osName)s",
"welcome_to_element": "Víta vás Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "JSON i pavlefshëm",
"misconfigured": "Element-i juaj është i keqformësuar"
},
"failed_to_start": "Su arrit të nisej",
"go_to_element_io": "Shko te element.io",
"incompatible_browser": {
"browser_links": "Ju lutemi, për funksionimin më të mirë, instaloni <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, ose <safariLink>Safari</safariLink>.",
"continue_warning": "I kuptoj rreziqet dhe dëshiroj të vazhdoj",
"feature_warning": "Mund të vazhdoni të përdorni shfletuesin tuaj të tanishëm, por disa ose krejt veçoritë mund të mos funksionojnë dhe pamja dhe ndjesitë prej aplikacionit të mos jenë të sakta.",
"features": "%(brand)s përdor veçori të thelluara të shfletuesit, të cilat shfletuesi juaj i tanishëm si mbulon.",
"summary": "Shfletuesi juaj smund të xhirojë %(brand)s",
"title": "Shfletues i pambuluar"
},
"powered_by_matrix": "Bazuar në Matrix",
"powered_by_matrix_with_logo": "Fjalosje &amp; bashkëpunim i decentralizuar, i fshehtëzuar, bazuar në $matrixLogo",
"unknown_device": "Pajisje e panjohur",
"use_brand_on_mobile": "Përdor %(brand)s në celular",
"web_default_device_name": "%(appName)s: %(browserName)s në %(osName)s",
"welcome_to_element": "Mirë se vini te Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Ogiltig JSON",
"misconfigured": "Din Element är felkonfigurerad"
},
"failed_to_start": "Misslyckade att starta",
"go_to_element_io": "Gå till element.io",
"incompatible_browser": {
"browser_links": "Installera <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, eller <safariLink>Safari</safariLink> för den bästa upplevelsen.",
"continue_warning": "Jag förstår riskerna och vill fortsätta",
"feature_warning": "Du kan fortsätta använda din nuvarande webbläsare, men vissa eller alla funktioner kanske inte fungerar och utseendet och känslan av applikationen kan var felaktig.",
"features": "%(brand)s använder avancerade webbläsarfunktioner som inte stöds av din aktuella webbläsare.",
"summary": "Din webbläsare kan inte köra %(brand)s",
"title": "Webbläsaren stöds ej"
},
"powered_by_matrix": "Drivs av Matrix",
"powered_by_matrix_with_logo": "Decentraliserad krypterad chatt &amp; samarbete som drivs av $matrixLogo",
"unknown_device": "Okänd enhet",
"use_brand_on_mobile": "Använd %(brand)s på mobilen",
"web_default_device_name": "%(appName)s: %(browserName)s på %(osName)s",
"welcome_to_element": "Välkommen till Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "Хибний JSON",
"misconfigured": "Ваш Element налаштовано неправильно"
},
"failed_to_start": "Не вдалося запустити",
"go_to_element_io": "Перейти на element.io",
"incompatible_browser": {
"browser_links": "Для найкращих вражень від користування встановіть, будь ласка, <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, або <safariLink>Safari</safariLink>.",
"continue_warning": "Я усвідомлюю ризик і бажаю продовжити",
"feature_warning": "Ви можете продовжити, користуючись вашим поточним браузером, але деякі функції можуть не працювати, а застосунок може виглядати неправильно.",
"features": "%(brand)s використовує передові властивості, які ваш браузер не підтримує.",
"summary": "Ваш браузер не може запустити %(brand)s",
"title": "Непідтримуваний браузер"
},
"powered_by_matrix": "Працює на Matrix",
"powered_by_matrix_with_logo": "Децентралізована, зашифрована бесіда та співпраця на основі $matrixLogo",
"unknown_device": "Невідомий пристрій",
"use_brand_on_mobile": "Користуйтеся %(brand)s на мобільному",
"web_default_device_name": "%(appName)s: %(browserName)s на %(osName)s",
"welcome_to_element": "Ласкаво просимо до Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "JSON không hợp lệ",
"misconfigured": "Element đang bị thiết lập sai"
},
"failed_to_start": "Không khởi động được",
"go_to_element_io": "Qua element.io",
"incompatible_browser": {
"browser_links": "Hãy cài đặt <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, hoặc <safariLink>Safari</safariLink> để có trải nghiệm tốt nhất.",
"continue_warning": "Tôi hiểu rủi ro và muốn tiếp tục",
"feature_warning": "Bạn có thể tiếp tục sử dụng trình duyệt hiện tại, tuy nhiên các tính năng có thể sẽ không hoạt động và trải nghiệm ứng dụng có thể sẽ không được tốt.",
"features": "%(brand)s sử dụng một số tính năng nâng cao mà trình duyệt của bạn không thể đáp ứng.",
"summary": "Trình duyệt của bạn không thể chạy %(brand)s",
"title": "Trình duyệt không được hỗ trợ"
},
"powered_by_matrix": "Chạy trên giao thức Matrix",
"powered_by_matrix_with_logo": "Dịch vụ nhắn tin &amp; liên lạc được mã hóa, phi tập trung. Được vận hành trên $matrixLogo",
"unknown_device": "Thiết bị không xác định",
"use_brand_on_mobile": "Sử dụng %(brand)s trên di động",
"web_default_device_name": "%(appName)s: %(browserName)s trên %(osName)s",
"welcome_to_element": "Chào mừng tới Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "无效的 JSON",
"misconfigured": "Element 配置错误"
},
"failed_to_start": "启动失败",
"go_to_element_io": "前往 element.io",
"incompatible_browser": {
"browser_links": "请安装 <chromeLink>Chrome</chromeLink>、<firefoxLink>Firefox</firefoxLink> 或 <safariLink>Safari</safariLink> 以获得最佳体验。",
"continue_warning": "我了解风险并希望继续",
"feature_warning": "您可以继续使用您目前的浏览器,但部分或全部功能可能无法正常工作,应用程序的外观可能也看起来不正确。",
"features": "当前浏览器不支持 %(brand)s 所需的高级浏览器特性。",
"summary": "你的浏览器无法运行 %(brand)s",
"title": "不支持的浏览器"
},
"powered_by_matrix": "由 Matrix 驱动",
"powered_by_matrix_with_logo": "去中心化、加密的聊天与协作,由 $matrixLogo 驱动",
"unknown_device": "未知设备",
"use_brand_on_mobile": "在移动设备上使用 %(brand)s",
"web_default_device_name": "%(appName)s%(browserName)s在%(osName)s",
"welcome_to_element": "欢迎来到 Element"
}

View file

@ -21,12 +21,20 @@
"invalid_json_generic": "無效的 JSON",
"misconfigured": "您的 Element 設定錯誤"
},
"failed_to_start": "啟動失敗",
"go_to_element_io": "前往 element.io",
"incompatible_browser": {
"browser_links": "請安裝 <chromeLink>Chrome</chromeLink>、<firefoxLink>Firefox</firefoxLink> 或 <safariLink>Safari</safariLink> 以取得最佳體驗。",
"continue_warning": "我了解風險並希望繼續",
"feature_warning": "您可以繼續使用目前的瀏覽器,但部份或全部的功能可能會無法運作,而應用程式的外觀與感覺可能也可能不正確。",
"features": "%(brand)s 使用了您目前瀏覽器不支援的進階功能。",
"summary": "您的瀏覽器無法執行 %(brand)s",
"title": "不支援的瀏覽器"
},
"powered_by_matrix": "由Matrix支持",
"powered_by_matrix_with_logo": "由 $matrixLogo 驅動的去中心化、加密的聊天與協作工具",
"unknown_device": "未知裝置",
"use_brand_on_mobile": "在行動裝置上使用 %(brand)s",
"web_default_device_name": "%(appName)s%(osName)s 的 %(browserName)s",
"welcome_to_element": "歡迎使用 Element"
}

View file

@ -1,188 +0,0 @@
/*
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;
};
} = {};
global.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());
});
global.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).
global.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 global.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();
console.log(`[ServiceWorker] /versions response for '${clientApiUrl}': ${JSON.stringify(versions)}`);
serverSupportMap[clientApiUrl] = {
supportsAuthedMedia: Boolean(versions?.versions?.includes("v1.11")),
cacheExpiryTimeMs: new Date().getTime() + 2 * 60 * 60 * 1000, // 2 hours from now
};
console.log(
`[ServiceWorker] serverSupportMap update for '${clientApiUrl}': ${JSON.stringify(serverSupportMap[clientApiUrl])}`,
);
}
// 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.
global.removeEventListener("message", listener); // cleanup, since we're not going to do anything else.
};
global.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}`,
},
};
}

Some files were not shown because too many files have changed in this diff Show more