Compare commits

...

77 Commits

Author SHA1 Message Date
dependabot[bot]
0a728b77a8 chore(ci): bump actions/cache from 4.2.0 to 5.0.4
Bumps [actions/cache](https://github.com/actions/cache) from 4.2.0 to 5.0.4.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4.2.0...668228422ae6a00e4ad889ee87cd7109ec5666a7)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: 5.0.4
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-26 14:17:52 +00:00
Vishal Malyan
768be97fa4 feat(ci) optimize Android SDK build by caching Gradle dependencies 2026-03-26 15:16:35 +01:00
Philip Örnfeldt
d67096ee8e lang(sv): Small change of wording
Signed-off-by: Örnfeldt Philip (66140321) <philip.ornfeldt@forsakringskassan.se>
2026-03-26 06:57:05 -05:00
Kevin Caballero
783527ac53 lang: add missing translation in main es 2026-03-26 06:56:22 -05:00
Дамян Минков
fc289dd5ae fix(tests): Report worker crash when session cleanup times out. (#17211)
* fix(tests): Report worker crash when session cleanup times out.

When the WebDriver session DELETE request times out, the worker exits
with code 1 before the JUnit reporter can flush, leaving a zero-byte
XML file that is invisible to the report generator. The onWorkerEnd
hook now detects this and writes a failure entry so the crash shows
up in the test report.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* squash: Fix lint errors.

* fix(tests): Use error instead of failure for worker crash XML.

The previous fix incorrectly used <failure> (test assertion failed) for
the zero-byte XML fallback. Since the test may have actually passed and
only the session cleanup timed out, use <error> (infrastructure problem)
with a message clarifying the result is unknown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* squash: Updates message.

* squash: Bumps connection timeout.

* squash: Bumps webdriver.io dependencies.

* squash:Use junitReportBuilder to build the report.

* Also add an allure report when a worker returns non-zero.

* squash: fix dependency version.

* fix(tests): Increase allure report generation timeout and improve error messages.

5 seconds was too tight for CI with a full test suite of allure results.
Also distinguish between timeout and non-zero exit code in the error message
to make failures easier to diagnose.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Boris Grozev <boris@jitsi.org>
2026-03-25 16:03:56 -05:00
Stephan Paternotte
e84877e91f lang: Update Dutch translations 2026-03-25 11:50:24 -05:00
Mihaela Dumitru
b24e615ded fix(ui) adjust svg fills and backgrounds (#17062) 2026-03-25 08:54:37 +02:00
Mihaela Dumitru
5ad6332632 feat(external-api): send full user context (#17147) 2026-03-24 17:43:36 +02:00
Calinteodor
8006bd05c6 Revert "feat(deep-linking): use same action for join in app if scheme url is undefined" 2026-03-24 13:15:11 +02:00
mishra
048791c858 fix(react-native-sdk): Export JitsiMeeting component
- Change main entry point from index.tsx to dist/index.js
- Add types field pointing to dist/index.d.ts
- Create tsconfig.json for TypeScript compilation
- Add build script: tsc -p tsconfig.json
- Update prepare hook to auto-compile on npm publish
- Add files array to control npm package contents
- Add .npmignore to exclude build artifacts

Resolves #16443 where JitsiMeeting could not be imported from @jitsi/react-native-sdk
2026-03-24 12:32:33 +02:00
Nishant kumar
ad82e557e0 * fix(invite): use URLSearchParams for decoding dial-in room name 2026-03-23 15:22:04 -05:00
Jaya Allamsetty
15511f86be chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2137.0.0+084a5a9c...v2140.0.0+fe26afb0
2026-03-23 13:49:36 -04:00
Naman Jain
7699cfdac5 feat(translation): added missing hindi translations 2026-03-20 14:31:16 -04:00
Calin-Teodor
16fcf27fb7 feat(deep-linking): use same action for join in app if scheme url is undefined 2026-03-19 15:51:24 +02:00
Jaya Allamsetty
94243c797c feat(tracks) Adds UI notification when SS is killed by macOS.
* feat(tracks) Adds UI notification when SS is killed by macOS.
2026-03-17 16:13:56 -04:00
damencho
6564ba52a2 feat(tests): Adds filesharing tests. 2026-03-13 14:32:07 -05:00
damencho
a77ac20db9 fix(file-sharing): Disable dragging on prejoin.
Updates docs to reflect implementation.
2026-03-13 14:32:07 -05:00
mishraditi
6907db1127 fix(settings) Refreshes audio input levels when microphone permission is regranted. 2026-03-13 11:28:47 -04:00
mishraditi
78931d4f0d fix(settings) Fixes missing previews after device permissions are granted. 2026-03-13 10:25:22 -04:00
Jaya Allamsetty
b19d76fbdf chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2135.0.0+17e2281c...v2137.0.0+084a5a9c
2026-03-12 16:54:14 -04:00
Nishant kumar
0676ca5e62 fix(invite): Use decoded room name for dial-in info page url
* fix(invite): normalize room before building dial-in URL to avoid double encoding

* refactor(invite): use getNormalizedRoomName for room normalization
2026-03-12 13:05:47 -05:00
mishraditi
f387ae2113 fix i18n key for breakout room participant ellipsis tooltip 2026-03-12 11:54:20 -05:00
Hristo Terezov
f4a6036c1b fix(custom-panel): Button group
Since we render the button last when it has group 2 out of 4 React prints console.error.
2026-03-11 15:15:45 -05:00
damencho
86fbf159ec fix(wepback-dep-proxy): Fixes header errors.
webpack-dev-server v5 added a cross-origin-header-check security middleware that unconditionally returns 403 Cross-Origin request blocked for any request with sec-fetch-mode: no-cors + sec-fetch-site: cross-site.
2026-03-11 10:26:58 -05:00
damencho
15ebf0d078 feat(speakerstats): Adds config to control history. 2026-03-10 15:54:12 -05:00
damencho
1674a05ad0 feat(etherpad): Drops duplicate command listener. 2026-03-10 14:02:42 -05:00
Дамян Минков
0097e08d60 feat(amplitude): Updates initialization.
* feat(amplitude): Updates initialization.

* fix(amplitude): remove ts-ignore.

---------

Co-authored-by: Hristo Terezov <hristo@jitsi.org>
2026-03-10 14:02:31 -05:00
dependabot[bot]
b567791092 chore(ci): bump actions/setup-node from 6.2.0 to 6.3.0
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.2.0 to 6.3.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](6044e13b5d...53b83947a5)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.3.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-10 15:46:47 +01:00
Vishal Malyan
5be7328c08 feat(ci,ios) optimize iOS SDK build with CocoaPods caching 2026-03-10 14:26:33 +01:00
dependabot[bot]
55fb2a2b98 chore(ci): bump actions/cache from 4.2.0 to 5.0.3
Bumps [actions/cache](https://github.com/actions/cache) from 4.2.0 to 5.0.3.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](1bd1e32a3b...cdf6c1fa76)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: 5.0.3
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-10 10:07:35 +01:00
Stephan Paternotte
9612467813 lang: Update Dutch translations
fix(authentication): Shows notification if popup is blocked.
2026-03-09 17:31:06 -05:00
Дамян Минков
6aba231783 feat(tests): Adds dialIn expectation to disable more numbers page. (#17109)
* feat(tests): Adds dialIn expectation to disable more numbers page.

* squash: Cleaup.

---------

Co-authored-by: Boris Grozev <boris@jitsi.org>
2026-03-09 13:59:18 -05:00
damencho
052024e3b7 fix(etherpad): Checks the received command value. 2026-03-09 12:50:54 -05:00
Solomon
eeb80fddf7 fix(UI): Mirrors Virtual Background previews (#17090)
* fix(vb-preview mirror):

Add flipVideoX CSS class to VirtualBackgroundPreview component

Fixes: #17089

* Update VirtualBackgroundPreview.tsx

Fixed the Lint errors
2026-03-09 13:23:05 -04:00
damencho
5c1c00615f fix(auth_ban): Simplifies jaas test.
Checks tenant for magic cookie, fixes first check when room does not exist.
2026-03-09 12:16:53 -05:00
Vishal Malyan
c3e442f160 fix(ui): update Switch callback deps to prevent stale toggle handler for E2EE 2026-03-09 10:22:29 -04:00
Aaron van Meerten
6f8414e67f fix(base/util): prevent double URL encoding of non-ASCII room names
Room names with non-ASCII characters (e.g. ò) were double URL-encoded
when appended as query parameters to websocket, conference-request, and
keepalive URLs. getBackendSafeRoomName() returns a percent-encoded string
which was then re-encoded by URLSearchParams.append() via appendURLParam().

Extract getNormalizedRoomName() that decodes, NFKC-normalizes, and
lowercases without percent-encoding, and use it in the appendURLParam
call sites. getBackendSafeRoomName() is refactored to call it internally,
preserving identical behavior for all other callers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 08:22:22 -05:00
damencho
0f33b88774 fix(authentication): Shows notification if popup is blocked.
Adds a retry logic with a button. The problem is that some browsers (Safari) when window.open is not executed directly in the onClick handler, but on some underlying Promise will block the popup.
2026-03-06 15:23:35 -06:00
Nitin Kumar
9e3b54ffdf feat(chat/web): add explicit ChatButtonEntry interface and return type to useChatButton hook (#16937) 2026-03-06 11:30:40 -05:00
Vishal Malyan
103d1f84ac feat(ci) optimize ios-rn-bundle-build by caching CocoaPods dependencies 2026-03-06 16:45:10 +01:00
Yash Rastogi
74158c25a1 fix(polls): use creatorName prop instead of localParticipant in native PollAnswer (#17083) 2026-03-06 10:37:50 -05:00
Vishal Malyan
8bcca2dd35 Hide Android status bar in landscape mode during conferences without immersive mode. (#16675)
* Hide status bar in landscape mode
2026-03-06 16:20:41 +02:00
Hristo Terezov
86e641c2a1 fix(chat): scroll to latest messages when opening chat or CC tabs
Chat and CC panels showed oldest messages at the top when opened because
scrollIntoView was called on hidden (display: none) elements where it
silently does nothing. Now we skip scrolling on mount for hidden tabs
and defer it to when each tab first becomes visible, while preserving
the user's scroll position on subsequent tab switches.
2026-03-06 06:46:42 -06:00
dependabot[bot]
31eef95e3d chore(deps): bump svgo
Bumps  and [svgo](https://github.com/svg/svgo). These dependencies needed to be updated together.

Updates `svgo` from 2.8.0 to 2.8.2
- [Release notes](https://github.com/svg/svgo/releases)
- [Commits](https://github.com/svg/svgo/compare/v2.8.0...v2.8.2)

Updates `svgo` from 3.0.2 to 3.3.3
- [Release notes](https://github.com/svg/svgo/releases)
- [Commits](https://github.com/svg/svgo/compare/v2.8.0...v2.8.2)

---
updated-dependencies:
- dependency-name: svgo
  dependency-version: 2.8.2
  dependency-type: indirect
- dependency-name: svgo
  dependency-version: 3.3.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 11:36:57 +01:00
dependabot[bot]
029072256b chore(deps): bump dompurify from 3.2.6 to 3.3.2
Bumps [dompurify](https://github.com/cure53/DOMPurify) from 3.2.6 to 3.3.2.
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](https://github.com/cure53/DOMPurify/compare/3.2.6...3.3.2)

---
updated-dependencies:
- dependency-name: dompurify
  dependency-version: 3.3.2
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-06 11:21:55 +01:00
mishraditi
5199068bd2 fix(breakout-rooms): fix participant menu not closing in breakout rooms (#17091)
* fix(breakout-rooms): fix participant context menu not closing on re-click
2026-03-05 12:49:49 -06:00
damencho
274ef35a5b feat(breakout): Adds a checkout whether participants were in breakout. 2026-03-05 11:34:37 -06:00
damencho
781f972a4d feat(breakout): Move to use is_admin utility. 2026-03-05 11:34:37 -06:00
Jaya Allamsetty
1fe5be2ea4 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2134.0.0+c279d01e...v2135.0.0+17e2281c
2026-03-04 16:24:34 -05:00
Yash Rastogi
33679ac163 fix(virtual-background): show notification when background limit is reached (#17053) 2026-03-04 13:23:21 -05:00
Jaya Allamsetty
2f3a4478b9 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2132.0.0+92c8c183...v2134.0.0+c279d01e
2026-03-03 17:24:41 -06:00
damencho
5da150d8ef fix(jwt): Some services will not give you a new token till it is expired. 2026-03-03 13:36:41 -06:00
damencho
c4472ec0cd feat(debian): Updates nginx template to redact log lines. 2026-03-03 13:36:32 -06:00
damencho
7d17db63b5 fix(polls): Avoid duplicating voters. 2026-03-03 11:30:22 -06:00
Horatiu Muresan
f1339644b0 fix(url-params) Sanitize url params (#17070)
- check the passed lang param is in allowed languages
- validate http/https on deployment URLs
2026-03-03 13:28:53 +02:00
vishal2005025
3883811439 fix(gifs): prevent GIF popover from closing on internal clicks 2026-03-03 10:42:19 +01:00
Hristo Terezov
1f1dbb2517 feat(pip): add debug logging for better PiP flow observability
Add logger.debug calls throughout the PiP (Picture-in-Picture) feature
to make it easier to trace the PiP lifecycle when investigating issues.
Covers API event dispatching, action invocations with state snapshots,
requestPictureInPicture success/failure paths, and Electron namespace
mutations.
2026-03-02 17:26:15 -06:00
dependabot[bot]
db1beda219 chore(deps-dev): bump lodash from 4.17.21 to 4.17.23
Bumps [lodash](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 21:43:37 +01:00
dependabot[bot]
0208a9f10f chore(deps): bump glob from 11.0.3 to 12.0.0
Bumps [glob](https://github.com/isaacs/node-glob) from 11.0.3 to 12.0.0.
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v11.0.3...v12.0.0)

---
updated-dependencies:
- dependency-name: glob
  dependency-version: 12.0.0
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 21:43:18 +01:00
dependabot[bot]
1017823715 chore(deps): bump qs and express
Bumps [qs](https://github.com/ljharb/qs) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `qs` from 6.13.0 to 6.14.2
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.13.0...v6.14.2)

Updates `express` from 4.21.2 to 4.22.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/v4.22.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.2...v4.22.1)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.14.2
  dependency-type: indirect
- dependency-name: express
  dependency-version: 4.22.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 21:00:03 +01:00
dependabot[bot]
719d5c23d2 chore(deps): bump aws-sdk-s3 from 1.181.0 to 1.208.0
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.181.0 to 1.208.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.208.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 20:58:43 +01:00
dependabot[bot]
7db7c65fad chore(deps-dev): bump jws from 3.2.2 to 3.2.3
Bumps [jws](https://github.com/brianloveswords/node-jws) from 3.2.2 to 3.2.3.
- [Release notes](https://github.com/brianloveswords/node-jws/releases)
- [Changelog](https://github.com/auth0/node-jws/blob/master/CHANGELOG.md)
- [Commits](https://github.com/brianloveswords/node-jws/compare/v3.2.2...v3.2.3)

---
updated-dependencies:
- dependency-name: jws
  dependency-version: 3.2.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 20:58:07 +01:00
dependabot[bot]
d2a739c69c chore(deps): bump fast-xml-parser
Bumps  and [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser). These dependencies needed to be updated together.

Updates `fast-xml-parser` from 4.5.0 to 4.5.4
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.5.0...v4.5.4)

Updates `fast-xml-parser` from 5.3.3 to 5.4.1
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-parser/compare/v4.5.0...v4.5.4)

---
updated-dependencies:
- dependency-name: fast-xml-parser
  dependency-version: 4.5.4
  dependency-type: indirect
- dependency-name: fast-xml-parser
  dependency-version: 5.4.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 20:55:55 +01:00
Saúl Ibarra Corretgé
17cb867078 feat(build) use Node 24, the current LTS 2026-03-02 20:15:07 +01:00
Saúl Ibarra Corretgé
b2ad0995ae feat(recording) remove recording limit functionality
It was designed for the 8x8 standalone apps which have been sunset for a
while.
2026-03-02 20:14:03 +01:00
dependabot[bot]
b61b72087b chore(deps): bump lodash-es from 4.17.21 to 4.17.23
Bumps [lodash-es](https://github.com/lodash/lodash) from 4.17.21 to 4.17.23.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash-es
  dependency-version: 4.17.23
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 18:04:09 +01:00
dependabot[bot]
157be6b660 chore(ci): bump actions/setup-node from 6.1.0 to 6.2.0
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6.1.0 to 6.2.0.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](395ad32622...6044e13b5d)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 16:10:01 +01:00
dependabot[bot]
be6aba9aec chore(deps-dev): bump webpack-dev-server from 5.1.0 to 5.2.1
Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 5.1.0 to 5.2.1.
- [Release notes](https://github.com/webpack/webpack-dev-server/releases)
- [Changelog](https://github.com/webpack/webpack-dev-server/blob/main/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-dev-server/compare/v5.1.0...v5.2.1)

---
updated-dependencies:
- dependency-name: webpack-dev-server
  dependency-version: 5.2.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 15:40:36 +01:00
vishal2005025
d4bbaaba83 fix(livestream): add YouTube “Go Live” reminder in Start Live Stream dialog 2026-03-02 15:09:26 +01:00
dependabot[bot]
e4f22df5f2 chore(deps): bump on-headers and compression
Bumps [on-headers](https://github.com/jshttp/on-headers) and [compression](https://github.com/expressjs/compression). These dependencies needed to be updated together.

Updates `on-headers` from 1.0.2 to 1.1.0
- [Release notes](https://github.com/jshttp/on-headers/releases)
- [Changelog](https://github.com/jshttp/on-headers/blob/master/HISTORY.md)
- [Commits](https://github.com/jshttp/on-headers/compare/v1.0.2...v1.1.0)

Updates `compression` from 1.7.4 to 1.8.1
- [Release notes](https://github.com/expressjs/compression/releases)
- [Changelog](https://github.com/expressjs/compression/blob/master/HISTORY.md)
- [Commits](https://github.com/expressjs/compression/compare/1.7.4...v1.8.1)

---
updated-dependencies:
- dependency-name: on-headers
  dependency-version: 1.1.0
  dependency-type: indirect
- dependency-name: compression
  dependency-version: 1.8.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 14:58:04 +01:00
Calinteodor
b6d89b0939 feat(modal): fixes around JitsiScreen footer (#17041)
*Add extra px for Jitsi screen footer when native keyboard is visible.
2026-03-02 15:54:41 +02:00
dependabot[bot]
a6d3000d45 chore(ci): bump actions/checkout from 6.0.1 to 6.0.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](8e8c483db8...de0fac2e45)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 14:54:15 +01:00
dependabot[bot]
c616d98667 chore(deps): bump faraday from 1.10.4 to 1.10.5
Bumps [faraday](https://github.com/lostisland/faraday) from 1.10.4 to 1.10.5.
- [Release notes](https://github.com/lostisland/faraday/releases)
- [Changelog](https://github.com/lostisland/faraday/blob/main/CHANGELOG.md)
- [Commits](https://github.com/lostisland/faraday/compare/v1.10.4...v1.10.5)

---
updated-dependencies:
- dependency-name: faraday
  dependency-version: 1.10.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 14:53:45 +01:00
Saúl Ibarra Corretgé
900a2da909 fix(i18n) make translateToHTML more resilient 2026-03-02 14:46:49 +01:00
dependabot[bot]
cb7cde2c9a chore(deps): bump ajv from 6.12.6 to 6.14.0
Bumps [ajv](https://github.com/ajv-validator/ajv) from 6.12.6 to 6.14.0.
- [Release notes](https://github.com/ajv-validator/ajv/releases)
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v6.14.0)

---
updated-dependencies:
- dependency-name: ajv
  dependency-version: 6.14.0
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 14:44:23 +01:00
dependabot[bot]
32b29b963e chore(ci): bump actions/stale from 10.1.0 to 10.2.0
Bumps [actions/stale](https://github.com/actions/stale) from 10.1.0 to 10.2.0.
- [Release notes](https://github.com/actions/stale/releases)
- [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md)
- [Commits](5f858e3efb...b5d41d4e1d)

---
updated-dependencies:
- dependency-name: actions/stale
  dependency-version: 10.2.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 14:43:31 +01:00
dependabot[bot]
ad7658d58b chore(deps): bump minimatch
Bumps  and [minimatch](https://github.com/isaacs/minimatch). These dependencies needed to be updated together.

Updates `minimatch` from 3.1.2 to 3.1.4
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.4)

Updates `minimatch` from 10.0.3 to 10.2.3
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.4)

Updates `minimatch` from 9.0.5 to 9.0.7
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.4)

Updates `minimatch` from 5.1.6 to 5.1.8
- [Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.4)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.4
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 10.2.3
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 9.0.7
  dependency-type: indirect
- dependency-name: minimatch
  dependency-version: 5.1.8
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-02 14:42:19 +01:00
140 changed files with 3437 additions and 3073 deletions

View File

@@ -7,7 +7,7 @@ jobs:
name: Luacheck
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- name: Install luarocks
run: sudo apt-get --install-recommends -y install luarocks

View File

@@ -7,8 +7,8 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0
with:
node-version-file: '.nvmrc'
cache: 'npm'
@@ -42,8 +42,8 @@ jobs:
matrix:
os: [macos-latest, ubuntu-latest]
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0
with:
node-version-file: '.nvmrc'
cache: 'npm'
@@ -59,8 +59,8 @@ jobs:
name: Build mobile bundle (Android)
runs-on: macos-15
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0
with:
node-version-file: '.nvmrc'
cache: 'npm'
@@ -74,8 +74,8 @@ jobs:
name: Build mobile bundle (iOS)
runs-on: macos-15
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0
with:
node-version-file: '.nvmrc'
cache: 'npm'
@@ -96,9 +96,18 @@ jobs:
ruby-version: '3.4'
bundler-cache: true
- run: npx react-native info
- name: Cache CocoaPods
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7
with:
path: |
ios/Pods
~/Library/Caches/CocoaPods
key: ${{ runner.os }}-cocoapods-${{ hashFiles('ios/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-cocoapods-
- name: Install Pods
working-directory: ./ios
run: bundle exec pod install --repo-update --deployment
run: bundle exec pod install --deployment
- run: npx react-native bundle --entry-file react/index.native.js --platform ios --bundle-output /tmp/ios.bundle --reset-cache
android-sdk-build:
name: Build mobile SDK (Android)
@@ -116,8 +125,8 @@ jobs:
rm -rf /host/usr/share/dotnet
rm -rf /host/usr/share/swift
df -h /
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0
with:
node-version-file: '.nvmrc'
cache: 'npm'
@@ -126,6 +135,13 @@ jobs:
node -v
npm -v
- run: npm install
- name: Cache Gradle dependencies
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7
with:
path: /root/.gradle
key: ${{ runner.os }}-gradle-${{ hashFiles('android/**/*.gradle*', 'android/gradle.properties', 'android/gradle/wrapper/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- run: |
cd android
./gradlew :sdk:clean
@@ -137,8 +153,8 @@ jobs:
name: Build mobile SDK (iOS)
runs-on: macos-15
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0
with:
node-version-file: '.nvmrc'
cache: 'npm'
@@ -164,10 +180,19 @@ jobs:
with:
ruby-version: '3.4'
bundler-cache: true
- name: Cache CocoaPods
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 #v5.0.4
with:
path: |
ios/Pods
~/Library/Caches/CocoaPods
key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock', 'Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- run: npx react-native info
- name: Install Pods
working-directory: ./ios
run: bundle exec pod install --repo-update --deployment
run: bundle exec pod install --deployment
- run: |
xcodebuild -downloadPlatform iOS -buildVersion 18.2
xcodebuild archive \
@@ -187,8 +212,8 @@ jobs:
name: Test Debian packages build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 #v6.0.1
- uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f #v6.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f #v6.3.0
with:
node-version-file: '.nvmrc'
cache: 'npm'

View File

@@ -7,7 +7,7 @@ jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@5f858e3efba33a5ca4407a664cc011ad407f2008 #v10.1.0
- uses: actions/stale@b5d41d4e1d5dceea10e7104786b73624c18a190f #v10.2.0
with:
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'

2
.nvmrc
View File

@@ -1 +1 @@
22
24

View File

@@ -25,25 +25,27 @@ GEM
json (>= 1.5.1)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.1)
aws-partitions (1.1050.0)
aws-sdk-core (3.218.1)
aws-eventstream (1.4.0)
aws-partitions (1.1220.0)
aws-sdk-core (3.242.0)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
bigdecimal
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.98.0)
aws-sdk-core (~> 3, >= 3.216.0)
logger
aws-sdk-kms (1.122.0)
aws-sdk-core (~> 3, >= 3.241.4)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.181.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-s3 (1.208.0)
aws-sdk-core (~> 3, >= 3.234.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.11.0)
aws-sigv4 (1.12.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
base64 (0.3.0)
benchmark (0.4.0)
bigdecimal (3.1.9)
claide (1.1.0)
@@ -102,7 +104,7 @@ GEM
ethon (0.16.0)
ffi (>= 1.15.0)
excon (0.112.0)
faraday (1.10.4)
faraday (1.10.5)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
@@ -118,10 +120,10 @@ GEM
faraday (>= 0.8.0)
http-cookie (~> 1.0.0)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-em_synchrony (1.0.1)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.1.0)
faraday-multipart (1.2.0)
multipart-post (~> 2.0)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)

View File

@@ -26,7 +26,7 @@
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />

View File

@@ -1641,12 +1641,6 @@ export default {
JitsiE2ePingEvents.E2E_RTT_CHANGED,
(...args) => APP.store.dispatch(e2eRttChanged(...args)));
room.addCommandListener(this.commands.defaults.ETHERPAD,
({ value }) => {
APP.UI.initEtherpad(value);
}
);
room.addCommandListener(this.commands.defaults.EMAIL, (data, from) => {
APP.store.dispatch(participantUpdated({
conference: room,

View File

@@ -646,21 +646,6 @@ var config = {
// sticky: 0,
// },
// // Options for the recording limit notification.
// recordingLimit: {
//
// // The recording limit in minutes. Note: This number appears in the notification text
// // but doesn't enforce the actual recording time limit. This should be configured in
// // jibri!
// limit: 60,
//
// // The name of the app with unlimited recordings.
// appName: 'Unlimited recordings APP',
//
// // The URL of the app with unlimited recordings.
// appURL: 'https://unlimited.recordings.app.com/',
// },
// Disables or enables RTX (RFC 4588) (defaults to false).
// disableRtx: false,

View File

@@ -196,4 +196,14 @@
color:#FFD740;
font-size: 0.75rem;
}
.youtube-go-live-warning {
margin-bottom: 16px;
padding: 8px 12px;
background-color: rgba(248, 174, 26, 0.1);
border-left: 3px solid #FFD740;
font-size: 0.875rem;
line-height: 1.25rem;
color: #FFD740;
}
}

View File

@@ -26,6 +26,22 @@ map $arg_vnode $prosody_node {
v7 v7;
v8 v8;
}
# Matches any URI or Referer with some matches and redacts the whole
# query string. log_format and map must be at the http context level.
map $request_uri $loggable_uri {
~^(?P<path>[^?]*)\?.*(?:jwt|token)= "${path}?[params_redacted]";
default $request_uri;
}
map $http_referer $loggable_referer {
~^(?P<url>[^?]*)\?.*(?:jwt|token)= "${url}?[params_redacted]";
default $http_referer;
}
log_format jitsi_log '$remote_addr - $remote_user [$time_local] '
'"$request_method $loggable_uri $server_protocol" '
'$status $body_bytes_sent "$loggable_referer" "$http_user_agent"';
server {
listen 80;
listen [::]:80;
@@ -66,6 +82,8 @@ server {
root /usr/share/jitsi-meet;
access_log /var/log/nginx/access.log jitsi_log;
# ssi on with javascript for multidomain variables in config.js
ssi on;
ssi_types application/x-javascript application/javascript;

View File

@@ -537,8 +537,6 @@
"googlePrivacyPolicy": "سياسية خصوصية غوغل",
"inProgress": "البث المباشر غير ممكّن على {{email}}. يرجى تمكين البث المباشر أو تسجيل الدخول إلى حساب مع تمكين البث المباشر.",
"invalidStreamKey": "يحتمل كون مفتاح البث الحي غير صحيح.",
"limitNotificationDescriptionNative": "سيقيَّد البث إلى {{limit}} د، ولكن إن أردت إجراء عملية بث غير محدودة، جرِّب {{app}}.",
"limitNotificationDescriptionWeb": "نظرًا للضغط الكبير، سيقيَّد البث إلى {{limit}} د، ولكن إن أردت إجراء عملية بث غير محدودة، جرِّب <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "أُوقِف البث الحي",
"offBy": "أوقف {{name}} البث الحي",
"on": "بث حي",
@@ -898,8 +896,6 @@
"highlightMomentSuccess": "تم تمييز اللحظة",
"highlightMomentSucessDescription": "ستتم إضافة اللحظة المميزة إلى ملخص المُلتقى.",
"inProgress": "التسجيل أو البث المباشر قيد التقدم",
"limitNotificationDescriptionNative": "نظرًا للضغط الكبير، سيقيَّد التسجيل إلى {{limit}} د، ولكن إن أردت التسجيل لمدة مفتوحة، جرِّب <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "نظرًا للضغط الكبير، سيقيَّد التسجيل إلى {{limit}} د، ولكن إن أردت التسجيل لمدة مفتوحة، جرِّب <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "لقد أنشأنا رابطًا لتسجيلك.",
"live": "مباشر",
"localRecordingNoNotificationWarning": "لن يتم الإعلان عن التسجيل للمشاركين الآخرين. ستحتاج إلى إخبارهم بأنه تم تسجيل الاجتماع.",

View File

@@ -359,7 +359,7 @@
"kickParticipantTitle": "Изгонване на този участник?",
"kickSystemTitle": "Ауч! Бяхте изгонени от срещата",
"kickTitle": "Ауч! {{participantDisplayName}} Ви изгони от тази среща",
"learnMore": "научи повече",
"learnMore": "Научи повече",
"linkMeeting": "Свързване на среща",
"linkMeetingTitle": "Свързване на среща със Salesforce",
"liveStreaming": "Излъчване на живо",
@@ -429,9 +429,7 @@
"recentlyUsedObjects": "Вашите наскоро използвани обекти",
"recording": "Запис",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Невъзможно докато е активно излъчване на живо",
"recordingInProgressDescription": "Тази среща се записва и анализира от AI{{learnMore}}. Звукът и видеото ви са изключени. Ако решите да ги включите, давате съгласие да бъдете записани.",
"recordingInProgressDescriptionFirstHalf": "Тази среща се записва и анализира от AI",
"recordingInProgressDescriptionSecondHalf": ". Звукът и видеото ви са изключени. Ако решите да ги включите, давате съгласие да бъдете записани.",
"recordingInProgressDescription": "Тази среща се записва и анализира от AI. Звукът и видеото ви са изключени. Ако решите да ги включите, давате съгласие да бъдете записани.",
"recordingInProgressTitle": "В момента се записва",
"rejoinNow": "Повторно присъединяване сега",
"remoteControlAllowedMessage": "{{user}} прие заявката Ви за отдалечено управление!",
@@ -692,8 +690,6 @@
"googlePrivacyPolicy": "Политика за поверителност на Google",
"inProgress": "В ход е запис или излъчване на живо",
"invalidStreamKey": "Ключът за предаване на живо е грешен.",
"limitNotificationDescriptionNative": "Излъчването ви ще бъде ограничено до {{limit}} мин. За неограничено излъчване опитайте {{app}}.",
"limitNotificationDescriptionWeb": "Поради голямото търсене, излъчването ви ще бъде ограничено до {{limit}} мин. За неограничено излъчване опитайте <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Край на излъчването на живо",
"offBy": "{{name}} спря излъчването на живо",
"on": "Излъчване на живо",
@@ -1111,8 +1107,6 @@
"highlightMomentSuccess": "Моментът е отбелязан",
"highlightMomentSucessDescription": "Отбелязаният момент ще бъде добавен към резюмето на срещата.",
"inProgress": "В ход е запис или излъчване на живо",
"limitNotificationDescriptionNative": "Поради голямото търсене записът ви ще бъде ограничен до {{limit}} мин. За неограничени записи опитайте <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Поради голямото търсене записът ви ще бъде ограничен до {{limit}} мин. За неограничени записи опитайте <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Генерирахме линк към вашия запис.",
"localRecordingNoNotificationWarning": "Записът няма да бъде обявен на другите участници. Ще трябва да ги уведомите, че срещата се записва.",
"localRecordingNoVideo": "Видеото не се записва",

View File

@@ -541,8 +541,6 @@
"googlePrivacyPolicy": "Polítiques de privadesa de Google",
"inProgress": "L'enregistrament o la transmissió en directe és en progrés",
"invalidStreamKey": "La clau de transmissió en directe pot ser incorrecta.",
"limitNotificationDescriptionNative": "L'emissió es limitarà a {{limit}} min. Per a emissions sense límit proveu {{app}}.",
"limitNotificationDescriptionWeb": "Atesa l'alta demanda, la vostra emissió es limitarà a {{limit}} minuts. Per a emissions il·limitades, proveu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>",
"off": "S'ha aturat la transmissió en directe",
"offBy": "{{name}} ha aturat la transmissió en directe",
"on": "Ha començat la transmissió en directe",
@@ -905,8 +903,6 @@
"highlightMomentSuccess": "Moment destacat",
"highlightMomentSucessDescription": "S'ha afegit el moment destacat al resum de la reunió.",
"inProgress": "L'enregistrament o la transmissió en directe és en progrés",
"limitNotificationDescriptionNative": "A causa de la gran demanda, el vostre enregistrament es limitarà a {{limit}} min. Per a enregistraments il·limitats, proveu <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "A causa de la gran demanda, l'enregistrament es limitarà a {{limit}} min. Per a enregistraments il·limitats, proveu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "S'ha generat un enllaç a l'enregistrament.",
"live": "EN DIRECTE",
"localRecordingNoNotificationWarning": "L'enregistrament no s'anunciarà als altres participants. Els haureu d'informar que la reunió s'està enregistrant.",

View File

@@ -635,8 +635,6 @@
"googlePrivacyPolicy": "Zásady soukromí Google",
"inProgress": "Probíhá nahrávání nebo živé visílání",
"invalidStreamKey": "Klíč k živému přenosu může být chybný.",
"limitNotificationDescriptionNative": "Váš živý přenos může trvat nejvýše {{limit}} min. Pro neomezený přenos vyzkoušejte {{app}}.",
"limitNotificationDescriptionWeb": "Kvůli vysokému zájmu může váš přenos trvat nejvýše {{limit}} min. Pro neomezený přenos vyzkoušejte <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Živý přenos skončil",
"offBy": "{{name}} zastavil/a živý přenos",
"on": "Živý přenos",
@@ -1037,8 +1035,6 @@
"highlightMomentSuccess": "Zvýrazněný okamžik",
"highlightMomentSucessDescription": "Váš zvýrazněný okamžik bude přidán do shrnutí setkání.",
"inProgress": "Probíhá nahrávání nebo živé vysílání",
"limitNotificationDescriptionNative": "Kvůli vysokému zájmu bude vaše nahrávka omezena na nejvýše {{limit}} min. Pro neomezené nahrávání zkuste <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Kvůli vysokému zájmu bude vaše nahrávka omezena na nejvýše {{limit}} min. Pro neomezené nahrávání zkuste <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Vygenerovali jsme odkaz na vaši nahrávku.",
"localRecordingNoNotificationWarning": "Nahrávka nebude oznámena ostatním účastníkům. Budete jim muset dát vědět, že schůzka je nahrána.",
"localRecordingNoVideo": "Video se nenahrává",

View File

@@ -440,9 +440,7 @@
"recentlyUsedObjects": "Dine nyligt anvendte objekter",
"recording": "Optagelse",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Ikke mulig, mens en livestream er igang",
"recordingInProgressDescription": "Dette møde bliver optaget og bearbejdet af AI{{learnMore}}. Din video og lyd er blevet deaktiveret. Hvis du vælger at unmute din video og lyd, giver du samtykke til at blive optaget.",
"recordingInProgressDescriptionFirstHalf": "Dette møde bliver optaget og bearbejdet af AI",
"recordingInProgressDescriptionSecondHalf": ". Din video og lyd er blevet deaktiveret. Hvis du vælger at unmute din video og lyd, giver du samtykke til at blive optaget.",
"recordingInProgressDescription": "Dette møde bliver optaget og bearbejdet af AI. Din video og lyd er blevet deaktiveret. Hvis du vælger at unmute din video og lyd, giver du samtykke til at blive optaget.",
"recordingInProgressTitle": "Optagelse er igang",
"rejoinNow": "Genforbind nu",
"remoteControlAllowedMessage": "{{user}} accepterede din anmodning om fjernbetjening!",
@@ -706,8 +704,6 @@
"googlePrivacyPolicy": "Google Privatlivspolitik",
"inProgress": "Optagelse eller livestreaming i gang",
"invalidStreamKey": "Vilkår og privatlivspolitik gælder KUN hvis der streames til Youtube",
"limitNotificationDescriptionNative": "Din streaming vil være begrænset til {{limit}} min. For ubegrænset streaming prøv {{app}}.",
"limitNotificationDescriptionWeb": "På grund af stor efterspørgsel vil din streaming være begrænset til {{limit}} min. For ubegrænset streaming prøv <a href={{url}} rel='noopener noreferrer' target='_blank'> {{app}} </a>.",
"off": "Livestreaming stoppede",
"offBy": "{{name}} stoppede livestreaming",
"on": "Livestreaming startede",
@@ -1127,8 +1123,6 @@
"highlightMomentSuccess": "Øjeblik fremhævet",
"highlightMomentSucessDescription": "Dit fremhævede øjeblik vil blive føjet til mødesammendrag.",
"inProgress": "Optagelse eller livestreaming i gang",
"limitNotificationDescriptionNative": "På grund af stor efterspørgsel vil din optagelse være begrænset til {{limit}} min. For ubegrænsede optagelser prøv <3> {{app}} </3>.",
"limitNotificationDescriptionWeb": "På grund af stor efterspørgsel vil din optagelse være begrænset til {{limit}} min. For ubegrænsede optagelser kan du prøve <a href={1y rel='noopener noreferrer' Target='_blank'> {{app}} </a>.",
"linkGenerated": "Vi har genereret et link til din optagelse.",
"localRecordingNoNotificationWarning": "Optagelsen vil ikke blive annonceret til andre deltagere. Du bliver nødt til at fortælle dem, at mødet er optaget.",
"localRecordingNoVideo": "Video optages ikke",

View File

@@ -445,9 +445,7 @@
"recentlyUsedObjects": "Ihre zuletzt verwendeten Objekte",
"recording": "Aufnahme",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Während eines Livestreams nicht möglich",
"recordingInProgressDescription": "Diese Konferenz wird aufgezeichnet und von KI analysiert {{learnMore}}. Ihr Ton und Video ist deaktiviert, wenn Sie es aktivieren, stimmen Sie der Aufzeichnung zu.",
"recordingInProgressDescriptionFirstHalf": "Diese Konferenz wird aufgezeichnet und von KI analysiert",
"recordingInProgressDescriptionSecondHalf": ". Ihr Ton und Video ist deaktiviert, wenn Sie es aktivieren, stimmen Sie der Aufzeichnung zu.",
"recordingInProgressDescription": "Diese Konferenz wird aufgezeichnet und von KI analysiert. Ihr Ton und Video ist deaktiviert, wenn Sie es aktivieren, stimmen Sie der Aufzeichnung zu.",
"recordingInProgressTitle": "Aufnahme läuft",
"rejoinNow": "Jetzt erneut beitreten",
"remoteControlAllowedMessage": "{{user}} hat die Anfrage zur Fernsteuerung angenommen!",
@@ -712,8 +710,6 @@
"googlePrivacyPolicy": "Google-Datenschutzerklärung",
"inProgress": "Livestreaming gestartet",
"invalidStreamKey": "Der Livestream-Schlüssel ist u. U. falsch.",
"limitNotificationDescriptionNative": "Ihr Stream ist begrenzt auf {{limit}} Min. Für unlimitiertes Streaming, nutzen Sie bitte {{app}}.",
"limitNotificationDescriptionWeb": "Wegen hoher Nachfrage ist Ihr Stream auf {{limit}} Min. begrenzt. Für unlimitiertes Streaming nutzen Sie bitte <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Livestream gestoppt",
"offBy": "{{name}} stoppte den Livestream",
"on": "Livestream",
@@ -1133,8 +1129,6 @@
"highlightMomentSuccess": "Highlight festgehalten",
"highlightMomentSucessDescription": "Ihr festgehaltener Moment wird zur Zusammenfassung der Konferenz hinzugefügt.",
"inProgress": "Aufzeichnung gestartet",
"limitNotificationDescriptionNative": "Wegen hoher Nachfrage ist Ihre Aufnahme auf {{limit}} Min. begrenzt. Für unlimitierte Aufnahmen nutzen Sie bitte <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Wegen hoher Nachfrage ist Ihre Aufnahme auf {{limit}} Min. begrenzt. Für unlimitierte Aufnahmen nutzen Sie bitte <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Link zur Aufzeichnung wurde generiert.",
"localRecordingNoNotificationWarning": "Die Aufzeichnung wird anderen Anwesenden nicht mitgeteilt. Sie müssen diese selbst darauf hinweisen, dass die Konferenz aufgezeichnet wird.",
"localRecordingNoVideo": "Videos werden nicht aufgenommen",

View File

@@ -543,8 +543,6 @@
"googlePrivacyPolicy": "regule k woplěwanju datow pla Google",
"inProgress": "Livestreaming jo se zachopił",
"invalidStreamKey": "Kluc za livestream jo ewentuelnje wopacny.",
"limitNotificationDescriptionNative": "Waš stream jo na {{limit}} minutow wobgranicowany. Za njelimitěrowany streaming, wužywajśo aplikaciju {{app}}.",
"limitNotificationDescriptionWeb": "Dla intensiwnego wužywanja jo Waš stream na {{limit}} minutow wobgranicowany. Za njelimitěrowany streaming wužywajśo aplikaciju <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Livestream jo zastajony",
"offBy": "{{name}} jo livestream zastajił",
"on": "livestream",
@@ -905,8 +903,6 @@
"highlightMomentSuccess": "highlight jo se markěrował",
"highlightMomentSucessDescription": "Waš markěrowany moment pśidajo se k wopowěsći wót zmakanja.",
"inProgress": "Nagrawanje abo livestream jo we źěle",
"limitNotificationDescriptionNative": "Dla intensiwnego wužywanja jo Wašo nagrawanje na {{limit}} minutow wobgranicowane. Za njelimitěrowane nagrawanje wužyj aplikaciju <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Dla intensiwnego wužywanja jo Wašo nagrawanje na {{limit}} minutow wobgranicowane. Za njelimitěrowane nagrawanje wužyjśo aplikaciju <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Link k nagrawanju jo se generěrował.",
"live": "LIVE",
"localRecordingNoNotificationWarning": "Druge wobźělniki njedostanu powěsći wót nagrawanja. Wy musyśo jich sami informěrowaś, až konferenca se nagrawa.",

View File

@@ -560,8 +560,6 @@
"googlePrivacyPolicy": "Πολιτική Απορρήτου της Google",
"inProgress": "Εγγραφή ή ζωντανή ροή σε εξέλιξη",
"invalidStreamKey": "Το κλειδί ζωντανής ροής μπορεί να είναι εσφαλμένο.",
"limitNotificationDescriptionNative": "Η ροή σας θα περιοριστεί σε {{limit}} λεπτά. Για ροή χωρίς όρια δοκιμάστε το {{app}}.",
"limitNotificationDescriptionWeb": "Λόγω υψηλής ζήτησης η ροή θα περιοριστεί σε {{limit}} λεπτά. Για απεριόριστες ροές δοκιμάστε το <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Η Ζωντανή Ροή σταμάτησε",
"offBy": "{{name}} σταμάτησε τη ζωντανή ροή",
"on": "Η Ζωντανή Ροή ξεκίνησε",
@@ -919,8 +917,6 @@
"highlightMomentSuccess": "Η στιγμή επισημάνθηκε",
"highlightMomentSucessDescription": "Οι επισημασμένη στιγμή θα προστεθεί στη περίληψη της σύσκεψης.",
"inProgress": "Σε εξέλιξη καταγραφή ή ζωντανή ροή",
"limitNotificationDescriptionNative": "Λόγω υψηλής ζήτησης η εγγραφή σας θα περιοριστεί σε {{limit}} λεπτά. Για απεριόριστες εγγραφές, δοκιμάστε το <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Λόγω υψηλής ζήτησης η εγγραφή σας θα περιοριστεί σε {{limit}} λεπτά. Για απεριόριστες εγγραφές, δοκιμάστε το <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Δημιουργήσαμε ένα σύνδεσμο για τη καταγραφή σας.",
"live": "ΖΩΝΤΑΝΑ",
"localRecordingNoNotificationWarning": "Η καταγραφή δεν θα κοινοποιηθεί στους άλλους συμμετέχοντες. Θα πρέπει εσείς να τους ενημερώσετε ότι η σύσκεψη καταγράφεται.",

View File

@@ -621,8 +621,6 @@
"googlePrivacyPolicy": "Privatecpolitiko de Google",
"inProgress": "Registrado aŭ vivelsendo farata",
"invalidStreamKey": "La ŝlosilo de tuja elsendfluo povas esti malĝusta.",
"limitNotificationDescriptionNative": "Via vivelsendo estos limigita al {{limit}} minutoj. Por senlima vivelsendo provu {{ app}}.",
"limitNotificationDescriptionWeb": "Pro alta postulo, via vivelsendo estos limigita al {{limit}} minutoj. Por senlima vivelsendo provu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Tuja elsendfluo finiĝis",
"offBy": "{{name}} ĉesigis la tujan elsendfluon",
"on": "Tuja elsendfluo",
@@ -996,8 +994,6 @@
"highlightMomentSuccess": "Momento emfazita",
"highlightMomentSucessDescription": "Via emfazita momento estos aldonita al la kunveno priskribo",
"inProgress": "Registrado aŭ vivelsendo farata",
"limitNotificationDescriptionNative": "Pro alta postulo via registrado estos limigita al {{ limo }} minutoj. Pro senlima registrado, provu <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Pro alta postulo via registrado estos limigita al {{ limo }} minutoj. Pro senlima registrado, provu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Ni generis ligilon al via registrado.",
"live": "LIVE",
"localRecordingNoNotificationWarning": "La registrado ne estos anoncita al aliaj partoprenantoj. Vi devos sciigi al ili, ke la renkontiĝo estas registrita.",

View File

@@ -502,8 +502,6 @@
"getStreamKeyManually": "No pudimos encontrar tu clave de transmisión. Por favor, obtenla de la página de YouTube y pégala.",
"googlePrivacyPolicy": "Política de Privacidad de Google",
"invalidStreamKey": "Es posible que la clave de transmisión sea incorrecta, o no es de YouTube.",
"limitNotificationDescriptionNative": "Su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en {{app}}.",
"limitNotificationDescriptionWeb": "Debido a la alta demanda su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Se detuvo la transmisión",
"offBy": "{{name}} detuvo la transmisión",
"on": "Transmitiendo en vivo",
@@ -800,8 +798,6 @@
"expandedPending": "La grabación se está iniciando…",
"failedToStart": "No se pudo iniciar la grabación",
"fileSharingdescription": "Compartir la grabación con los participantes de la reunión",
"limitNotificationDescriptionNative": "Su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Debido a la alta demanda su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Hemos generado un enlace a su grabación.",
"live": "EN VIVO",
"loggedIn": "Sesión iniciada como {{userName}}",

View File

@@ -578,8 +578,6 @@
"googlePrivacyPolicy": "Política de Privacidad de Google",
"inProgress": "Grabación o transmisión en vivo en curso",
"invalidStreamKey": "Es posible que la clave de transmisión sea incorrecta, o no es de YouTube.",
"limitNotificationDescriptionNative": "Su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en {{app}}.",
"limitNotificationDescriptionWeb": "Debido a la alta demanda su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Se detuvo la transmisión",
"offBy": "{{name}} detuvo la transmisión",
"on": "Transmitiendo en vivo",
@@ -885,6 +883,7 @@
"or": "o",
"premeeting": "Pre-reunión",
"proceedAnyway": "Continuar de todos modos",
"recordingWarning": "Otros participantes pueden estar grabando esta llamada",
"screenSharingError": "Error al compartir pantalla:",
"startWithPhone": "Iniciar con audio de llamada telefónica",
"unsafeRoomConsent": "Comprendo los riesgos, quiero unirme a la reunión",
@@ -947,8 +946,6 @@
"highlightMomentSuccess": "Momento destacado",
"highlightMomentSucessDescription": "Su momento destacado será agregado al resumen de la reunión.",
"inProgress": "Grabación o transmisión en vivo en curso",
"limitNotificationDescriptionNative": "Su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Debido a la alta demanda su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Hemos generado un enlace a su grabación.",
"live": "EN VIVO",
"localRecordingNoNotificationWarning": "La grabación no será anunciada al resto de participantes. Necesitarás hacerles saber que la reunión está siendo grabada.",

View File

@@ -444,8 +444,6 @@
"getStreamKeyManually": "Ezin izan dugu zure transmisio-gakoa bilatu. Lortu ezazu YouTuberen webgunetik.",
"googlePrivacyPolicy": "Google-en pribatutasun-politika",
"invalidStreamKey": "Zuzeneko transmisioaren gakoa okerra izan daiteke.",
"limitNotificationDescriptionNative": "Zure emanaldia {{limit}} minutura mugatuta dago. Mugarik gabekoa nahi baduzu probatu {{app}}.",
"limitNotificationDescriptionWeb": "Zuzeneko emanaldien arrakasta dela eta {{limit}} minutura mugatuta daude. Mugarik gabekoa nahi baduzu probatu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Zuzeneko transmisioa gelditu da",
"offBy": "{{name}} erabiltzaileak zuzeneko emanaldia gelditu du",
"on": "Zuzeneko transmisioa",
@@ -685,8 +683,6 @@
"expandedPending": "Grabaketa abian da…",
"failedToStart": "Grabazioa hasteak huts egin du",
"fileSharingdescription": "Partekatu grabazioa bileraren parte-hartzaileekin",
"limitNotificationDescriptionNative": "Zure grabazioa {{limit}} minutura mugatuta dago. Mugarik gabeko grabazioak izateko probatu <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Zure grabazioa {{limit}} minutura mugatuta dago. Mugarik gabeko grabazioak izateko probatu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"live": "ZUZENEAN",
"loggedIn": "{{userName}} gisa saioa hasita",
"off": "Grabazioa gelditu da",

View File

@@ -442,9 +442,7 @@
"recentlyUsedObjects": "اشیائی که به‌تازگی استفاده کرده‌اید",
"recording": "درحال ضبط",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "هنگامی که پخش زنده در جریان است ممکن نیست",
"recordingInProgressDescription": "این جلسه در حال ضبط و تحلیل توسط هوش مصنوعی است{{learnMore}}. صدا و تصویر شما بی‌صدا شده‌اند. اگر صدا یا تصویر خود را روشن کنید، به ضبط شدن رضایت می‌دهید.",
"recordingInProgressDescriptionFirstHalf": "این جلسه در حال ضبط و تحلیل توسط هوش مصنوعی است",
"recordingInProgressDescriptionSecondHalf": ". صدا و تصویر شما بی‌صدا شده‌اند. اگر صدا یا تصویر خود را روشن کنید، به ضبط شدن رضایت می‌دهید.",
"recordingInProgressDescription": "این جلسه در حال ضبط و تحلیل توسط هوش مصنوعی است. صدا و تصویر شما بی‌صدا شده‌اند. اگر صدا یا تصویر خود را روشن کنید، به ضبط شدن رضایت می‌دهید.",
"recordingInProgressTitle": "ضبط در حال انجام است",
"rejoinNow": "پیوستن مجدد",
"remoteControlAllowedMessage": "{{user}} درخواست کنترل از راه دور را پذیرفت!",
@@ -708,8 +706,6 @@
"googlePrivacyPolicy": "سیاست محرمانگی گوگل",
"inProgress": "ضبط یا پخش زنده درحال انجام است",
"invalidStreamKey": "کلید پخش زنده ممکن است اشتباه باشد.",
"limitNotificationDescriptionNative": "پخش زنده شما به {{limit}} دقیقه محدود خواهد شد. برای پخش نامحدود از {{app}} استفاده کنید.",
"limitNotificationDescriptionWeb": "به دلیل درخواست‌های زیاد، پخش زندهٔ شما به {{limit}} دقیقه محدود خواهد شد. برای پخش نامحدود از <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a> استفاده کنید.",
"off": "پخش زنده قطع شد",
"offBy": "{{name}} پخش زنده را متوقف کرد",
"on": "پخش زنده شروع شد",
@@ -1133,8 +1129,6 @@
"highlightMomentSuccess": "لحظه علامت‌گذاری شد",
"highlightMomentSucessDescription": "لحظه‌های علامت‌گذاری‌شدهٔ شما به خلاصهٔ جلسه افزوده خواهند شد.",
"inProgress": "ضبط یا پخش زنده درحال انجام است",
"limitNotificationDescriptionNative": "به دلیل درخواست‌های زیاد، ضبط شما به {{limit}} دقیقه محدود خواهد شد. برای ضبط نامحدود از <3>{{app}}</3> استفاده کنید.",
"limitNotificationDescriptionWeb": "به دلیل درخواست‌های زیاد، ضبط شما به {{limit}} دقیقه محدود خواهد شد. برای ضبط نامحدود از <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a> استفاده کنید.",
"linkGenerated": "ما لینکی برای ضبط شما ایجاد کرده‌ایم.",
"live": "<b>زنده</b>",
"localRecordingNoNotificationWarning": "این ضبط به آگاهی دیگر شرکت‌کنندگان نخواهد رسید. لازم است که به آن‌ها بگویید که جلسه ضبط شده است.",

View File

@@ -373,7 +373,7 @@
"kickParticipantTitle": "Poista tämä osallistuja?",
"kickSystemTitle": "Hups! Sinut poistettiin kokouksesta",
"kickTitle": "Hups! {{participantDisplayName}} poisti sinut kokouksesta",
"learnMore": "lue lisää",
"learnMore": "Lue lisää",
"linkMeeting": "Linkitä kokous",
"linkMeetingTitle": "Linkitä kokous Salesforceen",
"liveStreaming": "Suoratoisto",
@@ -443,9 +443,7 @@
"recentlyUsedObjects": "Viimeksi käyttämäsi objektit",
"recording": "Nauhoitetaan",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Ei mahdollista suoratoiston ollessa käynnissä",
"recordingInProgressDescription": "Tämä kokous nauhoitetaan ja analysoidaan tekolyn avulla{{learnMore}}. Äänesi ja videosi on mykistetty. Jos poistat mykistyksen, suostut nauhoitukseen.",
"recordingInProgressDescriptionFirstHalf": "Tämä kokous nauhoitetaan ja analysoidaan tekolyn avulla",
"recordingInProgressDescriptionSecondHalf": ". Äänesi ja videosi on mykistetty. Jos poistat mykistyksen, suostut nauhoitukseen.",
"recordingInProgressDescription": "Tämä kokous nauhoitetaan ja analysoidaan tekolyn avulla. Äänesi ja videosi on mykistetty. Jos poistat mykistyksen, suostut nauhoitukseen.",
"recordingInProgressTitle": "Nauhoitus käynnissä",
"rejoinNow": "Liity nyt uudelleen",
"remoteControlAllowedMessage": "{{user}} hyväksyi etäkäyttöpyyntösi!",
@@ -710,8 +708,6 @@
"googlePrivacyPolicy": "Googlen tietosuojakäytäntö",
"inProgress": "Nauhoitus tai suoratoisto käynnissä",
"invalidStreamKey": "Suoratoistokoodi voi olla virheellinen.",
"limitNotificationDescriptionNative": "Suoratoistosi rajoitetaan {{limit}} minuuttiin. Rajattomaan suoratoistoon kokeile sovellusta {{app}}.",
"limitNotificationDescriptionWeb": "Suuren kysynnän vuoksi suoratoistosi rajoitetaan {{limit}} minuuttiin. Rajattomaan suoratoistoon kokeile <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Suoratoisto päättyi",
"offBy": "{{name}} pysäytti suoratoiston",
"on": "Suoratoisto",
@@ -1131,8 +1127,6 @@
"highlightMomentSuccess": "Hetki korostettu",
"highlightMomentSucessDescription": "Korostamasi hetki lisätään kokouksen yhteenvetoon.",
"inProgress": "Nauhoitus tai suoratoisto käynnissä",
"limitNotificationDescriptionNative": "Suuren kysynnän vuoksi nauhoituksesi rajoitetaan {{limit}} minuuttiin. Rajattomia nauhoituksia varten kokeile <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Suuren kysynnän vuoksi nauhoituksesi rajoitetaan {{limit}} minuuttiin. Rajattomia nauhoituksia varten kokeile <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Olemme luoneet linkin nauhoitukseesi.",
"localRecordingNoNotificationWarning": "Nauhoituksesta ei ilmoiteta muille osallistujille. Sinun täytyy kertoa heille, että kokousta nauhoitetaan.",
"localRecordingNoVideo": "Videota ei nauhoiteta",

View File

@@ -359,7 +359,7 @@
"kickParticipantTitle": "Expulser ce membre?",
"kickSystemTitle": "Oups ! Vous avez été expulsé de la réunion",
"kickTitle": "Expulsé de la réunion",
"learnMore": "en savoir plus",
"learnMore": "En savoir plus",
"linkMeeting": "Relier la réunion",
"linkMeetingTitle": "Relier la réunion à Salesforce",
"liveStreaming": "Diffusion en direct",
@@ -429,9 +429,7 @@
"recentlyUsedObjects": "Vos objets récemment utilisés",
"recording": "Enregistrement",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Impossible durant le direct",
"recordingInProgressDescription": "Cette réunion est en cours d'enregistrement et d'analyse par IA{{learnMore}}. Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
"recordingInProgressDescriptionFirstHalf": "Cette réunion est en cours d'enregistrement et d'analyse par IA",
"recordingInProgressDescriptionSecondHalf": ". Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
"recordingInProgressDescription": "Cette réunion est en cours d'enregistrement et d'analyse par IA. Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
"recordingInProgressTitle": "Enregistrement en cours",
"rejoinNow": "Rejoindre maintenant",
"remoteControlAllowedMessage": "{{user}} a accepté votre demande de contrôle à distance!",
@@ -692,8 +690,6 @@
"googlePrivacyPolicy": "Politique de confidentialité de Google",
"inProgress": "Enregisrtement ou diffusion en cours",
"invalidStreamKey": "La clé de diffusion en direct peut être erronée.",
"limitNotificationDescriptionNative": "Votre diffusion sera limitée à {{limit}} min. Pour une diffusion illimitée, essayez {{app}}.",
"limitNotificationDescriptionWeb": "En raison d'une forte demande, votre diffusion sera limitée à {{limit}} min. Pour une diffusion illimitée, essayez <a href={{url}} rel='noopener noreferrer' target='_blank'> {{app}} </a>.",
"off": "La diffusion en direct s'est arrêtée",
"offBy": "{{name}} a arrêté la diffusion en continu",
"on": "Diffusion en direct",
@@ -1111,8 +1107,6 @@
"highlightMomentSuccess": "Moment souligné",
"highlightMomentSucessDescription": "Votre moment souligné sera ajouté au résumé de la réunion.",
"inProgress": "Enregistrement ou diffusion en cours",
"limitNotificationDescriptionNative": "En raison d'une forte demande, votre enregistrement sera limité à {{limit}} min. Pour des enregistrements illimités, essayez <3> {{app}} </3>.",
"limitNotificationDescriptionWeb": "En raison d'une forte demande, votre enregistrement sera limité à {{limit}} min. Pour des enregistrements illimités, essayez <a href={{url}} rel='noopener noreferrer' target='_blank'> {{app}} </a>.",
"linkGenerated": "Nous avons généré un lien à votre enregistrement.",
"localRecordingNoNotificationWarning": "Le démarrage de lenregistrement ne sera pas annoncé aux autres participants. Vous devrez les informer par vous-même que la réunion sera enregistrée.",
"localRecordingNoVideo": "La vidéo n'est pas en cours denregistrement",

View File

@@ -373,7 +373,7 @@
"kickParticipantTitle": "Expulser ce participant ?",
"kickSystemTitle": "Oups ! Vous avez été expulsé de la réunion",
"kickTitle": "Oups ! vous avez été expulsé(e) par {{participantDisplayName}}",
"learnMore": "en savoir plus",
"learnMore": "En savoir plus",
"linkMeeting": "Relier la conférence",
"linkMeetingTitle": "Relier la conférence à Salesforce",
"liveStreaming": "Direct",
@@ -443,9 +443,7 @@
"recentlyUsedObjects": "Vos objets récemment utilisés",
"recording": "Enregistrement",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Impossible durant le direct",
"recordingInProgressDescription": "Cette réunion est en cours d'enregistrement et d'analyse par IA{{learnMore}}. Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
"recordingInProgressDescriptionFirstHalf": "Cette réunion est en cours d'enregistrement et d'analyse par IA",
"recordingInProgressDescriptionSecondHalf": ". Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
"recordingInProgressDescription": "Cette réunion est en cours d'enregistrement et d'analyse par IA. Votre audio et vidéo ont été coupés. Si vous choisissez de vous réactiver, vous consentez à être enregistré.",
"recordingInProgressTitle": "Enregistrement en cours",
"rejoinNow": "Rejoindre maintenant",
"remoteControlAllowedMessage": "{{user}} a accepté votre demande de prise en main à distance !",
@@ -709,8 +707,6 @@
"googlePrivacyPolicy": "Politique de confidentialité de Google",
"inProgress": "Enregisrtement ou diffusion en cours",
"invalidStreamKey": "La clé de diffusion en direct n'est peut-être pas correcte.",
"limitNotificationDescriptionNative": "Votre diffusion sera limitée à {{limit}} min. Pour une diffusion illimitée, essayez {{app}}.",
"limitNotificationDescriptionWeb": "En raison d'une forte demande, votre diffusion sera limitée à {{limit}} min. Pour une diffusion illimitée, essayez <a href={{url}} rel='noopener noreferrer' target='_blank'> {{app}} </a>.",
"off": "La diffusion en direct (streaming) a été arrêté",
"offBy": "{{name}} a arrêté la diffusion en direct",
"on": "En direct",
@@ -1130,8 +1126,6 @@
"highlightMomentSuccess": "Moment souligné",
"highlightMomentSucessDescription": "Votre moment souligné sera ajouté au résumé de la réunion.",
"inProgress": "Enregistrement ou diffusion en cours",
"limitNotificationDescriptionNative": "En raison d'une forte demande, votre enregistrement sera limité à {{limit}} min. Pour des enregistrements illimités, essayez <3> {{app}} </3>.",
"limitNotificationDescriptionWeb": "En raison d'une forte demande, votre enregistrement sera limité à {{limit}} min. Pour des enregistrements illimités, essayez <a href={{url}} rel='noopener noreferrer' target='_blank'> {{app}} </a>.",
"linkGenerated": "Nous avons généré un lien à votre enregistrement.",
"localRecordingNoNotificationWarning": "Le démarrage de lenregistrement ne sera pas annoncé aux autres participants. Vous devrez les informer par vous-même que la réunion sera enregistrée.",
"localRecordingNoVideo": "La vidéo n'est pas en cours denregistrement",

File diff suppressed because it is too large Load Diff

View File

@@ -541,8 +541,6 @@
"googlePrivacyPolicy": "Google politika privatnosti",
"inProgress": "U tijeku je snimanje ili prijenos uživo",
"invalidStreamKey": "Ključ prijenosa uživo možda nije ispravan.",
"limitNotificationDescriptionNative": "Tvoj prijenos će biti ograničen na {{limit}} min. Za neograničeni prijenos isprobaj {{app}}.",
"limitNotificationDescriptionWeb": "Zbog velike potražnje će tvoj prijenos biti ograničen na {{limit}} min. Za neograničeni prijenos isprobaj <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Prijenos uživo prekinut",
"offBy": "{{name}} je prekinuo/la prijenos uživo",
"on": "Prijenos uživo pokrenut",
@@ -903,8 +901,6 @@
"highlightMomentSuccess": "Trenutak istaknut",
"highlightMomentSucessDescription": "Tvoj istaknuti trenutak će se dodati u sažetak sastanka.",
"inProgress": "Snimanje ili prijenos uživo u tijeku",
"limitNotificationDescriptionNative": "Zbog velike potražnje, tvoje će snimanje biti ograničeno na {{limit}} min. Za neograničeno snimanje isprobaj <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Zbog velike potražnje, tvoje će snimanje biti ograničeno na {{limit}} min. Za neograničeno snimanje isprobaj <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Generirali smo poveznicu za tvoje snimanje.",
"live": "UŽIVO",
"localRecordingNoNotificationWarning": "Snimanje se neće najaviti ostalim sudionicima. Morat ćeš ih obavijestiti da se sastanak snima.",

View File

@@ -531,8 +531,6 @@
"googlePrivacyPolicy": "regule za datowy škit pola Google",
"inProgress": "live-stream startowany",
"invalidStreamKey": "Kluč za live-stream njeje najskerje prawy.",
"limitNotificationDescriptionNative": "Waš stream je na {{limit}} mjeń. wobmjezowany. Za njewobmjezowany streaming wužiwajće prošu {{app}}.",
"limitNotificationDescriptionWeb": "Wysokeje potrjeby dla je Waš stream na {{limit}} mjeń. wobmjezowany. Za njewobmjezowany streaming dźiće prošu na <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "live-stream stopowany",
"offBy": "{{name}} zadźerža live-stream",
"on": "live-stream",
@@ -887,8 +885,6 @@
"highlightMomentSuccess": "markěrowane",
"highlightMomentSucessDescription": "Waš markěrowany wokomik so k zjeću konferency přida.",
"inProgress": "nahrawanje startowane",
"limitNotificationDescriptionNative": " Wulkeje potrjeby dla je Waše nahraće na {{limit}} mjeń. wobmjezowane. Za njewobmjezowane nahraće wužiwajće prošu <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Wulkeje potrjeby dla je Waše nahrawanje na {{limit}} mjeń. wobmjezowane. Za njewobmjezowane nahrawanje wužiwajće prošu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "link na nahrawanje bu kreěrowany",
"live": "LIVE",
"localRecordingWarning": "Kedźbujće na to, aktualny tab za prawe widejo a awdijo wužiwać.",

View File

@@ -631,8 +631,6 @@
"googlePrivacyPolicy": "Kebijakan Privasi Google",
"inProgress": "Perekaman atau siaran langsung sedang berlangsung",
"invalidStreamKey": "Kunci siaran langsung mungkin salah.",
"limitNotificationDescriptionNative": "Pemutaran streaming Anda akan dibatasi menjadi {{limit}} menit. Untuk streaming tanpa batas, coba {{app}}.",
"limitNotificationDescriptionWeb": "Karena permintaan yang tinggi, streaming Anda akan dibatasi menjadi {{limit}} menit. Untuk streaming tanpa batas, coba <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Siaran Langsung berhenti",
"offBy": "{{name}} menghentikan siaran langsung",
"on": "Siaran Langsung dimulai",
@@ -1016,8 +1014,6 @@
"highlightMomentSuccess": "Momen disorot",
"highlightMomentSucessDescription": "Momen yang Anda sorot akan ditambahkan ke ringkasan pertemuan.",
"inProgress": "Rekaman atau siaran langsung sedang berlangsung",
"limitNotificationDescriptionNative": "Karena permintaan tinggi, rekaman Anda akan dibatasi menjadi {{limit}} menit. Untuk rekaman tanpa batas, coba <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Karena permintaan tinggi, rekaman Anda akan dibatasi menjadi {{limit}} menit. Untuk rekaman tanpa batas, coba <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Kami telah menghasilkan tautan untuk rekaman Anda.",
"localRecordingNoNotificationWarning": "Rekaman tidak akan diumumkan kepada peserta lain. Anda perlu memberi tahu mereka bahwa pertemuan direkam.",
"localRecordingNoVideo": "Video tidak direkam",

View File

@@ -622,8 +622,6 @@
"googlePrivacyPolicy": "Meðferð persónuupplýsinga hjá Google",
"inProgress": "Upptaka eða beint streymi í gangi",
"invalidStreamKey": "Lykill fyrir beint streymi gæti verið rangur.",
"limitNotificationDescriptionNative": "Streymið þitt verður takmarkað við {{limit}} mínútur. Fyrir ótakmarkað streymi ættirðu að prófa {{app}}.",
"limitNotificationDescriptionWeb": "Vegna mikils álags verður streymið þitt takmarkað við {{limit}} mínútur. Fyrir ótakmarkað streymi ættirðu að prófa <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Beint streymi stöðvað",
"offBy": "{{name}} stöðvaði beina streymið",
"on": "Beint streymi er hafið",
@@ -997,8 +995,6 @@
"highlightMomentSuccess": "Áherslulitað augnablik",
"highlightMomentSucessDescription": "Áherslulituðum augnablikum mun verða bætt við yfirlit fundarins.",
"inProgress": "Upptaka eða beint streymi í gangi",
"limitNotificationDescriptionNative": "Vegna mikils álags verður upptakan þín takmörkuð við {{limit}} mínútur. Fyrir ótakmarkaðar upptökur ættirðu að prófa <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Vegna mikils álags verður upptakan þín takmörkuð við {{limit}} mínútur. Fyrir ótakmarkaðar upptökur ættirðu að prófa <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Við höfum útbúið tengil á upptökuna þína.",
"localRecordingNoNotificationWarning": "Upptakan verður ekki tilkynnt öðrum þátttakendum. Þú þarft að láta aðra vita að fundurinn sé tekinn upp.",
"localRecordingNoVideo": "Ekki er verið að taka upp myndmerki",

View File

@@ -370,7 +370,7 @@
"kickParticipantTitle": "Espellere questo partecipante?",
"kickSystemTitle": "Oh! Sei stato espulso dalla riunione",
"kickTitle": "Oh! {{participantDisplayName}} ti ha espulso dalla riunione.",
"learnMore": "ulteriori informazioni",
"learnMore": "Ulteriori informazioni",
"linkMeeting": "Collega la riunione",
"linkMeetingTitle": "Collega la riunione a Salesforce",
"liveStreaming": "Diretta",
@@ -441,8 +441,6 @@
"recording": "Registrazione",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Impossibile durante una diretta.",
"recordingInProgressDescription": "Questa riunione sta venendo registrata e analizzata dall'IA. I tuoi audio e video sono stati disattivati. Riattivandoli, acconsenti ad essere registrato.",
"recordingInProgressDescriptionFirstHalf": "Questa riunione sta venendo registrata e analizzata dall'IA",
"recordingInProgressDescriptionSecondHalf": ". I tuoi audio e video sono stati disattivati. Riattivandoli, acconsenti ad essere registrato.",
"recordingInProgressTitle": "Registrazione in corso",
"rejoinNow": "Ricollegati ora",
"remoteControlAllowedMessage": "{{user}} ha accettato la tua richiesta di controllo remoto!",
@@ -706,8 +704,6 @@
"googlePrivacyPolicy": "Politiche sulla privacy di Google",
"inProgress": "Registrazione o diretta in corso",
"invalidStreamKey": "La chiave della diretta potrebbe non essere corretta.",
"limitNotificationDescriptionNative": "La tua diretta sarà limitata a {{limit}} minuti. Per dirette illimitate prova {{app}}.",
"limitNotificationDescriptionWeb": "Data la grossa domanda la tua diretta sarà limitata a {{limit}} minuti. Per dirette illimitate, prova <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "La diretta si è interrotta",
"offBy": "{{name}} ha fermato la diretta",
"on": "Diretta avviata",
@@ -1127,8 +1123,6 @@
"highlightMomentSuccess": "Momento evidenziato",
"highlightMomentSucessDescription": "Il tuo momento evidenziato sarà aggiunto al riepilogo della riunione.",
"inProgress": "Registrazione o diretta in corso",
"limitNotificationDescriptionNative": "La tua registrazione sarà limitata a {{limit}} minuti. Per registrazioni illimitate, prova <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Per la grossa domanda la tua registrazione sarà limitata a {{limit}} minuti. Per registrazioni illimitate, prova <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "È stato generato un collegamento alla tua registrazione.",
"localRecordingNoNotificationWarning": "La registrazione non verrà annunciata ai partecipanti. Dovrai dir loro che la riunione viene registrata.",
"localRecordingNoVideo": "Il video non sta venendo registrato",

View File

@@ -505,8 +505,6 @@
"googlePrivacyPolicy": "Google プライバシーポリシー",
"inProgress": "録画またはライブ配信中です",
"invalidStreamKey": "ストリームキーが正しくないようです。",
"limitNotificationDescriptionNative": "利用者が多いため、あなたの録画は {{limit}} 分に制限されます。無制限に録画するには<3>{{app}}</3>をお試しください。",
"limitNotificationDescriptionWeb": "利用者が多いため、あなたの録画は {{limit}} 分に制限されます。 無制限に録画するには<a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>をお試しください。",
"off": "ライブ配信を停止しました",
"offBy": "{{name}} がライブ配信を停止しました",
"on": "ライブ配信を開始しました",
@@ -835,8 +833,6 @@
"highlightMomentSuccess": "ハイライトされました",
"highlightMomentSucessDescription": "ハイライトされた瞬間は議事録に追加されます。",
"inProgress": "録画またはライブ配信中です",
"limitNotificationDescriptionNative": "利用者が多いため、あなたの録画は {{limit}} 分に制限されます。無制限に録画するには<3>{{app}}</3>をお試しください。",
"limitNotificationDescriptionWeb": "利用者が多いため、あなたの録画は {{limit}} 分に制限されます。 無制限に録画するには<a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>をお試しください。",
"linkGenerated": "あなたの録画へのリンクを生成しました。",
"live": "LIVE",
"localRecordingNoNotificationWarning": "この録画は他の参加者に通知されません。このミーティングが録画されていることを他の参加者に伝えてください。",

View File

@@ -480,8 +480,6 @@
"getStreamKeyManually": "Ur nessaweḍ ara ad d-nerr ula d yiwen n usuddem usrid. Ɛreḍ ad d-tawiḍ tasarut-ik·im n usuddem usrid seg Youtube.",
"googlePrivacyPolicy": "Tasertit tabaḍnit n Google",
"invalidStreamKey": "Tasarut n usuddem usrid yezmer mačči d tameɣtut.",
"limitNotificationDescriptionNative": "Asuddem-inek·inem ad yesɛu kan {{limit}} tesdidin. I usuddem war talast ɛreḍ {{app}}.",
"limitNotificationDescriptionWeb": "Seg wakken yegget usuter, asuddem-inek·inem ad yesɛu talast n {{limit}} tesdidin. I usuddem n war tilas, ɛreḍ <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Asuddem usrid yettuḥbes",
"offBy": "{{name}} iseḥbes asuddem usrid",
"on": "Yebda usuddem usrid",
@@ -777,8 +775,6 @@
"expandedPending": "Asekles ha-t-an yebda….",
"failedToStart": "Beddu n usekles ur yeddi ara",
"fileSharingdescription": "Bḍu asekles d yimttekkiyen n temlilit",
"limitNotificationDescriptionNative": "Seg tuget n usuter, asekles-inek·inem ad yesɛu kan {{limit}} tesdidin. I yiseklas war tilas, ɛreḍ <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Seg tuget n usuter, asekles-inek·inem ad yesɛu kan {{limit}} tesdidin. I yiseklas war tilas, ɛreḍ <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Nsirew-d aseɣwen i usekles-inek·inem.",
"live": "SRID",
"loggedIn": "Yekcem s {{userName}}",

View File

@@ -440,9 +440,7 @@
"recentlyUsedObjects": "Жақында пайдаланылған объектілеріңіз",
"recording": "Жазу",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Тікелей эфир белсенді болған кезде мүмкін емес",
"recordingInProgressDescription": "Бұл жиналыс жазылуда және AI{{learnMore}} арқылы талдануда. Сіздің аудио және бейнеңіз өшірілді. Егер дыбысты қосуды таңдасаңыз, жазылуға келісім бересіз.",
"recordingInProgressDescriptionFirstHalf": "Бұл жиналыс жазылуда және AI арқылы талдануда",
"recordingInProgressDescriptionSecondHalf": ". Сіздің аудио және бейнеңіз өшірілді. Егер дыбысты қосуды таңдасаңыз, жазылуға келісім бересіз.",
"recordingInProgressDescription": "Бұл жиналыс жазылуда және AI арқылы талдануда. Сіздің аудио және бейнеңіз өшірілді. Егер дыбысты қосуды таңдасаңыз, жазылуға келісім бересіз.",
"recordingInProgressTitle": "Жазу орындалуда",
"rejoinNow": "Қазір қайта қосылу",
"remoteControlAllowedMessage": "{{user}} қашықтан басқару сұрауыңызды қабылдады!",
@@ -706,8 +704,6 @@
"googlePrivacyPolicy": "Google құпиялылық саясаты",
"inProgress": "Жазу немесе тікелей эфир орындалуда",
"invalidStreamKey": "Тікелей эфир кілті қате болуы мүмкін.",
"limitNotificationDescriptionNative": "Ағыныңыз {{limit}} минутпен шектеледі. Шексіз ағын үшін {{app}} қолданып көріңіз.",
"limitNotificationDescriptionWeb": "Жоғары сұранысқа байланысты ағыныңыз {{limit}} минутпен шектеледі. Шексіз ағын үшін <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a> қолданып көріңіз.",
"off": "Тікелей эфир тоқтатылды",
"offBy": "{{name}} тікелей эфирді тоқтатты",
"on": "Тікелей эфир басталды",
@@ -1127,8 +1123,6 @@
"highlightMomentSuccess": "Сәт бөлектенді",
"highlightMomentSucessDescription": "Бөлектенген сәтіңіз жиналыс қорытындысына қосылады.",
"inProgress": "Жазу немесе тікелей эфир орындалуда",
"limitNotificationDescriptionNative": "Жоғары сұранысқа байланысты жазбаңыз {{limit}} минутпен шектеледі. Шексіз жазбалар үшін <3>{{app}}</3> қолданып көріңіз.",
"limitNotificationDescriptionWeb": "Жоғары сұранысқа байланысты жазбаңыз {{limit}} минутпен шектеледі. Шексіз жазбалар үшін <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a> қолданып көріңіз.",
"linkGenerated": "Біз жазбаңызға сілтеме жасадық.",
"localRecordingNoNotificationWarning": "Жазба басқа қатысушыларға хабарланбайды. Жиналыс жазылып жатқанын оларға хабарлауыңыз керек.",
"localRecordingNoVideo": "Бейне жазылып жатқан жоқ",

View File

@@ -634,8 +634,6 @@
"googlePrivacyPolicy": "Google 개인 정보 보호 정책",
"inProgress": "녹화 또는 실시간 스트리밍 진행 중",
"invalidStreamKey": "라이브 스트림 키가 잘못되었을 수 있습니다.",
"limitNotificationDescriptionNative": "스트리밍이 {{limit}}분으로 제한됩니다. 무제한 스트리밍을 사용하려면 {{app}}을 시도해 보세요.",
"limitNotificationDescriptionWeb": "수요가 많아 스트리밍이 {{limit}}분으로 제한됩니다. 무제한 스트리밍을 사용하려면 <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>을 시도해 보세요.",
"off": "실시간 스트리밍이 중지됨",
"offBy": "{{name}}님이 실시간 스트리밍을 중지했습니다",
"on": "실시간 스트리밍",
@@ -1036,8 +1034,6 @@
"highlightMomentSuccess": "순간 강조 표시됨",
"highlightMomentSucessDescription": "강조 표시된 순간이 회의 요약에 추가됩니다.",
"inProgress": "녹화 또는 실시간 스트리밍 진행 중",
"limitNotificationDescriptionNative": "수요가 많아 녹화가 {{limit}}분으로 제한됩니다. 무제한 녹화를 사용하려면 {{app}}을 시도해 보세요.",
"limitNotificationDescriptionWeb": "수요가 많아 녹화가 {{limit}}분으로 제한됩니다. 무제한 녹화를 사용하려면 <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>을 시도해 보세요.",
"linkGenerated": "녹화에 대한 링크를 생성했습니다.",
"localRecordingNoNotificationWarning": "녹화가 다른 참가자에게 알리지 않습니다. 회의가 녹화되고 있음을 알려야 합니다.",
"localRecordingNoVideo": "비디오는 녹화되지 않습니다",

View File

@@ -370,7 +370,7 @@
"kickParticipantTitle": "Izraidīt šo dalībnieku?",
"kickSystemTitle": "Ak! Jūs izraidīja no sapulces",
"kickTitle": "Ak! {{participantDisplayName}} izraidīja jūs no sapulces",
"learnMore": "uzzināt vairāk",
"learnMore": "Uzzināt vairāk",
"linkMeeting": "Sasaistīt sapulci",
"linkMeetingTitle": "Sasaistīt sapulci ar Salesforce",
"liveStreaming": "Tiešraides straumēšana",
@@ -441,8 +441,6 @@
"recording": "Ieraksts",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Nav iespējams, kamēr ir aktīva tiešraides straume",
"recordingInProgressDescription": "Šī sapulce tiek ierakstīta. Jūsu audio un video ir izslēgti. Ja izvēlaties ieslēgt skaņu vai video, jūs piekrītat ierakstīšanai.",
"recordingInProgressDescriptionFirstHalf": "Šo sanāksmi ieraksta un analizē mākslīgais intelekts",
"recordingInProgressDescriptionSecondHalf": ". Jūsu audio un video skaņa ir izslēgta. Ja izvēlaties ieslēgt skaņu, jūs piekrītat ierakstīšanai.",
"recordingInProgressTitle": "Notiek ierakstīšana",
"rejoinNow": "Pieslēgties no jauna",
"remoteControlAllowedMessage": "{{user}} apstiprināja jūsu attālās pārvaldības pieprasījumu!",
@@ -706,8 +704,6 @@
"googlePrivacyPolicy": "Google konfidencialitātes politika",
"inProgress": "Notiek ierakstīšana vai tiešraides straumēšana",
"invalidStreamKey": "Izskatās, ka tiešraides atslēga nav pareiza.",
"limitNotificationDescriptionNative": "ūsu straumēšana būs ierobežota līdz {{limit}} min. Lai iegūtu neierobežotu straumēšanu, izmēģiniet {{app}}.",
"limitNotificationDescriptionWeb": "Lielā pieprasījuma dēļ jūsu straumēšana tiks ierobežota līdz {{limit}} min. Lai iegūtu neierobežotu straumēšanu, izmēģiniet <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Tiešraide izslēgta",
"offBy": "{{name}} izslēdza tiešraidi",
"on": "Tiešraide ieslēgta",
@@ -1127,8 +1123,6 @@
"highlightMomentSuccess": "Brīdis izcelts",
"highlightMomentSucessDescription": "Jūsu izceltais brīdis tiks pievienots sapulces kopsavilkumam.",
"inProgress": "Notiek ierakstīšana vai tiešraides straumēšana",
"limitNotificationDescriptionNative": "Lielā pieprasījuma dēļ jūsu ieraksts tiks ierobežots līdz {{limit}} min. Lai iegūtu neierobežotu ierakstu skaitu, izmēģiniet <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Lielā pieprasījuma dēļ jūsu ieraksts tiks ierobežots līdz {{limit}} min. Lai iegūtu neierobežotu ierakstu skaitu, izmēģiniet <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Mēs esam izveidojuši saiti uz jūsu ierakstu.",
"localRecordingNoNotificationWarning": "Ieraksts netiks izziņots citiem dalībniekiem. Jums būs jāpaziņo viņiem, ka sapulce tiek ierakstīta.",
"localRecordingNoVideo": "Video netiek ierakstīts",

View File

@@ -416,8 +416,6 @@
"getStreamKeyManually": "ഞങ്ങൾക്ക് തത്സമയ സ്ട്രീമുകളൊന്നും നേടാനായില്ല. യൂട്യൂബിൽ നിന്ന് നിങ്ങളുടെ തത്സമയ സ്ട്രീം കീ നേടാൻ ശ്രമിക്കുക.",
"googlePrivacyPolicy": "ഗൂഗിൾ സ്വകാര്യതാ നയം",
"invalidStreamKey": "തത്സമയ സ്ട്രീം കീ തെറ്റായിരിക്കാം.",
"limitNotificationDescriptionNative": "നിങ്ങളുടെ സ്ട്രീമിംഗ് {{limit}} മിനിറ്റായി പരിമിതപ്പെടുത്തും.പരിധിയില്ലാത്ത സ്ട്രീമിംഗിനായി ശ്രമിക്കുക {{app}}.",
"limitNotificationDescriptionWeb": "ഉയർന്ന ഡിമാൻഡ് കാരണം നിങ്ങളുടെ സ്ട്രീമിംഗ് {{limit}} മിനിറ്റായി പരിമിതപ്പെടുത്തും. പരിധിയില്ലാത്ത സ്ട്രീമിംഗിനായി ശ്രമിക്കുക <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "തത്സമയ സ്ട്രീമിംഗ് അവസാനിച്ചു",
"offBy": "{{name}} തത്സമയ സ്ട്രീമിംഗ് നിർത്തി",
"on": "തത്സമയ സംപ്രേക്ഷണം",
@@ -640,8 +638,6 @@
"expandedPending": "റെക്കോർഡിംഗ് ആരംഭിച്ചു…",
"failedToStart": "റെക്കോർഡിംഗ് ആരംഭിക്കുന്നതിൽ പരാജയപ്പെട്ടു",
"fileSharingdescription": "മീറ്റിംഗ് പങ്കാളികളുമായി റെക്കോർഡിംഗ് പങ്കിടുക",
"limitNotificationDescriptionNative": "ഉയർന്ന ഡിമാൻഡ് കാരണം നിങ്ങളുടെ റെക്കോർഡിംഗ് {{limit}} മിനിറ്റായി പരിമിതപ്പെടുത്തും. പരിധിയില്ലാത്ത റെക്കോർഡിംഗുകൾക്കായി <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "ഉയർന്ന ഡിമാൻഡ് കാരണം നിങ്ങളുടെ റെക്കോർഡിംഗ് {{limit}} മിനിറ്റായി പരിമിതപ്പെടുത്തും. പരിധിയില്ലാത്ത റെക്കോർഡിംഗുകൾക്കായി <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"live": "തത്സമയം",
"loggedIn": "{{userName}} എന്നയാളായി ലോഗിൻ ചെയ്‌തു",
"off": "െക്കോർഡിംഗ് അവസാനിച്ചു",

View File

@@ -566,8 +566,6 @@
"googlePrivacyPolicy": "Google хувийн мэдээлэл хамгаалах дүрэм",
"inProgress": "Шууд дамжуулалтыг бичиж байна",
"invalidStreamKey": "Шууд дамжуулалтын түлхүүрээ шалгана уу.",
"limitNotificationDescriptionNative": "Таны шууд дамжуулалтын хугацаа {{limit}}-аар минутын хязгаарлагдана. Хязгааргүй болгохын тулд {{app}} аппыг ажиллуулж үзнэ үү.",
"limitNotificationDescriptionWeb": "Таны шууд дамжуулалт чанараас хамааран хугацаа Due to high demand your streaming will be limited to {{limit}} min. For unlimited streaming try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Шууд дамжуулалт зогссон",
"offBy": "{{name}} шууд дамжуулалтыг зогсоосон",
"on": "Шууд дамжуулалт",
@@ -932,8 +930,6 @@
"highlightMomentSuccess": "Энэ мөчийг онцолсон",
"highlightMomentSucessDescription": "Таны онцолсон мөч уулзалтын хураангуй хэсэгт нэмэгдэнэ.",
"inProgress": "Бичлэг хийх эсвэл шууд дамжуулалт идэвхитэй",
"limitNotificationDescriptionNative": "Бичлэгийн чанараас хамааран таны минут {{limit}}-р хязгаарлагдаж байна. Хязгаарлалтгүй бичлэг хийхийн тулд <3>{{app}}</3> үзээрэй.",
"limitNotificationDescriptionWeb": "Бичлэгийн чанараас хамааран таны минут {{limit}}-р хязгаарлагдаж байна. Хязгаарлалтгүй бичлэг хийхийн тулд <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a> ашиглана уу.",
"linkGenerated": "Таны бичлэгийн холбоосыг үүсгэсэн.",
"live": "ШУУД",
"localRecordingNoNotificationWarning": "Бусад оролцогчид бичлэгийн хийх талаар мэдэгдэнэ. Та энэ бичлэгийн талаарх мэдэгдлийг зөвшөөрөх шаардлагатай.",

View File

@@ -635,8 +635,6 @@
"googlePrivacyPolicy": "Googles personvernpolicy",
"inProgress": "Opptak eller direktesending pågår",
"invalidStreamKey": "Strømmenøkkelen kan være feil.",
"limitNotificationDescriptionNative": "Direktesendingen din vil være begrenset til {{limit}} min. For ubegrenset strømming, prøv {{app}}.",
"limitNotificationDescriptionWeb": "På grunn av høy etterspørsel vil direktesendingen din være begrenset til {{limit}} min. For ubegrenset strømming, prøv <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Direktesending stoppet",
"offBy": "{{name}} stoppet direktesendingen",
"on": "Direktesending startet",
@@ -1037,8 +1035,6 @@
"highlightMomentSuccess": "Øyeblikk markert",
"highlightMomentSucessDescription": "Det markerte øyeblikket vil bli lagt til møtereferatet.",
"inProgress": "Opptak eller direktesending pågår",
"limitNotificationDescriptionNative": "På grunn av høy etterspørsel vil opptaket være begrenset til {{limit}} min. For ubegrensede opptak, prøv <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "På grunn av høy etterspørsel vil opptaket være begrenset til {{limit}} min. For ubegrensede opptak, prøv <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Vi har generert en lenke til opptaket ditt.",
"localRecordingNoNotificationWarning": "Opptaket vil ikke bli annonsert til de andre deltakerne. Du må informere dem om at møtet blir tatt opp.",
"localRecordingNoVideo": "Video blir ikke tatt opp",

View File

@@ -373,7 +373,7 @@
"kickParticipantTitle": "Deze deelnemer verwijderen?",
"kickSystemTitle": "Oei! U bent uit de vergadering verwijderd",
"kickTitle": "Oei! {{participantDisplayName}} heeft u uit de vergadering verwijderd",
"learnMore": "meer informatie",
"learnMore": "Meer informatie",
"linkMeeting": "Vergadering koppelen",
"linkMeetingTitle": "Vergadering koppelen aan Salesforce",
"liveStreaming": "Livestreamen",
@@ -385,6 +385,7 @@
"login": "Inloggen",
"loginFailed": "Inloggen is mislukt.",
"loginOnResume": "Uw authenticatiesessie is verlopen. U moet opnieuw inloggen om de vergadering voort te zetten.",
"loginPopupBlocked": "Inloggen-popup werd geblokkeerd door uw browser.",
"loginQuestion": "Weet u zeker dat u wilt inloggen en de conferentie verlaten?",
"logoutQuestion": "Weet u zeker dat u zich wilt afmelden en de conferentie wilt stoppen?",
"logoutTitle": "Afmelden",
@@ -445,9 +446,7 @@
"recentlyUsedObjects": "Uw recent gebruikte objecten",
"recording": "Opname",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Niet mogelijk tijdens een livestream",
"recordingInProgressDescription": "Deze bijeenkomst wordt opgenomen en geanalyseerd door AI{{learnMore}}. Uw audio en video zijn gedempt. Als u ervoor kiest om de demping op te heffen, stemt u ermee in dat u wordt opgenomen.",
"recordingInProgressDescriptionFirstHalf": "Deze bijeenkomst wordt opgenomen en geanalyseerd door AI",
"recordingInProgressDescriptionSecondHalf": ". Uw audio en video zijn gedempt. Als u ervoor kiest om de demping op te heffen, stemt u ermee in dat u wordt opgenomen.",
"recordingInProgressDescription": "Deze bijeenkomst wordt opgenomen en geanalyseerd door AI. Uw audio en video zijn gedempt. Als u ervoor kiest om de demping op te heffen, stemt u ermee in dat u wordt opgenomen.",
"recordingInProgressTitle": "Opname loopt",
"rejoinNow": "Nu opnieuw deelnemen",
"remoteControlAllowedMessage": "{{user}} heeft uw verzoek om extern beheer geaccepteerd.",
@@ -470,6 +469,8 @@
"screenSharingFailed": "Oeps! Er is iets misgegaan, de schermdeling kon niet worden gestart!",
"screenSharingFailedTitle": "Schermdeling mislukt!",
"screenSharingPermissionDeniedError": "Oeps! Er is iets misgegaan met uw toegangsrechten voor schermdeling. Herlaad en probeer opnieuw.",
"screenshareStoppedDiskSpace": "Dit gebeurt als u de zwevende werkbalk van macOS hebt gebruikt om het delen van schermen te stoppen. Het kan ook te wijten zijn aan een lage schijfruimte.",
"screenshareStoppedTitle": "Scherm delen gestopt via systeem",
"searchInSalesforce": "Zoeken in Salesforce",
"searchResults": "Zoekresultaten({{count}})",
"searchResultsDetailsError": "Er ging iets mis bij het ophalen van eigenaargegevens.",
@@ -712,8 +713,6 @@
"googlePrivacyPolicy": "Privacybeleid Google",
"inProgress": "Opname of livestreaming gaande",
"invalidStreamKey": "Livestream-sleutel is mogelijk onjuist.",
"limitNotificationDescriptionNative": "Uw stream zal beperkt worden tot {{limit}} min. Voor ongelimiteerd streamen, probeer {{app}}.",
"limitNotificationDescriptionWeb": "Vanwege een grote vraag zal uw stream beperkt worden tot {{limit}} min. Voor ongelimiteerd streamen, probeer <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Livestream gestopt",
"offBy": "{{name}} heeft de livestream gestopt.",
"on": "Livestream",
@@ -730,6 +729,7 @@
"streamIdHelp": "Wat is dit?",
"title": "Livestream",
"unavailableTitle": "Livestreamen niet beschikbaar",
"youTubeGoLiveWarning": "Vergeet niet om op 'Go Live' te klikken in YouTube Studio als Auto-Start/Auto-Stop is uitgeschakeld. Anders begint de stream niet met opnemen.",
"youtubeTerms": "Servicevoorwaarden YouTube"
},
"lobby": {
@@ -995,7 +995,7 @@
"pollQuestion": "Peiling vraag",
"questionPlaceholder": "Stel een vraag",
"removeOption": "Optie verwijderen",
"send": "Opslaan"
"save": "Opslaan"
},
"errors": {
"notUniqueOption": "Opties moeten uniek zijn"
@@ -1133,8 +1133,6 @@
"highlightMomentSuccess": "Moment gemarkeerd",
"highlightMomentSucessDescription": "Uw gemarkeerde moment wordt toegevoegd aan de samenvatting van de vergadering.",
"inProgress": "Opname of live streaming in uitvoering",
"limitNotificationDescriptionNative": "Vanwege een grote vraag wordt uw opname beperkt tot {{limit}} min. Voor ongelimiteerde opnamen, probeer <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Vanwege een grote vraag wordt uw opname beperkt tot {{limit}} min. Voor ongelimiteerde opnamen, probeer <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Wij hebben een link naar uw opname gegenereerd.",
"localRecordingNoNotificationWarning": "De opname wordt niet aan andere deelnemers bekendgemaakt. U moet hen laten weten dat de vergadering is opgenomen.",
"localRecordingNoVideo": "Video wordt niet opgenomen",
@@ -1609,6 +1607,7 @@
"addBackground": "Achtergrond toevoegen",
"apply": "Toepassen",
"backgroundEffectError": "Toepassen van achtergrondeffect niet gelukt.",
"backgroundLimitReached": "Aangepaste achtergrondlimiet bereikt",
"blur": "Vervagen",
"deleteImage": "Afbeelding verwijderen",
"desktopShare": "Bureaublad delen",
@@ -1621,6 +1620,7 @@
"image6": "Bos ",
"image7": "Zonsopkomst",
"none": "Geen",
"oldestBackgroundRemoved": "De oudste aangepaste achtergrond is verwijderd om de nieuwe toe te voegen.",
"pleaseWait": "Even geduld a.u.b…",
"removeBackground": "Verwijder achtergrond",
"slightBlur": "Licht vervagen",

View File

@@ -635,8 +635,6 @@
"googlePrivacyPolicy": "Googles personvernpolicy",
"inProgress": "Opptak eller direktesending pågår",
"invalidStreamKey": "Strømmenøkkelen kan være feil.",
"limitNotificationDescriptionNative": "Direktesendingen din vil være begrenset til {{limit}} min. For ubegrenset strømming, prøv {{app}}.",
"limitNotificationDescriptionWeb": "På grunn av høy etterspørsel vil direktesendingen din være begrenset til {{limit}} min. For ubegrenset strømming, prøv <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Direktesending stoppet",
"offBy": "{{name}} stoppet direktesendingen",
"on": "Direktesending startet",
@@ -1037,8 +1035,6 @@
"highlightMomentSuccess": "Øyeblikk markert",
"highlightMomentSucessDescription": "Det markerte øyeblikket vil bli lagt til møtereferatet.",
"inProgress": "Opptak eller direktesending pågår",
"limitNotificationDescriptionNative": "På grunn av høy etterspørsel vil opptaket være begrenset til {{limit}} min. For ubegrensede opptak, prøv <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "På grunn av høy etterspørsel vil opptaket være begrenset til {{limit}} min. For ubegrensede opptak, prøv <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Vi har generert en lenke til opptaket ditt.",
"localRecordingNoNotificationWarning": "Opptaket vil ikke bli annonsert til de andre deltakerne. Du må informere dem om at møtet blir tatt opp.",
"localRecordingNoVideo": "Video blir ikke tatt opp",

View File

@@ -635,8 +635,6 @@
"googlePrivacyPolicy": "Politica de confidencialitat de Google",
"inProgress": "Enregistrament o difusion en dirècte en cors",
"invalidStreamKey": "La clau de difusion en dirècte es benlèu pas corrècta.",
"limitNotificationDescriptionNative": "Vòstra difusion serà limitada a {{limit}} min. Per de difusions illimitada ensajatz {{app}}.",
"limitNotificationDescriptionWeb": "A causa d'una brava demanda vòstra difusion serà limitada a {{limit}} min. Per de difusion illimitada ensajatz <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "La difusion en dirècte es estada arrestada",
"offBy": "{{name}} a arrestat la difusion en dirècte",
"on": "Difusion en dirècte",
@@ -1037,8 +1035,6 @@
"highlightMomentSuccess": "Moments destacats",
"highlightMomentSucessDescription": "Vòstre moment suslinhat serà apondut al resumit de la reünion.",
"inProgress": "Enregistrament o difusion en dirècte en cors",
"limitNotificationDescriptionNative": "A causa duna demanda fòrta vòstre enregistrament serà limitat a {{limit}} min. Per denregistraments sens limit ensajatz <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "A causa duna demanda fòrta vòstre enregistrament serà limitat a {{limit}} min. Per denregistraments sens limit ensajatz <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Avèm generat un ligam pel vòstre enregistrament.",
"localRecordingNoNotificationWarning": "L'enregistrament s'anonciarà pas als autres participants. Los deuretz informar que la reünion serà enregistrada.",
"localRecordingNoVideo": "La vidèo es pas enregistrada actualament",

View File

@@ -566,8 +566,6 @@
"googlePrivacyPolicy": "Polityka prywatności Google",
"inProgress": "Trwa nagrywanie lub transmisja na żywo",
"invalidStreamKey": "Klucz transmisji na żywo może być nieprawidłowy.",
"limitNotificationDescriptionNative": "Twoje strumieniowanie będzie ograniczone do {{limit}} minut. Aby strumieniować bez ograniczeń wybróbuj {{app}}.",
"limitNotificationDescriptionWeb": "Ze względu na duże zapotrzebowanie twoje strumieniowanie będzie ograniczone do {{limit}} minut. Aby strumieniować bez ograniczeń wybróbuj <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Transmitowanie na żywo zostało zatrzymane",
"offBy": "{{name}} zatrzymał transmisję na żywo",
"on": "Strumień live",
@@ -935,8 +933,6 @@
"highlightMomentSuccess": "Zaznaczony moment",
"highlightMomentSucessDescription": "Zaznaczony moment zostanie dodany do podsumowania spotkania.",
"inProgress": "Trwa nagrywanie lub transmisja na żywo",
"limitNotificationDescriptionNative": "Ze względu na duże zapotrzebowanie twoje nagrywanie będzie ograniczone do {{limit}} minut. Aby strumieniować bez ograniczeń wybróbuj <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Ze względu na duże zapotrzebowanie twoje nagrywanie będzie ograniczone do {{limit}} minut. Aby strumieniować bez ograniczeń wybróbuj <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Wygenerowano link do nagrania.",
"live": "NA ŻYWO",
"localRecordingNoNotificationWarning": "Nagranie nie zostanie ogłoszone innym uczestnikom. Musisz poinformować ich, że spotkanie jest nagrywane.",

View File

@@ -622,8 +622,6 @@
"googlePrivacyPolicy": "Política de Privacidade do Google",
"inProgress": "Gravação ou live streaming em andamento",
"invalidStreamKey": "A senha para transmissão ao vivo pode estar incorreta.",
"limitNotificationDescriptionNative": "Sua transmissão será limitada a {{limit}} minutos. Para transmissão ilimitada tente {{app}}.",
"limitNotificationDescriptionWeb": "Devido a alta demanda sua transmissão será limitada a {{limit}} minutos. Para transmissão ilimitada tente <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Transmissão ao vivo encerrada",
"offBy": "{{name}} parou a transmissão ao vivo",
"on": "Transmissão ao Vivo",
@@ -996,8 +994,6 @@
"highlightMomentSuccess": "Momento destacado",
"highlightMomentSucessDescription": "Seu momento destacado será adicionado ao sumário da reunião.",
"inProgress": "Gravação ou live streaming em andamento",
"limitNotificationDescriptionNative": "Devido a demanda, sua gravação ficará limitada a {{limit}} minutos. Para gravação ilimitada tente <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Devido a demanda, sua gravação ficará limitada a {{limit}} minutos. Para gravação ilimitada tente <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Geramos um link para sua gravação.",
"live": "AO VIVO",
"localRecordingNoNotificationWarning": "A gravação não será anunciada aos outros participantes. Você precisará avisá-los que a reunião está sendo gravada.",

View File

@@ -370,7 +370,7 @@
"kickParticipantTitle": "Expulsar este participante?",
"kickSystemTitle": "Ai! Foste expulso da reunião.",
"kickTitle": "Ai! {{participantDisplayName}} expulsou-o da reunião",
"learnMore": "saiba mais",
"learnMore": "Saiba mais",
"linkMeeting": "Link da reunião",
"linkMeetingTitle": "Link da reunião à Força de Vendas",
"liveStreaming": "Transmissão em direto",
@@ -440,9 +440,7 @@
"recentlyUsedObjects": "Os seus objetos recentemente utilizados",
"recording": "A gravar",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Não possível enquanto a transmissão em direto estiver activa",
"recordingInProgressDescription": "Esta reunião está a ser gravada e analisada pela IA{{learnMore}}. O seu áudio e vídeo foram silenciados. Se optar por ativar o som, concorda em ser gravado.",
"recordingInProgressDescriptionFirstHalf": "Esta reunião está a ser gravada e analisada por IA.",
"recordingInProgressDescriptionSecondHalf": ". Your audio and video have been muted. If you choose to unmute, you consent to being recorded.",
"recordingInProgressDescription": "Esta reunião está a ser gravada e analisada pela IA. O seu áudio e vídeo foram silenciados. Se optar por ativar o som, concorda em ser gravado.",
"recordingInProgressTitle": "Gravação em andamento",
"rejoinNow": "Reingressar agora",
"remoteControlAllowedMessage": "{{user}} aceitou o seu pedido de controlo remoto!",
@@ -706,8 +704,6 @@
"googlePrivacyPolicy": "Política de Privacidade do Google",
"inProgress": "Gravação ou transmissão em direto em curso",
"invalidStreamKey": "A senha para transmissão em direto pode estar incorreta.",
"limitNotificationDescriptionNative": "A sua transmissão será limitada a {{limit}} min. Para uma tentativa de streaming ilimitada tente {{app}}.",
"limitNotificationDescriptionWeb": "Devido à grande procura, a sua transmissão será limitada a {{limit}} min. Para uma tentativa de streaming ilimitada tente <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Transmissão em direto encerrada",
"offBy": "{{name}} parou a transmissão em direto",
"on": "Iniciada a transmissão em direto",
@@ -1127,8 +1123,6 @@
"highlightMomentSuccess": "Momento destacado",
"highlightMomentSucessDescription": "O seu momento destacado será acrescentado ao resumo da reunião.",
"inProgress": "Gravação ou transmissão em direto em curso",
"limitNotificationDescriptionNative": "Due to high demand your recording will be limited to {{limit}} min. Para gravações ilimitadas tente <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Devido à grande procura, a sua gravação será limitada a {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Gerámos um link para a sua gravação.",
"localRecordingNoNotificationWarning": "A gravação não será anunciada aos outros participantes. Será necessário avisá-los de que a reunião está gravada.",
"localRecordingNoVideo": "O vídeo não está a ser gravado",

View File

@@ -628,8 +628,6 @@
"googlePrivacyPolicy": "Политика конфиденциальности Google",
"inProgress": "Идет запись или прямая трансляция",
"invalidStreamKey": "Похоже ключ прямой трансляции неверен.",
"limitNotificationDescriptionNative": "Ваша трансляция будет ограничена {{limit}} мин. Для неограниченного просмотра попробуйте {{app}}.",
"limitNotificationDescriptionWeb": "Из-за высокой нагрузки ваша потоковая передача будет ограничена {{limit}} мин. Для неограниченной потоковой передачи попробуйте <a href={{url}} rel='noopener noreferrer' target='_blank'> {{app}} </a>.",
"off": "Трансляция остановлена",
"offBy": "{{name}} остановил прямую трансляцию",
"on": "Трансляция",
@@ -1011,8 +1009,6 @@
"highlightMomentSuccess": "Моменты выделены",
"highlightMomentSucessDescription": "Ваши выделенные моменты будут добавлены в итоги встречи.",
"inProgress": "Идет запись или прямая трансляция",
"limitNotificationDescriptionNative": "Из-за высокой нагрузки ваша запись будет ограничена {{limit}} мин. Для неограниченного количества записей попробуйте <3> {{app}} </3>.",
"limitNotificationDescriptionWeb": "Из-за высокой нагрузки ваша запись будет ограничена {{limit}} мин. Для неограниченного количества записей попробуйте <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Мы создали ссылку на вашу запись.",
"localRecordingNoNotificationWarning": "Запись не будет объявлена другим участникам. Вам необходимо самостоятельно уведомить их о том, что встреча записывается.",
"localRecordingNoVideo": "Видео не записывается",

View File

@@ -360,7 +360,7 @@
"kickParticipantTitle": "Cheres bogare custa persone?",
"kickSystemTitle": "Ohia, t'ant bogadu dae s'addòbiu",
"kickTitle": "Ohi! {{participantDisplayName}} t'at bogadu de sa riunione",
"learnMore": "àteras informatziones",
"learnMore": "Àteras informatziones",
"linkMeeting": "Acàpia sa riunione",
"linkMeetingTitle": "Acàpia sa riunione a Salesforce",
"liveStreaming": "Trasmissione in direta",
@@ -430,9 +430,7 @@
"recentlyUsedObjects": "Ogetos impreados de reghente",
"recording": "Registrende",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Impossìbile in su mentras chi sa trasmissione in direta est ativa",
"recordingInProgressDescription": "Est in cursu sa registratzione e s'anàlisi de custu addòbiu cun IA{{learnMore}}. S'àudio e su vìdeu tuos sunt disativados. Si ddos ativas, atzetas chi siant registrados.",
"recordingInProgressDescriptionFirstHalf": "Est in cursu sa registratzione e s'anàlisi de custu addòbiu cun IA",
"recordingInProgressDescriptionSecondHalf": ". S'àudio e su vìdeu tuos sunt disativados. Si ddos ativas, atzetas chi siant registrados.",
"recordingInProgressDescription": "Est in cursu sa registratzione e s'anàlisi de custu addòbiu cun IA. S'àudio e su vìdeu tuos sunt disativados. Si ddos ativas, atzetas chi siant registrados.",
"recordingInProgressTitle": "Registratzione in cursu",
"rejoinNow": "Torra a intrare",
"remoteControlAllowedMessage": "{{user}} at atzetadu sa rechesta tua de controllu remotu.",
@@ -693,8 +691,6 @@
"googlePrivacyPolicy": "Polìtica de riservadesa de Google",
"inProgress": "Registratzione o trasmissione in direta in cursu",
"invalidStreamKey": "Sa crae pro is trasmissiones in direta podet èssere iscurreta.",
"limitNotificationDescriptionNative": "Sa trasmissione in direta tua at a èssere limitada a {{limit}} minutos. Pro una trasmissione sena lìmites, imprea {{app}}.",
"limitNotificationDescriptionWeb": "A càusa de s'arta dimanda, sa trasmissione in direta tua at a èssere limitada a {{limit}} minutos. Pro una trasmissione sena lìmites, imprea <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Trasmissione in direta firmada",
"offBy": "{{name}} at firmadu sa trasmissione in direta",
"on": "Trasmissione in direta aviada",
@@ -1111,8 +1107,6 @@
"highlightMomentSuccess": "Momentu in evidèntzia",
"highlightMomentSucessDescription": "Su momentu chi as postu in evidèntzia at a èssere agiuntu a su resumu de sa riunione.",
"inProgress": "Registratzione o trasmissione in direta in cursu",
"limitNotificationDescriptionNative": "A càusa de s'arta dimanda, sa registratzione tua at a èssere limitada a {{limit}} minutos. Pro una registratzione sena lìmites, imprea <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "A càusa de s'arta dimanda, sa registratzione tua at a èssere limitada a {{limit}} minutos. Pro registrare sena lìmites, imprea <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Amus generadu unu ligòngiu a sa registratzione tua.",
"localRecordingNoNotificationWarning": "Sa registratzione no at a èssere annuntziada a is partetzipantes. Si dd'as a dèpere fàghere iscire tue.",
"localRecordingNoVideo": "Su vìdeu no s'est registrende.",

View File

@@ -418,8 +418,6 @@
"getStreamKeyManually": "Nepodarilo sa získať žiadne živé vysielania. Skúste získať kľúč pre živé vysielanie z YouTube.",
"googlePrivacyPolicy": "Pravidlá ochrany súkromia Google",
"invalidStreamKey": "Kľúč pre živé vysielanie je nesprávny.",
"limitNotificationDescriptionNative": "Živé vysielanie je obmedzené na {{limit}} minút. Pre neobmedzené vysielanie skúste {{app}}.",
"limitNotificationDescriptionWeb": "Živé vysielanie je obmedzené na {{limit}} minút. Pre neobmedzené vysielanie skúste <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Živé vysielanie ukončené",
"offBy": "{{name}} ukončil živé vysielanie",
"on": "Živé vysielanie",
@@ -620,8 +618,6 @@
"expandedPending": "Začína sa nahrávanie…",
"failedToStart": "Nepodarilo sa začať nahrávanie",
"fileSharingdescription": "Nahrávku zdielať s účastníkmi stretnutia",
"limitNotificationDescriptionNative": "Nahrávanie je obmedzené na {{limit}} minút. Pre neobmedzené nahrávanie skúste <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Nahrávanie je obmedzené na {{limit}} minút. Pre neobmedzené nahrávanie skúste <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"live": "LIVE",
"loggedIn": "Prihlásený ako {{userName}}",
"off": "Nahrávanie zastavené",

View File

@@ -480,8 +480,6 @@
"getStreamKeyManually": "Ni bilo mogoče najti prenosov v živo. Poskusite pridobiti ključ za prenos v živo iz YouTuba.",
"googlePrivacyPolicy": "Politika zasebnosti Google",
"invalidStreamKey": "Ključ prenosa v živo je morda napačen.",
"limitNotificationDescriptionNative": "Vaš prenos v živo bo omejen na {{limit}} min. Za neomejen prenos preizkusite {{app}}.",
"limitNotificationDescriptionWeb": "Zaradi velikega povpraševanja bo vaš prenos omejen na {{limit}} min. Za neomejen prenos preizkusite <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Prenos v živo zaustavljen",
"offBy": "Uporabnik {{name}} je prekinil prenos v živo",
"on": "Prenos v živo",
@@ -778,8 +776,6 @@
"expandedPending": "Snemanje se začenja…",
"failedToStart": "Snemanja ni bilo mogoče začeti",
"fileSharingdescription": "Delite snemanje z udeleženci srečanja",
"limitNotificationDescriptionNative": "Zaradi velikega povpraševanja bo snemanje omejeno na {{limit}} min. Za neomejeno snemanje preizkusite <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Zaradi velikega povpraševanja bo snemanje omejeno na {limit}} min. Za neomejeno snemanje preizkusite <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Ustvarili smo povezava do posnetka.",
"live": "V ŽIVO",
"loggedIn": "Vpisan kot {{userName}}",

View File

@@ -373,7 +373,7 @@
"kickParticipantTitle": "Të përzihet ky pjesëmarrës?",
"kickSystemTitle": "Ooh! U përzutë nga takimi",
"kickTitle": "Ooh! {{participantDisplayName}} ju përzuri nga takimi",
"learnMore": "mësoni më tepër",
"learnMore": "Mësoni më tepër",
"linkMeeting": "Lidheni takimin",
"linkMeetingTitle": "Lidheni takimin me Salesforce",
"liveStreaming": "Transmetim i Drejtpërdrejtë",
@@ -445,9 +445,7 @@
"recentlyUsedObjects": "Së fundi përdorët objekte",
"recording": "Regjistrim",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Jo i mundshëm, kur ka aktiv një transmetim të drejtpërdrejtë",
"recordingInProgressDescription": "Ky takim po regjistrohet dhe analizohet nga IA{{learnMore}}. Audioja dhe videoja juaj janë heshtuar. Nëse zgjidhni të hiqet heshtimi, pranimi juaj po regjistrohet.",
"recordingInProgressDescriptionFirstHalf": "Ky takim po regjistrohet dhe analizohet nga IA",
"recordingInProgressDescriptionSecondHalf": ". Audioja dhe videoja juaj janë heshtuar. Nëse zgjidhni të hiqet heshtimi, pranimi juaj po regjistrohet.",
"recordingInProgressDescription": "Ky takim po regjistrohet dhe analizohet nga IA. Audioja dhe videoja juaj janë heshtuar. Nëse zgjidhni të hiqet heshtimi, pranimi juaj po regjistrohet.",
"recordingInProgressTitle": "Regjistrim në kryerje e sipër",
"rejoinNow": "Rihyni tani",
"remoteControlAllowedMessage": "{{user}} pranoi kërkesën tuaj për kontroll së largëti!",
@@ -712,8 +710,6 @@
"googlePrivacyPolicy": "Rregulla Privatësie Google",
"inProgress": "Regjistrim ose transmetim i drejtpërdrejtë në punë e sipër",
"invalidStreamKey": "Kyçi për transmetim të drejtpërdrejtë mund të jetë i pasaktë.",
"limitNotificationDescriptionNative": "Transmetimi juaj do të kufizohet në {{limit}} min. Për transmetim të pakufizuar, provoni {{app}}.",
"limitNotificationDescriptionWeb": "Për shkak kërkesash të shumta, transmetimi juaj do të kufizohet në {{limit}} min. Për transmetim të pakufizuar, provoni <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Transmetimi i Drejtpërdrejtë u ndal",
"offBy": "{{name}} ndali transmetimin e drejtpërdrejtë",
"on": "Filloi Transmetimi i Drejtpërdrejtë",
@@ -1133,8 +1129,6 @@
"highlightMomentSuccess": "Çasti u nxor në pah",
"highlightMomentSucessDescription": "Çasti i nxjerrë në pah nga ju do të shtohet te përmbledhja e takimit.",
"inProgress": "Regjistrim ose transmetim drejtpërsëdrejti në ecuri e sipër",
"limitNotificationDescriptionNative": "Për shkak kërkesash të shumta, regjistrimi juaj do të kufizohet në {{limit}} min. Për regjistrime të pakufizuara provoni <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Për shkak kërkesash të shumta, regjistrimi juaj do të kufizohet në {{limit}} min. Për regjistrime të pakufizuara provoni <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Kemi prodhuar një lidhje për te regjistrimi juaj.",
"localRecordingNoNotificationWarning": "Regjistrimi sdo tu njoftohet pjesëmarrësve të tjerë. Do tju duhet ti vini në dijeni se takimi po regjistrohet.",
"localRecordingNoVideo": "Videoja spo regjistrohet",

View File

@@ -429,9 +429,7 @@
"recentlyUsedObjects": "Dina senaste använda objekt",
"recording": "Inspelning",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Ej möjligt medan livestreaming pågår.",
"recordingInProgressDescription": "Mötet spelas in och analyseras av AI{{learnMore}}. Ditt ljud och din bild har stängts av, om du väljer att starta kamera eller mikrofon så accepterar du att bli inspelad.",
"recordingInProgressDescriptionFirstHalf": "Mötet spelas in och analyseras av AI",
"recordingInProgressDescriptionSecondHalf": "Ditt ljud och din bild har stängts av, om du väljer att starta kamera eller mikrofon så accepterar du att bli inspelad.",
"recordingInProgressDescription": "Mötet spelas in och analyseras av AI. Ditt ljud och din bild har stängts av, om du väljer att starta kamera eller mikrofon så accepterar du att bli inspelad.",
"recordingInProgressTitle": "Inspelning pågår",
"rejoinNow": "Återanslut nu",
"remoteControlAllowedMessage": "{{user}} godkände din begäran om fjärrstyrning.",
@@ -695,8 +693,6 @@
"googlePrivacyPolicy": "Googles sekretesspolicy",
"inProgress": "Inspelning eller livestreaming pågår",
"invalidStreamKey": "Livesändningslösenordet kan vara felaktigt.",
"limitNotificationDescriptionNative": "Din strömning är begränsad till {{limit}} min. För obegränsad strömning, prova {{app}}.",
"limitNotificationDescriptionWeb": "På grund av stor efterfrågan kommer din strömning att begränsas till {{limit}} min. För obegränsad strömning, prova <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Strömning avslutad",
"offBy": "{{name}} stoppade direktströmningen",
"on": "Strömma",
@@ -821,7 +817,7 @@
"focusFail": "{{component}} inte tillgänglig försöker igen om {{ms}} sek",
"gifsMenu": "GIPHY",
"groupTitle": "Notifieringar",
"hostAskedUnmute": "Värden vill att du ska stänga av ljudet",
"hostAskedUnmute": "Värden vill att du ska starta din mikrofon",
"invalidTenant": "Ogiltig tenant",
"invalidTenantHyphenDescription": "Tenant du använder har ogiltiga tecken (startar eller slutar med '-').",
"invalidTenantLengthDescription": "Tenant du använder är för lång",
@@ -1116,8 +1112,6 @@
"highlightMomentSuccess": "Moment framhävt",
"highlightMomentSucessDescription": "Ditt framhävda ögonblick läggs till i mötessammanfattningen.",
"inProgress": "Inspelning eller livestreaming pågår",
"limitNotificationDescriptionNative": "På grund av stor efterfrågan är din inspelning begränsad till {{limit}} min. För obegränsade inspelningar, försök <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "På grund av stor efterfrågan är din inspelning begränsad till {{limit}} min. För obegränsade inspelningar, prova <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Vi har genererat en länk till din inspelning.",
"localRecordingNoNotificationWarning": "Inspelningen kommer inte att meddelas till andra deltagare. Du måste meddela dem att mötet inspelas.",
"localRecordingNoVideo": "Video spelas inte in",

View File

@@ -436,8 +436,6 @@
"getStreamKeyManually": "We werent able to fetch any live streams. Try getting your live stream key from YouTube.",
"googlePrivacyPolicy": "గూగుల్ గోప్యతా విధానం",
"invalidStreamKey": "Live stream key may be incorrect.",
"limitNotificationDescriptionNative": "Your streaming will be limited to {{limit}} min. For unlimited streaming try {{app}}.",
"limitNotificationDescriptionWeb": "Due to high demand your streaming will be limited to {{limit}} min. For unlimited streaming try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Live Streaming stopped",
"offBy": "{{name}} stopped the live streaming",
"on": "Live Streaming started",
@@ -672,8 +670,6 @@
"expandedPending": "రికార్డింగు మొదలవుతూన్నది…",
"failedToStart": "రికార్డింగు మొదలవడం విఫలమైంది",
"fileSharingdescription": "రికార్డింగును సదస్యులతో పంచుకోండి",
"limitNotificationDescriptionNative": "Due to high demand your recording will be limited to {{limit}} min. For unlimited recordings try <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Due to high demand your recording will be limited to {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"live": "LIVE",
"loggedIn": "{{userName}}‌గా ప్రవేశించారు",
"off": "రికార్డింగు ఆగిపోయింది",

View File

@@ -634,8 +634,6 @@
"googlePrivacyPolicy": "Google Gizlilik Politikası",
"inProgress": "Kaydetme veya canlı akış işlemde",
"invalidStreamKey": "Canlı akış anahtarı yanlış olabilir.",
"limitNotificationDescriptionNative": "Akışınız {{limit}} dk ile sınırlı olacak. Sınırsız akış için {{app}} deneyin.",
"limitNotificationDescriptionWeb": "Yüksek talep nedeniyle akışınız {{limit}} dk ile sınırlı olacaktır. Sınırsız akış için <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a> deneyin.",
"off": "Canlı Akış durduruldu",
"offBy": "{{name}} canlı akışı durdurdu",
"on": "Canlı Akış başlatıldı",
@@ -1031,8 +1029,6 @@
"highlightMomentSuccess": "An vurgulandı",
"highlightMomentSucessDescription": "Vurgulanan anınız toplantı özetine eklenecektir.",
"inProgress": "Kayıt veya canlı akış devam ediyor",
"limitNotificationDescriptionNative": "Yüksek talep nedeniyle kaydınız {{limit}} dakika ile sınırlı olacaktır. Sınırsız kayıt için deneyin <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Yüksek talep nedeniyle kaydınız {{limit}} dakika ile sınırlı olacaktır. Sınırsız kayıt için deneyin <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Kaydınızla ilgili link oluşturduk.",
"localRecordingNoNotificationWarning": "Kayıt diğer katılımcılara duyurulmayacaktır. Onlara toplantının kaydedildiğini bildirmeniz gerekecek.",
"localRecordingNoVideo": "Video kaydedilmiyor",

View File

@@ -564,8 +564,6 @@
"googlePrivacyPolicy": "Політика конфіденційності Google",
"inProgress": "Триває запис або трансляція наживо",
"invalidStreamKey": "Ключ до трансляції наживо неправильний.",
"limitNotificationDescriptionNative": "Ваша трансляція наживо буде обмежена {{limit}} хв. Для необмеженої трансляції, спробуйте {{app}}",
"limitNotificationDescriptionWeb": "Через високе навантаження, трансляція наживо буде обмежена {{limit}} хв. Для необмеженої трансляції, спробуйте <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Трансляцію наживо зупинено",
"offBy": "{{name}} зупинив трансляцію наживо",
"on": "Трансляція наживо",
@@ -930,8 +928,6 @@
"highlightMomentSuccess": "Подію виділено",
"highlightMomentSucessDescription": "Виділену подію буде додано до підсумку зустрічі.",
"inProgress": "Триває запис або трансляція наживо",
"limitNotificationDescriptionNative": "Через велике навантаження сервера ваш запис буде обмежено {{limit}}хв. Для можливості безлімітних записів, спробуйте <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Через велике навантаження сервера ваш запис буде обмежено {{limit}} хв. Для можливості безлімітних записів, спробуйте <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Готово посилання на ваш запис.",
"live": "НАЖИВО",
"localRecordingNoNotificationWarning": "Наявність посилання на запис зустрічі не анонсується іншим учасникам. Повідомте їм про це окремо.",

View File

@@ -629,8 +629,6 @@
"googlePrivacyPolicy": "Chính sách bảo mật của Google",
"inProgress": "Đang ghi hoặc phát trực tiếp",
"invalidStreamKey": "Mã phát trực tuyến có thể sai.",
"limitNotificationDescriptionNative": "Việc phát trực tuyến của bạn sẽ bị giới hạn ở {{limit}} phút. Để phát trực tuyến không giới hạn, hãy thử {{app}}.",
"limitNotificationDescriptionWeb": "Do nhu cầu cao, việc phát trực tuyến của bạn sẽ bị giới hạn ở {{limit}} phút. Để phát trực tuyến không giới hạn, hãy thử <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}</a>.",
"off": "Phát trực tuyến đã dừng",
"offBy": "{{name}} đã dừng ghi",
"on": "Phát trực tuyến",
@@ -1009,8 +1007,6 @@
"highlightMomentSuccess": "Khoảnh khắc được đánh dấu",
"highlightMomentSucessDescription": "Khoảnh khắc bạn đã đánh dấu sẽ được thêm vào tóm tắt cuộc họp.",
"inProgress": "Đang ghi âm hoặc phát trực tiếp",
"limitNotificationDescriptionNative": "Do nhu cầu cao, ghi âm của bạn sẽ bị giới hạn trong {{limit}} phút. Để có ghi âm không giới hạn, hãy thử <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Do nhu cầu cao, ghi âm của bạn sẽ bị giới hạn trong {{limit}} phút. Để có ghi âm không giới hạn, hãy thử <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Chúng tôi đã tạo một liên kết đến ghi âm của bạn.",
"localRecordingNoNotificationWarning": "Cuộc họp sẽ không được thông báo cho các thành viên khác. Bạn sẽ cần thông báo cho họ biết cuộc họp đang được ghi âm.",
"localRecordingNoVideo": "Video không được ghi lại",

View File

@@ -433,9 +433,7 @@
"recentlyUsedObjects": "你最近使用的对象",
"recording": "录制中",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "直播时无法使用",
"recordingInProgressDescription": "本会议正由AI录制并分析{{learnMore}},你已被静音。如需发言,视为同意录制。",
"recordingInProgressDescriptionFirstHalf": "本会议正由AI录制并分析",
"recordingInProgressDescriptionSecondHalf": ",你已被静音。如需发言,视为同意录制。",
"recordingInProgressDescription": "本会议正由AI录制并分析你已被静音。如需发言视为同意录制。",
"recordingInProgressTitle": "录制中",
"rejoinNow": "马上重新加入",
"remoteControlAllowedMessage": "{{user}}接受了你的远程控制请求!",
@@ -699,8 +697,6 @@
"googlePrivacyPolicy": "Google 隐私权政策",
"inProgress": "录制或直播正在进行中",
"invalidStreamKey": "直播码可能不正确。",
"limitNotificationDescriptionNative": "你的直播将被限制在{{limit}}分钟之内,如需不受限的直播,请使用{{app}}。",
"limitNotificationDescriptionWeb": "由于需求量大,你的直播将被限制在{{limit}}分钟之内。如需不受限的直播,请使用<a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>。",
"off": "直播已停止",
"offBy": "{{name}}已停止直播",
"on": "直播已开始",
@@ -1122,8 +1118,6 @@
"highlightMomentSuccess": "时刻已突出显示",
"highlightMomentSucessDescription": "你突出显示的时刻将会添加到会议摘要中。",
"inProgress": "正在进行录制或直播流",
"limitNotificationDescriptionNative": "由于高需求,您的录制将限制在{{limit}}分钟内。若要无限制录制,请尝试<3>{{app}}</3>。",
"limitNotificationDescriptionWeb": "由于高需求,您的录制将限制在{{limit}}分钟内。若要无限制录制,请尝试<a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>。",
"linkGenerated": "我们已生成录制链接。",
"localRecordingNoNotificationWarning": "系统不会主动通知参会者录制已开启,主持人需另行提醒。",
"localRecordingNoVideo": "视频未被录制",

View File

@@ -433,9 +433,7 @@
"recentlyUsedObjects": "您最近使用過的物件",
"recording": "錄製中",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "正在直播時無法使用",
"recordingInProgressDescription": "本會議正在錄製並由 AI 分析{{learnMore}},您的音訊與影像已靜音。如果您選擇取消靜音,即表示您同意被錄製。",
"recordingInProgressDescriptionFirstHalf": "本會議正在錄製並由 AI 分析",
"recordingInProgressDescriptionSecondHalf": ",您的音訊與影像已靜音。如果您選擇取消靜音,即表示您同意被錄製。",
"recordingInProgressDescription": "本會議正在錄製並由 AI 分析,您的音訊與影像已靜音。如果您選擇取消靜音,即表示您同意被錄製。",
"recordingInProgressTitle": "正在錄製",
"rejoinNow": "立即重新加入",
"remoteControlAllowedMessage": "{{user}} 接受您進行遠端控制的請求!",
@@ -699,8 +697,6 @@
"googlePrivacyPolicy": "Google 隱私權政策",
"inProgress": "正在錄製或直播",
"invalidStreamKey": "直播串流金鑰可能不正確。",
"limitNotificationDescriptionNative": "您的最大直播長度將被限制在 {{limit}} 分鐘,若要不受限的直播,請使用 {{app}}。",
"limitNotificationDescriptionWeb": "由於目前流量過大,您的最大直播長度將被限制在 {{limit}} 分鐘。若要不受限的直播,請使用 <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>。",
"off": "直播串流已停用",
"offBy": "{{name}} 停用了直播串流",
"on": "直播串流已啟動",
@@ -1122,8 +1118,6 @@
"highlightMomentSuccess": "已精選的時刻",
"highlightMomentSucessDescription": "您的精選時刻將新增至會議摘要。",
"inProgress": "正在錄製或直播",
"limitNotificationDescriptionNative": "由於目前流量過大,您的錄製時間被限制在 {{limit}} 分鐘。若要無限制的錄製,請試試 <3>{{app}}</3>。",
"limitNotificationDescriptionWeb": "由於目前流量過大,您的錄製時間被限制在 {{limit}} 分鐘。若要無限制的錄製,請試試 <a href={{url}}rel='noopener noreferrer' target='_blank'>{{app}}</a>。",
"linkGenerated": "我們建立了您的錄製檔案的連結。",
"localRecordingNoNotificationWarning": "系統不會主動知會與會者錄製已開啟,主持人需另行通知。",
"localRecordingNoVideo": "沒有錄製的視訊",

View File

@@ -373,7 +373,7 @@
"kickParticipantTitle": "Kick this participant?",
"kickSystemTitle": "Ouch! You were kicked out of the meeting",
"kickTitle": "Ouch! {{participantDisplayName}} kicked you out of the meeting",
"learnMore": "learn more",
"learnMore": "Learn more",
"linkMeeting": "Link meeting",
"linkMeetingTitle": "Link meeting to Salesforce",
"liveStreaming": "Live Streaming",
@@ -385,6 +385,7 @@
"login": "Login",
"loginFailed": "Login failed.",
"loginOnResume": "Your authentication session has expired. You need to login again to continue the meeting.",
"loginPopupBlocked": "Login popup was blocked by your browser.",
"loginQuestion": "Are you sure you want to login and leave the conference?",
"logoutQuestion": "Are you sure you want to logout and leave the conference?",
"logoutTitle": "Logout",
@@ -445,9 +446,7 @@
"recentlyUsedObjects": "Your recently used objects",
"recording": "Recording",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Not possible while a live stream is active",
"recordingInProgressDescription": "This meeting is being recorded and analyzed by AI{{learnMore}}. Your audio and video have been muted. If you choose to unmute, you consent to being recorded.",
"recordingInProgressDescriptionFirstHalf": "This meeting is being recorded and analyzed by AI",
"recordingInProgressDescriptionSecondHalf": ". Your audio and video have been muted. If you choose to unmute, you consent to being recorded.",
"recordingInProgressDescription": "This meeting is being recorded and analyzed by AI. Your audio and video have been muted. If you choose to unmute, you consent to being recorded.",
"recordingInProgressTitle": "Recording in progress",
"rejoinNow": "Rejoin now",
"remoteControlAllowedMessage": "{{user}} accepted your remote control request!",
@@ -470,6 +469,8 @@
"screenSharingFailed": "Oops! Something went wrong, we weren't able to start screen sharing!",
"screenSharingFailedTitle": "Screen sharing failed!",
"screenSharingPermissionDeniedError": "Oops! Something went wrong with your screen sharing permissions. Please reload and try again.",
"screenshareStoppedDiskSpace": "This happens if you used the macOS's floating toolbar to stop screen sharing. It may also be due to low disk space.",
"screenshareStoppedTitle": "Screen sharing stopped via system",
"searchInSalesforce": "Search in Salesforce",
"searchResults": "Search results({{count}})",
"searchResultsDetailsError": "Something went wrong while retrieving owner data.",
@@ -712,8 +713,6 @@
"googlePrivacyPolicy": "Google Privacy Policy",
"inProgress": "Recording or live streaming in progress",
"invalidStreamKey": "Live stream key may be incorrect.",
"limitNotificationDescriptionNative": "Your streaming will be limited to {{limit}} min. For unlimited streaming try {{app}}.",
"limitNotificationDescriptionWeb": "Due to high demand your streaming will be limited to {{limit}} min. For unlimited streaming try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"off": "Live Streaming stopped",
"offBy": "{{name}} stopped the live streaming",
"on": "Live Streaming started",
@@ -730,6 +729,7 @@
"streamIdHelp": "What's this?",
"title": "Live Stream",
"unavailableTitle": "Live Streaming unavailable",
"youTubeGoLiveWarning": "Remember to click 'Go Live' in YouTube Studio if Auto-Start/Auto-Stop are disabled. Otherwise the stream will not begin recording.",
"youtubeTerms": "YouTube terms of services"
},
"lobby": {
@@ -1133,8 +1133,6 @@
"highlightMomentSuccess": "Moment highlighted",
"highlightMomentSucessDescription": "Your highlighted moment will be added to the meeting summary.",
"inProgress": "Recording or live streaming in progress",
"limitNotificationDescriptionNative": "Due to high demand your recording will be limited to {{limit}} min. For unlimited recordings try <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Due to high demand your recording will be limited to {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "We have generated a link to your recording.",
"localRecordingNoNotificationWarning": "The recording will not be announced to other participants. You will need to let them know that the meeting is recorded.",
"localRecordingNoVideo": "Video is not being recorded",
@@ -1609,6 +1607,7 @@
"addBackground": "Add background",
"apply": "Apply",
"backgroundEffectError": "Failed to apply background effect.",
"backgroundLimitReached": "Custom background limit reached",
"blur": "Blur",
"deleteImage": "Delete image",
"desktopShare": "Desktop share",
@@ -1621,6 +1620,7 @@
"image6": "Forest ",
"image7": "Sunrise",
"none": "None",
"oldestBackgroundRemoved": "The oldest custom background has been removed to add the new one.",
"pleaseWait": "Please wait…",
"removeBackground": "Remove background",
"slightBlur": "Half Blur",

View File

@@ -2325,6 +2325,7 @@ class API {
* @returns {void}
*/
notifyPictureInPictureRequested() {
logger.debug('Sending _pip-requested event to External API');
this._sendEvent({
name: '_pip-requested'
});
@@ -2336,6 +2337,7 @@ class API {
* @returns {void}
*/
notifyPictureInPictureEntered() {
logger.debug('Sending pip-entered event to External API');
this._sendEvent({
name: 'pip-entered'
});
@@ -2347,6 +2349,7 @@ class API {
* @returns {void}
*/
notifyPictureInPictureLeft() {
logger.debug('Sending pip-left event to External API');
this._sendEvent({
name: 'pip-left'
});

View File

@@ -3,15 +3,11 @@
const UI = {};
import Logger from '@jitsi/logger';
import {
conferenceWillInit
} from '../../react/features/base/conference/actions';
import { isMobileBrowser } from '../../react/features/base/environment/utils';
import { setColorAlpha } from '../../react/features/base/util/helpers';
import { sanitizeUrl } from '../../react/features/base/util/uri';
import { setDocumentUrl } from '../../react/features/etherpad/actions';
import {
setNotificationsEnabled,
showNotification
@@ -28,8 +24,6 @@ import EtherpadManager from './etherpad/Etherpad';
import UIUtil from './util/UIUtil';
import VideoLayout from './videolayout/VideoLayout';
const logger = Logger.getLogger('ui:core');
let etherpadManager;
/**
@@ -117,24 +111,17 @@ UI.unbindEvents = () => {
/**
* Setup and show Etherpad.
* @param {string} name etherpad id
*/
UI.initEtherpad = name => {
const { getState, dispatch } = APP.store;
UI.initEtherpad = () => {
const { getState } = APP.store;
const configState = getState()['features/base/config'];
const etherpadBaseUrl = sanitizeUrl(configState.etherpad_base);
if (etherpadManager || !etherpadBaseUrl || !name) {
if (etherpadManager) {
return;
}
logger.log('Etherpad is enabled');
etherpadManager = new EtherpadManager();
const url = new URL(name, etherpadBaseUrl);
dispatch(setDocumentUrl(url.toString()));
if (configState.openSharedDocumentOnJoin) {
etherpadManager.toggleEtherpad();
}

3620
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -57,10 +57,10 @@
"clipboard-copy": "4.0.1",
"clsx": "1.1.1",
"dayjs": "1.11.13",
"dompurify": "3.2.6",
"dompurify": "3.3.2",
"dropbox": "10.7.0",
"focus-visible": "5.1.0",
"glob": "11.0.3",
"glob": "12.0.0",
"grapheme-splitter": "1.0.4",
"i18n-iso-countries": "6.8.0",
"i18next": "17.0.6",
@@ -72,8 +72,8 @@
"js-md5": "0.6.1",
"js-sha512": "0.8.0",
"jwt-decode": "2.2.0",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2132.0.0+92c8c183/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2140.0.0+fe26afb0/lib-jitsi-meet.tgz",
"lodash-es": "4.17.23",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
"pixelmatch": "5.3.0",
@@ -164,12 +164,12 @@
"@types/w3c-image-capture": "1.0.6",
"@types/w3c-web-hid": "1.0.3",
"@types/zxcvbn": "4.4.1",
"@wdio/allure-reporter": "9.23.2",
"@wdio/cli": "9.23.2",
"@wdio/globals": "9.23.0",
"@wdio/junit-reporter": "9.23.2",
"@wdio/local-runner": "9.23.2",
"@wdio/mocha-framework": "9.23.2",
"@wdio/allure-reporter": "9.27.0",
"@wdio/cli": "9.27.0",
"@wdio/globals": "9.27.0",
"@wdio/junit-reporter": "9.27.0",
"@wdio/local-runner": "9.27.0",
"@wdio/mocha-framework": "9.27.0",
"babel-loader": "9.1.0",
"babel-plugin-optional-require": "0.3.1",
"circular-dependency-plugin": "5.2.0",
@@ -184,6 +184,7 @@
"eslint-plugin-typescript-sort-keys": "3.3.0",
"jetifier": "1.6.4",
"jsonwebtoken": "9.0.2",
"junit-report-builder": "5.1.1",
"patch-package": "6.4.7",
"pretty": "2.0.0",
"process": "0.11.10",
@@ -193,15 +194,15 @@
"ts-loader": "9.4.2",
"typescript": "5.7.2",
"unorm": "1.6.0",
"webdriverio": "9.22.0",
"webdriverio": "9.27.0",
"webpack": "5.105.0",
"webpack-bundle-analyzer": "4.4.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "5.1.0"
"webpack-dev-server": "5.2.1"
},
"engines": {
"node": ">=22.0.0",
"npm": ">=10.0.0"
"node": ">=24.0.0",
"npm": ">=11.0.0"
},
"license": "Apache-2.0",
"scripts": {

View File

@@ -1 +1,6 @@
*.tgz
tsconfig.json
.npmrc
.git
.gitignore
node_modules

View File

@@ -2,7 +2,8 @@
"name": "@jitsi/react-native-sdk",
"version": "0.0.0",
"description": "React Native SDK for Jitsi Meet.",
"main": "index.tsx",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"license": "Apache-2.0",
"author": "",
"homepage": "https://jitsi.org",
@@ -92,9 +93,27 @@
"@babel/plugin-proposal-optional-chaining": "0.0.0"
},
"scripts": {
"build": "tsc -p tsconfig.json",
"postinstall": "node sdk_instructions.js",
"prepare": "node prepare_sdk.js"
"prepare": "node prepare_sdk.js && npm run build"
},
"files": [
"dist",
"android",
"ios",
"index.tsx",
"jitsi-meet-rnsdk.podspec",
"prepare_sdk.js",
"sdk_instructions.js",
"update_dependencies.js",
"update_sdk_dependencies.js",
"README.md",
"images",
"sounds",
"lang",
"modules",
"react"
],
"bugs": {
"url": "https://github.com/jitsi/jitsi-meet/issues"
},

View File

@@ -0,0 +1,17 @@
{
"extends": "../tsconfig.native.json",
"compilerOptions": {
"outDir": "./dist",
"declaration": true,
"declarationMap": true,
"sourceMap": true,
"emitDeclarationOnly": false
},
"include": [
"index.tsx"
],
"exclude": [
"node_modules",
"dist"
]
}

View File

@@ -1,9 +1,50 @@
import { createInstance } from '@amplitude/analytics-browser';
import { EnrichmentPlugin, Event, PluginType } from '@amplitude/analytics-types';
const amplitude = createInstance();
export default amplitude;
function stripParam(url?: string): string | undefined {
if (!url) return url;
try {
const u = new URL(url);
u.hash = '';
u.search = '';
return u.toString();
} catch {
return url.split('#')[0].split('?')[0];
}
}
class StripParamsPlugin implements EnrichmentPlugin {
name: 'strip-params-plugin';
type: PluginType.ENRICHMENT;
async setup(): Promise<void> {
return undefined;
}
async execute(event: Event): Promise<Event | null> {
const { event_properties } = event;
if (event_properties) {
// These are only needed to make TS happy.
type EventPropertiesKey = keyof typeof event_properties;
const PAGE_LOCATION_KEY = '[Amplitude] Page Location' as EventPropertiesKey;
const PAGE_URL_KEY = '[Amplitude] Page URL' as EventPropertiesKey;
event_properties[PAGE_LOCATION_KEY] = stripParam(event_properties[PAGE_LOCATION_KEY]);
event_properties[PAGE_URL_KEY] = stripParam(event_properties[PAGE_URL_KEY]);
}
return event;
}
}
/**
* Initializes the Amplitude instance.
*
@@ -31,8 +72,9 @@ export function initAmplitude(
formInteractions: false,
elementInteractions: false
},
defaultTracking: false
};
amplitude.add(new StripParamsPlugin());
return amplitude.init(amplitudeAPPKey, user, options).promise;
}

View File

@@ -122,9 +122,8 @@ export function maybeRedirectToTokenAuthUrl(
const refreshToken = state['features/base/jwt'].refreshToken;
const expirationDate = getJwtExpirationDate(jwt);
// if there is jwt and its expiration time is less than 3 minutes away
// let's obtain new token
if (expirationDate && expirationDate.getTime() - Date.now() < 3 * 60 * 1000) {
// if there is jwt token, and it is expired let's obtain a new one
if (expirationDate && expirationDate.getTime() <= Date.now()) {
const room = state['features/base/conference'].room;
const { tenant } = parseURIString(locationURL.href) || {};

View File

@@ -18,7 +18,7 @@ import isInsecureRoomName from '../base/util/isInsecureRoomName';
import { parseURLParams } from '../base/util/parseURLParams';
import {
appendURLParam,
getBackendSafeRoomName,
getNormalizedRoomName,
parseURIString,
toURLString
} from '../base/util/uri';
@@ -110,7 +110,7 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
let url = `${baseURL}config.js`;
// XXX In order to support multiple shards, tell the room to the deployment.
room && (url = appendURLParam(url, 'room', getBackendSafeRoomName(room) ?? ''));
room && (url = appendURLParam(url, 'room', getNormalizedRoomName(room) ?? ''));
const { release } = parseURLParams(location, true, 'search');

View File

@@ -4,7 +4,8 @@ import { connect } from '../base/connection/actions';
import { openDialog } from '../base/dialog/actions';
import { setJWT } from '../base/jwt/actions';
import { browser } from '../base/lib-jitsi-meet';
import { showErrorNotification } from '../notifications/actions';
import { hideNotification, showErrorNotification, showNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE, NOTIFICATION_TYPE } from '../notifications/constants';
import { CANCEL_LOGIN } from './actionTypes';
import LoginQuestionDialog from './components/web/LoginQuestionDialog';
@@ -13,6 +14,22 @@ import logger from './logger';
export * from './actions.any';
const PROMPT_POPUP_NOTIFICATION_ID = 'PROMPT_POPUP_NOTIFICATION_ID';
/**
* Custom error that includes a recovery callback.
*/
class PopupBlockedError extends Error {
constructor(
message: string = 'Popup was blocked by browser',
public readonly retry?: () => Window | null
) {
super(message);
this.name = 'PopupBlockedError';
Error.captureStackTrace(this, PopupBlockedError);
}
}
/**
* Cancels {@ink LoginDialog}.
*
@@ -68,17 +85,12 @@ function generateNonce(): string {
* Performs login with a popup window.
*
* @param {string} tokenAuthServiceUrl - Authentication service URL.
* @param {Window|undefined} popup - Authentication service URL.
* @returns {Promise<any>} A promise that resolves with the authentication
* result or rejects with an error.
*/
export function loginWithPopup(tokenAuthServiceUrl: string): Promise<any> {
export function loginWithPopup(tokenAuthServiceUrl: string, popup?: Window | null): Promise<any> {
return new Promise<any>((resolve, reject) => {
// Open popup
const width = 500;
const height = 600;
const left = window.screen.width / 2 - width / 2;
const top = window.screen.height / 2 - height / 2;
let nonceParam = '';
try {
@@ -97,14 +109,30 @@ export function loginWithPopup(tokenAuthServiceUrl: string): Promise<any> {
}
}
const popup = window.open(
`${tokenAuthServiceUrl}${nonceParam}`,
`Auth-${Date.now()}`,
`width=${width},height=${height},left=${left},top=${top}`
);
const openPopup = () => {
// Open popup
const width = 500;
const height = 600;
const left = window.screen.width / 2 - width / 2;
const top = window.screen.height / 2 - height / 2;
return window.open(
`${tokenAuthServiceUrl}${nonceParam}`,
`Auth-${Date.now()}`,
`width=${width},height=${height},left=${left},top=${top}`
);
};
if (!popup) {
reject(new Error('Popup blocked'));
popup = openPopup();
}
if (!popup) {
// adds a callback to the error that can be used to directly retry where window.open will be executed
// on the user click without any promises(dispatches) incoved
reject(new PopupBlockedError('Popup blocked', () => {
return openPopup();
}));
return;
}
@@ -113,7 +141,7 @@ export function loginWithPopup(tokenAuthServiceUrl: string): Promise<any> {
const cleanup = (handler: (event: MessageEvent) => void) => {
window.removeEventListener('message', handler);
clearInterval(closedPollInterval);
popup.close();
popup?.close();
try {
sessionStorage.removeItem('oauth_nonce');
@@ -153,7 +181,7 @@ export function loginWithPopup(tokenAuthServiceUrl: string): Promise<any> {
// Detect manual popup close before authentication completes
closedPollInterval = setInterval(() => {
if (popup.closed) {
if (popup?.closed) {
cleanup(handler);
reject(new Error('Login cancelled'));
}
@@ -210,41 +238,62 @@ export function openTokenAuthUrl(tokenAuthServiceUrl: string): any {
};
if (!browser.isElectron() && isTokenAuthInline(getState()['features/base/config'])) {
loginWithPopup(tokenAuthServiceUrl)
.then((result: { accessToken: string; idToken: string; refreshToken?: string; }) => {
// @ts-ignore
const token: string = result.accessToken;
const idToken: string = result.idToken;
const refreshToken: string | undefined = result.refreshToken;
const login = (popup?: Window | null) => {
return loginWithPopup(tokenAuthServiceUrl, popup)
.then((result: { accessToken: string; idToken: string; refreshToken?: string; }) => {
// @ts-ignore
const token: string = result.accessToken;
const idToken: string = result.idToken;
const refreshToken: string | undefined = result.refreshToken;
// @ts-ignore
dispatch(setJWT(token, idToken, refreshToken));
// @ts-ignore
dispatch(setJWT(token, idToken, refreshToken));
logger.info('Reconnecting to conference with new token.');
logger.info('Reconnecting to conference with new token.');
const { connection } = getState()['features/base/connection'];
const { connection } = getState()['features/base/connection'];
if (connection) {
connection.refreshToken(token).then(
() => {
const { membersOnly } = getState()['features/base/conference'];
if (connection) {
connection.refreshToken(token).then(
() => {
const { membersOnly } = getState()['features/base/conference'];
membersOnly?.join();
})
.catch((err: any) => {
dispatch(setJWT());
logger.error(err);
});
} else {
dispatch(connect());
}
})
.catch(err => {
membersOnly?.join();
})
.catch((err: any) => {
dispatch(setJWT());
logger.error(err);
});
} else {
dispatch(connect());
}
});
};
login().catch(err => {
if (err instanceof PopupBlockedError) {
dispatch(showNotification({
titleKey: 'dialog.loginPopupBlocked',
uid: PROMPT_POPUP_NOTIFICATION_ID,
customActionNameKey: [ 'dialog.retry' ],
customActionHandler: [ () => {
dispatch(hideNotification(PROMPT_POPUP_NOTIFICATION_ID));
// the window.open will be executed directly from the onClick handler of the notification action button
login(err.retry ? err.retry() : undefined)
.catch(logger.error);
} ],
appearance: NOTIFICATION_TYPE.ERROR
}, NOTIFICATION_TIMEOUT_TYPE.STICKY));
} else {
// let's add expand that will show the error message in the notification
dispatch(showErrorNotification({
titleKey: 'dialog.loginFailed'
}));
logger.error(err);
});
}
logger.error(err);
});
return;
}

View File

@@ -95,12 +95,6 @@ export function commonUserJoinedHandling(
const isPromoted = conference?.getMetadataHandler().getMetadata()?.visitors?.promoted?.[id];
const userIdentity = user.getIdentity()?.user;
// Map identity from JWT context to userContext for external API
const userContext = userIdentity ? {
id: userIdentity.id,
name: userIdentity.name
} : undefined;
// the identity and avatar come from jwt and never change in the presence
dispatch(participantJoined({
avatarURL: userIdentity?.avatar,
@@ -113,7 +107,7 @@ export function commonUserJoinedHandling(
isPromoted,
isReplacing,
sources: user.getSources(),
userContext
userContext: userIdentity
}));
}
}

View File

@@ -539,11 +539,6 @@ export interface IConfig {
disableRemoveRaisedHandOnFocus?: boolean;
};
readOnlyName?: boolean;
recordingLimit?: {
appName?: string;
appURL?: string;
limit?: number;
};
recordingService?: {
enabled?: boolean;
hideStorageWarning?: boolean;

View File

@@ -9,7 +9,8 @@ import { isEmbedded } from '../util/embedUtils';
import { parseURLParams } from '../util/parseURLParams';
import {
appendURLParam,
getBackendSafeRoomName
getBackendSafeRoomName,
getNormalizedRoomName
} from '../util/uri';
import {
@@ -142,7 +143,7 @@ export function constructOptions(state: IReduxState) {
const { room } = state['features/base/conference'];
if (serviceUrl && room) {
const roomName = getBackendSafeRoomName(room);
const roomName = getNormalizedRoomName(room);
options.serviceUrl = appendURLParam(serviceUrl, 'room', roomName ?? '');

View File

@@ -1,3 +1,4 @@
import { noop } from 'lodash-es';
declare let config: any;
@@ -5,12 +6,7 @@ declare let config: any;
* Custom language detection, just returns the config property if any.
*/
export default {
/**
* Does not support caching.
*
* @returns {void}
*/
cacheUserLanguage: Function.prototype,
cacheUserLanguage: noop,
/**
* Looks the language up in the config.

View File

@@ -29,18 +29,3 @@ export function translate<P extends WithTranslation>(component: React.ComponentT
// Use the default list of namespaces.
return withTranslation([ 'main', 'languages', 'countries' ])(component);
}
/**
* Translates a specific key to text containing HTML via a specific translate
* function.
*
* @param {Function} t - The translate function.
* @param {string} key - The key to translate.
* @param {Array<*>} options - The options, if any, to pass to {@link t}.
* @returns {ReactElement} A ReactElement which depicts the translated HTML
* text.
*/
export function translateToHTML(t: Function, key: string, options: Object = {}) {
// eslint-disable-next-line react/no-danger
return <span dangerouslySetInnerHTML = {{ __html: t(key, options) }} />;
}

View File

@@ -0,0 +1,19 @@
import React from 'react';
import { Text } from 'react-native';
export { changeLanguageBundle, translate } from './functions.any';
/**
* Translates a specific key to text containing HTML via a specific translate
* function. On native, HTML tags are stripped and the plain text is rendered.
*
* @param {Function} t - The translate function.
* @param {string} key - The key to translate.
* @param {Record<string, unknown>} options - The options, if any, to pass to {@link t}.
* @returns {ReactElement} A ReactElement which depicts the translated text.
*/
export function translateToHTML(t: Function, key: string, options: Record<string, unknown> = {}) {
const text = t(key, options).replace(/<[^>]*>/g, '');
return <Text>{ text }</Text>;
}

View File

@@ -0,0 +1,47 @@
import DOMPurify from 'dompurify';
import React from 'react';
export { changeLanguageBundle, translate } from './functions.any';
const SANITIZE_CONFIG = {
ALLOWED_TAGS: [ 'a', 'b', 'br', 'span' ],
ALLOWED_ATTR: [ 'href', 'target', 'rel' ],
ALLOWED_URI_REGEXP: /^https?:\/\//i
};
/**
* Escapes a string for safe inclusion in HTML.
*
* @param {string} value - The string to escape.
* @returns {string} The escaped string.
*/
function escapeHTML(value: string): string {
const el = document.createElement('span');
el.textContent = value;
return el.innerHTML;
}
/**
* Translates a specific key to text containing HTML via a specific translate
* function.
*
* @param {Function} t - The translate function.
* @param {string} key - The key to translate.
* @param {Record<string, unknown>} options - The options, if any, to pass to {@link t}.
* @returns {ReactElement} A ReactElement which depicts the translated HTML
* text.
*/
export function translateToHTML(t: Function, key: string, options: Record<string, unknown> = {}) {
const escapedOptions: Record<string, unknown> = {};
for (const [ k, v ] of Object.entries(options)) {
escapedOptions[k] = typeof v === 'string' ? escapeHTML(v) : v;
}
const html = DOMPurify.sanitize(t(key, escapedOptions), SANITIZE_CONFIG);
// eslint-disable-next-line react/no-danger
return <span dangerouslySetInnerHTML = {{ __html: html }} />;
}

View File

@@ -1,7 +1,38 @@
import BrowserLanguageDetector from 'i18next-browser-languagedetector';
import { noop } from 'lodash-es';
import LANGUAGES_RESOURCES from '../../../../lang/languages.json';
import configLanguageDetector from './configLanguageDetector';
// Map from lowercased key → original key (e.g. 'fr-ca' → 'fr-CA') for
// case-insensitive lookup that still returns the exact casing i18next expects.
const SUPPORTED_LANGUAGES = new Map(
Object.keys(LANGUAGES_RESOURCES).map(lang => [ lang.toLowerCase(), lang ])
);
/**
* Custom querystring language detector that validates the raw `lang` query
* parameter against the application's supported-language allowlist before
* returning it. This prevents unsanitized user-controlled input from reaching
* i18next internals (defence-in-depth on top of i18next's own whitelist).
*/
const safeLangQueryDetector = {
name: 'safeLangQuery',
cacheUserLanguage: noop,
lookup() {
const value = new URLSearchParams(window.location.search).get('lang');
const lang = value && SUPPORTED_LANGUAGES.get(value.toLowerCase());
if (lang) {
return lang;
}
return undefined;
}
};
/**
* The ordered list (by name) of language detectors to be utilized as backends
* by the singleton language detector for Web.
@@ -9,7 +40,7 @@ import configLanguageDetector from './configLanguageDetector';
* @type {Array<string>}
*/
const order = [
'querystring',
safeLangQueryDetector.name,
'localStorage'
];
@@ -33,7 +64,7 @@ const languageDetector
order
});
// @ts-ignore
languageDetector.addDetector(safeLangQueryDetector);
languageDetector.addDetector(configLanguageDetector);
export default languageDetector;

View File

@@ -3,6 +3,8 @@ import { View } from 'react-native';
import { Edge, SafeAreaView } from 'react-native-safe-area-context';
import { StyleType } from '../../styles/functions.any';
import BaseTheme from '../../ui/components/BaseTheme.native';
import { useKeyboardVisible } from '../hooks.native';
import JitsiKeyboardAvoidingView from './JitsiKeyboardAvoidingView';
import styles from './styles';
@@ -34,6 +36,11 @@ interface IProps {
*/
footerComponent?: Function;
/**
* Extra bottom padding applied to the footer when keyboard is visible.
*/
footerKeyboardSpacing?: number;
/**
* Is a text input rendered at the bottom of the screen?
*/
@@ -61,11 +68,14 @@ const JitsiScreen = ({
children,
disableForcedKeyboardDismiss = false,
footerComponent,
footerKeyboardSpacing = BaseTheme.spacing[4],
hasBottomTextInput = false,
hasExtraHeaderHeight = false,
safeAreaInsets = [ 'bottom', 'left', 'right' ],
style
}: IProps) => {
const keyboardVisible = useKeyboardVisible();
const renderContent = () => (
<JitsiKeyboardAvoidingView
addBottomPadding = { addBottomPadding }
@@ -78,7 +88,11 @@ const JitsiScreen = ({
edges = { safeAreaInsets }
style = { styles.safeArea }>
{ children }
{ footerComponent?.() }
{ footerComponent && (
<View style = { keyboardVisible && { paddingBottom: footerKeyboardSpacing } }>
{ footerComponent() }
</View>
) }
</SafeAreaView>
</JitsiKeyboardAvoidingView>
);

View File

@@ -0,0 +1,26 @@
import { useEffect, useState } from 'react';
import { Keyboard, Platform } from 'react-native';
const showEvent = Platform.OS === 'ios' ? 'keyboardWillShow' : 'keyboardDidShow';
const hideEvent = Platform.OS === 'ios' ? 'keyboardWillHide' : 'keyboardDidHide';
/**
* A hook that tracks whether the native keyboard is visible.
*
* @returns {boolean} - Whether the keyboard is visible.
*/
export const useKeyboardVisible = (): boolean => {
const [ keyboardVisible, setKeyboardVisible ] = useState(false);
useEffect(() => {
const showSub = Keyboard.addListener(showEvent, () => setKeyboardVisible(true));
const hideSub = Keyboard.addListener(hideEvent, () => setKeyboardVisible(false));
return () => {
showSub.remove();
hideSub.remove();
};
}, []);
return keyboardVisible;
};

View File

@@ -619,17 +619,12 @@ function _localParticipantJoined({ getState, dispatch }: IStore, next: Function,
const settings = state['features/base/settings'];
const jwtUser = state['features/base/jwt']?.user;
const userContext = jwtUser ? {
id: jwtUser.id,
name: jwtUser.name
} : undefined;
dispatch(localParticipantJoined({
avatarURL: settings.avatarURL,
email: settings.email,
name: settings.displayName,
id: '',
userContext
userContext: jwtUser
}));
return result;

View File

@@ -45,6 +45,7 @@ export interface IParticipant {
}
export interface IUserContext {
[key: string]: any;
id?: string;
name?: string;
}

View File

@@ -1,10 +1,11 @@
import { createTrackMutedEvent } from '../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../analytics/functions';
import { IStore } from '../../app/types';
import { showErrorNotification, showNotification } from '../../notifications/actions';
import { showErrorNotification, showNotification, showWarningNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT, NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import { getCurrentConference } from '../conference/functions';
import { IJitsiConference } from '../conference/reducer';
import { isMacOS } from '../environment/environment';
import { JitsiTrackErrors, JitsiTrackEvents } from '../lib-jitsi-meet';
import { setAudioMuted, setScreenshareMuted, setVideoMuted } from '../media/actions';
import {
@@ -439,6 +440,12 @@ export function trackAdded(track: any) {
track.on(JitsiTrackEvents.LOCAL_TRACK_STOPPED,
() => {
logger.debug(`Local track stopped: ${track}, removing it from the conference`);
if (mediaType === MEDIA_TYPE.SCREENSHARE && isMacOS()) {
dispatch(showWarningNotification({
descriptionKey: 'dialog.screenshareStoppedDiskSpace',
titleKey: 'dialog.screenshareStoppedTitle'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
}
dispatch({
type: TRACK_STOPPED,
track: {

View File

@@ -214,7 +214,7 @@ export const colorMap = {
// Visitors
visitorsCountBadge: 'warning02', // Visitors count badge background
visitorsCountText: 'uiBackground', // Visitors count badge text
visitorsCountIcon: 'icon04', // Visitors count icon
visitorsCountIcon: 'iconSvgFill', // Visitors count icon
visitorsQueueBackground: 'ui01', // Visitors queue panel background
visitorsQueueText: 'text01', // Visitors queue text
visitorsArrowBackground: 'ui02', // Visitors arrow container background
@@ -355,7 +355,7 @@ export const colorMap = {
dialInSecondaryText: 'text02', // Dial-in summary secondary text
// Reactions
reactionsMenuBackground: 'ui01', // Reactions menu background
reactionsMenuBackground: '#242528', // Reactions menu background
reactionsMenuBorder: 'ui02', // Reactions menu border
reactionsMenuButtonToggled: 'surface01', // Reactions menu button toggled state background
reactionsMenuBoxShadow1: 'ui09', // Reactions menu box shadow primary
@@ -411,7 +411,7 @@ export const colorMap = {
fileSharingItemBorder: 'ui02', // File sharing item hover/border
// Gifs
gifsBackground: 'ui01', // GIFs panel background
gifsBackground: '#242528', // GIFs panel background
gifsText: 'text01', // GIFs panel text
// Whiteboard

View File

@@ -116,7 +116,7 @@ const Switch = ({ className, id, checked, disabled, onChange }: IProps) => {
const change = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
onChange(e.target.checked);
}, []);
}, [ onChange ]);
return (
<span

View File

@@ -1,3 +1,5 @@
import logger from './logger';
/**
* Opens URL in the browser.
*
@@ -6,6 +8,22 @@
* @returns {void}
*/
export function openURLInBrowser(url: string, openInNewTab?: boolean) {
let parsed;
try {
parsed = new URL(url);
} catch {
logger.warn(`Blocked invalid URL: ${url}`);
return;
}
if (![ 'http:', 'https:' ].includes(parsed.protocol)) {
logger.warn(`Blocked URL with disallowed protocol: ${parsed.protocol}`);
return;
}
const target = openInNewTab ? '_blank' : '';
window.open(url, target, 'noopener');

View File

@@ -134,12 +134,13 @@ export function getBackendSafePath(path?: string): string | undefined {
}
/**
* Converts a room name to a backend-safe format. Properly lowercased and url encoded.
* Decodes, NFKC-normalizes, and lowercases a room name without percent-encoding the result.
* Use this when the result will be passed to an API (e.g. URLSearchParams) that encodes automatically.
*
* @param {string?} room - The room name to convert.
* @param {string?} room - The room name to normalize.
* @returns {string?}
*/
export function getBackendSafeRoomName(room?: string): string | undefined {
export function getNormalizedRoomName(room?: string): string | undefined {
if (!room) {
return room;
}
@@ -162,16 +163,27 @@ export function getBackendSafeRoomName(room?: string): string | undefined {
// Only decoded and normalized strings can be lowercased properly.
room = room?.toLowerCase();
// But we still need to (re)encode it.
room = encodeURIComponent(room ?? '');
/* eslint-enable no-param-reassign */
// Unfortunately we still need to lowercase it, because encoding a string will
// add some uppercase characters, but some backend services
// expect it to be full lowercase. However lowercasing an encoded string
// doesn't change the string value.
return room.toLowerCase();
return room;
}
/**
* Converts a room name to a backend-safe format. Properly lowercased and url encoded.
*
* @param {string?} room - The room name to convert.
* @returns {string?}
*/
export function getBackendSafeRoomName(room?: string): string | undefined {
const normalized = getNormalizedRoomName(room);
if (!normalized) {
return normalized;
}
// Lowercase again after encoding because encodeURIComponent produces uppercase hex digits,
// but some backend services expect fully lowercase encoded strings.
return encodeURIComponent(normalized).toLowerCase();
}
/**

View File

@@ -19,6 +19,7 @@ export interface IBreakoutRoomsState {
rooms: IRooms;
userContextCache: {
[participantId: string]: {
[key: string]: any;
id?: string;
name?: string;
};

View File

@@ -9,6 +9,7 @@ export interface IRoom {
jid: string;
role: string;
userContext?: {
[key: string]: any;
id?: string;
name?: string;
};
@@ -38,6 +39,7 @@ export interface IRoomInfoParticipant {
jid: string;
role: string;
userContext?: {
[key: string]: any;
id?: string;
name?: string;
};

View File

@@ -137,7 +137,7 @@ export default {
* A special padding to avoid issues on some devices (such as Android devices with custom suggestions bar).
*/
extraBarPadding: {
paddingBottom: BaseTheme.spacing[8]
paddingBottom: BaseTheme.spacing[6]
},
inputBar: {
@@ -147,12 +147,12 @@ export default {
},
sendButton: {
marginRight: BaseTheme.spacing[5],
marginRight: BaseTheme.spacing[4],
marginLeft: BaseTheme.spacing[2]
},
customInputContainer: {
marginLeft: BaseTheme.spacing[5],
marginLeft: BaseTheme.spacing[4],
flex: 1
},

View File

@@ -483,6 +483,7 @@ const Chat = ({
role = 'tabpanel'
tabIndex = { 0 }>
<MessageContainer
isVisible = { _focusedTab === ChatTabs.CHAT }
messages = { _messages } />
<MessageRecipient />
{isPrivateChatAllowed && (

View File

@@ -1,11 +1,14 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import Icon from '../../../base/icons/components/Icon';
import { IconSubtitles } from '../../../base/icons/svg';
import Button from '../../../base/ui/components/web/Button';
import LanguageSelector from '../../../subtitles/components/web/LanguageSelector';
import { ChatTabs } from '../../constants';
import { getFocusedTab } from '../../functions';
// @ts-ignore
import AbstractClosedCaptions, { AbstractProps } from '../AbstractClosedCaptions';
@@ -82,6 +85,7 @@ const ClosedCaptionsTab = ({
}: AbstractProps): JSX.Element => {
const { classes, theme } = useStyles();
const { t } = useTranslation();
const isVisible = useSelector(getFocusedTab) === ChatTabs.CLOSED_CAPTIONS;
if (!isTranscribing) {
if (canStartSubtitles) {
@@ -118,6 +122,7 @@ const ClosedCaptionsTab = ({
<div className = { classes.messagesContainer }>
<SubtitlesMessagesContainer
groups = { groupedSubtitles }
isVisible = { isVisible }
messages = { filteredSubtitles } />
</div>
</div>

View File

@@ -11,6 +11,12 @@ import ChatMessageGroup from './ChatMessageGroup';
import NewMessagesButton from './NewMessagesButton';
interface IProps {
/**
* Whether the message container is currently visible to the user.
* Defaults to true when not provided.
*/
isVisible?: boolean;
messages: IMessage[];
}
@@ -65,7 +71,14 @@ export default class MessageContainer extends Component<IProps, IState> {
*/
_bottomListObserver: IntersectionObserver;
/**
* Whether the component has performed its initial scroll to the bottom.
* Used to ensure we scroll on first visibility but preserve scroll position on subsequent tab switches.
*/
_hasInitiallyScrolled: boolean;
static defaultProps = {
isVisible: true,
messages: [] as IMessage[]
};
@@ -80,6 +93,7 @@ export default class MessageContainer extends Component<IProps, IState> {
this._messageListRef = React.createRef<HTMLDivElement>();
this._messagesListEndRef = React.createRef<HTMLDivElement>();
this._hasInitiallyScrolled = false;
// Bind event handlers so they are only bound once for every instance.
this._handleIntersectBottomList = this._handleIntersectBottomList.bind(this);
@@ -139,7 +153,16 @@ export default class MessageContainer extends Component<IProps, IState> {
* @inheritdoc
*/
override componentDidMount() {
this.scrollToElement(false, null);
// Only scroll on mount if the component is visible, since scrollIntoView
// silently does nothing on hidden (display: none) elements. If hidden,
// componentDidUpdate will handle scrolling when the component first becomes visible.
if (this.props.isVisible) {
this._hasInitiallyScrolled = true;
requestAnimationFrame(() => {
this.scrollToElement(false, null);
});
}
this._createBottomListObserver();
}
@@ -164,6 +187,15 @@ export default class MessageContainer extends Component<IProps, IState> {
this.setState({ hasNewMessages: true });
}
}
// If the component was mounted while hidden, scrollIntoView was skipped.
// Scroll to the bottom the first time it becomes visible to show the latest messages.
if (this.props.isVisible && !prevProps.isVisible && !this._hasInitiallyScrolled) {
this._hasInitiallyScrolled = true;
requestAnimationFrame(() => {
this.scrollToElement(false, null);
});
}
}
/**

View File

@@ -12,6 +12,11 @@ interface IProps {
messages: ISubtitle[];
senderId: string;
}>;
/**
* Whether the subtitles container is currently visible to the user.
*/
isVisible: boolean;
messages: ISubtitle[];
}
@@ -46,12 +51,13 @@ const useStyles = makeStyles()(() => {
*
* @returns {JSX.Element} - A React component displaying subtitles messages with scroll functionality.
*/
export function SubtitlesMessagesContainer({ messages, groups }: IProps) {
export function SubtitlesMessagesContainer({ messages, groups, isVisible }: IProps) {
const { classes } = useStyles();
const [ hasNewMessages, setHasNewMessages ] = useState(false);
const [ isScrolledToBottom, setIsScrolledToBottom ] = useState(true);
const [ observer, setObserver ] = useState<IntersectionObserver | null>(null);
const messagesEndRef = useRef<HTMLDivElement>(null);
const hasInitiallyScrolled = useRef(false);
const scrollToElement = useCallback((withAnimation: boolean, element: Element | null) => {
const scrollTo = element ? element : messagesEndRef.current;
@@ -97,7 +103,16 @@ export function SubtitlesMessagesContainer({ messages, groups }: IProps) {
};
useEffect(() => {
scrollToElement(false, null);
// Only scroll on mount if the component is visible, since scrollIntoView
// silently does nothing on hidden (display: none) elements. If hidden,
// the isVisible useEffect below will handle scrolling when it first becomes visible.
if (isVisible) {
hasInitiallyScrolled.current = true;
requestAnimationFrame(() => {
scrollToElement(false, null);
});
}
createBottomListObserver();
return () => {
@@ -108,6 +123,15 @@ export function SubtitlesMessagesContainer({ messages, groups }: IProps) {
};
}, []);
useEffect(() => {
if (isVisible && !hasInitiallyScrolled.current) {
hasInitiallyScrolled.current = true;
requestAnimationFrame(() => {
scrollToElement(false, null);
});
}
}, [ isVisible, scrollToElement ]);
const previousMessages = useRef(messages);
useEffect(() => {

View File

@@ -3,7 +3,13 @@ import { useSelector } from 'react-redux';
import ChatButton from './components/web/ChatButton';
import { isChatDisabled } from './functions';
const chat = {
interface IChatButtonEntry {
Content: typeof ChatButton;
group: number;
key: string;
}
const chat: IChatButtonEntry = {
key: 'chat',
Content: ChatButton,
group: 2
@@ -14,10 +20,12 @@ const chat = {
*
* @returns {Object | undefined} - The chat button object or undefined.
*/
export function useChatButton() {
export function useChatButton(): IChatButtonEntry | undefined {
const _isChatDisabled = useSelector(isChatDisabled);
if (!_isChatDisabled) {
return chat;
if (_isChatDisabled) {
return;
}
return chat;
}

View File

@@ -3,6 +3,7 @@ import React, { useCallback } from 'react';
import {
BackHandler,
NativeModules,
StatusBar,
View,
ViewStyle
} from 'react-native';
@@ -267,15 +268,21 @@ class Conference extends AbstractConference<IProps, State> {
*/
override render() {
const {
_aspectRatio,
_brandingStyles,
} = this.props;
const isLandscape = _aspectRatio === ASPECT_RATIO_WIDE;
return (
<Container
style = { [
styles.conference,
_brandingStyles
] }>
<StatusBar
animated = { true }
hidden = { isLandscape } />
<BrandingImageBackground />
{ this._renderContent() }
</Container>

View File

@@ -483,6 +483,7 @@ export default reactReduxConnect(_mapStateToProps)(translate(props => {
const { isOpen: isChatOpen } = useSelector((state: IReduxState) => state['features/chat']);
const isFileUploadEnabled = useSelector(isFileUploadingEnabled);
const isOnPrejoin = useSelector(isPrejoinPageVisible);
const handleDragEnter = useCallback((e: React.DragEvent) => {
e.preventDefault();
@@ -500,7 +501,7 @@ export default reactReduxConnect(_mapStateToProps)(translate(props => {
e.preventDefault();
e.stopPropagation();
if (!isFileUploadEnabled) {
if (!isFileUploadEnabled || isOnPrejoin) {
return;
}
@@ -510,7 +511,7 @@ export default reactReduxConnect(_mapStateToProps)(translate(props => {
}
dispatch(setFocusedTab(ChatTabs.FILE_SHARING));
}
}, [ isChatOpen, isDragging, isFileUploadEnabled ]);
}, [ isChatOpen, isDragging, isFileUploadEnabled, isOnPrejoin ]);
const handleDrop = useCallback((e: React.DragEvent) => {
e.preventDefault();
@@ -528,6 +529,7 @@ export default reactReduxConnect(_mapStateToProps)(translate(props => {
return (
<div
data-testid = 'conference-drag-zone'
onDragEnter = { handleDragEnter }
onDragLeave = { handleDragLeave }
onDragOver = { handleDragOver }

View File

@@ -9,7 +9,7 @@ import { isCustomPanelEnabled } from './functions';
const customPanel = {
key: 'custom-panel',
Content: CustomPanelButton,
group: 2
group: 5
};
/**

View File

@@ -235,6 +235,13 @@ class AudioDevicesSelection extends AbstractDialogTab<IProps, {}> {
!== this.props.selectedAudioInputId) {
this._createAudioInputTrack(this.props.selectedAudioInputId);
}
if (!prevProps.hasAudioPermission && this.props.hasAudioPermission) {
this._createAudioInputTrack(this.props.selectedAudioInputId)
?.then(() => {
this.props.dispatch(getAvailableDevices());
});
}
}
/**

View File

@@ -194,6 +194,13 @@ class VideoDeviceSelection extends AbstractDialogTab<IProps, IState> {
!== this.props.selectedVideoInputId) {
this._createVideoInputTrack(this.props.selectedVideoInputId);
}
if (!prevProps.hasVideoPermission && this.props.hasVideoPermission) {
this._createVideoInputTrack(this.props.selectedVideoInputId)
?.then(() => {
this.props.dispatch(getAvailableDevices());
});
}
}
/**

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