Merge branch 'livekit' into layout-state

This commit is contained in:
Robin
2024-04-19 13:28:30 -04:00
47 changed files with 852 additions and 801 deletions

View File

@@ -1,34 +1,25 @@
name: Build name: Build
on: on:
pull_request: {} pull_request:
types:
- synchronize
- opened
- labeled
paths-ignore:
- ".github/**"
- "docs/**"
push: push:
branches: [livekit, full-mesh] branches: [livekit, full-mesh]
paths-ignore:
- ".github/**"
- "docs/**"
jobs: jobs:
build: build_element_call:
name: Build uses: ./.github/workflows/element-call.yaml
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Yarn cache
uses: actions/setup-node@v4
with: with:
cache: "yarn" vite_app_version: ${{ github.event.release.tag_name || github.sha }}
- name: Install dependencies secrets:
run: "yarn install"
- name: Build
run: "yarn run build"
env:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }} SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
VITE_APP_VERSION: ${{ github.sha }}
NODE_OPTIONS: "--max-old-space-size=4096"
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: build
path: dist
# We'll only use this in a triggered job, then we're done with it
retention-days: 1

56
.github/workflows/docker.yaml vendored Normal file
View File

@@ -0,0 +1,56 @@
name: Docker - Deploy
on:
workflow_call:
inputs:
docker_tags:
required: true
type: string
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build_and_deploy:
name: Build & publish docker
runs-on: ubuntu-latest
permissions:
contents: write # required to upload release asset
packages: write
steps:
- name: Check it out
uses: actions/checkout@v4
- name: 📥 Download artifact
uses: actions/download-artifact@v4
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
run-id: ${{ github.event.workflow_run.id }}
name: build-output
path: dist
- name: Log in to container registry
uses: docker/login-action@5f4866a30a54f16a52d2ecb4a3898e9e424939cf
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@1294d94f8ee362ab42b6da04c35f4cd03a0e6af7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: ${{ inputs.docker_tags}}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@a530e948adbeb357dbca95a7f8845d385edf4438
- name: Build and push Docker image
uses: docker/build-push-action@7e6f77677b7892794c8852c6e3773c3e9bc3129a
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

46
.github/workflows/element-call.yaml vendored Normal file
View File

@@ -0,0 +1,46 @@
name: Element Call - Build
on:
workflow_call:
inputs:
vite_app_version:
required: true
type: string
secrets:
SENTRY_ORG:
required: true
SENTRY_PROJECT:
required: true
SENTRY_URL:
required: true
SENTRY_AUTH_TOKEN:
required: true
jobs:
build:
name: Build Element Call
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Yarn cache
uses: actions/setup-node@v4
with:
cache: "yarn"
- name: Install dependencies
run: "yarn install"
- name: Build
run: "yarn run build"
env:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
VITE_APP_VERSION: ${{ inputs.vite_app_version }}
NODE_OPTIONS: "--max-old-space-size=4096"
- name: Upload Artifact
uses: actions/upload-artifact@v4
with:
name: build-output
path: dist
# We'll only use this in a triggered job, then we're done with it
retention-days: 1

View File

@@ -1,15 +1,29 @@
name: Netlify PR Preview name: Netlify - Deploy
on: on:
workflow_run: workflow_call:
workflows: ["Build"] inputs:
types: pr_number:
- completed required: true
branches-ignore: type: string
- "main" pr_head_full_name:
- "livekit" required: true
type: string
pr_head_ref:
required: true
type: string
deployment_ref:
required: true
type: string
secrets:
ELEMENT_BOT_TOKEN:
required: true
NETLIFY_AUTH_TOKEN:
required: true
NETLIFY_SITE_ID:
required: true
jobs: jobs:
deploy: deploy:
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
deployments: write deployments: write
@@ -22,24 +36,17 @@ jobs:
step: start step: start
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
env: Netlify env: Netlify
ref: ${{ github.event.workflow_run.head_sha }} ref: ${{ inputs.deployment_ref }}
desc: | desc: |
Do you trust the author of this PR? Maybe this build will steal your keys or give you malware. Do you trust the author of this PR? Maybe this build will steal your keys or give you malware.
Exercise caution. Use test accounts. Exercise caution. Use test accounts.
- id: prdetails
uses: matrix-org/pr-details-action@v1.3
with:
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
branch: ${{ github.event.workflow_run.head_branch }}
# There's a 'download artifact' action, but it hasn't been updated for the workflow_run action
# (https://github.com/actions/download-artifact/issues/60) so instead we get this mess:
- name: 📥 Download artifact - name: 📥 Download artifact
uses: dawidd6/action-download-artifact@v3 uses: actions/download-artifact@v4
with: with:
run_id: ${{ github.event.workflow_run.id }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
name: build run-id: ${{ github.event.workflow_run.id }}
name: build-output
path: webapp path: webapp
- name: Add redirects file - name: Add redirects file
@@ -47,18 +54,15 @@ jobs:
run: curl -s https://raw.githubusercontent.com/element-hq/element-call/main/config/netlify_redirects > webapp/_redirects run: curl -s https://raw.githubusercontent.com/element-hq/element-call/main/config/netlify_redirects > webapp/_redirects
- name: Add config file - name: Add config file
run: curl -s "https://raw.githubusercontent.com/${{ github.event.workflow_run.head_repository.full_name }}/${{ github.event.workflow_run.head_branch }}/config/element_io_preview.json" > webapp/config.json run: curl -s "https://raw.githubusercontent.com/${{ inputs.pr_head_full_name }}/${{ inputs.pr_head_ref }}/config/element_io_preview.json" > webapp/config.json
- name: ☁️ Deploy to Netlify - name: ☁️ Deploy to Netlify
id: netlify id: netlify
uses: nwtgck/actions-netlify@v2.1 uses: nwtgck/actions-netlify@v3.0
with: with:
publish-dir: webapp publish-dir: webapp
deploy-message: "Deploy from GitHub Actions" deploy-message: "Deploy from GitHub Actions"
# These don't work because we're in workflow_run alias: pr${{ inputs.pr_number }}
enable-pull-request-comment: false
enable-commit-comment: false
alias: pr${{ steps.prdetails.outputs.pr_id }}
env: env:
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}

48
.github/workflows/pr-deploy.yaml vendored Normal file
View File

@@ -0,0 +1,48 @@
name: PR Preview Deployments
on:
workflow_run:
workflows: ["Build"]
types:
- completed
jobs:
prdetails:
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request' }}
runs-on: ubuntu-latest
outputs:
pr_number: ${{ steps.prdetails.outputs.pr_id }}
pr_data_json: ${{ steps.prdetails.outputs.data }}
steps:
- id: prdetails
uses: matrix-org/pr-details-action@v1.3
continue-on-error: true
with:
owner: ${{ github.event.workflow_run.head_repository.owner.login }}
branch: ${{ github.event.workflow_run.head_branch }}
netlify:
needs: prdetails
permissions:
deployments: write
uses: ./.github/workflows/netlify.yaml
with:
pr_number: ${{ needs.prdetails.outputs.pr_number }}
pr_head_full_name: ${{ github.event.workflow_run.head_repository.full_name }}
pr_head_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.ref }}
deployment_ref: ${{ needs.prdetails.outputs.pr_data_json && fromJSON(needs.prdetails.outputs.pr_data_json).head.sha || github.ref || github.head_ref }}
secrets:
ELEMENT_BOT_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }}
docker:
if: ${{ needs.prdetails.outputs.pr_data_json && contains(fromJSON(needs.prdetails.outputs.pr_data_json).labels.*.name, 'docker build') }}
needs: prdetails
permissions:
contents: write
packages: write
uses: ./.github/workflows/docker.yaml
with:
docker_tags: |
type=sha,format=short,event=branch
type=raw,value=pr_${{ needs.prdetails.outputs.pr_number }}

View File

