mirror of
https://github.com/element-hq/element-web.git
synced 2025-12-05 01:10:40 +00:00
Compare commits
56 Commits
andybalaam
...
matthew/sh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47d12136b7 | ||
|
|
e121377bcf | ||
|
|
5b9944474c | ||
|
|
2f72104302 | ||
|
|
a713b5c9b6 | ||
|
|
a597cd0d6f | ||
|
|
1f9ee07b02 | ||
|
|
46dbb8159d | ||
|
|
be5dd058b3 | ||
|
|
2326a7c8dc | ||
|
|
0bee6ef187 | ||
|
|
c52ec3efd1 | ||
|
|
0bee060dbc | ||
|
|
302baa061f | ||
|
|
785a12a029 | ||
|
|
c9548ec1d0 | ||
|
|
fadd54f0b3 | ||
|
|
6ac66da5eb | ||
|
|
8be05f0ad9 | ||
|
|
5faae73055 | ||
|
|
32dfabbcb6 | ||
|
|
972366b5ae | ||
|
|
597a0d25ac | ||
|
|
fe8d5aee63 | ||
|
|
900fa53a33 | ||
|
|
706d929f3a | ||
|
|
2b5f687c40 | ||
|
|
501c8194e5 | ||
|
|
16d57074df | ||
|
|
c84cf3c36c | ||
|
|
e235100dd0 | ||
|
|
10757b4357 | ||
|
|
64047b0702 | ||
|
|
0d5a8aafbd | ||
|
|
fb5c4ffc8b | ||
|
|
308f892cef | ||
|
|
54a00baff8 | ||
|
|
08acbf9b14 | ||
|
|
a3f5d207de | ||
|
|
0f783ede5e | ||
|
|
e427b71040 | ||
|
|
d553be6316 | ||
|
|
6063209fff | ||
|
|
36d25da288 | ||
|
|
74fbd892a1 | ||
|
|
6ba21dafa7 | ||
|
|
8ac2f60720 | ||
|
|
64f0dfe0bc | ||
|
|
a728385385 | ||
|
|
d9926c8784 | ||
|
|
186f7e71be | ||
|
|
9eb90a8204 | ||
|
|
21e79710c6 | ||
|
|
0948475192 | ||
|
|
9f560f1f89 | ||
|
|
8e3fb5288b |
6
.github/workflows/build.yml
vendored
6
.github/workflows/build.yml
vendored
@@ -43,9 +43,9 @@ jobs:
|
||||
run:
|
||||
shell: bash
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
# Disable cache on Windows as it is slower than not caching
|
||||
# https://github.com/actions/setup-node/issues/975
|
||||
@@ -77,7 +77,7 @@ jobs:
|
||||
yarn build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: webapp-${{ matrix.image }}
|
||||
path: webapp
|
||||
|
||||
4
.github/workflows/build_debian.yaml
vendored
4
.github/workflows/build_debian.yaml
vendored
@@ -14,7 +14,7 @@ jobs:
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
VERSION: ${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- name: Download package
|
||||
run: |
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
dpkg-gencontrol -v"$VERSION" -ldebian/tmp/DEBIAN/changelog
|
||||
dpkg-deb -Zxz --root-owner-group --build debian/tmp element-web.deb
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: element-web.deb
|
||||
path: element-web.deb
|
||||
|
||||
6
.github/workflows/build_develop.yml
vendored
6
.github/workflows/build_develop.yml
vendored
@@ -26,9 +26,9 @@ jobs:
|
||||
R2_URL: ${{ vars.CF_R2_S3_API }}
|
||||
R2_PUBLIC_URL: "https://element-web-develop.element.io"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
@@ -53,7 +53,7 @@ jobs:
|
||||
|
||||
- run: mv dist/element-*.tar.gz dist/develop.tar.gz
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: webapp
|
||||
path: dist/develop.tar.gz
|
||||
|
||||
2
.github/workflows/deploy.yml
vendored
2
.github/workflows/deploy.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
env:
|
||||
SITE: ${{ inputs.site || 'staging.element.io' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- name: Load GPG key
|
||||
run: |
|
||||
|
||||
2
.github/workflows/docker.yaml
vendored
2
.github/workflows/docker.yaml
vendored
@@ -20,7 +20,7 @@ jobs:
|
||||
env:
|
||||
TEST_TAG: vectorim/element-web:test
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
fetch-depth: 0 # needed for docker-package to be able to calculate the version
|
||||
|
||||
|
||||
14
.github/workflows/docs.yml
vendored
14
.github/workflows/docs.yml
vendored
@@ -17,23 +17,23 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Fetch element-desktop
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
path: element-desktop
|
||||
|
||||
- name: Fetch element-web
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
path: element-web
|
||||
|
||||
- name: Fetch matrix-js-sdk
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
path: matrix-js-sdk
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: element-web/yarn.lock
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
echo "- [Automations](automations.md)" >> docs/SUMMARY.md
|
||||
|
||||
- name: Setup mdBook
|
||||
uses: peaceiris/actions-mdbook@v2
|
||||
uses: peaceiris/actions-mdbook@ee69d230fe19748b7abf22df32acaa93833fad08 # v2
|
||||
with:
|
||||
mdbook-version: "0.4.10"
|
||||
|
||||
@@ -88,7 +88,7 @@ jobs:
|
||||
run: mdbook build
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3
|
||||
with:
|
||||
path: ./book
|
||||
|
||||
@@ -104,4 +104,4 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
actions: read
|
||||
steps:
|
||||
- name: Download HTML report
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
path: playwright-report
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@v3
|
||||
uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3
|
||||
with:
|
||||
path: playwright-report
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
|
||||
26
.github/workflows/end-to-end-tests.yaml
vendored
26
.github/workflows/end-to-end-tests.yaml
vendored
@@ -50,11 +50,11 @@ jobs:
|
||||
runners-matrix: ${{ steps.runner-vars.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
yarn build
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
@@ -89,7 +89,7 @@ jobs:
|
||||
|
||||
- name: Calculate runner variables
|
||||
id: runner-vars
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
const numRunners = parseInt(process.env.NUM_RUNNERS, 10);
|
||||
@@ -129,18 +129,18 @@ jobs:
|
||||
- runAllTests: false
|
||||
project: Pinecone
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
name: webapp
|
||||
path: webapp
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
cache-dependency-path: yarn.lock
|
||||
@@ -154,7 +154,7 @@ jobs:
|
||||
run: echo "version=$(yarn list --pattern @playwright/test --depth=0 --json --non-interactive --no-progress | jq -r '.data.trees[].name')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache playwright binaries
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
|
||||
id: playwright-cache
|
||||
with:
|
||||
path: |
|
||||
@@ -180,7 +180,7 @@ jobs:
|
||||
|
||||
- name: Upload blob report to GitHub Actions Artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: all-blob-reports-${{ matrix.project }}-${{ matrix.runner }}
|
||||
path: blob-report
|
||||
@@ -192,13 +192,13 @@ jobs:
|
||||
if: always()
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
if: inputs.skip != true
|
||||
with:
|
||||
persist-credentials: false
|
||||
repository: element-hq/element-web
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
if: inputs.skip != true
|
||||
with:
|
||||
cache: "yarn"
|
||||
@@ -210,7 +210,7 @@ jobs:
|
||||
|
||||
- name: Download blob reports from GitHub Actions Artifacts
|
||||
if: inputs.skip != true
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
pattern: all-blob-reports-*
|
||||
path: all-blob-reports
|
||||
@@ -226,7 +226,7 @@ jobs:
|
||||
# Upload the HTML report even if one of our reporters fails, this can happen when stale screenshots are detected
|
||||
- name: Upload HTML report
|
||||
if: always() && inputs.skip != true
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: html-report
|
||||
path: playwright-report
|
||||
|
||||
4
.github/workflows/issue_closed.yml
vendored
4
.github/workflows/issue_closed.yml
vendored
@@ -10,7 +10,7 @@ jobs:
|
||||
name: Tidy closed issues
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
id: main
|
||||
with:
|
||||
# PAT needed as the GITHUB_TOKEN won't be able to see cross-references from other orgs (matrix-org)
|
||||
@@ -142,7 +142,7 @@ jobs:
|
||||
});
|
||||
}
|
||||
}
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
name: Close duplicate as Not Planned
|
||||
if: steps.main.outputs.closeAsNotPlanned
|
||||
with:
|
||||
|
||||
4
.github/workflows/netlify.yaml
vendored
4
.github/workflows/netlify.yaml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
Exercise caution. Use test accounts.
|
||||
|
||||
- name: 📥 Download artifact
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
@@ -36,7 +36,7 @@ jobs:
|
||||
path: webapp
|
||||
|
||||
- name: 📤 Deploy to Netlify
|
||||
uses: matrix-org/netlify-pr-preview@v3
|
||||
uses: matrix-org/netlify-pr-preview@9805cd123fc9a7e421e35340a05e1ebc5dee46b5 # v3
|
||||
with:
|
||||
path: webapp
|
||||
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
|
||||
|
||||
2
.github/workflows/pending-reviews.yaml
vendored
2
.github/workflows/pending-reviews.yaml
vendored
@@ -16,7 +16,7 @@ jobs:
|
||||
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+"
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
|
||||
@@ -10,7 +10,7 @@ jobs:
|
||||
permissions:
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- name: Update synapse image
|
||||
run: |
|
||||
|
||||
@@ -8,7 +8,7 @@ jobs:
|
||||
name: Check PR base branch
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
const baseBranch = context.payload.pull_request.base.ref;
|
||||
|
||||
6
.github/workflows/release_prepare.yml
vendored
6
.github/workflows/release_prepare.yml
vendored
@@ -41,7 +41,7 @@ jobs:
|
||||
REPOS: matrix-js-sdk element-web element-desktop
|
||||
steps:
|
||||
- name: Checkout Element Desktop
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
if: inputs.element-desktop
|
||||
with:
|
||||
repository: element-hq/element-desktop
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Element Web
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
if: inputs.element-web
|
||||
with:
|
||||
repository: element-hq/element-web
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
fetch-tags: true
|
||||
token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- name: Checkout Matrix JS SDK
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
if: inputs.matrix-js-sdk
|
||||
with:
|
||||
repository: matrix-org/matrix-js-sdk
|
||||
|
||||
22
.github/workflows/static_analysis.yaml
vendored
22
.github/workflows/static_analysis.yaml
vendored
@@ -23,9 +23,9 @@ jobs:
|
||||
name: "Typescript Syntax Check"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
@@ -57,7 +57,7 @@ jobs:
|
||||
name: "Rethemendex Check"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- run: ./res/css/rethemendex.sh
|
||||
|
||||
@@ -67,9 +67,9 @@ jobs:
|
||||
name: "ESLint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
@@ -85,9 +85,9 @@ jobs:
|
||||
name: "Style Lint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
@@ -103,9 +103,9 @@ jobs:
|
||||
name: "Workflow Lint"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
@@ -121,9 +121,9 @@ jobs:
|
||||
name: "Analyse Dead Code"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
8
.github/workflows/tests.yml
vendored
8
.github/workflows/tests.yml
vendored
@@ -39,12 +39,12 @@ jobs:
|
||||
runner: [1, 2]
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
with:
|
||||
repository: ${{ inputs.matrix-js-sdk-sha && 'element-hq/element-web' || github.repository }}
|
||||
|
||||
- name: Yarn cache
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
node-version: "lts/*"
|
||||
cache: "yarn"
|
||||
@@ -55,7 +55,7 @@ jobs:
|
||||
JS_SDK_GITHUB_BASE_REF: ${{ inputs.matrix-js-sdk-sha }}
|
||||
|
||||
- name: Jest Cache
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4
|
||||
with:
|
||||
path: /tmp/jest_cache
|
||||
key: ${{ hashFiles('**/yarn.lock') }}
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
|
||||
- name: Upload Artifact
|
||||
if: env.ENABLE_COVERAGE == 'true'
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
||||
with:
|
||||
name: coverage-${{ matrix.runner }}
|
||||
path: |
|
||||
|
||||
16
.github/workflows/triage-labelled.yml
vendored
16
.github/workflows/triage-labelled.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'good first issue') ||
|
||||
contains(github.event.issue.labels.*.name, 'Hacktoberfest')
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
@@ -61,7 +61,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
@@ -84,7 +84,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'Z-Flaky-Test')
|
||||
steps:
|
||||
- id: add_to_project
|
||||
uses: actions/add-to-project@v1.0.2
|
||||
uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2
|
||||
with:
|
||||
project-url: ${{ env.PROJECT_URL }}
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
@@ -150,15 +150,15 @@ jobs:
|
||||
project-url: https://github.com/orgs/element-hq/projects/41
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
verticals_feature:
|
||||
name: Add labelled issues to Verticals Feature project
|
||||
crypto:
|
||||
name: Add labelled issues to Crypto project
|
||||
runs-on: ubuntu-24.04
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'Team: Verticals Feature')
|
||||
contains(github.event.issue.labels.*.name, 'Team: Crypto')
|
||||
steps:
|
||||
- uses: actions/add-to-project@main
|
||||
with:
|
||||
project-url: https://github.com/orgs/element-hq/projects/57
|
||||
project-url: https://github.com/orgs/element-hq/projects/76
|
||||
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
tech_debt:
|
||||
|
||||
2
.github/workflows/triage-stale.yml
vendored
2
.github/workflows/triage-stale.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v9
|
||||
- uses: actions/stale@5bef64f19d7facfb25b37b414482c7164d639639 # v9
|
||||
with:
|
||||
operations-per-run: 100
|
||||
# Flaky test issue closing
|
||||
|
||||
2
.github/workflows/triage-unlabelled.yml
vendored
2
.github/workflows/triage-unlabelled.yml
vendored
@@ -62,7 +62,7 @@ jobs:
|
||||
contains(github.event.issue.labels.*.name, 'A-Element-Call')) &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-Labs')
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
|
||||
4
.github/workflows/update-jitsi.yml
vendored
4
.github/workflows/update-jitsi.yml
vendored
@@ -9,9 +9,9 @@ jobs:
|
||||
update:
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
|
||||
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
|
||||
with:
|
||||
cache: "yarn"
|
||||
node-version: "lts/*"
|
||||
|
||||
2
.github/workflows/update-topics.yaml
vendored
2
.github/workflows/update-topics.yaml
vendored
@@ -22,7 +22,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
environment: Matrix
|
||||
steps:
|
||||
- uses: actions/github-script@v7
|
||||
- uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7
|
||||
env:
|
||||
HS_URL: ${{ secrets.BETABOT_HS_URL }}
|
||||
LOBBY_ROOM_ID: ${{ secrets.ROOM_ID }}
|
||||
|
||||
23
CHANGELOG.md
23
CHANGELOG.md
@@ -1,3 +1,26 @@
|
||||
Changes in [1.11.100](https://github.com/element-hq/element-web/releases/tag/v1.11.100) (2025-05-06)
|
||||
====================================================================================================
|
||||
## ✨ Features
|
||||
|
||||
* Move rich topics out of labs / stabilise MSC3765 ([#29817](https://github.com/element-hq/element-web/pull/29817)). Contributed by @Johennes.
|
||||
* Spell out that Element Web does \*not\* work on mobile. ([#29211](https://github.com/element-hq/element-web/pull/29211)). Contributed by @ara4n.
|
||||
* Add message preview support to the new room list ([#29784](https://github.com/element-hq/element-web/pull/29784)). Contributed by @dbkr.
|
||||
* Global configuration flag for media previews ([#29582](https://github.com/element-hq/element-web/pull/29582)). Contributed by @Half-Shot.
|
||||
* New room list: add partial keyboard shortcuts support ([#29783](https://github.com/element-hq/element-web/pull/29783)). Contributed by @florianduros.
|
||||
* MVVM RoomSummaryCard Topic ([#29710](https://github.com/element-hq/element-web/pull/29710)). Contributed by @MarcWadai.
|
||||
* Warn on self change from settings > roles ([#28926](https://github.com/element-hq/element-web/pull/28926)). Contributed by @MarcWadai.
|
||||
* New room list: new visual for invitation ([#29773](https://github.com/element-hq/element-web/pull/29773)). Contributed by @florianduros.
|
||||
|
||||
## 🐛 Bug Fixes
|
||||
|
||||
* Fix incorrect display of the user info display name ([#29826](https://github.com/element-hq/element-web/pull/29826)). Contributed by @langleyd.
|
||||
* RoomListStore: Remove invite rooms on decline ([#29804](https://github.com/element-hq/element-web/pull/29804)). Contributed by @MidhunSureshR.
|
||||
* Fix the buttons not being displayed with long preview text ([#29811](https://github.com/element-hq/element-web/pull/29811)). Contributed by @dbkr.
|
||||
* New room list: fix missing/incorrect notification decoration ([#29796](https://github.com/element-hq/element-web/pull/29796)). Contributed by @florianduros.
|
||||
* New Room List: Prevent potential scroll jump/flicker when switching spaces ([#29781](https://github.com/element-hq/element-web/pull/29781)). Contributed by @MidhunSureshR.
|
||||
* New room list: fix incorrect decoration ([#29770](https://github.com/element-hq/element-web/pull/29770)). Contributed by @florianduros.
|
||||
|
||||
|
||||
Changes in [1.11.99](https://github.com/element-hq/element-web/releases/tag/v1.11.99) (2025-04-23)
|
||||
==================================================================================================
|
||||
No changes, just bumping the version to accommodate a new Element Desktop release
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# syntax=docker.io/docker/dockerfile:1.15-labs
|
||||
# syntax=docker.io/docker/dockerfile:1.15-labs@sha256:94edd5b349df43675bd6f542e2b9a24e7177432dec45fe3066bfcf2ab14c4355
|
||||
|
||||
# Builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye AS builder
|
||||
FROM --platform=$BUILDPLATFORM node:22-bullseye@sha256:ed0338dd02fd86861a59dc1cbc2e12152f3a93c4ce5933d347d6677232000dc7 AS builder
|
||||
|
||||
# Support custom branch of the js-sdk. This also helps us build images of element-web develop.
|
||||
ARG USE_CUSTOM_SDKS=false
|
||||
@@ -19,7 +19,7 @@ RUN /src/scripts/docker-package.sh
|
||||
RUN cp /src/config.sample.json /src/webapp/config.json
|
||||
|
||||
# App
|
||||
FROM nginxinc/nginx-unprivileged:alpine-slim
|
||||
FROM nginxinc/nginx-unprivileged:alpine-slim@sha256:0a49675e3e35cc2f89ce831f00f767af9c32df04f5a80167739fd32346f1fe99
|
||||
|
||||
# Need root user to install packages & manipulate the usr directory
|
||||
USER root
|
||||
|
||||
30
package.json
30
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "element-web",
|
||||
"version": "1.11.99",
|
||||
"version": "1.11.100",
|
||||
"description": "Element: the future of secure communication",
|
||||
"author": "New Vector Ltd.",
|
||||
"repository": {
|
||||
@@ -70,18 +70,18 @@
|
||||
"resolutions": {
|
||||
"**/pretty-format/react-is": "19.1.0",
|
||||
"@playwright/test": "1.52.0",
|
||||
"@types/react": "19.1.2",
|
||||
"@types/react-dom": "19.1.2",
|
||||
"oidc-client-ts": "3.2.0",
|
||||
"@types/react": "19.1.4",
|
||||
"@types/react-dom": "19.1.5",
|
||||
"oidc-client-ts": "3.2.1",
|
||||
"jwt-decode": "4.0.0",
|
||||
"caniuse-lite": "1.0.30001715",
|
||||
"testcontainers": "10.24.2",
|
||||
"caniuse-lite": "1.0.30001717",
|
||||
"testcontainers": "10.25.0",
|
||||
"wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0",
|
||||
"wrap-ansi": "npm:wrap-ansi@^7.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.12.5",
|
||||
"@element-hq/element-web-module-api": "^0.1.1",
|
||||
"@element-hq/element-web-module-api": "1.0.0",
|
||||
"@fontsource/inconsolata": "^5",
|
||||
"@fontsource/inter": "^5",
|
||||
"@formatjs/intl-segmenter": "^11.5.7",
|
||||
@@ -123,9 +123,9 @@
|
||||
"jsrsasign": "^11.0.0",
|
||||
"jszip": "^3.7.0",
|
||||
"katex": "^0.16.0",
|
||||
"linkify-react": "4.2.0",
|
||||
"linkify-string": "4.2.0",
|
||||
"linkifyjs": "4.2.0",
|
||||
"linkify-react": "4.3.1",
|
||||
"linkify-string": "4.3.1",
|
||||
"linkifyjs": "4.3.1",
|
||||
"lodash": "^4.17.21",
|
||||
"maplibre-gl": "^5.0.0",
|
||||
"matrix-encrypt-attachment": "^1.0.3",
|
||||
@@ -138,7 +138,7 @@
|
||||
"opus-recorder": "^8.0.3",
|
||||
"pako": "^2.0.3",
|
||||
"png-chunks-extract": "^1.0.0",
|
||||
"posthog-js": "1.236.7",
|
||||
"posthog-js": "1.240.6",
|
||||
"qrcode": "1.5.4",
|
||||
"re-resizable": "6.11.2",
|
||||
"react": "^19.0.0",
|
||||
@@ -212,11 +212,11 @@
|
||||
"@types/node-fetch": "^2.6.2",
|
||||
"@types/pako": "^2.0.0",
|
||||
"@types/qrcode": "^1.3.5",
|
||||
"@types/react": "19.1.2",
|
||||
"@types/react": "19.1.4",
|
||||
"@types/react-beautiful-dnd": "^13.0.0",
|
||||
"@types/react-dom": "19.1.2",
|
||||
"@types/react-dom": "19.1.5",
|
||||
"@types/react-transition-group": "^4.4.0",
|
||||
"@types/sanitize-html": "2.15.0",
|
||||
"@types/sanitize-html": "2.16.0",
|
||||
"@types/semver": "^7.5.8",
|
||||
"@types/tar-js": "^0.3.5",
|
||||
"@types/ua-parser-js": "^0.7.36",
|
||||
@@ -262,7 +262,7 @@
|
||||
"jest-raw-loader": "^1.0.1",
|
||||
"jsqr": "^1.4.0",
|
||||
"knip": "^5.36.2",
|
||||
"lint-staged": "^15.0.2",
|
||||
"lint-staged": "^16.0.0",
|
||||
"matrix-web-i18n": "^3.2.1",
|
||||
"mini-css-extract-plugin": "2.9.2",
|
||||
"minimist": "^1.2.6",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/node_modules/@types/react/index.d.ts b/node_modules/@types/react/index.d.ts
|
||||
index 2272032..18bd20a 100644
|
||||
index d3318dc..c2b2c77 100644
|
||||
--- a/node_modules/@types/react/index.d.ts
|
||||
+++ b/node_modules/@types/react/index.d.ts
|
||||
@@ -134,7 +134,7 @@ declare namespace React {
|
||||
@@ -11,7 +11,7 @@ index 2272032..18bd20a 100644
|
||||
|
||||
/**
|
||||
* Created by {@link createRef}, or {@link useRef} when passed `null`.
|
||||
@@ -941,7 +941,7 @@ declare namespace React {
|
||||
@@ -945,7 +945,7 @@ declare namespace React {
|
||||
context: unknown;
|
||||
|
||||
// Keep in sync with constructor signature of JSXElementConstructor and ComponentClass.
|
||||
@@ -20,7 +20,7 @@ index 2272032..18bd20a 100644
|
||||
|
||||
// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
|
||||
// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
|
||||
@@ -1113,7 +1113,7 @@ declare namespace React {
|
||||
@@ -1117,7 +1117,7 @@ declare namespace React {
|
||||
*/
|
||||
interface ComponentClass<P = {}, S = ComponentState> extends StaticLifecycle<P, S> {
|
||||
// constructor signature must match React.Component
|
||||
@@ -5,8 +5,11 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type Visibility } from "matrix-js-sdk/src/matrix";
|
||||
import { type Locator, type Page } from "@playwright/test";
|
||||
|
||||
import { expect, test } from "../../../element-web-test";
|
||||
import type { Locator, Page } from "@playwright/test";
|
||||
import { SettingLevel } from "../../../../src/settings/SettingLevel";
|
||||
|
||||
test.describe("Room list filters and sort", () => {
|
||||
test.use({
|
||||
@@ -39,6 +42,65 @@ test.describe("Room list filters and sort", () => {
|
||||
await app.closeNotificationToast();
|
||||
});
|
||||
|
||||
test("Tombstoned rooms are not shown even when they receive updates", async ({ page, app, bot }) => {
|
||||
// This bug shows up with this setting turned on
|
||||
await app.settings.setValue("Spaces.allRoomsInHome", null, SettingLevel.DEVICE, true);
|
||||
|
||||
/*
|
||||
We will first create a room named 'Old Room' and will invite the bot user to this room.
|
||||
We will also send a simple message in this room.
|
||||
*/
|
||||
const oldRoomId = await app.client.createRoom({ name: "Old Room" });
|
||||
await app.client.inviteUser(oldRoomId, bot.credentials.userId);
|
||||
await bot.joinRoom(oldRoomId);
|
||||
const response = await app.client.sendMessage(oldRoomId, "Hello!");
|
||||
|
||||
/*
|
||||
At this point, we haven't done anything interesting.
|
||||
So we expect 'Old Room' to show up in the room list.
|
||||
*/
|
||||
const roomListView = getRoomList(page);
|
||||
const oldRoomTile = roomListView.getByRole("gridcell", { name: "Open room Old Room" });
|
||||
await expect(oldRoomTile).toBeVisible();
|
||||
|
||||
/*
|
||||
Now let's tombstone 'Old Room'.
|
||||
First we create a new room ('New Room') with the predecessor set to the old room..
|
||||
*/
|
||||
const newRoomId = await bot.createRoom({
|
||||
name: "New Room",
|
||||
creation_content: {
|
||||
predecessor: {
|
||||
event_id: response.event_id,
|
||||
room_id: oldRoomId,
|
||||
},
|
||||
},
|
||||
visibility: "public" as Visibility,
|
||||
});
|
||||
|
||||
/*
|
||||
Now we can send the tombstone event itself to the 'Old Room'.
|
||||
*/
|
||||
await app.client.sendStateEvent(oldRoomId, "m.room.tombstone", {
|
||||
body: "This room has been replaced",
|
||||
replacement_room: newRoomId,
|
||||
});
|
||||
|
||||
// Let's join the replaced room.
|
||||
await app.client.joinRoom(newRoomId);
|
||||
|
||||
// We expect 'Old Room' to be hidden from the room list.
|
||||
await expect(oldRoomTile).not.toBeVisible();
|
||||
|
||||
/*
|
||||
Let's say some user in the 'Old Room' changes their display name.
|
||||
This will send events to the all the rooms including 'Old Room'.
|
||||
Nevertheless, the replaced room should not be shown in the room list.
|
||||
*/
|
||||
await bot.setDisplayName("MyNewName");
|
||||
await expect(oldRoomTile).not.toBeVisible();
|
||||
});
|
||||
|
||||
test.describe("Scroll behaviour", () => {
|
||||
test("should scroll to the top of list when filter is applied and active room is not in filtered list", async ({
|
||||
page,
|
||||
|
||||
@@ -43,7 +43,8 @@ test.describe("Room list", () => {
|
||||
await expect(roomListView.getByRole("gridcell", { name: "Open room room29" })).toBeVisible();
|
||||
await expect(roomListView).toMatchScreenshot("room-list.png");
|
||||
|
||||
await roomListView.hover();
|
||||
// Put focus on the room list
|
||||
await roomListView.getByRole("gridcell", { name: "Open room room29" }).click();
|
||||
// Scroll to the end of the room list
|
||||
await page.mouse.wheel(0, 1000);
|
||||
await expect(roomListView.getByRole("gridcell", { name: "Open room room0" })).toBeVisible();
|
||||
@@ -105,13 +106,10 @@ test.describe("Room list", () => {
|
||||
// It should make the room muted
|
||||
await page.getByRole("menuitem", { name: "Mute room" }).click();
|
||||
|
||||
// Remove hover on the room list item
|
||||
await roomListView.hover();
|
||||
|
||||
// Scroll to the bottom of the list
|
||||
await page.getByRole("grid", { name: "Room list" }).evaluate((e) => {
|
||||
e.scrollTop = e.scrollHeight;
|
||||
});
|
||||
// Put focus on the room list
|
||||
await roomListView.getByRole("gridcell", { name: "Open room room28" }).click();
|
||||
// Scroll to the end of the room list
|
||||
await page.mouse.wheel(0, 1000);
|
||||
|
||||
// The room decoration should have the muted icon
|
||||
await expect(roomItem.getByTestId("notification-decoration")).toBeVisible();
|
||||
@@ -129,7 +127,8 @@ test.describe("Room list", () => {
|
||||
|
||||
test("should scroll to the current room", async ({ page, app, user }) => {
|
||||
const roomListView = getRoomList(page);
|
||||
await roomListView.hover();
|
||||
// Put focus on the room list
|
||||
await roomListView.getByRole("gridcell", { name: "Open room room29" }).click();
|
||||
// Scroll to the end of the room list
|
||||
await page.mouse.wheel(0, 1000);
|
||||
|
||||
@@ -183,6 +182,57 @@ test.describe("Room list", () => {
|
||||
await expect(page.getByRole("heading", { name: "1 notification", level: 1 })).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Keyboard navigation", () => {
|
||||
test("should navigate to the room list", async ({ page, app, user }) => {
|
||||
const roomListView = getRoomList(page);
|
||||
|
||||
const room29 = roomListView.getByRole("gridcell", { name: "Open room room29" });
|
||||
const room28 = roomListView.getByRole("gridcell", { name: "Open room room28" });
|
||||
|
||||
// open the room
|
||||
await room29.click();
|
||||
// put focus back on the room list item
|
||||
await room29.click();
|
||||
await expect(room29).toBeFocused();
|
||||
|
||||
await page.keyboard.press("ArrowDown");
|
||||
await expect(room28).toBeFocused();
|
||||
await expect(room29).not.toBeFocused();
|
||||
|
||||
await page.keyboard.press("ArrowUp");
|
||||
await expect(room29).toBeFocused();
|
||||
await expect(room28).not.toBeFocused();
|
||||
});
|
||||
|
||||
test("should navigate to the notification menu", async ({ page, app, user }) => {
|
||||
const roomListView = getRoomList(page);
|
||||
const room29 = roomListView.getByRole("gridcell", { name: "Open room room29" });
|
||||
const moreButton = room29.getByRole("button", { name: "More options" });
|
||||
const notificationButton = room29.getByRole("button", { name: "Notification options" });
|
||||
|
||||
await room29.click();
|
||||
// put focus back on the room list item
|
||||
await room29.click();
|
||||
await page.keyboard.press("Tab");
|
||||
await expect(moreButton).toBeFocused();
|
||||
await page.keyboard.press("Tab");
|
||||
await expect(notificationButton).toBeFocused();
|
||||
|
||||
// Open the menu
|
||||
await notificationButton.click();
|
||||
// Wait for the menu to be open
|
||||
await expect(page.getByRole("menuitem", { name: "Match default settings" })).toHaveAttribute(
|
||||
"aria-selected",
|
||||
"true",
|
||||
);
|
||||
|
||||
// Close the menu
|
||||
await page.keyboard.press("Escape");
|
||||
// Focus should be back on the room list item
|
||||
await expect(room29).toBeFocused();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe("Avatar decoration", () => {
|
||||
|
||||
@@ -15,6 +15,7 @@ test.describe("Module loading", () => {
|
||||
test.describe("Example Module", () => {
|
||||
test.use({
|
||||
config: {
|
||||
brand: "TestBrand",
|
||||
modules: ["/modules/example-module.js"],
|
||||
},
|
||||
page: async ({ page }, use) => {
|
||||
@@ -25,11 +26,31 @@ test.describe("Module loading", () => {
|
||||
},
|
||||
});
|
||||
|
||||
test("should show alert", async ({ page }) => {
|
||||
const dialogPromise = page.waitForEvent("dialog");
|
||||
await page.goto("/");
|
||||
const dialog = await dialogPromise;
|
||||
expect(dialog.message()).toBe("Testing module loading successful!");
|
||||
});
|
||||
const testCases = [
|
||||
["en", "TestBrand module loading successful!"],
|
||||
["de", "TestBrand-Module erfolgreich geladen!"],
|
||||
];
|
||||
|
||||
for (const [lang, message] of testCases) {
|
||||
test.describe(`language-${lang}`, () => {
|
||||
test.use({
|
||||
config: async ({ config }, use) => {
|
||||
await use({
|
||||
...config,
|
||||
setting_defaults: {
|
||||
language: lang,
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
test("should show alert", async ({ page }) => {
|
||||
const dialogPromise = page.waitForEvent("dialog");
|
||||
await page.goto("/");
|
||||
const dialog = await dialogPromise;
|
||||
expect(dialog.message()).toBe(message);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -88,7 +88,6 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
|
||||
await expect(page.getByText("Welcome")).toBeVisible();
|
||||
await page.goto("about:blank");
|
||||
|
||||
// @ts-expect-error
|
||||
const result = await mas.manage("kill-sessions", userId);
|
||||
expect(result.output).toContain("Ended 1 active OAuth 2.0 session");
|
||||
|
||||
|
||||
@@ -15,20 +15,34 @@ test.describe("Release announcement", () => {
|
||||
feature_release_announcement: true,
|
||||
},
|
||||
},
|
||||
labsFlags: ["threadsActivityCentre"],
|
||||
room: async ({ app, user }, use) => {
|
||||
const roomId = await app.client.createRoom({
|
||||
name: "Test room",
|
||||
});
|
||||
await app.viewRoomById(roomId);
|
||||
await use({ roomId });
|
||||
},
|
||||
});
|
||||
|
||||
test("should display the release announcement process", { tag: "@screenshot" }, async ({ page, app, util }) => {
|
||||
// The TAC release announcement should be displayed
|
||||
await util.assertReleaseAnnouncementIsVisible("Threads Activity Centre");
|
||||
// Hide the release announcement
|
||||
await util.markReleaseAnnouncementAsRead("Threads Activity Centre");
|
||||
await util.assertReleaseAnnouncementIsNotVisible("Threads Activity Centre");
|
||||
test(
|
||||
"should display the pinned messages release announcement",
|
||||
{ tag: "@screenshot" },
|
||||
async ({ page, app, room, util }) => {
|
||||
await app.toggleRoomInfoPanel();
|
||||
|
||||
await page.reload();
|
||||
// Wait for EW to load
|
||||
await expect(page.getByRole("navigation", { name: "Spaces" })).toBeVisible();
|
||||
// Check that once the release announcement has been marked as viewed, it does not appear again
|
||||
await util.assertReleaseAnnouncementIsNotVisible("Threads Activity Centre");
|
||||
});
|
||||
const name = "All new pinned messages";
|
||||
|
||||
// The release announcement should be displayed
|
||||
await util.assertReleaseAnnouncementIsVisible(name);
|
||||
// Hide the release announcement
|
||||
await util.markReleaseAnnouncementAsRead(name);
|
||||
await util.assertReleaseAnnouncementIsNotVisible(name);
|
||||
|
||||
await page.reload();
|
||||
await app.toggleRoomInfoPanel();
|
||||
await expect(page.getByRole("menuitem", { name: "Pinned messages" })).toBeVisible();
|
||||
// Check that once the release announcement has been marked as viewed, it does not appear again
|
||||
await util.assertReleaseAnnouncementIsNotVisible(name);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
34
playwright/e2e/share-dialog/share-by-url.spec.ts
Normal file
34
playwright/e2e/share-dialog/share-by-url.spec.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { test, expect } from "../../element-web-test";
|
||||
|
||||
test.describe("share from URL", () => {
|
||||
test.use({
|
||||
displayName: "Alice",
|
||||
room: async ({ app }, use) => {
|
||||
const roomId = await app.client.createRoom({ name: "A test room" });
|
||||
await use({ roomId });
|
||||
},
|
||||
});
|
||||
|
||||
test("should share message when users navigates to share URL", async ({ page, user, room, app }) => {
|
||||
await page.goto("/#/share?msg=Hello+world");
|
||||
// The forward message dialog doesn't update as new infomation arrives via sync, which means sometimes
|
||||
// this is just says, "Empty room". For the same reason, we can't reliably write a test for loading the
|
||||
// app straight away with a /#/share url as the room doesn't appear until the client syncs.]
|
||||
// Ideally we should fix the forward dialog to update and eliminate races, until then, there is only one
|
||||
// room so we click the first button.
|
||||
await page.getByRole("listitem" /*, { name: "A test room" }*/).getByRole("button", { name: "Send" }).click();
|
||||
await page.keyboard.press("Escape");
|
||||
await app.viewRoomByName("A test room");
|
||||
const lastMessage = page.locator(".mx_RoomView_MessageList .mx_EventTile_last");
|
||||
await expect(lastMessage).toBeVisible();
|
||||
const lastMessageText = await lastMessage.locator(".mx_EventTile_body").innerText();
|
||||
await expect(lastMessageText).toBe("Hello world");
|
||||
});
|
||||
});
|
||||
@@ -19,7 +19,6 @@ test.describe("Threads Activity Centre", { tag: "@no-firefox" }, () => {
|
||||
test.use({
|
||||
displayName: "Alice",
|
||||
botCreateOpts: { displayName: "Other User" },
|
||||
labsFlags: ["threadsActivityCentre"],
|
||||
});
|
||||
|
||||
test(
|
||||
|
||||
@@ -6,11 +6,19 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
export default class ExampleModule {
|
||||
static moduleApiVersion = "^0.1.0";
|
||||
static moduleApiVersion = "^1.0.0";
|
||||
constructor(api) {
|
||||
this.api = api;
|
||||
|
||||
this.api.i18n.register({
|
||||
key: {
|
||||
en: "%(brand)s module loading successful!",
|
||||
de: "%(brand)s-Module erfolgreich geladen!",
|
||||
},
|
||||
});
|
||||
}
|
||||
async load() {
|
||||
alert("Testing module loading successful!");
|
||||
const brand = this.api.config.get("brand");
|
||||
alert(this.api.i18n.translate("key", { brand }));
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 91 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 106 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 64 KiB |
@@ -18,10 +18,6 @@
|
||||
all: unset;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--cpd-color-bg-action-secondary-hovered);
|
||||
}
|
||||
|
||||
.mx_RoomListItemView_container {
|
||||
padding-left: var(--cpd-space-2x);
|
||||
font: var(--cpd-font-body-md-regular);
|
||||
@@ -56,12 +52,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.mx_RoomListItemView_menu_open {
|
||||
.mx_RoomListItemView_hover {
|
||||
background-color: var(--cpd-color-bg-action-secondary-hovered);
|
||||
}
|
||||
|
||||
.mx_RoomListItemView_content {
|
||||
padding-right: var(--cpd-space-1-5x);
|
||||
}
|
||||
.mx_RoomListItemView_menu_open .mx_RoomListItemView_content {
|
||||
padding-right: var(--cpd-space-1-5x);
|
||||
}
|
||||
|
||||
.mx_RoomListItemView_selected {
|
||||
|
||||
37
src/@types/global.d.ts
vendored
37
src/@types/global.d.ts
vendored
@@ -82,19 +82,10 @@ declare global {
|
||||
mxMatrixClientPeg: IMatrixClientPeg;
|
||||
mxReactSdkConfig: DeepReadonly<IConfigOptions>;
|
||||
|
||||
// Needed for Safari, unknown to TypeScript
|
||||
webkitAudioContext: typeof AudioContext;
|
||||
|
||||
// https://docs.microsoft.com/en-us/previous-versions/hh772328(v=vs.85)
|
||||
// we only ever check for its existence, so we can ignore its actual type
|
||||
MSStream?: unknown;
|
||||
|
||||
// https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1029#issuecomment-869224737
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
||||
OffscreenCanvas?: {
|
||||
new (width: number, height: number): OffscreenCanvas;
|
||||
};
|
||||
|
||||
mxContentMessages: ContentMessages;
|
||||
mxToastStore: ToastStore;
|
||||
mxDeviceListener: DeviceListener;
|
||||
@@ -156,31 +147,10 @@ declare global {
|
||||
fetchWindowIcons?: boolean;
|
||||
}
|
||||
|
||||
interface Document {
|
||||
// Safari & IE11 only have this prefixed: we used prefixed versions
|
||||
// previously so let's continue to support them for now
|
||||
webkitExitFullscreen(): Promise<void>;
|
||||
msExitFullscreen(): Promise<void>;
|
||||
readonly webkitFullscreenElement: Element | null;
|
||||
readonly msFullscreenElement: Element | null;
|
||||
}
|
||||
|
||||
interface Navigator {
|
||||
userLanguage?: string;
|
||||
}
|
||||
|
||||
interface StorageEstimate {
|
||||
usageDetails?: { [key: string]: number };
|
||||
}
|
||||
|
||||
interface Element {
|
||||
// Safari & IE11 only have this prefixed: we used prefixed versions
|
||||
// previously so let's continue to support them for now
|
||||
webkitRequestFullScreen(options?: FullscreenOptions): Promise<void>;
|
||||
msRequestFullscreen(options?: FullscreenOptions): Promise<void>;
|
||||
// scrollIntoView(arg?: boolean | _ScrollIntoViewOptions): void;
|
||||
}
|
||||
|
||||
// https://github.com/microsoft/TypeScript/issues/28308#issuecomment-650802278
|
||||
interface AudioWorkletProcessor {
|
||||
readonly port: MessagePort;
|
||||
@@ -239,11 +209,4 @@ declare global {
|
||||
var mx_rage_store: IndexedDBLogStore;
|
||||
}
|
||||
|
||||
// add method which is missing from the node typing
|
||||
declare module "url" {
|
||||
interface Url {
|
||||
format(): string;
|
||||
}
|
||||
}
|
||||
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
|
||||
@@ -72,7 +72,7 @@ export default abstract class BasePlatform {
|
||||
protected _favicon?: Favicon;
|
||||
|
||||
protected constructor() {
|
||||
dis.register(this.onAction);
|
||||
dis.register(this.onAction.bind(this));
|
||||
this.startUpdateCheck = this.startUpdateCheck.bind(this);
|
||||
}
|
||||
|
||||
@@ -85,14 +85,14 @@ export default abstract class BasePlatform {
|
||||
*/
|
||||
public abstract getDefaultDeviceDisplayName(): string;
|
||||
|
||||
protected onAction = (payload: ActionPayload): void => {
|
||||
protected onAction(payload: ActionPayload): void {
|
||||
switch (payload.action) {
|
||||
case "on_client_not_viable":
|
||||
case Action.OnLoggedOut:
|
||||
this.setNotificationCount(0);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Used primarily for Analytics
|
||||
public abstract getHumanReadableName(): string;
|
||||
|
||||
@@ -132,7 +132,7 @@ export default class DeviceListener {
|
||||
this.dismissedThisDeviceToast = false;
|
||||
this.keyBackupInfo = null;
|
||||
this.keyBackupFetchedAt = null;
|
||||
this.keyBackupStatusChecked = false;
|
||||
this.cachedKeyBackupStatus = undefined;
|
||||
this.ourDeviceIdsAtStart = null;
|
||||
this.displayingToastsForDeviceIds = new Set();
|
||||
this.client = undefined;
|
||||
@@ -512,18 +512,36 @@ export default class DeviceListener {
|
||||
* trigger an auto-rageshake).
|
||||
*/
|
||||
private checkKeyBackupStatus = async (): Promise<void> => {
|
||||
if (this.keyBackupStatusChecked || !this.client) {
|
||||
return;
|
||||
}
|
||||
const activeKeyBackupVersion = await this.client.getCrypto()?.getActiveSessionBackupVersion();
|
||||
// if key backup is enabled, no need to check this ever again (XXX: why only when it is enabled?)
|
||||
this.keyBackupStatusChecked = !!activeKeyBackupVersion;
|
||||
|
||||
if (!activeKeyBackupVersion) {
|
||||
if (!(await this.getKeyBackupStatus())) {
|
||||
dis.dispatch({ action: Action.ReportKeyBackupNotEnabled });
|
||||
}
|
||||
};
|
||||
private keyBackupStatusChecked = false;
|
||||
|
||||
/**
|
||||
* Is key backup enabled? Use a cached answer if we have one.
|
||||
*/
|
||||
private getKeyBackupStatus = async (): Promise<boolean> => {
|
||||
if (!this.client) {
|
||||
// To preserve existing behaviour, if there is no client, we
|
||||
// pretend key storage is on.
|
||||
//
|
||||
// Someone looking to improve this code could try throwing an error
|
||||
// here since we don't expect client to be undefined.
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we've already cached the answer, return it.
|
||||
if (this.cachedKeyBackupStatus !== undefined) {
|
||||
return this.cachedKeyBackupStatus;
|
||||
}
|
||||
|
||||
// Fetch the answer and cache it
|
||||
const activeKeyBackupVersion = await this.client.getCrypto()?.getActiveSessionBackupVersion();
|
||||
this.cachedKeyBackupStatus = !!activeKeyBackupVersion;
|
||||
|
||||
return this.cachedKeyBackupStatus;
|
||||
};
|
||||
private cachedKeyBackupStatus: boolean | undefined = undefined;
|
||||
|
||||
private onRecordClientInformationSettingChange: CallbackFn = (
|
||||
_originalSettingName,
|
||||
|
||||
@@ -1115,7 +1115,9 @@ export async function onLoggedOut(): Promise<void> {
|
||||
* @param {object} opts Options for how to clear storage.
|
||||
* @returns {Promise} promise which resolves once the stores have been cleared
|
||||
*/
|
||||
async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void> {
|
||||
export async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void> {
|
||||
logger.info(`Clearing storage, deleteEverything=${opts?.deleteEverything}`);
|
||||
|
||||
if (window.localStorage) {
|
||||
// get the currently defined device language, if set, so we can restore it later
|
||||
const language = SettingsStore.getValueAt(SettingLevel.DEVICE, "language", null, true, true);
|
||||
|
||||
@@ -10,7 +10,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React, { StrictMode } from "react";
|
||||
import { createRoot, type Root } from "react-dom/client";
|
||||
import classNames from "classnames";
|
||||
import { type IDeferred, defer } from "matrix-js-sdk/src/utils";
|
||||
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
|
||||
import { Glass, TooltipProvider } from "@vector-im/compound-web";
|
||||
|
||||
@@ -70,7 +69,7 @@ export interface IModal<C extends ComponentType> {
|
||||
/** A deferred to resolve when the dialog closes, with the results as provided by
|
||||
* the call to {@link close} (normally from the `onFinished` callback).
|
||||
*/
|
||||
deferred?: IDeferred<OnFinishedParams<C> | []>;
|
||||
deferred?: PromiseWithResolvers<OnFinishedParams<C> | []>;
|
||||
}
|
||||
|
||||
/** The result of {@link Modal.createDialog}.
|
||||
@@ -254,7 +253,7 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
|
||||
}
|
||||
|
||||
private getCloseFn<C extends ComponentType>(modal: IModal<C>): [IHandle<C>["close"], IHandle<C>["finished"]] {
|
||||
modal.deferred = defer<OnFinishedParams<C> | []>();
|
||||
modal.deferred = Promise.withResolvers<OnFinishedParams<C> | []>();
|
||||
return [
|
||||
async (...args: OnFinishedParams<C>): Promise<void> => {
|
||||
if (modal.beforeClosePromise) {
|
||||
|
||||
@@ -49,7 +49,7 @@ import {
|
||||
SlidingSyncState,
|
||||
} from "matrix-js-sdk/src/sliding-sync";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { defer, sleep } from "matrix-js-sdk/src/utils";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
|
||||
// how long to long poll for
|
||||
const SLIDING_SYNC_TIMEOUT_MS = 20 * 1000;
|
||||
@@ -184,7 +184,7 @@ export class SlidingSyncManager {
|
||||
public slidingSync?: SlidingSync;
|
||||
private client?: MatrixClient;
|
||||
|
||||
private configureDefer = defer<void>();
|
||||
private configureDefer = Promise.withResolvers<void>();
|
||||
|
||||
public static get instance(): SlidingSyncManager {
|
||||
return SlidingSyncManager.internalInstance;
|
||||
|
||||
@@ -6,14 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { defer, type IDeferred } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import { type WorkerPayload } from "./workers/worker";
|
||||
|
||||
export class WorkerManager<Request extends object, Response> {
|
||||
private readonly worker: Worker;
|
||||
private seq = 0;
|
||||
private pendingDeferredMap = new Map<number, IDeferred<Response>>();
|
||||
private pendingDeferredMap = new Map<number, PromiseWithResolvers<Response>>();
|
||||
|
||||
public constructor(worker: Worker) {
|
||||
this.worker = worker;
|
||||
@@ -30,7 +28,7 @@ export class WorkerManager<Request extends object, Response> {
|
||||
|
||||
public call(request: Request): Promise<Response> {
|
||||
const seq = this.seq++;
|
||||
const deferred = defer<Response>();
|
||||
const deferred = Promise.withResolvers<Response>();
|
||||
this.pendingDeferredMap.set(seq, deferred);
|
||||
this.worker.postMessage({ seq, ...request });
|
||||
return deferred.promise;
|
||||
|
||||
@@ -521,7 +521,8 @@ export const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
|
||||
[KeyBindingAction.GoToHome]: {
|
||||
default: {
|
||||
ctrlKey: true,
|
||||
altKey: true,
|
||||
altKey: !IS_MAC,
|
||||
shiftKey: IS_MAC,
|
||||
key: Key.H,
|
||||
},
|
||||
displayName: _td("keyboard|go_home_view"),
|
||||
@@ -586,7 +587,7 @@ export const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
|
||||
default: {
|
||||
ctrlKey: true,
|
||||
shiftKey: true,
|
||||
key: Key.H,
|
||||
key: Key.J,
|
||||
},
|
||||
displayName: _td("keyboard|toggle_hidden_events"),
|
||||
},
|
||||
|
||||
@@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
import EventEmitter from "events";
|
||||
import { SimpleObservable } from "matrix-widget-api";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import { UPDATE_EVENT } from "../stores/AsyncStore";
|
||||
import { arrayFastResample } from "../utils/arrays";
|
||||
@@ -158,42 +157,27 @@ export class Playback extends EventEmitter implements IDestroyable, PlaybackInte
|
||||
// 5mb
|
||||
logger.log("Audio file too large: processing through <audio /> element");
|
||||
this.element = document.createElement("AUDIO") as HTMLAudioElement;
|
||||
const deferred = defer<unknown>();
|
||||
const deferred = Promise.withResolvers<unknown>();
|
||||
this.element.onloadeddata = deferred.resolve;
|
||||
this.element.onerror = deferred.reject;
|
||||
this.element.src = URL.createObjectURL(new Blob([this.buf]));
|
||||
await deferred.promise; // make sure the audio element is ready for us
|
||||
} else {
|
||||
// Safari compat: promise API not supported on this function
|
||||
this.audioBuf = await new Promise((resolve, reject) => {
|
||||
this.context.decodeAudioData(
|
||||
this.buf,
|
||||
(b) => resolve(b),
|
||||
async (e): Promise<void> => {
|
||||
try {
|
||||
// This error handler is largely for Safari as well, which doesn't support Opus/Ogg
|
||||
// very well.
|
||||
logger.error("Error decoding recording: ", e);
|
||||
logger.warn("Trying to re-encode to WAV instead...");
|
||||
try {
|
||||
this.audioBuf = await this.context.decodeAudioData(this.buf);
|
||||
} catch (e) {
|
||||
logger.error("Error decoding recording:", e);
|
||||
logger.warn("Trying to re-encode to WAV instead...");
|
||||
|
||||
const wav = await decodeOgg(this.buf);
|
||||
|
||||
// noinspection ES6MissingAwait - not needed when using callbacks
|
||||
this.context.decodeAudioData(
|
||||
wav,
|
||||
(b) => resolve(b),
|
||||
(e) => {
|
||||
logger.error("Still failed to decode recording: ", e);
|
||||
reject(e);
|
||||
},
|
||||
);
|
||||
} catch (e) {
|
||||
logger.error("Caught decoding error:", e);
|
||||
reject(e);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
try {
|
||||
// This error handler is largely for Safari, which doesn't support Opus/Ogg very well.
|
||||
const wav = await decodeOgg(this.buf);
|
||||
this.audioBuf = await this.context.decodeAudioData(wav);
|
||||
} catch (e) {
|
||||
logger.error("Error decoding recording:", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the waveform to the real waveform once we have channel data to use. We don't
|
||||
// exactly trust the user-provided waveform to be accurate...
|
||||
|
||||
@@ -15,21 +15,15 @@ import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { SAMPLE_RATE } from "./VoiceRecording";
|
||||
|
||||
export function createAudioContext(opts?: AudioContextOptions): AudioContext {
|
||||
let ctx: AudioContext;
|
||||
if (window.AudioContext) {
|
||||
ctx = new AudioContext(opts);
|
||||
} else if (window.webkitAudioContext) {
|
||||
// While the linter is correct that "a constructor name should not start with
|
||||
// a lowercase letter", it's also wrong to think that we have control over this.
|
||||
// eslint-disable-next-line new-cap
|
||||
ctx = new window.webkitAudioContext(opts);
|
||||
const ctx = new AudioContext(opts);
|
||||
// Initialize in suspended state, as Firefox starts using
|
||||
// CPU/battery right away, even if we don't play any sound yet.
|
||||
void ctx.suspend();
|
||||
return ctx;
|
||||
} else {
|
||||
throw new Error("Unsupported browser");
|
||||
}
|
||||
// Initialize in suspended state, as Firefox starts using
|
||||
// CPU/battery right away, even if we don't play any sound yet.
|
||||
void ctx.suspend();
|
||||
return ctx;
|
||||
}
|
||||
|
||||
export function decodeOgg(audioBuffer: ArrayBuffer): Promise<ArrayBuffer> {
|
||||
|
||||
@@ -13,20 +13,21 @@ import {
|
||||
EventType,
|
||||
HttpApiEvent,
|
||||
type MatrixClient,
|
||||
type MatrixEvent,
|
||||
MatrixEvent,
|
||||
MsgType,
|
||||
type RoomType,
|
||||
SyncState,
|
||||
type SyncStateData,
|
||||
type TimelineEvents,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { defer, type IDeferred, type QueryDict } from "matrix-js-sdk/src/utils";
|
||||
import { type QueryDict } from "matrix-js-sdk/src/utils";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { throttle } from "lodash";
|
||||
import { CryptoEvent, type KeyBackupInfo } from "matrix-js-sdk/src/crypto-api";
|
||||
import { TooltipProvider } from "@vector-im/compound-web";
|
||||
|
||||
// what-input helps improve keyboard accessibility
|
||||
import "what-input";
|
||||
import sanitizeHtml from "sanitize-html";
|
||||
|
||||
import PosthogTrackers from "../../PosthogTrackers";
|
||||
import { DecryptionFailureTracker } from "../../DecryptionFailureTracker";
|
||||
@@ -50,6 +51,7 @@ import ThemeController from "../../settings/controllers/ThemeController";
|
||||
import { startAnyRegistrationFlow } from "../../Registration";
|
||||
import ResizeNotifier from "../../utils/ResizeNotifier";
|
||||
import AutoDiscoveryUtils from "../../utils/AutoDiscoveryUtils";
|
||||
import { makeRoomPermalink } from "../../utils/permalinks/Permalinks";
|
||||
import ThemeWatcher, { ThemeWatcherEvent } from "../../settings/watchers/ThemeWatcher";
|
||||
import { FontWatcher } from "../../settings/watchers/FontWatcher";
|
||||
import { storeRoomAliasInCache } from "../../RoomAliasCache";
|
||||
@@ -94,7 +96,6 @@ import VerificationRequestToast from "../views/toasts/VerificationRequestToast";
|
||||
import PerformanceMonitor, { PerformanceEntryNames } from "../../performance";
|
||||
import UIStore, { UI_EVENTS } from "../../stores/UIStore";
|
||||
import SoftLogout from "./auth/SoftLogout";
|
||||
import { makeRoomPermalink } from "../../utils/permalinks/Permalinks";
|
||||
import { copyPlaintext } from "../../utils/strings";
|
||||
import { PosthogAnalytics } from "../../PosthogAnalytics";
|
||||
import { initSentry } from "../../sentry";
|
||||
@@ -123,7 +124,7 @@ import { viewUserDeviceSettings } from "../../actions/handlers/viewUserDeviceSet
|
||||
import GenericToast from "../views/toasts/GenericToast";
|
||||
import RovingSpotlightDialog from "../views/dialogs/spotlight/SpotlightDialog";
|
||||
import { findDMForUser } from "../../utils/dm/findDMForUser";
|
||||
import { Linkify } from "../../HtmlUtils";
|
||||
import { getHtmlText, Linkify } from "../../HtmlUtils";
|
||||
import { NotificationLevel } from "../../stores/notifications/NotificationLevel";
|
||||
import { type UserTab } from "../views/dialogs/UserTab";
|
||||
import { shouldSkipSetupEncryption } from "../../utils/crypto/shouldSkipSetupEncryption";
|
||||
@@ -135,6 +136,10 @@ import { LoginSplashView } from "./auth/LoginSplashView";
|
||||
import { cleanUpDraftsIfRequired } from "../../DraftCleaner";
|
||||
import { InitialCryptoSetupStore } from "../../stores/InitialCryptoSetupStore";
|
||||
import { setTheme } from "../../theme";
|
||||
import { type OpenForwardDialogPayload } from "../../dispatcher/payloads/OpenForwardDialogPayload";
|
||||
import { ShareFormat, type SharePayload } from "../../dispatcher/payloads/SharePayload";
|
||||
import Markdown from "../../Markdown";
|
||||
import { sanitizeHtmlParams } from "../../Linkify";
|
||||
|
||||
// legacy export
|
||||
export { default as Views } from "../../Views";
|
||||
@@ -215,7 +220,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
};
|
||||
|
||||
private firstSyncComplete = false;
|
||||
private firstSyncPromise: IDeferred<void>;
|
||||
private firstSyncPromise: PromiseWithResolvers<void>;
|
||||
|
||||
private screenAfterLogin?: IScreen;
|
||||
private tokenLogin?: boolean;
|
||||
@@ -254,7 +259,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
|
||||
// Used by _viewRoom before getting state from sync
|
||||
this.firstSyncComplete = false;
|
||||
this.firstSyncPromise = defer();
|
||||
this.firstSyncPromise = Promise.withResolvers();
|
||||
|
||||
if (this.props.config.sync_timeline_limit) {
|
||||
MatrixClientPeg.opts.initialSyncLimit = this.props.config.sync_timeline_limit;
|
||||
@@ -779,6 +784,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
case Action.ViewHomePage:
|
||||
this.viewHome(payload.justRegistered);
|
||||
break;
|
||||
case Action.Share:
|
||||
this.viewShare(payload.format, payload.msg);
|
||||
break;
|
||||
case Action.ViewStartChatOrReuse:
|
||||
this.chatCreateOrReuse(payload.user_id);
|
||||
break;
|
||||
@@ -1114,6 +1122,58 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
});
|
||||
}
|
||||
|
||||
private viewShare(format: ShareFormat, msg: string): void {
|
||||
// Wait for the first sync so we can present possible rooms to share into
|
||||
this.firstSyncPromise.promise.then(() => {
|
||||
this.notifyNewScreen("share");
|
||||
let rawEvent;
|
||||
switch (format) {
|
||||
case ShareFormat.Html: {
|
||||
rawEvent = {
|
||||
type: "m.room.message",
|
||||
content: {
|
||||
msgtype: MsgType.Text,
|
||||
body: getHtmlText(msg),
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: sanitizeHtml(msg, sanitizeHtmlParams),
|
||||
},
|
||||
origin_server_ts: Date.now(),
|
||||
};
|
||||
break;
|
||||
}
|
||||
case ShareFormat.Markdown: {
|
||||
const html = new Markdown(msg).toHTML({ externalLinks: true });
|
||||
rawEvent = {
|
||||
type: "m.room.message",
|
||||
content: {
|
||||
msgtype: MsgType.Text,
|
||||
body: msg,
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body: html,
|
||||
},
|
||||
origin_server_ts: Date.now(),
|
||||
};
|
||||
break;
|
||||
}
|
||||
default:
|
||||
rawEvent = {
|
||||
type: "m.room.message",
|
||||
content: {
|
||||
msgtype: MsgType.Text,
|
||||
body: msg,
|
||||
},
|
||||
origin_server_ts: Date.now(),
|
||||
};
|
||||
}
|
||||
const event = new MatrixEvent(rawEvent);
|
||||
dis.dispatch<OpenForwardDialogPayload>({
|
||||
action: Action.OpenForwardDialog,
|
||||
event: event,
|
||||
permalinkCreator: null,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async createRoom(defaultPublic = false, defaultName?: string, type?: RoomType): Promise<void> {
|
||||
const modal = Modal.createDialog(CreateRoomDialog, {
|
||||
type,
|
||||
@@ -1471,11 +1531,11 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
// since we're about to start the client and therefore about to do the first sync
|
||||
// We resolve the existing promise with the new one to update any existing listeners
|
||||
if (!this.firstSyncComplete) {
|
||||
const firstSyncPromise = defer<void>();
|
||||
const firstSyncPromise = Promise.withResolvers<void>();
|
||||
this.firstSyncPromise.resolve(firstSyncPromise.promise);
|
||||
this.firstSyncPromise = firstSyncPromise;
|
||||
} else {
|
||||
this.firstSyncPromise = defer();
|
||||
this.firstSyncPromise = Promise.withResolvers();
|
||||
}
|
||||
this.firstSyncComplete = false;
|
||||
const cli = MatrixClientPeg.safeGet();
|
||||
@@ -1739,6 +1799,20 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
dis.dispatch({
|
||||
action: Action.CreateChat,
|
||||
});
|
||||
} else if (screen === "share") {
|
||||
if (params && params["msg"] !== undefined) {
|
||||
dis.dispatch<SharePayload>({
|
||||
action: Action.Share,
|
||||
msg: params["msg"],
|
||||
format: params["format"],
|
||||
});
|
||||
}
|
||||
// if we weren't already coming at this from an existing screen
|
||||
// and we're logged in, then explicitly default to home.
|
||||
// if we're not logged in, then the login flow will do the right thing.
|
||||
if (!this.state.currentRoomId && !this.state.currentUserId) {
|
||||
this.viewHome();
|
||||
}
|
||||
} else if (screen === "settings") {
|
||||
dis.fire(Action.ViewUserSettings);
|
||||
} else if (screen === "welcome") {
|
||||
|
||||
@@ -220,7 +220,7 @@ function useRoomMessagePreview(room: Room): string | undefined {
|
||||
room,
|
||||
roomIsDM ? DefaultTagID.DM : DefaultTagID.Untagged,
|
||||
);
|
||||
if (messagePreview) setPreviewText(messagePreview.text);
|
||||
setPreviewText(messagePreview?.text);
|
||||
}, [room, shouldShowMessagePreview]);
|
||||
|
||||
// MessagePreviewStore and the other AsyncStores need to be converted to TypedEventEmitter
|
||||
|
||||
@@ -8,7 +8,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import React, { type JSX } from "react";
|
||||
import { type MatrixEvent, EventType, RelationType, type MatrixClient, MatrixError } from "matrix-js-sdk/src/matrix";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
||||
@@ -58,7 +57,7 @@ export default class MessageEditHistoryDialog extends React.PureComponent<IProps
|
||||
const eventId = this.props.mxEvent.getId()!;
|
||||
const client = MatrixClientPeg.safeGet();
|
||||
|
||||
const { resolve, reject, promise } = defer<boolean>();
|
||||
const { resolve, reject, promise } = Promise.withResolvers<boolean>();
|
||||
let result: Awaited<ReturnType<MatrixClient["relations"]>>;
|
||||
|
||||
try {
|
||||
|
||||
@@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { type JSX, createRef, type CSSProperties, useRef, useState } from "react";
|
||||
import React, { type JSX, createRef, type CSSProperties, useRef, useState, useMemo } from "react";
|
||||
import FocusLock from "react-focus-lock";
|
||||
import { type MatrixEvent, parseErrorResponse } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
@@ -33,6 +33,7 @@ import AccessibleButton from "./AccessibleButton";
|
||||
import Modal from "../../../Modal";
|
||||
import ErrorDialog from "../dialogs/ErrorDialog";
|
||||
import { FileDownloader } from "../../../utils/FileDownloader";
|
||||
import { MediaEventHelper } from "../../../utils/MediaEventHelper.ts";
|
||||
|
||||
// Max scale to keep gaps around the image
|
||||
const MAX_SCALE = 0.95;
|
||||
@@ -549,7 +550,7 @@ export default class ImageView extends React.Component<IProps, IState> {
|
||||
title={_t("lightbox|rotate_right")}
|
||||
onClick={this.onRotateClockwiseClick}
|
||||
/>
|
||||
<DownloadButton url={this.props.src} fileName={this.props.name} />
|
||||
<DownloadButton url={this.props.src} fileName={this.props.name} mxEvent={this.props.mxEvent} />
|
||||
{contextMenuButton}
|
||||
<AccessibleButton
|
||||
className="mx_ImageView_button mx_ImageView_button_close"
|
||||
@@ -582,10 +583,19 @@ export default class ImageView extends React.Component<IProps, IState> {
|
||||
}
|
||||
}
|
||||
|
||||
function DownloadButton({ url, fileName }: { url: string; fileName?: string }): JSX.Element {
|
||||
function DownloadButton({
|
||||
url,
|
||||
fileName,
|
||||
mxEvent,
|
||||
}: {
|
||||
url: string;
|
||||
fileName?: string;
|
||||
mxEvent?: MatrixEvent;
|
||||
}): JSX.Element {
|
||||
const downloader = useRef(new FileDownloader()).current;
|
||||
const [loading, setLoading] = useState(false);
|
||||
const blobRef = useRef<Blob>(undefined);
|
||||
const mediaEventHelper = useMemo(() => (mxEvent ? new MediaEventHelper(mxEvent) : undefined), [mxEvent]);
|
||||
|
||||
function showError(e: unknown): void {
|
||||
Modal.createDialog(ErrorDialog, {
|
||||
@@ -625,7 +635,7 @@ function DownloadButton({ url, fileName }: { url: string; fileName?: string }):
|
||||
async function downloadBlob(blob: Blob): Promise<void> {
|
||||
await downloader.download({
|
||||
blob,
|
||||
name: fileName ?? _t("common|image"),
|
||||
name: mediaEventHelper?.fileName ?? fileName ?? _t("common|image"),
|
||||
});
|
||||
setLoading(false);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import React, { type ReactElement } from "react";
|
||||
import classNames from "classnames";
|
||||
|
||||
import * as languageHandler from "../../../languageHandler";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { _t } from "../../../languageHandler";
|
||||
import Spinner from "./Spinner";
|
||||
import Dropdown from "./Dropdown";
|
||||
@@ -29,7 +28,7 @@ function languageMatchesSearchQuery(query: string, language: Languages[0]): bool
|
||||
interface IProps {
|
||||
className?: string;
|
||||
onOptionChange: (language: string) => void;
|
||||
value?: string;
|
||||
value: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
@@ -103,17 +102,6 @@ export default class LanguageDropdown extends React.Component<IProps, IState> {
|
||||
return <div key={language.value}>{language.labelInTargetLanguage}</div>;
|
||||
}) as NonEmptyArray<ReactElement & { key: string }>;
|
||||
|
||||
// default value here too, otherwise we need to handle null / undefined
|
||||
// values between mounting and the initial value propagating
|
||||
let language = SettingsStore.getValue("language", null, /*excludeDefault:*/ true);
|
||||
let value: string | undefined;
|
||||
if (language) {
|
||||
value = this.props.value || language;
|
||||
} else {
|
||||
language = navigator.language || navigator.userLanguage;
|
||||
value = this.props.value || language;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
id="mx_LanguageDropdown"
|
||||
@@ -121,7 +109,7 @@ export default class LanguageDropdown extends React.Component<IProps, IState> {
|
||||
onOptionChange={this.props.onOptionChange}
|
||||
onSearchChange={this.onSearchChange}
|
||||
searchEnabled={true}
|
||||
value={value}
|
||||
value={this.props.value}
|
||||
label={_t("language_dropdown_label")}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
|
||||
@@ -10,7 +10,6 @@ import React, { type ReactElement } from "react";
|
||||
|
||||
import Dropdown from "../../views/elements/Dropdown";
|
||||
import PlatformPeg from "../../../PlatformPeg";
|
||||
import SettingsStore from "../../../settings/SettingsStore";
|
||||
import { _t, getUserLanguage } from "../../../languageHandler";
|
||||
import Spinner from "./Spinner";
|
||||
import { type NonEmptyArray } from "../../../@types/common";
|
||||
@@ -105,17 +104,6 @@ export default class SpellCheckLanguagesDropdown extends React.Component<
|
||||
return <div key={language.value}>{language.label}</div>;
|
||||
}) as NonEmptyArray<ReactElement & { key: string }>;
|
||||
|
||||
// default value here too, otherwise we need to handle null / undefined;
|
||||
// values between mounting and the initial value propagating
|
||||
let language = SettingsStore.getValue("language", null, /*excludeDefault:*/ true);
|
||||
let value: string | undefined;
|
||||
if (language) {
|
||||
value = this.props.value || language;
|
||||
} else {
|
||||
language = navigator.language || navigator.userLanguage;
|
||||
value = this.props.value || language;
|
||||
}
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
id="mx_LanguageDropdown"
|
||||
@@ -123,7 +111,7 @@ export default class SpellCheckLanguagesDropdown extends React.Component<
|
||||
onOptionChange={this.props.onOptionChange}
|
||||
onSearchChange={this.onSearchChange}
|
||||
searchEnabled={true}
|
||||
value={value}
|
||||
value={this.props.value}
|
||||
label={_t("language_dropdown_label")}
|
||||
placeholder={_t("settings|general|spell_check_locale_placeholder")}
|
||||
>
|
||||
|
||||
@@ -179,7 +179,7 @@ const RoomSummaryCard: React.FC<IProps> = ({
|
||||
onSearchChange,
|
||||
onSearchCancel,
|
||||
focusRoomSearch,
|
||||
searchTerm,
|
||||
searchTerm = "",
|
||||
}) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
@@ -245,6 +245,13 @@ const RoomSummaryCard: React.FC<IProps> = ({
|
||||
}
|
||||
});
|
||||
|
||||
// The search field is controlled and onSearchChange is debounced in RoomView,
|
||||
// so we need to set the value of the input right away
|
||||
const [searchValue, setSearchValue] = useState(searchTerm);
|
||||
useEffect(() => {
|
||||
setSearchValue(searchTerm);
|
||||
}, [searchTerm]);
|
||||
|
||||
const alias = room.getCanonicalAlias() || room.getAltAliases()[0] || "";
|
||||
const roomInfo = (
|
||||
<header className="mx_RoomSummaryCard_container">
|
||||
@@ -320,9 +327,10 @@ const RoomSummaryCard: React.FC<IProps> = ({
|
||||
placeholder={_t("room|search|placeholder")}
|
||||
name="room_message_search"
|
||||
onChange={(e) => {
|
||||
setSearchValue(e.currentTarget.value);
|
||||
onSearchChange(e.currentTarget.value);
|
||||
}}
|
||||
value={searchTerm}
|
||||
value={searchValue}
|
||||
className="mx_no_textinput"
|
||||
ref={searchInputRef}
|
||||
autoFocus={focusRoomSearch}
|
||||
|
||||
@@ -10,7 +10,6 @@ import React, { createRef, type RefObject } from "react";
|
||||
import classNames from "classnames";
|
||||
import { flatMap } from "lodash";
|
||||
import { type Room } from "matrix-js-sdk/src/matrix";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import Autocompleter, {
|
||||
type ICompletion,
|
||||
@@ -177,7 +176,7 @@ export default class Autocomplete extends React.PureComponent<IProps, IState> {
|
||||
}
|
||||
}
|
||||
|
||||
const deferred = defer<void>();
|
||||
const deferred = Promise.withResolvers<void>();
|
||||
this.setState(
|
||||
{
|
||||
completions,
|
||||
|
||||
@@ -11,6 +11,10 @@ import { AutoSizer, List, type ListRowProps } from "react-virtualized";
|
||||
import { type RoomListViewState } from "../../../viewmodels/roomlist/RoomListViewModel";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import { RoomListItemView } from "./RoomListItemView";
|
||||
import { RovingTabIndexProvider } from "../../../../accessibility/RovingTabIndex";
|
||||
import { getKeyBindingsManager } from "../../../../KeyBindingsManager";
|
||||
import { KeyBindingAction } from "../../../../accessibility/KeyboardShortcuts";
|
||||
import { Landmark, LandmarkNavigation } from "../../../../accessibility/LandmarkNavigation";
|
||||
|
||||
interface RoomListProps {
|
||||
/**
|
||||
@@ -32,21 +36,45 @@ export function RoomList({ vm: { rooms, activeIndex } }: RoomListProps): JSX.Ele
|
||||
|
||||
// The first div is needed to make the virtualized list take all the remaining space and scroll correctly
|
||||
return (
|
||||
<div className="mx_RoomList" data-testid="room-list">
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<List
|
||||
aria-label={_t("room_list|list_title")}
|
||||
className="mx_RoomList_List"
|
||||
rowRenderer={roomRendererMemoized}
|
||||
rowCount={rooms.length}
|
||||
rowHeight={48}
|
||||
height={height}
|
||||
width={width}
|
||||
scrollToIndex={activeIndex ?? 0}
|
||||
/>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
<RovingTabIndexProvider handleHomeEnd={true} handleUpDown={true}>
|
||||
{({ onKeyDownHandler }) => (
|
||||
<div
|
||||
className="mx_RoomList"
|
||||
data-testid="room-list"
|
||||
onKeyDown={(ev) => {
|
||||
const navAction = getKeyBindingsManager().getNavigationAction(ev);
|
||||
if (
|
||||
navAction === KeyBindingAction.NextLandmark ||
|
||||
navAction === KeyBindingAction.PreviousLandmark
|
||||
) {
|
||||
LandmarkNavigation.findAndFocusNextLandmark(
|
||||
Landmark.ROOM_LIST,
|
||||
navAction === KeyBindingAction.PreviousLandmark,
|
||||
);
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
return;
|
||||
}
|
||||
onKeyDownHandler(ev);
|
||||
}}
|
||||
>
|
||||
<AutoSizer>
|
||||
{({ height, width }) => (
|
||||
<List
|
||||
aria-label={_t("room_list|list_title")}
|
||||
className="mx_RoomList_List"
|
||||
rowRenderer={roomRendererMemoized}
|
||||
rowCount={rooms.length}
|
||||
rowHeight={48}
|
||||
height={height}
|
||||
width={width}
|
||||
scrollToIndex={activeIndex ?? 0}
|
||||
tabIndex={-1}
|
||||
/>
|
||||
)}
|
||||
</AutoSizer>
|
||||
</div>
|
||||
)}
|
||||
</RovingTabIndexProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import React, { type JSX, memo, useState } from "react";
|
||||
import React, { type JSX, memo, useCallback, useRef, useState } from "react";
|
||||
import { type Room } from "matrix-js-sdk/src/matrix";
|
||||
import classNames from "classnames";
|
||||
|
||||
@@ -14,6 +14,7 @@ import { Flex } from "../../../utils/Flex";
|
||||
import { RoomListItemMenuView } from "./RoomListItemMenuView";
|
||||
import { NotificationDecoration } from "../NotificationDecoration";
|
||||
import { RoomAvatarView } from "../../avatars/RoomAvatarView";
|
||||
import { useRovingTabIndex } from "../../../../accessibility/RovingTabIndex";
|
||||
|
||||
interface RoomListItemViewProps extends React.HTMLAttributes<HTMLButtonElement> {
|
||||
/**
|
||||
@@ -34,22 +35,29 @@ export const RoomListItemView = memo(function RoomListItemView({
|
||||
isSelected,
|
||||
...props
|
||||
}: RoomListItemViewProps): JSX.Element {
|
||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||
const [onFocus, isActive, ref] = useRovingTabIndex(buttonRef);
|
||||
|
||||
const vm = useRoomListItemViewModel(room);
|
||||
|
||||
const [isHover, setIsHover] = useState(false);
|
||||
const [isHover, setIsHoverWithDelay] = useIsHover();
|
||||
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
||||
// The compound menu in RoomListItemMenuView needs to be rendered when the hover menu is shown
|
||||
// Using display: none; and then display:flex when hovered in CSS causes the menu to be misaligned
|
||||
const showHoverDecoration = (isMenuOpen || isHover) && vm.showHoverMenu;
|
||||
const showHoverDecoration = isMenuOpen || isHover;
|
||||
const showHoverMenu = showHoverDecoration && vm.showHoverMenu;
|
||||
|
||||
const isNotificationDecorationVisible = !showHoverDecoration && vm.showNotificationDecoration;
|
||||
const isInvitation = vm.notificationState.invited;
|
||||
const isNotificationDecorationVisible = isInvitation || (!showHoverDecoration && vm.showNotificationDecoration);
|
||||
|
||||
return (
|
||||
<button
|
||||
ref={ref}
|
||||
className={classNames("mx_RoomListItemView", {
|
||||
mx_RoomListItemView_empty: !isNotificationDecorationVisible && !showHoverDecoration,
|
||||
mx_RoomListItemView_notification_decoration: isNotificationDecorationVisible,
|
||||
mx_RoomListItemView_menu_open: showHoverDecoration,
|
||||
mx_RoomListItemView_hover: showHoverDecoration,
|
||||
mx_RoomListItemView_menu_open: showHoverMenu,
|
||||
mx_RoomListItemView_selected: isSelected,
|
||||
mx_RoomListItemView_bold: vm.isBold,
|
||||
})}
|
||||
@@ -57,10 +65,17 @@ export const RoomListItemView = memo(function RoomListItemView({
|
||||
aria-selected={isSelected}
|
||||
aria-label={vm.a11yLabel}
|
||||
onClick={() => vm.openRoom()}
|
||||
onMouseOver={() => setIsHover(true)}
|
||||
onMouseOut={() => setIsHover(false)}
|
||||
onFocus={() => setIsHover(true)}
|
||||
onBlur={() => setIsHover(false)}
|
||||
onMouseOver={() => setIsHoverWithDelay(true)}
|
||||
onMouseOut={() => setIsHoverWithDelay(false)}
|
||||
onFocus={() => {
|
||||
setIsHoverWithDelay(true);
|
||||
onFocus();
|
||||
}}
|
||||
// Adding a timeout because when tabbing to go to the more options and notification menu, the focus moves out of the button
|
||||
// The blur makes the button lose the hover state and these menu are not shown
|
||||
// We delay the blur event to give time to the focus to move to the menu
|
||||
onBlur={() => setIsHoverWithDelay(false, 10)}
|
||||
tabIndex={isActive ? 0 : -1}
|
||||
{...props}
|
||||
>
|
||||
{/* We need this extra div between the button and the content in order to add a padding which is not messing with the virtualized list */}
|
||||
@@ -79,13 +94,19 @@ export const RoomListItemView = memo(function RoomListItemView({
|
||||
</div>
|
||||
<div className="mx_RoomListItemView_messagePreview">{vm.messagePreview}</div>
|
||||
</div>
|
||||
{showHoverDecoration ? (
|
||||
{showHoverMenu ? (
|
||||
<RoomListItemMenuView
|
||||
room={room}
|
||||
setMenuOpen={(isOpen) => {
|
||||
if (isOpen) setIsMenuOpen(isOpen);
|
||||
// To avoid icon blinking when closing the menu, we delay the state update
|
||||
else setTimeout(() => setIsMenuOpen(isOpen), 0);
|
||||
if (isOpen) {
|
||||
setIsMenuOpen(isOpen);
|
||||
} else {
|
||||
// To avoid icon blinking when closing the menu, we delay the state update
|
||||
setTimeout(() => setIsMenuOpen(isOpen), 0);
|
||||
// After closing the menu, we need to set the focus back to the button
|
||||
// 10ms because the focus moves to the body and we put back the focus on the button
|
||||
setTimeout(() => buttonRef.current?.focus(), 10);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
@@ -105,3 +126,33 @@ export const RoomListItemView = memo(function RoomListItemView({
|
||||
</button>
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* Custom hook to manage the hover state of the room list item
|
||||
* If the timeout is set, it will set the hover state after the timeout
|
||||
* If the timeout is not set, it will set the hover state immediately
|
||||
* When the set method is called, it will clear any existing timeout
|
||||
*
|
||||
* @returns {boolean} isHover - The hover state
|
||||
*/
|
||||
function useIsHover(): [boolean, (value: boolean, timeout?: number) => void] {
|
||||
const [isHover, setIsHover] = useState(false);
|
||||
// Store the timeout ID
|
||||
const timeoutRef = useRef<number | undefined>(undefined);
|
||||
|
||||
const setIsHoverWithDelay = useCallback((value: boolean, timeout?: number): void => {
|
||||
// Clear the timeout if it exists
|
||||
clearTimeout(timeoutRef.current);
|
||||
|
||||
// No delay, set the value immediately
|
||||
if (timeout === undefined) {
|
||||
setIsHover(value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set a timeout to set the value after the delay
|
||||
timeoutRef.current = setTimeout(() => setIsHover(value), timeout);
|
||||
}, []);
|
||||
|
||||
return [isHover, setIsHoverWithDelay];
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ Please see LICENSE files in the repository root for full details.
|
||||
import React, { lazy, Suspense, useCallback, useContext, useEffect, useRef, useState } from "react";
|
||||
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { defer } from "matrix-js-sdk/src/utils";
|
||||
|
||||
import { _t } from "../../../../../languageHandler";
|
||||
import Modal from "../../../../../Modal";
|
||||
@@ -98,7 +97,7 @@ const useSignOut = (
|
||||
const url = getManageDeviceUrl(delegatedAuthAccountUrl, deviceId);
|
||||
window.open(url, "_blank");
|
||||
} else {
|
||||
const deferredSuccess = defer<boolean>();
|
||||
const deferredSuccess = Promise.withResolvers<boolean>();
|
||||
await deleteDevicesWithInteractiveAuth(matrixClient, deviceIds, async (success) => {
|
||||
deferredSuccess.resolve(!!success);
|
||||
});
|
||||
|
||||
@@ -24,10 +24,7 @@ import { type NotificationLevel } from "../../../../stores/notifications/Notific
|
||||
import PosthogTrackers from "../../../../PosthogTrackers";
|
||||
import { getKeyBindingsManager } from "../../../../KeyBindingsManager";
|
||||
import { KeyBindingAction } from "../../../../accessibility/KeyboardShortcuts";
|
||||
import { ReleaseAnnouncement } from "../../../structures/ReleaseAnnouncement";
|
||||
import { useIsReleaseAnnouncementOpen } from "../../../../hooks/useIsReleaseAnnouncementOpen";
|
||||
import { useSettingValue } from "../../../../hooks/useSettings";
|
||||
import { ReleaseAnnouncementStore } from "../../../../stores/ReleaseAnnouncementStore";
|
||||
|
||||
interface ThreadsActivityCentreProps {
|
||||
/**
|
||||
@@ -43,7 +40,6 @@ interface ThreadsActivityCentreProps {
|
||||
export function ThreadsActivityCentre({ displayButtonLabel }: ThreadsActivityCentreProps): JSX.Element {
|
||||
const [open, setOpen] = useState(false);
|
||||
const roomsAndNotifications = useUnreadThreadRooms(open);
|
||||
const isReleaseAnnouncementOpen = useIsReleaseAnnouncementOpen("threadsActivityCentre");
|
||||
const settingTACOnlyNotifs = useSettingValue("Notifications.tac_only_notifications");
|
||||
|
||||
const emptyCaption = settingTACOnlyNotifs
|
||||
@@ -65,59 +61,39 @@ export function ThreadsActivityCentre({ displayButtonLabel }: ThreadsActivityCen
|
||||
}
|
||||
}}
|
||||
>
|
||||
{isReleaseAnnouncementOpen ? (
|
||||
<ReleaseAnnouncement
|
||||
feature="threadsActivityCentre"
|
||||
header={_t("threads_activity_centre|release_announcement_header")}
|
||||
description={_t("threads_activity_centre|release_announcement_description")}
|
||||
closeLabel={_t("action|ok")}
|
||||
>
|
||||
<Menu
|
||||
align="start"
|
||||
side="top"
|
||||
open={open}
|
||||
onOpenChange={(newOpen) => {
|
||||
// Track only when the Threads Activity Centre is opened
|
||||
if (newOpen) PosthogTrackers.trackInteraction("WebThreadsActivityCentreButton");
|
||||
|
||||
setOpen(newOpen);
|
||||
}}
|
||||
title={_t("threads_activity_centre|header")}
|
||||
trigger={
|
||||
<ThreadsActivityCentreButton
|
||||
disableTooltip={true}
|
||||
displayLabel={displayButtonLabel}
|
||||
notificationLevel={roomsAndNotifications.greatestNotificationLevel}
|
||||
onClick={async () => {
|
||||
// Open the TAC after the release announcement closing
|
||||
setOpen(true);
|
||||
await ReleaseAnnouncementStore.instance.nextReleaseAnnouncement();
|
||||
}}
|
||||
/>
|
||||
</ReleaseAnnouncement>
|
||||
) : (
|
||||
<Menu
|
||||
align="start"
|
||||
side="top"
|
||||
open={open}
|
||||
onOpenChange={(newOpen) => {
|
||||
// Track only when the Threads Activity Centre is opened
|
||||
if (newOpen) PosthogTrackers.trackInteraction("WebThreadsActivityCentreButton");
|
||||
|
||||
setOpen(newOpen);
|
||||
}}
|
||||
title={_t("threads_activity_centre|header")}
|
||||
trigger={
|
||||
<ThreadsActivityCentreButton
|
||||
displayLabel={displayButtonLabel}
|
||||
notificationLevel={roomsAndNotifications.greatestNotificationLevel}
|
||||
}
|
||||
>
|
||||
{/* Make the content of the pop-up scrollable */}
|
||||
<div className="mx_ThreadsActivityCentre_rows">
|
||||
{roomsAndNotifications.rooms.map(({ room, notificationLevel }) => (
|
||||
<ThreadsActivityCentreRow
|
||||
key={room.roomId}
|
||||
room={room}
|
||||
notificationLevel={notificationLevel}
|
||||
onClick={() => setOpen(false)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
{/* Make the content of the pop-up scrollable */}
|
||||
<div className="mx_ThreadsActivityCentre_rows">
|
||||
{roomsAndNotifications.rooms.map(({ room, notificationLevel }) => (
|
||||
<ThreadsActivityCentreRow
|
||||
key={room.roomId}
|
||||
room={room}
|
||||
notificationLevel={notificationLevel}
|
||||
onClick={() => setOpen(false)}
|
||||
/>
|
||||
))}
|
||||
{roomsAndNotifications.rooms.length === 0 && (
|
||||
<div className="mx_ThreadsActivityCentre_emptyCaption">{emptyCaption}</div>
|
||||
)}
|
||||
</div>
|
||||
</Menu>
|
||||
)}
|
||||
))}
|
||||
{roomsAndNotifications.rooms.length === 0 && (
|
||||
<div className="mx_ThreadsActivityCentre_emptyCaption">{emptyCaption}</div>
|
||||
)}
|
||||
</div>
|
||||
</Menu>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,26 +66,15 @@ interface IState {
|
||||
}
|
||||
|
||||
function getFullScreenElement(): Element | null {
|
||||
return (
|
||||
document.fullscreenElement ||
|
||||
// moz omitted because firefox supports this unprefixed now (webkit here for safari)
|
||||
document.webkitFullscreenElement ||
|
||||
document.msFullscreenElement
|
||||
);
|
||||
return document.fullscreenElement;
|
||||
}
|
||||
|
||||
function requestFullscreen(element: Element): void {
|
||||
const method =
|
||||
element.requestFullscreen ||
|
||||
// moz omitted since firefox supports unprefixed now
|
||||
element.webkitRequestFullScreen ||
|
||||
element.msRequestFullscreen;
|
||||
if (method) method.call(element);
|
||||
element.requestFullscreen();
|
||||
}
|
||||
|
||||
function exitFullscreen(): void {
|
||||
const exitMethod = document.exitFullscreen || document.webkitExitFullscreen || document.msExitFullscreen;
|
||||
if (exitMethod) exitMethod.call(document);
|
||||
document.exitFullscreen();
|
||||
}
|
||||
|
||||
export default class LegacyCallView extends React.Component<IProps, IState> {
|
||||
|
||||
@@ -26,6 +26,11 @@ export enum Action {
|
||||
*/
|
||||
ViewUser = "view_user",
|
||||
|
||||
/**
|
||||
* Share a text message by forwarding it to a room selected by the user
|
||||
*/
|
||||
Share = "share",
|
||||
|
||||
/**
|
||||
* Open the user settings. No additional payload information required.
|
||||
* Optionally can include an OpenToTabPayload.
|
||||
|
||||
29
src/dispatcher/payloads/SharePayload.ts
Normal file
29
src/dispatcher/payloads/SharePayload.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type ActionPayload } from "../payloads";
|
||||
import { type Action } from "../actions";
|
||||
|
||||
export enum ShareFormat {
|
||||
Text = "text",
|
||||
Html = "html",
|
||||
Markdown = "md",
|
||||
}
|
||||
|
||||
export interface SharePayload extends ActionPayload {
|
||||
action: Action.Share;
|
||||
|
||||
/**
|
||||
* The format of message to be shared (optional)
|
||||
*/
|
||||
format: ShareFormat;
|
||||
|
||||
/**
|
||||
* The message to be shared.
|
||||
*/
|
||||
msg: string;
|
||||
}
|
||||
@@ -388,6 +388,7 @@
|
||||
"fallback_button": "Zahájit autentizaci",
|
||||
"mas_cross_signing_reset_cta": "Přejděte na svůj účet",
|
||||
"mas_cross_signing_reset_description": "Resetujte svou identitu prostřednictvím svého poskytovatele účtu a poté se vraťte a klikněte na \"Opakovat\".",
|
||||
"mas_cross_signing_reset_title": "Přejděte na svůj účet a obnovte svou identitu",
|
||||
"msisdn": "Na číslo %(msisdn)s byla odeslána textová zpráva",
|
||||
"msisdn_token_incorrect": "Neplatný token",
|
||||
"msisdn_token_prompt": "Prosím zadejte kód z této zprávy:",
|
||||
@@ -995,7 +996,6 @@
|
||||
"accepting": "Přijímání…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Zařízení ověřeno",
|
||||
"reset_confirmation": "Opravdu chcete resetovat ověřovací klíče?",
|
||||
"skip_verification": "Prozatím přeskočit ověřování",
|
||||
"unable_to_verify": "Nelze ověřit toto zařízení",
|
||||
"verify_this_device": "Ověřit toto zařízení"
|
||||
@@ -1066,8 +1066,6 @@
|
||||
"verify_emoji_prompt": "Ověření porovnáním několika emoji.",
|
||||
"verify_emoji_prompt_qr": "Pokud vám skenování kódů nefunguje, ověřte se porovnáním emoji.",
|
||||
"verify_later": "Ověřím se později",
|
||||
"verify_reset_warning_1": "Resetování ověřovacích klíčů nelze vrátit zpět. Po jejich resetování nebudete mít přístup ke starým zašifrovaným zprávám a všem přátelům, kteří vás dříve ověřili, se zobrazí bezpečnostní varování, dokud se u nich znovu neověříte.",
|
||||
"verify_reset_warning_2": "Pokračujte pouze v případě, že jste si jisti, že jste ztratili všechna ostatní zařízení a klíč pro obnovení.",
|
||||
"verify_using_device": "Ověřit pomocí jiného zařízení",
|
||||
"verify_using_key": "Ověřit pomocí klíče pro obnovení",
|
||||
"verify_using_key_or_phrase": "Ověření pomocí klíče pro obnovení nebo fráze",
|
||||
@@ -2127,6 +2125,7 @@
|
||||
"failed_add_tag": "Nepodařilo se přidat štítek %(tagName)s k místnosti",
|
||||
"failed_remove_tag": "Nepodařilo se odstranit štítek %(tagName)s z místnosti",
|
||||
"failed_set_dm_tag": "Nepodařilo se nastavit značku přímé zprávy",
|
||||
"filter": "Filtr",
|
||||
"filters": {
|
||||
"favourite": "Oblíbené",
|
||||
"people": "Lidé",
|
||||
@@ -2160,6 +2159,12 @@
|
||||
"open_room": "Otevřít místnost %(roomName)s"
|
||||
},
|
||||
"room_options": "Možnosti místnosti",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Veškerá aktivita",
|
||||
"invites_only": "Pouze pozvané",
|
||||
"low_priority": "Nízká priorita",
|
||||
"mentions_only": "Pouze zmínky"
|
||||
},
|
||||
"secondary_filters": "Sekundární filtry",
|
||||
"show_less": "Zobrazit méně",
|
||||
"show_message_previews": "Zobrazit náhledy zpráv",
|
||||
@@ -2458,6 +2463,10 @@
|
||||
"recent_changes_heading": "Nedávné změny, které dosud nebyly přijaty",
|
||||
"title": "Server neodpovídá"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s vyžaduje service worker pro načítání ověřených médií z úložiště obsahu Matrixu. Váš prohlížeč to nepodporuje, takže může dojít k selhání načtení médií.",
|
||||
"title": "Nepodařilo se načíst service worker"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Inicializace vyhledávání zpráv se nezdařila, zkontrolujte <a>svá nastavení</a>",
|
||||
"reset_button": "Resetovat úložiště událostí",
|
||||
@@ -2636,6 +2645,7 @@
|
||||
"discovery_needs_terms_title": "Umožněte lidem, aby vás našli",
|
||||
"display_name": "Zobrazovaný název",
|
||||
"display_name_error": "Nelze nastavit zobrazovaný název",
|
||||
"email_adding_unsupported_by_hs": "Tento domovský server nepodporuje přidávání e-mailových adres do vašeho účtu.",
|
||||
"email_address_in_use": "Tato e-mailová adresa je již používána",
|
||||
"email_address_label": "E-mailová adresa",
|
||||
"email_not_verified": "Vaše e-mailová adresa ještě nebyla ověřena",
|
||||
@@ -2660,7 +2670,9 @@
|
||||
"error_share_msisdn_discovery": "Nepovedlo se nasdílet telefonní číslo",
|
||||
"identity_server_no_token": "Nebyl nalezen žádný přístupový token identity",
|
||||
"identity_server_not_set": "Server identit není nastaven",
|
||||
"invalid_phone_number": "Zadané telefonní číslo se nezdá být platné.",
|
||||
"language_section": "Jazyk",
|
||||
"msisdn_adding_unsupported_by_hs": "Tento domovský server nepodporuje přidávání telefonních čísel do vašeho účtu.",
|
||||
"msisdn_in_use": "Toto telefonní číslo je již používáno",
|
||||
"msisdn_label": "Telefonní číslo",
|
||||
"msisdn_verification_field_label": "Ověřovací kód",
|
||||
@@ -3233,7 +3245,7 @@
|
||||
"heading_without_query": "Hledat",
|
||||
"join_button_text": "Vstoupit do %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "K pohybu použijte <arrows/>",
|
||||
"message_search_section_title": "Další vyhledávání",
|
||||
"messages_label": "Zprávy",
|
||||
"other_rooms_in_space": "Další místnosti v %(spaceName)s",
|
||||
"public_rooms_label": "Veřejné místnosti",
|
||||
"public_spaces_label": "Veřejné prostory",
|
||||
@@ -3243,7 +3255,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Některé výsledky mohou být z důvodu ochrany soukromí skryté",
|
||||
"result_may_be_hidden_warning": "Některé výsledky mohou být skryté",
|
||||
"search_dialog": "Dialogové okno hledání",
|
||||
"search_messages_hint": "Pro vyhledávání zpráv hledejte tuto ikonu v horní části místnosti <icon/>",
|
||||
"spaces_title": "Prostory, ve kterých se nacházíte",
|
||||
"start_group_chat_button": "Zahájit skupinový chat"
|
||||
},
|
||||
@@ -3292,9 +3303,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Aktivita vláken",
|
||||
"no_rooms_with_threads_notifs": "Zatím nemáte k dispozici místnosti s upozorněními na vlákna.",
|
||||
"no_rooms_with_unread_threads": "Zatím nemáte místnosti s nepřečtenými vlákny.",
|
||||
"release_announcement_description": "Oznámení o vláknech se přesunula, od nynějška je najdete zde.",
|
||||
"release_announcement_header": "Centrum aktivity vláken"
|
||||
"no_rooms_with_unread_threads": "Zatím nemáte místnosti s nepřečtenými vlákny."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "před jedním dnem",
|
||||
@@ -3805,10 +3814,11 @@
|
||||
"unavailable": "Nedostupné"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Chcete-li vytvořit sdílený odkaz, musíte hostům povolit, aby se k této místnosti připojili. Může se tak stát, že místnost bude méně bezpečná. Po dokončení hovoru můžete místnost opět učinit soukromou.",
|
||||
"dont_change_description": "Případně můžete hovor uskutečnit v oddělené místnosti.",
|
||||
"description": "Chcete-li vytvořit sdílený odkaz, nastavte tuto místnost <b>veřejnou</b> nebo povolte možnost, aby uživatelé <b>požádali o vstup</b>. To umožňuje hostům připojit se, aniž by byli pozváni.",
|
||||
"dont_change_description": "Pokud nechcete změnit přístup k této místnosti, můžete pro odkaz na hovor vytvořit novou místnost.",
|
||||
"no_change": "Nechci měnit úroveň přístupu.",
|
||||
"title": "Změna úrovně přístupu do místnosti"
|
||||
"revert_access_description": "(Tuto hodnotu lze vrátit na předchozí hodnotu v Nastavení místnosti: <b>Zabezpečení a soukromí</b> / <b>Přístup</b>)",
|
||||
"title": "Povolit hostům vstup do této místnosti"
|
||||
},
|
||||
"upload_failed_generic": "Soubor '%(fileName)s' se nepodařilo nahrát.",
|
||||
"upload_failed_size": "Soubor '%(fileName)s' je větší než povoluje limit domovského serveru",
|
||||
|
||||
@@ -989,7 +989,6 @@
|
||||
"accepting": "Yn derbyn…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Dyfais wedi'i dilysu",
|
||||
"reset_confirmation": "Ailosod allweddi dilysu mewn gwirionedd?",
|
||||
"skip_verification": "Hepgor dilysu am y tro",
|
||||
"unable_to_verify": "Methu â gwirio'r ddyfais hon",
|
||||
"verify_this_device": "Dilyswch y ddyfais hon"
|
||||
@@ -1060,8 +1059,6 @@
|
||||
"verify_emoji_prompt": "Gwiriwch trwy gymharu emoji unigryw.",
|
||||
"verify_emoji_prompt_qr": "Os na allwch sganio'r cod uchod, gwiriwch trwy gymharu emoji unigryw.",
|
||||
"verify_later": "Byddaf yn gwirio yn ddiweddarach",
|
||||
"verify_reset_warning_1": "Nid oes modd dadwneud ailosod eich allweddi dilysu. Ar ôl ailosod, ni fydd gennych fynediad i hen negeseuon wedi'u hamgryptio, a bydd unrhyw ffrindiau sydd wedi'ch dilysu o'r blaen yn gweld rhybuddion diogelwch nes i chi ail-ddilysu gyda nhw.",
|
||||
"verify_reset_warning_2": "Mynd ymlaen dim ond os ydych yn siŵr eich bod wedi colli eich holl ddyfeisiau eraill a'ch Allwedd Adfer.",
|
||||
"verify_using_device": "Gwiriwch gyda dyfais arall",
|
||||
"verify_using_key": "Dilyswch gydag Allwedd Adfer",
|
||||
"verify_using_key_or_phrase": "Dilyswch gydag Allwedd Adfer neu Ymadrodd",
|
||||
@@ -3070,7 +3067,6 @@
|
||||
"heading_without_query": "Chwilio am",
|
||||
"join_button_text": "Ymuno â %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Defnydd<arrows/> i sgrolio",
|
||||
"message_search_section_title": "Chwiliadau eraill",
|
||||
"other_rooms_in_space": "Ystafelloedd eraill yn %(spaceName)s",
|
||||
"public_rooms_label": "Ystafelloedd cyhoeddus",
|
||||
"public_spaces_label": "Gofodau cyhoeddus",
|
||||
@@ -3080,7 +3076,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Gall rhai canlyniadau gael eu cuddio er preifatrwydd",
|
||||
"result_may_be_hidden_warning": "Efallai y bydd rhai canlyniadau wedi'u cuddio",
|
||||
"search_dialog": "Deialog Chwilio",
|
||||
"search_messages_hint": "I chwilio negeseuon, edrychwch am yr eicon hwn ar frig ystafell<icon/>",
|
||||
"spaces_title": "Gofodau rydych chi ynddyn nhw",
|
||||
"start_group_chat_button": "Dechreuwch sgwrs grŵp"
|
||||
},
|
||||
@@ -3125,9 +3120,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Gweithgaredd edafedd",
|
||||
"no_rooms_with_threads_notifs": "Nid oes gennych chi ystafelloedd gyda hysbysiadau edafedd eto.",
|
||||
"no_rooms_with_unread_threads": "Nid oes gennych chi ystafelloedd ag edafedd heb eu darllen eto.",
|
||||
"release_announcement_description": "Mae hysbysiadau edafedd wedi symud, dewch o hyd iddyn nhw yma o hyn ymlaen.",
|
||||
"release_announcement_header": "Canolfan Gweithgareddau Edafedd"
|
||||
"no_rooms_with_unread_threads": "Nid oes gennych chi ystafelloedd ag edafedd heb eu darllen eto."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "tua diwrnod yn ôl",
|
||||
|
||||
@@ -386,6 +386,7 @@
|
||||
"fallback_button": "Authentifizierung beginnen",
|
||||
"mas_cross_signing_reset_cta": "Gehen Sie zu Ihren Konto",
|
||||
"mas_cross_signing_reset_description": "Setzen Sie Ihre Identität über Ihren Kontoanbieter zurück. Kommen Sie dann zurück und klicken Sie auf „Wiederholen“.",
|
||||
"mas_cross_signing_reset_title": "Gehen sie zu ihrem Konto, um ihre Identität zurückzusetzen",
|
||||
"msisdn": "Eine Textnachricht wurde an %(msisdn)s gesendet",
|
||||
"msisdn_token_incorrect": "Token fehlerhaft",
|
||||
"msisdn_token_prompt": "Bitte gib den darin enthaltenen Code ein:",
|
||||
@@ -782,7 +783,7 @@
|
||||
"cross_signing_public_keys_on_device_status": "Überkreuzsignierung öffentlicher Schlüssel:",
|
||||
"cross_signing_ready": "Kreuzsignatur ist einsatzbereit.",
|
||||
"cross_signing_status": "Status der Kreuzsignatur",
|
||||
"cross_signing_untrusted": "Ihr Konto verfügt über eine Cross-Signing-Identität im geheimen Speicher, diese wird von dieser Sitzung jedoch noch nicht als vertrauenswürdig eingestuft.",
|
||||
"cross_signing_untrusted": "Ihr Konto hat eine Cross-Signing-Identität im sicheren Speicher, der von dieser Sitzung jedoch noch nicht als vertrauenswürdig eingestuft wird.",
|
||||
"crypto_not_available": "Das kryptografische Modul ist nicht verfügbar",
|
||||
"key_backup_active_version": "Aktive Backup Version:",
|
||||
"key_backup_active_version_none": "Keine",
|
||||
@@ -993,7 +994,6 @@
|
||||
"accepting": "Annehmen…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Gerät verifiziert",
|
||||
"reset_confirmation": "Willst du deine Verifizierungsschlüssel wirklich zurücksetzen?",
|
||||
"skip_verification": "Verifizierung vorläufig überspringen",
|
||||
"unable_to_verify": "Gerät konnte nicht verifiziert werden",
|
||||
"verify_this_device": "Dieses Gerät verifizieren"
|
||||
@@ -1064,8 +1064,6 @@
|
||||
"verify_emoji_prompt": "Durch den Vergleich einzigartiger Emojis verifizieren.",
|
||||
"verify_emoji_prompt_qr": "Wenn du obigen Code nicht erfassen kannst, verifiziere stattdessen durch den Vergleich von Emojis.",
|
||||
"verify_later": "Später verifizieren",
|
||||
"verify_reset_warning_1": "Das Zurücksetzen deiner Sicherheitsschlüssel kann nicht rückgängig gemacht werden. Nach dem Zurücksetzen wirst du alte Nachrichten nicht mehr lesen können und Freunde, die dich vorher verifiziert haben werden Sicherheitswarnungen bekommen, bis du dich erneut mit ihnen verifizierst.",
|
||||
"verify_reset_warning_2": "Bitte fahren Sie nur fort, wenn Sie sicher sind, dass Sie Ihren Zugang zu allen anderen Geräte und Ihren Wiederherstellungsschlüssel verloren haben.",
|
||||
"verify_using_device": "Mit anderem Gerät verifizieren",
|
||||
"verify_using_key": "Mit Wiederherstellungsschlüssel verifizieren",
|
||||
"verify_using_key_or_phrase": "Mit Wiederherstellungsschlüssel oder Wiederherstellungsphrase verifizieren",
|
||||
@@ -1974,7 +1972,7 @@
|
||||
},
|
||||
"room_is_public": "Dieser Raum ist öffentlich"
|
||||
},
|
||||
"header_avatar_open_settings_label": "Chatroomeinstellungen öffnen",
|
||||
"header_avatar_open_settings_label": "Raumeinstellungen öffnen",
|
||||
"header_face_pile_tooltip": "Personen",
|
||||
"header_untrusted_label": "Nicht vertrauenswürdig",
|
||||
"inaccessible": "Dieser Raum oder Space ist im Moment nicht zugänglich.",
|
||||
@@ -2101,6 +2099,7 @@
|
||||
"room_list": {
|
||||
"add_room_label": "Raum hinzufügen",
|
||||
"add_space_label": "Space hinzufügen",
|
||||
"appearance": "Erscheinungsbild",
|
||||
"breadcrumbs_empty": "Keine kürzlich besuchten Räume",
|
||||
"breadcrumbs_label": "Kürzlich besuchte Räume",
|
||||
"empty": {
|
||||
@@ -2119,6 +2118,7 @@
|
||||
"failed_add_tag": "Fehler beim Hinzufügen des \"%(tagName)s\"-Tags an dem Raum",
|
||||
"failed_remove_tag": "Entfernen der Raum-Kennzeichnung %(tagName)s fehlgeschlagen",
|
||||
"failed_set_dm_tag": "Fehler beim Setzen der Nachrichtenmarkierung",
|
||||
"filter": "Filter",
|
||||
"filters": {
|
||||
"favourite": "Favoriten",
|
||||
"people": "Personen",
|
||||
@@ -2151,7 +2151,16 @@
|
||||
"more_options": "Weitere Optionen",
|
||||
"open_room": "Raum öffnen %(roomName)s"
|
||||
},
|
||||
"room_options": "Chatroomoptionen",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Alle Aktivitäten",
|
||||
"invites_only": "Nur Einladungen",
|
||||
"low_priority": "Niedrige Priorität",
|
||||
"mentions_only": "Nur Erwähnungen"
|
||||
},
|
||||
"secondary_filters": "Sekundäre Filter",
|
||||
"show_less": "Weniger anzeigen",
|
||||
"show_message_previews": "Nachrichtenvorschau anzeigen",
|
||||
"show_n_more": {
|
||||
"other": "%(count)s weitere anzeigen",
|
||||
"one": "%(count)s weitere anzeigen"
|
||||
@@ -2447,6 +2456,10 @@
|
||||
"recent_changes_heading": "Letzte Änderungen, die noch nicht eingegangen sind",
|
||||
"title": "Server reagiert nicht"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s benötigt einen Service Worker zum Laden authentifizierter Medien aus Matrix-Inhaltsrepositorys. Dies wird von Ihrem Browser nicht unterstützt, sodass Medien möglicherweise nicht geladen werden können.",
|
||||
"title": "Service Worker konnte nicht geladen werden"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Initialisierung der Suche fehlgeschlagen, für weitere Informationen öffne <a>deine Einstellungen</a>",
|
||||
"reset_button": "Ereignisspeicher zurück setzen",
|
||||
@@ -2625,6 +2638,7 @@
|
||||
"discovery_needs_terms_title": "Lassen Sie sich von anderen finden",
|
||||
"display_name": "Anzeigename",
|
||||
"display_name_error": "Anzeigename konnte nicht gesetzt werden",
|
||||
"email_adding_unsupported_by_hs": "Dieser Homeserver unterstützt das Hinzufügen von E-Mail-Adressen zu Ihrem Konto nicht.",
|
||||
"email_address_in_use": "Diese E-Mail-Adresse wird bereits verwendet",
|
||||
"email_address_label": "E-Mail-Adresse",
|
||||
"email_not_verified": "Deine E-Mail-Adresse wurde noch nicht verifiziert",
|
||||
@@ -2649,7 +2663,9 @@
|
||||
"error_share_msisdn_discovery": "Teilen der Telefonnummer nicht möglich",
|
||||
"identity_server_no_token": "Kein Identitäts-Zugangs-Token gefunden",
|
||||
"identity_server_not_set": "Kein Identitäts-Server festgelegt",
|
||||
"invalid_phone_number": "Die angegebene Telefonnummer scheint nicht gültig zu sein.",
|
||||
"language_section": "Sprache",
|
||||
"msisdn_adding_unsupported_by_hs": "Dieser Homeserver unterstützt das Hinzufügen von Telefonnummern zu Ihrem Konto nicht.",
|
||||
"msisdn_in_use": "Diese Telefonnummer wird bereits verwendet",
|
||||
"msisdn_label": "Telefonnummer",
|
||||
"msisdn_verification_field_label": "Bestätigungscode",
|
||||
@@ -3221,7 +3237,7 @@
|
||||
"heading_without_query": "Suche nach",
|
||||
"join_button_text": "%(roomAddress)s betreten",
|
||||
"keyboard_scroll_hint": "Benutze <arrows/> zum Scrollen",
|
||||
"message_search_section_title": "Andere Suchen",
|
||||
"messages_label": "Nachrichten",
|
||||
"other_rooms_in_space": "Andere Räume in %(spaceName)s",
|
||||
"public_rooms_label": "Öffentliche Räume",
|
||||
"public_spaces_label": "Öffentliche Spaces",
|
||||
@@ -3231,7 +3247,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Einige Vorschläge könnten aus Gründen der Privatsphäre ausgeblendet sein",
|
||||
"result_may_be_hidden_warning": "Einige Ergebnisse können ausgeblendet sein",
|
||||
"search_dialog": "Suchdialog",
|
||||
"search_messages_hint": "Wenn du Nachrichten durchsuchen willst, klicke auf das <icon/> Icon oberhalb des Raumes",
|
||||
"spaces_title": "Spaces, in denen du Mitglied bist",
|
||||
"start_group_chat_button": "Gruppenunterhaltung beginnen"
|
||||
},
|
||||
@@ -3280,9 +3295,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Thread-Aktivität",
|
||||
"no_rooms_with_threads_notifs": "Sie haben noch keine Chatrooms mit Thread-Benachrichtigungen.",
|
||||
"no_rooms_with_unread_threads": "Sie haben noch keine Chatrooms mit ungelesenen Threads.",
|
||||
"release_announcement_description": "Die Thread-Benachrichtigungen wurden verschoben. Sie finden sie ab sofort hier.",
|
||||
"release_announcement_header": "Thread Aktivitätszentrum"
|
||||
"no_rooms_with_unread_threads": "Sie haben noch keine Chatrooms mit ungelesenen Threads."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "vor etwa einem Tag",
|
||||
@@ -3793,10 +3806,11 @@
|
||||
"unavailable": "Nicht verfügbar"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Um einen Link zum Teilen zu erstellen, müssen Sie Gästen erlauben, diesem Chatroom beizutreten. Dadurch kann der Chatroom weniger sicher werden. Wenn Sie mit dem Anruf fertig sind, können Sie den Raum wieder privat machen.",
|
||||
"dont_change_description": "Sie können den Anruf auch in einem separaten Chatroom führen.",
|
||||
"description": "Um einen Link zum Teilen zu erstellen, mache diesen Chatroom <b> öffentlich </b> oder erlaube <b>Beitrittsanfragen</b>. Auf diese Weise können Gäste beitreten, ohne eingeladen zu werden.",
|
||||
"dont_change_description": "Andernfalls, wenn Sie den Zugang dieses Raumes nicht anpassen möchten, können sie einen neuen Raum für den Anruflink erstellen.",
|
||||
"no_change": "Ich möchte die Zugriffsebene nicht ändern.",
|
||||
"title": "Ändern Sie die Zugriffsebene des Chatrooms."
|
||||
"revert_access_description": "(Dies kann in den Raumeinstellungen auf den vorherigen Wert zurückgesetzt werden: <b> Sicherheit & Datenschutz</b>/<b>Zutritt</b>)",
|
||||
"title": "Gastbenutzern erlauben, diesem Raum beizutreten"
|
||||
},
|
||||
"upload_failed_generic": "Die Datei „%(fileName)s“ konnte nicht hochgeladen werden.",
|
||||
"upload_failed_size": "Die Datei „%(fileName)s“ überschreitet das Hochladelimit deines Heim-Servers",
|
||||
|
||||
@@ -782,7 +782,6 @@
|
||||
"accepting": "Αποδοχή …",
|
||||
"after_new_login": {
|
||||
"device_verified": "Η συσκευή επαληθεύτηκε",
|
||||
"reset_confirmation": "Είστε σίγουρος ότι θέλετε να επαναφέρετε τα κλειδιά επαλήθευσης;",
|
||||
"skip_verification": "Παράβλεψη επαλήθευσης προς το παρόν",
|
||||
"unable_to_verify": "Αδυναμία επαλήθευσης αυτής της συσκευής",
|
||||
"verify_this_device": "Επαληθεύστε αυτήν τη συσκευή"
|
||||
@@ -845,7 +844,6 @@
|
||||
"verify_emoji_prompt": "Επαληθεύστε συγκρίνοντας μοναδικά emoji.",
|
||||
"verify_emoji_prompt_qr": "Εάν δεν μπορείτε να σαρώσετε τον παραπάνω κώδικα, επαληθεύστε το συγκρίνοντας μοναδικά emoji.",
|
||||
"verify_later": "Θα επαληθεύσω αργότερα",
|
||||
"verify_reset_warning_1": "Δεν είναι δυνατή η αναίρεση της επαναφοράς των κλειδιών επαλήθευσης. Μετά την επαναφορά, δε θα έχετε πρόσβαση σε παλιά κρυπτογραφημένα μηνύματα και όλοι οι φίλοι που σας έχουν προηγουμένως επαληθεύσει θα βλέπουν προειδοποιήσεις ασφαλείας μέχρι να επαληθεύσετε ξανά μαζί τους.",
|
||||
"verify_using_device": "Επαλήθευση με άλλη συσκευή",
|
||||
"verify_using_key": "Επαλήθευση με Κλειδί ασφαλείας",
|
||||
"verify_using_key_or_phrase": "Επαλήθευση με Κλειδί Ασφαλείας ή Φράση Ασφαλείας",
|
||||
@@ -2438,7 +2436,6 @@
|
||||
"heading_without_query": "Αναζήτηση για",
|
||||
"join_button_text": "Συμμετοχή στο %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Χρησιμοποιήστε τα <arrows/> για κύλιση",
|
||||
"message_search_section_title": "'Άλλες αναζητήσεις",
|
||||
"other_rooms_in_space": "Άλλα δωμάτιο στο %(spaceName)s",
|
||||
"public_rooms_label": "Δημόσια δωμάτια",
|
||||
"recent_searches_section_title": "Πρόσφατες αναζητήσεις",
|
||||
@@ -2446,7 +2443,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Ορισμένα αποτελέσματα ενδέχεται να είναι κρυφά για λόγους απορρήτου",
|
||||
"result_may_be_hidden_warning": "Ορισμένα αποτελέσματα ενδέχεται να είναι κρυμμένα",
|
||||
"search_dialog": "Παράθυρο Αναζήτησης",
|
||||
"search_messages_hint": "Για να αναζητήσετε μηνύματα, βρείτε αυτό το εικονίδιο στην κορυφή ενός δωματίου <icon/>",
|
||||
"spaces_title": "Χώροι που ανήκετε",
|
||||
"start_group_chat_button": "Ξεκινήστε μια ομαδική συνομιλία"
|
||||
},
|
||||
|
||||
@@ -2457,6 +2457,10 @@
|
||||
"recent_changes_heading": "Recent changes that have not yet been received",
|
||||
"title": "Server isn't responding"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s requires a service worker for loading authenticated media from Matrix content repositories. This is not supported by your browser so you may experience media failing to load.",
|
||||
"title": "Failed to load service worker"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Message search initialisation failed, check <a>your settings</a> for more information",
|
||||
"reset_button": "Reset event store",
|
||||
@@ -3292,9 +3296,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Threads activity",
|
||||
"no_rooms_with_threads_notifs": "You don't have rooms with thread notifications yet.",
|
||||
"no_rooms_with_unread_threads": "You don't have rooms with unread threads yet.",
|
||||
"release_announcement_description": "Threads notifications have moved, find them here from now on.",
|
||||
"release_announcement_header": "Threads Activity Centre"
|
||||
"no_rooms_with_unread_threads": "You don't have rooms with unread threads yet."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "about a day ago",
|
||||
|
||||
@@ -813,7 +813,6 @@
|
||||
"accepting": "Aceptando…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Dispositivo verificado",
|
||||
"reset_confirmation": "¿De verdad quieres restablecer las claves de verificación?",
|
||||
"skip_verification": "Saltar la verificación por ahora",
|
||||
"unable_to_verify": "No se ha podido verificar el dispositivo",
|
||||
"verify_this_device": "Verificar este dispositivo"
|
||||
@@ -883,7 +882,6 @@
|
||||
"verify_emoji_prompt": "Verifica comparando emoji únicos.",
|
||||
"verify_emoji_prompt_qr": "Si no puedes escanear el código de arriba, verifica comparando emoji únicos.",
|
||||
"verify_later": "La verificaré en otro momento",
|
||||
"verify_reset_warning_1": "Una vez restableces las claves de verificación, no lo podrás deshacer. Después de restablecerlas, no podrás acceder a los mensajes cifrados antiguos, y cualquier persona que te haya verificado verá avisos de seguridad hasta que vuelvas a hacer la verificación con ella.",
|
||||
"verify_using_device": "Verificar con otro dispositivo",
|
||||
"verify_using_key": "Verificar con una clave de seguridad",
|
||||
"verify_using_key_or_phrase": "Verificar con una clave o frase de seguridad",
|
||||
@@ -2602,7 +2600,6 @@
|
||||
"heading_without_query": "Buscar",
|
||||
"join_button_text": "Unirte a %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Usa <arrows/> para desplazarte",
|
||||
"message_search_section_title": "Otras búsquedas",
|
||||
"other_rooms_in_space": "Otras salas en %(spaceName)s",
|
||||
"public_rooms_label": "Salas públicas",
|
||||
"recent_searches_section_title": "Búsquedas recientes",
|
||||
@@ -2611,7 +2608,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Algunos resultados pueden estar ocultos por motivos de privacidad",
|
||||
"result_may_be_hidden_warning": "Algunos resultados pueden estar ocultos",
|
||||
"search_dialog": "Ventana de búsqueda",
|
||||
"search_messages_hint": "Para buscar contenido de mensajes, usa este icono en la parte de arriba de una sala: <icon/>",
|
||||
"spaces_title": "Tus espacios",
|
||||
"start_group_chat_button": "Crear conversación en grupo"
|
||||
},
|
||||
|
||||
@@ -386,6 +386,7 @@
|
||||
"fallback_button": "Alusta autentimist",
|
||||
"mas_cross_signing_reset_cta": "Mine oma kasutajakonto andmete juurde",
|
||||
"mas_cross_signing_reset_description": "Lähtesta oma võrguidentiteet oma teenusepakkuja abil ning tule siis siia tagasi ja vajuta „Proovi uuesti“.",
|
||||
"mas_cross_signing_reset_title": "Oma võrguidentiteedi lähtestamiseks ava oma kasutajakonto vaade",
|
||||
"msisdn": "Saatsime tekstisõnumi telefoninumbrile %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Vigane tunnusluba",
|
||||
"msisdn_token_prompt": "Palun sisesta seal kuvatud kood:",
|
||||
@@ -993,7 +994,6 @@
|
||||
"accepting": "Nõustun …",
|
||||
"after_new_login": {
|
||||
"device_verified": "Seade on verifitseeritud",
|
||||
"reset_confirmation": "Kas tõesti kustutame kõik verifitseerimisvõtmed?",
|
||||
"skip_verification": "Jäta verifitseerimine praegu vahele",
|
||||
"unable_to_verify": "Selle seadme verifitseerimine ei õnnestunud",
|
||||
"verify_this_device": "Verifitseeri see seade"
|
||||
@@ -1064,8 +1064,6 @@
|
||||
"verify_emoji_prompt": "Verifitseeri unikaalsete emoji'de võrdlemise teel.",
|
||||
"verify_emoji_prompt_qr": "Kui sa ei saa skaneerida eespool kuvatud koodi, siis verifitseeri unikaalsete emoji'de võrdlemise teel.",
|
||||
"verify_later": "Ma verifitseerin hiljem",
|
||||
"verify_reset_warning_1": "Verifitseerimisvõtmete kustutamist ei saa hiljem tagasi võtta. Peale seda sul puudub ligipääs vanadele krüptitud sõnumitele ja kõik sinu verifitseeritud sõbrad-tuttavad näevad turvahoiatusi seni kuni sa uuesti nad verifitseerid.",
|
||||
"verify_reset_warning_2": "Palun jätka ainult siis, kui sa oled kaotanud ligipääsu oma kõikidele muudele seadmetele ning oma taastevõtmele.",
|
||||
"verify_using_device": "Verifitseeri teise seadmega",
|
||||
"verify_using_key": "Verifitseeri taastevõtmega",
|
||||
"verify_using_key_or_phrase": "Verifitseeri taastevõtme või -fraasiga",
|
||||
@@ -2121,6 +2119,7 @@
|
||||
"failed_add_tag": "Sildi %(tagName)s lisamine jututoale ebaõnnestus",
|
||||
"failed_remove_tag": "Sildi %(tagName)s eemaldamine jututoast ebaõnnestus",
|
||||
"failed_set_dm_tag": "Otsevestluse sildi seadmine ei õnnestunud",
|
||||
"filter": "Filtreerimise alus",
|
||||
"filters": {
|
||||
"favourite": "Lemmikud",
|
||||
"people": "Inimesed",
|
||||
@@ -2154,6 +2153,12 @@
|
||||
"open_room": "Ava jututuba: %(roomName)s"
|
||||
},
|
||||
"room_options": "Jututoa valikud",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Kõik tegevused",
|
||||
"invites_only": "Vaid kutsed",
|
||||
"low_priority": "Vähetähtsad",
|
||||
"mentions_only": "Vaid mainimised"
|
||||
},
|
||||
"secondary_filters": "Teisesed filtrid",
|
||||
"show_less": "Näita vähem",
|
||||
"show_message_previews": "Näita sõnumite eelvaateid",
|
||||
@@ -2452,6 +2457,10 @@
|
||||
"recent_changes_heading": "Hiljutised muudatused, mis pole veel alla laetud või saabunud",
|
||||
"title": "Server ei vasta päringutele"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "Selleks, et autenditud meediafailide laadimine Matrixi sisuhoidlast toimiks, eeldab %(brand)s taustal toimiva teenuse töötleja kasutamist. See funktsionaalsus pole sinu veebibrauseris toetatud ja meediafailid võivad jääda laadimata.",
|
||||
"title": "Teenuse töötleja laadimine ei õnnestunud"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Sõnumite otsingu ettevalmistamine ei õnnestunud, lisateavet leiad <a>rakenduse seadistustest</a>",
|
||||
"reset_button": "Lähtesta sündmuste andmekogu",
|
||||
@@ -2630,6 +2639,7 @@
|
||||
"discovery_needs_terms_title": "Võimalda teistel Matrixi võrgu kasutajatel sind leida",
|
||||
"display_name": "Kuvatav nimi",
|
||||
"display_name_error": "Kuvatava nime määramine ei õnnestu",
|
||||
"email_adding_unsupported_by_hs": "See koduserver ei toeta kasutajakonto juurde e-posti aadressi lisamise võimalust.",
|
||||
"email_address_in_use": "See e-posti aadress on juba kasutusel",
|
||||
"email_address_label": "E-posti aadress",
|
||||
"email_not_verified": "Sinu e-posti aadress pole veel verifitseeritud",
|
||||
@@ -2654,7 +2664,9 @@
|
||||
"error_share_msisdn_discovery": "Telefoninumbri jagamine ei õnnestunud",
|
||||
"identity_server_no_token": "Ei leidu tunnusluba isikutuvastusserveri jaoks",
|
||||
"identity_server_not_set": "Isikutuvastusserver on määramata",
|
||||
"invalid_phone_number": "Sisestatud telefoninumber ei tundu olema korrektne",
|
||||
"language_section": "Keel",
|
||||
"msisdn_adding_unsupported_by_hs": "See koduserver ei toeta kasutajakonto juurde telefoninumbri lisamise võimalust.",
|
||||
"msisdn_in_use": "See telefoninumber on juba kasutusel",
|
||||
"msisdn_label": "Telefoninumber",
|
||||
"msisdn_verification_field_label": "Verifikatsioonikood",
|
||||
@@ -3226,7 +3238,7 @@
|
||||
"heading_without_query": "Otsingusõna",
|
||||
"join_button_text": "Liitu %(roomAddress)s jututoaga",
|
||||
"keyboard_scroll_hint": "Kerimiseks kasuta <arrows/>",
|
||||
"message_search_section_title": "Muud otsingud",
|
||||
"messages_label": "Sõnumid",
|
||||
"other_rooms_in_space": "Muud jututoad %(spaceName)s kogukonnad",
|
||||
"public_rooms_label": "Avalikud jututoad",
|
||||
"public_spaces_label": "Avalikud kogukonnad",
|
||||
@@ -3236,7 +3248,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Mõned tulemused võivad privaatsusseadistuste tõttu olla peidetud",
|
||||
"result_may_be_hidden_warning": "Mõned tulemused võivad olla peidetud",
|
||||
"search_dialog": "Otsinguvaade",
|
||||
"search_messages_hint": "Sõnumite otsimiseks klõpsi <icon/> ikooni jututoa ülaosas",
|
||||
"spaces_title": "Kogukonnad, mille liige sa oled",
|
||||
"start_group_chat_button": "Alusta rühmavestlust"
|
||||
},
|
||||
@@ -3285,9 +3296,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Jutulõngade ülevaade",
|
||||
"no_rooms_with_threads_notifs": "Pole veel ühtegi jutulõngakohase teavitusega jututuba.",
|
||||
"no_rooms_with_unread_threads": "Pole veel ühtegi lugemata jutulõngaga jututuba.",
|
||||
"release_announcement_description": "Jutulõngade teavitused leiduvad nüüd uues kohas. Nüüd leiad nad siit.",
|
||||
"release_announcement_header": "Jutulõngade ülevaade"
|
||||
"no_rooms_with_unread_threads": "Pole veel ühtegi lugemata jutulõngaga jututuba."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "umbes päev tagasi",
|
||||
@@ -3798,10 +3807,11 @@
|
||||
"unavailable": "Ei ole saadaval"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Osalemiseks mõeldud lingi loomiseks on vaja, et külalised saavad selle jututoaga liituda. See aga võib muuta jututoa vähem turvaliseks. Kui sa oled aga kõne lõpetanud, siis saad soovi korral jututoa uuesti muuta privaatseks.",
|
||||
"dont_change_description": "Teise võimalusena saad helistada eraldi jututoas",
|
||||
"description": "Kui soovid luua jagatavat linki, siis pead selle jututoa tegema <b>avalikuks</b> või pead seadistustest lubama huvilistel <b>paluda võimalust liitumiseks</b>. See võimaldab külalistel liituda ilma kutseta.",
|
||||
"dont_change_description": "Kui sa ei soovi selle jututoa ligipääsuõigusi muuta, siis teise võimalusena saad helistamiseks luua eraldi jututoa",
|
||||
"no_change": "Ma ei soovi muuta õigusi jututoas.",
|
||||
"title": "Muuda õigusi jututoas"
|
||||
"revert_access_description": "(Eelmise väärtuse saad taastada jututoa seadistustest: <b>Turvalisus & Privaatsus</b> / <b>Ligipääs</b>)",
|
||||
"title": "Luba külalistel selle jututoaga liituda"
|
||||
},
|
||||
"upload_failed_generic": "Faili '%(fileName)s' üleslaadimine ei õnnestunud.",
|
||||
"upload_failed_size": "Faili '%(fileName)s' suurus ületab serveris seadistatud üleslaadimise piiri",
|
||||
|
||||
@@ -2757,7 +2757,6 @@
|
||||
"heading_without_query": "Etsittävät kohteet",
|
||||
"join_button_text": "Liity %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Käytä <arrows/> vierittääksesi",
|
||||
"message_search_section_title": "Muut haut",
|
||||
"other_rooms_in_space": "Muut huoneet avaruudessa %(spaceName)s",
|
||||
"public_rooms_label": "Julkiset huoneet",
|
||||
"public_spaces_label": "Julkiset avaruudet",
|
||||
@@ -2765,7 +2764,6 @@
|
||||
"recently_viewed_section_title": "Äskettäin katsottu",
|
||||
"result_may_be_hidden_privacy_warning": "Jotkin tulokset saatetaan piilottaa tietosuojan takia",
|
||||
"result_may_be_hidden_warning": "Jotkin tulokset saatetaan piilottaa",
|
||||
"search_messages_hint": "Etsi viesteistä huoneen yläosassa olevalla kuvakkeella <icon/>",
|
||||
"spaces_title": "Avaruudet, joissa olet",
|
||||
"start_group_chat_button": "Aloita ryhmäkeskustelu"
|
||||
},
|
||||
|
||||
@@ -386,6 +386,7 @@
|
||||
"fallback_button": "Commencer l’authentification",
|
||||
"mas_cross_signing_reset_cta": "Accédez à votre compte",
|
||||
"mas_cross_signing_reset_description": "Réinitialisez votre identité par l’intermédiaire de votre fournisseur de compte, puis revenez et cliquez sur « Réessayer ».",
|
||||
"mas_cross_signing_reset_title": "Accédez à votre compte pour réinitialiser votre identité",
|
||||
"msisdn": "Un message a été envoyé à %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Jeton incorrect",
|
||||
"msisdn_token_prompt": "Merci de saisir le code qu’il contient :",
|
||||
@@ -993,7 +994,6 @@
|
||||
"accepting": "Acceptation…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Appareil vérifié",
|
||||
"reset_confirmation": "Réinitialiser les clés de vérification, c’est certain ?",
|
||||
"skip_verification": "Ignorer la vérification pour l’instant",
|
||||
"unable_to_verify": "Impossible de vérifier cet appareil",
|
||||
"verify_this_device": "Vérifier cet appareil"
|
||||
@@ -1064,8 +1064,6 @@
|
||||
"verify_emoji_prompt": "Vérifier en comparant des émojis uniques.",
|
||||
"verify_emoji_prompt_qr": "Si vous ne pouvez pas scanner le code ci-dessus, vérifiez en comparant des émojis uniques.",
|
||||
"verify_later": "Je ferai la vérification plus tard",
|
||||
"verify_reset_warning_1": "La réinitialisation de vos clés de vérification ne peut pas être annulé. Après la réinitialisation, vous n’aurez plus accès à vos anciens messages chiffrés, et tous les amis que vous aviez précédemment vérifiés verront des avertissement de sécurité jusqu'à ce vous les vérifiiez à nouveau.",
|
||||
"verify_reset_warning_2": "Veuillez ne continuer que si vous êtes certain d’avoir perdu tous vos autres appareils et votre clé de récupération.",
|
||||
"verify_using_device": "Vérifier avec un autre appareil",
|
||||
"verify_using_key": "Vérifier avec la clé de récupération",
|
||||
"verify_using_key_or_phrase": "Vérifier avec une clé de récupération ou une phrase",
|
||||
@@ -2120,6 +2118,7 @@
|
||||
"failed_add_tag": "Échec de l’ajout de l’étiquette %(tagName)s au salon",
|
||||
"failed_remove_tag": "Échec de la suppression de l’étiquette %(tagName)s du salon",
|
||||
"failed_set_dm_tag": "Échec de l’ajout de l’étiquette de conversation privée",
|
||||
"filter": "Filtre",
|
||||
"filters": {
|
||||
"favourite": "Favoris",
|
||||
"people": "Personnes",
|
||||
@@ -2153,6 +2152,12 @@
|
||||
"open_room": "Ouvrir salon %(roomName)s"
|
||||
},
|
||||
"room_options": "Options du salon",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Toutes les activités",
|
||||
"invites_only": "Invitations uniquement",
|
||||
"low_priority": "Faible priorité",
|
||||
"mentions_only": "Mentions uniquement"
|
||||
},
|
||||
"secondary_filters": "Filtres secondaires",
|
||||
"show_less": "En voir moins",
|
||||
"show_message_previews": "Afficher les aperçus des messages",
|
||||
@@ -2451,6 +2456,10 @@
|
||||
"recent_changes_heading": "Changements récents qui n’ont pas encore été reçus",
|
||||
"title": "Le serveur ne répond pas"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s nécessite un service worker pour charger les médias authentifiés à partir des référentiels de contenu Matrix. Ceci n'est pas pris en charge par votre navigateur. Il est donc possible que le contenu multimédia ne se charge pas.",
|
||||
"title": "Échec du chargement du service worker"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Échec de l’initialisation de la recherche de messages, vérifiez <a>vos paramètres</a> pour plus d’information",
|
||||
"reset_button": "Réinitialiser le magasin d’évènements",
|
||||
@@ -2629,6 +2638,7 @@
|
||||
"discovery_needs_terms_title": "Laissez les gens vous trouver",
|
||||
"display_name": "Nom d'affichage",
|
||||
"display_name_error": "Impossible de définir le nom d'affichage",
|
||||
"email_adding_unsupported_by_hs": "Ce serveur d'accueil ne prend pas en charge l'ajout d'adresses e-mail à votre compte.",
|
||||
"email_address_in_use": "Cette adresse e-mail est déjà utilisée",
|
||||
"email_address_label": "Adresse e-mail",
|
||||
"email_not_verified": "Votre adresse e-mail n’a pas encore été vérifiée",
|
||||
@@ -2653,7 +2663,9 @@
|
||||
"error_share_msisdn_discovery": "Impossible de partager le numéro de téléphone",
|
||||
"identity_server_no_token": "Aucun jeton d’accès d’identité trouvé",
|
||||
"identity_server_not_set": "Serveur d'identité non défini",
|
||||
"invalid_phone_number": "Le numéro de téléphone fourni est invalide.",
|
||||
"language_section": "Langue",
|
||||
"msisdn_adding_unsupported_by_hs": "Ce serveur d'accueil ne prend pas en charge l'ajout de numéros de téléphone à votre compte.",
|
||||
"msisdn_in_use": "Ce numéro de téléphone est déjà utilisé",
|
||||
"msisdn_label": "Numéro de téléphone",
|
||||
"msisdn_verification_field_label": "Code de vérification",
|
||||
@@ -3225,7 +3237,7 @@
|
||||
"heading_without_query": "Recherche de",
|
||||
"join_button_text": "Rejoindre %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Utilisez <arrows/> pour faire défiler",
|
||||
"message_search_section_title": "Autres recherches",
|
||||
"messages_label": "Messages",
|
||||
"other_rooms_in_space": "Autres salons dans %(spaceName)s",
|
||||
"public_rooms_label": "Salons publics",
|
||||
"public_spaces_label": "Espaces publics",
|
||||
@@ -3235,7 +3247,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Certains résultats pourraient être masqués pour des raisons de confidentialité",
|
||||
"result_may_be_hidden_warning": "Certains résultats peuvent être cachés",
|
||||
"search_dialog": "Fenêtre de recherche",
|
||||
"search_messages_hint": "Pour chercher des messages, repérez cette icône en haut à droite d'un salon <icon/>",
|
||||
"spaces_title": "Espaces où vous êtes",
|
||||
"start_group_chat_button": "Démarrer une conversation de groupe"
|
||||
},
|
||||
@@ -3284,9 +3295,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Activité des fils de discussions",
|
||||
"no_rooms_with_threads_notifs": "Vous n’avez pas encore de salons avec des notifications de fil de discussion.",
|
||||
"no_rooms_with_unread_threads": "Vous n'avez pas encore de salons contenant des fils de discussion non lus.",
|
||||
"release_announcement_description": "Les notifications des fils de discussion ont été déplacées. À partir de maintenant, retrouvez-les ici.",
|
||||
"release_announcement_header": "Centre d'activité des fils de discussions"
|
||||
"no_rooms_with_unread_threads": "Vous n'avez pas encore de salons contenant des fils de discussion non lus."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "il y a environ un jour",
|
||||
@@ -3797,10 +3806,11 @@
|
||||
"unavailable": "Indisponible"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Pour créer un lien de partage, vous devez autoriser les invités à rejoindre ce salon. Cela peut rendre le salon moins sûr. Lorsque vous aurez terminé l'appel, vous pourrez redéfinir la confidentialité du salon.",
|
||||
"dont_change_description": "Vous pouvez également prendre l'appel dans un salon séparé.",
|
||||
"description": "Pour créer un lien de partage, rendez ce salon <b>publique</b> ou activer l 'option permettant aux utilisateurs de <b>demander à rejoindre</b>. Cela permet aux invités de participer sans être invités.",
|
||||
"dont_change_description": "Si vous ne souhaitez pas modifier l'accès à ce salon, vous pouvez créer un nouveau salon pour le lien d'appel.",
|
||||
"no_change": "Je ne souhaite pas modifier le niveau d'accès.",
|
||||
"title": "Modifier le niveau d'accès du salon"
|
||||
"revert_access_description": "(Ceci peut être rétabli à sa valeur précédente dans les paramètres du salon : <b> Sécurité et confidentialité</b>/<b>Accès</b>)",
|
||||
"title": "Autoriser les utilisateurs invités à rejoindre ce salon"
|
||||
},
|
||||
"upload_failed_generic": "Le fichier « %(fileName)s » n’a pas pu être envoyé.",
|
||||
"upload_failed_size": "Le fichier « %(fileName)s » dépasse la taille limite autorisée par ce serveur pour les envois",
|
||||
|
||||
@@ -741,7 +741,6 @@
|
||||
"accepting": "Aceptando…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Dispositivo verificado",
|
||||
"reset_confirmation": "Queres restablecer as chaves de verificación?",
|
||||
"skip_verification": "Omitir a verificación por agora",
|
||||
"unable_to_verify": "Non se puido verificar este dispositivo",
|
||||
"verify_this_device": "Verifica este dispositivo"
|
||||
@@ -804,7 +803,6 @@
|
||||
"verify_emoji_prompt": "Verficación por comparación de emoticonas.",
|
||||
"verify_emoji_prompt_qr": "Se non podes escanear o código superior, verifica comparando as emoticonas.",
|
||||
"verify_later": "Verificarei máis tarde",
|
||||
"verify_reset_warning_1": "O restablecemento das chaves de seguridade non se pode desfacer. Tras o restablecemento, non terás acceso ás antigas mensaxes cifradas, e calquera amizade que verificaras con anterioridade vai ver un aviso de seguridade ata que volvades a verificarvos mutuamente.",
|
||||
"verify_using_device": "Verifica usando outro dispositivo",
|
||||
"verify_using_key": "Verificar coa Chave de Seguridade",
|
||||
"verify_using_key_or_phrase": "Verificar coa Chave ou Frase de Seguridade",
|
||||
@@ -2372,7 +2370,6 @@
|
||||
"heading_without_query": "Buscar",
|
||||
"join_button_text": "Unirse a %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Usa <arrows/> para desprazarte",
|
||||
"message_search_section_title": "Outras buscas",
|
||||
"other_rooms_in_space": "Outras salas en %(spaceName)s",
|
||||
"public_rooms_label": "Salas públicas",
|
||||
"recent_searches_section_title": "Buscas recentes",
|
||||
@@ -2381,7 +2378,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Algúns resultados poden estar agochados por privacidade",
|
||||
"result_may_be_hidden_warning": "Algúns resultados poderían estar agochados",
|
||||
"search_dialog": "Diálogo de busca",
|
||||
"search_messages_hint": "Para buscar mensaxes, busca esta icona arriba de todo na sala <icon/>",
|
||||
"spaces_title": "Espazos nos que estás",
|
||||
"start_group_chat_button": "Inicia un chat en grupo"
|
||||
},
|
||||
|
||||
@@ -386,6 +386,7 @@
|
||||
"fallback_button": "Hitelesítés indítása",
|
||||
"mas_cross_signing_reset_cta": "Ugrás a fiókjához",
|
||||
"mas_cross_signing_reset_description": "Állítsa alaphelyzetbe személyazonosságát a fiókszolgáltatón keresztül, majd térjen vissza, és kattintson az „Újra” gombra.",
|
||||
"mas_cross_signing_reset_title": "Ugorjon a fiókjához a személyazonossága alaphelyzetbe állításához",
|
||||
"msisdn": "Szöveges üzenet küldve ide: %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Helytelen token",
|
||||
"msisdn_token_prompt": "Adja meg a benne lévő kódot:",
|
||||
@@ -525,6 +526,7 @@
|
||||
"message_timestamp_invalid": "Érvénytelen időbélyeg",
|
||||
"microphone": "Mikrofon",
|
||||
"model": "Modell",
|
||||
"moderation_and_safety": "Moderálás és biztonság",
|
||||
"modern": "Modern",
|
||||
"mute": "Némítás",
|
||||
"n_members": {
|
||||
@@ -989,7 +991,6 @@
|
||||
"accepting": "Elfogadás…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Eszköz ellenőrizve",
|
||||
"reset_confirmation": "Biztos, hogy lecseréli az ellenőrzési kulcsokat?",
|
||||
"skip_verification": "Ellenőrzés kihagyása most",
|
||||
"unable_to_verify": "Ennek az eszköznek az ellenőrzése nem lehetséges",
|
||||
"verify_this_device": "Az eszköz ellenőrzése"
|
||||
@@ -1060,8 +1061,6 @@
|
||||
"verify_emoji_prompt": "Ellenőrzés egyedi emodzsik összehasonlításával.",
|
||||
"verify_emoji_prompt_qr": "Ha nem tudod beolvasni az alábbi kódot, ellenőrizd az egyedi emodzsik összehasonlításával.",
|
||||
"verify_later": "Később ellenőrzöm",
|
||||
"verify_reset_warning_1": "Az ellenőrzéshez használt kulcsok lecserélését nem lehet visszavonni. A visszaállítás után nem fog hozzáférni a régi titkosított üzenetekhez, és minden ismerőse, aki eddig ellenőrizte a személyazonosságát, biztonsági figyelmeztetést fog látni, amíg újra nem ellenőrzi.",
|
||||
"verify_reset_warning_2": "Csak akkor folytassa, ha biztos benne, hogy elvesztette a hozzáférést a többi eszközéhez és helyreállítási kulcsához.",
|
||||
"verify_using_device": "Ellenőrizze egy másik eszközzel",
|
||||
"verify_using_key": "Ellenőrzés helyreállítási kulccsal",
|
||||
"verify_using_key_or_phrase": "Ellenőrzés helyreállítási kulccsal vagy jelmondattal",
|
||||
@@ -2085,6 +2084,7 @@
|
||||
"room_list": {
|
||||
"add_room_label": "Szoba hozzáadása",
|
||||
"add_space_label": "Tér hozzáadása",
|
||||
"appearance": "Megjelenés",
|
||||
"breadcrumbs_empty": "Nincsenek nemrégiben meglátogatott szobák",
|
||||
"breadcrumbs_label": "Nemrég meglátogatott szobák",
|
||||
"empty": {
|
||||
@@ -2103,6 +2103,7 @@
|
||||
"failed_add_tag": "Nem sikerült hozzáadni a szobához ezt: %(tagName)s",
|
||||
"failed_remove_tag": "Nem sikerült a szobáról eltávolítani ezt: %(tagName)s",
|
||||
"failed_set_dm_tag": "Nem sikerült a közvetlen beszélgetés címkét beállítani",
|
||||
"filter": "Szűrő",
|
||||
"filters": {
|
||||
"favourite": "Kedvencek",
|
||||
"people": "Emberek",
|
||||
@@ -2133,7 +2134,16 @@
|
||||
"more_options": "További lehetőségek",
|
||||
"open_room": "A(z) %(roomName)s szoba megnyitása"
|
||||
},
|
||||
"room_options": "Szobabeállítások",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Összes tevékenység",
|
||||
"invites_only": "Csak meghívók",
|
||||
"low_priority": "Alacsony prioritás",
|
||||
"mentions_only": "Csak megemlítések"
|
||||
},
|
||||
"secondary_filters": "Másodlagos szűrők",
|
||||
"show_less": "Kevesebb megjelenítése",
|
||||
"show_message_previews": "Üzenetelőnézetek megjelenítése",
|
||||
"show_n_more": {
|
||||
"Még %(count)s megjelenítése": "one"
|
||||
},
|
||||
@@ -2605,6 +2615,7 @@
|
||||
"discovery_needs_terms_title": "Hagyja, hogy mások megtalálhassák",
|
||||
"display_name": "Megjelenítendő név",
|
||||
"display_name_error": "Nem sikerült beállítani a megjelenítési nevet",
|
||||
"email_adding_unsupported_by_hs": "Ez a Matrix-kiszolgáló nem támogatja az e-mail-címek hozzáadását a fiókjához.",
|
||||
"email_address_in_use": "Ez az e-mail-cím már használatban van",
|
||||
"email_address_label": "E-mail cím",
|
||||
"email_not_verified": "Az e-mail-címe még nincs ellenőrizve",
|
||||
@@ -2629,7 +2640,9 @@
|
||||
"error_share_msisdn_discovery": "A telefonszámot nem sikerült megosztani",
|
||||
"identity_server_no_token": "Nem található személyazonosság-hozzáférési kulcs",
|
||||
"identity_server_not_set": "Az azonosítási kiszolgáló nincs megadva",
|
||||
"invalid_phone_number": "A megadott telefonszám nem tűnik érvényesnek.",
|
||||
"language_section": "Nyelv",
|
||||
"msisdn_adding_unsupported_by_hs": "Ez a Matrix-kiszolgáló nem támogatja a telefonszámok hozzáadását a fiókjához.",
|
||||
"msisdn_in_use": "Ez a telefonszám már használatban van",
|
||||
"msisdn_label": "Telefonszám",
|
||||
"msisdn_verification_field_label": "Ellenőrző kód",
|
||||
@@ -2710,6 +2723,14 @@
|
||||
"labs_mjolnir": {
|
||||
"dialog_title": "<strong>Beállítások:</strong> Figyelmen kívül hagyott felhasználók"
|
||||
},
|
||||
"media_preview": {
|
||||
"hide_avatars": "A szoba és a meghívó profilképének elrejtése",
|
||||
"hide_media": "Elrejtés mindig",
|
||||
"media_preview_description": "A rejtett médiatartalmak koppintással jeleníthetők meg",
|
||||
"media_preview_label": "Média megjelenítése az idővonalon",
|
||||
"show_in_private": "Privát szobákban",
|
||||
"show_media": "Megjelenítés mindig"
|
||||
},
|
||||
"notifications": {
|
||||
"default_setting_description": "Ez a beállítás alapértelmezés szerint az összes szobájára érvényes lesz.",
|
||||
"default_setting_section": "Szeretnék értesítést kapni az alábbiakról (Alapértelmezett beállítás)",
|
||||
@@ -3188,7 +3209,7 @@
|
||||
"heading_without_query": "Keresés:",
|
||||
"join_button_text": "Belépés ide: %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Görgetés ezekkel: <arrows/>",
|
||||
"message_search_section_title": "Más keresések",
|
||||
"messages_label": "Üzenetek",
|
||||
"other_rooms_in_space": "Más szobák itt: %(spaceName)s",
|
||||
"public_rooms_label": "Nyilvános szobák",
|
||||
"public_spaces_label": "Nyilvános terek",
|
||||
@@ -3198,7 +3219,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Adatvédelmi okokból néhány találat rejtve lehet",
|
||||
"result_may_be_hidden_warning": "Néhány találat rejtve lehet",
|
||||
"search_dialog": "Keresési párbeszédablak",
|
||||
"search_messages_hint": "Az üzenetek kereséséhez keresse ezt az ikont a szoba tetején: <icon/>",
|
||||
"spaces_title": "Terek, amelynek tagja",
|
||||
"start_group_chat_button": "Csoportos csevegés indítása"
|
||||
},
|
||||
@@ -3246,9 +3266,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Üzenetszál-tevékenységek",
|
||||
"no_rooms_with_threads_notifs": "Még nincsenek olyan szobái, amelyek üzenetszál értesítéseket tartalmaznak.",
|
||||
"no_rooms_with_unread_threads": "Nincsenek még olvasatlan üzenetszálakkal rendelkező szobái.",
|
||||
"release_announcement_description": "Az üzenetszálak értesítései átkerültek, mostantól itt találja őket.",
|
||||
"release_announcement_header": "Üzenetszálak tevékenységközpontja"
|
||||
"no_rooms_with_unread_threads": "Nincsenek még olvasatlan üzenetszálakkal rendelkező szobái."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "egy napja",
|
||||
@@ -3756,10 +3774,11 @@
|
||||
"unavailable": "Elérhetetlen"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Megosztási hivatkozás létrehozásához engedélyeznie kell a vendégek számára, hogy csatlakozzanak ehhez a szobához. Ez kevésbé biztonságossá teheti a szobát. Ha befejezte a hívást, ismét priváttá teheti a szobát.",
|
||||
"dont_change_description": "Alternatív megoldásként a hívást külön szobában is tarthatja.",
|
||||
"description": "Megosztási hivatkozás létrehozásához tegye <b>nyilvánossá</b> ezt a szobát, vagy engedélyezze azt a lehetőséget, hogy a felhasználók csatlakozást <b>kérhessenek</b>. Ez lehetővé teszi a vendégek számára, hogy meghívás nélkül csatlakozzanak.",
|
||||
"dont_change_description": "Ha nem szeretné módosítani a szoba hozzáférését, létrehozhat egy új szobát a híváshoz.",
|
||||
"no_change": "Nem akarom megváltoztatni a hozzáférési szintet.",
|
||||
"title": "A szoba hozzáférési szintjének módosítása"
|
||||
"revert_access_description": "(Ez visszaállítható az előző értékre a Szoba beállításaiban: <b>Biztonság és adatvédelem </b> / <b>Hozzáférés</b>)",
|
||||
"title": "Vendégfelhasználók csatlakozásának engedélyezése ehhez a szobához"
|
||||
},
|
||||
"upload_failed_generic": "A(z) „%(fileName)s” fájl feltöltése sikertelen.",
|
||||
"upload_failed_size": "A(z) „%(fileName)s” mérete túllépi a Matrix-kiszolgáló által megengedett korlátot",
|
||||
|
||||
@@ -384,6 +384,7 @@
|
||||
"fallback_button": "Mulai autentikasi",
|
||||
"mas_cross_signing_reset_cta": "Buka akun Anda",
|
||||
"mas_cross_signing_reset_description": "Atur ulang identitas Anda melalui penyedia akun Anda, kemudian kembali dan klik “Coba lagi”.",
|
||||
"mas_cross_signing_reset_title": "Buka akun Anda untuk mengatur ulang identitas Anda",
|
||||
"msisdn": "Sebuah pesan teks telah dikirim ke %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Token salah",
|
||||
"msisdn_token_prompt": "Silakan masukkan kode yang berisi:",
|
||||
@@ -990,7 +991,6 @@
|
||||
"accepting": "Menerima…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Perangkat telah diverifikasi",
|
||||
"reset_confirmation": "Benar-benar ingin mengatur ulang kunci-kunci verifikasi?",
|
||||
"skip_verification": "Lewatkan verifikasi untuk sementara",
|
||||
"unable_to_verify": "Tidak dapat memverifikasi perangkat ini",
|
||||
"verify_this_device": "Verifikasi perangkat ini"
|
||||
@@ -1061,8 +1061,6 @@
|
||||
"verify_emoji_prompt": "Verifikasi dengan membandingkan emoji unik.",
|
||||
"verify_emoji_prompt_qr": "Jika Anda tidak dapat memindai kode di atas, verifikasi dengan membandingkan emoji yang unik.",
|
||||
"verify_later": "Saya verifikasi nanti",
|
||||
"verify_reset_warning_1": "Mengatur ulang kunci verifikasi Anda tidak dapat dibatalkan. Setelah mengatur ulang, Anda tidak akan memiliki akses ke pesan terenkripsi lama, dan semua orang yang sebelumnya telah memverifikasi Anda akan melihat peringatan keamanan sampai Anda memverifikasi ulang dengan mereka.",
|
||||
"verify_reset_warning_2": "Silakan lanjutkan hanya jika Anda yakin telah kehilangan semua perangkat lain dan Kunci Pemulihan Anda.",
|
||||
"verify_using_device": "Verifikasi dengan perangkat lain",
|
||||
"verify_using_key": "Verifikasi dengan Kunci Keamanan",
|
||||
"verify_using_key_or_phrase": "Verifikasi dengan Kunci atau Frasa Keamanan",
|
||||
@@ -2113,6 +2111,7 @@
|
||||
"failed_add_tag": "Gagal menambahkan tag %(tagName)s ke ruangan",
|
||||
"failed_remove_tag": "Gagal menghapus tanda %(tagName)s dari ruangan",
|
||||
"failed_set_dm_tag": "Gagal menetapkan tanda pesan langsung",
|
||||
"filter": "Filter",
|
||||
"filters": {
|
||||
"favourite": "Favorit",
|
||||
"people": "Orang",
|
||||
@@ -2146,6 +2145,12 @@
|
||||
"open_room": "Buka ruangan %(roomName)s"
|
||||
},
|
||||
"room_options": "Opsi Ruangan",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Semua aktivitas",
|
||||
"invites_only": "Hanya undangan",
|
||||
"low_priority": "Prioritas rendah",
|
||||
"mentions_only": "Sebutan saja"
|
||||
},
|
||||
"secondary_filters": "Saringan sekunder",
|
||||
"show_less": "Tampilkan lebih sedikit",
|
||||
"show_message_previews": "Tampilkan pratinjau pesan",
|
||||
@@ -2444,6 +2449,10 @@
|
||||
"recent_changes_heading": "Perubahan terbaru yang belum diterima",
|
||||
"title": "Server tidak merespon"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s memerlukan pekerja layanan untuk memuat media yang diautentikasi dari repositori konten Matrix. Ini tidak didukung oleh peramban Anda sehingga Anda mungkin mengalami kegagalan pemuatan media.",
|
||||
"title": "Gagal memuat pekerja layanan"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Initialisasi pencarian pesan gagal, periksa <a>pengaturan Anda</a> untuk informasi lanjut",
|
||||
"reset_button": "Atur ulang penyimpanan peristiwa",
|
||||
@@ -2622,6 +2631,7 @@
|
||||
"discovery_needs_terms_title": "Biarkan orang lain menemukan Anda",
|
||||
"display_name": "Nama Tampilan",
|
||||
"display_name_error": "Tidak dapat mengatur nama tampilan",
|
||||
"email_adding_unsupported_by_hs": "Homeserver ini tidak mendukung penambahan alamat surel ke akun Anda.",
|
||||
"email_address_in_use": "Alamat email ini telah dipakai",
|
||||
"email_address_label": "Alamat Email",
|
||||
"email_not_verified": "Alamat email Anda belum diverifikasi",
|
||||
@@ -2646,7 +2656,9 @@
|
||||
"error_share_msisdn_discovery": "Tidak dapat membagikan nomor telepon",
|
||||
"identity_server_no_token": "Tidak ada token akses identitas yang ditemukan",
|
||||
"identity_server_not_set": "Server identitas tidak diatur",
|
||||
"invalid_phone_number": "Nomor telepon yang diberikan tampaknya tidak valid.",
|
||||
"language_section": "Bahasa",
|
||||
"msisdn_adding_unsupported_by_hs": "Homeserver ini tidak mendukung penambahan nomor telepon ke akun Anda.",
|
||||
"msisdn_in_use": "Nomor telepon ini telah dipakai",
|
||||
"msisdn_label": "Nomor Telepon",
|
||||
"msisdn_verification_field_label": "Kode verifikasi",
|
||||
@@ -3218,7 +3230,7 @@
|
||||
"heading_without_query": "Cari",
|
||||
"join_button_text": "Bergabung dengan %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Gunakan <arrows/> untuk menggulirkan",
|
||||
"message_search_section_title": "Pencarian lainnya",
|
||||
"messages_label": "Pesan",
|
||||
"other_rooms_in_space": "Ruangan lainnya di %(spaceName)s",
|
||||
"public_rooms_label": "Ruangan publik",
|
||||
"public_spaces_label": "Space publik",
|
||||
@@ -3228,7 +3240,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Beberapa hasil mungkin disembunyikan untuk privasi",
|
||||
"result_may_be_hidden_warning": "Beberapa hasil mungkin tersembunyi",
|
||||
"search_dialog": "Dialog Pencarian",
|
||||
"search_messages_hint": "Untuk mencari pesan-pesan, lihat ikon ini di atas ruangan <icon/>",
|
||||
"spaces_title": "Space yang Anda berada",
|
||||
"start_group_chat_button": "Mulai sebuah grup obrolan"
|
||||
},
|
||||
@@ -3277,9 +3288,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Aktivitas utas",
|
||||
"no_rooms_with_threads_notifs": "Anda belum memiliki ruangan dengan notifikasi utas.",
|
||||
"no_rooms_with_unread_threads": "Anda belum memiliki ruangan dengan utas yang belum dibaca.",
|
||||
"release_announcement_description": "Notifikasi utas telah dipindahkan, temukan di sini mulai sekarang.",
|
||||
"release_announcement_header": "Pusat Aktivitas Utas"
|
||||
"no_rooms_with_unread_threads": "Anda belum memiliki ruangan dengan utas yang belum dibaca."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "1 hari yang lalu",
|
||||
@@ -3790,10 +3799,11 @@
|
||||
"unavailable": "Tidak Tersedia"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Untuk membuat tautan berbagi, Anda harus mengizinkan tamu bergabung dengan ruangan ini. Hal ini dapat membuat ruangan menjadi kurang aman. Setelah selesai dengan panggilan, Anda dapat membuat ruangan menjadi pribadi lagi.",
|
||||
"dont_change_description": "Sebagai alternatif, Anda dapat melakukan panggilan di ruangan terpisah.",
|
||||
"description": "Untuk membuat tautan berbagi, jadikan ruangan ini <b>publik</b> atau aktifkan opsi bagi pengguna untuk <b>meminta bergabung</b>. Hal ini memungkinkan tamu untuk bergabung tanpa diundang.",
|
||||
"dont_change_description": "Jika Anda tidak ingin mengubah akses ruangan ini, Anda dapat membuat ruang baru untuk tautan panggilan.",
|
||||
"no_change": "Saya tidak ingin mengubah tingkat akses.",
|
||||
"title": "Ubah tingkat akses ruangan"
|
||||
"revert_access_description": "(Ini dapat dikembalikan ke nilai sebelumnya di Pengaturan Ruangan: <b>Keamanan & Privasi</b> / <b>Akses</b>)",
|
||||
"title": "Izinkan pengguna tamu untuk bergabung dengan ruangan ini"
|
||||
},
|
||||
"upload_failed_generic": "File '%(fileName)s' gagal untuk diunggah.",
|
||||
"upload_failed_size": "File '%(fileName)s' melebihi batas ukuran unggahan file homeserver",
|
||||
|
||||
@@ -729,7 +729,6 @@
|
||||
"accepting": "Samþykki…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Tæki er sannreynt",
|
||||
"reset_confirmation": "Viltu í alvörunni endurstilla sannvottunarlyklana?",
|
||||
"skip_verification": "Sleppa sannvottun í bili",
|
||||
"unable_to_verify": "Tókst ekki að sannreyna þetta tæki",
|
||||
"verify_this_device": "Sannreyna þetta tæki"
|
||||
@@ -2291,7 +2290,6 @@
|
||||
"heading_without_query": "Leita að",
|
||||
"join_button_text": "Taka þátt í %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Notaðu <arrows/> til að skruna",
|
||||
"message_search_section_title": "Aðrar leitir",
|
||||
"other_rooms_in_space": "Aðrar spjallrásir í %(spaceName)s",
|
||||
"public_rooms_label": "Almenningsspjallrásir",
|
||||
"recent_searches_section_title": "Nýlegar leitir",
|
||||
|
||||
@@ -869,7 +869,6 @@
|
||||
"accepting": "Accettazione…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Dispositivo verificato",
|
||||
"reset_confirmation": "Reimpostare le chiavi di verifica?",
|
||||
"skip_verification": "Salta la verifica per adesso",
|
||||
"unable_to_verify": "Impossibile verificare questo dispositivo",
|
||||
"verify_this_device": "Verifica questo dispositivo"
|
||||
@@ -939,8 +938,6 @@
|
||||
"verify_emoji_prompt": "Verifica confrontando emoji specifici.",
|
||||
"verify_emoji_prompt_qr": "Se non riesci a scansionare il codice sopra, verifica confrontando emoji specifiche.",
|
||||
"verify_later": "Verificherò dopo",
|
||||
"verify_reset_warning_1": "La reimpostazione delle chiavi di verifica non può essere annullata. Dopo averlo fatto, non avrai accesso ai vecchi messaggi cifrati, e gli amici che ti avevano verificato in precedenza vedranno avvisi di sicurezza fino a quando non ti ri-verifichi con loro.",
|
||||
"verify_reset_warning_2": "Procedi solo se sei sicuro di avere perso tutti gli altri tuoi dispositivi e la chiave di sicurezza.",
|
||||
"verify_using_device": "Verifica con un altro dispositivo",
|
||||
"verify_using_key": "Verifica con chiave di sicurezza",
|
||||
"verify_using_key_or_phrase": "Verifica con chiave di sicurezza o frase",
|
||||
@@ -2833,7 +2830,6 @@
|
||||
"heading_without_query": "Cerca",
|
||||
"join_button_text": "Entra in %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Usa <arrows/> per scorrere",
|
||||
"message_search_section_title": "Altre ricerche",
|
||||
"other_rooms_in_space": "Altre stanze in %(spaceName)s",
|
||||
"public_rooms_label": "Stanze pubbliche",
|
||||
"public_spaces_label": "Spazi pubblici",
|
||||
@@ -2843,7 +2839,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Alcuni risultati potrebbero essere nascosti per privacy",
|
||||
"result_may_be_hidden_warning": "Alcuni risultati potrebbero essere nascosti",
|
||||
"search_dialog": "Finestra di ricerca",
|
||||
"search_messages_hint": "Per cercare messaggi, trova questa icona in cima ad una stanza <icon/>",
|
||||
"spaces_title": "Spazi in cui sei",
|
||||
"start_group_chat_button": "Inizia una conversazione di gruppo"
|
||||
},
|
||||
|
||||
@@ -825,7 +825,6 @@
|
||||
"accepting": "承認しています…",
|
||||
"after_new_login": {
|
||||
"device_verified": "端末が認証されました",
|
||||
"reset_confirmation": "本当に認証鍵をリセットしますか?",
|
||||
"skip_verification": "認証をスキップ",
|
||||
"unable_to_verify": "この端末を認証できません",
|
||||
"verify_this_device": "この端末を認証"
|
||||
@@ -892,8 +891,6 @@
|
||||
"verify_emoji_prompt": "絵文字の並びを比較して認証。",
|
||||
"verify_emoji_prompt_qr": "上記のコードをスキャンできない場合は、絵文字による確認を行ってください。",
|
||||
"verify_later": "後で認証",
|
||||
"verify_reset_warning_1": "認証鍵のリセットは取り消せません。リセットすると、以前の暗号化されたメッセージにはアクセスできなくなります。また、あなたのアカウントを認証した連絡先には、再認証するまで、セキュリティーに関する警告が表示されます。",
|
||||
"verify_reset_warning_2": "全ての端末とセキュリティーキーを紛失してしまったことが確かである場合にのみ、続行してください。",
|
||||
"verify_using_device": "別の端末で認証",
|
||||
"verify_using_key": "セキュリティーキーで認証",
|
||||
"verify_using_key_or_phrase": "セキュリティーキーあるいはセキュリティーフレーズで認証",
|
||||
@@ -2580,7 +2577,6 @@
|
||||
"heading_without_query": "検索",
|
||||
"join_button_text": "%(roomAddress)sに参加",
|
||||
"keyboard_scroll_hint": "<arrows/>でスクロール",
|
||||
"message_search_section_title": "その他の検索",
|
||||
"other_rooms_in_space": "%(spaceName)sの他のルーム",
|
||||
"public_rooms_label": "公開ルーム",
|
||||
"recent_searches_section_title": "最近の検索",
|
||||
@@ -2589,7 +2585,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "プライバシーの観点から表示していない結果があります",
|
||||
"result_may_be_hidden_warning": "いくつかの結果が表示されていない可能性があります",
|
||||
"search_dialog": "検索ダイアログ",
|
||||
"search_messages_hint": "メッセージを検索する場合は、ルームの上に表示されるアイコン<icon/>をクリックしてください。",
|
||||
"spaces_title": "参加しているスペース",
|
||||
"start_group_chat_button": "グループチャットを開始"
|
||||
},
|
||||
|
||||
@@ -733,7 +733,6 @@
|
||||
"accepting": "მიღება…",
|
||||
"after_new_login": {
|
||||
"device_verified": "მოწყობილობა დადასტურებულია",
|
||||
"reset_confirmation": "ნამდვილად გადააყენეთ დადასტურების გასაღებები?",
|
||||
"skip_verification": "ამ დროისთვის გამოტოვეთ დადასტურება",
|
||||
"unable_to_verify": "ამ მოწყობილობის დადასტურება შეუძლებელია",
|
||||
"verify_this_device": "დაადასტურეთ ეს მოწყობილობა"
|
||||
@@ -803,8 +802,6 @@
|
||||
"verify_emoji_prompt": "გადაამოწმეთ უნიკალური emoji-ების შედარებით.",
|
||||
"verify_emoji_prompt_qr": "თუ ზემოთ მოცემულ კოდს ვერ სკანირებთ, გადაამოწმეთ უნიკალური emoji-ების შედარებით.",
|
||||
"verify_later": "მოგვიანებით გადავამოწმებ",
|
||||
"verify_reset_warning_1": "თქვენი დამადასტურებელი გასაღებების გადაყენება შეუძლებელია. გადატვირთვის შემდეგ, თქვენ არ გექნებათ წვდომა ძველ დაშიფრულ შეტყობინებებზე და ყველა მეგობარი, ვინც ადრე დაგიდასტურდათ, დაინახავს უსაფრთხოების გაფრთხილებებს, სანამ მათთან ხელახლა გადაამოწმებთ.",
|
||||
"verify_reset_warning_2": "გთხოვთ გააგრძელოთ მხოლოდ იმ შემთხვევაში, თუ დარწმუნებული ხართ, რომ დაკარგეთ ყველა თქვენი სხვა მოწყობილობა და უსაფრთხოების გასაღები.",
|
||||
"verify_using_device": "გადაამოწმეთ სხვა მოწყობილობით",
|
||||
"verify_using_key": "გადაამოწმეთ უსაფრთხოების გასაღებით",
|
||||
"verify_using_key_or_phrase": "გადაამოწმეთ უსაფრთხოების გასაღებით ან ფრაზით",
|
||||
|
||||
@@ -731,7 +731,6 @@
|
||||
"accepting": "ກຳລັງຍອມຮັບ…",
|
||||
"after_new_login": {
|
||||
"device_verified": "ຢັ້ງຢືນອຸປະກອນແລ້ວ",
|
||||
"reset_confirmation": "ຕັ້ງຄ່າຢືນຢັນກະແຈຄືນໃໝ່ບໍ?",
|
||||
"skip_verification": "ຂ້າມການຢັ້ງຢືນດຽວນີ້",
|
||||
"unable_to_verify": "ບໍ່ສາມາດຢັ້ງຢືນອຸປະກອນນີ້ໄດ້",
|
||||
"verify_this_device": "ຢັ້ງຢືນອຸປະກອນນີ້"
|
||||
@@ -793,7 +792,6 @@
|
||||
"verify_emoji_prompt": "ຢັ້ງຢືນໂດຍການປຽບທຽບ emoji ທີ່ເປັນເອກະລັກ.",
|
||||
"verify_emoji_prompt_qr": "ຖ້າທ່ານບໍ່ສາມາດສະແກນລະຫັດຂ້າງເທິງໄດ້, ໃຫ້ກວດສອບໂດຍການປຽບທຽບອີໂມຈິທີ່ເປັນເອກະລັກ.",
|
||||
"verify_later": "ຂ້ອຍຈະກວດສອບພາຍຫຼັງ",
|
||||
"verify_reset_warning_1": "ການຕັ້ງຄ່າລະຫັດຢືນຢັນຂອງທ່ານບໍ່ສາມາດຍົກເລີກໄດ້. ຫຼັງຈາກການຕັ້ງຄ່າແລ້ວ, ທ່ານຈະບໍ່ສາມາດເຂົ້າເຖິງຂໍ້ຄວາມທີ່ເຂົ້າລະຫັດເກົ່າໄດ້, ແລະ ໝູ່ເພື່ອນທີ່ຢືນຢັນໄປກ່ອນໜ້ານີ້ ທ່ານຈະເຫັນຄຳເຕືອນຄວາມປອດໄພຈົນກວ່າທ່ານຈະຢືນຢັນກັບພວກມັນຄືນໃໝ່.",
|
||||
"verify_using_device": "ຢັ້ງຢືນດ້ວຍອຸປະກອນອື່ນ",
|
||||
"verify_using_key": "ຢືນຢັນດ້ວຍກະແຈຄວາມປອດໄພ",
|
||||
"verify_using_key_or_phrase": "ຢືນຢັນດ້ວຍກະແຈຄວາມປອດໄພ ຫຼືປະໂຫຍກ",
|
||||
@@ -2285,13 +2283,11 @@
|
||||
"heading_with_query": "ໃຊ້ \"%(query)s\" ເພື່ອຊອກຫາ",
|
||||
"join_button_text": "ເຂົ້າຮ່ວມ %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "ໃຊ້ <arrows/> ເພື່ອເລື່ອນ",
|
||||
"message_search_section_title": "ການຄົ້ນຫາອື່ນໆ",
|
||||
"other_rooms_in_space": "ຫ້ອງອື່ນໆ%(spaceName)s",
|
||||
"public_rooms_label": "ຫ້ອງສາທາລະນະ",
|
||||
"recent_searches_section_title": "ການຄົ້ນຫາທີ່ຜ່ານມາ",
|
||||
"recently_viewed_section_title": "ເບິ່ງເມື່ອບໍ່ດົນມານີ້",
|
||||
"search_dialog": "ຊອກຫາ ກ່ອງໂຕ້ຕອບ",
|
||||
"search_messages_hint": "ເພື່ອຊອກຫາຂໍ້ຄວາມ, ຊອກຫາໄອຄອນນີ້ຢູ່ເທິງສຸດຂອງຫ້ອງ <icon/>",
|
||||
"spaces_title": "ຊ່ອງທີ່ທ່ານຢູ່"
|
||||
},
|
||||
"stickers": {
|
||||
|
||||
@@ -908,7 +908,6 @@
|
||||
"accepting": "Apstiprina…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Ierīce ir verificēta",
|
||||
"reset_confirmation": "Vai tiešām atiestatīt verifikācijas atslēgas?",
|
||||
"skip_verification": "Pagaidām izlaist verifikāciju",
|
||||
"unable_to_verify": "Neizdevās verificēt šo ierīci",
|
||||
"verify_this_device": "Verificēt šo ierīci"
|
||||
@@ -979,8 +978,6 @@
|
||||
"verify_emoji_prompt": "Apliecināt ar vienreizēju emocijzīmu salīdzināšanu.",
|
||||
"verify_emoji_prompt_qr": "Ja nevar nolasīt augstāk esošo kodu, var apliecināt ar vienreizēju emocijzīmju salīdzināšanu.",
|
||||
"verify_later": "Es verificēšu vēlāk",
|
||||
"verify_reset_warning_1": "Verifikācijas atslēgu atiestatīšanu nevar atsaukt. Pēc atiestatīšanas jūs nevarēsit piekļūt vecām šifrētām ziņām, un visi draugi, kas jūs iepriekš ir verificējuši, redzēs drošības brīdinājumus, līdz veiksit atkārtotu verifikāciju.",
|
||||
"verify_reset_warning_2": "Lūdzu, turpiniet tikai tad, ja esat pārliecināts, ka esat zaudējis visas pārējās ierīces un drošības atslēgu.",
|
||||
"verify_using_device": "Verificēt ar citu ierīci",
|
||||
"verify_using_key": "Verificēt ar drošības atslēgu",
|
||||
"verify_using_key_or_phrase": "Verificēt, izmantojot drošības atslēgu vai frāzi",
|
||||
@@ -2765,7 +2762,6 @@
|
||||
"heading_with_query": "Izmantot \"%(query)s\" meklēšanai",
|
||||
"heading_without_query": "Meklēt",
|
||||
"keyboard_scroll_hint": "Lietojiet <arrows/> ritināšanai",
|
||||
"message_search_section_title": "Citi meklējumi",
|
||||
"other_rooms_in_space": "Citas istabas %(spaceName)s",
|
||||
"public_rooms_label": "Publiskas istabas",
|
||||
"public_spaces_label": "Publiskās telpas",
|
||||
@@ -2774,7 +2770,6 @@
|
||||
"remove_filter": "Noņemt meklēšanas filtru %(filter)s",
|
||||
"result_may_be_hidden_privacy_warning": "Daži rezultāti var būt slēpti dēļ privātuma",
|
||||
"result_may_be_hidden_warning": "Atsevišķi rezultāti var būt slēpti",
|
||||
"search_messages_hint": "Lai meklētu ziņas, istabas augšpusē meklējiet šo ikonu <icon/>",
|
||||
"spaces_title": "Telpas, kurās atrodaties",
|
||||
"start_group_chat_button": "Uzsākt grupas tērzēšanu"
|
||||
},
|
||||
|
||||
@@ -865,7 +865,6 @@
|
||||
"accepting": "Manaiky…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Voamarina ny fitaovana",
|
||||
"reset_confirmation": "Avereno tokoa ny fanalahidiny fanamarinana?",
|
||||
"skip_verification": "Alefaso ny fanamarinana amin'izao fotoana izao",
|
||||
"unable_to_verify": "Tsy afaka manamarina ity fitaovana ity",
|
||||
"verify_this_device": "Hamarino ity fitaovana ity"
|
||||
@@ -935,8 +934,6 @@
|
||||
"verify_emoji_prompt": "Hamarino amin'ny fampitahana emoji tokana.",
|
||||
"verify_emoji_prompt_qr": "Raha tsy azonao atao ny mijery ny kaody etsy ambony dia hamarino amin'ny fampitahana emoji tokana.",
|
||||
"verify_later": "Hamariniko avy eo",
|
||||
"verify_reset_warning_1": "Tsy azo atao ny mamerina ny fanalahidiny fanamarinanao. Aoriany famerenanao dia tsy ho afaka miditra amin'ny hafatra miafina taloha ianao, ary izay namana nanamarina anao teo aloha dia hahita fampitandremana momba ny fiarovana mandra-panamarinanao azy ireo indray.",
|
||||
"verify_reset_warning_2": "Tohizo ihany azafady raha azonao antoka fa very daholo ny fitaovanao hafa rehetra sy ny Key Security.",
|
||||
"verify_using_device": "Hamarino amin'ny fitaovana hafa",
|
||||
"verify_using_key": "Hamarino aminy fanalahidiny voaharo",
|
||||
"verify_using_key_or_phrase": "Hamarino amin'ny fanalahidy na rakin-tsoratra voaharo",
|
||||
@@ -2817,7 +2814,6 @@
|
||||
"heading_without_query": "Hitady ny",
|
||||
"join_button_text": "anjara%(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Ampiasao<arrows/> ny horonan-taratasy",
|
||||
"message_search_section_title": "Fikarohana hafa",
|
||||
"other_rooms_in_space": "Efitrano hafa ao%(spaceName)s",
|
||||
"public_rooms_label": "Efitranom-bahoaka",
|
||||
"public_spaces_label": "Toeram-bahoaka",
|
||||
@@ -2827,7 +2823,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Mety hafenina hoany fiainana manokana ny valiny sasany",
|
||||
"result_may_be_hidden_warning": "Mety hafenina ny valiny sasany",
|
||||
"search_dialog": "Fikarohana Dialog",
|
||||
"search_messages_hint": "Raha hikaroka hafatra dia tadiavo ity kisary ity eo an-tampon'ny efitrano iray<icon/>",
|
||||
"spaces_title": "Toerana misy anao",
|
||||
"start_group_chat_button": "Manomboha resaka vondrona"
|
||||
},
|
||||
|
||||
@@ -386,6 +386,7 @@
|
||||
"fallback_button": "Begynn autentisering",
|
||||
"mas_cross_signing_reset_cta": "Gå til kontoen din",
|
||||
"mas_cross_signing_reset_description": "Tilbakestill identiteten din gjennom kontoleverandøren din, og kom deretter tilbake og klikk \"Prøv på nytt\".",
|
||||
"mas_cross_signing_reset_title": "Gå til kontoen din for å tilbakestille identiteten din",
|
||||
"msisdn": "En SMS har blitt sendt til %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Sjetongen er feil",
|
||||
"msisdn_token_prompt": "Vennligst skriv inn koden den inneholder:",
|
||||
@@ -993,7 +994,6 @@
|
||||
"accepting": "Aksepterer …",
|
||||
"after_new_login": {
|
||||
"device_verified": "Enhet verifisert",
|
||||
"reset_confirmation": "Vil du virkelig tilbakestille bekreftelsesnøkler?",
|
||||
"skip_verification": "Hopp over verifisering for nå",
|
||||
"unable_to_verify": "Kan ikke verifisere denne enheten",
|
||||
"verify_this_device": "Verifiser denne enheten"
|
||||
@@ -1064,8 +1064,6 @@
|
||||
"verify_emoji_prompt": "Bekreft ved å sammenligne unike emoji.",
|
||||
"verify_emoji_prompt_qr": "Hvis du ikke kan skanne koden ovenfor, bekreft ved å sammenligne unike emoji.",
|
||||
"verify_later": "Jeg bekrefter senere",
|
||||
"verify_reset_warning_1": "Tilbakestilling av bekreftelsesnøklene kan ikke angres. Etter tilbakestilling har du ikke tilgang til gamle krypterte meldinger, og eventuelle venner som tidligere har bekreftet deg, vil se sikkerhetsadvarsler til du bekrefter med dem på nytt.",
|
||||
"verify_reset_warning_2": "Fortsett bare hvis du er sikker på at du har mistet alle de andre enhetene og sikkerhetsnøkkelen din.",
|
||||
"verify_using_device": "Bekreft med en annen enhet",
|
||||
"verify_using_key": "Bekreft med gjenopprettingsnøkkel",
|
||||
"verify_using_key_or_phrase": "Bekreft med gjenopprettingsnøkkel eller -frase",
|
||||
@@ -2121,6 +2119,7 @@
|
||||
"failed_add_tag": "Kunne ikke legge til tagg %(tagName)s til rom",
|
||||
"failed_remove_tag": "Kunne ikke fjerne tagg %(tagName)s fra rommet",
|
||||
"failed_set_dm_tag": "Kan ikke sette kode på direktemeldingen",
|
||||
"filter": "Filter",
|
||||
"filters": {
|
||||
"favourite": "Favoritter",
|
||||
"people": "Personer",
|
||||
@@ -2154,6 +2153,12 @@
|
||||
"open_room": "Åpne rom %(roomName)s"
|
||||
},
|
||||
"room_options": "Rominnstillinger",
|
||||
"secondary_filter": {
|
||||
"all_activity": "All aktivitet",
|
||||
"invites_only": "Kun invitasjoner",
|
||||
"low_priority": "Lav prioritet",
|
||||
"mentions_only": "Kun omtaler"
|
||||
},
|
||||
"secondary_filters": "Sekundære filtre",
|
||||
"show_less": "Vis mindre",
|
||||
"show_message_previews": "Aktiver forhåndsvisning av meldinger",
|
||||
@@ -2629,6 +2634,7 @@
|
||||
"discovery_needs_terms_title": "La folk finne deg",
|
||||
"display_name": "Visningsnavn",
|
||||
"display_name_error": "Kan ikke angi visningsnavn",
|
||||
"email_adding_unsupported_by_hs": "Denne hjemmeserveren støtter ikke å legge til flere e-postadresser til kontoen din.",
|
||||
"email_address_in_use": "Denne e-postadressen er allerede i bruk",
|
||||
"email_address_label": "E-postadresse",
|
||||
"email_not_verified": "E-postadressen din er ikke verifisert ennå",
|
||||
@@ -2653,7 +2659,9 @@
|
||||
"error_share_msisdn_discovery": "Kan ikke dele telefonnummer",
|
||||
"identity_server_no_token": "Ingen identitetstilgangstoken funnet",
|
||||
"identity_server_not_set": "Identitetsserver er ikke angitt",
|
||||
"invalid_phone_number": "Telefonnummeret som er oppgitt ser ikke ut til å være gyldig.",
|
||||
"language_section": "Språk",
|
||||
"msisdn_adding_unsupported_by_hs": "Denne hjemmeserveren støtter ikke å legge til telefonnumre til kontoen din.",
|
||||
"msisdn_in_use": "Dette mobilnummeret er allerede i bruk",
|
||||
"msisdn_label": "Telefonnummer",
|
||||
"msisdn_verification_field_label": "Verifikasjonskode",
|
||||
@@ -3225,7 +3233,7 @@
|
||||
"heading_without_query": "Søk etter",
|
||||
"join_button_text": "Bli med i %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Bruk <arrows/> for å scrolle",
|
||||
"message_search_section_title": "Andre søk",
|
||||
"messages_label": "Meldinger",
|
||||
"other_rooms_in_space": "Andre rom i %(spaceName)s",
|
||||
"public_rooms_label": "Offentlige rom",
|
||||
"public_spaces_label": "Offentlige områder",
|
||||
@@ -3235,7 +3243,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Noen resultater kan være skjult av personvernhensyn",
|
||||
"result_may_be_hidden_warning": "Noen resultater kan være skjult",
|
||||
"search_dialog": "Søkedialog",
|
||||
"search_messages_hint": "For å søke i meldinger, se etter dette ikonet øverst i et rom <icon/>",
|
||||
"spaces_title": "Områder du er i",
|
||||
"start_group_chat_button": "Start en gruppechat"
|
||||
},
|
||||
@@ -3284,9 +3291,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Trådaktivitet",
|
||||
"no_rooms_with_threads_notifs": "Du har ikke rom med trådvarsler ennå.",
|
||||
"no_rooms_with_unread_threads": "Du har ikke rom med uleste tråder ennå.",
|
||||
"release_announcement_description": "Trådenotifikasjoner er flyttet, du finner dem her fra nå av.",
|
||||
"release_announcement_header": "Aktivitetssenter for tråder"
|
||||
"no_rooms_with_unread_threads": "Du har ikke rom med uleste tråder ennå."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "cirka 1 dag siden",
|
||||
@@ -3794,10 +3799,10 @@
|
||||
"unavailable": "Ikke tilgjengelig"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Hvis du vil opprette en delingslenke, må du tillate gjester å bli med i dette rommet. Dette kan gjøre rommet mindre sikkert. Når du er ferdig med samtalen, kan du gjøre rommet privat igjen.",
|
||||
"dont_change_description": "Alternativt kan du holde samtalen i et eget rom.",
|
||||
"description": "For å opprette en delingslenke, lag dette rommet <b>offentlig</b> eller aktiver alternativet for brukere å <b>be om å bli med</b> Dette lar gjester bli med uten å bli invitert.",
|
||||
"dont_change_description": "Hvis du ikke ønsker å endre tilgangen til dette rommet, kan du opprette et nytt rom for lenken.",
|
||||
"no_change": "Jeg vil ikke endre tilgangsnivået.",
|
||||
"title": "Endre tilgangsnivået til rommet"
|
||||
"title": "Tillat gjestebrukere å bli med i dette rommet"
|
||||
},
|
||||
"upload_failed_generic": "Filen '%(fileName)s' kunne ikke lastes opp.",
|
||||
"upload_failed_size": "Filen \"%(fileName)s\" er større enn hjemmeserverens grense for opplastninger",
|
||||
|
||||
@@ -764,7 +764,6 @@
|
||||
"accepting": "Toestaan…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Apparaat geverifieerd",
|
||||
"reset_confirmation": "Echt je verificatiesleutels resetten?",
|
||||
"skip_verification": "Verificatie voorlopig overslaan",
|
||||
"unable_to_verify": "Kan dit apparaat niet verifiëren",
|
||||
"verify_this_device": "Verifieer dit apparaat"
|
||||
@@ -826,7 +825,6 @@
|
||||
"verify_emoji_prompt": "Verifieer door unieke emoji te vergelijken.",
|
||||
"verify_emoji_prompt_qr": "Als je bovenstaande code niet kan scannen, verifieer dan door unieke emoji te vergelijken.",
|
||||
"verify_later": "Ik verifieer het later",
|
||||
"verify_reset_warning_1": "Het resetten van je verificatiesleutels kan niet ongedaan worden gemaakt. Na het resetten heb je geen toegang meer tot oude versleutelde berichten, en vrienden die je eerder hebben geverifieerd zullen veiligheidswaarschuwingen zien totdat je opnieuw bij hen geverifieert bent.",
|
||||
"verify_using_device": "Verifieer met andere apparaat",
|
||||
"verify_using_key": "Verifieer met veiligheidssleutel",
|
||||
"verify_using_key_or_phrase": "Verifieer met veiligheidssleutel of -wachtwoord",
|
||||
@@ -2417,7 +2415,6 @@
|
||||
"heading_without_query": "Zoeken naar",
|
||||
"join_button_text": "%(roomAddress)s toetreden",
|
||||
"keyboard_scroll_hint": "Gebruik <arrows/> om te scrollen",
|
||||
"message_search_section_title": "Andere zoekopdrachten",
|
||||
"other_rooms_in_space": "Andere kamers in %(spaceName)s",
|
||||
"public_rooms_label": "Publieke kamers",
|
||||
"recent_searches_section_title": "Recente zoekopdrachten",
|
||||
@@ -2426,7 +2423,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Sommige resultaten kunnen om privacyredenen verborgen zijn",
|
||||
"result_may_be_hidden_warning": "Sommige resultaten zijn mogelijk verborgen",
|
||||
"search_dialog": "Dialoogvenster Zoeken",
|
||||
"search_messages_hint": "Om berichten te zoeken, zoek naar dit icoon bovenaan een kamer <icon/>",
|
||||
"spaces_title": "Spaces waar u in zit",
|
||||
"start_group_chat_button": "Start een groepsgesprek"
|
||||
},
|
||||
|
||||
@@ -388,6 +388,7 @@
|
||||
"fallback_button": "Rozpocznij uwierzytelnienie",
|
||||
"mas_cross_signing_reset_cta": "Przejdź do swojego konta",
|
||||
"mas_cross_signing_reset_description": "Zresetuj swoją tożsamość poprzez dostawcę swojego konta, wróć i kliknij „Ponów”.",
|
||||
"mas_cross_signing_reset_title": "Przejdź do swojego konta, aby zresetować swoją tożsamość",
|
||||
"msisdn": "Wysłano wiadomość tekstową do %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Niepoprawny token",
|
||||
"msisdn_token_prompt": "Wpisz kod, który jest tam zawarty:",
|
||||
@@ -917,7 +918,7 @@
|
||||
"access_secret_storage_dialog": {
|
||||
"enter_phrase_or_key_prompt": "Wprowadź swoją frazę bezpieczeństwa lub <button>użyj klucza przywracania</button>, aby kontynuować.",
|
||||
"key_validation_text": {
|
||||
"invalid_security_key": "Błędny klucz przywracania",
|
||||
"invalid_security_key": "Nieprawidłowy klucz przywracania",
|
||||
"recovery_key_is_correct": "Wygląda dobrze!",
|
||||
"wrong_file_type": "Błędny typ pliku",
|
||||
"wrong_security_key": "Błędny klucz przywracania"
|
||||
@@ -999,7 +1000,6 @@
|
||||
"accepting": "Akceptowanie…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Urządzenie zweryfikowane",
|
||||
"reset_confirmation": "Czy na pewno zresetować klucze weryfikacyjne?",
|
||||
"skip_verification": "Pomiń weryfikację na razie",
|
||||
"unable_to_verify": "Nie można zweryfikować tego urządzenia",
|
||||
"verify_this_device": "Zweryfikuj to urządzenie"
|
||||
@@ -1070,8 +1070,6 @@
|
||||
"verify_emoji_prompt": "Zweryfikuj, porównując unikalne emotikony.",
|
||||
"verify_emoji_prompt_qr": "Jeśli nie jesteś w stanie skanować kodu powyżej, zweryfikuj porównując emoji.",
|
||||
"verify_later": "Zweryfikuję później",
|
||||
"verify_reset_warning_1": "Zresetowanie kluczy weryfikacyjnych nie może być cofnięte. Po zresetowaniu, nie będziesz mieć dostępu do starych wiadomości szyfrowanych, a wszyscy znajomi, którzy wcześniej Cię zweryfikowali, będą widzieć ostrzeżenia do czasu ponownej weryfikacji.",
|
||||
"verify_reset_warning_2": "Kontynuuj tylko wtedy, gdy masz pewność, że utraciłeś wszystkie inne urządzenia i swój klucz przywracania.",
|
||||
"verify_using_device": "Zweryfikuj innym urządzeniem",
|
||||
"verify_using_key": "Zweryfikuj kluczem przywracania",
|
||||
"verify_using_key_or_phrase": "Zweryfikuj kluczem przywracania lub frazą",
|
||||
@@ -2137,6 +2135,7 @@
|
||||
"failed_add_tag": "Nie można dodać tagu %(tagName)s do pokoju",
|
||||
"failed_remove_tag": "Nie udało się usunąć tagu %(tagName)s z pokoju",
|
||||
"failed_set_dm_tag": "Nie udało się ustawić tagu wiadomości prywatnych",
|
||||
"filter": "Filtr",
|
||||
"filters": {
|
||||
"favourite": "Ulubione",
|
||||
"people": "Osoby",
|
||||
@@ -2170,6 +2169,12 @@
|
||||
"open_room": "Pokój otwarty %(roomName)s"
|
||||
},
|
||||
"room_options": "Opcje pokoju",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Cała aktywność",
|
||||
"invites_only": "Tylko zaproszenie",
|
||||
"low_priority": "Niski priorytet",
|
||||
"mentions_only": "Tylko wzmianki"
|
||||
},
|
||||
"secondary_filters": "Filtry poboczne",
|
||||
"show_less": "Pokaż mniej",
|
||||
"show_message_previews": "Pokaż podglądy wiadomości",
|
||||
@@ -2469,6 +2474,10 @@
|
||||
"recent_changes_heading": "Najnowsze zmiany nie zostały jeszcze wprowadzone",
|
||||
"title": "Serwer nie odpowiada"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s wymaga workera usługi, aby móc załadować zabezpieczone media z repozytoriów Matrix. Ta funkcja nie jest obsługiwana przez Twoją przeglądarkę, więc niektóre media mogą się nie załadować.",
|
||||
"title": "Nie udało się załadować workera usługi"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Wystąpił błąd inicjalizacji wyszukiwania wiadomości, sprawdź <a>swoje ustawienia</a> po więcej informacji",
|
||||
"reset_button": "Resetuj bank wydarzeń",
|
||||
@@ -2647,6 +2656,7 @@
|
||||
"discovery_needs_terms_title": "Pozwól ludziom Cię znaleźć",
|
||||
"display_name": "Wyświetlana nazwa",
|
||||
"display_name_error": "Nie można ustawić wyświetlanej nazwy",
|
||||
"email_adding_unsupported_by_hs": "Ten serwer domowy nie obsługuje dodawania adresów e-mail do Twojego konta.",
|
||||
"email_address_in_use": "Podany adres e-mail jest już w użyciu",
|
||||
"email_address_label": "Adres e-mail",
|
||||
"email_not_verified": "Twój adres e-mail nie został jeszcze zweryfikowany",
|
||||
@@ -2671,7 +2681,9 @@
|
||||
"error_share_msisdn_discovery": "Nie udało się udostępnić numeru telefonu",
|
||||
"identity_server_no_token": "Nie znaleziono tokena dostępu tożsamości",
|
||||
"identity_server_not_set": "Serwer tożsamości nie jest ustawiony",
|
||||
"invalid_phone_number": "Podany numer telefonu nie wydaje się być poprawny.",
|
||||
"language_section": "Język",
|
||||
"msisdn_adding_unsupported_by_hs": "Ten serwer domowy nie obsługuje dodawania numerów telefonu do Twojego konta.",
|
||||
"msisdn_in_use": "Ten numer telefonu jest już zajęty",
|
||||
"msisdn_label": "Numer telefonu",
|
||||
"msisdn_verification_field_label": "Kod weryfikacyjny",
|
||||
@@ -3243,7 +3255,7 @@
|
||||
"heading_without_query": "Szukaj",
|
||||
"join_button_text": "Dołącz %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Użyj <arrows/>, aby przewijać",
|
||||
"message_search_section_title": "Inne wyszukiwania",
|
||||
"messages_label": "Wiadomości",
|
||||
"other_rooms_in_space": "Inne pokoje w %(spaceName)s",
|
||||
"public_rooms_label": "Pokoje publiczne",
|
||||
"public_spaces_label": "Przestrzenie publiczne",
|
||||
@@ -3253,7 +3265,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Niektóre wyniki zostały ukryte dla ochrony prywatności",
|
||||
"result_may_be_hidden_warning": "Niektóre wyniki mogą być ukryte",
|
||||
"search_dialog": "Pasek wyszukiwania",
|
||||
"search_messages_hint": "Aby szukać wiadomości, poszukaj tej ikony na górze pokoju <icon/>",
|
||||
"spaces_title": "Przestrzenie, w których jesteś",
|
||||
"start_group_chat_button": "Rozpocznij czat grupowy"
|
||||
},
|
||||
@@ -3291,7 +3302,7 @@
|
||||
"other": "%(count)s odpowiedzi"
|
||||
},
|
||||
"empty_description": "Użyj „%(replyInThread)s” po najechaniu kursorem na wiadomość",
|
||||
"empty_title": "Wątki pomagają utrzymać tematykę rozmów i łatwo za nimi podążyć.",
|
||||
"empty_title": "Wątki pomagają utrzymać tematykę rozmów i łatwo za nimi podążać.",
|
||||
"error_start_thread_existing_relation": "Nie można utworzyć wątku z wydarzenia z istniejącą relacją",
|
||||
"mark_all_read": "Oznacz wszystkie jako przeczytane",
|
||||
"my_threads": "Moje wątki",
|
||||
@@ -3302,9 +3313,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Aktywność wątków",
|
||||
"no_rooms_with_threads_notifs": "Nie masz jeszcze pokoi z powiadomieniami w wątku.",
|
||||
"no_rooms_with_unread_threads": "Nie masz jeszcze pokoi z nieprzeczytanymi wątkami.",
|
||||
"release_announcement_description": "Powiadomienia w wątkach zostały przeniesione, teraz znajdziesz je tutaj.",
|
||||
"release_announcement_header": "Centrum aktywności wątków"
|
||||
"no_rooms_with_unread_threads": "Nie masz jeszcze pokoi z nieprzeczytanymi wątkami."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "około dzień temu",
|
||||
@@ -3822,10 +3831,10 @@
|
||||
"unavailable": "Niedostępny"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Aby utworzyć link udostępniania, musisz zezwolić gościom na dołączenie do tego pokoju. Może to zmniejszyć bezpieczeństwo pokoju. Gdy zakończysz połączenie, możesz ustawić pokój jako prywatny z powrotem.",
|
||||
"dont_change_description": "Możesz również zadzwonić w innym pokoju.",
|
||||
"description": "Aby utworzyć link udostępniania, ustaw ten pokój jako <b>publiczny</b> lub włącz opcję umożliwiającą użytkownikom <b>poprosić o dołączenie</b>. Dzięki temu goście będą mogli dołączyć bez zaproszenia.",
|
||||
"dont_change_description": "Jeśli nie chcesz zmieniać uprawnień dostępu tego pokoju, możesz utworzyć link połączenia w nowym pokoju.",
|
||||
"no_change": "Nie chce zmieniać poziomu uprawnień.",
|
||||
"title": "Zmień poziom dostępu pokoju"
|
||||
"title": "Zezwól gościom na dołączenie do tego pokoju"
|
||||
},
|
||||
"upload_failed_generic": "Nie udało się przesłać pliku '%(fileName)s'.",
|
||||
"upload_failed_size": "Plik '%(fileName)s' przekracza limit rozmiaru dla tego serwera głównego",
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
"go_back": "Voltar",
|
||||
"got_it": "Entendi",
|
||||
"hide": "Ocultar",
|
||||
"hide_advanced": "Ocultar avançado",
|
||||
"hide_advanced": "Ocultar avançadas",
|
||||
"hold": "Espera",
|
||||
"ignore": "Ignorar",
|
||||
"import": "Importar",
|
||||
@@ -939,8 +939,8 @@
|
||||
"title": "Novo método de recuperação",
|
||||
"warning": "Se não tiveres definido o novo método de recuperação, um atacante pode estar a tentar aceder à tua conta. Altera a palavra-passe da tua conta e define imediatamente um novo método de recuperação nas Definições."
|
||||
},
|
||||
"pinned_identity_changed": "A identidade de %(displayName)s (<b>%(userId)s</b> ) parece ter mudado.<a> Saber mais</a>",
|
||||
"pinned_identity_changed_no_displayname": "A identidade de <b>%(userId)s</b> parece ter mudado. <a>Saiba mais</a>",
|
||||
"pinned_identity_changed": "A identidade de %(displayName)s (<b>%(userId)s</b> ) foi alterada. <a> Saber mais</a>",
|
||||
"pinned_identity_changed_no_displayname": "A identidade de <b>%(userId)s</b> foi alterada. <a>Saber mais</a>",
|
||||
"recovery_method_removed": {
|
||||
"description_1": "Esta sessão detectou que a tua frase de segurança e a chave para as mensagens seguras foram removidas.",
|
||||
"description_2": "Se o fizeste acidentalmente, podes configurar as Mensagens seguras nesta sessão, o que criptografará novamente o histórico de mensagens desta sessão com um novo método de recuperação.",
|
||||
@@ -969,7 +969,6 @@
|
||||
"accepting": "Aceitando...",
|
||||
"after_new_login": {
|
||||
"device_verified": "Dispositivo verificado",
|
||||
"reset_confirmation": "Repõe mesmo as chaves de verificação?",
|
||||
"skip_verification": "Ignora a verificação por enquanto",
|
||||
"unable_to_verify": "Não é possível verificar este dispositivo",
|
||||
"verify_this_device": "Verifica este dispositivo"
|
||||
@@ -1040,8 +1039,6 @@
|
||||
"verify_emoji_prompt": "Verifica comparando o emoji único.",
|
||||
"verify_emoji_prompt_qr": "Se não conseguires ler o código acima, verifica-o comparando emojis.",
|
||||
"verify_later": "Verificarei mais tarde",
|
||||
"verify_reset_warning_1": "A reposição das tuas chaves de verificação não pode ser anulada. Após a reposição, não terás acesso a mensagens encriptadas antigas e todos os amigos que te tenham verificado anteriormente verão avisos de segurança até voltares a verificar com eles.",
|
||||
"verify_reset_warning_2": "Só avances se tiveres a certeza de que perdeste todos os teus outros dispositivos e a tua chave de recuperação.",
|
||||
"verify_using_device": "Verifica com outro dispositivo",
|
||||
"verify_using_key": "Verifica com a chave de recuperação",
|
||||
"verify_using_key_or_phrase": "Verifica com a chave ou frase de recuperação",
|
||||
@@ -1052,7 +1049,7 @@
|
||||
},
|
||||
"verification_requested_toast_title": "Verificação solicitada",
|
||||
"verified_identity_changed": "%(displayName)s(<b>%(userId)s</b>) mudou a tua identidade verificada. <a>Saber mais</a>",
|
||||
"verified_identity_changed_no_displayname": "A identidade verificada de <b>%(userId)s</b> foi alterada. <a>Saber mais</a>",
|
||||
"verified_identity_changed_no_displayname": "A identidade de <b>%(userId)s</b> foi alterada. <a>Saber mais</a>",
|
||||
"verify_toast_description": "Outros utilizadores podem não confiar nisto",
|
||||
"verify_toast_title": "Verifica esta sessão",
|
||||
"withdraw_verification_action": "Retirar verificação"
|
||||
@@ -2168,7 +2165,7 @@
|
||||
"upgrade_dwarning_ialog_title_public": "Atualizar sala pública",
|
||||
"upgrade_warning_dialog_description": "A atualização de uma divisão é uma ação avançada e é normalmente recomendada quando uma divisão está instável devido a erros, funcionalidades em falta ou vulnerabilidades de segurança.",
|
||||
"upgrade_warning_dialog_explainer": "<b>Tem em atenção que a atualização fará uma nova versão da sala</b>. Todas as mensagens actuais permanecerão nesta sala arquivada.",
|
||||
"upgrade_warning_dialog_footer": "Actualizarás este quarto de <oldVersion /> para <newVersion />.",
|
||||
"upgrade_warning_dialog_footer": "Esta sala será atualizada de <oldVersion /> para <newVersion />.",
|
||||
"upgrade_warning_dialog_invite_label": "Convida automaticamente os membros desta sala para a nova sala",
|
||||
"upgrade_warning_dialog_report_bug_prompt": "Normalmente, isto só afecta a forma como a sala é processada no servidor. Se estiveres a ter problemas com o teu %(brand)s, por favor reporta um erro.",
|
||||
"upgrade_warning_dialog_report_bug_prompt_link": "Normalmente, isto apenas afecta a forma como a sala é processada no servidor. Se estiveres a ter problemas com o teu %(brand)s, por favor <a>reporta um bug</a>.",
|
||||
@@ -2308,7 +2305,7 @@
|
||||
"encrypted_room_public_confirm_description_1": "<b>Não é recomendável tornar públicas as salas encriptadas.</b> Isso significa que qualquer pessoa pode encontrar e entrar na sala, pelo que qualquer pessoa pode ler as mensagens. Não terás nenhum dos benefícios da encriptação. Encriptar mensagens numa sala pública tornará a receção e o envio de mensagens mais lento.",
|
||||
"encrypted_room_public_confirm_description_2": "Para evitar estes problemas, cria uma <a>nova sala pública</a> para a conversa que pretendes ter.",
|
||||
"encrypted_room_public_confirm_title": "Tens a certeza de que queres tornar pública esta sala encriptada?",
|
||||
"encryption_forced": "O teu servidor requer que a encriptação seja desactivada.",
|
||||
"encryption_forced": "O servidor requer que a encriptação seja desativada.",
|
||||
"encryption_permanent": "Uma vez activada, a encriptação não pode ser desactivada.",
|
||||
"error_join_rule_change_title": "Falha ao atualizar as regras de adesão",
|
||||
"error_join_rule_change_unknown": "Falha desconhecida",
|
||||
@@ -2363,7 +2360,7 @@
|
||||
"public_without_alias_warning": "Para estabelecer uma ligação a esta sala, adiciona um endereço.",
|
||||
"publish_room": "Torna esta sala visível no diretório público de salas.",
|
||||
"publish_space": "Torna este espaço visível no diretório de salas públicas.",
|
||||
"strict_encryption": "Nunca envia mensagens encriptadas para sessões não verificadas nesta sala a partir desta sessão",
|
||||
"strict_encryption": "Enviar mensagens apenas a utilizadores verificados.",
|
||||
"title": "Segurança e privacidade"
|
||||
},
|
||||
"title": "Configurações da sala -%(roomName)s",
|
||||
@@ -2818,7 +2815,7 @@
|
||||
"message_search_unsupported_web": "%(brand)s não é possível armazenar mensagens encriptadas em cache com segurança localmente durante a execução num navegador da Web. Usa <desktopLink>%(brand)s Desktop</desktopLink> para que as mensagens encriptadas apareçam nos resultados da pesquisa.",
|
||||
"record_session_details": "Grava o nome do cliente, a versão e o URL para reconhecer mais facilmente as sessões no gestor de sessões",
|
||||
"send_analytics": "Envia dados analíticos",
|
||||
"strict_encryption": "Nunca envies mensagens encriptadas para sessões não verificadas a partir desta sessão"
|
||||
"strict_encryption": "Enviar mensagens apenas a utilizadores verificados"
|
||||
},
|
||||
"send_read_receipts": "Enviar recibos lidos",
|
||||
"send_read_receipts_unsupported": "O teu servidor não suporta a desativação do envio de recibos de leitura.",
|
||||
@@ -3182,7 +3179,6 @@
|
||||
"heading_without_query": "Pesquisar por",
|
||||
"join_button_text": "Aderir %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Utiliza <arrows/> para te deslocares",
|
||||
"message_search_section_title": "Outras pesquisas",
|
||||
"other_rooms_in_space": "Outras salas em %(spaceName)s",
|
||||
"public_rooms_label": "Salas públicas",
|
||||
"public_spaces_label": "Espaços públicos",
|
||||
@@ -3192,7 +3188,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Alguns resultados podem estar ocultos por motivos de privacidade",
|
||||
"result_may_be_hidden_warning": "Alguns resultados podem estar ocultos",
|
||||
"search_dialog": "Diálogo de pesquisa",
|
||||
"search_messages_hint": "Para procurar mensagens, procura este ícone na parte superior de uma sala <icon/>",
|
||||
"spaces_title": "Espaços em que te encontras",
|
||||
"start_group_chat_button": "Inicia uma conversa de grupo"
|
||||
},
|
||||
@@ -3241,9 +3236,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Atividade de tópicos",
|
||||
"no_rooms_with_threads_notifs": "Ainda não tens salas com notificações de tópicos.",
|
||||
"no_rooms_with_unread_threads": "Ainda não tens salas com tópicos não lidos.",
|
||||
"release_announcement_description": "As notificações de tópicos foram movidas, encontre-as aqui a partir de agora.",
|
||||
"release_announcement_header": "Centro de Actividades Tópicos"
|
||||
"no_rooms_with_unread_threads": "Ainda não tens salas com tópicos não lidos."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "há cerca de um dia",
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"click": "Clicar",
|
||||
"click_to_copy": "Clique para copiar",
|
||||
"close": "Fechar",
|
||||
"collapse": "Colapsar",
|
||||
"collapse": "Recolher",
|
||||
"complete": "Concluir",
|
||||
"confirm": "Confirmar",
|
||||
"continue": "Continuar",
|
||||
@@ -72,7 +72,7 @@
|
||||
"explore_public_rooms": "Explorar salas públicas",
|
||||
"explore_rooms": "Explorar salas",
|
||||
"export": "Exportar",
|
||||
"forward": "Avançar",
|
||||
"forward": "Encaminhar",
|
||||
"go": "Próximo",
|
||||
"go_back": "Voltar",
|
||||
"got_it": "Ok, entendi",
|
||||
@@ -365,7 +365,7 @@
|
||||
"clear_data_description": "Apagar todos os dados desta sessão é uma ação permanente. Mensagens criptografadas serão perdidas, a não ser que as chaves delas tenham sido copiadas para o backup.",
|
||||
"clear_data_title": "Limpar todos os dados nesta sessão?"
|
||||
},
|
||||
"soft_logout_heading": "Você está desconectada/o",
|
||||
"soft_logout_heading": "Você está desconectado",
|
||||
"soft_logout_intro_password": "Digite sua senha para entrar e recuperar o acesso à sua conta.",
|
||||
"soft_logout_intro_sso": "Entre e recupere o acesso à sua conta.",
|
||||
"soft_logout_intro_unsupported_auth": "Você não pôde se conectar na sua conta. Entre em contato com o administrador do servidor para obter mais informações.",
|
||||
@@ -386,6 +386,7 @@
|
||||
"fallback_button": "Iniciar autenticação",
|
||||
"mas_cross_signing_reset_cta": "Vá para sua conta",
|
||||
"mas_cross_signing_reset_description": "Redefina sua identidade por meio do provedor da conta e, em seguida, volte e clique em “Tentar novamente”.",
|
||||
"mas_cross_signing_reset_title": "Acesse sua conta para redefinir sua identidade",
|
||||
"msisdn": "Uma mensagem de texto foi enviada para %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Token incorreto",
|
||||
"msisdn_token_prompt": "Por favor, entre com o código que está na mensagem:",
|
||||
@@ -415,12 +416,12 @@
|
||||
"before_submitting": "Antes de enviar os relatórios, você deve <a>criar um bilhete de erro no GitHub</a> para descrever seu problema.",
|
||||
"collecting_information": "Coletando informação sobre a versão do app",
|
||||
"collecting_logs": "Coletando logs",
|
||||
"create_new_issue": "Por favor, <newIssueLink>crie um novo bilhete de erro</newIssueLink> no GitHub para que possamos investigar esta falha.",
|
||||
"create_new_issue": "Por favor, <newIssueLink>crie um novo ticket de erro</newIssueLink> no GitHub para que possamos investigar esta falha.",
|
||||
"description": "Os logs de depuração contêm dados de uso do aplicativo, incluindo seu nome de usuário, os IDs ou aliases das salas que você visitou, com quais elementos da IU você interagiu pela última vez e os nomes de usuários de outros usuários. Eles não contêm mensagens.",
|
||||
"download_logs": "Baixar relatórios",
|
||||
"downloading_logs": "Baixando relatórios",
|
||||
"error_empty": "Por favor, diga-nos o que aconteceu de errado ou, ainda melhor, crie um bilhete de erro no GitHub que descreva o problema.",
|
||||
"failed_download_logs": "Falha ao baixar os registros de depuração: ",
|
||||
"download_logs": "Baixar logs",
|
||||
"downloading_logs": "Baixando logs",
|
||||
"error_empty": "Por favor, diga-nos o que aconteceu de errado ou, ainda melhor, crie um ticket de erro no GitHub que descreva o problema.",
|
||||
"failed_download_logs": "Falha ao baixar os logs: ",
|
||||
"failed_send_logs_causes": {
|
||||
"disallowed_app": "Seu relatório de bug foi rejeitado. O servidor rageshake não suporta esse aplicativo.",
|
||||
"rejected_generic": "Seu relatório de bug foi rejeitado. O servidor rageshake rejeitou o conteúdo do relatório devido a uma política.",
|
||||
@@ -429,20 +430,20 @@
|
||||
"server_unknown_error": "O servidor rageshake encontrou um erro desconhecido e não conseguiu lidar com o relatório.",
|
||||
"unknown_error": "Falha ao enviar logs."
|
||||
},
|
||||
"github_issue": "Bilhete de erro no GitHub",
|
||||
"github_issue": "Ticket de erro no GitHub",
|
||||
"introduction": "Se você enviou um bug pelo GitHub, os logs de depuração podem nos ajudar a rastrear o problema. ",
|
||||
"log_request": "Para nos ajudar a evitar isso no futuro, <a>envie-nos os relatórios</a>.",
|
||||
"logs_sent": "Relatórios enviados",
|
||||
"log_request": "Para nos ajudar a evitar que isso aconteça no futuro, <a>envie-nos logs</a>.",
|
||||
"logs_sent": "Logs enviados",
|
||||
"matrix_security_issue": "Para relatar um problema de segurança relacionado à tecnologia Matrix, leia a <a>Política de Divulgação de Segurança</a> da Matrix.org.",
|
||||
"preparing_download": "Preparando os relatórios para download",
|
||||
"preparing_logs": "Preparando para enviar relatórios",
|
||||
"send_logs": "Enviar relatórios",
|
||||
"submit_debug_logs": "Enviar relatórios de erros",
|
||||
"preparing_download": "Preparando para baixar logs",
|
||||
"preparing_logs": "Preparando para enviar logs",
|
||||
"send_logs": "Enviar logs",
|
||||
"submit_debug_logs": "Enviar logs de depuração",
|
||||
"textarea_label": "Notas",
|
||||
"thank_you": "Obrigado!",
|
||||
"title": "Relato de Erros",
|
||||
"unsupported_browser": "Lembrete: seu navegador não é compatível; portanto, sua experiência pode ser imprevisível.",
|
||||
"uploading_logs": "Enviando relatórios",
|
||||
"uploading_logs": "Enviando logs",
|
||||
"waiting_for_server": "Aguardando a resposta do servidor"
|
||||
},
|
||||
"cannot_invite_without_identity_server": "Não é possível convidar usuários por e-mail sem um servidor de identidade. Você pode se conectar a um em “Configurações”.",
|
||||
@@ -504,7 +505,7 @@
|
||||
"forward_message": "Encaminhar",
|
||||
"general": "Geral",
|
||||
"go_to_settings": "Ir para as configurações",
|
||||
"guest": "Convidada(o)",
|
||||
"guest": "Convidado",
|
||||
"help": "Ajuda",
|
||||
"historical": "Histórico",
|
||||
"home": "Início",
|
||||
@@ -715,7 +716,7 @@
|
||||
"name_required": "Por favor entre o nome do espaço",
|
||||
"personal_space": "Apenas eu",
|
||||
"personal_space_description": "Um espaço privado para organizar suas salas",
|
||||
"private_description": "Somente convite, melhor para si mesmo(a) ou para equipes",
|
||||
"private_description": "Somente para convidados, melhor para você ou para equipes",
|
||||
"private_heading": "O seu espaço privado",
|
||||
"private_personal_description": "Certifique-se de que as pessoas certas tenham acesso a %(name)s",
|
||||
"private_personal_heading": "Com quem você está trabalhando?",
|
||||
@@ -993,7 +994,6 @@
|
||||
"accepting": "Aceitando…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Dispositivo verificado",
|
||||
"reset_confirmation": "Você realmente deseja redefinir as chaves de verificação?",
|
||||
"skip_verification": "Ignorar a verificação por enquanto",
|
||||
"unable_to_verify": "Não foi possível verificar este dispositivo",
|
||||
"verify_this_device": "Verifique este dispositivo"
|
||||
@@ -1064,8 +1064,6 @@
|
||||
"verify_emoji_prompt": "Confirmar comparando emojis únicos.",
|
||||
"verify_emoji_prompt_qr": "Se você não consegue escanear o código acima, confirme comparando emojis únicos.",
|
||||
"verify_later": "Vou verificar mais tarde",
|
||||
"verify_reset_warning_1": "A redefinição de suas chaves de verificação não pode ser desfeita. Após a redefinição, você não terá acesso às mensagens criptografadas antigas e todos os amigos que tenham verificado você anteriormente verão avisos de segurança até que você verifique novamente com eles.",
|
||||
"verify_reset_warning_2": "Prossiga apenas se tiver a certeza de que perdeu todos os seus outros dispositivos e a sua Chave de Recuperação.",
|
||||
"verify_using_device": "Verifique com outro dispositivo",
|
||||
"verify_using_key": "Verifique com a chave de segurança",
|
||||
"verify_using_key_or_phrase": "Verificar com chave de segurança ou frase",
|
||||
@@ -1236,7 +1234,7 @@
|
||||
"existing_issue_link": "Por favor, consulte os <existingIssuesLink> erros conhecidos no Github </existingIssuesLink> antes de enviar o seu. Se ninguém tiver mencionado o seu erro, <newIssueLink> informe-nos sobre um erro novo </newIssueLink>.",
|
||||
"may_contact_label": "Você pode entrar em contato comigo se quiser acompanhar ou me deixar testar as próximas ideias",
|
||||
"platform_username": "Sua plataforma e nome de usuário serão registrados para nos ajudar a usar seu feedback o máximo possível.",
|
||||
"pro_type": "DICA: se você nos informar um erro, envie <debugLogsLink> relatórios de erro </debugLogsLink> para nos ajudar a rastrear o problema.",
|
||||
"pro_type": "DICA: se você nos informar um erro, envie <debugLogsLink> relatórios de erro</debugLogsLink> para nos ajudar a rastrear o problema.",
|
||||
"send_feedback_action": "Enviar comentário",
|
||||
"sent": "Comentário enviado"
|
||||
},
|
||||
@@ -1349,7 +1347,7 @@
|
||||
"error_unfederated_space": "Esse espaço não é federado. Você não pode convidar pessoas de servidores externos.",
|
||||
"error_unknown": "Erro de servidor desconhecido",
|
||||
"error_user_not_found": "O usuário não existe",
|
||||
"error_version_unsupported_room": "O servidor desta(e) usuária(o) não suporta a versão desta sala.",
|
||||
"error_version_unsupported_room": "O servidor doméstico do usuário não é compatível com a versão da sala.",
|
||||
"error_version_unsupported_space": "O servidor doméstico do usuário não é compatível com a versão do espaço.",
|
||||
"failed_generic": "A operação falhou",
|
||||
"failed_title": "Falha ao enviar o convite",
|
||||
@@ -1411,7 +1409,7 @@
|
||||
"composer_toggle_code_block": "Alternar para bloco de código",
|
||||
"composer_toggle_italics": "Itálico",
|
||||
"composer_toggle_link": "Alternar para link",
|
||||
"composer_toggle_quote": "Citar",
|
||||
"composer_toggle_quote": "Alternar para citação",
|
||||
"composer_undo": "Desfazer edição",
|
||||
"control": "Ctrl",
|
||||
"dismiss_read_marker_and_jump_bottom": "Ignorar o marcador de leitura e ir para o final",
|
||||
@@ -1463,8 +1461,8 @@
|
||||
"allow_screen_share_only_mode": "Permitir somente o modo de compartilhamento de tela",
|
||||
"ask_to_join": "Habilitar pedir para participar",
|
||||
"automatic_debug_logs": "Enviar automaticamente logs de depuração em qualquer erro",
|
||||
"automatic_debug_logs_decryption": "Enviar automaticamente registros de depuração sobre erros de descriptografia",
|
||||
"automatic_debug_logs_key_backup": "Envie automaticamente registros de depuração quando o backup da chave não estiver funcionando",
|
||||
"automatic_debug_logs_decryption": "Enviar automaticamente logs sobre erros de descriptografia",
|
||||
"automatic_debug_logs_key_backup": "Envie automaticamente logs quando o backup da chave não estiver funcionando",
|
||||
"beta_description": "O que vem por aí no %(brand)s? Os laboratórios são a melhor maneira de obter informações antecipadas, testar novos recursos e ajudar a moldá-los antes do lançamento.",
|
||||
"beta_feature": "Este é um recurso beta",
|
||||
"beta_feedback_leave_button": "Para sair do beta, vá nas suas configurações.",
|
||||
@@ -1582,7 +1580,7 @@
|
||||
"leave_space_question": "Tem certeza de que deseja sair desse espaço '%(spaceName)s'?",
|
||||
"room_leave_admin_warning": "Você é o único administrador nesta sala. Se você sair, ninguém poderá alterar as configurações da sala ou realizar outras ações importantes.",
|
||||
"room_leave_mod_warning": "Você é o único moderador nesta sala. Se você sair, ninguém poderá alterar as configurações da sala ou realizar outras ações importantes.",
|
||||
"room_rejoin_warning": "Esta sala não é pública. Você não poderá voltar sem ser convidada/o.",
|
||||
"room_rejoin_warning": "Esta sala não é pública. Você não poderá entrar novamente sem um convite.",
|
||||
"space_rejoin_warning": "Este espaço não é público. Você não poderá entrar novamente sem um convite."
|
||||
},
|
||||
"left_panel": {
|
||||
@@ -1767,7 +1765,7 @@
|
||||
"idle_for": "Inativo há %(duration)s",
|
||||
"offline": "Offline",
|
||||
"offline_for": "Offline há %(duration)s",
|
||||
"online": "Conectada/o",
|
||||
"online": "Disponível",
|
||||
"online_for": "Online há %(duration)s",
|
||||
"unknown": "Desconhecido",
|
||||
"unknown_for": "Status desconhecido há %(duration)s",
|
||||
@@ -1792,7 +1790,7 @@
|
||||
"reason_label": "Motivo (opcional)"
|
||||
},
|
||||
"report_content": {
|
||||
"description": "Reportar esta mensagem enviará o seu 'event ID' único para o/a administrador/a do seu Homeserver. Se as mensagens nesta sala são criptografadas, o/a administrador/a não conseguirá ler o texto da mensagem nem ver nenhuma imagem ou arquivo.",
|
||||
"description": "Denunciar essa mensagem enviará seu “ID de evento” exclusivo ao administrador do seu servidor doméstico. Se as mensagens nesta sala forem criptografadas, o administrador do servidor doméstico não poderá ler o texto da mensagem nem visualizar arquivos ou imagens.",
|
||||
"disagree": "Discordo",
|
||||
"error_create_room_moderation_bot": "Não é possível criar espaço com o bot de moderação",
|
||||
"hide_messages_from_user": "Marque se você deseja ocultar todas as mensagens atuais e futuras desse usuário.",
|
||||
@@ -2120,6 +2118,7 @@
|
||||
"failed_add_tag": "Falha ao adicionar a tag %(tagName)s para a sala",
|
||||
"failed_remove_tag": "Falha ao remover a tag %(tagName)s da sala",
|
||||
"failed_set_dm_tag": "Falha ao definir a marca de mensagem direta",
|
||||
"filter": "Filtro",
|
||||
"filters": {
|
||||
"favourite": "Favoritos",
|
||||
"people": "Pessoas",
|
||||
@@ -2153,6 +2152,12 @@
|
||||
"open_room": "Abrir sala %(roomName)s"
|
||||
},
|
||||
"room_options": "Opções da Sala",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Toda a atividade",
|
||||
"invites_only": "Somente para convidados",
|
||||
"low_priority": "Baixa prioridade",
|
||||
"mentions_only": "Apenas menções"
|
||||
},
|
||||
"secondary_filters": "Filtros secundários",
|
||||
"show_less": "Mostrar menos",
|
||||
"show_message_previews": "Mostrar prévias de mensagens",
|
||||
@@ -2326,7 +2331,7 @@
|
||||
"permissions_section": "Permissões",
|
||||
"permissions_section_description_room": "Selecione os cargos necessários para alterar várias partes da sala",
|
||||
"permissions_section_description_space": "Selecionar os cargos necessários para alterar certas partes do espaço",
|
||||
"privileged_users_section": "Usuárias/os privilegiadas/os",
|
||||
"privileged_users_section": "Usuários privilegiados",
|
||||
"redact": "Remover mensagens enviadas por outros",
|
||||
"send_event_type": "Enviar eventos de %(eventType)s",
|
||||
"state_default": "Alterar configurações",
|
||||
@@ -2347,7 +2352,7 @@
|
||||
"error_join_rule_change_title": "Falha ao atualizar as regras de entrada",
|
||||
"error_join_rule_change_unknown": "Falha desconhecida",
|
||||
"guest_access_warning": "Pessoas com clientes suportados poderão entrar na sala sem ter uma conta registrada.",
|
||||
"history_visibility_invited": "Apenas participantes (desde que foram convidadas/os)",
|
||||
"history_visibility_invited": "Somente membros (desde que tenham sido convidados)",
|
||||
"history_visibility_joined": "Apenas participantes (desde que entraram na sala)",
|
||||
"history_visibility_legend": "Quem pode ler o histórico da sala?",
|
||||
"history_visibility_shared": "Apenas participantes (a partir do momento em que esta opção for selecionada)",
|
||||
@@ -2451,6 +2456,10 @@
|
||||
"recent_changes_heading": "Alterações recentes que ainda não foram recebidas",
|
||||
"title": "O servidor não está respondendo"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s requer um operador de serviço para carregar mídia autenticada de repositórios de conteúdo Matrix. Isso não é suportado pelo seu navegador, portanto, pode ocorrer uma falha no carregamento de mídia.",
|
||||
"title": "Falha ao carregar o operador de serviço"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Falha na inicialização da pesquisa por mensagem, confire <a>suas configurações</a> para mais informações",
|
||||
"reset_button": "Redefinir armazenamento de eventos",
|
||||
@@ -2505,7 +2514,7 @@
|
||||
"image_size_large": "Grande",
|
||||
"layout_bubbles": "Balões de mensagem",
|
||||
"layout_irc": "IRC (experimental)",
|
||||
"match_system_theme": "Se adaptar ao tema do sistema",
|
||||
"match_system_theme": "Se adaptar ao padrão do sistema",
|
||||
"timeline_image_size": "Tamanho da imagem na linha do tempo"
|
||||
},
|
||||
"automatic_language_detection_syntax_highlight": "Ativar detecção automática de idioma para ressaltar erros de ortografia",
|
||||
@@ -2520,7 +2529,7 @@
|
||||
},
|
||||
"emoji_autocomplete": "Ativar sugestões de emojis ao digitar",
|
||||
"enable_markdown": "Habilitar markdown",
|
||||
"enable_markdown_description": "Inicie mensagens com <code> /plain </code> para enviar sem marcação.",
|
||||
"enable_markdown_description": "Inicie as mensagens com <code>/plain</code> para enviar sem markdown.",
|
||||
"encryption": {
|
||||
"advanced": {
|
||||
"breadcrumb_first_description": "Os detalhes da sua conta, contatos, preferências e lista de bate-papo serão mantidos",
|
||||
@@ -2629,6 +2638,7 @@
|
||||
"discovery_needs_terms_title": "Deixe que as pessoas encontrem você",
|
||||
"display_name": "Nome de exibição",
|
||||
"display_name_error": "Não foi possível definir o nome de exibição",
|
||||
"email_adding_unsupported_by_hs": "Este servidor doméstico não suporta a adição de endereços de e-mail à sua conta.",
|
||||
"email_address_in_use": "Este endereço de email já está em uso",
|
||||
"email_address_label": "Endereço de e-mail",
|
||||
"email_not_verified": "Seu endereço de e-mail ainda não foi confirmado",
|
||||
@@ -2653,7 +2663,9 @@
|
||||
"error_share_msisdn_discovery": "Não foi possível compartilhar o número de celular",
|
||||
"identity_server_no_token": "Nenhum token de acesso à identidade foi encontrado",
|
||||
"identity_server_not_set": "Servidor de identidade não definido",
|
||||
"invalid_phone_number": "O número de telefone fornecido não parece ser válido.",
|
||||
"language_section": "Idioma",
|
||||
"msisdn_adding_unsupported_by_hs": "Este servidor doméstico não suporta a adição de números de telefone à sua conta.",
|
||||
"msisdn_in_use": "Este número de telefone já está em uso",
|
||||
"msisdn_label": "Número de telefone",
|
||||
"msisdn_verification_field_label": "Código de confirmação",
|
||||
@@ -2789,7 +2801,7 @@
|
||||
"rule_contains_user_name": "Mensagens contendo meu nome de usuário",
|
||||
"rule_encrypted": "Mensagens criptografadas em salas",
|
||||
"rule_encrypted_room_one_to_one": "Mensagens criptografadas em conversas individuais",
|
||||
"rule_invite_for_me": "Quando eu for convidada(o) a uma sala",
|
||||
"rule_invite_for_me": "Quando sou convidado para uma sala",
|
||||
"rule_message": "Mensagens em salas",
|
||||
"rule_room_one_to_one": "Mensagens em conversas individuais",
|
||||
"rule_roomnotif": "Mensagens contendo @room",
|
||||
@@ -3064,7 +3076,7 @@
|
||||
"help": "Exibe a lista de comandos com usos e descrições",
|
||||
"help_dialog_title": "Ajuda com Comandos",
|
||||
"holdcall": "Pausa a chamada na sala atual",
|
||||
"html": "Envia uma mensagem como HTML, sem formatação",
|
||||
"html": "Envia uma mensagem como html, sem interpretá-la como markdown",
|
||||
"ignore": "Bloqueia um usuário, escondendo as mensagens dele de você",
|
||||
"ignore_dialog_description": "Agora você está bloqueando %(userId)s",
|
||||
"ignore_dialog_title": "Usuário bloqueado",
|
||||
@@ -3086,10 +3098,10 @@
|
||||
"no_active_call": "Nenhuma chamada ativa nesta sala",
|
||||
"op": "Define o nível de permissões de um usuário",
|
||||
"part_unknown_alias": "Endereço da sala não reconhecido: %(roomAlias)s",
|
||||
"plain": "Envia uma mensagem de texto sem formatação",
|
||||
"plain": "Envia uma mensagem como texto simples, sem interpretá-la como markdown",
|
||||
"query": "Abre um chat com determinada pessoa",
|
||||
"query_not_found_phone_number": "Não foi possível encontrar o ID Matrix pelo número de telefone",
|
||||
"rageshake": "Envia um relatório de erro",
|
||||
"rageshake": "Enviar um relatório de bug com logs",
|
||||
"rainbow": "Envia a mensagem colorida como arco-íris",
|
||||
"rainbowme": "Envia o emoji colorido como um arco-íris",
|
||||
"remove": "Remove desta sala o usuário com o ID determinado",
|
||||
@@ -3225,7 +3237,7 @@
|
||||
"heading_without_query": "Pesquisar por",
|
||||
"join_button_text": "Junte-se a %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Use <arrows/> para rolar",
|
||||
"message_search_section_title": "Outras pesquisas",
|
||||
"messages_label": "Mensagens",
|
||||
"other_rooms_in_space": "Outras salas em %(spaceName)s",
|
||||
"public_rooms_label": "Salas públicas",
|
||||
"public_spaces_label": "Espaços públicos",
|
||||
@@ -3235,7 +3247,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Alguns resultados podem estar ocultos por questões de privacidade",
|
||||
"result_may_be_hidden_warning": "Alguns resultados podem estar ocultos",
|
||||
"search_dialog": "Diálogo de pesquisa",
|
||||
"search_messages_hint": "Para pesquisar mensagens, procure esse ícone na parte superior de uma sala <icon/>",
|
||||
"spaces_title": "Espaços em que você está",
|
||||
"start_group_chat_button": "Inicie um bate-papo em grupo"
|
||||
},
|
||||
@@ -3254,7 +3265,7 @@
|
||||
"integration_manager": "Use bots, integrações, widgets e pacotes de figurinhas",
|
||||
"intro": "Para continuar, você precisa aceitar os termos deste serviço.",
|
||||
"summary_identity_server_1": "Encontre outras pessoas por telefone ou e-mail",
|
||||
"summary_identity_server_2": "Seja encontrada/o por número de celular ou por e-mail",
|
||||
"summary_identity_server_2": "Seja encontrado por telefone ou e-mail",
|
||||
"tac_button": "Revise os termos e condições",
|
||||
"tac_description": "Para continuar usando o servidor local %(homeserverDomain)s, você deve ler e concordar com nossos termos e condições.",
|
||||
"tac_title": "Termos e Condições",
|
||||
@@ -3284,9 +3295,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Atividade de tópicos",
|
||||
"no_rooms_with_threads_notifs": "Você ainda não tem salas com notificações de tópicos.",
|
||||
"no_rooms_with_unread_threads": "Você ainda não tem salas com tópicos não lidos.",
|
||||
"release_announcement_description": "As notificações de tópicos foram movidas, encontre-as aqui a partir de agora.",
|
||||
"release_announcement_header": "Centro de Atividades de Tópicos"
|
||||
"no_rooms_with_unread_threads": "Você ainda não tem salas com tópicos não lidos."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "há aproximadamente um dia",
|
||||
@@ -3321,7 +3330,7 @@
|
||||
"collapse_reply_thread": "Recolher tópico de resposta",
|
||||
"external_url": "Link do código-fonte",
|
||||
"open_in_osm": "Abrir no OpenStreetMap",
|
||||
"report": "Relatório",
|
||||
"report": "Denunciar",
|
||||
"resent_unsent_reactions": "Reenviar %(unsentCount)s reações",
|
||||
"show_url_preview": "Mostrar pré-visualização",
|
||||
"view_related_event": "Exibir evento relacionado",
|
||||
@@ -3658,12 +3667,12 @@
|
||||
"one": "%(severalUsers)s tiveram os convites retirados"
|
||||
},
|
||||
"invited": {
|
||||
"other": "foi convidada/o %(count)s vezes",
|
||||
"one": "foi convidada/o"
|
||||
"one": "foi convidado",
|
||||
"other": "foi convidado %(count)s vezes"
|
||||
},
|
||||
"invited_multiple": {
|
||||
"other": "foram convidadas/os %(count)s vezes",
|
||||
"one": "foram convidadas/os"
|
||||
"one": "foram convidados",
|
||||
"other": "foram convidados %(count)s vezes"
|
||||
},
|
||||
"joined": {
|
||||
"other": "%(oneUser)s entrou %(count)s vezes",
|
||||
@@ -3797,10 +3806,11 @@
|
||||
"unavailable": "Indisponível"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Para criar um link de compartilhamento, você precisa permitir que os convidados entrem nesta sala. Isso pode tornar a sala menos segura. Quando terminar a ligação, você poderá tornar a sala privada novamente.",
|
||||
"dont_change_description": "Como alternativa, você pode realizar a chamada em uma sala separada.",
|
||||
"description": "Para criar um link de compartilhamento, torne esta sala <b>pública</b> ou habilite a opção para que os usuários <b>peçam para entrar</b>. Isso permite que os convidados entrem sem serem convidados.",
|
||||
"dont_change_description": "Se não quiser alterar o acesso a essa sala, você pode criar uma nova sala para o link de chamada.",
|
||||
"no_change": "Eu não quero mudar o nível de acesso.",
|
||||
"title": "Alterar o nível de acesso da sala"
|
||||
"revert_access_description": "(Isso pode ser revertido para o valor anterior nas configurações da sala: <b>Segurança e privacidade</b> / <b>Acesso</b>)",
|
||||
"title": "Permitir que usuários convidados entrem nesta sala"
|
||||
},
|
||||
"upload_failed_generic": "O envio do arquivo '%(fileName)s' falhou.",
|
||||
"upload_failed_size": "O arquivo '%(fileName)s' excede o limite de tamanho deste homeserver para uploads",
|
||||
@@ -3840,7 +3850,7 @@
|
||||
"error_ban_user": "Não foi possível banir o usuário",
|
||||
"error_deactivate": "Falha ao desativar o usuário",
|
||||
"error_kicking_user": "Falha ao remover usuário",
|
||||
"error_mute_user": "Não foi possível remover notificações da/do usuária/o",
|
||||
"error_mute_user": "Falha ao silenciar o usuário",
|
||||
"error_revoke_3pid_invite_description": "Não foi possível revogar o convite. O servidor pode estar com um problema temporário ou você não tem permissões suficientes para revogar o convite.",
|
||||
"error_revoke_3pid_invite_title": "Falha ao revogar o convite",
|
||||
"ignore_button": "Ignorar",
|
||||
|
||||
@@ -952,7 +952,6 @@
|
||||
"accepting": "Принятие…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Сеанс заверен",
|
||||
"reset_confirmation": "Действительно сбросить ключи подтверждения?",
|
||||
"skip_verification": "Пока пропустить проверку",
|
||||
"unable_to_verify": "Невозможно заверить этот сеанс",
|
||||
"verify_this_device": "Заверьте этот сеанс"
|
||||
@@ -1023,8 +1022,6 @@
|
||||
"verify_emoji_prompt": "Подтверждение сравнением уникальных смайлов.",
|
||||
"verify_emoji_prompt_qr": "Если вы не можете отсканировать код выше, попробуйте сравнить уникальные смайлы.",
|
||||
"verify_later": "Я заверю позже",
|
||||
"verify_reset_warning_1": "Сброс ключей проверки нельзя отменить. После сброса вы не сможете получить доступ к старым зашифрованным сообщениям, а друзья, которые ранее проверили вас, будут видеть предупреждения о безопасности, пока вы не пройдете повторную проверку.",
|
||||
"verify_reset_warning_2": "Продолжайте, только если вы уверены, что потеряли все остальные устройства и ключ безопасности.",
|
||||
"verify_using_device": "Сверить с другим сеансом",
|
||||
"verify_using_key": "Заверить бумажным ключом",
|
||||
"verify_using_key_or_phrase": "Проверка с помощью ключа безопасности или фразы",
|
||||
@@ -3062,7 +3059,6 @@
|
||||
"heading_without_query": "Поиск",
|
||||
"join_button_text": "Присоединиться к %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Используйте <arrows/> для прокрутки",
|
||||
"message_search_section_title": "Другие поиски",
|
||||
"other_rooms_in_space": "Прочие комнаты в %(spaceName)s",
|
||||
"public_rooms_label": "Публичные комнаты",
|
||||
"public_spaces_label": "Публичное пространство",
|
||||
@@ -3072,7 +3068,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Некоторые результаты могут быть скрыты из-за конфиденциальности",
|
||||
"result_may_be_hidden_warning": "Некоторые результаты могут быть скрыты",
|
||||
"search_dialog": "Окно поиска",
|
||||
"search_messages_hint": "Для поиска сообщений найдите этот значок <icon/> в верхней части комнаты",
|
||||
"spaces_title": "Ваши пространства",
|
||||
"start_group_chat_button": "Начать групповой чат"
|
||||
},
|
||||
|
||||
@@ -390,6 +390,7 @@
|
||||
"fallback_button": "Spustiť overenie",
|
||||
"mas_cross_signing_reset_cta": "Prejdite do svojho účtu",
|
||||
"mas_cross_signing_reset_description": "Obnovte svoju totožnosť prostredníctvom poskytovateľa účtu a potom sa vráťte späť a kliknite na tlačidlo „Skúsiť znova“.",
|
||||
"mas_cross_signing_reset_title": "Prejdite do svojho účtu a obnovte svoju totožnosť",
|
||||
"msisdn": "Na číslo %(msisdn)s bola odoslaná textová správa",
|
||||
"msisdn_token_incorrect": "Neplatný token",
|
||||
"msisdn_token_prompt": "Prosím, zadajte kód z tejto správy:",
|
||||
@@ -1002,7 +1003,6 @@
|
||||
"accepting": "Akceptovanie…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Zariadenie overené",
|
||||
"reset_confirmation": "Skutočne vynulovať overovacie kľúče?",
|
||||
"skip_verification": "Vynechať zatiaľ overovanie",
|
||||
"unable_to_verify": "Nie je možné overiť toto zariadenie",
|
||||
"verify_this_device": "Overiť toto zariadenie"
|
||||
@@ -1073,8 +1073,6 @@
|
||||
"verify_emoji_prompt": "Overenie porovnaním jedinečnej kombinácie emotikonov.",
|
||||
"verify_emoji_prompt_qr": "Ak sa vám nepodarí naskenovať uvedený kód, overte pomocou porovnania jedinečných emotikonov.",
|
||||
"verify_later": "Overím to neskôr",
|
||||
"verify_reset_warning_1": "Vynulovanie overovacích kľúčov sa nedá vrátiť späť. Po vynulovaní nebudete mať prístup k starým zašifrovaným správam a všetci priatelia, ktorí vás predtým overili, uvidia bezpečnostné upozornenia, kým sa u nich znovu neoveríte.",
|
||||
"verify_reset_warning_2": "Pokračujte prosím iba vtedy, ak ste si istí, že ste stratili všetky ostatné zariadenia aj váš kľúč na obnovenie.",
|
||||
"verify_using_device": "Overiť pomocou iného zariadenia",
|
||||
"verify_using_key": "Overiť pomocou kľúča na obnovenie",
|
||||
"verify_using_key_or_phrase": "Overiť pomocou kľúča na obnovenie alebo frázy",
|
||||
@@ -2151,6 +2149,7 @@
|
||||
"failed_add_tag": "Miestnosti sa nepodarilo pridať značku %(tagName)s",
|
||||
"failed_remove_tag": "Z miestnosti sa nepodarilo odstrániť značku %(tagName)s",
|
||||
"failed_set_dm_tag": "Nepodarilo sa nastaviť značku priamej správy",
|
||||
"filter": "Filter",
|
||||
"filters": {
|
||||
"favourite": "Obľúbené",
|
||||
"people": "Ľudia",
|
||||
@@ -2186,6 +2185,12 @@
|
||||
"open_room": "Otvoriť miestnosť %(roomName)s"
|
||||
},
|
||||
"room_options": "Možnosti miestnosti",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Všetka aktivita",
|
||||
"invites_only": "Len pozvánky",
|
||||
"low_priority": "Nízka priorita",
|
||||
"mentions_only": "Iba zmienky"
|
||||
},
|
||||
"secondary_filters": "Sekundárne filtre",
|
||||
"show_less": "Zobraziť menej",
|
||||
"show_message_previews": "Zobraziť náhľady správ",
|
||||
@@ -2488,6 +2493,10 @@
|
||||
"recent_changes_heading": "Nedávne zmeny, ktoré ešte neboli prijaté",
|
||||
"title": "Server neodpovedá"
|
||||
},
|
||||
"service_worker_error": {
|
||||
"description": "%(brand)s vyžaduje proces služby na načítanie overených médií z úložísk obsahu Matrix. Váš prehliadač to nepodporuje, takže sa môže vyskytnúť zlyhanie načítania médií.",
|
||||
"title": "Nepodarilo sa načítať proces služby"
|
||||
},
|
||||
"seshat": {
|
||||
"error_initialising": "Inicializácia vyhľadávania správ zlyhala, pre viac informácií skontrolujte <a>svoje nastavenia</a>",
|
||||
"reset_button": "Obnoviť úložisko udalostí",
|
||||
@@ -2666,6 +2675,7 @@
|
||||
"discovery_needs_terms_title": "Umožnite ľuďom, aby vás našli",
|
||||
"display_name": "Zobrazované meno",
|
||||
"display_name_error": "Nedá sa nastaviť zobrazované meno",
|
||||
"email_adding_unsupported_by_hs": "Tento domovský server nepodporuje pridávanie e-mailových adries do vášho účtu.",
|
||||
"email_address_in_use": "Táto emailová adresa sa už používa",
|
||||
"email_address_label": "Emailová adresa",
|
||||
"email_not_verified": "Vaša emailová adresa nebola zatiaľ overená",
|
||||
@@ -2690,7 +2700,9 @@
|
||||
"error_share_msisdn_discovery": "Nepodarilo sa zdieľanie telefónneho čísla",
|
||||
"identity_server_no_token": "Nenašiel sa prístupový token totožnosti",
|
||||
"identity_server_not_set": "Server totožnosti nie je nastavený",
|
||||
"invalid_phone_number": "Poskytnuté telefónne číslo sa nezdá byť platné.",
|
||||
"language_section": "Jazyk",
|
||||
"msisdn_adding_unsupported_by_hs": "Tento domovský server nepodporuje pridávanie telefónnych čísel do vášho účtu.",
|
||||
"msisdn_in_use": "Toto telefónne číslo sa už používa",
|
||||
"msisdn_label": "Telefónne číslo",
|
||||
"msisdn_verification_field_label": "Overovací kód",
|
||||
@@ -3267,7 +3279,7 @@
|
||||
"heading_without_query": "Hľadať",
|
||||
"join_button_text": "Pripojiť sa k %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Na posúvanie použite <arrows/>",
|
||||
"message_search_section_title": "Iné vyhľadávania",
|
||||
"messages_label": "Správy",
|
||||
"other_rooms_in_space": "Ostatné miestnosti v %(spaceName)s",
|
||||
"public_rooms_label": "Verejné miestnosti",
|
||||
"public_spaces_label": "Verejné priestory",
|
||||
@@ -3277,7 +3289,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Niektoré výsledky môžu byť skryté kvôli ochrane súkromia",
|
||||
"result_may_be_hidden_warning": "Niektoré výsledky môžu byť skryté",
|
||||
"search_dialog": "Vyhľadávacie dialógové okno",
|
||||
"search_messages_hint": "Ak chcete vyhľadávať správy, nájdite túto ikonu v hornej časti miestnosti <icon/>",
|
||||
"spaces_title": "Priestory, v ktorých sa nachádzate",
|
||||
"start_group_chat_button": "Začať skupinovú konverzáciu"
|
||||
},
|
||||
@@ -3327,9 +3338,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Aktivita vlákien",
|
||||
"no_rooms_with_threads_notifs": "Zatiaľ nemáte miestnosti s upozorneniami na vlákna.",
|
||||
"no_rooms_with_unread_threads": "Zatiaľ nemáte miestnosti s neprečítanými vláknami.",
|
||||
"release_announcement_description": "Upozornenia na vlákna sa presunuli, odteraz ich nájdete tu.",
|
||||
"release_announcement_header": "Centrum aktivity vlákien"
|
||||
"no_rooms_with_unread_threads": "Zatiaľ nemáte miestnosti s neprečítanými vláknami."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "asi pred jedným dňom",
|
||||
@@ -3874,10 +3883,11 @@
|
||||
"unavailable": "Nedostupné"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Ak chcete vytvoriť odkaz na zdieľanie, musíte povoliť hosťom pripojiť sa k tejto miestnosti. To môže spôsobiť, že miestnosť bude menej bezpečná. Keď ukončíte hovor, môžete miestnosť opäť nastaviť na súkromnú.",
|
||||
"dont_change_description": "Prípadne môžete hovor uskutočniť v samostatnej miestnosti.",
|
||||
"description": "Ak chcete vytvoriť odkaz na zdieľanie, nastavte túto miestnosť ako <b> verejnú</b> alebo povolte používateľom možnosť <b>požiadať o pripojenie</b>. To umožní hosťom pripojiť sa bez pozvánky.",
|
||||
"dont_change_description": "Ak nechcete zmeniť prístup do tejto miestnosti, môžete vytvoriť novú miestnosť pre odkaz na hovor.",
|
||||
"no_change": "Nechcem zmeniť úroveň prístupu.",
|
||||
"title": "Zmeniť úroveň prístupu do miestnosti"
|
||||
"revert_access_description": "(Túto hodnotu je možné vrátiť na predchádzajúcu hodnotu v nastaveniach miestnosti: <b>Zabezpečenie a súkromie</b> / <b>Prístup</b>)",
|
||||
"title": "Povoliť hosťom pripojiť sa k tejto miestnosti"
|
||||
},
|
||||
"upload_failed_generic": "Nepodarilo sa nahrať súbor „%(fileName)s“.",
|
||||
"upload_failed_size": "Veľkosť súboru „%(fileName)s“ prekračuje limit veľkosti súboru nahrávania na tento domovský server",
|
||||
|
||||
@@ -827,7 +827,6 @@
|
||||
"accepting": "Po pranohet…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Pajisja u verifikua",
|
||||
"reset_confirmation": "Të kthehen vërtet te parazgjedhjet kyçet e verifikimit?",
|
||||
"skip_verification": "Anashkaloje verifikimin hëpërhë",
|
||||
"unable_to_verify": "S’arrihet të verifikohet kjo pajisje",
|
||||
"verify_this_device": "Verifikoni këtë pajisje"
|
||||
@@ -897,8 +896,6 @@
|
||||
"verify_emoji_prompt": "Verifikoje duke krahasuar emoji unik.",
|
||||
"verify_emoji_prompt_qr": "Nëse s’e skanoni dot kodin më sipër, verifikojeni duke krahasuar emoji unik.",
|
||||
"verify_later": "Do ta verifikoj më vonë",
|
||||
"verify_reset_warning_1": "Rikthimi te parazgjedhjet i kyçeve tuaj të verifikimit s’mund të zhbëhet. Pas rikthimit te parazgjedhjet, s’do të mund të hyni dot te mesazhe të dikurshëm të fshehtëzuar dhe, cilido shok që ju ka verifikuar më parë, do të shohë një sinjalizim sigurie deri sa të ribëni verifikimin me ta.",
|
||||
"verify_reset_warning_2": "Ju lutemi, ecni më tej vetëm nëse jeni i sigurt se keni humbur krejt pajisjet tuaja të tjera dhe Kyçin tuaj të Sigurisë.",
|
||||
"verify_using_device": "Verifikojeni me pajisje tjetër",
|
||||
"verify_using_key": "Verifikoje me Kyç Sigurie",
|
||||
"verify_using_key_or_phrase": "Verifikojeni me Kyç ose Frazë Sigurie",
|
||||
@@ -2650,7 +2647,6 @@
|
||||
"heading_without_query": "Kërkoni për",
|
||||
"join_button_text": "Hyni te %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Përdorni <arrows/> për rrëshqitje",
|
||||
"message_search_section_title": "Kërkime të tjera",
|
||||
"other_rooms_in_space": "Dhoma të tjera në %(spaceName)s",
|
||||
"public_rooms_label": "Dhoma publike",
|
||||
"recent_searches_section_title": "Kërkime së fundi",
|
||||
@@ -2659,7 +2655,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Disa përfundime mund të jenë fshehur, për arsye privatësie",
|
||||
"result_may_be_hidden_warning": "Disa përfundime mund të jenë të fshehura",
|
||||
"search_dialog": "Dialog Kërkimi",
|
||||
"search_messages_hint": "Që të kërkoni te mesazhet, shihni për këtë ikonë në krye të një dhome <icon/>",
|
||||
"spaces_title": "Hapësira ku jeni i pranishëm",
|
||||
"start_group_chat_button": "Nisni një fjalosje grupi"
|
||||
},
|
||||
|
||||
@@ -993,7 +993,6 @@
|
||||
"accepting": "Accepterar…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Enhet verifierad",
|
||||
"reset_confirmation": "Återställ verkligen verifieringsnycklar?",
|
||||
"skip_verification": "Hoppa över verifiering för tillfället",
|
||||
"unable_to_verify": "Kunde inte verifiera den här enheten",
|
||||
"verify_this_device": "Verifiera den här enheten"
|
||||
@@ -1064,8 +1063,6 @@
|
||||
"verify_emoji_prompt": "Verifiera genom att jämföra unika emojier.",
|
||||
"verify_emoji_prompt_qr": "Om du inte kan skanna koden ovan, verifiera genom att jämföra unika emojier.",
|
||||
"verify_later": "Jag verifierar senare",
|
||||
"verify_reset_warning_1": "Återställning av dina verifieringsnycklar kan inte ångras. Efter återställning så kommer du inte att komma åt dina krypterade meddelanden, och alla vänner som tidigare har verifierat dig kommer att se säkerhetsvarningar tills du återverifierar med dem.",
|
||||
"verify_reset_warning_2": "Fortsätt bara om du är säker på att du har förlorat alla dina övriga enheter och din säkerhetsnyckel.",
|
||||
"verify_using_device": "Verifiera med annan enhet",
|
||||
"verify_using_key": "Verifiera med säkerhetsnyckel",
|
||||
"verify_using_key_or_phrase": "Verifiera med säkerhetsnyckel eller -fras",
|
||||
@@ -3225,7 +3222,6 @@
|
||||
"heading_without_query": "Sök efter",
|
||||
"join_button_text": "Gå med i %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Använd <arrows/> för att skrolla",
|
||||
"message_search_section_title": "Andra sökningar",
|
||||
"other_rooms_in_space": "Andra rum i %(spaceName)s",
|
||||
"public_rooms_label": "Offentliga rum",
|
||||
"public_spaces_label": "Offentliga utrymmen",
|
||||
@@ -3235,7 +3231,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Vissa resultat kan vara dolda av sekretesskäl",
|
||||
"result_may_be_hidden_warning": "Vissa resultat kanske är dolda",
|
||||
"search_dialog": "Sökdialog",
|
||||
"search_messages_hint": "För att söka efter meddelanden, leta efter den här ikonen på toppen av ett rum <icon/>",
|
||||
"spaces_title": "Utrymmen du är med i",
|
||||
"start_group_chat_button": "Starta en gruppchatt"
|
||||
},
|
||||
@@ -3284,9 +3279,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Aktivitet för trådar",
|
||||
"no_rooms_with_threads_notifs": "Du har inga rum med trådaviseringar ännu.",
|
||||
"no_rooms_with_unread_threads": "Du har inga rum med olästa trådar än.",
|
||||
"release_announcement_description": "Meddelanden om trådar har flyttats, du hittar dem här från och med nu.",
|
||||
"release_announcement_header": "Aktivitetscenter för Trådar"
|
||||
"no_rooms_with_unread_threads": "Du har inga rum med olästa trådar än."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "cirka en dag sedan",
|
||||
|
||||
@@ -967,7 +967,6 @@
|
||||
"accepting": "Kabul ediyorum…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Cihaz doğrulandı",
|
||||
"reset_confirmation": "Doğrulama anahtarlarını sıfırlamak istediğinizden emin misiniz?",
|
||||
"skip_verification": "Şimdilik doğrulamayı atla",
|
||||
"unable_to_verify": "Bu cihaz doğrulanamıyor",
|
||||
"verify_this_device": "Bu cihazı doğrulayın"
|
||||
@@ -1038,8 +1037,6 @@
|
||||
"verify_emoji_prompt": "Eşsiz emoji eşleştirme ile doğrulama.",
|
||||
"verify_emoji_prompt_qr": "Yukarıdaki kodu tarayamıyorsanız benzersiz emojiyi karşılaştırarak doğrulayın.",
|
||||
"verify_later": "Daha sonra doğrulayacağım",
|
||||
"verify_reset_warning_1": "Doğrulama anahtarlarınızı sıfırlama işlemi geri alınamaz. Sıfırladıktan sonra eski şifrelenmiş mesajlara erişiminiz olmaz ve sizi daha önce doğrulamış olan arkadaşlarınız, siz onlarla yeniden doğrulayana kadar güvenlik uyarıları görür.",
|
||||
"verify_reset_warning_2": "Lütfen yalnızca diğer tüm cihazlarınızı ve Güvenlik Anahtarınızı kaybettiğinizden eminseniz devam edin.",
|
||||
"verify_using_device": "Başka bir cihazla doğrula",
|
||||
"verify_using_key": "Güvenlik Anahtarı ile Doğrula",
|
||||
"verify_using_key_or_phrase": "Güvenlik Anahtarı veya İfadesiyle Doğrula",
|
||||
@@ -3151,7 +3148,6 @@
|
||||
"heading_without_query": "Ara",
|
||||
"join_button_text": "Katıl %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Kaydırmak için <arrows/> kullanın",
|
||||
"message_search_section_title": "Diğer aramalar",
|
||||
"other_rooms_in_space": "%(spaceName)s alanındaki diğer odalar",
|
||||
"public_rooms_label": "Herkese açık odalar",
|
||||
"public_spaces_label": "Herkese açık alanlar",
|
||||
@@ -3161,7 +3157,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Bazı sonuçlar gizlilik için gizlenmiş olabilir",
|
||||
"result_may_be_hidden_warning": "Bazı sonuçlar gizlenmiş olabilir",
|
||||
"search_dialog": "Arama İletişim Kutusu",
|
||||
"search_messages_hint": "Mesajları aramak için odanın üst kısmında bu simgeye tıklayın <icon/>",
|
||||
"spaces_title": "Bulunduğunuz alanlar",
|
||||
"start_group_chat_button": "Grup sohbeti başlat"
|
||||
},
|
||||
@@ -3210,9 +3205,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Mesaj dizileri etkinliği",
|
||||
"no_rooms_with_threads_notifs": "Henüz mesaj dizisi bildirimleri olan odalarınız yok.",
|
||||
"no_rooms_with_unread_threads": "Henüz okunmamış mesaj dizilerinin bulunduğu odalarınız yok.",
|
||||
"release_announcement_description": "Mesaj dizisi bildirimleri taşındı, bundan sonra burada bulabilirsiniz.",
|
||||
"release_announcement_header": "Mesaj Dizileri Etkinlik Merkezi"
|
||||
"no_rooms_with_unread_threads": "Henüz okunmamış mesaj dizilerinin bulunduğu odalarınız yok."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "yaklaşık bir gün önce",
|
||||
|
||||
@@ -388,6 +388,7 @@
|
||||
"fallback_button": "Почати автентифікацію",
|
||||
"mas_cross_signing_reset_cta": "Перейти до свого облікового запису",
|
||||
"mas_cross_signing_reset_description": "Скиньте свою особистість через постачальника облікового запису, а потім поверніться та натисніть «Повторити».",
|
||||
"mas_cross_signing_reset_title": "Перейдіть до свого облікового запису, щоб скинути свою ідентичність",
|
||||
"msisdn": "Текстове повідомлення надіслано на %(msisdn)s",
|
||||
"msisdn_token_incorrect": "Хибний токен",
|
||||
"msisdn_token_prompt": "Введіть отриманий код:",
|
||||
@@ -996,7 +997,6 @@
|
||||
"accepting": "Прийняття…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Пристрій звірено",
|
||||
"reset_confirmation": "Точно скинути ключі звірки?",
|
||||
"skip_verification": "На разі пропустити звірку",
|
||||
"unable_to_verify": "Не вдалося звірити цей пристрій",
|
||||
"verify_this_device": "Звірити цей пристрій"
|
||||
@@ -1067,8 +1067,6 @@
|
||||
"verify_emoji_prompt": "Звірити порівнянням унікальних емодзі.",
|
||||
"verify_emoji_prompt_qr": "Якщо ви не можете сканувати зазначений код, звірте порівнянням унікальних емодзі.",
|
||||
"verify_later": "Звірю пізніше",
|
||||
"verify_reset_warning_1": "Скидання ключів звірки неможливо скасувати. Після скидання, ви втратите доступ до старих зашифрованих повідомлень, а всі друзі, які раніше вас звіряли, бачитимуть застереження безпеки, поки ви не проведете звірку з ними знову.",
|
||||
"verify_reset_warning_2": "Будь ласка, продовжуйте лише в разі втрати всіх своїх інших пристроїв та ключа відновлення.",
|
||||
"verify_using_device": "Звірити за допомогою іншого пристрою",
|
||||
"verify_using_key": "Верифікувати за допомогою ключа відновлення",
|
||||
"verify_using_key_or_phrase": "Верифікувати за допомогою фрази або ключа відновлення",
|
||||
@@ -2127,6 +2125,7 @@
|
||||
"failed_add_tag": "Не вдалось додати до кімнати мітку %(tagName)s",
|
||||
"failed_remove_tag": "Не вдалося прибрати з кімнати мітку %(tagName)s",
|
||||
"failed_set_dm_tag": "Не вдалося встановити мітку особистого повідомлення",
|
||||
"filter": "Фільтр",
|
||||
"filters": {
|
||||
"favourite": "Обрані",
|
||||
"people": "Люди",
|
||||
@@ -2160,6 +2159,12 @@
|
||||
"open_room": "Відкрити кімнату %(roomName)s"
|
||||
},
|
||||
"room_options": "Параметри кімнати",
|
||||
"secondary_filter": {
|
||||
"all_activity": "Уся діяльність",
|
||||
"invites_only": "Лише запрошення",
|
||||
"low_priority": "Неважливі",
|
||||
"mentions_only": "Лише згадки"
|
||||
},
|
||||
"secondary_filters": "Додаткові фільтри",
|
||||
"show_less": "Згорнути",
|
||||
"show_message_previews": "Показати попередній перегляд повідомлень",
|
||||
@@ -2636,6 +2641,7 @@
|
||||
"discovery_needs_terms_title": "Дайте змогу людям знаходити вас",
|
||||
"display_name": "Показуване ім'я",
|
||||
"display_name_error": "Не вдалося встановити показуване ім'я",
|
||||
"email_adding_unsupported_by_hs": "Цей домашній сервер не підтримує додавання адрес електронної пошти до вашого облікового запису.",
|
||||
"email_address_in_use": "Ця е-пошта вже використовується",
|
||||
"email_address_label": "Адреса е-пошти",
|
||||
"email_not_verified": "Ваша адреса е-пошти ще не підтверджена",
|
||||
@@ -2660,7 +2666,9 @@
|
||||
"error_share_msisdn_discovery": "Не вдалося надіслати телефонний номер",
|
||||
"identity_server_no_token": "Токен доступу до ідентифікації не знайдено",
|
||||
"identity_server_not_set": "Сервер ідентифікації не налаштовано",
|
||||
"invalid_phone_number": "Вказано недійсний номер телефону.",
|
||||
"language_section": "Мова",
|
||||
"msisdn_adding_unsupported_by_hs": "Цей домашній сервер не підтримує додавання телефонних номерів до вашого облікового запису.",
|
||||
"msisdn_in_use": "Цей телефонний номер вже використовується",
|
||||
"msisdn_label": "Телефонний номер",
|
||||
"msisdn_verification_field_label": "Код перевірки",
|
||||
@@ -3232,7 +3240,7 @@
|
||||
"heading_without_query": "Пошук",
|
||||
"join_button_text": "Приєднатися до %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Використовуйте <arrows/>, щоб прокручувати",
|
||||
"message_search_section_title": "Інші пошуки",
|
||||
"messages_label": "Повідомлення",
|
||||
"other_rooms_in_space": "Інші кімнати в %(spaceName)s",
|
||||
"public_rooms_label": "Загальнодоступні кімнати",
|
||||
"public_spaces_label": "Загальнодоступні простори",
|
||||
@@ -3242,7 +3250,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "Деякі результати можуть бути приховані через приватність",
|
||||
"result_may_be_hidden_warning": "Деякі результати можуть бути приховані",
|
||||
"search_dialog": "Вікно пошуку",
|
||||
"search_messages_hint": "Шукайте повідомлення за допомогою піктограми <icon/> вгорі кімнати",
|
||||
"spaces_title": "Ваші простори",
|
||||
"start_group_chat_button": "Розпочати нову бесіду"
|
||||
},
|
||||
@@ -3291,9 +3298,7 @@
|
||||
"threads_activity_centre": {
|
||||
"header": "Діяльність у гілках",
|
||||
"no_rooms_with_threads_notifs": "У вас ще немає кімнат зі сповіщеннями в гілках.",
|
||||
"no_rooms_with_unread_threads": "У вас ще немає кімнат з непрочитаними гілками.",
|
||||
"release_announcement_description": "Сповіщення гілок переміщено, відтепер вони тут.",
|
||||
"release_announcement_header": "Центр діяльності в гілках"
|
||||
"no_rooms_with_unread_threads": "У вас ще немає кімнат з непрочитаними гілками."
|
||||
},
|
||||
"time": {
|
||||
"about_day_ago": "близько доби тому",
|
||||
@@ -3804,10 +3809,11 @@
|
||||
"unavailable": "Недоступний"
|
||||
},
|
||||
"update_room_access_modal": {
|
||||
"description": "Щоб створити посилання для спільного доступу, потрібно дозволити гостям приєднуватися до цієї кімнати. Рівень безпеки кімнати стане нижчим. Після завершення виклику, ви можете знову зробити кімнату приватною.",
|
||||
"dont_change_description": "Як варіант, ви можете провести виклик в окремій кімнаті.",
|
||||
"description": "Щоб створити посилання для поширення, зробіть кімнату <b>загальнодоступною</b> або дозвольте користувачам надсилати <b>запит приєднатися</b>. Це дозволить гостям приєднуватися без запрошення.",
|
||||
"dont_change_description": "Якщо ви не хочете змінювати доступ до цієї кімнати, ви можете створити нову кімнату для посилання на виклик.",
|
||||
"no_change": "Я не хочу змінювати рівень доступу.",
|
||||
"title": "Змінити рівень доступу до кімнати"
|
||||
"revert_access_description": "(Це значення можна повернути до попереднього в налаштуваннях кімнати: <b>Безпека та приватність</b> /<b> Доступ</b>)",
|
||||
"title": "Дозволити гостьовим користувачам приєднуватися до цієї кімнати"
|
||||
},
|
||||
"upload_failed_generic": "Не вдалося вивантажити файл '%(fileName)s'.",
|
||||
"upload_failed_size": "Файл '%(fileName)s' перевищує ліміт розміру для відвантажень домашнього сервера",
|
||||
|
||||
@@ -788,7 +788,6 @@
|
||||
"accepting": "Đang chấp nhận…",
|
||||
"after_new_login": {
|
||||
"device_verified": "Thiết bị được xác thực",
|
||||
"reset_confirmation": "Thực sự đặt lại các khóa xác minh?",
|
||||
"skip_verification": "Bỏ qua xác thực ngay bây giờ",
|
||||
"unable_to_verify": "Không thể xác thực thiết bị này",
|
||||
"verify_this_device": "Xác thực thiết bị này"
|
||||
@@ -858,8 +857,6 @@
|
||||
"verify_emoji_prompt": "Xác thực bằng cách so sánh biểu tượng cảm xúc độc đáo.",
|
||||
"verify_emoji_prompt_qr": "Nếu bạn không thể quét mã ở trên, hãy xác thực bằng cách so sánh biểu tượng cảm xúc duy nhất.",
|
||||
"verify_later": "Tôi sẽ xác thực sau",
|
||||
"verify_reset_warning_1": "Sẽ không thể hoàn tác lại việc đặt lại các khóa xác thực của bạn. Sau khi đặt lại, bạn sẽ không có quyền truy cập vào các tin nhắn đã được mã hóa cũ, và bạn bè đã được xác thực trước đó bạn sẽ thấy các cảnh báo bảo mật cho đến khi bạn xác thực lại với họ.",
|
||||
"verify_reset_warning_2": "Chỉ tiếp tục nếu bạn chắc chắn là mình đã mất mọi thiết bị khác và khóa bảo mật.",
|
||||
"verify_using_device": "Xác thực bằng thiết bị khác",
|
||||
"verify_using_key": "Xác thực bằng Khóa Bảo mật",
|
||||
"verify_using_key_or_phrase": "Xác thực bằng Khóa hoặc Chuỗi Bảo mật",
|
||||
@@ -2563,14 +2560,12 @@
|
||||
"heading_without_query": "Tìm",
|
||||
"join_button_text": "Tham gia %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "Dùng <arrows/> để cuộn",
|
||||
"message_search_section_title": "Các tìm kiếm khác",
|
||||
"other_rooms_in_space": "Các phòng khác trong %(spaceName)s",
|
||||
"public_rooms_label": "Các phòng công cộng",
|
||||
"recent_searches_section_title": "Các tìm kiếm gần đây",
|
||||
"recently_viewed_section_title": "Được xem gần đây",
|
||||
"result_may_be_hidden_privacy_warning": "Một số kết quả có thể bị ẩn để đảm bảo quyền riêng tư",
|
||||
"result_may_be_hidden_warning": "Một số kết quả có thể bị ẩn",
|
||||
"search_messages_hint": "Để tìm các tin nhắn, hãy tìm biểu tượng này ở đầu phòng <icon/>",
|
||||
"spaces_title": "Các Space bạn đang trong đó",
|
||||
"start_group_chat_button": "Bắt đầu cuộc trò chuyện nhóm"
|
||||
},
|
||||
|
||||
@@ -798,7 +798,6 @@
|
||||
"accepting": "正在接受……",
|
||||
"after_new_login": {
|
||||
"device_verified": "设备已验证",
|
||||
"reset_confirmation": "确实要重置验证密钥?",
|
||||
"skip_verification": "暂时跳过验证",
|
||||
"unable_to_verify": "无法验证此设备",
|
||||
"verify_this_device": "验证此设备"
|
||||
@@ -862,7 +861,6 @@
|
||||
"verify_emoji_prompt": "通过比较唯一的表情符号来验证。",
|
||||
"verify_emoji_prompt_qr": "如果你不能扫描以上代码,请通过比较唯一的表情符号来验证。",
|
||||
"verify_later": "我稍后进行验证",
|
||||
"verify_reset_warning_1": "无法撤消重置验证密钥的操作。重置后,你将无法访问旧的加密消息,任何之前验证过你的朋友将看到安全警告,直到你再次和他们进行验证。",
|
||||
"verify_using_device": "使用其他设备进行验证",
|
||||
"verify_using_key": "使用安全密钥进行验证",
|
||||
"verify_using_key_or_phrase": "使用安全密钥或短语进行验证",
|
||||
@@ -2518,7 +2516,6 @@
|
||||
"heading_without_query": "搜索",
|
||||
"join_button_text": "加入%(roomAddress)s",
|
||||
"keyboard_scroll_hint": "用<arrows/>来滚动",
|
||||
"message_search_section_title": "其他搜索",
|
||||
"other_rooms_in_space": "%(spaceName)s 中的其他房间",
|
||||
"public_rooms_label": "公共房间",
|
||||
"public_spaces_label": "公共空间",
|
||||
@@ -2528,7 +2525,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "为保护隐私,一些结果可能被隐藏",
|
||||
"result_may_be_hidden_warning": "一些结果可能被隐藏",
|
||||
"search_dialog": "搜索对话",
|
||||
"search_messages_hint": "要搜索消息,请在房间顶部查找此图标<icon/>",
|
||||
"spaces_title": "你所在的空间",
|
||||
"start_group_chat_button": "发起群聊天"
|
||||
},
|
||||
|
||||
@@ -856,7 +856,6 @@
|
||||
"accepting": "正在接受…",
|
||||
"after_new_login": {
|
||||
"device_verified": "裝置已驗證",
|
||||
"reset_confirmation": "真的要重設驗證金鑰?",
|
||||
"skip_verification": "暫時略過驗證",
|
||||
"unable_to_verify": "無法驗證此裝置",
|
||||
"verify_this_device": "驗證此裝置"
|
||||
@@ -926,8 +925,6 @@
|
||||
"verify_emoji_prompt": "透過比對獨特的表情符號來進行驗證。",
|
||||
"verify_emoji_prompt_qr": "如果您無法掃描上面的條碼,請透過比較獨特的表情符號驗證。",
|
||||
"verify_later": "我稍後驗證",
|
||||
"verify_reset_warning_1": "重設您的驗證金鑰將無法復原。重設後,您將無法存取舊的加密訊息,之前任何驗證過您的朋友也會看到安全警告,直到您重新驗證。",
|
||||
"verify_reset_warning_2": "請僅在您確定遺失了您其他所有裝置與安全金鑰時才繼續。",
|
||||
"verify_using_device": "用另一台裝置驗證",
|
||||
"verify_using_key": "使用安全金鑰進行驗證",
|
||||
"verify_using_key_or_phrase": "使用安全金鑰或密語進行驗證",
|
||||
@@ -2765,7 +2762,6 @@
|
||||
"heading_without_query": "搜尋",
|
||||
"join_button_text": "加入 %(roomAddress)s",
|
||||
"keyboard_scroll_hint": "使用 <arrows/> 捲動",
|
||||
"message_search_section_title": "其他搜尋",
|
||||
"other_rooms_in_space": "其他在 %(spaceName)s 中的聊天室",
|
||||
"public_rooms_label": "公開聊天室",
|
||||
"recent_searches_section_title": "近期搜尋",
|
||||
@@ -2774,7 +2770,6 @@
|
||||
"result_may_be_hidden_privacy_warning": "出於隱私考量,可能會隱藏一些結果",
|
||||
"result_may_be_hidden_warning": "某些結果可能會被隱藏",
|
||||
"search_dialog": "搜尋對話方塊",
|
||||
"search_messages_hint": "要搜尋訊息,請在聊天室頂部尋找此圖示 <icon/>",
|
||||
"spaces_title": "您所在的聊天空間",
|
||||
"start_group_chat_button": "開始群組聊天"
|
||||
},
|
||||
|
||||
@@ -113,6 +113,10 @@ export function _td(s: TranslationKey): TranslationKey {
|
||||
return s;
|
||||
}
|
||||
|
||||
function isValidTranslation(translated: string): boolean {
|
||||
return typeof translated === "string" && !translated.startsWith("missing translation:");
|
||||
}
|
||||
|
||||
/**
|
||||
* to improve screen reader experience translations that are not in the main page language
|
||||
* eg a translation that fell back to english from another language
|
||||
@@ -124,30 +128,26 @@ export function _td(s: TranslationKey): TranslationKey {
|
||||
* */
|
||||
const translateWithFallback = (text: string, options?: IVariables): { translated: string; isFallback?: boolean } => {
|
||||
const translated = counterpart.translate(text, { ...options, fallbackLocale: counterpart.getLocale() });
|
||||
if (!translated || translated.startsWith("missing translation:")) {
|
||||
const fallbackTranslated = counterpart.translate(text, { ...options, locale: FALLBACK_LOCALE });
|
||||
if (
|
||||
(!fallbackTranslated || fallbackTranslated.startsWith("missing translation:")) &&
|
||||
process.env.NODE_ENV !== "development"
|
||||
) {
|
||||
// Even the translation via FALLBACK_LOCALE failed; this can happen if
|
||||
//
|
||||
// 1. The string isn't in the translations dictionary, usually because you're in develop
|
||||
// and haven't run yarn i18n
|
||||
// 2. Loading the translation resources over the network failed, which can happen due to
|
||||
// to network or if the client tried to load a translation that's been removed from the
|
||||
// server.
|
||||
//
|
||||
// At this point, its the lesser evil to show the untranslated text, which
|
||||
// will be in English, so the user can still make out *something*, rather than an opaque
|
||||
// "missing translation" error.
|
||||
//
|
||||
// Don't do this in develop so people remember to run yarn i18n.
|
||||
return { translated: text, isFallback: true };
|
||||
}
|
||||
if (isValidTranslation(translated)) {
|
||||
return { translated };
|
||||
}
|
||||
|
||||
const fallbackTranslated = counterpart.translate(text, { ...options, locale: FALLBACK_LOCALE });
|
||||
if (isValidTranslation(fallbackTranslated)) {
|
||||
return { translated: fallbackTranslated, isFallback: true };
|
||||
}
|
||||
return { translated };
|
||||
|
||||
// Even the translation via FALLBACK_LOCALE failed; this can happen if
|
||||
//
|
||||
// 1. The string isn't in the translations dictionary, usually because you're in develop
|
||||
// and haven't run yarn i18n
|
||||
// 2. Loading the translation resources over the network failed, which can happen due to
|
||||
// to network or if the client tried to load a translation that's been removed from the
|
||||
// server.
|
||||
//
|
||||
// At this point, its the lesser evil to show the i18n key which will be in English but not human-friendly,
|
||||
// so the user can still make out *something*, rather than an opaque possibly-untranslated "missing translation" error.
|
||||
return { translated: text, isFallback: true };
|
||||
};
|
||||
|
||||
// Wrapper for counterpart's translation function so that it handles nulls and undefineds properly
|
||||
@@ -454,55 +454,35 @@ type Languages = {
|
||||
[lang: string]: string;
|
||||
};
|
||||
|
||||
export function setLanguage(preferredLangs: string | string[]): Promise<void> {
|
||||
if (!Array.isArray(preferredLangs)) {
|
||||
preferredLangs = [preferredLangs];
|
||||
export async function setLanguage(...preferredLangs: string[]): Promise<void> {
|
||||
PlatformPeg.get()?.setLanguage(preferredLangs);
|
||||
|
||||
const availableLanguages = await getLangsJson();
|
||||
let chosenLanguage = preferredLangs.find((lang) => availableLanguages.hasOwnProperty(lang));
|
||||
if (!chosenLanguage) {
|
||||
// Fallback to en_EN if none is found
|
||||
chosenLanguage = "en";
|
||||
logger.error("Unable to find an appropriate language, preferred: ", preferredLangs);
|
||||
}
|
||||
|
||||
const plaf = PlatformPeg.get();
|
||||
if (plaf) {
|
||||
plaf.setLanguage(preferredLangs);
|
||||
const languageData = await getLanguageRetry(i18nFolder + availableLanguages[chosenLanguage]);
|
||||
|
||||
counterpart.registerTranslations(chosenLanguage, languageData);
|
||||
counterpart.setLocale(chosenLanguage);
|
||||
|
||||
await SettingsStore.setValue("language", null, SettingLevel.DEVICE, chosenLanguage);
|
||||
// Adds a lot of noise to test runs, so disable logging there.
|
||||
if (process.env.NODE_ENV !== "test") {
|
||||
logger.log("set language to " + chosenLanguage);
|
||||
}
|
||||
|
||||
let langToUse: string;
|
||||
let availLangs: Languages;
|
||||
return getLangsJson()
|
||||
.then((result) => {
|
||||
availLangs = result;
|
||||
// Set 'en' as fallback language:
|
||||
if (chosenLanguage !== "en") {
|
||||
const fallbackLanguageData = await getLanguageRetry(i18nFolder + availableLanguages["en"]);
|
||||
counterpart.registerTranslations("en", fallbackLanguageData);
|
||||
}
|
||||
|
||||
for (let i = 0; i < preferredLangs.length; ++i) {
|
||||
if (availLangs.hasOwnProperty(preferredLangs[i])) {
|
||||
langToUse = preferredLangs[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!langToUse) {
|
||||
// Fallback to en_EN if none is found
|
||||
langToUse = "en";
|
||||
logger.error("Unable to find an appropriate language");
|
||||
}
|
||||
|
||||
return getLanguageRetry(i18nFolder + availLangs[langToUse]);
|
||||
})
|
||||
.then(async (langData): Promise<ICounterpartTranslation | undefined> => {
|
||||
counterpart.registerTranslations(langToUse, langData);
|
||||
await registerCustomTranslations();
|
||||
counterpart.setLocale(langToUse);
|
||||
await SettingsStore.setValue("language", null, SettingLevel.DEVICE, langToUse);
|
||||
// Adds a lot of noise to test runs, so disable logging there.
|
||||
if (process.env.NODE_ENV !== "test") {
|
||||
logger.log("set language to " + langToUse);
|
||||
}
|
||||
|
||||
// Set 'en' as fallback language:
|
||||
if (langToUse !== "en") {
|
||||
return getLanguageRetry(i18nFolder + availLangs["en"]);
|
||||
}
|
||||
})
|
||||
.then(async (langData): Promise<void> => {
|
||||
if (langData) counterpart.registerTranslations("en", langData);
|
||||
await registerCustomTranslations();
|
||||
});
|
||||
await registerCustomTranslations();
|
||||
}
|
||||
|
||||
type Language = {
|
||||
@@ -529,8 +509,7 @@ export async function getAllLanguagesWithLabels(): Promise<Language[]> {
|
||||
|
||||
export function getLanguagesFromBrowser(): readonly string[] {
|
||||
if (navigator.languages && navigator.languages.length) return navigator.languages;
|
||||
if (navigator.language) return [navigator.language];
|
||||
return [navigator.userLanguage || "en"];
|
||||
return [navigator.language ?? "en"];
|
||||
}
|
||||
|
||||
export function getLanguageFromBrowser(): string {
|
||||
|
||||
@@ -5,7 +5,9 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { Api, RuntimeModuleConstructor, Config } from "@element-hq/element-web-module-api";
|
||||
import { createRoot, type Root } from "react-dom/client";
|
||||
|
||||
import type { Api, RuntimeModuleConstructor } from "@element-hq/element-web-module-api";
|
||||
import { ModuleRunner } from "./ModuleRunner.ts";
|
||||
import AliasCustomisations from "../customisations/Alias.ts";
|
||||
import { RoomListCustomisations } from "../customisations/RoomList.ts";
|
||||
@@ -17,7 +19,8 @@ import * as MediaCustomisations from "../customisations/Media.ts";
|
||||
import UserIdentifierCustomisations from "../customisations/UserIdentifier.ts";
|
||||
import { WidgetPermissionCustomisations } from "../customisations/WidgetPermissions.ts";
|
||||
import { WidgetVariableCustomisations } from "../customisations/WidgetVariables.ts";
|
||||
import SdkConfig from "../SdkConfig.ts";
|
||||
import { ConfigApi } from "./ConfigApi.ts";
|
||||
import { I18nApi } from "./I18nApi.ts";
|
||||
|
||||
const legacyCustomisationsFactory = <T extends object>(baseCustomisations: T) => {
|
||||
let used = false;
|
||||
@@ -28,17 +31,6 @@ const legacyCustomisationsFactory = <T extends object>(baseCustomisations: T) =>
|
||||
};
|
||||
};
|
||||
|
||||
class ConfigApi {
|
||||
public get(): Config;
|
||||
public get<K extends keyof Config>(key: K): Config[K];
|
||||
public get<K extends keyof Config = never>(key?: K): Config | Config[K] {
|
||||
if (key === undefined) {
|
||||
return SdkConfig.get() as Config;
|
||||
}
|
||||
return SdkConfig.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of the @element-hq/element-web-module-api runtime module API.
|
||||
*/
|
||||
@@ -65,6 +57,12 @@ class ModuleApi implements Api {
|
||||
/* eslint-enable @typescript-eslint/naming-convention */
|
||||
|
||||
public readonly config = new ConfigApi();
|
||||
public readonly i18n = new I18nApi();
|
||||
public readonly rootNode = document.getElementById("matrixchat")!;
|
||||
|
||||
public createRoot(element: Element): Root {
|
||||
return createRoot(element);
|
||||
}
|
||||
}
|
||||
|
||||
export type ModuleApiType = ModuleApi;
|
||||
|
||||
20
src/modules/ConfigApi.ts
Normal file
20
src/modules/ConfigApi.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import type { ConfigApi as IConfigApi, Config } from "@element-hq/element-web-module-api";
|
||||
import SdkConfig from "../SdkConfig.ts";
|
||||
|
||||
export class ConfigApi implements IConfigApi {
|
||||
public get(): Config;
|
||||
public get<K extends keyof Config>(key: K): Config[K];
|
||||
public get<K extends keyof Config = never>(key?: K): Config | Config[K] {
|
||||
if (key === undefined) {
|
||||
return SdkConfig.get() as Config;
|
||||
}
|
||||
return SdkConfig.get(key);
|
||||
}
|
||||
}
|
||||
47
src/modules/I18nApi.ts
Normal file
47
src/modules/I18nApi.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
Copyright 2025 New Vector Ltd.
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type I18nApi as II18nApi, type Variables, type Translations } from "@element-hq/element-web-module-api";
|
||||
import counterpart from "counterpart";
|
||||
|
||||
import { _t, getCurrentLanguage, type TranslationKey } from "../languageHandler.tsx";
|
||||
|
||||
export class I18nApi implements II18nApi {
|
||||
/**
|
||||
* Read the current language of the user in IETF Language Tag format
|
||||
*/
|
||||
public get language(): string {
|
||||
return getCurrentLanguage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register translations for the module, may override app's existing translations
|
||||
*/
|
||||
public register(translations: Partial<Translations>): void {
|
||||
const langs: Record<string, Record<string, string>> = {};
|
||||
for (const key in translations) {
|
||||
for (const lang in translations[key]) {
|
||||
langs[lang] = langs[lang] || {};
|
||||
langs[lang][key] = translations[key][lang];
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, tell counterpart about our translations
|
||||
for (const lang in langs) {
|
||||
counterpart.registerTranslations(lang, langs[lang]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a translation, with optional variables
|
||||
* @param key - The key to translate
|
||||
* @param variables - Optional variables to interpolate into the translation
|
||||
*/
|
||||
public translate(key: TranslationKey, variables?: Variables): string {
|
||||
return _t(key, variables);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2024 New Vector Ltd.
|
||||
Copyright 2024, 2025 New Vector Ltd.
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2017 Travis Ralston
|
||||
|
||||
@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { type ReactNode } from "react";
|
||||
import { ClientEvent, SyncState } from "matrix-js-sdk/src/matrix";
|
||||
import { ClientEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
import DeviceSettingsHandler from "./handlers/DeviceSettingsHandler";
|
||||
import RoomDeviceSettingsHandler from "./handlers/RoomDeviceSettingsHandler";
|
||||
@@ -667,35 +667,25 @@ export default class SettingsStore {
|
||||
|
||||
const client = MatrixClientPeg.safeGet();
|
||||
|
||||
const doMigration = async (): Promise<void> => {
|
||||
logger.info("Performing one-time settings migration of URL previews in E2EE rooms");
|
||||
while (!client.isInitialSyncComplete()) {
|
||||
await new Promise((r) => client.once(ClientEvent.Sync, r));
|
||||
}
|
||||
|
||||
const roomAccounthandler = LEVEL_HANDLERS[SettingLevel.ROOM_ACCOUNT];
|
||||
logger.info("Performing one-time settings migration of URL previews in E2EE rooms");
|
||||
|
||||
for (const room of client.getRooms()) {
|
||||
// We need to use the handler directly because this setting is no longer supported
|
||||
// at this level at all
|
||||
const val = roomAccounthandler.getValue("urlPreviewsEnabled_e2ee", room.roomId);
|
||||
const roomAccounthandler = LEVEL_HANDLERS[SettingLevel.ROOM_ACCOUNT];
|
||||
|
||||
if (val !== undefined) {
|
||||
await SettingsStore.setValue("urlPreviewsEnabled_e2ee", room.roomId, SettingLevel.ROOM_DEVICE, val);
|
||||
}
|
||||
for (const room of client.getRooms()) {
|
||||
// We need to use the handler directly because this setting is no longer supported
|
||||
// at this level at all
|
||||
const val = roomAccounthandler.getValue("urlPreviewsEnabled_e2ee", room.roomId);
|
||||
|
||||
if (val !== undefined) {
|
||||
await SettingsStore.setValue("urlPreviewsEnabled_e2ee", room.roomId, SettingLevel.ROOM_DEVICE, val);
|
||||
}
|
||||
}
|
||||
|
||||
localStorage.setItem(MIGRATION_DONE_FLAG, "true");
|
||||
};
|
||||
|
||||
const onSync = (state: SyncState): void => {
|
||||
if (state === SyncState.Prepared) {
|
||||
client.removeListener(ClientEvent.Sync, onSync);
|
||||
|
||||
doMigration().catch((e) => {
|
||||
logger.error("Failed to migrate URL previews in E2EE rooms:", e);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
client.on(ClientEvent.Sync, onSync);
|
||||
localStorage.setItem(MIGRATION_DONE_FLAG, "true");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -718,25 +708,31 @@ export default class SettingsStore {
|
||||
|
||||
/**
|
||||
* Migrate the setting for visible images to a setting.
|
||||
*
|
||||
* @param isFreshLogin True if the user has just logged in, false if a previous session is being restored.
|
||||
*/
|
||||
private static migrateMediaControlsToSetting(): void {
|
||||
const MIGRATION_DONE_FLAG = "mx_migrate_media_controls";
|
||||
if (localStorage.getItem(MIGRATION_DONE_FLAG)) return;
|
||||
private static async migrateMediaControlsToSetting(isFreshLogin: boolean): Promise<void> {
|
||||
if (isFreshLogin) return;
|
||||
const client = MatrixClientPeg.safeGet();
|
||||
|
||||
while (!client.isInitialSyncComplete()) {
|
||||
await new Promise((r) => client.once(ClientEvent.Sync, r));
|
||||
}
|
||||
// Never migrate if the config already exists.
|
||||
if (client.getAccountData("io.element.msc4278.media_preview_config")) {
|
||||
return;
|
||||
}
|
||||
logger.info("Performing one-time settings migration of show images and invite avatars to account data");
|
||||
const handler = LEVEL_HANDLERS[SettingLevel.ACCOUNT];
|
||||
const showImages = handler.getValue("showImages", null);
|
||||
const showAvatarsOnInvites = handler.getValue("showAvatarsOnInvites", null);
|
||||
|
||||
const AccountHandler = LEVEL_HANDLERS[SettingLevel.ACCOUNT];
|
||||
if (showImages !== null || showAvatarsOnInvites !== null) {
|
||||
AccountHandler.setValue("mediaPreviewConfig", null, {
|
||||
if (typeof showImages === "boolean" || typeof showAvatarsOnInvites === "boolean") {
|
||||
this.setValue("mediaPreviewConfig", null, SettingLevel.ACCOUNT, {
|
||||
invite_avatars: showAvatarsOnInvites === false ? MediaPreviewValue.Off : MediaPreviewValue.On,
|
||||
media_previews: showImages === false ? MediaPreviewValue.Off : MediaPreviewValue.On,
|
||||
});
|
||||
} // else, we don't set anything and use the server value
|
||||
|
||||
localStorage.setItem(MIGRATION_DONE_FLAG, "true");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -748,7 +744,9 @@ export default class SettingsStore {
|
||||
// (so around October 2024).
|
||||
// The consequences of missing the migration are only that URL previews will
|
||||
// be disabled in E2EE rooms.
|
||||
SettingsStore.migrateURLPreviewsE2EE(isFreshLogin);
|
||||
SettingsStore.migrateURLPreviewsE2EE(isFreshLogin).catch((e) => {
|
||||
logger.error("Failed to migrate URL previews in E2EE rooms:", e);
|
||||
});
|
||||
|
||||
// This can be removed once enough users have run a version of Element with
|
||||
// this migration.
|
||||
@@ -760,8 +758,9 @@ export default class SettingsStore {
|
||||
// this migration.
|
||||
// The consequences of missing the migration are that the previously set
|
||||
// media controls for this user will be missing
|
||||
SettingsStore.migrateMediaControlsToSetting();
|
||||
|
||||
SettingsStore.migrateMediaControlsToSetting(isFreshLogin).catch((e) => {
|
||||
logger.error("Failed to migrate media config settings", e);
|
||||
});
|
||||
// Dev notes: to add your migration, just add a new `migrateMyFeature` function, call it, and
|
||||
// add a comment to note when it can be removed.
|
||||
return;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user