@@ -3,17 +3,32 @@ name: Build & publish images to the package registry for tags
on: on:
release: release:
types: [published] types: [published]
push: workflow_run:
workflows: ["Build"]
branches: [livekit] branches: [livekit]
types:
- completed
env: env:
REGISTRY: ghcr.io REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }} IMAGE_NAME: ${{ github.repository }}
jobs: jobs:
build: build_element_call:
name: Build & publish if: ${{ github.event.workflow_run.event == 'release' }}
uses: ./.github/workflows/element-call.yaml
with:
vite_app_version: ${{ github.event.release.tag_name || github.sha }}
secrets:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
publish_tarball:
name: Publish tarball
runs-on: ubuntu-latest runs-on: ubuntu-latest
outputs:
unix_time: ${{steps.current-time.outputs.unix_time}}
permissions: permissions:
contents: write # required to upload release asset contents: write # required to upload release asset
packages: write packages: write
@@ -21,64 +36,33 @@ jobs:
- name: Get current time - name: Get current time
id: current-time id: current-time
run: echo "unix_time=$(date +'%s')" >> $GITHUB_OUTPUT run: echo "unix_time=$(date +'%s')" >> $GITHUB_OUTPUT
- name: 📥 Download artifact
- name: Check it out uses: actions/download-artifact@v4
uses: actions/checkout@v4
- name: Log in to container registry
uses: docker/login-action@83a00bc1ab5ded6580f31df1c49e6aaa932d840d
with: with:
registry: ${{ env.REGISTRY }} github-token: ${{ secrets.GITHUB_TOKEN }}
username: ${{ github.actor }} run-id: ${{ github.event.workflow_run.id }}
password: ${{ secrets.GITHUB_TOKEN }} name: build-output
path: dist
- name: Yarn cache
uses: actions/setup-node@v4
with:
cache: "yarn"
- name: Install dependencies
run: "yarn install"
- name: Build
run: "yarn run build"
env:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
SENTRY_URL: ${{ secrets.SENTRY_URL }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
VITE_APP_VERSION: ${{ github.event.release.tag_name || github.sha }}
- name: Create Tarball - name: Create Tarball
env: env:
TARBALL_VERSION: ${{ github.event.release.tag_name || github.sha }} TARBALL_VERSION: ${{ github.event.release.tag_name || github.sha }}
run: | run: |
tar --numeric-owner --transform "s/dist/element-call-${TARBALL_VERSION}/" -cvzf element-call-${TARBALL_VERSION}.tar.gz dist tar --numeric-owner --transform "s/dist/element-call-${TARBALL_VERSION}/" -cvzf element-call-${TARBALL_VERSION}.tar.gz dist
- name: Upload - name: Upload
uses: actions/upload-artifact@ef09cdac3e2d3e60d8ccadda691f4f1cec5035cb uses: actions/upload-artifact@b06cde36fc32a3ee94080e87258567f73f921537
env: env:
GITHUB_TOKEN: ${{ github.token }} GITHUB_TOKEN: ${{ github.token }}
with: with:
path: "./element-call-*.tar.gz" path: "./element-call-*.tar.gz"
publish_docker:
- name: Extract metadata (tags, labels) for Docker needs: publish_tarball
id: meta permissions:
uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 contents: write
packages: write
uses: ./.github/workflows/docker.yaml
with: with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} docker_tags: |
tags: |
type=sha,format=short,event=branch type=sha,format=short,event=branch
type=semver,pattern=v{{version}} type=semver,pattern=v{{version}}
type=raw,value=latest-ci,enable={{is_default_branch}} type=raw,value=latest-ci,enable={{is_default_branch}}
type=raw,value=latest-ci_${{steps.current-time.outputs.unix_time}},enable={{is_default_branch}} type=raw,value=latest-ci_${{needs.publish_tarball.outputs.unix_time}},enable={{is_default_branch}}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@edfb0fe6204400c56fbfd3feba3fe9ad1adfa345
- name: Build and push Docker image
uses: docker/build-push-action@4976231911ebf5f32aad765192d35f942aa48cb8
with:
context: .
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

View File

@@ -38,7 +38,7 @@ jobs:
- name: Create Pull Request - name: Create Pull Request
id: cpr id: cpr
uses: peter-evans/create-pull-request@v6.0.0 uses: peter-evans/create-pull-request@v6.0.3
with: with:
token: ${{ secrets.ELEMENT_BOT_TOKEN }} token: ${{ secrets.ELEMENT_BOT_TOKEN }}
branch: actions/localazy-download branch: actions/localazy-download

View File

@@ -3,6 +3,8 @@ on:
push: push:
branches: branches:
- livekit - livekit
paths-ignore:
- ".github/**"
jobs: jobs:
upload: upload:

View File

@@ -22,5 +22,3 @@ turn:
external_tls: true external_tls: true
keys: keys:
devkey: secret devkey: secret
signal_relay:
enabled: true

30
config/httpd.conf Normal file
View File

@@ -0,0 +1,30 @@
<VirtualHost *:8080>
ServerName localhost
DocumentRoot "/app"
<Location "/">
# disable cache entriely by default (apart from Etag which is accurate enough)
Header add Cache-Control "private no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
CacheDisable on
ExpiresActive off
# also turn off last-modified since they are just the timestamps of the file in the docker image
# and may or may not bear any resemblance to when the resource changed
Header add Last-Modified ""
DirectoryIndex index.html
</Location>
# assets can be cached because they have hashed filenames
<Location "/assets">
ExpiresActive on
ExpiresDefault "access plus 1 week"
Header add Cache-Control "public, no-transform"
</Location>
<Location "/apple-app-site-association">
ForceType application/json
</Location>
</VirtualHost>

View File

@@ -19,15 +19,15 @@
}, },
"dependencies": { "dependencies": {
"@juggle/resize-observer": "^3.3.1", "@juggle/resize-observer": "^3.3.1",
"@livekit/components-core": "^0.9.0", "@livekit/components-core": "^0.10.0",
"@livekit/components-react": "^2.0.0", "@livekit/components-react": "^2.0.0",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz", "@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz",
"@opentelemetry/api": "^1.4.0", "@opentelemetry/api": "^1.4.0",
"@opentelemetry/context-zone": "^1.9.1", "@opentelemetry/context-zone": "^1.9.1",
"@opentelemetry/exporter-jaeger": "^1.9.1", "@opentelemetry/exporter-jaeger": "^1.9.1",
"@opentelemetry/exporter-trace-otlp-http": "^0.48.0", "@opentelemetry/exporter-trace-otlp-http": "^0.48.0",
"@opentelemetry/instrumentation-document-load": "^0.35.0", "@opentelemetry/instrumentation-document-load": "^0.36.0",
"@opentelemetry/instrumentation-user-interaction": "^0.35.0", "@opentelemetry/instrumentation-user-interaction": "^0.36.0",
"@opentelemetry/sdk-trace-web": "^1.9.1", "@opentelemetry/sdk-trace-web": "^1.9.1",
"@radix-ui/react-dialog": "^1.0.4", "@radix-ui/react-dialog": "^1.0.4",
"@radix-ui/react-slider": "^1.1.2", "@radix-ui/react-slider": "^1.1.2",
@@ -62,7 +62,7 @@
"i18next-http-backend": "^2.0.0", "i18next-http-backend": "^2.0.0",
"livekit-client": "^2.0.2", "livekit-client": "^2.0.2",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#8123e9a3f1142a7619758c0a238172b007e3a06a", "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#d55c6a36df539f6adacc335efe5b9be27c9cee4a",
"matrix-widget-api": "^1.3.1", "matrix-widget-api": "^1.3.1",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"pako": "^2.0.4", "pako": "^2.0.4",

View File

@@ -13,7 +13,8 @@
</script> </script>
</head> </head>
<body class="cpd-theme-dark"> <!-- The default class is: .no-theme {display: none}. It will be overwritten once the app is loaded. -->
<body class="no-theme">
<div id="root"></div> <div id="root"></div>
</body> </body>
</html> </html>

View File

@@ -31,8 +31,6 @@
"username": "Потребителско име", "username": "Потребителско име",
"video": "Видео" "video": "Видео"
}, },
"exit_fullscreen_button_label": "Излез от цял екран",
"fullscreen_button_label": "Цял екран",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "Да, присъедини се", "join_button": "Да, присъедини се",
"text": "Този разговор вече съществува, искате ли да се присъедините?", "text": "Този разговор вече съществува, искате ли да се присъедините?",
@@ -42,7 +40,6 @@
"lobby": { "lobby": {
"join_button": "Влез в разговора" "join_button": "Влез в разговора"
}, },
"local_volume_label": "Локална сила на звука",
"logging_in": "Влизане…", "logging_in": "Влизане…",
"login_auth_links": "<0>Създайте акаунт</0> или <2>Влезте като гост</2>", "login_auth_links": "<0>Създайте акаунт</0> или <2>Влезте като гост</2>",
"login_title": "Влез", "login_title": "Влез",

View File

@@ -29,10 +29,8 @@
"settings": "Nastavení", "settings": "Nastavení",
"username": "Uživatelské jméno" "username": "Uživatelské jméno"
}, },
"exit_fullscreen_button_label": "Ukončit režim celé obrazovky",
"full_screen_view_description": "<0>Odeslání ladících záznamů nám pomůže diagnostikovat problém.</0>", "full_screen_view_description": "<0>Odeslání ladících záznamů nám pomůže diagnostikovat problém.</0>",
"full_screen_view_h1": "<0>Oops, něco se pokazilo.</0>", "full_screen_view_h1": "<0>Oops, něco se pokazilo.</0>",
"fullscreen_button_label": "Zvětšit na celou obrazovku",
"header_label": "Domov Element Call", "header_label": "Domov Element Call",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "Ano, připojit se", "join_button": "Ano, připojit se",
@@ -43,7 +41,6 @@
"lobby": { "lobby": {
"join_button": "Připojit se k hovoru" "join_button": "Připojit se k hovoru"
}, },
"local_volume_label": "Lokální hlasitost",
"logging_in": "Přihlašování se…", "logging_in": "Přihlašování se…",
"login_auth_links": "<0>Vytvořit účet</0> Or <2>Jako host</2>", "login_auth_links": "<0>Vytvořit účet</0> Or <2>Jako host</2>",
"login_title": "Přihlášení", "login_title": "Přihlášení",

View File

@@ -56,10 +56,8 @@
"video": "Video" "video": "Video"
}, },
"disconnected_banner": "Die Verbindung zum Server wurde getrennt.", "disconnected_banner": "Die Verbindung zum Server wurde getrennt.",
"exit_fullscreen_button_label": "Vollbildmodus verlassen",
"full_screen_view_description": "<0>Übermittelte Problemberichte helfen uns, Fehler zu beheben.</0>", "full_screen_view_description": "<0>Übermittelte Problemberichte helfen uns, Fehler zu beheben.</0>",
"full_screen_view_h1": "<0>Hoppla, etwas ist schiefgelaufen.</0>", "full_screen_view_h1": "<0>Hoppla, etwas ist schiefgelaufen.</0>",
"fullscreen_button_label": "Vollbild",
"group_call_loader_failed_heading": "Anruf nicht gefunden", "group_call_loader_failed_heading": "Anruf nicht gefunden",
"group_call_loader_failed_text": "Anrufe sind nun Ende-zu-Ende-verschlüsselt und müssen auf der Startseite erstellt werden. Damit stellen wir sicher, dass alle denselben Schlüssel verwenden.", "group_call_loader_failed_text": "Anrufe sind nun Ende-zu-Ende-verschlüsselt und müssen auf der Startseite erstellt werden. Damit stellen wir sicher, dass alle denselben Schlüssel verwenden.",
"hangup_button_label": "Anruf beenden", "hangup_button_label": "Anruf beenden",
@@ -80,7 +78,6 @@
"join_button": "Anruf beitreten", "join_button": "Anruf beitreten",
"leave_button": "Zurück zu kürzlichen Anrufen" "leave_button": "Zurück zu kürzlichen Anrufen"
}, },
"local_volume_label": "Lokale Lautstärke",
"log_in": "Anmelden", "log_in": "Anmelden",
"logging_in": "Anmelden …", "logging_in": "Anmelden …",
"login_auth_links": "<0>Konto erstellen</0> Oder <2>Als Gast betreten</2>", "login_auth_links": "<0>Konto erstellen</0> Oder <2>Als Gast betreten</2>",
@@ -141,7 +138,6 @@
"unmute_microphone_button_label": "Mikrofon aktivieren", "unmute_microphone_button_label": "Mikrofon aktivieren",
"version": "Version: {{version}}", "version": "Version: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} präsentiert",
"sfu_participant_local": "Du" "sfu_participant_local": "Du"
}, },
"waiting_for_participants": "Warte auf weitere Teilnehmer …" "waiting_for_participants": "Warte auf weitere Teilnehmer …"

View File

@@ -37,10 +37,8 @@
"username": "Όνομα χρήστη", "username": "Όνομα χρήστη",
"video": "Βίντεο" "video": "Βίντεο"
}, },
"exit_fullscreen_button_label": "Έξοδος από πλήρη οθόνη",
"full_screen_view_description": "<0>Η υποβολή αρχείων καταγραφής σφαλμάτων θα μας βοηθήσει να εντοπίσουμε το πρόβλημα.</0>", "full_screen_view_description": "<0>Η υποβολή αρχείων καταγραφής σφαλμάτων θα μας βοηθήσει να εντοπίσουμε το πρόβλημα.</0>",
"full_screen_view_h1": "<0>Ωχ, κάτι πήγε στραβά.</0>", "full_screen_view_h1": "<0>Ωχ, κάτι πήγε στραβά.</0>",
"fullscreen_button_label": "Πλήρη οθόνη",
"header_label": "Element Κεντρική Οθόνη Κλήσεων", "header_label": "Element Κεντρική Οθόνη Κλήσεων",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "Ναι, συμμετοχή στην κλήση", "join_button": "Ναι, συμμετοχή στην κλήση",
@@ -50,7 +48,6 @@
"lobby": { "lobby": {
"join_button": "Συμμετοχή στην κλήση" "join_button": "Συμμετοχή στην κλήση"
}, },
"local_volume_label": "Τοπική ένταση",
"logging_in": "Σύνδεση…", "logging_in": "Σύνδεση…",
"login_auth_links": "<0>Δημιουργήστε λογαριασμό</0> Ή <2>Συμμετέχετε ως επισκέπτης</2>", "login_auth_links": "<0>Δημιουργήστε λογαριασμό</0> Ή <2>Συμμετέχετε ως επισκέπτης</2>",
"login_title": "Σύνδεση", "login_title": "Σύνδεση",
@@ -94,8 +91,5 @@
"unauthenticated_view_body": "Δεν έχετε εγγραφεί ακόμα; <2>Δημιουργήστε λογαριασμό</2>", "unauthenticated_view_body": "Δεν έχετε εγγραφεί ακόμα; <2>Δημιουργήστε λογαριασμό</2>",
"unauthenticated_view_login_button": "Συνδεθείτε στον λογαριασμό σας", "unauthenticated_view_login_button": "Συνδεθείτε στον λογαριασμό σας",
"version": "Έκδοση: {{version}}", "version": "Έκδοση: {{version}}",
"video_tile": {
"presenter_label": "{{displayName}} παρουσιάζει"
},
"waiting_for_participants": "Αναμονή για άλλους συμμετέχοντες…" "waiting_for_participants": "Αναμονή για άλλους συμμετέχοντες…"
} }

View File

@@ -34,10 +34,8 @@
"settings": "Ajustes", "settings": "Ajustes",
"username": "Nombre de usuario" "username": "Nombre de usuario"
}, },
"exit_fullscreen_button_label": "Salir de pantalla completa",
"full_screen_view_description": "<0>Subir los registros de depuración nos ayudará a encontrar el problema.</0>", "full_screen_view_description": "<0>Subir los registros de depuración nos ayudará a encontrar el problema.</0>",
"full_screen_view_h1": "<0>Ups, algo ha salido mal.</0>", "full_screen_view_h1": "<0>Ups, algo ha salido mal.</0>",
"fullscreen_button_label": "Pantalla completa",
"header_label": "Inicio de Element Call", "header_label": "Inicio de Element Call",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "Si, unirse a la llamada", "join_button": "Si, unirse a la llamada",
@@ -48,7 +46,6 @@
"lobby": { "lobby": {
"join_button": "Unirse a la llamada" "join_button": "Unirse a la llamada"
}, },
"local_volume_label": "Volumen local",
"logging_in": "Iniciando sesión…", "logging_in": "Iniciando sesión…",
"login_auth_links": "<0>Crear una cuenta</0> o <2>Acceder como invitado</2>", "login_auth_links": "<0>Crear una cuenta</0> o <2>Acceder como invitado</2>",
"login_title": "Iniciar sesión", "login_title": "Iniciar sesión",
@@ -95,8 +92,5 @@
"unauthenticated_view_eula_caption": "Al hacer clic en \"Comenzar\", aceptas nuestro <2>Contrato de Licencia de Usuario Final (CLUF)</2>", "unauthenticated_view_eula_caption": "Al hacer clic en \"Comenzar\", aceptas nuestro <2>Contrato de Licencia de Usuario Final (CLUF)</2>",
"unauthenticated_view_login_button": "Iniciar sesión en tu cuenta", "unauthenticated_view_login_button": "Iniciar sesión en tu cuenta",
"version": "Versión: {{version}}", "version": "Versión: {{version}}",
"video_tile": {
"presenter_label": "{{displayName}} está presentando"
},
"waiting_for_participants": "Esperando a los otros participantes…" "waiting_for_participants": "Esperando a los otros participantes…"
} }

View File

@@ -52,10 +52,8 @@
"username": "Kasutajanimi" "username": "Kasutajanimi"
}, },
"disconnected_banner": "Võrguühendus serveriga on katkenud.", "disconnected_banner": "Võrguühendus serveriga on katkenud.",
"exit_fullscreen_button_label": "Välju täisekraanivaatest",
"full_screen_view_description": "<0>Kui saadad meile vealogid, siis on lihtsam vea põhjust otsida.</0>", "full_screen_view_description": "<0>Kui saadad meile vealogid, siis on lihtsam vea põhjust otsida.</0>",
"full_screen_view_h1": "<0>Ohoo, midagi on nüüd katki.</0>", "full_screen_view_h1": "<0>Ohoo, midagi on nüüd katki.</0>",
"fullscreen_button_label": "Täisekraan",
"group_call_loader_failed_heading": "Kõnet ei leidu", "group_call_loader_failed_heading": "Kõnet ei leidu",
"group_call_loader_failed_text": "Kõned on nüüd läbivalt krüptitud ning need pead looma kodulehelt. Sellega tagad, et kõik kasutavad samu krüptovõtmeid.", "group_call_loader_failed_text": "Kõned on nüüd läbivalt krüptitud ning need pead looma kodulehelt. Sellega tagad, et kõik kasutavad samu krüptovõtmeid.",
"hangup_button_label": "Lõpeta kõne", "hangup_button_label": "Lõpeta kõne",
@@ -75,7 +73,6 @@
"join_button": "Kõnega liitumine", "join_button": "Kõnega liitumine",
"leave_button": "Tagasi hiljutiste kõnede juurde" "leave_button": "Tagasi hiljutiste kõnede juurde"
}, },
"local_volume_label": "Kohalik helitugevus",
"logging_in": "Sisselogimine …", "logging_in": "Sisselogimine …",
"login_auth_links": "<0>Loo konto</0> Või <2>Sisene külalisena</2>", "login_auth_links": "<0>Loo konto</0> Või <2>Sisene külalisena</2>",
"login_title": "Sisselogimine", "login_title": "Sisselogimine",
@@ -133,7 +130,6 @@
"unmute_microphone_button_label": "Lülita mikrofon sisse", "unmute_microphone_button_label": "Lülita mikrofon sisse",
"version": "Versioon: {{version}}", "version": "Versioon: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} on esitlemas",
"sfu_participant_local": "Sina" "sfu_participant_local": "Sina"
}, },
"waiting_for_participants": "Ootame teiste osalejate lisandumist…" "waiting_for_participants": "Ootame teiste osalejate lisandumist…"

View File

@@ -32,8 +32,6 @@
"username": "نام کاربری", "username": "نام کاربری",
"video": "ویدیو" "video": "ویدیو"
}, },
"exit_fullscreen_button_label": "خروج از حالت تمام صفحه",
"fullscreen_button_label": "تمام صحفه",
"header_label": "خانهٔ تماس المنت", "header_label": "خانهٔ تماس المنت",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "بله، به تماس بپیوندید", "join_button": "بله، به تماس بپیوندید",
@@ -44,7 +42,6 @@
"lobby": { "lobby": {
"join_button": "پیوستن به تماس" "join_button": "پیوستن به تماس"
}, },
"local_volume_label": "حجم داخلی",
"logging_in": "ورود…", "logging_in": "ورود…",
"login_auth_links": "<0>ساخت حساب کاربری</0> Or <2>دسترسی به عنوان میهمان</2>", "login_auth_links": "<0>ساخت حساب کاربری</0> Or <2>دسترسی به عنوان میهمان</2>",
"login_title": "ورود", "login_title": "ورود",

View File

@@ -50,10 +50,8 @@
"video": "Vidéo" "video": "Vidéo"
}, },
"disconnected_banner": "La connexion avec le serveur a été perdue.", "disconnected_banner": "La connexion avec le serveur a été perdue.",
"exit_fullscreen_button_label": "Quitter le plein écran",
"full_screen_view_description": "<0>Soumettre les journaux de débogage nous aidera à déterminer le problème.</0>", "full_screen_view_description": "<0>Soumettre les journaux de débogage nous aidera à déterminer le problème.</0>",
"full_screen_view_h1": "<0>Oups, quelque chose sest mal passé.</0>", "full_screen_view_h1": "<0>Oups, quelque chose sest mal passé.</0>",
"fullscreen_button_label": "Plein écran",
"group_call_loader_failed_heading": "Appel non trouvé", "group_call_loader_failed_heading": "Appel non trouvé",
"group_call_loader_failed_text": "Les appels sont maintenant chiffrés de bout-en-bout et doivent être créés depuis la page daccueil. Cela permet dêtre sûr que tout le monde utilise la même clé de chiffrement.", "group_call_loader_failed_text": "Les appels sont maintenant chiffrés de bout-en-bout et doivent être créés depuis la page daccueil. Cela permet dêtre sûr que tout le monde utilise la même clé de chiffrement.",
"hangup_button_label": "Terminer lappel", "hangup_button_label": "Terminer lappel",
@@ -73,7 +71,6 @@
"join_button": "Rejoindre lappel", "join_button": "Rejoindre lappel",
"leave_button": "Revenir à lhistorique des appels" "leave_button": "Revenir à lhistorique des appels"
}, },
"local_volume_label": "Volume local",
"logging_in": "Connexion…", "logging_in": "Connexion…",
"login_auth_links": "<0>Créer un compte</0> Or <2>Accès invité</2>", "login_auth_links": "<0>Créer un compte</0> Or <2>Accès invité</2>",
"login_title": "Connexion", "login_title": "Connexion",
@@ -131,7 +128,6 @@
"unmute_microphone_button_label": "Allumer le microphone", "unmute_microphone_button_label": "Allumer le microphone",
"version": "Version : {{version}}", "version": "Version : {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} est à lécran",
"sfu_participant_local": "Vous" "sfu_participant_local": "Vous"
}, },
"waiting_for_participants": "En attente dautres participants…" "waiting_for_participants": "En attente dautres participants…"

View File

@@ -50,10 +50,8 @@
"username": "Nama pengguna" "username": "Nama pengguna"
}, },
"disconnected_banner": "Koneksi ke server telah hilang.", "disconnected_banner": "Koneksi ke server telah hilang.",
"exit_fullscreen_button_label": "Keluar dari layar penuh",
"full_screen_view_description": "<0>Mengirim catatan pengawakutuan akan membantu kami melacak masalahnya.</0>", "full_screen_view_description": "<0>Mengirim catatan pengawakutuan akan membantu kami melacak masalahnya.</0>",
"full_screen_view_h1": "<0>Aduh, ada yang salah.</0>", "full_screen_view_h1": "<0>Aduh, ada yang salah.</0>",
"fullscreen_button_label": "Layar penuh",
"group_call_loader_failed_heading": "Panggilan tidak ditemukan", "group_call_loader_failed_heading": "Panggilan tidak ditemukan",
"group_call_loader_failed_text": "Panggilan sekarang terenkripsi secara ujung ke ujung dan harus dibuat dari laman beranda. Ini memastikan bahwa semuanya menggunakan kunci enkripsi yang sama.", "group_call_loader_failed_text": "Panggilan sekarang terenkripsi secara ujung ke ujung dan harus dibuat dari laman beranda. Ini memastikan bahwa semuanya menggunakan kunci enkripsi yang sama.",
"hangup_button_label": "Akhiri panggilan", "hangup_button_label": "Akhiri panggilan",
@@ -74,7 +72,6 @@
"join_button": "Bergabung ke panggilan", "join_button": "Bergabung ke panggilan",
"leave_button": "Kembali ke terkini" "leave_button": "Kembali ke terkini"
}, },
"local_volume_label": "Volume lokal",
"logging_in": "Memasuki…", "logging_in": "Memasuki…",
"login_auth_links": "<0>Buat akun</0> Atau <2>Akses sebagai tamu</2>", "login_auth_links": "<0>Buat akun</0> Atau <2>Akses sebagai tamu</2>",
"login_title": "Masuk", "login_title": "Masuk",
@@ -132,7 +129,6 @@
"unmute_microphone_button_label": "Nyalakan mikrofon", "unmute_microphone_button_label": "Nyalakan mikrofon",
"version": "Versi: {{version}}", "version": "Versi: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} sedang menampilkan",
"sfu_participant_local": "Anda" "sfu_participant_local": "Anda"
}, },
"waiting_for_participants": "Menunggu peserta lain…" "waiting_for_participants": "Menunggu peserta lain…"

View File

@@ -48,10 +48,8 @@
"username": "Nome utente" "username": "Nome utente"
}, },
"disconnected_banner": "La connessione al server è stata persa.", "disconnected_banner": "La connessione al server è stata persa.",
"exit_fullscreen_button_label": "Esci da schermo intero",
"full_screen_view_description": "<0>L'invio di registri di debug ci aiuterà ad individuare il problema.</0>", "full_screen_view_description": "<0>L'invio di registri di debug ci aiuterà ad individuare il problema.</0>",
"full_screen_view_h1": "<0>Ops, qualcosa è andato storto.</0>", "full_screen_view_h1": "<0>Ops, qualcosa è andato storto.</0>",
"fullscreen_button_label": "Schermo intero",
"group_call_loader_failed_heading": "Chiamata non trovata", "group_call_loader_failed_heading": "Chiamata non trovata",
"group_call_loader_failed_text": "Le chiamate ora sono cifrate end-to-end e devono essere create dalla pagina principale. Ciò assicura che chiunque usi la stessa chiave di crittografia.", "group_call_loader_failed_text": "Le chiamate ora sono cifrate end-to-end e devono essere create dalla pagina principale. Ciò assicura che chiunque usi la stessa chiave di crittografia.",
"hangup_button_label": "Termina chiamata", "hangup_button_label": "Termina chiamata",
@@ -72,7 +70,6 @@
"join_button": "Entra in chiamata", "join_button": "Entra in chiamata",
"leave_button": "Torna ai recenti" "leave_button": "Torna ai recenti"
}, },
"local_volume_label": "Volume locale",
"logging_in": "Accesso…", "logging_in": "Accesso…",
"login_auth_links": "<0>Crea un profilo</0> o <2>Accedi come ospite</2>", "login_auth_links": "<0>Crea un profilo</0> o <2>Accedi come ospite</2>",
"login_title": "Accedi", "login_title": "Accedi",
@@ -129,7 +126,6 @@
"unmute_microphone_button_label": "Riaccendi il microfono", "unmute_microphone_button_label": "Riaccendi il microfono",
"version": "Versione: {{version}}", "version": "Versione: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} sta presentando",
"sfu_participant_local": "Tu" "sfu_participant_local": "Tu"
}, },
"waiting_for_participants": "In attesa di altri partecipanti…" "waiting_for_participants": "In attesa di altri partecipanti…"

View File

@@ -30,9 +30,7 @@
"username": "ユーザー名", "username": "ユーザー名",
"video": "ビデオ" "video": "ビデオ"
}, },
"exit_fullscreen_button_label": "全画面表示を終了",
"full_screen_view_h1": "<0>何かがうまく行きませんでした。</0>", "full_screen_view_h1": "<0>何かがうまく行きませんでした。</0>",
"fullscreen_button_label": "全画面表示",
"header_label": "Element Call ホーム", "header_label": "Element Call ホーム",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "はい、通話に参加", "join_button": "はい、通話に参加",

View File

@@ -40,10 +40,8 @@
"username": "Lietotājvārds" "username": "Lietotājvārds"
}, },
"disconnected_banner": "Ir zaudēts savienojums ar serveri.", "disconnected_banner": "Ir zaudēts savienojums ar serveri.",
"exit_fullscreen_button_label": "Iziet no pilnekrāna",
"full_screen_view_description": "<0>Atkļūdošanas žurnāla ierakstu iesūtīšana palīdzēs mums atklāt nepilnību.</0>", "full_screen_view_description": "<0>Atkļūdošanas žurnāla ierakstu iesūtīšana palīdzēs mums atklāt nepilnību.</0>",
"full_screen_view_h1": "<0>Ak vai, kaut kas nogāja greizi!</0>", "full_screen_view_h1": "<0>Ak vai, kaut kas nogāja greizi!</0>",
"fullscreen_button_label": "Pilnekrāns",
"header_label": "Element Call sākums", "header_label": "Element Call sākums",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "Jā, pievienoties zvanam", "join_button": "Jā, pievienoties zvanam",
@@ -54,7 +52,6 @@
"lobby": { "lobby": {
"join_button": "Pievienoties zvanam" "join_button": "Pievienoties zvanam"
}, },
"local_volume_label": "Vietējais skaļums",
"logging_in": "Piesakās…", "logging_in": "Piesakās…",
"login_auth_links": "<0>Izveidot kontu</0> vai <2>Piekļūt kā viesim</2>", "login_auth_links": "<0>Izveidot kontu</0> vai <2>Piekļūt kā viesim</2>",
"login_title": "Pieteikties", "login_title": "Pieteikties",
@@ -103,8 +100,5 @@
"unauthenticated_view_eula_caption": "Klikšķināšana uz \"Aiziet\" apliecina piekrišanu mūsu <2>galalietotāja licencēšanas nolīgumam (GLLN)</2>", "unauthenticated_view_eula_caption": "Klikšķināšana uz \"Aiziet\" apliecina piekrišanu mūsu <2>galalietotāja licencēšanas nolīgumam (GLLN)</2>",
"unauthenticated_view_login_button": "Pieteikties kontā", "unauthenticated_view_login_button": "Pieteikties kontā",
"version": "Versija: {{version}}", "version": "Versija: {{version}}",
"video_tile": {
"presenter_label": "{{displayName}} uzstājas"
},
"waiting_for_participants": "Gaida citus dalībniekus…" "waiting_for_participants": "Gaida citus dalībniekus…"
} }

View File

@@ -53,10 +53,8 @@
"video": "Wideo" "video": "Wideo"
}, },
"disconnected_banner": "Utracono połączenie z serwerem.", "disconnected_banner": "Utracono połączenie z serwerem.",
"exit_fullscreen_button_label": "Opuść pełny ekran",
"full_screen_view_description": "<0>Wysłanie dzienników debuggowania pomoże nam ustalić przyczynę problemu.</0>", "full_screen_view_description": "<0>Wysłanie dzienników debuggowania pomoże nam ustalić przyczynę problemu.</0>",
"full_screen_view_h1": "<0>Ojej, coś poszło nie tak.</0>", "full_screen_view_h1": "<0>Ojej, coś poszło nie tak.</0>",
"fullscreen_button_label": "Pełny ekran",
"group_call_loader_failed_heading": "Nie znaleziono połączenia", "group_call_loader_failed_heading": "Nie znaleziono połączenia",
"group_call_loader_failed_text": "Połączenia są teraz szyfrowane end-to-end i muszą zostać utworzone ze strony głównej. Pomaga to upewnić się, że każdy korzysta z tego samego klucza szyfrującego.", "group_call_loader_failed_text": "Połączenia są teraz szyfrowane end-to-end i muszą zostać utworzone ze strony głównej. Pomaga to upewnić się, że każdy korzysta z tego samego klucza szyfrującego.",
"hangup_button_label": "Zakończ połączenie", "hangup_button_label": "Zakończ połączenie",
@@ -77,7 +75,6 @@
"join_button": "Dołącz do połączenia", "join_button": "Dołącz do połączenia",
"leave_button": "Wróć do ostatnie" "leave_button": "Wróć do ostatnie"
}, },
"local_volume_label": "Głośność lokalna",
"logging_in": "Logowanie…", "logging_in": "Logowanie…",
"login_auth_links": "<0>Utwórz konto</0> lub <2>Dołącz jako gość</2>", "login_auth_links": "<0>Utwórz konto</0> lub <2>Dołącz jako gość</2>",
"login_title": "Zaloguj się", "login_title": "Zaloguj się",
@@ -135,7 +132,6 @@
"unmute_microphone_button_label": "Odcisz mikrofon", "unmute_microphone_button_label": "Odcisz mikrofon",
"version": "Wersja: {{version}}", "version": "Wersja: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} prezentuje",
"sfu_participant_local": "Ty" "sfu_participant_local": "Ty"
}, },
"waiting_for_participants": "Oczekiwanie na pozostałych uczestników…" "waiting_for_participants": "Oczekiwanie na pozostałych uczestników…"

View File

@@ -38,10 +38,8 @@
"username": "Имя пользователя", "username": "Имя пользователя",
"video": "Видео" "video": "Видео"
}, },
"exit_fullscreen_button_label": "Выйти из полноэкранного режима",
"full_screen_view_description": "<0>Отправка журналов поможет нам найти и устранить проблему.</0>", "full_screen_view_description": "<0>Отправка журналов поможет нам найти и устранить проблему.</0>",
"full_screen_view_h1": "<0>Упс, что-то пошло не так.</0>", "full_screen_view_h1": "<0>Упс, что-то пошло не так.</0>",
"fullscreen_button_label": "Полноэкранный режим",
"header_label": "Главная Element Call", "header_label": "Главная Element Call",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "Да, присоединиться", "join_button": "Да, присоединиться",
@@ -52,7 +50,6 @@
"lobby": { "lobby": {
"join_button": "Присоединиться" "join_button": "Присоединиться"
}, },
"local_volume_label": "Местная громкость",
"logging_in": "Вход…", "logging_in": "Вход…",
"login_auth_links": "<0>Создать аккаунт</0> или <2>Зайти как гость</2>", "login_auth_links": "<0>Создать аккаунт</0> или <2>Зайти как гость</2>",
"login_title": "Вход", "login_title": "Вход",
@@ -96,8 +93,5 @@
"unauthenticated_view_body": "Ещё не зарегистрированы? <2>Создайте аккаунт</2>", "unauthenticated_view_body": "Ещё не зарегистрированы? <2>Создайте аккаунт</2>",
"unauthenticated_view_login_button": "Войдите в свой аккаунт", "unauthenticated_view_login_button": "Войдите в свой аккаунт",
"version": "Версия: {{version}}", "version": "Версия: {{version}}",
"video_tile": {
"presenter_label": "{{displayName}} представляет"
},
"waiting_for_participants": "Ожидание других участников…" "waiting_for_participants": "Ожидание других участников…"
} }

View File

@@ -51,10 +51,8 @@
"username": "Meno používateľa" "username": "Meno používateľa"
}, },
"disconnected_banner": "Spojenie so serverom sa stratilo.", "disconnected_banner": "Spojenie so serverom sa stratilo.",
"exit_fullscreen_button_label": "Ukončiť zobrazenie na celú obrazovku",
"full_screen_view_description": "<0>Odoslanie záznamov ladenia nám pomôže nájsť problém.</0>", "full_screen_view_description": "<0>Odoslanie záznamov ladenia nám pomôže nájsť problém.</0>",
"full_screen_view_h1": "<0>Hups, niečo sa pokazilo.</0>", "full_screen_view_h1": "<0>Hups, niečo sa pokazilo.</0>",
"fullscreen_button_label": "Zobrazenie na celú obrazovku",
"group_call_loader_failed_heading": "Hovor nebol nájdený", "group_call_loader_failed_heading": "Hovor nebol nájdený",
"group_call_loader_failed_text": "Hovory sú teraz end-to-end šifrované a je potrebné ich vytvoriť z domovskej stránky. To pomáha zabezpečiť, aby všetci používali rovnaký šifrovací kľúč.", "group_call_loader_failed_text": "Hovory sú teraz end-to-end šifrované a je potrebné ich vytvoriť z domovskej stránky. To pomáha zabezpečiť, aby všetci používali rovnaký šifrovací kľúč.",
"hangup_button_label": "Ukončiť hovor", "hangup_button_label": "Ukončiť hovor",
@@ -75,7 +73,6 @@
"join_button": "Pripojiť sa k hovoru", "join_button": "Pripojiť sa k hovoru",
"leave_button": "Späť k nedávnym" "leave_button": "Späť k nedávnym"
}, },
"local_volume_label": "Lokálna hlasitosť",
"logging_in": "Prihlasovanie…", "logging_in": "Prihlasovanie…",
"login_auth_links": "<0>Vytvoriť konto</0> Alebo <2>Prihlásiť sa ako hosť</2>", "login_auth_links": "<0>Vytvoriť konto</0> Alebo <2>Prihlásiť sa ako hosť</2>",
"login_title": "Prihlásiť sa", "login_title": "Prihlásiť sa",
@@ -133,7 +130,6 @@
"unmute_microphone_button_label": "Zrušiť stlmenie mikrofónu", "unmute_microphone_button_label": "Zrušiť stlmenie mikrofónu",
"version": "Verzia: {{version}}", "version": "Verzia: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} prezentuje",
"sfu_participant_local": "Vy" "sfu_participant_local": "Vy"
}, },
"waiting_for_participants": "Čaká sa na ďalších účastníkov…" "waiting_for_participants": "Čaká sa na ďalších účastníkov…"

View File

@@ -3,8 +3,5 @@
"headline": "{{displayName}}, ditt samtal har avslutats." "headline": "{{displayName}}, ditt samtal har avslutats."
}, },
"star_rating_input_label_one": "{{count}} stjärna", "star_rating_input_label_one": "{{count}} stjärna",
"star_rating_input_label_other": "{{count}} stjärnor", "star_rating_input_label_other": "{{count}} stjärnor"
"video_tile": {
"presenter_label": "{{displayName}} presenterar"
}
} }

View File

@@ -24,8 +24,6 @@
"password": "Parola", "password": "Parola",
"settings": "Ayarlar" "settings": "Ayarlar"
}, },
"exit_fullscreen_button_label": "Tam ekranı terk et",
"fullscreen_button_label": "Tam ekran",
"join_existing_call_modal": { "join_existing_call_modal": {
"text": "Bu arama zaten var, katılmak ister misiniz?", "text": "Bu arama zaten var, katılmak ister misiniz?",
"title": "Mevcut aramaya katıl?" "title": "Mevcut aramaya katıl?"
@@ -33,7 +31,6 @@
"lobby": { "lobby": {
"join_button": "Aramaya katıl" "join_button": "Aramaya katıl"
}, },
"local_volume_label": "Yerel ses seviyesi",
"logging_in": "Giriliyor…", "logging_in": "Giriliyor…",
"login_auth_links": "<0>Hesap oluştur</0> yahut <2>Konuk olarak gir</2>", "login_auth_links": "<0>Hesap oluştur</0> yahut <2>Konuk olarak gir</2>",
"login_title": "Gir", "login_title": "Gir",

View File

@@ -53,10 +53,8 @@
"video": "Відео" "video": "Відео"
}, },
"disconnected_banner": "Втрачено зв'язок з сервером.", "disconnected_banner": "Втрачено зв'язок з сервером.",
"exit_fullscreen_button_label": "Вийти з повноекранного режиму",
"full_screen_view_description": "<0>Надсилання журналів налагодження допоможе нам виявити проблему.</0>", "full_screen_view_description": "<0>Надсилання журналів налагодження допоможе нам виявити проблему.</0>",
"full_screen_view_h1": "<0>Йой, щось пішло не за планом.</0>", "full_screen_view_h1": "<0>Йой, щось пішло не за планом.</0>",
"fullscreen_button_label": "Повноекранний режим",
"group_call_loader_failed_heading": "Виклик не знайдено", "group_call_loader_failed_heading": "Виклик не знайдено",
"group_call_loader_failed_text": "Відтепер виклики захищено наскрізним шифруванням, і їх потрібно створювати з домашньої сторінки. Це допомагає переконатися, що всі користувачі використовують один і той самий ключ шифрування.", "group_call_loader_failed_text": "Відтепер виклики захищено наскрізним шифруванням, і їх потрібно створювати з домашньої сторінки. Це допомагає переконатися, що всі користувачі використовують один і той самий ключ шифрування.",
"hangup_button_label": "Завершити виклик", "hangup_button_label": "Завершити виклик",
@@ -77,7 +75,6 @@
"join_button": "Приєднатися до виклику", "join_button": "Приєднатися до виклику",
"leave_button": "Повернутися до недавніх" "leave_button": "Повернутися до недавніх"
}, },
"local_volume_label": "Локальна гучність",
"logging_in": "Вхід…", "logging_in": "Вхід…",
"login_auth_links": "<0>Створити обліковий запис</0> або <2>Отримати доступ як гість</2>", "login_auth_links": "<0>Створити обліковий запис</0> або <2>Отримати доступ як гість</2>",
"login_title": "Увійти", "login_title": "Увійти",
@@ -135,7 +132,6 @@
"unmute_microphone_button_label": "Увімкнути мікрофон", "unmute_microphone_button_label": "Увімкнути мікрофон",
"version": "Версія: {{version}}", "version": "Версія: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} представляє",
"sfu_participant_local": "Ви" "sfu_participant_local": "Ви"
}, },
"waiting_for_participants": "Очікування на інших учасників…" "waiting_for_participants": "Очікування на інших учасників…"

View File

@@ -29,10 +29,8 @@
"username": "Tên người dùng", "username": "Tên người dùng",
"video": "Truyền hình" "video": "Truyền hình"
}, },
"exit_fullscreen_button_label": "Rời chế độ toàn màn hình",
"full_screen_view_description": "<0>Gửi nhật ký gỡ lỗi sẽ giúp chúng tôi theo dõi vấn đề.</0>", "full_screen_view_description": "<0>Gửi nhật ký gỡ lỗi sẽ giúp chúng tôi theo dõi vấn đề.</0>",
"full_screen_view_h1": "<0>Ối, có cái gì đó sai.</0>", "full_screen_view_h1": "<0>Ối, có cái gì đó sai.</0>",
"fullscreen_button_label": "Toàn màn hình",
"join_existing_call_modal": { "join_existing_call_modal": {
"join_button": "Vâng, tham gia cuộc gọi", "join_button": "Vâng, tham gia cuộc gọi",
"text": "Cuộc gọi đã tồn tại, bạn có muốn tham gia không?", "text": "Cuộc gọi đã tồn tại, bạn có muốn tham gia không?",
@@ -73,8 +71,5 @@
"unauthenticated_view_body": "Chưa đăng ký? <2>Tạo tài khoản</2>", "unauthenticated_view_body": "Chưa đăng ký? <2>Tạo tài khoản</2>",
"unauthenticated_view_login_button": "Đăng nhập vào tài khoản của bạn", "unauthenticated_view_login_button": "Đăng nhập vào tài khoản của bạn",
"version": "Phiên bản: {{version}}", "version": "Phiên bản: {{version}}",
"video_tile": {
"presenter_label": "{{displayName}} đang trình bày"
},
"waiting_for_participants": "Đang đợi những người khác…" "waiting_for_participants": "Đang đợi những người khác…"
} }

View File

@@ -51,10 +51,8 @@
"video": "视频" "video": "视频"
}, },
"disconnected_banner": "与服务器的连接中断。", "disconnected_banner": "与服务器的连接中断。",
"exit_fullscreen_button_label": "退出全屏",
"full_screen_view_description": "<0>提交日志以帮助我们修复问题。</0>", "full_screen_view_description": "<0>提交日志以帮助我们修复问题。</0>",
"full_screen_view_h1": "<0>哎哟,出问题了。</0>", "full_screen_view_h1": "<0>哎哟,出问题了。</0>",
"fullscreen_button_label": "全屏",
"group_call_loader_failed_heading": "未找到通话", "group_call_loader_failed_heading": "未找到通话",
"group_call_loader_failed_text": "现在,通话是端对端加密的,需要从主页创建。这有助于确保每个人都使用相同的加密密钥。", "group_call_loader_failed_text": "现在,通话是端对端加密的,需要从主页创建。这有助于确保每个人都使用相同的加密密钥。",
"hangup_button_label": "通话结束", "hangup_button_label": "通话结束",
@@ -70,7 +68,6 @@
"join_button": "加入通话", "join_button": "加入通话",
"leave_button": "返回最近通话" "leave_button": "返回最近通话"
}, },
"local_volume_label": "本地音量",
"logging_in": "登录中……", "logging_in": "登录中……",
"login_auth_links": "<0>创建账户</0> Or <2>以访客身份继续</2>", "login_auth_links": "<0>创建账户</0> Or <2>以访客身份继续</2>",
"login_title": "登录", "login_title": "登录",
@@ -128,7 +125,6 @@
"unmute_microphone_button_label": "取消麦克风静音", "unmute_microphone_button_label": "取消麦克风静音",
"version": "版本:{{version}}", "version": "版本:{{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}}正在展示",
"sfu_participant_local": "你" "sfu_participant_local": "你"
}, },
"waiting_for_participants": "等待其他参与者……" "waiting_for_participants": "等待其他参与者……"

View File

@@ -53,10 +53,8 @@
"video": "視訊" "video": "視訊"
}, },
"disconnected_banner": "到伺服器的連線已遺失。", "disconnected_banner": "到伺服器的連線已遺失。",
"exit_fullscreen_button_label": "退出全螢幕",
"full_screen_view_description": "<0>送出除錯紀錄,可幫助我們修正問題。</0>", "full_screen_view_description": "<0>送出除錯紀錄,可幫助我們修正問題。</0>",
"full_screen_view_h1": "<0>喔喔,有些地方怪怪的。</0>", "full_screen_view_h1": "<0>喔喔,有些地方怪怪的。</0>",
"fullscreen_button_label": "全螢幕",
"group_call_loader_failed_heading": "找不到通話", "group_call_loader_failed_heading": "找不到通話",
"group_call_loader_failed_text": "通話現在是端對端加密的,必須從首頁建立。這有助於確保每個人都使用相同的加密金鑰。", "group_call_loader_failed_text": "通話現在是端對端加密的,必須從首頁建立。這有助於確保每個人都使用相同的加密金鑰。",
"hangup_button_label": "結束通話", "hangup_button_label": "結束通話",
@@ -77,7 +75,6 @@
"join_button": "加入通話", "join_button": "加入通話",
"leave_button": "回到最近的通話" "leave_button": "回到最近的通話"
}, },
"local_volume_label": "您的音量",
"logging_in": "登入中…", "logging_in": "登入中…",
"login_auth_links": "<0>建立帳號</0> 或<2>以訪客身份登入</2>", "login_auth_links": "<0>建立帳號</0> 或<2>以訪客身份登入</2>",
"login_title": "登入", "login_title": "登入",
@@ -135,7 +132,6 @@
"unmute_microphone_button_label": "將麥克風取消靜音", "unmute_microphone_button_label": "將麥克風取消靜音",
"version": "版本: {{version}}", "version": "版本: {{version}}",
"video_tile": { "video_tile": {
"presenter_label": "{{displayName}} 正在展示",
"sfu_participant_local": "您" "sfu_participant_local": "您"
}, },
"waiting_for_participants": "等待其他參加者…" "waiting_for_participants": "等待其他參加者…"

View File

@@ -72,7 +72,9 @@ export const App: FC<AppProps> = ({ history }) => {
const [loaded, setLoaded] = useState(false); const [loaded, setLoaded] = useState(false);
useEffect(() => { useEffect(() => {
Initializer.init()?.then(() => { Initializer.init()?.then(() => {
if (loaded) return;
setLoaded(true); setLoaded(true);
widget?.api.sendContentLoaded();
}); });
}); });

View File

@@ -27,6 +27,7 @@ import styles from "./FullScreenView.module.css";
import { TranslatedError } from "./TranslatedError"; import { TranslatedError } from "./TranslatedError";
import { Config } from "./config/Config"; import { Config } from "./config/Config";
import { RageshakeButton } from "./settings/RageshakeButton"; import { RageshakeButton } from "./settings/RageshakeButton";
import { useUrlParams } from "./UrlParams";
interface FullScreenViewProps { interface FullScreenViewProps {
className?: string; className?: string;
@@ -37,12 +38,11 @@ export const FullScreenView: FC<FullScreenViewProps> = ({
className, className,
children, children,
}) => { }) => {
const { hideHeader } = useUrlParams();
return ( return (
<div className={classNames(styles.page, className)}> <div className={classNames(styles.page, className)}>
<Header> <Header>
<LeftNav> <LeftNav>{!hideHeader && <HeaderLogo />}</LeftNav>
<HeaderLogo />
</LeftNav>
<RightNav /> <RightNav />
</Header> </Header>
<div className={styles.container}> <div className={styles.container}>

View File

@@ -31,6 +31,7 @@ import {
UndecryptableToDeviceEventTracker, UndecryptableToDeviceEventTracker,
QualitySurveyEventTracker, QualitySurveyEventTracker,
CallDisconnectedEventTracker, CallDisconnectedEventTracker,
CallConnectDurationTracker,
} from "./PosthogEvents"; } from "./PosthogEvents";
import { Config } from "../config/Config"; import { Config } from "../config/Config";
import { getUrlParams } from "../UrlParams"; import { getUrlParams } from "../UrlParams";
@@ -444,4 +445,5 @@ export class PosthogAnalytics {
public eventUndecryptableToDevice = new UndecryptableToDeviceEventTracker(); public eventUndecryptableToDevice = new UndecryptableToDeviceEventTracker();
public eventQualitySurvey = new QualitySurveyEventTracker(); public eventQualitySurvey = new QualitySurveyEventTracker();
public eventCallDisconnected = new CallDisconnectedEventTracker(); public eventCallDisconnected = new CallDisconnectedEventTracker();
public eventCallConnectDuration = new CallConnectDurationTracker();
} }

View File

@@ -15,6 +15,7 @@ limitations under the License.
*/ */
import { DisconnectReason } from "livekit-client"; import { DisconnectReason } from "livekit-client";
import { logger } from "matrix-js-sdk/src/logger";
import { import {
IPosthogEvent, IPosthogEvent,
@@ -201,3 +202,38 @@ export class CallDisconnectedEventTracker {
}); });
} }
} }
interface CallConnectDuration extends IPosthogEvent {
eventName: "CallConnectDuration";
totalDuration: number;
websocketDuration: number;
peerConnectionDuration: number;
}
export class CallConnectDurationTracker {
private connectStart = 0;
private websocketConnected = 0;
public cacheConnectStart(): void {
this.connectStart = Date.now();
}
public cacheWsConnect(): void {
this.websocketConnected = Date.now();
}
public track(options = { log: false }): void {
const now = Date.now();
const totalDuration = now - this.connectStart;
const websocketDuration = this.websocketConnected - this.connectStart;
const peerConnectionDuration = now - this.websocketConnected;
PosthogAnalytics.instance.trackEvent<CallConnectDuration>({
eventName: "CallConnectDuration",
totalDuration,
websocketDuration,
peerConnectionDuration,
});
if (options.log)
logger.log(
`Time to connect:\ntotal: ${totalDuration}ms\npeerConnection: ${websocketDuration}ms\nwebsocket: ${peerConnectionDuration}ms`,
);
}
}

View File

@@ -82,7 +82,12 @@ export const LoginPage: FC = () => {
}, },
[login, location, history, homeserver, setClient], [login, location, history, homeserver, setClient],
); );
// we need to limit the length of the homserver name to not cover the whole loginview input with the string.
let shortendHomeserverName = Config.defaultServerName()?.slice(0, 25);
shortendHomeserverName =
shortendHomeserverName?.length !== Config.defaultServerName()?.length
? shortendHomeserverName + "..."
: shortendHomeserverName;
return ( return (
<> <>
<div className={styles.container}> <div className={styles.container}>
@@ -102,7 +107,7 @@ export const LoginPage: FC = () => {
autoCorrect="off" autoCorrect="off"
autoCapitalize="none" autoCapitalize="none"
prefix="@" prefix="@"
suffix={`:${Config.defaultServerName()}`} suffix={`:${shortendHomeserverName}`}
data-testid="login_username" data-testid="login_username"
/> />
</FieldRow> </FieldRow>

View File

@@ -21,6 +21,7 @@ import { createClient, MatrixClient } from "matrix-js-sdk/src/matrix";
import { initClient } from "../matrix-utils"; import { initClient } from "../matrix-utils";
import { Session } from "../ClientContext"; import { Session } from "../ClientContext";
import { Config } from "../config/Config"; import { Config } from "../config/Config";
import { widget } from "../widget";
export const useInteractiveRegistration = (): { export const useInteractiveRegistration = (): {
privacyPolicyUrl?: string; privacyPolicyUrl?: string;
@@ -48,6 +49,8 @@ export const useInteractiveRegistration = (): {
} }
useEffect(() => { useEffect(() => {
if (widget) return;
// An empty registerRequest is used to get the privacy policy and recaptcha key.
authClient.current!.registerRequest({}).catch((error) => { authClient.current!.registerRequest({}).catch((error) => {
setPrivacyPolicyUrl( setPrivacyPolicyUrl(
error.data?.params["m.login.terms"]?.policies?.privacy_policy?.en?.url, error.data?.params["m.login.terms"]?.policies?.privacy_policy?.en?.url,

View File

@@ -156,6 +156,12 @@ body {
margin: 0; margin: 0;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
-webkit-tap-highlight-color: transparent;
}
/* We use this to not render the page at all until we know the theme.*/
.no-theme {
opacity: 0;
} }
html, html,

View File

@@ -59,4 +59,5 @@ export const defaultLiveKitOptions: RoomOptions = {
stopLocalTrackOnUnpublish: true, stopLocalTrackOnUnpublish: true,
reconnectPolicy: new DefaultReconnectPolicy(), reconnectPolicy: new DefaultReconnectPolicy(),
disconnectOnPageLeave: true, disconnectOnPageLeave: true,
webAudioMix: false,
}; };

View File

@@ -27,6 +27,14 @@ import { logger } from "matrix-js-sdk/src/logger";
import * as Sentry from "@sentry/react"; import * as Sentry from "@sentry/react";
import { SFUConfig, sfuConfigEquals } from "./openIDSFU"; import { SFUConfig, sfuConfigEquals } from "./openIDSFU";
import { PosthogAnalytics } from "../analytics/PosthogAnalytics";
declare global {
interface Window {
peerConnectionTimeout?: number;
websocketTimeout?: number;
}
}
/* /*
* Additional values for states that a call can be in, beyond what livekit * Additional values for states that a call can be in, beyond what livekit
@@ -124,7 +132,21 @@ async function connectAndPublish(
micTrack: LocalTrack | undefined, micTrack: LocalTrack | undefined,
screenshareTracks: MediaStreamTrack[], screenshareTracks: MediaStreamTrack[],
): Promise<void> { ): Promise<void> {
await livekitRoom!.connect(sfuConfig!.url, sfuConfig!.jwt); const tracker = PosthogAnalytics.instance.eventCallConnectDuration;
// Track call connect duration
tracker.cacheConnectStart();
livekitRoom.once(RoomEvent.SignalConnected, tracker.cacheWsConnect);
await livekitRoom!.connect(sfuConfig!.url, sfuConfig!.jwt, {
// Due to stability issues on Firefox we are testing the effect of different
// timeouts, and allow these values to be set through the console
peerConnectionTimeout: window.peerConnectionTimeout ?? 45000,
websocketTimeout: window.websocketTimeout ?? 45000,
});
// remove listener in case the connect promise rejects before `SignalConnected` is emitted.
livekitRoom.off(RoomEvent.SignalConnected, tracker.cacheWsConnect);
tracker.track({ log: true });
if (micTrack) { if (micTrack) {
logger.info(`Publishing precreated mic track`); logger.info(`Publishing precreated mic track`);

View File

@@ -1,5 +1,5 @@
/* /*
Copyright 2023 New Vector Ltd Copyright 2023-2024 New Vector Ltd
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@@ -14,18 +14,17 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
*/ */
import { useEffect, useRef } from "react"; import { useRef } from "react";
import { BehaviorSubject, Observable } from "rxjs"; import { BehaviorSubject, Observable } from "rxjs";
/** /**
* React hook that creates an Observable from a changing value. The Observable * React hook that creates an Observable from a changing value. The Observable
* replays its current value upon subscription, emits whenever the value * replays its current value upon subscription and emits whenever the value
* changes, and completes when the component is unmounted. * changes.
*/ */
export function useObservable<T>(value: T): Observable<T> { export function useObservable<T>(value: T): Observable<T> {
const subject = useRef<BehaviorSubject<T>>(); const subject = useRef<BehaviorSubject<T>>();
subject.current ??= new BehaviorSubject(value); subject.current ??= new BehaviorSubject(value);
if (value !== subject.current.value) subject.current.next(value); if (value !== subject.current.value) subject.current.next(value);
useEffect(() => subject.current!.complete(), []);
return subject.current; return subject.current;
} }

View File

@@ -22,10 +22,9 @@ export const useTheme = (): void => {
const { theme: themeName } = useUrlParams(); const { theme: themeName } = useUrlParams();
const previousTheme = useRef<string | null>(document.body.classList.item(0)); const previousTheme = useRef<string | null>(document.body.classList.item(0));
useLayoutEffect(() => { useLayoutEffect(() => {
// Don't update the current theme if the url does not contain a theme prop. // If the url does not contain a theme props we default to "dark".
if (!themeName) return; const theme = themeName?.includes("light") ? "light" : "dark";
const theme = themeName.includes("light") ? "light" : "dark"; const themeHighContrast = themeName?.includes("high-contrast") ? "-hc" : "";
const themeHighContrast = themeName.includes("high-contrast") ? "-hc" : "";
const themeString = "cpd-theme-" + theme + themeHighContrast; const themeString = "cpd-theme-" + theme + themeHighContrast;
if (themeString !== previousTheme.current) { if (themeString !== previousTheme.current) {
document.body.classList.remove( document.body.classList.remove(
@@ -37,5 +36,6 @@ export const useTheme = (): void => {
document.body.classList.add(themeString); document.body.classList.add(themeString);
previousTheme.current = themeString; previousTheme.current = themeString;
} }
document.body.classList.remove("no-theme");
}, [previousTheme, themeName]); }, [previousTheme, themeName]);
}; };

View File

@@ -158,6 +158,8 @@ export const widget = ((): WidgetHelpers | null => {
useE2eForGroupCall: e2eEnabled, useE2eForGroupCall: e2eEnabled,
fallbackICEServerAllowed: allowIceFallback, fallbackICEServerAllowed: allowIceFallback,
}, },
// ContentLoaded event will be sent as soon as the theme is set (see useTheme.ts)
false,
); );
const clientPromise = new Promise<MatrixClient>((resolve) => { const clientPromise = new Promise<MatrixClient>((resolve) => {

View File

@@ -26,7 +26,7 @@
"./node_modules/livekit-client/dist/src/room/participant/Participant.d.ts" "./node_modules/livekit-client/dist/src/room/participant/Participant.d.ts"
], ],
"livekit-client/dist/src/proto/livekit_models_pb": [ "livekit-client/dist/src/proto/livekit_models_pb": [
"./node_modules/livekit-client/dist/src/proto/livekit_models_pb.d.ts" "./node_modules/@livekit/protocol/src/gen/livekit_models_pb.d.ts"
] ]
}, },

1061
yarn.lock

File diff suppressed because it is too large Load Diff