Compare commits

...

130 Commits

Author SHA1 Message Date
dependabot[bot]
7a9ba79783 chore(deps): bump node-forge from 1.3.1 to 1.3.2
Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2.
- [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md)
- [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: node-forge
  dependency-version: 1.3.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-27 08:51:30 +01:00
Damien Fetis
1f5a3b5b0f fix(recording): allow samesite iframe embeds to work with local recording
* fix(recording): allow samesite iframe embeds to work with local recording

Skip capture handle validation when inside an iframe to ensure local
recording works. This only applies if the iframe is served from the
same domain.

* fix(recording): add missing line breaks for better readability in LocalRecordingManager
2025-11-26 07:35:23 -07:00
bgrozev
fe2aff4f3c chore(deps) lib-jitsi-meet@latest (#16706)
https://github.com/jitsi/lib-jitsi-meet/compare/v2114.0.0+0e62818c...v2115.0.0+cc2f34c2
2025-11-25 11:57:53 -06:00
bgrozev
d847f6f96b feat: Accept transcription messages from non-participant entities. (#16631) 2025-11-25 11:06:16 -06:00
damencho
45ce467dcd feat(polls): Fixes support for breakout rooms.
Fixes #16693.
2025-11-25 09:30:10 -06:00
bgrozev
2b81fa6bd3 config(webpack): Listen on localhost by default. (#16703) 2025-11-25 08:42:19 -06:00
damencho
6f6100ceb2 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2113.0.0+ffcffaa7...v2114.0.0+0e62818c
2025-11-21 05:56:46 -06:00
Calin-Teodor
62cd1c29d7 align react native docker version with package json version 2025-11-21 13:45:53 +02:00
Дамян Минков
64869e8970 fix(deb): Adds Include on upgrade prosody. (#16687)
* fix(deb): Adds Include on upgrade prosody.

* squash: Restart if config has changed.
2025-11-20 16:13:29 -06:00
Saúl Ibarra Corretgé
29464e6886 Revert "chore(deps-dev): bump @react-native-community/cli from 15.0.1 to 17.0.1"
This reverts commit 421b21edeb.
2025-11-20 13:45:05 +01:00
Saúl Ibarra Corretgé
5ed92f2bc5 fix(deps) use Olm from npm
The Matrix GitLab repo was behind CF and thus affected by today's
outage.

Since they released the last Olm version to npm, let's consume that one.
2025-11-20 13:01:52 +01:00
srijan
048d12de24 feat(logging): replace console.* with centralized logger infrastructure (#16655)
* feat(logging): replace console.* with centralized logger infrastructure

* fix(logging): remove logger from size-constrained bundles
2025-11-19 18:31:35 -06:00
emrah
40c240c7ca fix(lang): add the missing translation (German) 2025-11-18 17:00:51 -06:00
Boris Grozev
289c1907e7 test: Skip iframe tests when the API is disabled. 2025-11-18 17:00:21 -06:00
damencho
35adea48ae fix(muc_rate_limit): Check connection when processing rate limited events.
If it happens that a connection was closed during waiting in the rate limited queue, we want to ignore those occupant events.
2025-11-18 14:24:26 -06:00
bgrozev
d72114d5bc test: Expect pin to have digits only, configure length. (#16670) 2025-11-18 12:00:06 -06:00
bgrozev
2f6b6ca837 fix: Fix transcription test expectation. (#16664) 2025-11-18 07:45:07 -06:00
bgrozev
615bbdc39b test: Order attachments by participant. (#16663) 2025-11-17 16:12:58 -06:00
bgrozev
ef97778158 test: Assert jaas visitors enabled. (#16662) 2025-11-17 16:12:45 -06:00
bgrozev
2885f39355 More test expectations (#16661)
* test: Add iframe API expectation.

* test: Add expectations for recording and live streaming.

* test: Remove iframe references from jaas/.

* test: Add a transcription expectation.
2025-11-17 16:12:34 -06:00
damencho
ae256b23b8 fix(cleanup_backend): Avoids cleanup when breakout rooms are active. 2025-11-17 12:56:00 -06:00
Дамян Минков
412aa83268 feat(jwt): Supports JWKS endpoint. (#16649)
* feat(jwt): Supports JWKS endpoint.

* squash: Allow setting just cache_keys_url.
2025-11-17 09:48:28 -06:00
damencho
f4c61e4760 fix(prosody): Order room-destroyed event.
Make sure we execute before prosody cleans it up from the list of room. If we try to look it up after that we will not find it. If we also add at 0 we cannot guarantee the order of hook execution.
2025-11-14 14:01:12 -06:00
Jaya Allamsetty
f313fb81d0 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2109.0.0+cb9d000c...v2113.0.0+ffcffaa7
2025-11-13 21:25:10 -05:00
Srijan
975af80e27 fix(chat): remove debug console.log statements from resize handlers 2025-11-13 16:52:24 -06:00
damencho
0a30a51bab feat(localstorage): Filter items. 2025-11-13 11:02:34 -06:00
Дамян Минков
54e28e223c fix(tests): Split participants presence. (#16642)
* fix(tests): Split participants presence.

* squash: Drop unused listener.
2025-11-12 11:42:43 -06:00
Edgars Voroboks
a4def96763 fix(lang): Update Latvian language translation 2025-11-12 11:42:29 -06:00
Hristo Terezov
dad4fb9e06 Revert "fix(large-video): Prevents unnecessary updates when container is hidden"
This reverts commit 6deb0a6385.
2025-11-11 12:48:16 -06:00
Vishal Malyan
3772b9a5ae feat(toolbar): implement toolbar background color via configOverwrite for web and mobile
* Change toolbar background color from IFrame API #16468 fixed

* fix(toolbar #16468): implement toolbar background color via configOverwrite for web and mobile

* keep toolbarConfig defaults commented in config.js

* add trailing comma to commented toolbarConfig.backgroundColor

* fix: resolve linting errors

Fixes #16468
2025-11-11 07:02:28 -06:00
bgrozev
89b9c75242 test: Default sort by test order in allure report. (#16636) 2025-11-10 14:07:23 -06:00
Дамян Минков
b24b60b735 fix(tests): Wait for transcriptions to be off via an event. (#16635) 2025-11-10 12:55:35 -06:00
Дамян Минков
486a1f6511 fix(tests): Avoids being blocked by notification when clicking toolbar buttons
* fix(tests): Avoids clicking UI buttons to avoid being blocked by notification.

In AV moderation tests sometimes clicking mute/unmute buttons is blocked by askedToUnmute notification.

* squash: fix waiting for button.

* squash: adds some docs.
2025-11-10 11:04:36 -06:00
Werner Fleischer
80b3f1d7d4 fix(mod_jitsi_permissions): Use correct session on moderator revocation
In the `process_set_affiliation` function, an undefined `session` variable was used when revoking moderator privileges. This prevented the `jitsi_meet_context_features` from being cleared for the occupant.
2025-11-10 05:07:47 -06:00
dependabot[bot]
421b21edeb chore(deps-dev): bump @react-native-community/cli from 15.0.1 to 17.0.1
Bumps [@react-native-community/cli](https://github.com/react-native-community/cli/tree/HEAD/packages/cli) from 15.0.1 to 17.0.1.
- [Release notes](https://github.com/react-native-community/cli/releases)
- [Changelog](https://github.com/react-native-community/cli/blob/main/packages/cli/CHANGELOG.md)
- [Commits](https://github.com/react-native-community/cli/commits/v17.0.1/packages/cli)

---
updated-dependencies:
- dependency-name: "@react-native-community/cli"
  dependency-version: 17.0.1
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-11-07 09:06:19 +01:00
Дамян Минков
a58b0d9a85 fix(tests): Update lobby test. (#16618)
* fix(tests): Update lobby test.
* test: Include name in "hangup" logs.
---------

Co-authored-by: Boris Grozev <boris@jitsi.org>
2025-11-06 14:56:43 -06:00
Дамян Минков
1aca8ab985 feat(dialog): Adds name to all dialogs. (#16626)
* feat(dialog): Adds name to all dialogs.

The name is used for debugging purposes to be added to logs.

* squash: Drop empty string.
2025-11-06 09:49:30 -06:00
Jaya Allamsetty
f9daba728f chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2101.0.0+8061f52a...v2109.0.0+cb9d000c
2025-11-05 15:45:04 -05:00
damencho
fbb6456317 fix(wait_for_host): Make sure the main room is set back to non-persistent. 2025-11-05 09:26:13 -06:00
damencho
52ead26bed feat(prosody): Adds a module to cleanup room with just service components in it. 2025-11-04 16:42:09 -06:00
damencho
8d1da83e3c fix(persistent_lobby): Avoids calling destroy twice. 2025-11-04 16:41:58 -06:00
Jaya Allamsetty
5453b615f5 fix(tests): Add missing helper function. 2025-11-04 11:04:54 -05:00
Jaya Allamsetty
81a7301a3e Revert "fix(large-video)pin prev speaker on stage when local user is dominant speaker. (#16511)"
This reverts commit 82d4628976.
2025-11-04 11:04:54 -05:00
Jaya Allamsetty
1138b7779b Revert "fix(filmstrip) Fixes an issue where remote tiles can disappear when SS is started"
This reverts commit 077602c427.
2025-11-04 11:04:54 -05:00
Calin-Teodor
2fd653d928 fix(chat): be explicit about screen navigation when polls are disabled 2025-11-04 15:35:24 +02:00
eastmancr
012c9fb329 feat(base): add WebRTC availability detection (#16608)
* feat(base/environment) add WebRTC availability detection

* feat(base/unsupported-browser) switch to JitsiMeetJS WebRTC detection

* fix(static/webrtcUnsupported) remove links
2025-11-03 14:25:10 -06:00
damencho
fdf95444e9 fix(lobby): Hide login button if authenticated(jwt is available). 2025-11-03 14:22:53 -06:00
Hristo Terezov
919c60b3d2 feat(chat): Add disableChat configuration option
Introduces a comprehensive disableChat config option that disables the entire chat feature including button visibility, notifications, sounds, private messages, and keyboard shortcuts. When disabled, the chat tab is hidden from the chat panel while allowing other tabs (polls, files, CC) to remain accessible.
2025-11-03 12:44:29 -06:00
Hristo Terezov
e02c4e8f7f feat(toolbox): Add polls and file sharing buttons to overflow menu
Adds dedicated buttons for polls and file sharing in the toolbar overflow menu, following the pattern of the CC button. Both buttons open the chat panel with their respective tab selected when clicked.
2025-11-03 12:44:29 -06:00
Дамян Минков
3fd9ce5f11 * fix(lobby): Updates metadata on destroy lobby room and let in participants on empty main.
* fix(lobby): Updates metadata on destroy lobby room.

* fix(visitors): Let people join lobby when main room is empty but with lobby.
2025-10-30 16:07:46 -05:00
bgrozev
93022b3281 feat: Filter transcription results. (#16606) 2025-10-30 15:38:00 -05:00
Jaya Allamsetty
5d63b31071 fix(video-layout) Possibly fixes auto-pinning of SS in a large call.
When a user joins a very large call with SS, sometime SS is not auto-pinned to stage. This may happen when lot of participant joins are processed at the same time and therefore the state for remoteScreenShares may not get updated in time. Added extra logging to help debug if this issue reproduces.
2025-10-30 15:21:29 -04:00
Jaya Allamsetty
4432f727a4 fix(tests) Check for continguous thunbnails in the filmstrip 2025-10-30 12:21:03 -04:00
Calin-Teodor
6f1bdb513a chore(android/sdk): invoke permissionListener immediatly 2025-10-30 10:52:13 +02:00
Jaya Allamsetty
ad144e6fd3 fix(tests) Check for the endpointID of the large-video (#16601) 2025-10-29 12:35:45 -04:00
Calin-Teodor
076d77a982 chore(android/sdk): handle foreground exceptions 2025-10-29 14:34:04 +02:00
damencho
5afdda7568 fix(tests): Give some time for recording events to be received. 2025-10-28 16:48:27 -05:00
Arvind Yadav.
6cb57c472c feat(avatar): Strip bracketed annotations from display names before generating initials
Fixes #16591.
2025-10-28 16:48:16 -05:00
bgrozev
e026bac42c feat(tests): Do not require WebhooksProxy for jaas dial-in test (#16595)
* Add a requireWebhooksProxy test property.

* test: Make the jaas dial-in test use but not require WH proxy.
2025-10-28 14:14:45 -05:00
Hugo Lavernhe
b29e48d471 fix(settings): Prevent enabling audio processing settings and stereo at the same time.
* Prevent enabling audio processing settings and stereo at the same time
2025-10-28 14:35:25 -04:00
Дамян Минков
99cb5e6c40 feat(metadata): Adds lobbyEnabled and visitorsEnabled to metadata. (#16583) 2025-10-28 09:20:37 -05:00
Calin-Teodor
01834903c2 feat(analytics): remove unused event 2025-10-28 16:11:48 +02:00
Avinash Alapati
2929317972 chore(editorconfig) extend to include Android and iOS indentation rules 2025-10-28 09:37:53 +01:00
damencho
57865d74c6 fix(tests): Fix hangup by avoiding not defined error.
ReferenceError: APP is not defined.
2025-10-23 13:29:25 -05:00
Дамян Минков
f8f331a576 fix(tests): Fix reference to APP in debug logs retrieval
Avoids `ReferenceError: APP is not defined` the failure may happen after hangup where APP is not defined.
2025-10-23 13:29:25 -05:00
Matteo
c610e955cd Update main-it.json 2025-10-23 13:29:17 -05:00
Boris Grozev
53899947a9 fix: Use latin M in logs. 2025-10-23 10:52:03 -05:00
Kerinlin
bf23107e7a fix(i18n): Fix Chinese language issues and hyphenated locale persistence
- Fix missing Chinese translations in main-zh-CN.json and main-zh-TW.json
- Fix language selection not persisting for hyphenated locales (zh-CN, zh-TW, es-US, fr-CA, pt-BR)
- Update normalizeCurrentLanguage to check exact match before normalization
2025-10-23 10:51:40 -05:00
bgrozev
6784921429 Minor test fixes (#16577)
* test: Increase password dialog timeout.
* test: Try to fix hangup().
2025-10-23 08:11:15 -05:00
damencho
a5ca57b8e4 feat(tests): Drop more aria selectors. 2025-10-22 15:58:12 -05:00
damencho
fa9703a41e fix(tests): Send logs to browser to keep correct order. 2025-10-22 15:58:12 -05:00
damencho
e82ef6de4b feat(tests): Uses memory logs on failure and stops logging during conference. 2025-10-22 15:58:12 -05:00
damencho
e0cad48734 feat(tests): Avoids using aria selector for breakout rooms.
It is reported to be slow at times.
2025-10-22 15:58:12 -05:00
Hristo Terezov
fff6636a9e refactor(mobile): Move querySelector polyfill to @jitsi/js-utils package
Moves the querySelector/querySelectorAll polyfill implementation from the local codebase to the @jitsi/js-utils package (v2.6.1) to reduce code duplication and make the polyfill available to other projects. This centralizes maintenance and ensures consistent behavior across the Jitsi ecosystem.
2025-10-22 15:02:24 -05:00
Jaya Allamsetty
077602c427 fix(filmstrip) Fixes an issue where remote tiles can disappear when SS is started
* fix(filmstrip) Fixes an issue where remote tiles can disappear when SS is started.
Regression caused by 82d4628976. More testcases have been added.
2025-10-21 19:13:15 -04:00
Hannes
b2f7b3be6c fix(chat): don't show private chat picker if disabled (#16556)
* fix: 🐛 don't show private chat picker if disabled

* style: 🚨

* refactor: ♻️ combine function
2025-10-21 07:57:55 -05:00
Jaya Allamsetty
29fd5df16a fix(tests) Increase backToP2PDelay to 3 secs.
Setting it to 1 sec was causing p2p connections to be created when it was not needed.
2025-10-17 11:27:10 -05:00
damencho
f324122d93 feat(tests): Fail early and gather debug logs for iframe tests. 2025-10-16 16:00:39 -05:00
Jaya Allamsetty
82d4628976 fix(large-video)pin prev speaker on stage when local user is dominant speaker. (#16511)
* fix(large-video)pin prev speaker on stage when local user is dominant speaker.
Also fix the case where the dominant speaker sometimes doesn't show up in the filmstrip when SS is pinned to stage.

* fix(test) Add more tests for activeSpeaker

* fix(test) Do not check for large-video if there is no remote video track.

* fix(filmstrip) Get updated display name for calc speaker order
2025-10-16 15:35:15 -04:00
damencho
8ab02d598c fix(visitors): Fix room token verification.
When allowUnauthenticatedAccess is enabled we want to allow main prosody participants without verifying their token.
2025-10-16 11:22:30 -05:00
damencho
5b23072bd0 feat(tests): Make sure dial-in user hangups.
Avoid closing browser and leaving it to the timeout of the connection.
2025-10-16 11:22:22 -05:00
damencho
7b4cc552fb feat(tests): Increase the randomness of the room name. 2025-10-16 11:22:22 -05:00
damencho
eb188ff02a fix(tests): Wait dialog elements to be clickable.
To avoid trying to click too quickly while animations are still rendered. Avoids: Can't call elementClick on element with selector "//input[@name="lockKey"]" because element wasn't found
2025-10-16 11:22:22 -05:00
damencho
b40c24db70 fix(tests): Visitors tests to avoid reordered webhook events. 2025-10-16 11:22:22 -05:00
Jaya Allamsetty
a855f76377 fix(tests) Wait for p2p switch before checking for SS 2025-10-16 11:20:16 -04:00
Calin-Teodor
c481e7ede4 chore(android/sdk): check also for sdk version that the app targets 2025-10-16 17:30:50 +03:00
Calinteodor
17b4c2156a chore(android): update colors for status bar and navigation bar (#16557)
*Update Android navigation color and add status bar color for both app and sdk.
2025-10-16 14:33:21 +03:00
Calin-Teodor
ca6579e032 feat(prejoin): fix room name backdrop and button sizes 2025-10-16 11:19:26 +03:00
damencho
f3e99624e9 fix(tests): Fix p2p enable flag in desktop sharing. 2025-10-15 15:32:20 -05:00
Saúl Ibarra Corretgé
3b5c2d9b0b fix(android) fix initializer not running
We want to merge our initializer with any others an app migh add.

Fixes: https://github.com/jitsi/jitsi-meet/issues/16505
Fixes: https://github.com/jitsi/jitsi-meet/issues/16527
2025-10-15 16:49:22 +03:00
Calinteodor
bab9ddbb57 feat(prejoin/lobby): style adjustments (#16550)
* UI adjustments, for prejoin and lobby, around device screen orientation.
2025-10-15 16:20:24 +03:00
Calinteodor
8d4193ce1e chore(android): insets navigation adjustments (#16543)
* Adjustments around top and bottom insets, especially for Android >= 15 where edge-to-edge is forced.
2025-10-15 16:12:09 +03:00
damencho
7d2cf3dbf2 fix: Disable urlNormalisation on FF. 2025-10-15 08:10:10 -05:00
bgrozev
9309d61c00 test: Fix jaas chat test again (typo). (#16548) 2025-10-14 17:08:02 -05:00
damencho
4089702060 feat(token_verification): Pass through recorder and transcriber into meetings. 2025-10-14 15:51:15 -05:00
damencho
bf2254c753 feat(keyboard-shortcuts): Adds support for any keyboard layout. 2025-10-14 13:06:45 -05:00
Mihaela Dumitru
641b52c51d feat(visitors): add showJoinMeetingDialog config option (#16540) 2025-10-14 19:36:36 +03:00
bgrozev
083037d152 test: Do not assert message order (they can race). (#16544) 2025-10-14 11:29:21 -05:00
Philip Örnfeldt
a3200a172f lang: Updated swedish translation 2025-10-14 10:44:14 -05:00
bgrozev
ebff46971d test: Add a test for joining a MUC without a conference request. (#16537) 2025-10-14 10:24:06 -05:00
bgrozev
657aefefc2 test: Use timeout for expected codec changes. (#16539)
I suspect some intermittent test failures are caused by not waiting for
the codec change to complete. Might be exacerbated by
ensureThreeParticipants only waiting for 1 remote stream, which means
it the "ensureTwo(); ensureThree()" call may return before p2 sees p3.
2025-10-14 09:20:30 -05:00
Mihaela Dumitru
683d6eb208 feat(visitors): add hideVisitorCountForVisitors config option (#16541) 2025-10-14 17:06:14 +03:00
Hristo Terezov
a62fa3f833 feat(chat): Display file uploads as inline chat messages
Integrates file sharing into the chat interface so uploaded files appear as messages in the chat timeline alongside text
messages.

Changes:
- Created FileMessage component for inline file display in chat
- Extracted FileItem component for reusable file UI across chat and file sharing tab
- Show "A file was deleted" placeholder instead of removing message when file deleted
- Hide message menu (3-dot) when no actions are available for file messages
- Add button backgrounds in chat context to hide text on hover
- Fix timing: local participant only sees file message after upload completes (progress: 100%)

Technical implementation:
- Added fileMetadata field to IMessage interface
- Added isDeleted flag to IFileMetadata for soft-delete state
- Middleware dispatches addMessage when files uploaded (ADD_FILE action)
- Middleware uses editMessage when files deleted to preserve chat history
- Minimal state retention (only isDeleted flag) for deleted files

This provides a unified messaging experience where file sharing is part of the conversation flow.
2025-10-14 08:45:51 -05:00
bgrozev
88f1ef27c5 fix: Fix dial-in test (wait until the dialog is closed). (#16538) 2025-10-13 11:49:08 -05:00
Mihaela Dumitru
95ecf73c71 feat(prejoin): add showHangUp config option to prejoinConfig (#16531) 2025-10-13 10:46:04 +03:00
Calin-Teodor
a96908dd7c fix(analytics/amplitude/native): package does nott have a def export 2025-10-10 14:17:11 +03:00
Saúl Ibarra Corretgé
a103b0e5bd chore(deps) update react-native-webrtc
- Fixes a crash in iOS 26 simulator
- Avoid NPE on Android
2025-10-09 22:54:47 +02:00
damencho
d67622f6f2 fix(prosody): Drops not needed debug log. 2025-10-09 15:11:59 -05:00
bgrozev
ecec65f7af feat: Whitelist the disableFocus config option. (#16526) 2025-10-09 14:58:03 -05:00
bgrozev
447be3f6a9 Reorganize tests by feature, minor test updates (#16518)
* test: Move lockRoom under moderation/.

* ref: Cleanup lockRoom test.

* test: Move lockRoomDigitsOnly to ui/.

* test: Add a setPasswordAvailable expectation.

* ref: Move the lobby test to moderation/.

* test: Move tests to media/.

* test: Add a useTenant expectation.

* test: Move mute to media/.

* test: Move audioOnly to media/.

* test: Move startMuted to media/.

* test: Move codecSelection to media/.

* ref: Simplify, log the "actual" codec value.

* test: Move stopVideo to media/.

* test: Move videoLayout to ui/.

* test: Move chatPanel to ui/.

* test: Move switchVideo to media/pinning.spec.ts.

* test: Move audioVideoModeration to media/.

* test: Move displayName to ui/.

* test: Move preJoin to ui/.

* test: Move endConference to ui/.

* test: Move selfView to ui/.

* test: Move oneOnOne to ui/.

* test: Move tileView to ui/.

* test: Move singlePort and udp to misc/connectivity.spec.ts.

* test: Move avatars to misc/.

* test: Move polls to misc/.

* test: Move breakoutRooms to misc/.

* test: Move followMe to misc/.

* test: Move invite to dial/dialInUi.spec.ts.

* test: Move dialInAudio to dial/dialIn.spec.ts.

* test: Only log expectations in the main wdio process.

* test: Move fakeDialInAudio to dial/.

* test: Move subject to misc/.

* test: Check for subject set remotely.

* test: Remove references to "2way", "3way".

* test: Consolidate all dial-in tests in one file.

* test: Move dialIn to misc/.

* test: Adjust test titles.

* Remove waitForAudioFromDialInParticipant test.
2025-10-09 14:11:20 -05:00
Saúl Ibarra Corretgé
1255b4dcf3 feat(ios) remove Apple Watch app
It has been unmaintained for years.
2025-10-09 16:43:18 +02:00
Mihaela Dumitru
47e420f10e fix(chat): improve naming convention for unread items (#16499) 2025-10-09 15:15:40 +03:00
damencho
698aa8db3e fix(persistent_lobby): Fix main room lookup.
The change about keeping jid was introduced in 5580301.
2025-10-08 14:42:10 -05:00
damencho
50bad7bbca fix(shot_lived_token): Handles case with empty string for tenant. 2025-10-08 10:29:51 -05:00
Mihaela Dumitru
9d4e6c2d0d fix(recording) prevent recording consent dialog for visitors (#16452) 2025-10-08 16:09:55 +03:00
JPL
f3e1fbfdce Update jitsi-meet-rnsdk.podspec
This PR addresses a sporadic issue where cp would fail with a "directory not found" error during file operations. Replaced cp with ditto, which handles directory copying more reliably on macOS and resolves the random failures observed.
2025-10-08 11:15:59 +03:00
damencho
6287c14dd3 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2100.0.0+0d2e5fef...v2101.0.0+8061f52a
2025-10-07 14:09:51 -04:00
bgrozev
8a7ee9bae5 test: Add skip reason to report (#16515)
* test: Add description, skip reason to Allure report.
* test: Adds reasons for skipped tests.
* test: Add more URL normalization test cases.
* ref: Move urlNormalization test to misc/.
2025-10-07 12:28:39 -05:00
Calinteodor
38677dbe0a dep(react-native-immersive-mode): remove everything related to this (#16513)
* Remove anything related to immersive mode on Android. Right now we use top and bottom insets.
2025-10-07 13:50:39 +03:00
bgrozev
1900c42098 test: Fix token for moderation test. (#16510) 2025-10-06 12:40:51 -05:00
Hristo Terezov
6deb0a6385 fix(large-video): Prevents unnecessary updates when container is hidden
Large video was being updated through scheduleLargeVideoUpdate even when
the large video container was hidden via CSS. This occurred in multiple
layout modes: tile view, stage filmstrip (with 2+ participants), and
etherpad editing. These updates caused expensive operations including
setting video streams, managing track listeners, updating avatars, and
running show/hide animations - all wasted CPU cycles since the container
wasn't visible.

The fix introduces a centralized shouldHideLargeVideo() function that checks
all cases where the large video container is hidden. This function is used in
selectParticipantInLargeVideo() to guard to not update the participant id.
A state listener monitors transitions from hidden to visible states and ensures
the large video participant id is properly updated when the container becomes
visible again and set to undefined when large video is hidden.

This improves performance by eliminating unnecessary video element manipulation
and handler execution across all layout modes where large video is not displayed.
2025-10-06 12:00:40 -05:00
Calinteodor
ce567955f0 chore(android): remove api check for setting top bottom insets (#16509)
* chore(android): remove api check for setting top bottom insets
2025-10-06 18:23:20 +03:00
Mihaela Dumitru
9d2f1ce8e0 fix(ui): improve tab badge styling (#16507) 2025-10-06 13:40:41 +03:00
Jaya Allamsetty
841ab8c052 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2099.0.0+89536686...v2100.0.0+0d2e5fef
2025-10-04 07:31:05 -04:00
yanas
3e4f45dc7b Update main-fr.json 2025-10-03 15:25:55 -05:00
damencho
19cff49ab1 feat(conference): Adds option to silently reconnect.
Uses the end_meeting endpoint to trigger a silent reconnect by destroying the current conference and passing its jid.
2025-10-03 14:58:56 -05:00
Mihaela Dumitru
a06c3fe715 feat(file-sharing): show count badges for unread files and notify on uploads/removals (#16484) 2025-10-03 01:52:24 +03:00
Дамян Минков
5580301ef7 fix(prosody): Avoid using stale room instances. (#16492)
* fix(prosody): Avoid using stale room instances.

In very rare cases a participant can request a room and jicofo join there, but the participant don't show up (waiting for host) so jicofo leaves and in the mean time if someone tries to use the room instance just before and after the room is being destroyed, strange things can occur like web connected and joined to a stale room where nothing is received exchanged compared to the live meeting room.

* squash: Revert meeting-id one, will fix it in the problem place where there is an async call.

* squash: Change to a simple check.
2025-10-02 16:50:01 -05:00
damencho
69b0ac4686 fix(tests): Fixes randomly failing start muted test. 2025-10-02 17:18:57 -04:00
bgrozev
9f7eb6b657 test: Add configurable test expectations. (#16496)
* Add a sample "expectations" config.
* feat: Add configurable expectation for dial in.
* Add JaaS unauthenticatedJoins expectation.
* test: Move grantModerator to moderation/, add expectation.
* test: Move kick test to moderation/, fix p2p enabled case.
* test: Add a test case for non-moderator kick.
2025-10-02 15:49:03 -05:00
344 changed files with 4327 additions and 4245 deletions

View File

@@ -14,3 +14,12 @@ trim_trailing_whitespace = false
[Makefile]
indent_style = tab
[*.{java,kt}]
indent_size = 4
[*.xml]
indent_size = 2
[*.{swift,m,mm,h}]
indent_size = 4

View File

@@ -103,7 +103,7 @@ jobs:
android-sdk-build:
name: Build mobile SDK (Android)
runs-on: ubuntu-latest
container: reactnativecommunity/react-native-android:v18.0
container: reactnativecommunity/react-native-android:v15.0
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#17A0DB</color>
<color name="navigationBarColor">#161618</color>
<color name="navigationBarColor">#040404</color>
<color name="statusBarColor">#040404</color>
</resources>

View File

@@ -3,6 +3,7 @@
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
<item name="android:forceDarkAllowed">false</item>
<item name="android:navigationBarColor">@color/navigationBarColor</item>
<item name="android:statusBarColor">@color/statusBarColor</item>
<item name="android:windowDisablePreview">true</item>
</style>
</resources>

View File

@@ -73,7 +73,6 @@ dependencies {
}
implementation project(':react-native-gesture-handler')
implementation project(':react-native-get-random-values')
implementation project(':react-native-immersive-mode')
implementation project(':react-native-keep-awake')
implementation project(':react-native-orientation-locker')
implementation project(':react-native-pager-view')

View File

@@ -62,7 +62,8 @@
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false">
android:exported="false"
tools:node="merge">
<meta-data android:name="org.jitsi.meet.sdk.JitsiInitializer"
android:value="androidx.startup" />
</provider>

View File

@@ -96,9 +96,6 @@ public class JitsiMeetActivity extends AppCompatActivity
public static void addTopBottomInsets(@NonNull Window w, @NonNull View v) {
// Only apply if edge-to-edge is supported (API 30+) or enforced (API 35+)
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) return;
View decorView = w.getDecorView();
decorView.post(() -> {
@@ -138,7 +135,12 @@ public class JitsiMeetActivity extends AppCompatActivity
JitsiMeetActivityDelegate.onHostResume(this);
setContentView(R.layout.activity_jitsi_meet);
addTopBottomInsets(getWindow(),findViewById(android.R.id.content));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
&& getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.VANILLA_ICE_CREAM) {
addTopBottomInsets(getWindow(), findViewById(android.R.id.content));
}
this.jitsiView = findViewById(R.id.jitsiView);
registerForBroadcastMessages();

View File

@@ -37,7 +37,6 @@ public class JitsiMeetActivityDelegate {
* React Native module.
*/
private static PermissionListener permissionListener;
private static Callback permissionsCallback;
/**
* Tells whether or not the permissions request is currently in progress.
@@ -142,11 +141,6 @@ public class JitsiMeetActivityDelegate {
if (reactInstanceManager != null) {
reactInstanceManager.onHostResume(activity, new DefaultHardwareBackBtnHandlerImpl(activity));
}
if (permissionsCallback != null) {
permissionsCallback.invoke();
permissionsCallback = null;
}
}
/**
@@ -169,15 +163,10 @@ public class JitsiMeetActivityDelegate {
public static void onRequestPermissionsResult(
final int requestCode, final String[] permissions, final int[] grantResults) {
permissionsCallback = new Callback() {
@Override
public void invoke(Object... args) {
if (permissionListener != null
&& permissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
permissionListener = null;
}
}
};
// Invoke the callback immediately
if (permissionListener != null && permissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
permissionListener = null;
}
}
public static void requestPermissions(Activity activity, String[] permissions, int requestCode, PermissionListener listener) {

View File

@@ -99,6 +99,7 @@ public class JitsiMeetOngoingConferenceService extends Service implements Ongoin
public static void launch(Context context, HashMap<String, Object> extraData) {
List<String> permissionsList = new ArrayList<>();
Activity activity = (Activity) context;
PermissionListener listener = new PermissionListener() {
@Override
@@ -134,7 +135,7 @@ public class JitsiMeetOngoingConferenceService extends Service implements Ongoin
if (permissionsArray.length > 0) {
JitsiMeetActivityDelegate.requestPermissions(
(Activity) context,
activity,
permissionsArray,
PERMISSIONS_REQUEST_CODE,
listener
@@ -159,12 +160,20 @@ public class JitsiMeetOngoingConferenceService extends Service implements Ongoin
stopSelf();
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
} else {
startForeground(NOTIFICATION_ID, notification);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
} else if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK);
} else {
startForeground(NOTIFICATION_ID, notification);
}
} catch (Exception e) {
// Handle ForegroundServiceStartNotAllowedException when app is in background and cannot start foreground service.
// See: https://developer.android.com/develop/background-work/services/fgs/restrictions-bg-start#wiu-restrictions
JitsiMeetLogger.w(TAG + " Failed to start foreground service", e);
stopSelf();
return;
}
}

View File

@@ -101,7 +101,6 @@ class ReactInstanceManagerHolder {
new com.oney.WebRTCModule.WebRTCModulePackage(),
new com.swmansion.gesturehandler.RNGestureHandlerPackage(),
new org.linusu.RNGetRandomValuesPackage(),
new com.rnimmersivemode.RNImmersiveModePackage(),
new com.swmansion.rnscreens.RNScreensPackage(),
new com.zmxv.RNSound.RNSoundPackage(),
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="navigationBarColor">#040404</color>
<color name="statusBarColor">#040404</color>
</resources>

View File

@@ -1,3 +1,6 @@
<resources>
<style name="JitsiMeetActivityStyle" parent="Theme.AppCompat.Light.NoActionBar"/>
<style name="JitsiMeetActivityStyle" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:navigationBarColor">@color/navigationBarColor</item>
<item name="android:statusBarColor">@color/statusBarColor</item>
</style>
</resources>

View File

@@ -24,8 +24,6 @@ include ':react-native-giphy'
project(':react-native-giphy').projectDir = new File(rootProject.projectDir, '../node_modules/@giphy/react-native-sdk/android')
include ':react-native-google-signin'
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-google-signin/google-signin/android')
include ':react-native-immersive-mode'
project(':react-native-immersive-mode').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive-mode/android')
include ':react-native-keep-awake'
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/@sayem314/react-native-keep-awake/android')
include ':react-native-orientation-locker'

View File

@@ -1375,7 +1375,7 @@ export default {
}
APP.store.dispatch(updateRemoteParticipantFeatures(user));
logger.log(`USER ${id} connected:`, user);
logger.log(`USER ${id} connected`);
APP.UI.addUser(user);
});

View File

@@ -139,6 +139,9 @@ var config = {
// Disables polls feature.
// disablePolls: false,
// Disables chat feature entirely including notifications, sounds, and private messages.
// disableChat: false,
// Disables demote button from self-view
// disableSelfDemote: false,
@@ -805,7 +808,9 @@ var config = {
// // By setting preCallTestEnabled, you enable the pre-call test in the prejoin page.
// // ICE server credentials need to be provided over the preCallTestICEUrl
// preCallTestEnabled: false,
// preCallTestICEUrl: ''
// preCallTestICEUrl: '',
// // Shows the hangup button in the lobby screen.
// showHangUp: true,
// },
// When 'true', the user cannot edit the display name.
@@ -902,6 +907,8 @@ var config = {
// alwaysVisible: false,
// // Indicates whether the toolbar should still autohide when chat is open
// autoHideWhileChatIsOpen: false,
// // Default background color for the main toolbar. Accepts any valid CSS color.
// // backgroundColor: '#ffffff',
// },
// Overrides the buttons displayed in the main toolbar. Depending on the screen size the number of displayed
@@ -1605,6 +1612,10 @@ var config = {
// audio: true,
// video: true
// },
// // Hides the visitor count for visitors.
// // hideVisitorCountForVisitors: false,
// // Whether to show the join meeting dialog when joining as a visitor.
// // showJoinMeetingDialog: true,
// },
// The default type of desktop sharing sources that will be used in the electron app.
// desktopSharingSources: ['screen', 'window'],

View File

@@ -124,10 +124,17 @@ case "$1" in
ln -s $PROSODY_HOST_CONFIG /etc/prosody/conf.d/$JVB_HOSTNAME.cfg.lua
fi
PROSODY_CREATE_JICOFO_USER="true"
fi
if ! grep -q "VirtualHost \"$JVB_HOSTNAME\"" $PROSODY_CONFIG_OLD; then
# on some distributions main prosody config doesn't include configs
# from conf.d folder enable it as this where we put our config by default
# also when upgrading to new prosody version from prosody repo we need to add it again
if ! grep -q "Include \"conf\.d\/\*\.cfg.lua\"" $PROSODY_CONFIG_OLD; then
echo -e "\nInclude \"conf.d/*.cfg.lua\"" >> $PROSODY_CONFIG_OLD
# trigger a restart
PROSODY_CONFIG_PRESENT="false"
fi
fi

View File

@@ -44,7 +44,6 @@ target 'JitsiMeetSDK' do
pod 'giphy-react-native-sdk', :path => '../node_modules/@giphy/react-native-sdk'
pod 'RNCalendarEvents', :path => '../node_modules/react-native-calendar-events'
pod 'RNGoogleSignin', :path => '../node_modules/@react-native-google-signin/google-signin'
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
# Native pod dependencies
#

View File

@@ -1473,7 +1473,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-webrtc (124.0.4):
- react-native-webrtc (124.0.7):
- JitsiWebRTC (~> 124.0.0)
- React-Core
- react-native-webview (13.13.5):
@@ -1870,8 +1870,6 @@ PODS:
- React-Core
- RNSVG (15.11.2):
- React-Core
- RNWatch (1.1.0):
- React
- SocketRocket (0.7.1)
- SplashView (0.0.18):
- DoubleConversion
@@ -1993,7 +1991,6 @@ DEPENDENCIES:
- RNScreens (from `../node_modules/react-native-screens`)
- RNSound (from `../node_modules/react-native-sound`)
- RNSVG (from `../node_modules/react-native-svg`)
- RNWatch (from `../node_modules/react-native-watch-connectivity`)
- SplashView (from `../node_modules/react-native-splash-view`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
@@ -2203,8 +2200,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-sound"
RNSVG:
:path: "../node_modules/react-native-svg"
RNWatch:
:path: "../node_modules/react-native-watch-connectivity"
SplashView:
:path: "../node_modules/react-native-splash-view"
Yoga:
@@ -2279,7 +2274,7 @@ SPEC CHECKSUMS:
react-native-safe-area-context: 0f7bf11598f9a61b7ceac8dc3f59ef98697e99e1
react-native-slider: 1205801a8d29b28cacc14eef08cb120015cdafcb
react-native-video: eb861d67a71dfef1bbf6086a811af5f338b13781
react-native-webrtc: 2261a482150195092246fe70b3aff976f2e11ec5
react-native-webrtc: e8f0ce746353adc2744a2b933645e1aeb41eaa74
react-native-webview: 079eca50edf657503318b66687dadfb903731aa8
react-native-worklets-core: b59cf88762c8fb6132d8796babd4cec15217d6f0
React-nativeconfig: ecf4dc92c40b97e2b3f0c619938f78bfd6507b08
@@ -2321,11 +2316,10 @@ SPEC CHECKSUMS:
RNScreens: 9ef996b6041d0960a4794a845f7d0808b171b4ef
RNSound: 314cc5226453ef4a3314a196c65e8a65e5106a7b
RNSVG: 67de7abef81f367387b708ba6d2acefe7d4f5895
RNWatch: 28fe1f5e0c6410d45fd20925f4796fce05522e3f
SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748
SplashView: ed71a114c3ffe60dc3a9e5aa2cefb352c3794a70
Yoga: 31a098f74c16780569aebd614a0f37a907de0189
PODFILE CHECKSUM: eac4bba07b2f30174fc20bccbaf64f86676d9b1f
PODFILE CHECKSUM: 7c37a89916893e11159576c8b308b7b5c25246c9
COCOAPODS: 1.16.2

View File

@@ -7,16 +7,6 @@
objects = {
/* Begin PBXBuildFile section */
0B5418471F7C5D8C00A2DD86 /* MeetingRowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */; };
0B7001701F7C51CC005944F4 /* InCallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B70016F1F7C51CC005944F4 /* InCallController.swift */; };
0BEA5C291F7B8F73000D0AB4 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C271F7B8F73000D0AB4 /* Interface.storyboard */; };
0BEA5C2B1F7B8F73000D0AB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C2A1F7B8F73000D0AB4 /* Assets.xcassets */; };
0BEA5C321F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
0BEA5C371F7B8F73000D0AB4 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C361F7B8F73000D0AB4 /* InterfaceController.swift */; };
0BEA5C391F7B8F73000D0AB4 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C381F7B8F73000D0AB4 /* ExtensionDelegate.swift */; };
0BEA5C3B1F7B8F73000D0AB4 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */; };
0BEA5C3D1F7B8F73000D0AB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */; };
0BEA5C411F7B8F73000D0AB4 /* JitsiMeetCompanion.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
2681BB562C7A0B42CFBA6719 /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */; };
@@ -36,27 +26,11 @@
DEA9F28A258A6EA800D4CD74 /* JitsiMeetSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DED016F128ECBC9D009D5E8D /* WebRTC.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */; };
DED016F228ECBC9D009D5E8D /* WebRTC.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
E588011722789D43008B0561 /* JitsiMeetContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = E58801132278944E008B0561 /* JitsiMeetContext.swift */; };
E5C97B63227A1EB400199214 /* JitsiMeetCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = E5C97B62227A1EB400199214 /* JitsiMeetCommands.swift */; };
FD572B9827EDF32300A800FB /* GiphyUISDK.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD572B9727EDF32300A800FB /* GiphyUISDK.xcframework */; };
FD572B9927EDF32300A800FB /* GiphyUISDK.xcframework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FD572B9727EDF32300A800FB /* GiphyUISDK.xcframework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
0BEA5C331F7B8F73000D0AB4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0BEA5C301F7B8F73000D0AB4;
remoteInfo = "JitsiMeetCompanion Extension";
};
0BEA5C3F1F7B8F73000D0AB4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 0BEA5C241F7B8F73000D0AB4;
remoteInfo = JitsiMeetCompanion;
};
4EB06029260E026600F524C5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
@@ -81,24 +55,12 @@
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
0BEA5C471F7B8F73000D0AB4 /* Embed App Extensions */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 13;
files = (
0BEA5C321F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex in Embed App Extensions */,
);
name = "Embed App Extensions";
runOnlyForDeploymentPostprocessing = 0;
};
0BEA5C491F7B8F73000D0AB4 /* Embed Watch Content */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "$(CONTENTS_FOLDER_PATH)/Watch";
dstSubfolderSpec = 16;
files = (
0BEA5C411F7B8F73000D0AB4 /* JitsiMeetCompanion.app in Embed Watch Content */,
);
name = "Embed Watch Content";
runOnlyForDeploymentPostprocessing = 0;
@@ -118,19 +80,7 @@
/* Begin PBXFileReference section */
0B26BE6D1EC5BC3C00EEFB41 /* JitsiMeet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JitsiMeet.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingRowController.swift; sourceTree = "<group>"; };
0B70016F1F7C51CC005944F4 /* InCallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InCallController.swift; sourceTree = "<group>"; };
0BD6B4361EF82A6B00D1F4CD /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.framework"; sourceTree = "<group>"; };
0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JitsiMeetCompanion.app; sourceTree = BUILT_PRODUCTS_DIR; };
0BEA5C281F7B8F73000D0AB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = "<group>"; };
0BEA5C2A1F7B8F73000D0AB4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0BEA5C2C1F7B8F73000D0AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "JitsiMeetCompanion Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; };
0BEA5C361F7B8F73000D0AB4 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = "<group>"; };
0BEA5C381F7B8F73000D0AB4 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = "<group>"; };
0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComplicationController.swift; sourceTree = "<group>"; };
0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0BEA5C3E1F7B8F73000D0AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* jitsi-meet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "jitsi-meet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = src/Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
@@ -156,19 +106,10 @@
DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JitsiMeetSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = ../Pods/JitsiWebRTC/WebRTC.xcframework; sourceTree = "<group>"; };
DEFDBBDB25656E3B00344B23 /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.xcframework"; sourceTree = "<group>"; };
E58801132278944E008B0561 /* JitsiMeetContext.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JitsiMeetContext.swift; sourceTree = "<group>"; };
E5C97B62227A1EB400199214 /* JitsiMeetCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JitsiMeetCommands.swift; sourceTree = "<group>"; };
FD572B9727EDF32300A800FB /* GiphyUISDK.xcframework */ = {isa = PBXFileReference; expectedSignature = "AppleDeveloperProgram:925PGC4MV7:Giphy, Inc."; lastKnownFileType = wrapper.xcframework; name = GiphyUISDK.xcframework; path = ../Pods/Giphy/GiphySDK/GiphyUISDK.xcframework; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
0BEA5C2E1F7B8F73000D0AB4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
13B07F8C1A680F5B00A75B9A /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -181,13 +122,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
1F021A8A5B056078665DE530 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
4EB06020260E026600F524C5 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -216,34 +150,6 @@
name = Frameworks;
sourceTree = "<group>";
};
0BEA5C261F7B8F73000D0AB4 /* Watch app */ = {
isa = PBXGroup;
children = (
0BEA5C271F7B8F73000D0AB4 /* Interface.storyboard */,
0BEA5C2A1F7B8F73000D0AB4 /* Assets.xcassets */,
0BEA5C2C1F7B8F73000D0AB4 /* Info.plist */,
);
name = "Watch app";
path = watchos/app;
sourceTree = "<group>";
};
0BEA5C351F7B8F73000D0AB4 /* WatchKit extension */ = {
isa = PBXGroup;
children = (
0BEA5C361F7B8F73000D0AB4 /* InterfaceController.swift */,
0BEA5C381F7B8F73000D0AB4 /* ExtensionDelegate.swift */,
0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */,
0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */,
0BEA5C3E1F7B8F73000D0AB4 /* Info.plist */,
0B70016F1F7C51CC005944F4 /* InCallController.swift */,
0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */,
E58801132278944E008B0561 /* JitsiMeetContext.swift */,
E5C97B62227A1EB400199214 /* JitsiMeetCommands.swift */,
);
name = "WatchKit extension";
path = watchos/extension;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* src */ = {
isa = PBXGroup;
children = (
@@ -279,11 +185,10 @@
0B26BE711EC5BC4D00EEFB41 /* Frameworks */,
83CBBA001A601CBA00E9B192 /* Products */,
13B07FAE1A68108700A75B9A /* src */,
0BEA5C261F7B8F73000D0AB4 /* Watch app */,
0BEA5C351F7B8F73000D0AB4 /* WatchKit extension */,
4EB06025260E026600F524C5 /* JitsiMeetBroadcast Extension */,
CDD71F5E1157E9F283DF92A8 /* Pods */,
5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */,
DEAC44E22E97D2C200AD7BEE /* Recovered References */,
);
indentWidth = 2;
sourceTree = "<group>";
@@ -293,8 +198,6 @@
isa = PBXGroup;
children = (
13B07F961A680F5B00A75B9A /* jitsi-meet.app */,
0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */,
0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */,
4EB06023260E026600F524C5 /* JitsiMeetBroadcastExtension.appex */,
);
name = Products;
@@ -310,44 +213,17 @@
path = ../Pods;
sourceTree = "<group>";
};
DEAC44E22E97D2C200AD7BEE /* Recovered References */ = {
isa = PBXGroup;
children = (
13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */,
);
name = "Recovered References";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0BEA5C481F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion" */;
buildPhases = (
0BEA5C231F7B8F73000D0AB4 /* Resources */,
0BEA5C471F7B8F73000D0AB4 /* Embed App Extensions */,
1F021A8A5B056078665DE530 /* Frameworks */,
);
buildRules = (
);
dependencies = (
0BEA5C341F7B8F73000D0AB4 /* PBXTargetDependency */,
);
name = JitsiMeetCompanion;
productName = JitsiMeetCompanion;
productReference = 0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */;
productType = "com.apple.product-type.application.watchapp2";
};
0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0BEA5C461F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion Extension" */;
buildPhases = (
0BEA5C2D1F7B8F73000D0AB4 /* Sources */,
0BEA5C2E1F7B8F73000D0AB4 /* Frameworks */,
0BEA5C2F1F7B8F73000D0AB4 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "JitsiMeetCompanion Extension";
productName = "JitsiMeetCompanion Extension";
productReference = 0BEA5C311F7B8F73000D0AB4 /* JitsiMeetCompanion Extension.appex */;
productType = "com.apple.product-type.watchkit2-extension";
};
13B07F861A680F5B00A75B9A /* JitsiMeet */ = {
isa = PBXNativeTarget;
buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "JitsiMeet" */;
@@ -369,7 +245,6 @@
buildRules = (
);
dependencies = (
0BEA5C401F7B8F73000D0AB4 /* PBXTargetDependency */,
4EB0602A260E026600F524C5 /* PBXTargetDependency */,
);
name = JitsiMeet;
@@ -404,16 +279,6 @@
LastUpgradeCheck = 1020;
ORGANIZATIONNAME = Jitsi;
TargetAttributes = {
0BEA5C241F7B8F73000D0AB4 = {
CreatedOnToolsVersion = 9.0;
DevelopmentTeam = FC967L3QRG;
ProvisioningStyle = Automatic;
};
0BEA5C301F7B8F73000D0AB4 = {
CreatedOnToolsVersion = 9.0;
DevelopmentTeam = FC967L3QRG;
ProvisioningStyle = Automatic;
};
13B07F861A680F5B00A75B9A = {
LastSwiftMigration = 1620;
SystemCapabilities = {
@@ -444,31 +309,12 @@
projectRoot = "";
targets = (
13B07F861A680F5B00A75B9A /* JitsiMeet */,
0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */,
0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */,
4EB06022260E026600F524C5 /* JitsiMeetBroadcastExtension */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
0BEA5C231F7B8F73000D0AB4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0BEA5C2B1F7B8F73000D0AB4 /* Assets.xcassets in Resources */,
0BEA5C291F7B8F73000D0AB4 /* Interface.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
0BEA5C2F1F7B8F73000D0AB4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0BEA5C3D1F7B8F73000D0AB4 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
13B07F8E1A680F5B00A75B9A /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -622,20 +468,6 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
0BEA5C2D1F7B8F73000D0AB4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0B7001701F7C51CC005944F4 /* InCallController.swift in Sources */,
E5C97B63227A1EB400199214 /* JitsiMeetCommands.swift in Sources */,
0B5418471F7C5D8C00A2DD86 /* MeetingRowController.swift in Sources */,
E588011722789D43008B0561 /* JitsiMeetContext.swift in Sources */,
0BEA5C391F7B8F73000D0AB4 /* ExtensionDelegate.swift in Sources */,
0BEA5C371F7B8F73000D0AB4 /* InterfaceController.swift in Sources */,
0BEA5C3B1F7B8F73000D0AB4 /* ComplicationController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
13B07F871A680F5B00A75B9A /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -660,16 +492,6 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
0BEA5C341F7B8F73000D0AB4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0BEA5C301F7B8F73000D0AB4 /* JitsiMeetCompanion Extension */;
targetProxy = 0BEA5C331F7B8F73000D0AB4 /* PBXContainerItemProxy */;
};
0BEA5C401F7B8F73000D0AB4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 0BEA5C241F7B8F73000D0AB4 /* JitsiMeetCompanion */;
targetProxy = 0BEA5C3F1F7B8F73000D0AB4 /* PBXContainerItemProxy */;
};
4EB0602A260E026600F524C5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 4EB06022260E026600F524C5 /* JitsiMeetBroadcastExtension */;
@@ -678,14 +500,6 @@
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
0BEA5C271F7B8F73000D0AB4 /* Interface.storyboard */ = {
isa = PBXVariantGroup;
children = (
0BEA5C281F7B8F73000D0AB4 /* Base */,
);
name = Interface.storyboard;
sourceTree = "<group>";
};
13B07FB11A68108700A75B9A /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
@@ -697,155 +511,10 @@
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
0BEA5C421F7B8F73000D0AB4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = FC967L3QRG;
GCC_C_LANGUAGE_STANDARD = gnu11;
IBSC_MODULE = JitsiMeetCompanion_Extension;
INFOPLIST_FILE = watchos/app/Info.plist;
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Debug;
};
0BEA5C431F7B8F73000D0AB4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = FC967L3QRG;
GCC_C_LANGUAGE_STANDARD = gnu11;
IBSC_MODULE = JitsiMeetCompanion_Extension;
INFOPLIST_FILE = watchos/app/Info.plist;
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Release;
};
0BEA5C441F7B8F73000D0AB4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = FC967L3QRG;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = watchos/extension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit.extension;
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Debug;
};
0BEA5C451F7B8F73000D0AB4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = FC967L3QRG;
GCC_C_LANGUAGE_STANDARD = gnu11;
INFOPLIST_FILE = watchos/extension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.meet.watchkit.extension;
PRODUCT_NAME = "${TARGET_NAME}";
SDKROOT = watchos;
SKIP_INSTALL = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = 4;
WATCHOS_DEPLOYMENT_TARGET = 4.0;
};
name = Release;
};
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 756FCE06C08D9B947653C98A /* Pods-JitsiMeet.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDebug;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = app.entitlements;
@@ -882,7 +551,6 @@
isa = XCBuildConfiguration;
baseConfigurationReference = 3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconRelease;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = app.entitlements;
@@ -1131,24 +799,6 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
0BEA5C461F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion Extension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0BEA5C441F7B8F73000D0AB4 /* Debug */,
0BEA5C451F7B8F73000D0AB4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
0BEA5C481F7B8F73000D0AB4 /* Build configuration list for PBXNativeTarget "JitsiMeetCompanion" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0BEA5C421F7B8F73000D0AB4 /* Debug */,
0BEA5C431F7B8F73000D0AB4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "JitsiMeet" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@@ -1,92 +0,0 @@
{
"images" : [
{
"size" : "24x24",
"idiom" : "watch",
"filename" : "Icon-24@2x.png",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "38mm"
},
{
"size" : "27.5x27.5",
"idiom" : "watch",
"filename" : "Icon-27.5@2x.png",
"scale" : "2x",
"role" : "notificationCenter",
"subtype" : "42mm"
},
{
"size" : "29x29",
"idiom" : "watch",
"filename" : "Icon-29@2x.png",
"role" : "companionSettings",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "watch",
"filename" : "Icon-29@3x.png",
"role" : "companionSettings",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "watch",
"filename" : "Icon-40@2x.png",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "38mm"
},
{
"size" : "44x44",
"idiom" : "watch",
"filename" : "Icon-88@2x.png",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "40mm"
},
{
"size" : "50x50",
"idiom" : "watch",
"filename" : "Icon-100@2x.png",
"scale" : "2x",
"role" : "appLauncher",
"subtype" : "44mm"
},
{
"size" : "86x86",
"idiom" : "watch",
"filename" : "Icon-86@2x.png",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "38mm"
},
{
"size" : "98x98",
"idiom" : "watch",
"filename" : "Icon-98@2x.png",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "42mm"
},
{
"size" : "108x108",
"idiom" : "watch",
"filename" : "Icon-216@2x.png",
"scale" : "2x",
"role" : "quickLook",
"subtype" : "44mm"
},
{
"size" : "1024x1024",
"idiom" : "watch-marketing",
"filename" : "Icon-1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,21 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "hangup@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -1,21 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "mute-off@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@@ -1,21 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "mute-on@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="14490.70" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="AgC-eL-Hgc">
<device id="watch38" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="watchOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="14490.21"/>
</dependencies>
<scenes>
<!--Meetings-->
<scene sceneID="aou-V4-d1y">
<objects>
<controller title="Meetings" id="AgC-eL-Hgc" customClass="InterfaceController" customModule="JitsiMeetCompanion" customModuleProvider="target">
<items>
<label alignment="left" textAlignment="left" numberOfLines="0" id="OQN-sx-tDt"/>
<table alignment="left" id="gpO-ql-Xsr">
<items>
<tableRow identifier="MeetingRowType" id="GGl-av-xeJ" customClass="MeetingRowController" customModule="JitsiMeetCompanion_Extension">
<group key="rootItem" width="1" height="0.0" alignment="left" layout="vertical" id="5XE-gq-qzG">
<items>
<label alignment="left" text="Label" id="Sij-up-N4p"/>
<label alignment="left" text="Label" id="V5K-sm-jEH">
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
<fontDescription key="font" style="UICTFontTextStyleFootnote"/>
</label>
</items>
<connections>
<segue destination="9RD-qP-1Z0" kind="push" id="Boa-6E-eZs"/>
</connections>
</group>
<connections>
<outlet property="roomLabel" destination="Sij-up-N4p" id="PdS-SO-ylc"/>
<outlet property="rowGroup" destination="5XE-gq-qzG" id="GZN-2c-2Gz"/>
<outlet property="timeLabel" destination="V5K-sm-jEH" id="fWQ-kx-vE4"/>
</connections>
</tableRow>
</items>
</table>
</items>
<connections>
<outlet property="infoLabel" destination="OQN-sx-tDt" id="Juv-tb-SNj"/>
<outlet property="table" destination="gpO-ql-Xsr" id="aVV-iZ-z3l"/>
</connections>
</controller>
</objects>
<point key="canvasLocation" x="-99" y="117"/>
</scene>
<!--Meetings-->
<scene sceneID="ns4-Kh-qqU">
<objects>
<controller identifier="InCallController" title="Meetings" hidesWhenLoading="NO" id="9RD-qP-1Z0" customClass="InCallController" customModule="JitsiMeetCompanion" customModuleProvider="target">
<items>
<label alignment="center" text="Label" id="vFt-lL-SNY"/>
<timer alignment="center" textAlignment="center" previewedSeconds="0" id="W8S-uZ-MPm">
<color key="textColor" red="0.024725984125768763" green="1" blue="0.24241188365329402" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<fontDescription key="font" style="UICTFontTextStyleHeadline"/>
</timer>
<group alignment="center" verticalAlignment="bottom" spacing="10" id="Hfk-a0-uWj">
<items>
<button width="60" height="60" alignment="left" verticalAlignment="bottom" backgroundImage="hangup" id="8jF-SI-UHz">
<connections>
<action selector="hangupClicked" destination="9RD-qP-1Z0" id="cXK-lw-tsd"/>
</connections>
</button>
<button width="60" height="60" alignment="right" verticalAlignment="bottom" backgroundImage="mute-off" id="LmN-FI-aQq">
<connections>
<action selector="muteClicked" destination="9RD-qP-1Z0" id="dJg-kV-cqH"/>
</connections>
</button>
</items>
</group>
</items>
<connections>
<outlet property="mutedButton" destination="LmN-FI-aQq" id="gfi-4T-gdN"/>
<outlet property="roomLabel" destination="vFt-lL-SNY" id="cYB-Tf-Efz"/>
<outlet property="timer" destination="W8S-uZ-MPm" id="r7T-j1-9VJ"/>
</connections>
</controller>
</objects>
<point key="canvasLocation" x="213" y="117"/>
</scene>
</scenes>
</document>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Jitsi Meet</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
<key>WKCompanionAppBundleIdentifier</key>
<string>org.jitsi.meet</string>
<key>WKWatchKitApp</key>
<true/>
</dict>
</plist>

View File

@@ -1,6 +0,0 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View File

@@ -1,21 +0,0 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "jitsi@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,81 +0,0 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import ClockKit
class ComplicationController: NSObject, CLKComplicationDataSource {
// MARK: - Timeline Configuration
func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) {
handler([])
}
func getPrivacyBehavior(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationPrivacyBehavior) -> Void) {
handler(.showOnLockScreen)
}
// MARK: - Timeline Population
func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void) {
// Call the handler with the current timeline entry
getLocalizableSampleTemplate(for: complication) {template in
guard let template = template else {
handler(nil)
return
}
handler(CLKComplicationTimelineEntry(date: Date(), complicationTemplate: template))
}
}
func getTimelineEntries(for complication: CLKComplication, before date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) {
// Call the handler with the timeline entries prior to the given date
handler(nil)
}
func getTimelineEntries(for complication: CLKComplication, after date: Date, limit: Int, withHandler handler: @escaping ([CLKComplicationTimelineEntry]?) -> Void) {
// Call the handler with the timeline entries after to the given date
handler(nil)
}
// MARK: - Placeholder Templates
func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void) {
// This method will be called once per supported complication, and the results will be cached
let imageProvider = CLKImageProvider(onePieceImage: UIImage(named: "jitsi")!)
if complication.family == .circularSmall {
let small = CLKComplicationTemplateCircularSmallRingImage()
small.imageProvider = imageProvider
small.ringStyle = .closed
small.fillFraction = 0
handler(small)
} else if complication.family == .utilitarianSmall {
let utilitarian = CLKComplicationTemplateUtilitarianSmallSquare()
utilitarian.imageProvider = imageProvider
handler(utilitarian)
} else if complication.family == .modularSmall {
let modular = CLKComplicationTemplateModularSmallRingImage()
modular.imageProvider = imageProvider
modular.ringStyle = .closed
modular.fillFraction = 0
handler(modular)
}
}
}

View File

@@ -1,103 +0,0 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import WatchConnectivity
import WatchKit
class ExtensionDelegate: NSObject, WCSessionDelegate, WKExtensionDelegate {
var currentContext : JitsiMeetContext = JitsiMeetContext()
static var currentJitsiMeetContext: JitsiMeetContext {
get {
return (WKExtension.shared().delegate as! ExtensionDelegate).currentContext
}
}
func applicationDidFinishLaunching() {
// Start Watch Connectivity
if WCSession.isSupported() {
let session = WCSession.default
session.delegate = self
session.activate()
}
}
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
// Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one.
for task in backgroundTasks {
// Use a switch statement to check the task type
switch task {
case let backgroundTask as WKApplicationRefreshBackgroundTask:
// Be sure to complete the background task once youre done.
backgroundTask.setTaskCompletedWithSnapshot(false)
case let snapshotTask as WKSnapshotRefreshBackgroundTask:
// Snapshot tasks have a unique completion call, make sure to set your expiration date
snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
// Be sure to complete the connectivity task once youre done.
connectivityTask.setTaskCompletedWithSnapshot(false)
case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
// Be sure to complete the URL session task once youre done.
urlSessionTask.setTaskCompletedWithSnapshot(false)
default:
// make sure to complete unhandled task types
task.setTaskCompletedWithSnapshot(false)
}
}
}
func session(_ session: WCSession, activationDidCompleteWith
activationState: WCSessionActivationState, error: Error?) {
if let error = error {
print("WATCH Session activation failed with error: \(error.localizedDescription)")
return
}
print("WATCH Session activated with state: \(activationState.rawValue)")
}
func session(_ session: WCSession, didReceiveApplicationContext applicationContext: [String : Any]) {
DispatchQueue.main.async {
let newContext = JitsiMeetContext(context: applicationContext)
print("WATCH got new context: \(newContext.description)");
// Update context on the root controller which displays the recent list
let controller = WKExtension.shared().rootInterfaceController as! InterfaceController
controller.updateUI(newContext)
// If the current controller is not the in-call controller and we have a
// conference URL, show the in-call controller
if let currentController = WKExtension.shared().visibleInterfaceController as? InterfaceController {
// Go to the in-call controller only if the conference URL has changed, because the user may have
// clicked the back button
if newContext.conferenceURL != nil
&& self.currentContext.conferenceURL != newContext.conferenceURL {
currentController.pushController(withName: "InCallController", context: newContext)
}
} else if let inCallController = WKExtension.shared().visibleInterfaceController as? InCallController {
if newContext.conferenceURL == nil {
inCallController.popToRootController()
} else {
inCallController.updateUI(newContext)
}
}
self.currentContext = newContext;
}
}
}

View File

@@ -1,109 +0,0 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import WatchConnectivity
import WatchKit
import Foundation
class InCallController: WKInterfaceController {
@IBOutlet var mutedButton: WKInterfaceButton!
@IBOutlet var roomLabel: WKInterfaceLabel!
@IBOutlet var timer: WKInterfaceTimer!
@IBAction func hangupClicked() {
sendCommand(JitsiMeetCommands.CMD_HANG_UP, message: nil)
}
@IBAction func muteClicked() {
if var micMuted = ExtensionDelegate.currentJitsiMeetContext.micMuted {
micMuted = !micMuted;
sendCommand(
JitsiMeetCommands.CMD_SET_MUTED,
message: [
"muted": micMuted ? "true" : "false"
])
updateMutedButton(withMuted: micMuted)
}
}
func sendCommand(_ command: JitsiMeetCommands, message: [String : Any]?) {
if WCSession.isSupported() {
let session = WCSession.default
var data = [String: Any]()
if let sessionID = ExtensionDelegate.currentJitsiMeetContext.sessionID {
if message != nil {
message!.forEach { data[$0] = $1 }
}
data["command"] = command.rawValue;
data["sessionID"] = sessionID;
session.sendMessage(data, replyHandler: nil, errorHandler: nil)
}
}
}
func updateUI(_ newContext: JitsiMeetContext) {
var conferenceURL = newContext.conferenceURL
if let joinConferenceURL = newContext.joinConferenceURL {
sendCommand(JitsiMeetCommands.CMD_JOIN_CONFERENCE, message: [ "data" : joinConferenceURL ])
conferenceURL = joinConferenceURL
}
let newRoomName = conferenceURL != nil ? conferenceURL!.components(separatedBy: "/").last : ""
roomLabel.setText(newRoomName)
if let newTimestamp = newContext.conferenceTimestamp {
restartTimer(newTimestamp)
}
if let newMuted = newContext.micMuted {
updateMutedButton(withMuted: newMuted)
}
}
func restartTimer(_ conferenceTimestamp: Int64) {
if (conferenceTimestamp != 0) {
let newDate = Date(timeIntervalSince1970: TimeInterval(conferenceTimestamp / 1000))
timer.setDate(newDate)
timer.start();
print("WATCH timer set date to: \(newDate) and start")
} else {
print("WATCH timer stop")
timer.stop();
}
}
func updateMutedButton(withMuted isMuted: Bool) {
if isMuted {
mutedButton.setBackgroundImageNamed("mute-on.png")
} else {
mutedButton.setBackgroundImageNamed("mute-off.png")
}
}
override func awake(withContext context: Any?) {
super.awake(withContext: context)
if let data = context as? JitsiMeetContext {
updateUI(data)
}
}
}

View File

@@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Jitsi Meet Companion Extension</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CLKComplicationPrincipalClass</key>
<string>$(PRODUCT_MODULE_NAME).ComplicationController</string>
<key>CLKComplicationSupportedFamilies</key>
<array>
<string>CLKComplicationFamilyModularSmall</string>
<string>CLKComplicationFamilyUtilitarianSmall</string>
<string>CLKComplicationFamilyCircularSmall</string>
</array>
<key>NSExtension</key>
<dict>
<key>NSExtensionAttributes</key>
<dict>
<key>WKAppBundleIdentifier</key>
<string>org.jitsi.meet.watchkit</string>
</dict>
<key>NSExtensionPointIdentifier</key>
<string>com.apple.watchkit</string>
</dict>
<key>WKExtensionDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).ExtensionDelegate</string>
</dict>
</plist>

View File

@@ -1,94 +0,0 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import WatchKit
import WatchConnectivity
import Foundation
class InterfaceController: WKInterfaceController {
@IBOutlet var infoLabel: WKInterfaceLabel!
@IBOutlet var table: WKInterfaceTable!
override func didAppear(){
self.updateUI(ExtensionDelegate.currentJitsiMeetContext)
}
func updateUI(_ newContext:JitsiMeetContext) {
if (newContext.recentURLs == nil || newContext.recentURLs!.count == 0) {
infoLabel.setText("There are no recent meetings. Please use the app on the phone to start a new call.")
table.setHidden(true)
infoLabel.setHidden(false)
} else {
updateRecents(withRecents: newContext.recentURLs!, currentContext: newContext)
table.setHidden(false)
infoLabel.setHidden(true)
}
}
private func updateRecents(withRecents recents: NSArray, currentContext: JitsiMeetContext) {
// Updating the # of rows only if it actually changed prevents from blinking the UI
if (table.numberOfRows != recents.count) {
table.setNumberOfRows(recents.count, withRowType: "MeetingRowType")
}
for (index, entry) in recents.enumerated() {
let entryDict = entry as! NSDictionary
let roomURL = entryDict["conference"] as! NSString
let timestamp = entryDict["date"] as! NSNumber
// Prepare values
let room = roomURL.components(separatedBy: "/").last
let date = Date(timeIntervalSince1970: timestamp.doubleValue / 1000) // timestamp is taken with Date.now() in JS, which uses milliseconds
let dateFormatter = DateFormatter()
dateFormatter.timeZone = TimeZone.current
dateFormatter.locale = NSLocale.current
dateFormatter.dateFormat = "HH:mm yyyy-MM-dd"
let strDate = dateFormatter.string(from: date)
// Update row controller
let controller = table.rowController(at: index) as! MeetingRowController
controller.room = room
controller.roomUrl = roomURL as String
controller.roomLabel.setText(room)
controller.timeLabel.setText(strDate)
// Change the background for the active meeting
if (controller.roomUrl == currentContext.conferenceURL) {
controller.rowGroup.setBackgroundColor(UIColor(red: 0.125, green: 0.58, blue: 0.98, alpha: 1))
} else {
controller.rowGroup.setBackgroundColor(UIColor(red: 0.949, green: 0.956, blue: 1, alpha: 0.14))
}
}
}
override func contextForSegue(withIdentifier segueIdentifier: String, in table: WKInterfaceTable, rowIndex: Int) -> Any? {
let controller = table.rowController(at: rowIndex) as! MeetingRowController
let currentContext = ExtensionDelegate.currentJitsiMeetContext
// Copy the current context and add the joinConferenceURL to trigger the command when the in-call screen is displayed
let actionContext = JitsiMeetContext(jmContext: currentContext)
actionContext.joinConferenceURL = controller.roomUrl
print("WATCH contextForSegue: \(actionContext.description)");
return actionContext;
}
}

View File

@@ -1,27 +0,0 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// This needs to be in sync with features/mobile/watchos/constants.js
enum JitsiMeetCommands : String {
typealias RawValue = String
case CMD_HANG_UP = "hangup";
case CMD_JOIN_CONFERENCE = "joinConference";
case CMD_SET_MUTED = "setMuted";
}

View File

@@ -1,71 +0,0 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Foundation
class JitsiMeetContext {
private var dictionary : [String : Any]
var joinConferenceURL : String? = nil;
init() {
dictionary = [:]
}
init(context: [String : Any]) {
dictionary = context
}
init(jmContext: JitsiMeetContext) {
dictionary = jmContext.dictionary
joinConferenceURL = jmContext.joinConferenceURL
}
var conferenceURL : String? {
get {
return dictionary["conferenceURL"] as? String
}
}
var conferenceTimestamp : Int64? {
get {
return dictionary["conferenceTimestamp"] as? Int64;
}
}
var sessionID : Int64? {
get {
return dictionary["sessionID"] as? Int64;
}
}
var recentURLs : NSArray? {
get {
return dictionary["recentURLs"] as? NSArray
}
}
var micMuted : Bool? {
get {
return (dictionary["micMuted"] as? NSNumber)?.boolValue ?? nil;
}
}
public var description: String {
return "JitsiMeetContext[conferenceURL: \(String(describing: conferenceURL)), conferenceTimestamp: \(String(describing:conferenceTimestamp)), sessionID: \(String(describing:sessionID)), recentURLs: \(String(describing:recentURLs)), joinConferenceURL: \(String(describing:joinConferenceURL)) "
}
}

View File

@@ -1,27 +0,0 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import WatchKit
class MeetingRowController: NSObject {
@IBOutlet var roomLabel: WKInterfaceLabel!
@IBOutlet var timeLabel: WKInterfaceLabel!
@IBOutlet var rowGroup: WKInterfaceGroup!
var room: String!
var roomUrl: String!
}

View File

@@ -39,36 +39,6 @@ platform :ios do
end
)
# Set the (watch) app identifier
update_app_identifier(
xcodeproj: "app/app.xcodeproj",
plist_path: "watchos/app/Info.plist",
app_identifier: "com.atlassian.JitsiMeet.ios.watchkit"
)
# Set the (watch) extension identifier
update_app_identifier(
xcodeproj: "app/app.xcodeproj",
plist_path: "watchos/extension/Info.plist",
app_identifier: "com.atlassian.JitsiMeet.ios.watchkit.extension"
)
update_info_plist(
xcodeproj: "app/app.xcodeproj",
plist_path: "watchos/app/Info.plist",
block: proc do |plist|
plist["WKCompanionAppBundleIdentifier"] = "com.atlassian.JitsiMeet.ios"
end
)
update_info_plist(
xcodeproj: "app/app.xcodeproj",
plist_path: "watchos/extension/Info.plist",
block: proc do |plist|
plist["NSExtension"]["NSExtensionAttributes"]["WKAppBundleIdentifier"] = "com.atlassian.JitsiMeet.ios.watchkit"
end
)
# Increment the build number by 1
increment_build_number(
build_number: Time.now.to_i,

View File

@@ -1,127 +0,0 @@
#!/bin/bash
set -e
# The script is based on tutorial written by Antonis Tsakiridis published at:
# https://medium.com/@atsakiridis/continuous-deployment-for-ios-using-travis-ci-55dcea342d9
#
# It is intended to be executed through the Travis CI REST API call, as it
# requires few arguments which are mandatory with no default values provided:
# PR_REPO_SLUG - the Github name of the repo to be merged into the origin/master
# PR_BRANCH - the branch to be merged, if set to "master" no merge will happen
# IPA_DEPLOY_LOCATION - the location understandable by the "scp" command
# executed at the end of the script to deploy the output .ipa file
# LIB_JITSI_MEET_PKG (optional) - the npm package for lib-jitsi-meet which will
# be put in place of the current version in the package.json file.
#
# Other than that the script requires the following env variables to be set
# (reading the tutorial mentioned above will help in understanding the
# variables):
#
# APPLE_CERT_URL - the URL pointing to Apple certificate (set to
# http://developer.apple.com/certificationauthority/AppleWWDRCA.cer by default)
# DEPLOY_SSH_CERT_URL - the SSH private key used by the 'scp' command to deploy
# the .ipa. It is expected to be encrypted with the $ENCRYPTION_PASSWORD.
# ENCRYPTION_PASSWORD - the password used to decrypt certificate/key files used
# in the script.
# IOS_DEV_CERT_KEY_URL - URL pointing to provisioning profile certificate key
# file (development-key.p12.enc from the tutorial) encrypted with the
# $ENCRYPTION_PASSWORD.
# IOS_DEV_CERT_URL - URL pointing to provisioning profile certificate file
# (development-cert.cer.enc from the tutorial) encrypted with the
# $ENCRYPTION_PASSWORD.
# IOS_DEV_PROV_PROFILE_URL - URL pointing to provisioning profile file
# (profile-development-olympus.mobileprovision.enc from the tutorial) encrypted
# with the $ENCRYPTION_PASSWORD.
# IOS_SIGNING_CERT_PASSWORD - the password to the provisioning profile
# certificate key (used to open development-key.p12 from the tutorial).
# IOS_TEAM_ID - the team ID inserted into build-ipa-.plist.template file in
# place of "YOUR_TEAM_ID".
# Travis will not print the last echo if there's no sleep 1
function echoSleepAndExit1() {
echo $1
sleep 1
exit 1
}
echo "TRAVIS_BRANCH=${TRAVIS_BRANCH}"
echo "TRAVIS_REPO_SLUG=${TRAVIS_REPO_SLUG}"
if [ -z $PR_REPO_SLUG ]; then
echoSleepAndExit1 "No PR_REPO_SLUG defined"
fi
if [ -z $PR_BRANCH ]; then
echoSleepAndExit1 "No PR_BRANCH defined"
fi
if [ -z $IPA_DEPLOY_LOCATION ]; then
echoSleepAndExit1 "No IPA_DEPLOY_LOCATION defined"
fi
echo "PR_REPO_SLUG=${PR_REPO_SLUG} PR_BRANCH=${PR_BRANCH}"
# do the merge and git log
if [ $PR_BRANCH != "master" ]; then
echo "Will merge ${PR_REPO_SLUG}/${PR_BRANCH} into master"
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch origin master
git checkout master
git pull https://github.com/${PR_REPO_SLUG}.git $PR_BRANCH --no-edit
fi
# Link this lib-jitsi-meet checkout in jitsi-meet through the package.json
if [ ! -z ${LIB_JITSI_MEET_PKG} ];
then
echo "Adjusting lib-jitsi-meet package in package.json to ${LIB_JITSI_MEET_PKG}"
# escape for the sed
LIB_JITSI_MEET_PKG=$(echo $LIB_JITSI_MEET_PKG | sed -e 's/\\/\\\\/g; s/\//\\\//g; s/&/\\\&/g')
sed -i.bak -e "s/\"lib-jitsi-meet.*/\"lib-jitsi-meet\"\: \"${LIB_JITSI_MEET_PKG}\",/g" package.json
echo "Package.json lib-jitsi-meet line:"
grep lib-jitsi-meet package.json
else
echo "LIB_JITSI_MEET_PKG var not set - will not modify the package.json"
fi
git log -20 --graph --pretty=format':%C(yellow)%h%Cblue%d%Creset %s %C(white) %an, %ar%Creset'
#certificates
CERT_DIR="ios/travis-ci/certs"
mkdir -p $CERT_DIR
./ios/ci/setup-certificates.sh $CERT_DIR
curl -L -o ${CERT_DIR}/id_rsa.enc ${DEPLOY_SSH_CERT_URL}
openssl aes-256-cbc -k "$ENCRYPTION_PASSWORD" -in ${CERT_DIR}/id_rsa.enc -d -a -out ${CERT_DIR}/id_rsa
chmod 0600 ${CERT_DIR}/id_rsa
ssh-add ${CERT_DIR}/id_rsa
npm install
# Ever since the Apple Watch app has been added the bitcode for WebRTC needs to be downloaded in order to build successfully
./node_modules/react-native-webrtc/tools/downloadBitcode.sh
cd ios
pod install --repo-update --no-ansi
cd ..
mkdir -p /tmp/jitsi-meet/
xcodebuild archive -quiet -workspace ios/jitsi-meet.xcworkspace -scheme jitsi-meet -configuration Release -archivePath /tmp/jitsi-meet/jitsi-meet.xcarchive
sed -e "s/YOUR_TEAM_ID/${IOS_TEAM_ID}/g" ios/ci/build-ipa.plist.template > ios/ci/build-ipa.plist
IPA_EXPORT_DIR=/tmp/jitsi-meet/jitsi-meet-ipa
xcodebuild -quiet -exportArchive -archivePath /tmp/jitsi-meet/jitsi-meet.xcarchive -exportPath $IPA_EXPORT_DIR -exportOptionsPlist ios/ci/build-ipa.plist
echo "Will try deploy the .ipa to: ${IPA_DEPLOY_LOCATION}"
if [ ! -z ${SCP_PROXY_HOST} ];
then
scp -o ProxyCommand="ssh -t -A -l %r ${SCP_PROXY_HOST} -o \"StrictHostKeyChecking no\" -o \"BatchMode yes\" -W %h:%p" -o StrictHostKeyChecking=no -o LogLevel=DEBUG "${IPA_EXPORT_DIR}/jitsi-meet.ipa" "${IPA_DEPLOY_LOCATION}"
else
scp -o StrictHostKeyChecking=no -o LogLevel=DEBUG "${IPA_EXPORT_DIR}/jitsi-meet.ipa" "${IPA_DEPLOY_LOCATION}"
fi

View File

@@ -1484,6 +1484,7 @@
"connectionInfo": "Verbindungsinformationen",
"demote": "Zu Gästen verschieben",
"domute": "Stummschalten",
"domuteDesktopOfOthers": "Bildschirm freigeben für alle beenden",
"domuteOthers": "Alle anderen stummschalten",
"domuteVideo": "Kamera ausschalten",
"domuteVideoOfOthers": "Alle anderen Kameras auschalten",

View File

@@ -120,7 +120,7 @@
"messageAccessibleTitle": "{{user}} dit: ",
"messageAccessibleTitleMe": "Je dis: ",
"messageTo": "Message privé à {{recipient}}",
"messagebox": "Saisissez un message",
"messagebox": "Envoyer un message",
"newMessages": "Nouveaux messages",
"nickname": {
"popover": "Choisissez un pseudonyme",

View File

@@ -114,6 +114,9 @@
"error": "Errore: il tuo messaggio non è stato inviato. Motivo: {{error}}",
"everyone": "Tutti",
"fieldPlaceHolder": "Scrivi qui il tuo messaggio",
"fileAccessibleTitle": "{{user}} ha caricato un file",
"fileAccessibleTitleMe": "ho caricato un file",
"fileDeleted": "Un file è stato eliminato",
"guestsChatIndicator": "(ospite)",
"lobbyChatMessageTo": "Messaggio a {{recipient}} in sala d'attesa",
"message": "Messaggio",
@@ -280,7 +283,6 @@
"Submit": "Invia",
"Understand": "Accetto, mantieni microfono e videocamera disattivati per ora",
"UnderstandAndUnmute": "Accetto, riattiva microfono e videocamera",
"WaitForHostMsg": "La riunione non è ancora iniziata. Se sei l'organizzatore, per favore autenticati. Altrimenti, attendi l'arrivo dell'organizzatore.",
"WaitForHostNoAuthMsg": "La riunione non è ancora iniziata perché nessun organizzatore si è ancora collegato. Si prega di attendere.",
"WaitingForHostButton": "Attendi l'organizzatore",
"WaitingForHostTitle": "In attesa dell'organizzatore…",
@@ -523,6 +525,7 @@
"tokenAuthFailedWithReasons": "Non sei autorizzato a partecipare a questa chiamata. Possibile motivo: {{reason}}",
"tokenAuthUnsupported": "Il token URL non è supportato.",
"transcribing": "Trascrizione in corso",
"unauthenticatedAccessDisabled": "Questa chiamata richiede l'autenticazione. Si prega di accedere per procedere.",
"unlockRoom": "Rimuovi la $t(lockRoomPassword) alla riunione",
"user": "Utente",
"userIdentifier": "Identificatore utente",
@@ -570,10 +573,12 @@
"downloadStarted": "Download del file iniziato",
"dragAndDrop": "Trascina e rilascia i file qui o da qualsiasi altra parte nella schermata",
"fileAlreadyUploaded": "Questo file è già stato caricato nella riunione.",
"fileRemovedByOther": "Il tuo file '{{ fileName }}' è stato rimosso",
"fileTooLargeDescription": "Assicurati che il file non superi {{ maxFileSize }}.",
"fileTooLargeTitle": "Il file selezionato è troppo grande",
"fileUploadProgress": "Caricamento del file in corso",
"fileUploadedSuccessfully": "Il file è stato caricato con successo",
"newFileNotification": "{{ participantName }} ha condiviso '{{ fileName }}'",
"removeFile": "Rimuovi",
"removeFileSuccess": "File rimosso con successo",
"uploadFailedDescription": "Si prega di riprovare.",
@@ -748,7 +753,8 @@
"notificationTitle": "Sala d'attesa",
"passwordJoinButton": "Entra",
"title": "Sala d'attesa",
"toggleLabel": "Attiva sala d'attesa"
"toggleLabel": "Attiva sala d'attesa",
"waitForModerator": "La riunione non è ancora iniziata, perché non è arrivato alcun organizzatore. Se vuoi diventarlo autenticati, altrimenti attendi."
},
"localRecording": {
"clientState": {
@@ -964,6 +970,9 @@
"by": "Da {{ name }}",
"closeButton": "Chiudi sondaggio",
"create": {
"accessibilityLabel": {
"send": "Invia sondaggio"
},
"addOption": "Aggiungi opzione",
"answerPlaceholder": "Opzione {{index}}",
"cancel": "Annulla",
@@ -972,8 +981,7 @@
"pollQuestion": "Domanda del sondaggio",
"questionPlaceholder": "Fai una domanda",
"removeOption": "Elimina opzione",
"save": "Salva",
"send": "Invia"
"save": "Salva"
},
"errors": {
"notUniqueOption": "Le opzioni devono essere uniche"
@@ -1617,6 +1625,8 @@
"noMainParticipantsTitle": "La riunione non è ancora iniziata.",
"noVisitorLobby": "Non puoi partecipare se la sala d'attesa è attiva per la riunione.",
"notAllowedPromotion": "Un partecipante deve autorizzare la tua richiesta prima.",
"requestToJoin": "Mano alzata",
"requestToJoinDescription": "La tua richiesta è stata inviata ai relatori. Tieni duro!",
"title": "Sei uno spettatore nella riunione"
},
"waitingMessage": "Ti unirai alla riunione quando inizierà!"

View File

@@ -114,6 +114,9 @@
"error": "Kļūda: Jūsu ziņa netika nosūtīta. Cēlonis: {{error}}",
"everyone": "Visi",
"fieldPlaceHolder": "Rakstiet ziņu šeit",
"fileAccessibleTitle": "{{user}} augšuplādēja failu",
"fileAccessibleTitleMe": "es augšuplādēju failu",
"fileDeleted": "Fails tika dzēsts",
"guestsChatIndicator": "(viesis)",
"lobbyChatMessageTo": "Vestibila tērzēšanas ziņa adresātam {{recipient}}",
"message": "Ziņa",
@@ -123,12 +126,20 @@
"messagebox": "Rakstiet ziņu",
"newMessages": "Jaunas ziņas",
"nickname": {
"popover": "Izvēlieties vārdu",
"title": "Ierakstiet vārdu, lai izmantotu tērzēšanā",
"titleWithCC": "Ievadiet segvārdu, lai izmantotu tērzēšanā un slēptos subtitros",
"titleWithPolls": "Ierakstiet segvārdu, lai izmantotu tērzēšanā un aptaujās",
"titleWithPollsAndCC": "Ievadiet segvārdu, lai izmantotu tērzēšanā, aptaujās un slēptos subtitros",
"titleWithPollsAndCCAndFileSharing": "Ievadiet segvārdu, lai izmantotu tērzēšanā, aptaujās, slēptos subtitros un failos"
"featureChat": "tērzētava",
"featureClosedCaptions": "slēgtie subtitri",
"featureFileSharing": "failu kopīgošana",
"featurePolls": "aptaujas",
"popover": "Izvēlieties segvārdu",
"title": "Ierakstiet segvārdu, lai izmantotu tērzēšanu",
"titleWith1Features": "Ievadiet segvārdu, lai izmantotu {{feature1}}",
"titleWith2Features": "Ievadiet segvārdu, lai izmantotu {{feature1}} un {{feature2}}",
"titleWith3Features": "Ievadiet segvārdu, lai izmantotu {{feature1}}, {{feature2}} un {{feature3}}",
"titleWith4Features": "Ievadiet segvārdu, lai izmantotu {{feature1}}, {{feature2}}, {{feature3}} un {{feature4}}",
"titleWithCC": "Ievadiet segvārdu, lai izmantotu tērzēšanu un slēgtos subtitrus",
"titleWithPolls": "Ierakstiet segvārdu, lai izmantotu tērzēšanu un aptaujas",
"titleWithPollsAndCC": "Ievadiet segvārdu, lai izmantotu tērzēšanu, aptaujas un slēgtos subtitrus",
"titleWithPollsAndCCAndFileSharing": "Ievadiet segvārdu, lai izmantotu tērzēšanu, aptaujas, slēgtos subtitrus un failus"
},
"noMessagesMessage": "Sapulcē pagaidām nav nevienas ziņas. Uzsāciet saraksti!",
"privateNotice": "Privāta ziņa adresātam {{recipient}}",
@@ -137,12 +148,12 @@
"systemDisplayName": "Sistēma",
"tabs": {
"chat": "Tērzēšana",
"closedCaptions": "Slēptie subtitri",
"closedCaptions": "Slēgtie subtitri",
"fileSharing": "Faili",
"polls": "Aptaujas"
},
"title": "Tērzēšana",
"titleWithCC": "Tērzēšana un Slēptie subtitri",
"titleWithCC": "Tērzēšana un Slēgtie subtitri",
"titleWithFeatures": "Tērzēšana un",
"titleWithFileSharing": "Faili",
"titleWithPolls": "Tērzēšana un Aptaujas",
@@ -156,8 +167,8 @@
"installExtensionText": "Uzstādīt spraudni Google kalendāra un Office 365 integrācijai"
},
"closedCaptionsTab": {
"emptyState": "Slēpto subtitru saturs būs pieejams, tiklīdz moderators uzsāks to.",
"startClosedCaptionsButton": "Uzsākt slēptos subtitrus"
"emptyState": "Slēgto subtitru saturs būs pieejams, tiklīdz moderators uzsāks to.",
"startClosedCaptionsButton": "Uzsākt slēgtos subtitrus"
},
"connectingOverlay": {
"joiningRoom": "Notiek pieslēgšanās jūsu sapulcei…"
@@ -280,7 +291,6 @@
"Submit": "Iesniegt",
"Understand": "Saprotu",
"UnderstandAndUnmute": "Es saprotu, lūdzu, ieslēdziet skaņu.",
"WaitForHostMsg": "Sapulce vēl nav sākusies, jo vēl nav ieradies neviens moderators. Lūdzu, autorizējieties, lai kļūtu par moderatoru. Pretējā gadījumā, lūdzu, uzgaidiet.",
"WaitForHostNoAuthMsg": "Sapulce vēl nav sākusies, jo vēl nav ieradies neviens moderators. Lūdzu, uzgaidiet.",
"WaitingForHostButton": "Gaidīt rīkotāju",
"WaitingForHostTitle": "Gaida rīkotāju…",
@@ -417,7 +427,7 @@
"muteParticipantsVideoDialog": "Vai tiešām vēlaties izslēgt šī dalībnieka kameru? Jūs nevarēsiet to ieslēgt atpakaļ, taču dalībnieks pats to varēs izdarīt jebkurā laikā.",
"muteParticipantsVideoDialogModerationOn": "Vai tiešām vēlaties izslēgt šī dalībnieka kameru? Ne Jūs, ne dalībnieks nevarēsiet to ieslēgt atpakaļ.",
"muteParticipantsVideoTitle": "Vai izslēgt šī dalībnieka video?",
"noDropboxToken": "Nav derīga Dropbox tokena",
"noDropboxToken": "Nav derīgas Dropbox pilnvaras",
"password": "Parole",
"passwordLabel": "Dalībnieks ir aizslēdzis sapulci. Lūdzu, ievadiet $t(lockRoomPassword), lai pievienotos.",
"passwordNotSupported": "Sapulces slēgšana ar $t(lockRoomPassword) netiek atbalstīta.",
@@ -501,7 +511,7 @@
"stopStreamingWarning": "Tiešām vēlaties beigt tiešraidi?",
"streamKey": "Tiešraides atslēga",
"thankYou": "Paldies, ka izmantojāt {{appName}}!",
"token": "tokens",
"token": "pilnvara",
"tokenAuthFailed": "Atvainojiet, jums nav atļauts pievienoties šim zvanam.",
"tokenAuthFailedReason": {
"audInvalid": "Nederīga `aud` vērtība. Tai vajadzētu būt `jitsi`.",
@@ -517,12 +527,13 @@
"nbfFuture": "`nbf` vērtība ir nākotnē.",
"nbfInvalid": "Nederīga `nbf` vērtība.",
"payloadNotFound": "Trūkst satura.",
"tokenExpired": "Token ir beidzies."
"tokenExpired": "Pilnvara ir beigusies."
},
"tokenAuthFailedTitle": "Autentifikācijas kļūda",
"tokenAuthFailedWithReasons": "Atvainojiet, jums nav atļauts pievienoties šim zvanam. Iespējamie iemesli: {{reason}}",
"tokenAuthUnsupported": "Token URL netiek atbalstīts.",
"tokenAuthUnsupported": "Pilnvaras URL nav atbalstīts.",
"transcribing": "Notiek atšifrējuma izveide",
"unauthenticatedAccessDisabled": "Šim zvanam nepieciešama autentifikācija. Lūdzu, piesakieties, lai turpinātu.",
"unlockRoom": "Noņemt $t(lockRoomPassword)",
"user": "Lietotājs",
"userIdentifier": "Lietotājvārds",
@@ -570,10 +581,12 @@
"downloadStarted": "Sākta faila lejuplāde",
"dragAndDrop": "Velciet un palaidiet failus šeit, vai jebkurā ekrāna vietā",
"fileAlreadyUploaded": "Fails jau ir augšuplādēts šajā sanāksmē.",
"fileRemovedByOther": "Jūsu fails '{{ fileName }}' tika noņemts",
"fileTooLargeDescription": "Lūdzu, pārliecinieties, vai faila lielums nepārsniedz {{ maxFileSize }}.",
"fileTooLargeTitle": "Izvēlētais fails ir pārāk liels",
"fileUploadProgress": "Faila augšuplādes gaita",
"fileUploadedSuccessfully": "Fails veiksmīgi augšuplādēts",
"newFileNotification": "{{ participantName }} kopīgoja '{{ fileName }}'",
"removeFile": "Noņemt",
"removeFileSuccess": "Fails veiksmīgi noņemts",
"uploadFailedDescription": "Lūdzu, mēģiniet vēlreiz.",
@@ -748,7 +761,8 @@
"notificationTitle": "Vestibils",
"passwordJoinButton": "Pievienoties",
"title": "Vestibils",
"toggleLabel": "Iespējot vestibilu"
"toggleLabel": "Iespējot vestibilu",
"waitForModerator": "Konference vēl nav sākusies, jo vēl nav ieradušies moderatori. Ja vēlaties kļūt par moderatoru, lūdzu, piesakieties. Pretējā gadījumā, lūdzu, uzgaidiet."
},
"localRecording": {
"clientState": {
@@ -775,7 +789,7 @@
"participant": "Dalībnieks",
"participantStats": "Dalībnieku statistika",
"selectTabTitle": "🎥 Lūdzu, atveriet šo cilni ierakstīšanai",
"sessionToken": "Sessijas tokens",
"sessionToken": "Sesijas Pilnvara",
"start": "Sākt ierakstu",
"stop": "Beigt ierakstu",
"stopping": "Ierakstīšanas pārtraukšana",
@@ -865,6 +879,7 @@
"oldElectronClientDescription1": "Izskatās, ka jūs izmantojat vecu Jitsi Meet klienta versiju, kurai ir zināmas drošības ievainojamības. Lūdzu, atjauniniet uz ",
"oldElectronClientDescription2": "jaunākā versija",
"oldElectronClientDescription3": "tagad!",
"openChat": "Atvērt tērzētavu",
"participantWantsToJoin": "Vēlas pievienoties sapulcei",
"participantsWantToJoin": "Vēlas pievienoties sapulcei",
"passwordRemovedRemotely": "Kāds dalībnieks noņēma $t(lockRoomPasswordUppercase).",
@@ -963,6 +978,9 @@
"by": "Pēc {{ name }} iniciatīvas",
"closeButton": "Slēgt aptauju",
"create": {
"accessibilityLabel": {
"send": "Nosūtīt aptauju"
},
"addOption": "Pievienot opciju",
"answerPlaceholder": "Opcija {{index}}",
"cancel": "Atcelt",
@@ -971,8 +989,7 @@
"pollQuestion": "Aptaujas Jautājums",
"questionPlaceholder": "Uzdod jautājumu",
"removeOption": "Noņemt opciju",
"save": "Saglabāt",
"send": "Nosūtīt"
"save": "Saglabāt"
},
"errors": {
"notUniqueOption": "Iespējām jābūt unikālām"
@@ -1091,7 +1108,7 @@
}
},
"recording": {
"authDropboxText": "Augšupielādēt uz Dropbox",
"authDropboxText": "Augšuplādēt uz Dropbox",
"availableSpace": "Pieejama vieta: {{spaceLeft}} MB (apmēram {{duration}} ieraksta minūtes)",
"beta": "BETA",
"busy": "Cenšamies nodrošināt ierakstam vairāk resursu. Lūdzu, pēc dažām minūtēm pamēģiniet vēlreiz.",
@@ -1145,7 +1162,7 @@
"title": "Ieraksts",
"unavailable": "Hmm! {{serviceName}} pašlaik nav pieejams. Mēs strādājam pie problēmas risināšanas. Lūdzu, pamēģiniet vēlreiz vēlāk.",
"unavailableTitle": "Ieraksts nav iespējams",
"uploadToCloud": "Augšupielādēt mākonī"
"uploadToCloud": "Augšuplādēt mākonī"
},
"screenshareDisplayName": "{{name}} ekrāns",
"sectionList": {
@@ -1300,7 +1317,7 @@
"closeChat": "Aizvērt tērzēšanu",
"closeMoreActions": "Aizvērt vairāk darbību izvēlni",
"closeParticipantsPane": "Aizvērt dalībnieku paneli",
"closedCaptions": "Slēptie subtitri",
"closedCaptions": "Slēgtie subtitri",
"collapse": "Sakļaut",
"document": "Kopīgotais dokuments (iesl./izsl.)",
"documentClose": "Aizvērt kopīgoto dokumentu",
@@ -1378,7 +1395,21 @@
"videomuteGUMPending": "Kameras pievienošana",
"videounmute": "Ieslēgt kameru"
},
"addPeople": "Pievienot cilvēkus savai sesijai/zvanam",
"addPeople": "Pievienot cilvēkus savam zvanam",
"advancedAudioSettings": {
"aec": {
"label": "Akustiskās atbalss slāpēšana"
},
"agc": {
"label": "Automātiska pastiprinājuma kontrole"
},
"ns": {
"label": "Trokšņu slāpēšana"
},
"stereo": {
"label": "Stereo"
}
},
"audioOnlyOff": "Atspējot kanāla/trafika taupības režīmu",
"audioOnlyOn": "Iespējot kanāla/trafika taupības režīmu",
"audioRoute": "Izvēlēties audioierīci",
@@ -1391,7 +1422,7 @@
"closeChat": "Aizvērt tērzētavu",
"closeParticipantsPane": "Aizvērt dalībnieku paneli",
"closeReactionsMenu": "Aizvērt reakciju izvēlni",
"closedCaptions": "Slēptie subtitri",
"closedCaptions": "Slēgtie subtitri",
"disableNoiseSuppression": "Atspējot trokšņu slāpēšanu",
"disableReactionSounds": "Šai sapulcei varat atspējot reakcijas skaņas",
"documentClose": "Aizvērt kopīgoto dokumentu",
@@ -1406,6 +1437,7 @@
"exitFullScreen": "Pilnekrāna režīms",
"exitTileView": "Tuvplāna režīms",
"feedback": "Atstāts atsauksmi",
"fileSharing": "Failu kopīgošana",
"giphy": "GIPHY izvēlne (rādīt/nerādīt)",
"hangup": "Iziet no sapulces",
"help": "Palīdzība",
@@ -1441,17 +1473,19 @@
"openReactionsMenu": "Atvērt reakciju izvēlni",
"participants": "Dalībnieki",
"pip": "Iesl. attēls attēlā (PIP) režīmu",
"polls": "Aptaujas",
"privateMessage": "Nosūtīt privātu ziņu",
"profile": "Rediģēt profilu",
"raiseHand": "Pacelt roku",
"raiseYourHand": "Pacelt roku",
"reactionBoo": "Nosūtīt būū reakciju",
"reactionClap": "Nosūtīt aplausu reakciju",
"reactionHeart": "Nosūtīt sirds reakciju",
"reactionLaugh": "Nosūtīt smieklu reakciju",
"reactionLike": "Nosūtīt īkšķi augšup reakciju",
"reactionSilence": "Nosūtīt klusuma reakciju",
"reactionSurprised": "Nosūtīt pārsteigts reakciju",
"reactionBoo": "Sūtīt būū reakciju",
"reactionClap": "Sūtīt aplausu reakciju",
"reactionHeart": "Sūtīt sirds reakciju",
"reactionLaugh": "Sūtīt smieklu reakciju",
"reactionLike": "Sūtīt īkšķis augšup reakciju",
"reactionLove": "Sūtīt mīlestības reakciju",
"reactionSilence": "Sūtīt klusuma reakciju",
"reactionSurprised": "Sūtīt pārsteiguma reakciju",
"reactions": "Reakcijas",
"security": "Drošības iespējas",
"selectBackground": "Izvēlēties fonu",
@@ -1484,7 +1518,7 @@
"failed": "Atšifrējuma izveide neizdevās",
"labelTooltip": "Šajā sapulcē notiek atšifrējuma izveide.",
"labelTooltipExtra": "Turklāt vēlāk būs pieejams atšifrējums.",
"openClosedCaptions": "Atvērt slēptos subtitrus",
"openClosedCaptions": "Atvērt slēgtos subtitrus",
"original": "Oriģināls",
"sourceLanguageDesc": "Pašlaik sapulces valoda ir iestatīta uz <b>{{sourceLanguage}}</b>. <br/> Varat to mainīt no ",
"sourceLanguageHere": "šeit",
@@ -1582,7 +1616,7 @@
"removeBackground": "Noņemt fonu",
"slightBlur": "Viegli izplūdis",
"title": "Virtuālie foni",
"uploadedImage": "Augšupielādēts attēls {{index}}",
"uploadedImage": "Augšuplādēts attēls {{index}}",
"webAssemblyWarning": "WebAssembly netiek atbalstīts",
"webAssemblyWarningDescription": "WebAssemb ir atspējots vai šī pārlūkprogramma to neatbalsta"
},
@@ -1601,6 +1635,8 @@
"noMainParticipantsTitle": "Šī sapulce vēl nav sākusies.",
"noVisitorLobby": "Jūs nevarat pievienoties, kamēr sapulcei ir iespējots vestibils.",
"notAllowedPromotion": "Dalībniekam vispirms ir jāatļauj jūsu pieprasījums.",
"requestToJoin": "Roka Pacelta",
"requestToJoinDescription": "Jūsu pieprasījums tika nosūtīts moderatoriem. Uzgaidiet!",
"title": "Jūs esat sapulces apmeklētājs"
},
"waitingMessage": "Jūs pievienosities sapulcei, tiklīdz tā sāksies!"

View File

@@ -109,9 +109,12 @@
}
},
"chat": {
"disabled": "Skicka chattmeddelande är inaktiverat",
"enter": "Delta i mötet",
"error": "Fel: ditt meddelande skickades inte. Orsak: {{error}}",
"everyone": "Alla",
"fieldPlaceHolder": "Skriv ditt meddelande här",
"guestsChatIndicator": "(gäst)",
"lobbyChatMessageTo": "Skicka meddelande",
"message": "Meddelande",
"messageAccessibleTitle": "{{user}} Säger:",
@@ -122,7 +125,10 @@
"nickname": {
"popover": "Välj ett namn",
"title": "Skriv in ett namn för att börja använda chatten",
"titleWithPolls": "Skriv in ett namn för att börja använda chatten"
"titleWithCC": "Skriv in ett namn för att börja använda chatten och för undertexter",
"titleWithPolls": "Skriv in ett namn för att börja använda chatten och omröstningar",
"titleWithPollsAndCC": "Skriv in ett namn för att börja använda chatten, omröstningar och undertexter",
"titleWithPollsAndCCAndFileSharing": "Skriv in ett namn för att börja använda chatten, omröstningar, undertexter och fildelning"
},
"noMessagesMessage": "Det finns ännu inga meddelanden i mötet. Påbörja en konversation!",
"privateNotice": "Privat meddelande till {{recipient}}",
@@ -131,11 +137,16 @@
"systemDisplayName": "",
"tabs": {
"chat": "Chatt",
"closedCaptions": "Undertexter",
"fileSharing": "Fildelning",
"polls": "Omröstningar"
},
"title": "Chatt",
"titleWithPolls": "Chatt",
"you": "du"
"titleWithCC": "Undertexter",
"titleWithFeatures": "Chatt och",
"titleWithFileSharing": "Filer",
"titleWithPolls": "Omröstningar",
"you": "dig"
},
"chromeExtensionBanner": {
"buttonText": "Installera Chrome-tillägg",
@@ -144,6 +155,10 @@
"dontShowAgain": "Visa inte det här igen",
"installExtensionText": "Installera tillägget för integration med Google Kalender och Office 365"
},
"closedCaptionsTab": {
"emptyState": "Undertexter kommer vara tillgängliga när en moderator startar de",
"startClosedCaptionsButton": "Starta undertexter"
},
"connectingOverlay": {
"joiningRoom": "Ansluter till mötet…"
},
@@ -263,7 +278,8 @@
"Remove": "Ta bort",
"Share": "Dela",
"Submit": "Skicka",
"WaitForHostMsg": "Konferensen har inte börjat än. Autentisera konferensen om du är värd. Vänta annars på att värden startar konferensen.",
"Understand": "Jag förstår, låt min mikrofon vara avstängd tillsvidare",
"UnderstandAndUnmute": "Jag förstår, starta min mikrofon",
"WaitForHostNoAuthMsg": "Konferensen har ännu inte startat eftersom ingen värd har anlänt ännu. Vänligen vänta.",
"WaitingForHostButton": "Vänta på värd",
"WaitingForHostTitle": "Väntar på värden…",
@@ -285,6 +301,12 @@
"alreadySharedVideoTitle": "Endast en delad video åt gången tillåts",
"applicationWindow": "Applikationsfönster",
"authenticationRequired": "Autentisering krävs",
"cameraCaptureDialog": {
"description": "Ta ett foto och skicka de via din mobila enhet",
"ok": "Starta kamera",
"reject": "Inte nu",
"title": "Ta ett foto"
},
"cameraConstraintFailedError": "Din kamera uppfyller inte kraven för användning.",
"cameraNotFoundError": "Hittar ingen kamera.",
"cameraNotSendingData": "Vi saknar åtkomst till kameran. Kontrollera om ett annat program använder enheten, välj en annan enhet från inställningsmenyn eller försök att starta om programmet.",
@@ -299,6 +321,7 @@
"conferenceReloadMsg": "Vi försöker fixa problemet. Återansluter om {{seconds}} sekunder…",
"conferenceReloadTitle": "Något gick snett.",
"confirm": "Bekräfta",
"confirmBack": "Bakåt",
"confirmNo": "Nej",
"confirmYes": "Ja",
"connectError": "Ojdå! Något gick fel och vi kunde inte ansluta till konferensen.",
@@ -331,11 +354,12 @@
"internalError": "Ett fel uppstod. Fel: {{error}}",
"internalErrorTitle": "Internt fel",
"kickMessage": "Du kan kontakta {{participantDisplayName}} för mer information.",
"kickParticipantButton": "Ta bort från mötet",
"kickParticipantButton": "Ta bort deltagaren från mötet",
"kickParticipantDialog": "Vill du ta bort denna deltagaren från mötet?",
"kickParticipantTitle": "Tysta deltagaren?",
"kickSystemTitle": "Du har blivit borttagen från mötet",
"kickTitle": "{{participantDisplayName}} tog bort dig från mötet",
"learnMore": "Läs mer",
"linkMeeting": "Länka möte",
"linkMeetingTitle": "Länka möte till Salesforce",
"liveStreaming": "Streama",
@@ -358,22 +382,34 @@
"micTimeoutError": "Time out, kunde ej starta ljud enhet",
"micUnknownError": "Av okänd anledning kan inte din mikrofon användas.",
"moderationAudioLabel": "Tillåt deltagarna att slå på ljudet för sig själva",
"moderationDesktopLabel": "Tillåt deltagare att skärmdela",
"moderationVideoLabel": "Tillåt deltagarna att starta sin video",
"muteEveryoneDialog": "Är du säker på att du vill tysta alla? Du kan inte slå på mikrofonen åt dem, men de kan själva slå på sin egen mikrofon när som helst.",
"muteEveryoneDialogModerationOn": "Deltagarna kan när som helst begära att få prata.",
"muteEveryoneElseDialog": "När någon tystats kan du inte slå på mikrofonen, men de kan själva slå på sin egen mikrofon när som helst.",
"muteEveryoneElseTitle": "Tysta alla utom {{whom}}?",
"muteEveryoneElsesDesktopDialog": "När delningen är stoppad kommer du inte kunna starta den igen. Men de kan dela med dig igen.",
"muteEveryoneElsesDesktopTitle": "Stoppa allas skärmdelning utom {{whom}}?",
"muteEveryoneElsesVideoDialog": "När kameran är inaktiverad kan den inte aktiveras igen. Däremot kan övriga deltagare aktivera sina kameror.",
"muteEveryoneElsesVideoTitle": "Inaktivera allas kameror förutom {{whom}}",
"muteEveryoneSelf": "Dig själv",
"muteEveryoneStartMuted": "Alla börjar tystade",
"muteEveryoneTitle": "Tysta alla?",
"muteEveryonesDesktopDialog": "Deltagarna kan dela sin skärm när som helst. Du kan inte starta deras skärmdelning åt dem.",
"muteEveryonesDesktopDialogModerationOn": "Deltagarna kan skicka en förfrågan om att starta skärmdelningen.",
"muteEveryonesDesktopTitle": "Stoppa alla deltagares skärmdelning?",
"muteEveryonesVideoDialog": "Är du säker du vill inaktivera allas kameror. Du kommer inte att kunna aktivera dessa igen. Däremot kommer deltagarna att kunna aktivera sin egen kamera när som.",
"muteEveryonesVideoDialogModerationOn": "Deltagarna kan när som helst begära att få aktivera sin kamera.",
"muteEveryonesVideoDialogOk": "Inaktivera",
"muteEveryonesVideoTitle": "Inaktiveras allas kameror",
"muteParticipantBody": "Du kan inte aktivera deras mikrofoner, men de kan göra det själva.",
"muteParticipantButton": "Tysta",
"muteParticipantsDesktopBody": "Du kommer inte kunna starta deltagarnas skärmdelning. Men deltagare kan starta skärmdelning.",
"muteParticipantsDesktopBodyModerationOn": "Du kommer inte kunna starta deltagarnas skärmdelning.Deltagare kommer inte kunna starta deras skärmdelning.",
"muteParticipantsDesktopButton": "Stoppa skärmdelning",
"muteParticipantsDesktopDialog": "Är du säker på att du vill stänga av deltagarens skärmdelning? Du kommer inte kunna slå igång den igen, utan deltagaren måste starta de igen.",
"muteParticipantsDesktopDialogModerationOn": "Är du säker på att du vill stänga av deltagarens skärmdelning? Du kommer inte kunna slå igång den igen, deltagaren kommer inte heller kunna starta den igen.",
"muteParticipantsDesktopTitle": "Avaktivera skärmdelning för deltagaren?",
"muteParticipantsVideoBody": "Du kommer inte att kunna aktivera kameran igen. Däremot kan deltagaren kunna aktivera sin egen kamera när som.",
"muteParticipantsVideoBodyModerationOn": "Du och deltagarna kommer inte att kunna aktivera kameran igen.",
"muteParticipantsVideoButton": "Inaktivera kamera",
@@ -393,6 +429,10 @@
"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.",
"recordingInProgressTitle": "Inspelning pågår",
"rejoinNow": "Återanslut nu",
"remoteControlAllowedMessage": "{{user}} godkände din begäran om fjärrstyrning.",
"remoteControlDeniedMessage": "{{user}} avböjde din begäran om fjärrstyrning.",
@@ -482,6 +522,7 @@
"tokenAuthFailedWithReasons": "Förlåt, du har inte tillåtelse att gå med i det här samtalet. Troliga anledingar: {{reason}}",
"tokenAuthUnsupported": "Token URL är inte tillåten",
"transcribing": "Transkriberar",
"unauthenticatedAccessDisabled": "Detta samtalet kräver identifiering. Logga in för att fortsätta.",
"unlockRoom": "Ta bort möte $t(lockRoomPassword)",
"user": "Användare",
"userIdentifier": "Användar-ID",
@@ -522,6 +563,25 @@
"veryBad": "Mycket dåligt",
"veryGood": "Mycket bra"
},
"fileSharing": {
"downloadFailedDescription": "Försök igen.",
"downloadFailedTitle": "Nedladdning misslyckades",
"downloadFile": "Ladda ner",
"downloadStarted": "Nedladdning har startat",
"dragAndDrop": "Dra och släpp filen här eller någonstans på skärmen",
"fileAlreadyUploaded": "Filen har redan laddats upp till mötet.",
"fileRemovedByOther": "Filen vid namn '{{ fileName }}' har tagits bort",
"fileTooLargeDescription": "Se till att filstorleken inte överskrider {{ maxFileSize }}.",
"fileTooLargeTitle": "Den valda filen är för stor",
"fileUploadProgress": "Överföring pågår",
"fileUploadedSuccessfully": "Överföring lyckades",
"newFileNotification": "{{ participantName }} delade '{{ fileName }}'",
"removeFile": "Ta bort",
"removeFileSuccess": "Filen togs bort",
"uploadFailedDescription": "Snälla försök igen.",
"uploadFailedTitle": "Överföring misslyckades",
"uploadFile": "Dela fil"
},
"filmstrip": {
"accessibilityLabel": {
"heading": "Videominiatyrer"
@@ -690,7 +750,8 @@
"notificationTitle": "Väntrum",
"passwordJoinButton": "Anslut",
"title": "Lobby",
"toggleLabel": "Aktivera väntrum"
"toggleLabel": "Aktivera väntrum",
"waitForModerator": "Konferensen har annu inte startat för ingen moderator anslutit. Om du vill bli moderator var vänlig logga in. Annars, var god dröj."
},
"localRecording": {
"clientState": {
@@ -733,7 +794,10 @@
"me": "jag",
"notify": {
"OldElectronAPPTitle": "Säkerhetsproblem!",
"allowAction": "Tillåt",
"allowAll": "Tillåt",
"allowAudio": "Tillåt ljud",
"allowDesktop": "Tillåt skärmdelning",
"allowVideo": "Tillåt kamera",
"allowedUnmute": "Du kan slå på mikrofonen, starta kameran eller dela din skärm.",
"audioUnmuteBlockedDescription": "Aktivering av mikrofonen har tillfälligt blockerats på grund av systembegränsningar.",
"audioUnmuteBlockedTitle": "Mikrofonen har blockerats!",
@@ -746,8 +810,10 @@
"dataChannelClosedDescription": "Bryggkanalen har kopplats bort och därmed är videokvaliteten begränsad till sin lägsta inställning",
"dataChannelClosedDescriptionWithAudio": "Bryggkanalen har kopplats bort och därmed kan abvrott i ljud och bild uppstå.",
"dataChannelClosedWithAudio": "Ljud och bild kvalite kan vara försämrad.",
"desktopMutedRemotelyTitle": "Din skärmdelning har avslutats av {{participantDisplayName}}",
"disabledIframe": "Inbäddning är endast avsedd för demonstrationsändamål, så det här samtalet kommer att kopplas ner om {{timeout}} minuter.",
"disabledIframeSecondary": "Bädda in {{domain}} är bara till för demo, så detta samtal kommer att kopplas bort inom {{timeout}} minuter. Var god använd <a href='{{jaasDomain}}' rel='nooper noreferrer' target='_blank'>Jitsi som tjänst</a> för att bädda in i produktion.",
"disabledIframeSecondaryNative": "Inbäddning {{domain}} är endast avsedd för demonstrationsändamål, så det här samtalet kommer att kopplas ner om {{timeout}} minuter.",
"disabledIframeSecondaryWeb": "Bädda in {{domain}} är bara till för demo, så detta samtal kommer att kopplas bort inom {{timeout}} minuter. Var god använd <a href='{{jaasDomain}}' rel='nooper noreferrer' target='_blank'>Jitsi som tjänst</a> för att bädda in i produktion.",
"disconnected": "frånkopplad",
"displayNotifications": "Visa aviseringar för",
"dontRemindMe": "Påminn mig inte",
@@ -802,6 +868,7 @@
"oldElectronClientDescription1": "Den version av Jitsi meet som används är gammal och har säkerhetsluckor. Var god uppdatera till den senaste versionen.",
"oldElectronClientDescription2": "senast build",
"oldElectronClientDescription3": "nu!",
"openChat": "Öppna chatt",
"participantWantsToJoin": "Vill vara med på mötet",
"participantsWantToJoin": "Vill vara med på mötet",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) togs bort av en annan deltagare",
@@ -825,6 +892,8 @@
"suggestRecordingDescription": "Vill du starta en inspelning?",
"suggestRecordingTitle": "Spela in detta mötet",
"unmute": "Slå på mikrofonen",
"unmuteScreen": "Starta skärmdelning",
"unmuteVideo": "Starta kamera",
"videoMutedRemotelyDescription": "Du kan alltid slå på den igen.",
"videoMutedRemotelyTitle": "Din kamera har inaktiverats av {{participantDisplayName}}!",
"videoUnmuteBlockedDescription": "Aktivering av kameran och delning av skrivbord har tillfälligt blockerats på grund av systembegränsningar.",
@@ -843,11 +912,14 @@
"admit": "Godkänn",
"admitAll": "Godkänn alla",
"allow": "Låt deltagarna:",
"allowDesktop": "Tillåt skärmdelning",
"allowVideo": "Tillåt kamera",
"askDesktop": "Skicka skärmdelningsförfrågan",
"askUnmute": "Be om att aktivera ljud",
"audioModeration": "Slå på ljudet för sig själva",
"blockEveryoneMicCamera": "Inaktivera allas mikrofon och kamera",
"breakoutRooms": "Grupprum",
"desktopModeration": "Starta skärmdelning",
"goLive": "Gå live",
"invite": "Bjud in någon",
"lowerAllHands": "Ta ner allas händer",
@@ -859,6 +931,8 @@
"muteAll": "Stäng av allt ljud",
"muteEveryoneElse": "Inaktivera ljud för alla deltagare",
"reject": "Avvisa",
"stopDesktop": "Stoppa skärmdelning",
"stopEveryonesDesktop": "Stoppa allas skärmdelning",
"stopEveryonesVideo": "Inaktivera allas video",
"stopVideo": "Inaktivera video",
"unblockEveryoneMicCamera": "Aktivera allas mikrofon och kamera",
@@ -868,12 +942,15 @@
"headings": {
"lobby": "Väntrum ({{count}})",
"participantsList": "Mötesdeltagare ({{count}})",
"viewerRequests": "Deltagar förfrågningar {{count}}",
"visitorInQueue": "(väntande {{count}})",
"visitorRequests": "(förfrågningar {{count}})",
"visitors": "Gäster ({{count}})",
"visitorsList": "Gäster ({{count}})",
"waitingLobby": "Väntar i väntrum ({{count}})"
},
"search": "Sök efter deltagare",
"searchDescription": "Börja skriv för att filtrera bland deltagare",
"title": "Deltagare"
},
"passwordDigitsOnly": "Ange max {{number}} siffror",
@@ -890,6 +967,9 @@
"by": "Av {{ name }}",
"closeButton": "Stäng omröstning",
"create": {
"accessibilityLabel": {
"send": "Skicka omröstning"
},
"addOption": "Lägg till alternativ",
"answerPlaceholder": "Alternativ",
"cancel": "Avbryt",
@@ -898,8 +978,7 @@
"pollQuestion": "Fråga för omröstning",
"questionPlaceholder": "Ställ en fråga",
"removeOption": "Ta bort alternativ",
"save": "Spara",
"send": "Skicka"
"save": "Spara"
},
"errors": {
"notUniqueOption": "Alternativ måste vara unika"
@@ -1100,6 +1179,7 @@
"signedIn": "Hämtar kalenderhändelser från {{email}}. Tryck på knappen nedan för att sluta hämta kalenderhändelser.",
"title": "Kalender"
},
"chatWithPermissions": "Chatt kräver högre rättigheter",
"desktopShareFramerate": "Bildfrekvens för skrivbordsdelning",
"desktopShareHighFpsWarning": "En högre bildhastighet för skrivbordsdelning kan påverka din bandbredd. Du måste starta om skärmdelningen för att de nya inställningarna ska träda i kraft.",
"desktopShareWarning": "Du måste starta om skärmdelningen för att de nya inställningarna ska träda i kraft.",
@@ -1129,6 +1209,7 @@
"selectMic": "Mikrofon",
"selfView": "Självvy",
"shortcuts": "Genvägar",
"showSubtitlesOnStage": "Vissa undertexter på scenen",
"speakers": "Högtalare",
"startAudioMuted": "Alla börjar tystade",
"startReactionsMuted": "Stäng av reaktionsljud för alla",
@@ -1188,6 +1269,7 @@
"neutral": "Neutral",
"sad": "Ledsen",
"search": "Sök",
"searchDescription": "Börja skriv för att filtrera bland deltagare",
"searchHint": "Sök deltagare",
"seconds": "{{count}} s",
"speakerStats": "Talarstatistik",
@@ -1224,6 +1306,7 @@
"closeChat": "Stäng chatten",
"closeMoreActions": "Stäng menyn för fler åtgärder",
"closeParticipantsPane": "Stäng deltagarfönstret",
"closedCaptions": "Undertexter",
"collapse": "Minimera",
"document": "Växla delat dokument",
"documentClose": "Stäng delat dokument",
@@ -1245,7 +1328,7 @@
"help": "Hjälp",
"hideWhiteboard": "Dölj whiteboard",
"invite": "Bjud in personer",
"kick": "Ta bort deltagare",
"kick": "Ta bort deltagare från möte",
"laugh": "Skratta",
"leaveConference": "Lämna mötet",
"like": "Tummen upp",
@@ -1302,6 +1385,20 @@
"videounmute": "Starta kameran"
},
"addPeople": "Lägg till personer i samtal",
"advancedAudioSettings": {
"aec": {
"label": "Akustisk eko hantering"
},
"agc": {
"label": "Automatisk gain kontroll"
},
"ns": {
"label": "Brusreducering"
},
"stereo": {
"label": "Stereo"
}
},
"audioOnlyOff": "Avsluta ljudläget",
"audioOnlyOn": "Starta ljudläget",
"audioRoute": "Välj ljudenhet",
@@ -1314,6 +1411,7 @@
"closeChat": "Stäng chatt",
"closeParticipantsPane": "Stäng deltagarrutan",
"closeReactionsMenu": "Stäng meny för reaktioner",
"closedCaptions": "Undertexter",
"disableNoiseSuppression": "Inaktivera brusreducering",
"disableReactionSounds": "Du kan inaktivera reaktionsljud för det här mötet",
"documentClose": "Stäng delat dokument",
@@ -1372,6 +1470,7 @@
"reactionHeart": "Skicka kärlek",
"reactionLaugh": "Skratta",
"reactionLike": "Skicka tummen upp",
"reactionLove": "Skicka kärleksreaktion",
"reactionSilence": "Skicka tyst reaktion",
"reactionSurprised": "Skicka reaktionen överaskad",
"reactions": "Reaktioner",
@@ -1404,14 +1503,18 @@
"ccButtonTooltip": "Aktivera / Inaktivera undertexter",
"expandedLabel": "Transkribering är aktiverad",
"failed": "Transkribiering misslyckades",
"labelToolTip": "Mötet transkriberas",
"labelTooltip": "Mötet transkriberas",
"labelTooltipExtra": "Transkriberingen kommer finnas tillgänglig senare.",
"openClosedCaptions": "Öppna undertexter",
"original": "Original",
"sourceLanguageDesc": "För närvarande är mötesspråket inställt på <b>{{sourceLanguage}}</b>. <br/> Du kan ändra det från ",
"sourceLanguageHere": "här",
"start": "Börja visa undertexter",
"stop": "Sluta visa undertexter",
"subtitles": "Undertexter",
"subtitlesOff": "Av",
"tr": "TR"
"tr": "TR",
"translateTo": "Översätt till"
},
"unpinParticipant": "Lossa deltagare",
"userMedia": {
@@ -1453,6 +1556,8 @@
"connectionInfo": "Anslutningsinformation",
"demote": "Gör till besökare",
"domute": "Tysta",
"domuteDesktop": "Stoppa skärmdelning",
"domuteDesktopOfOthers": "Stoppa skärmdelning för alla andra",
"domuteOthers": "Inaktivera ljud för alla andra",
"domuteVideo": "Inaktivera kamera",
"domuteVideoOfOthers": "Inaktivera kamera för alla andra",
@@ -1517,6 +1622,8 @@
"noMainParticipantsTitle": "Det är mötet har inte startat än",
"noVisitorLobby": "Du kan inte gå med medans lobby är påslagen för mötet.",
"notAllowedPromotion": "En deltagare behöver godkänna din förfrågan först.",
"requestToJoin": "Håller upp handen",
"requestToJoinDescription": "Din begäran skickades till en moderator. Var god dröj!",
"title": "Du är en besökare i mötet"
},
"waitingMessage": "Du kommer att komma in i mötet när det är live!"

View File

@@ -112,7 +112,12 @@
"disabled": "聊天已禁用",
"enter": "加入会议室",
"error": "错误:你的消息未发送。原因:{{error}}",
"everyone": "所有人",
"fieldPlaceHolder": "在这里输入你的信息",
"fileAccessibleTitle": "{{user}}上传了一个文件",
"fileAccessibleTitleMe": "我上传了一个文件",
"fileDeleted": "文件已被删除",
"guestsChatIndicator": "(访客)",
"lobbyChatMessageTo": "等候室聊天消息发送至{{recipient}}",
"message": "信息",
"messageAccessibleTitle": "{{user}}",
@@ -300,6 +305,12 @@
"alreadySharedVideoTitle": "同一时间只允许一个视频分享",
"applicationWindow": "应用程序窗口",
"authenticationRequired": "需要身份验证",
"cameraCaptureDialog": {
"description": "使用手机摄像头拍照并发送",
"ok": "打开相机",
"reject": "暂不使用",
"title": "拍照"
},
"cameraConstraintFailedError": "你的摄像头未满足某些必要条件。",
"cameraNotFoundError": "找不到摄像头",
"cameraNotSendingData": "我们无法访问你的摄像头,请检查是否有其他应用程序正在使用此设备,从设置菜单中选择另一个设备,或尝试重新加载应用程序。",
@@ -375,22 +386,34 @@
"micTimeoutError": "无法开启音频设备,发生超时!",
"micUnknownError": "由于未知原因,无法使用麦克风。",
"moderationAudioLabel": "允许参会者自己解除静音",
"moderationDesktopLabel": "允许非主持人共享屏幕",
"moderationVideoLabel": "允许参会者自己开启视频",
"muteEveryoneDialog": "参会者可以在任何时候解除自己的静音。",
"muteEveryoneDialogModerationOn": "参会者可以在任何时候请求发言。",
"muteEveryoneElseDialog": "静音后,你将无法为其解除静音,但是他们可以随时解除自己的静音。",
"muteEveryoneElseTitle": "除了{{whom}}以外的将所有人静音?",
"muteEveryoneElsesDesktopDialog": "一旦停止共享,你将无法重新开启他们的屏幕共享,但他们可以随时重新开启。",
"muteEveryoneElsesDesktopTitle": "停止除了{{whom}}以外所有人的屏幕共享?",
"muteEveryoneElsesVideoDialog": "一旦关闭,你将无法重新开启他们的摄像头,但他们随时可以重新开启。",
"muteEveryoneElsesVideoTitle": "除了{{whom}}以外,关闭所有人的摄像头?",
"muteEveryoneSelf": "你自己",
"muteEveryoneStartMuted": "现在所有人都已静音",
"muteEveryoneTitle": "静音所有人?",
"muteEveryonesDesktopDialog": "参会者可以随时共享他们的屏幕",
"muteEveryonesDesktopDialogModerationOn": "参会者可以随时请求共享他们的屏幕",
"muteEveryonesDesktopTitle": "停止所有人的屏幕共享?",
"muteEveryonesVideoDialog": "参会者可以随时开启他们的摄像头",
"muteEveryonesVideoDialogModerationOn": "参会者可以随时请求开启他们的摄像头",
"muteEveryonesVideoDialogOk": "关闭",
"muteEveryonesVideoTitle": "关闭所有人的摄像头?",
"muteParticipantBody": "你将无法为他们解除静音,但是他们可以随时解除自己的静音。",
"muteParticipantButton": "静音",
"muteParticipantsDesktopBody": "你无法重新开启他们的屏幕共享,但他们可以随时重新开启。",
"muteParticipantsDesktopBodyModerationOn": "你和他们都无法重新开启屏幕共享",
"muteParticipantsDesktopButton": "停止屏幕共享",
"muteParticipantsDesktopDialog": "你确定要停止这个参会者的屏幕共享吗?你将无法重新开启他们的屏幕共享,但他们可以随时重新开启。",
"muteParticipantsDesktopDialogModerationOn": "你确定要停止这个参会者的屏幕共享吗?你和他们都无法重新开启屏幕共享。",
"muteParticipantsDesktopTitle": "停止这个参会者的屏幕共享?",
"muteParticipantsVideoBody": "你无法重新开启摄像头,但他们随时可以重新开启。",
"muteParticipantsVideoBodyModerationOn": "你和他们都无法重新开启摄像头",
"muteParticipantsVideoButton": "关闭摄像头",
@@ -503,6 +526,7 @@
"tokenAuthFailedWithReasons": "抱歉,你无法加入此通话,原因:",
"tokenAuthUnsupported": "Token地址不支持",
"transcribing": "转录中",
"unauthenticatedAccessDisabled": "此会议需要身份验证,请先登录后继续。",
"unlockRoom": "移除会议$t(lockRoomPassword)",
"user": "用户",
"userIdentifier": "用户ID",
@@ -547,11 +571,17 @@
"downloadFailedDescription": "请稍后重试",
"downloadFailedTitle": "下载失败",
"downloadFile": "下载",
"downloadStarted": "文件下载已开始",
"dragAndDrop": "拖拽文件到此处上传",
"fileAlreadyUploaded": "文件已上传至本次会议",
"fileRemovedByOther": "你的文件{{fileName}}已被移除",
"fileTooLargeDescription": "请确保文件不超过 {{ maxFileSize }}",
"fileTooLargeTitle": "文件太大",
"fileUploadProgress": "文件上传进度",
"fileUploadedSuccessfully": "文件上传成功",
"newFileNotification": "{{participantName}}分享了{{fileName}}",
"removeFile": "移除",
"removeFileSuccess": "文件移除成功",
"uploadFailedDescription": "请稍后重试",
"uploadFailedTitle": "上传失败",
"uploadFile": "文件共享"
@@ -724,7 +754,8 @@
"notificationTitle": "等候室",
"passwordJoinButton": "加入",
"title": "等候室",
"toggleLabel": "开启等候室模式"
"toggleLabel": "开启等候室模式",
"waitForModerator": "会议尚未开始,暂无主持人入会。如需成为主持人请先登录,或耐心等待会议开始。"
},
"localRecording": {
"clientState": {
@@ -767,8 +798,10 @@
"me": "我",
"notify": {
"OldElectronAPPTitle": "安全漏洞!",
"allowAll": "允许全部",
"allowAudio": "允许开启麦克风",
"allowBoth": "允许音视频",
"allowDesktop": "允许屏幕共享",
"allowVideo": "允许开启摄像头",
"allowedUnmute": "你可以解除麦克风静音、启动摄像头或共享屏幕。",
"audioUnmuteBlockedDescription": "由于系统限制,麦克风解除静音操作被暂时阻止。",
@@ -782,6 +815,7 @@
"dataChannelClosedDescription": "桥接通道已断开,视频质量可能会被限制为最低设置",
"dataChannelClosedDescriptionWithAudio": "桥接通道已断开,音视频可能会出现卡顿或中断",
"dataChannelClosedWithAudio": "音视频质量可能受影响",
"desktopMutedRemotelyTitle": "你的屏幕共享已被{{participantDisplayName}}停止",
"disabledIframe": "嵌入仅用于演示,本次通话将在{{timeout}}分钟后自动断开",
"disabledIframeSecondaryNative": "嵌入{{domain}}仅用于演示,本次通话将在{{timeout}}分钟后自动断开",
"disabledIframeSecondaryWeb": "嵌入{{domain}}仅用于演示,本次通话将在{{timeout}}分钟后自动断开。如需在正式环境嵌入,请使用<a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi服务</a>",
@@ -839,6 +873,7 @@
"oldElectronClientDescription1": "你似乎正在使用存在已知安全漏洞的旧版Jitsi Meet客户端请确保您更新到我们的",
"oldElectronClientDescription2": "最新版本",
"oldElectronClientDescription3": "",
"openChat": "打开聊天",
"participantWantsToJoin": "想要加入会议",
"participantsWantToJoin": "想要加入会议",
"passwordRemovedRemotely": "其他参会者移除了$t(lockRoomPasswordUppercase)",
@@ -862,6 +897,7 @@
"suggestRecordingDescription": "是否需要录制本次会议?",
"suggestRecordingTitle": "录制会议",
"unmute": "解除静音",
"unmuteScreen": "开始屏幕共享",
"unmuteVideo": "开启摄像头",
"videoMutedRemotelyDescription": "你可随时重新开启视频",
"videoMutedRemotelyTitle": "{{participantDisplayName}}已关闭你的视频",
@@ -881,11 +917,14 @@
"admit": "同意加入",
"admitAll": "全部同意加入",
"allow": "允许参会者:",
"allowDesktop": "允许屏幕共享",
"allowVideo": "允许开启摄像头",
"askDesktop": "请求共享屏幕",
"askUnmute": "请求取消静音",
"audioModeration": "自行解除静音",
"blockEveryoneMicCamera": "禁用所有人的麦克风和摄像头",
"breakoutRooms": "分组讨论室",
"desktopModeration": "开始屏幕共享",
"goLive": "开始直播",
"invite": "邀请其他人",
"lowerAllHands": "取消全部举手",
@@ -897,6 +936,8 @@
"muteAll": "全体静音",
"muteEveryoneElse": "静音其他人",
"reject": "拒绝",
"stopDesktop": "停止屏幕共享",
"stopEveryonesDesktop": "停止所有人的屏幕共享",
"stopEveryonesVideo": "关闭所有人摄像头",
"stopVideo": "关闭摄像头",
"unblockEveryoneMicCamera": "允许所有人开启麦克风和摄像头",
@@ -906,9 +947,11 @@
"headings": {
"lobby": "等候室(({{count}}人)",
"participantsList": "会议参会者({{count}}人)",
"viewerRequests": "观众请求({{count}}人)",
"visitorInQueue": "(排队中:{{count}}人)",
"visitorRequests": "(请求加入:{{count}}人)",
"visitors": "观众(({{count}}人)",
"visitorsList": "观众({{count}}人)",
"waitingLobby": "在等候室等待({{count}}人)"
},
"search": "搜索参会者",
@@ -929,6 +972,9 @@
"by": "由{{ name }}发起",
"closeButton": "结束投票",
"create": {
"accessibilityLabel": {
"send": "发送投票"
},
"addOption": "添加选项",
"answerPlaceholder": "选项{{index}}",
"cancel": "取消",
@@ -1345,6 +1391,20 @@
"videounmute": "打开摄像头"
},
"addPeople": "添加成员到通话中",
"advancedAudioSettings": {
"aec": {
"label": "回声消除"
},
"agc": {
"label": "自动增益控制"
},
"ns": {
"label": "降噪"
},
"stereo": {
"label": "立体声"
}
},
"audioOnlyOff": "关闭省流模式",
"audioOnlyOn": "开启省流模式",
"audioRoute": "选择音频设备",
@@ -1416,6 +1476,7 @@
"reactionHeart": "发送爱心",
"reactionLaugh": "发送大笑",
"reactionLike": "发送点赞",
"reactionLove": "发送爱心",
"reactionSilence": "发送沉默",
"reactionSurprised": "发送惊讶",
"reactions": "互动表情",
@@ -1501,6 +1562,8 @@
"connectionInfo": "连接信息",
"demote": "设为观众",
"domute": "静音",
"domuteDesktop": "停止屏幕共享",
"domuteDesktopOfOthers": "停止屏幕共享给其他人",
"domuteOthers": "静音其他人",
"domuteVideo": "关闭摄像头",
"domuteVideoOfOthers": "关闭其他人摄像头",
@@ -1565,6 +1628,8 @@
"noMainParticipantsTitle": "会议尚未开始",
"noVisitorLobby": "当前会议已开启等候室,暂无法加入",
"notAllowedPromotion": "需由会议成员同意才能参与讨论",
"requestToJoin": "举手请求",
"requestToJoinDescription": "你的请求已发送给主持人,请稍候!",
"title": "你当前为会议观众"
},
"waitingMessage": "会议开始后将自动加入"

View File

@@ -112,7 +112,12 @@
"disabled": "聊天訊息已停用",
"enter": "加入聊天室",
"error": "錯誤:您的訊息未被傳送。原因:{{error}}",
"everyone": "所有人",
"fieldPlaceHolder": "在此輸入您的訊息",
"fileAccessibleTitle": "{{user}}上傳了一個檔案",
"fileAccessibleTitleMe": "我上傳了一個檔案",
"fileDeleted": "檔案已被刪除",
"guestsChatIndicator": "(訪客)",
"lobbyChatMessageTo": "大廳聊天訊息傳送至 {{recipient}}",
"message": "訊息",
"messageAccessibleTitle": "{{user}}",
@@ -300,6 +305,12 @@
"alreadySharedVideoTitle": "同一時間只允許一位影像分享",
"applicationWindow": "應用程式視窗",
"authenticationRequired": "需要驗證",
"cameraCaptureDialog": {
"description": "使用手機攝影機拍照並傳送",
"ok": "開啟相機",
"reject": "暫不使用",
"title": "拍照"
},
"cameraConstraintFailedError": "您的網路攝影機不符合要求。",
"cameraNotFoundError": "找不到網路攝影機。",
"cameraNotSendingData": "我們無法存取您的網路攝影機,請檢查是否有其他應用程式正在使用這個裝置,並從裝置選單裡選擇其他設備或者重新載入。",
@@ -375,22 +386,34 @@
"micTimeoutError": "無法啟動音訊裝置,連線逾時!",
"micUnknownError": "不明原因造成麥克風無法使用。",
"moderationAudioLabel": "允許與會者自我解除靜音",
"moderationDesktopLabel": "允許非主持人共享螢幕",
"moderationVideoLabel": "允許與會者開啟視訊",
"muteEveryoneDialog": "與會者可以隨時解除自己的靜音狀態。",
"muteEveryoneDialogModerationOn": "與會者可以隨時請求發言。",
"muteEveryoneElseDialog": "靜音後,您就不能再解除對方的靜音,但對方可以隨時解除自己的靜音狀態。",
"muteEveryoneElseTitle": "是否要讓除了 {{whom}} 以外的人靜音?",
"muteEveryoneElsesDesktopDialog": "一旦停止共享,您將無法重新開啟他們的螢幕共享,但他們可以隨時重新開啟。",
"muteEveryoneElsesDesktopTitle": "停止除了{{whom}}以外所有人的螢幕共享?",
"muteEveryoneElsesVideoDialog": "一旦停用,您就不能再重新開啟對方的網路攝影機,但對方隨時能重新開啟自己的網路攝影機。",
"muteEveryoneElsesVideoTitle": "是否要關閉除了 {{whom}} 以外的人的網路攝影機?",
"muteEveryoneSelf": "您自己",
"muteEveryoneStartMuted": "現在所有人皆已靜音",
"muteEveryoneTitle": "要將所有人靜音嗎?",
"muteEveryonesDesktopDialog": "與會者可以隨時共享他們的螢幕",
"muteEveryonesDesktopDialogModerationOn": "與會者可以隨時請求共享他們的螢幕",
"muteEveryonesDesktopTitle": "停止所有人的螢幕共享?",
"muteEveryonesVideoDialog": "與會者隨時可以重新開啟自己的網路攝影機。",
"muteEveryonesVideoDialogModerationOn": "與會者可以隨時傳送開啟視訊請求。",
"muteEveryonesVideoDialogOk": "停用",
"muteEveryonesVideoTitle": "要關閉所有人的網路攝影機嗎?",
"muteParticipantBody": "您無法對他們解除靜音,但是他們自己隨時可以解除靜音。",
"muteParticipantButton": "靜音",
"muteParticipantsDesktopBody": "您無法重新開啟他們的螢幕共享,但他們可以隨時重新開啟。",
"muteParticipantsDesktopBodyModerationOn": "您和他們都無法重新開啟螢幕共享",
"muteParticipantsDesktopButton": "停止螢幕分享",
"muteParticipantsDesktopDialog": "您確定要停止這位與會者的螢幕共享嗎?您將無法重新開啟他們的螢幕共享,但他們可以隨時重新開啟。",
"muteParticipantsDesktopDialogModerationOn": "您確定要停止這位與會者的螢幕共享嗎?您和他們都無法重新開啟螢幕共享。",
"muteParticipantsDesktopTitle": "停止這位與會者的螢幕共享?",
"muteParticipantsVideoBody": "您無法重新開啟,只有對方能自己重新開啟。",
"muteParticipantsVideoBodyModerationOn": "您和他都無法再將視訊重新開啟。",
"muteParticipantsVideoButton": "停用網路攝影機",
@@ -503,6 +526,7 @@
"tokenAuthFailedWithReasons": "抱歉,您無法參加這個通話,可能原因:{{reason}}",
"tokenAuthUnsupported": "不支援權杖網址。",
"transcribing": "轉錄中",
"unauthenticatedAccessDisabled": "此會議需要身份驗證,請先登入後繼續。",
"unlockRoom": "移除會議 $t(lockRoomPassword)",
"user": "使用者",
"userIdentifier": "使用者 ID",
@@ -547,11 +571,17 @@
"downloadFailedDescription": "請重試",
"downloadFailedTitle": "下載失敗",
"downloadFile": "下載",
"downloadStarted": "檔案下載已開始",
"dragAndDrop": "將檔案拖曳至此或畫面任一處上傳",
"fileAlreadyUploaded": "檔案已上傳至此會議",
"fileRemovedByOther": "您的檔案「{{fileName}}」已被移除",
"fileTooLargeDescription": "請確認檔案未超過 {{ maxFileSize }}",
"fileTooLargeTitle": "檔案過大",
"fileUploadProgress": "檔案上傳進度",
"fileUploadedSuccessfully": "檔案上傳成功",
"newFileNotification": "{{participantName}}分享了「{{fileName}}」",
"removeFile": "移除",
"removeFileSuccess": "檔案移除成功",
"uploadFailedDescription": "請重試",
"uploadFailedTitle": "上傳失敗",
"uploadFile": "分享檔案"
@@ -724,7 +754,8 @@
"notificationTitle": "大廳",
"passwordJoinButton": "加入",
"title": "大廳",
"toggleLabel": "啟用大廳模式"
"toggleLabel": "啟用大廳模式",
"waitForModerator": "會議尚未開始,暫無主持人入會。如需成為主持人請先登入,或耐心等待會議開始。"
},
"localRecording": {
"clientState": {
@@ -767,8 +798,10 @@
"me": "我",
"notify": {
"OldElectronAPPTitle": "安全漏洞!",
"allowAll": "允許全部",
"allowAudio": "允許音訊",
"allowBoth": "允許音訊與視訊",
"allowDesktop": "允許螢幕分享",
"allowVideo": "允許視訊",
"allowedUnmute": "您可以將麥克風解除靜音、開啟視訊,或是分享您的螢幕。",
"audioUnmuteBlockedDescription": "麥克風解除靜音操作由於系統限制而被暫時封鎖。",
@@ -782,6 +815,7 @@
"dataChannelClosedDescription": "橋接通道已斷開,視訊品質降至最低設定。",
"dataChannelClosedDescriptionWithAudio": "橋接通道已斷開,音訊和視訊可能會受到影響。",
"dataChannelClosedWithAudio": "音訊和視訊品質可能會降低。",
"desktopMutedRemotelyTitle": "您的螢幕分享已被{{participantDisplayName}}停止",
"disabledIframe": "嵌入僅供示範使用,此通話將於 {{timeout}} 分鐘後中斷連線。",
"disabledIframeSecondaryNative": "嵌入 {{domain}} 僅供示範,此通話將於 {{timeout}} 分鐘後中斷。",
"disabledIframeSecondaryWeb": "嵌入 {{domain}} 僅供示範,此通話將於 {{timeout}} 分鐘後中斷,請使用 <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi 服務</a> 來進行正式嵌入!",
@@ -839,6 +873,7 @@
"oldElectronClientDescription1": "您似乎正在使用存在已知安全漏洞的過時 Jitsi Meet 用戶端,請盡快更新至我們的",
"oldElectronClientDescription2": "最新版本",
"oldElectronClientDescription3": "",
"openChat": "開啟聊天",
"participantWantsToJoin": "希望加入會議",
"participantsWantToJoin": "希望加入會議",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) 已被其他與會者移除",
@@ -862,6 +897,7 @@
"suggestRecordingDescription": "是否要開始錄製這場會議?",
"suggestRecordingTitle": "錄製此會議",
"unmute": "取消靜音",
"unmuteScreen": "開始螢幕分享",
"unmuteVideo": "啟用視訊",
"videoMutedRemotelyDescription": "您隨時可以再次啟用。",
"videoMutedRemotelyTitle": "您的視訊已被 {{participantDisplayName}} 停用",
@@ -881,11 +917,14 @@
"admit": "準許",
"admitAll": "準許所有人",
"allow": "允許與會者能夠:",
"allowDesktop": "允許螢幕分享",
"allowVideo": "允許視訊",
"askDesktop": "請求共享螢幕",
"askUnmute": "要求解除靜音",
"audioModeration": "自我解除靜音",
"blockEveryoneMicCamera": "停用所有人的麥克風和網路攝影機",
"breakoutRooms": "分組討論室",
"desktopModeration": "開始螢幕分享",
"goLive": "開始直播",
"invite": "邀請他人",
"lowerAllHands": "全部取消舉手",
@@ -897,6 +936,8 @@
"muteAll": "靜音所有人",
"muteEveryoneElse": "靜音其他人",
"reject": "拒絕",
"stopDesktop": "停止螢幕分享",
"stopEveryonesDesktop": "停止所有人的螢幕分享",
"stopEveryonesVideo": "停用所有人的視訊",
"stopVideo": "停用視訊",
"unblockEveryoneMicCamera": "解除封鎖所有人的麥克風及網路攝影機",
@@ -906,9 +947,11 @@
"headings": {
"lobby": "大廳({{count}} 人)",
"participantsList": "會議與會者({{count}} 人)",
"viewerRequests": "觀眾請求({{count}}人)",
"visitorInQueue": "{{count}} 人等候中)",
"visitorRequests": "{{count}} 人申請",
"visitors": "訪客({{count}} 人)",
"visitorsList": "觀眾({{count}}人)",
"waitingLobby": "於大廳等候({{count}} 人)"
},
"search": "搜尋與會者",
@@ -929,6 +972,9 @@
"by": "由 {{ name }}",
"closeButton": "結束投票",
"create": {
"accessibilityLabel": {
"send": "傳送投票"
},
"addOption": "新增選項",
"answerPlaceholder": "選項 {{index}}",
"cancel": "取消",
@@ -1345,6 +1391,20 @@
"videounmute": "啟用網路攝影機"
},
"addPeople": "新增人員到您的通話中",
"advancedAudioSettings": {
"aec": {
"label": "回聲消除"
},
"agc": {
"label": "自動增益控制"
},
"ns": {
"label": "降噪"
},
"stereo": {
"label": "立體聲"
}
},
"audioOnlyOff": "停用低頻寬模式",
"audioOnlyOn": "啟用低頻寬模式",
"audioRoute": "選擇音訊裝置",
@@ -1416,6 +1476,7 @@
"reactionHeart": "傳送愛心反應",
"reactionLaugh": "傳送大笑反應",
"reactionLike": "傳送比讚反應",
"reactionLove": "傳送愛心",
"reactionSilence": "傳送沉默反應",
"reactionSurprised": "傳送驚訝反應",
"reactions": "反應",
@@ -1501,6 +1562,8 @@
"connectionInfo": "連線資訊",
"demote": "轉為訪客",
"domute": "靜音",
"domuteDesktop": "停止螢幕分享",
"domuteDesktopOfOthers": "停止螢幕分享給其他人",
"domuteOthers": "靜音其他人",
"domuteVideo": "停用網路攝影機",
"domuteVideoOfOthers": "停用其他人的網路攝影機",
@@ -1565,6 +1628,8 @@
"noMainParticipantsTitle": "會議尚未開始",
"noVisitorLobby": "此會議啟用大廳,暫時無法加入",
"notAllowedPromotion": "需由與會者同意您的申請",
"requestToJoin": "舉手請求",
"requestToJoinDescription": "您的請求已傳送給主持人,請稍候!",
"title": "您是會議中的訪客"
},
"waitingMessage": "會議開始後您將自動加入!"

View File

@@ -114,6 +114,9 @@
"error": "Error: your message was not sent. Reason: {{error}}",
"everyone": "Everyone",
"fieldPlaceHolder": "Aa",
"fileAccessibleTitle": "{{user}} uploaded a file",
"fileAccessibleTitleMe": "me uploaded a file",
"fileDeleted": "A file was deleted",
"guestsChatIndicator": "(guest)",
"lobbyChatMessageTo": "Lobby chat message to {{recipient}}",
"message": "Message",
@@ -123,8 +126,16 @@
"messagebox": "Type a message",
"newMessages": "New messages",
"nickname": {
"featureChat": "chat",
"featureClosedCaptions": "closed captions",
"featureFileSharing": "file sharing",
"featurePolls": "polls",
"popover": "Choose a nickname",
"title": "Enter a nickname to use chat",
"titleWith1Features": "Enter a nickname to use {{feature1}}",
"titleWith2Features": "Enter a nickname to use {{feature1}} and {{feature2}}",
"titleWith3Features": "Enter a nickname to use {{feature1}}, {{feature2}} and {{feature3}}",
"titleWith4Features": "Enter a nickname to use {{feature1}}, {{feature2}}, {{feature3}} and {{feature4}}",
"titleWithCC": "Enter a nickname to use chat and closed captions",
"titleWithPolls": "Enter a nickname to use chat and polls",
"titleWithPollsAndCC": "Enter a nickname to use chat, polls and closed captions",
@@ -570,10 +581,12 @@
"downloadStarted": "File download started",
"dragAndDrop": "Drag and drop files here or anywhere on screen",
"fileAlreadyUploaded": "File has already been uploaded to this meeting.",
"fileRemovedByOther": "Your file '{{ fileName }}' was removed",
"fileTooLargeDescription": "Please make sure the file does not exceed {{ maxFileSize }}.",
"fileTooLargeTitle": "The selected file is too large",
"fileUploadProgress": "File upload progress",
"fileUploadedSuccessfully": "File uploaded successfully",
"newFileNotification": "{{ participantName }} shared '{{ fileName }}'",
"removeFile": "Remove",
"removeFileSuccess": "File removed successfully",
"uploadFailedDescription": "Please try again.",
@@ -1424,6 +1437,7 @@
"exitFullScreen": "Exit full screen",
"exitTileView": "Exit tile view",
"feedback": "Leave feedback",
"fileSharing": "File sharing",
"giphy": "Toggle GIPHY menu",
"hangup": "Leave the meeting",
"help": "Help",
@@ -1459,6 +1473,7 @@
"openReactionsMenu": "Open reactions menu",
"participants": "Participants",
"pip": "Enter Picture-in-Picture mode",
"polls": "Polls",
"privateMessage": "Send private message",
"profile": "Edit your profile",
"raiseHand": "Raise your hand",

View File

@@ -340,6 +340,7 @@ function initCommands() {
APP.store.dispatch(setAssumedBandwidthBps(value));
},
'set-blurred-background': blurType => {
const tracks = APP.store.getState()['features/base/tracks'];
const videoTrack = getLocalVideoTrack(tracks)?.jitsiTrack;

146
package-lock.json generated
View File

@@ -19,10 +19,10 @@
"@giphy/react-components": "6.9.4",
"@giphy/react-native-sdk": "4.1.0",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.19/jitsi-excalidraw-0.0.19.tgz",
"@jitsi/js-utils": "2.2.1",
"@jitsi/js-utils": "2.6.7",
"@jitsi/logger": "2.1.1",
"@jitsi/rnnoise-wasm": "0.2.1",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
"@matrix-org/olm": "3.2.15",
"@microsoft/microsoft-graph-client": "3.0.1",
"@mui/material": "5.12.1",
"@react-native-async-storage/async-storage": "1.23.1",
@@ -66,7 +66,7 @@
"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/v2099.0.0+89536686/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2115.0.0+cc2f34c2/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
@@ -87,7 +87,6 @@
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
"react-native-gesture-handler": "2.24.0",
"react-native-get-random-values": "1.11.0",
"react-native-immersive-mode": "https://github.com/jitsi/react-native-immersive-mode.git#38cc9001db24618bc0c61800f81e889bcfb6ff2c",
"react-native-orientation-locker": "https://github.com/jitsi/react-native-orientation-locker.git#fe095651d819cf134624f786b61fc8667862178a",
"react-native-pager-view": "6.8.1",
"react-native-paper": "5.10.3",
@@ -101,8 +100,7 @@
"react-native-tab-view": "3.5.2",
"react-native-url-polyfill": "2.0.0",
"react-native-video": "6.13.0",
"react-native-watch-connectivity": "1.1.0",
"react-native-webrtc": "124.0.4",
"react-native-webrtc": "124.0.7",
"react-native-webview": "13.13.5",
"react-native-worklets-core": "https://github.com/jitsi/react-native-worklets-core.git#8c5dfab2a5907305da8971696a781b60f0f9cb18",
"react-native-youtube-iframe": "2.3.0",
@@ -4546,9 +4544,10 @@
}
},
"node_modules/@jitsi/js-utils": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.2.1.tgz",
"integrity": "sha512-4Ia4hWO7aTMGbYftzeBr+IHIu5YxiWwTlhsSK34z6925oNAUNI863WgYYGTcXkW/1yuM6LBZrnuZBySDqosISA==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.6.7.tgz",
"integrity": "sha512-r16J3CjYt325CFIpfHznND4O3b9BE7CZ7cu+Xx0uk1C+ZY6/bDPZFM/0d4t0VH+1/rmfG4I7i18qxXct3xmPrw==",
"license": "Apache-2.0",
"dependencies": {
"@hapi/bourne": "^3.0.0",
"js-md5": "0.7.3",
@@ -4691,9 +4690,9 @@
"dev": true
},
"node_modules/@matrix-org/olm": {
"version": "3.2.3",
"resolved": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
"integrity": "sha512-OhC9wwZ/ox9vputA1MR2A7QlYlvfXCV+tdbADOR7Jn7o9qoXh3HWf+AbSpXTK3daF0GIHA69Ws8XOnWqu5n53A==",
"version": "3.2.15",
"resolved": "https://registry.npmjs.org/@matrix-org/olm/-/olm-3.2.15.tgz",
"integrity": "sha512-S7lOrndAK9/8qOtaTq/WhttJC/o4GAzdfK0MUPpo8ApzsJEC0QjtwrkC3KBXdFP1cD1MXi/mlKR7aaoVMKgs6Q==",
"license": "Apache-2.0"
},
"node_modules/@microsoft/microsoft-graph-client": {
@@ -18260,11 +18259,11 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2099.0.0+89536686/lib-jitsi-meet.tgz",
"integrity": "sha512-0FYPvOFSdg9L4ocH8bJw8doUE0rM55JnqRijXMOLS3ZOphbpeBg8tBTH33jwb+bqgo5jjmjTrvJkmkvGNF5/Jg==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2115.0.0+cc2f34c2/lib-jitsi-meet.tgz",
"integrity": "sha512-/fpQChyB3jTrQbAhm1YVHmU8HcU7hZyfK+dq8NblKKdnnalzfYUelG1c3leSG3SVb6s3xPyxgmulIgTBX5y6eA==",
"license": "Apache-2.0",
"dependencies": {
"@jitsi/js-utils": "2.4.6",
"@jitsi/js-utils": "^2.6.7",
"@jitsi/logger": "2.1.1",
"@jitsi/precall-test": "1.0.6",
"@jitsi/rtcstats": "9.7.0",
@@ -18280,17 +18279,6 @@
"webrtc-adapter": "8.1.1"
}
},
"node_modules/lib-jitsi-meet/node_modules/@jitsi/js-utils": {
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.4.6.tgz",
"integrity": "sha512-z/VbM9c0V35T8Zkhxq2gdWbMWmM/3w4BD68xJVmQNrq/NQHxH0fDkRoT/MUds9Mp6dK3AV/h15tCKxVA/0w8Kg==",
"license": "Apache-2.0",
"dependencies": {
"@hapi/bourne": "^3.0.0",
"js-md5": "0.7.3",
"ua-parser-js": "1.0.35"
}
},
"node_modules/lib-jitsi-meet/node_modules/@jitsi/logger": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@jitsi/logger/-/logger-2.0.2.tgz",
@@ -18313,12 +18301,6 @@
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
"license": "MIT"
},
"node_modules/lib-jitsi-meet/node_modules/js-md5": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ==",
"license": "MIT"
},
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
@@ -18535,11 +18517,6 @@
"integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==",
"dev": true
},
"node_modules/lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
},
"node_modules/lodash.throttle": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
@@ -20109,9 +20086,10 @@
}
},
"node_modules/node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz",
"integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==",
"license": "(BSD-3-Clause OR GPL-2.0)",
"engines": {
"node": ">= 6.13.0"
}
@@ -21870,14 +21848,6 @@
"react-native": ">=0.56"
}
},
"node_modules/react-native-immersive-mode": {
"version": "2.0.2",
"resolved": "git+ssh://git@github.com/jitsi/react-native-immersive-mode.git#38cc9001db24618bc0c61800f81e889bcfb6ff2c",
"license": "MIT",
"peerDependencies": {
"react-native": ">=0.60.5"
}
},
"node_modules/react-native-is-edge-to-edge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz",
@@ -22485,22 +22455,11 @@
"react-native": "*"
}
},
"node_modules/react-native-watch-connectivity": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/react-native-watch-connectivity/-/react-native-watch-connectivity-1.1.0.tgz",
"integrity": "sha512-s+zlKOVENRXgkVQvJt5f73CyqpC6ZhKlRsXLybtaFIsR1KR3ARzExm0yTm3DAb5K9AqtCpYX+1SOd4d0Af2ZNQ==",
"dependencies": {
"lodash.sortby": "^4.7.0"
},
"peerDependencies": {
"react": ">=15.1",
"react-native": ">=0.40"
}
},
"node_modules/react-native-webrtc": {
"version": "124.0.4",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-124.0.4.tgz",
"integrity": "sha512-ZbhSz1f+kc1v5VE0B84+v6ujIWTHa2fIuocrYzGUIFab7E5izmct7PNHb9dzzs0xhBGqh4c2rUa49jbL+P/e2w==",
"version": "124.0.7",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-124.0.7.tgz",
"integrity": "sha512-gnXPdbUS8IkKHq9WNaWptW/yy5s6nMyI6cNn90LXdobPVCgYSk6NA2uUGdT4c4J14BRgaFA95F+cR28tUPkMVA==",
"license": "MIT",
"dependencies": {
"base64-js": "1.5.1",
"debug": "4.3.4",
@@ -30042,9 +30001,9 @@
"integrity": "sha512-8fAv3cVEuoukSyu5RBZg0YWcrGEMjSKsdeQJuMmeOL2vVXIBWo0TpaHqys4HNCGRmZKzkhYccqxtmNSTxlBgkQ=="
},
"@jitsi/js-utils": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.2.1.tgz",
"integrity": "sha512-4Ia4hWO7aTMGbYftzeBr+IHIu5YxiWwTlhsSK34z6925oNAUNI863WgYYGTcXkW/1yuM6LBZrnuZBySDqosISA==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.6.7.tgz",
"integrity": "sha512-r16J3CjYt325CFIpfHznND4O3b9BE7CZ7cu+Xx0uk1C+ZY6/bDPZFM/0d4t0VH+1/rmfG4I7i18qxXct3xmPrw==",
"requires": {
"@hapi/bourne": "^3.0.0",
"js-md5": "0.7.3",
@@ -30147,8 +30106,9 @@
"dev": true
},
"@matrix-org/olm": {
"version": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
"integrity": "sha512-OhC9wwZ/ox9vputA1MR2A7QlYlvfXCV+tdbADOR7Jn7o9qoXh3HWf+AbSpXTK3daF0GIHA69Ws8XOnWqu5n53A=="
"version": "3.2.15",
"resolved": "https://registry.npmjs.org/@matrix-org/olm/-/olm-3.2.15.tgz",
"integrity": "sha512-S7lOrndAK9/8qOtaTq/WhttJC/o4GAzdfK0MUPpo8ApzsJEC0QjtwrkC3KBXdFP1cD1MXi/mlKR7aaoVMKgs6Q=="
},
"@microsoft/microsoft-graph-client": {
"version": "3.0.1",
@@ -39715,10 +39675,10 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2099.0.0+89536686/lib-jitsi-meet.tgz",
"integrity": "sha512-0FYPvOFSdg9L4ocH8bJw8doUE0rM55JnqRijXMOLS3ZOphbpeBg8tBTH33jwb+bqgo5jjmjTrvJkmkvGNF5/Jg==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2115.0.0+cc2f34c2/lib-jitsi-meet.tgz",
"integrity": "sha512-/fpQChyB3jTrQbAhm1YVHmU8HcU7hZyfK+dq8NblKKdnnalzfYUelG1c3leSG3SVb6s3xPyxgmulIgTBX5y6eA==",
"requires": {
"@jitsi/js-utils": "2.4.6",
"@jitsi/js-utils": "^2.6.7",
"@jitsi/logger": "2.1.1",
"@jitsi/precall-test": "1.0.6",
"@jitsi/rtcstats": "9.7.0",
@@ -39734,16 +39694,6 @@
"webrtc-adapter": "8.1.1"
},
"dependencies": {
"@jitsi/js-utils": {
"version": "2.4.6",
"resolved": "https://registry.npmjs.org/@jitsi/js-utils/-/js-utils-2.4.6.tgz",
"integrity": "sha512-z/VbM9c0V35T8Zkhxq2gdWbMWmM/3w4BD68xJVmQNrq/NQHxH0fDkRoT/MUds9Mp6dK3AV/h15tCKxVA/0w8Kg==",
"requires": {
"@hapi/bourne": "^3.0.0",
"js-md5": "0.7.3",
"ua-parser-js": "1.0.35"
}
},
"@jitsi/logger": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@jitsi/logger/-/logger-2.0.2.tgz",
@@ -39764,11 +39714,6 @@
"version": "10.4.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
"integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw=="
},
"js-md5": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
"integrity": "sha512-ZC41vPSTLKGwIRjqDh8DfXoCrdQIyBgspJVPXHBGu4nZlAEvG3nf+jO9avM9RmLiGakg7vz974ms99nEV0tmTQ=="
}
}
},
@@ -39958,11 +39903,6 @@
"integrity": "sha512-AZV+GsS/6ckvPOVQPXSiFFacKvKB4kOQu6ynt9wz0F3LO4R9Ij4K1ddYsIytDpSgLz88JHd9P+oaLeej5/Sl7Q==",
"dev": true
},
"lodash.sortby": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
},
"lodash.throttle": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
@@ -41081,9 +41021,9 @@
}
},
"node-forge": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz",
"integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA=="
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz",
"integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw=="
},
"node-int64": {
"version": "0.4.0",
@@ -42365,10 +42305,6 @@
"fast-base64-decode": "^1.0.0"
}
},
"react-native-immersive-mode": {
"version": "git+ssh://git@github.com/jitsi/react-native-immersive-mode.git#38cc9001db24618bc0c61800f81e889bcfb6ff2c",
"from": "react-native-immersive-mode@https://github.com/jitsi/react-native-immersive-mode.git#38cc9001db24618bc0c61800f81e889bcfb6ff2c"
},
"react-native-is-edge-to-edge": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/react-native-is-edge-to-edge/-/react-native-is-edge-to-edge-1.2.1.tgz",
@@ -42719,18 +42655,10 @@
"resolved": "https://registry.npmjs.org/react-native-video/-/react-native-video-6.13.0.tgz",
"integrity": "sha512-eY6jgLcmYKAAlAZhsZbp8wfCVrGu7jmUYTTspn8udN8j4jqr4Fq90ROOM/QegGkwNs4waclL0IkzGuq61kT4DQ=="
},
"react-native-watch-connectivity": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/react-native-watch-connectivity/-/react-native-watch-connectivity-1.1.0.tgz",
"integrity": "sha512-s+zlKOVENRXgkVQvJt5f73CyqpC6ZhKlRsXLybtaFIsR1KR3ARzExm0yTm3DAb5K9AqtCpYX+1SOd4d0Af2ZNQ==",
"requires": {
"lodash.sortby": "^4.7.0"
}
},
"react-native-webrtc": {
"version": "124.0.4",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-124.0.4.tgz",
"integrity": "sha512-ZbhSz1f+kc1v5VE0B84+v6ujIWTHa2fIuocrYzGUIFab7E5izmct7PNHb9dzzs0xhBGqh4c2rUa49jbL+P/e2w==",
"version": "124.0.7",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-124.0.7.tgz",
"integrity": "sha512-gnXPdbUS8IkKHq9WNaWptW/yy5s6nMyI6cNn90LXdobPVCgYSk6NA2uUGdT4c4J14BRgaFA95F+cR28tUPkMVA==",
"requires": {
"base64-js": "1.5.1",
"debug": "4.3.4",

View File

@@ -25,10 +25,10 @@
"@giphy/react-components": "6.9.4",
"@giphy/react-native-sdk": "4.1.0",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.19/jitsi-excalidraw-0.0.19.tgz",
"@jitsi/js-utils": "2.2.1",
"@jitsi/js-utils": "2.6.7",
"@jitsi/logger": "2.1.1",
"@jitsi/rnnoise-wasm": "0.2.1",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
"@matrix-org/olm": "3.2.15",
"@microsoft/microsoft-graph-client": "3.0.1",
"@mui/material": "5.12.1",
"@react-native-async-storage/async-storage": "1.23.1",
@@ -72,7 +72,7 @@
"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/v2099.0.0+89536686/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2115.0.0+cc2f34c2/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
@@ -93,7 +93,6 @@
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
"react-native-gesture-handler": "2.24.0",
"react-native-get-random-values": "1.11.0",
"react-native-immersive-mode": "https://github.com/jitsi/react-native-immersive-mode.git#38cc9001db24618bc0c61800f81e889bcfb6ff2c",
"react-native-orientation-locker": "https://github.com/jitsi/react-native-orientation-locker.git#fe095651d819cf134624f786b61fc8667862178a",
"react-native-pager-view": "6.8.1",
"react-native-paper": "5.10.3",
@@ -107,8 +106,7 @@
"react-native-tab-view": "3.5.2",
"react-native-url-polyfill": "2.0.0",
"react-native-video": "6.13.0",
"react-native-watch-connectivity": "1.1.0",
"react-native-webrtc": "124.0.4",
"react-native-webrtc": "124.0.7",
"react-native-webview": "13.13.5",
"react-native-worklets-core": "https://github.com/jitsi/react-native-worklets-core.git#8c5dfab2a5907305da8971696a781b60f0f9cb18",
"react-native-youtube-iframe": "2.3.0",

View File

@@ -29,7 +29,7 @@ Pod::Spec.new do |s|
SOURCE_PATH="${PODS_TARGET_SRCROOT}/sounds/"
TARGET_PATH=$(dirname "${CONFIGURATION_BUILD_DIR}")
PROJECT_NAME=$(basename $(dirname $(dirname "${PROJECT_DIR}"))).app
cp -R "${SOURCE_PATH}" "${TARGET_PATH}/${PROJECT_NAME}"
ditto "${SOURCE_PATH}" "${TARGET_PATH}/${PROJECT_NAME}/sounds"
',
}
end

View File

@@ -73,7 +73,6 @@
"react-native-device-info": "0.0.0",
"react-native-get-random-values": "0.0.0",
"react-native-gesture-handler": "0.0.0",
"react-native-immersive-mode": "0.0.0",
"react-native-pager-view": "0.0.0",
"react-native-performance": "0.0.0",
"react-native-orientation-locker": "0.0.0",

View File

@@ -20,11 +20,6 @@ module.exports = {
platforms: {
ios: null
}
},
'react-native-watch-connectivity': {
platforms: {
ios: null
}
}
}
};

View File

@@ -600,31 +600,6 @@ export function createRemoteVideoMenuButtonEvent(buttonName: string, attributes
};
}
/**
* The rtcstats websocket onclose event. We send this to amplitude in order
* to detect trace ws prematurely closing.
*
* @param {Object} closeEvent - The event with which the websocket closed.
* @returns {Object} The event in a format suitable for sending via
* sendAnalytics.
*/
export function createRTCStatsTraceCloseEvent(closeEvent: { code: string; reason: string; }) {
const event: {
action: string;
code?: string;
reason?: string;
source: string;
} = {
action: 'trace.onclose',
source: 'rtcstats'
};
event.code = closeEvent.code;
event.reason = closeEvent.reason;
return event;
}
/**
* Creates an event indicating that an action related to screen sharing
* occurred (e.g. It was started or stopped).

View File

@@ -1,4 +1,4 @@
import amplitude from '@amplitude/analytics-react-native';
import * as amplitude from '@amplitude/analytics-react-native';
export default amplitude;

View File

@@ -4,13 +4,11 @@ import '../mobile/audio-mode/middleware';
import '../mobile/background/middleware';
import '../mobile/call-integration/middleware';
import '../mobile/external-api/middleware';
import '../mobile/full-screen/middleware';
import '../mobile/navigation/middleware';
import '../mobile/permissions/middleware';
import '../mobile/proximity/middleware';
import '../mobile/wake-lock/middleware';
import '../mobile/react-native-sdk/middleware';
import '../mobile/watchos/middleware';
import '../share-room/middleware';
import '../shared-video/middleware';
import '../toolbox/middleware.native';

View File

@@ -2,8 +2,6 @@ import '../mobile/audio-mode/reducer';
import '../mobile/background/reducer';
import '../mobile/call-integration/reducer';
import '../mobile/external-api/reducer';
import '../mobile/full-screen/reducer';
import '../mobile/watchos/reducer';
import '../share-room/reducer';
import './reducer.native';

View File

@@ -52,8 +52,6 @@ import { IMobileAudioModeState } from '../mobile/audio-mode/reducer';
import { IMobileBackgroundState } from '../mobile/background/reducer';
import { ICallIntegrationState } from '../mobile/call-integration/reducer';
import { IMobileExternalApiState } from '../mobile/external-api/reducer';
import { IFullScreenState } from '../mobile/full-screen/reducer';
import { IMobileWatchOSState } from '../mobile/watchos/reducer';
import { INoAudioSignalState } from '../no-audio-signal/reducer';
import { INoiseDetectionState } from '../noise-detection/reducer';
import { INoiseSuppressionState } from '../noise-suppression/reducer';
@@ -132,7 +130,6 @@ export interface IReduxState {
'features/file-sharing': IFileSharingState;
'features/filmstrip': IFilmstripState;
'features/follow-me': IFollowMeState;
'features/full-screen': IFullScreenState;
'features/gifs': IGifsState;
'features/google-api': IGoogleApiState;
'features/invite': IInviteState;
@@ -143,7 +140,6 @@ export interface IReduxState {
'features/mobile/audio-mode': IMobileAudioModeState;
'features/mobile/background': IMobileBackgroundState;
'features/mobile/external-api': IMobileExternalApiState;
'features/mobile/watchos': IMobileWatchOSState;
'features/no-audio-signal': INoAudioSignalState;
'features/noise-detection': INoiseDetectionState;
'features/noise-suppression': INoiseSuppressionState;

View File

@@ -139,7 +139,7 @@ function _upgradeRoleStarted(thenableWithCancel: Object) {
* @returns {Function}
*/
export function hideLoginDialog() {
return hideDialog(LoginDialog);
return hideDialog('LoginDialog', LoginDialog);
}
/**
@@ -199,7 +199,7 @@ export function enableModeratorLogin() {
* @returns {Action}
*/
export function openWaitForOwnerDialog() {
return openDialog(WaitForOwnerDialog);
return openDialog('WaitForOwnerDialog', WaitForOwnerDialog);
}
@@ -240,7 +240,7 @@ export function waitForOwner() {
* @returns {Action}
*/
export function openLoginDialog() {
return openDialog(LoginDialog);
return openDialog('LoginDialog', LoginDialog);
}
/**

View File

@@ -65,7 +65,7 @@ export function openTokenAuthUrl(tokenAuthServiceUrl: string): any {
// Show warning for leaving conference only when in a conference.
if (!browser.isElectron() && getState()['features/base/conference'].conference) {
dispatch(openDialog(LoginQuestionDialog, {
dispatch(openDialog('LoginQuestionDialog', LoginQuestionDialog, {
handler: () => {
// Give time for the dialog to close.
setTimeout(() => redirect(), 500);

View File

@@ -209,7 +209,7 @@ MiddlewareRegistry.register(store => next => action => {
case STOP_WAIT_FOR_OWNER:
_clearExistingWaitForOwnerTimeout(store);
store.dispatch(hideDialog(WaitForOwnerDialog));
store.dispatch(hideDialog('WaitForOwnerDialog', WaitForOwnerDialog));
break;
case UPGRADE_ROLE_FINISHED: {

View File

@@ -55,6 +55,28 @@ function getFirstGraphemeUpper(word: string) {
return splitter.splitGraphemes(word)[0].toUpperCase();
}
/**
* Strips bracketed annotations from a display name. Handles multiple bracket types like (),
* [], and {}.
*
* @param {string} name - The display name to clean.
* @returns {string} The cleaned display name without bracketed annotations.
*/
function stripBracketedAnnotations(name: string): string {
// Match content within any of the bracket types at the end of the string
// This regex matches: (...) or [...] or {...} at the end
const bracketRegex = /\s*[([{][^)\]}]*[)\]}]$/;
let cleaned = name;
// Remove all trailing bracketed annotations (handle multiple occurrences)
while (bracketRegex.test(cleaned)) {
cleaned = cleaned.replace(bracketRegex, '');
}
return cleaned.trim();
}
/**
* Generates initials for a simple string.
*
@@ -64,7 +86,15 @@ function getFirstGraphemeUpper(word: string) {
export function getInitials(s?: string) {
// We don't want to use the domain part of an email address, if it is one
const initialsBasis = split(s, '@')[0];
const [ firstWord, ...remainingWords ] = initialsBasis.split(wordSplitRegex).filter(Boolean);
// Strip bracketed annotations (e.g., "(Department)", "[Team]", "{Org}")
// to prevent them from being considered as name parts
const cleanedName = stripBracketedAnnotations(initialsBasis);
// Fallback to original if cleaned name is empty
const nameForInitials = cleanedName || initialsBasis;
const [ firstWord, ...remainingWords ] = nameForInitials.split(wordSplitRegex).filter(Boolean);
return getFirstGraphemeUpper(firstWord) + getFirstGraphemeUpper(remainingWords.pop() || '');
}

View File

@@ -7,6 +7,8 @@ import { showNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import { determineTranscriptionLanguage } from '../../transcribing/functions';
import { IStateful } from '../app/types';
import { connect } from '../connection/actions';
import { disconnect } from '../connection/actions.any';
import { JitsiTrackErrors } from '../lib-jitsi-meet';
import { setAudioMuted, setVideoMuted } from '../media/actions';
import { VIDEO_MUTISM_AUTHORITY } from '../media/constants';
@@ -22,7 +24,7 @@ import {
safeDecodeURIComponent
} from '../util/uri';
import { setObfuscatedRoom } from './actions';
import { conferenceWillInit, setObfuscatedRoom } from './actions';
import {
AVATAR_URL_COMMAND,
EMAIL_COMMAND,
@@ -618,3 +620,34 @@ export function updateTrackMuteState(stateful: IStateful, dispatch: IStore['disp
}, NOTIFICATION_TIMEOUT_TYPE.SHORT));
}
}
/**
* Processes the "destroyed" event of a conference and if the destroyed conference is the current one,
* it silently reconnects to the same room.
*
* @param {Object|Function} stateful - Either the whole Redux state object or the Redux store's {@code getState} method.
* @param {Function} dispatch - Redux dispatch function.
* @param {Array} params - The parameters for the destroy event.
*
* @returns {boolean} - True if the destroyed conference was the current one, and we are reconnecting, false otherwise.
*/
export function processDestroyConferenceEvent(stateful: IStateful, dispatch: IStore['dispatch'], params: Array<any>) {
const [ jid ] = params;
const conference = getCurrentConference(stateful);
// if the jid of the room is the same as the current conference, we are being
// notified that the current conference has been destroyed, and we need to reconnect
if (conference?.room?.roomjid === jid) {
dispatch(disconnect(true, false))
.then(() => {
dispatch(conferenceWillInit());
logger.info('Dispatching silent re-connect.');
return dispatch(connect());
});
return true;
}
return false;
}

View File

@@ -6,8 +6,8 @@ import MiddlewareRegistry from '../redux/MiddlewareRegistry';
import { CONFERENCE_FAILED } from './actionTypes';
import { conferenceLeft } from './actions.native';
import { TRIGGER_READY_TO_CLOSE_REASONS } from './constants';
import './middleware.any';
import { processDestroyConferenceEvent } from './functions';
MiddlewareRegistry.register(store => next => action => {
const { dispatch } = store;
@@ -23,6 +23,10 @@ MiddlewareRegistry.register(store => next => action => {
break;
}
if (processDestroyConferenceEvent(state, dispatch, error.params)) {
break;
}
if (!notifyOnConferenceDestruction) {
dispatch(conferenceLeft(action.conference));
dispatch(appNavigate(undefined));

View File

@@ -24,8 +24,8 @@ import {
KICKED_OUT
} from './actionTypes';
import { TRIGGER_READY_TO_CLOSE_REASONS } from './constants';
import { processDestroyConferenceEvent } from './functions';
import logger from './logger';
import './middleware.any';
let screenLock: WakeLockSentinel | undefined;
@@ -127,6 +127,11 @@ MiddlewareRegistry.register(store => next => action => {
const state = getState();
const { notifyOnConferenceDestruction = true } = state['features/base/config'];
const [ reason ] = action.error.params;
if (processDestroyConferenceEvent(state, dispatch, action.error.params)) {
break;
}
const titlekey = Object.keys(TRIGGER_READY_TO_CLOSE_REASONS)[
Object.values(TRIGGER_READY_TO_CLOSE_REASONS).indexOf(reason)
];

View File

@@ -285,6 +285,7 @@ export interface IConfig {
disableAudioLevels?: boolean;
disableBeforeUnloadHandlers?: boolean;
disableCameraTintForeground?: boolean;
disableChat?: boolean;
disableChatSmileys?: boolean;
disableDeepLinking?: boolean;
disableFilmstripAutohiding?: boolean;
@@ -393,6 +394,7 @@ export interface IConfig {
disabled?: boolean;
initialWidth?: number;
minParticipantCountForTopPanel?: number;
stageFilmstripParticipants?: number;
};
flags?: {
ssrcRewritingEnabled: boolean;
@@ -524,6 +526,7 @@ export interface IConfig {
hideExtraJoinButtons?: Array<string>;
preCallTestEnabled?: boolean;
preCallTestICEUrl?: string;
showHangUp?: boolean;
};
raisedHands?: {
disableLowerHandByModerator?: boolean;
@@ -615,6 +618,10 @@ export interface IConfig {
toolbarConfig?: {
alwaysVisible?: boolean;
autoHideWhileChatIsOpen?: boolean;
/**
* Background color for the main toolbar. Accepts any valid CSS color.
*/
backgroundColor?: string;
initialTimeout?: number;
timeout?: number;
};
@@ -653,7 +660,9 @@ export interface IConfig {
audio?: boolean;
video?: boolean;
};
hideVisitorCountForVisitors?: boolean;
queueService: string;
showJoinMeetingDialog?: boolean;
};
watchRTCConfigParams?: IWatchRTCConfiguration;
webhookProxyUrl?: string;

View File

@@ -94,11 +94,13 @@ export default [
'disableAudioLevels',
'disableBeforeUnloadHandlers',
'disableCameraTintForeground',
'disableChat',
'disableChatSmileys',
'disableDeepLinking',
'disabledNotifications',
'disabledSounds',
'disableFilmstripAutohiding',
'disableFocus',
'disableInitialGUM',
'disableInviteFunctions',
'disableIncomingMessageSound',
@@ -237,6 +239,8 @@ export default [
'useTurnUdp',
'videoQuality',
'visitors.enableMediaOnPromote',
'visitors.hideVisitorCountForVisitors',
'visitors.showJoinMeetingDialog',
'watchRTCConfigParams.allowBrowserLogCollection',
'watchRTCConfigParams.collectionInterval',
'watchRTCConfigParams.console',

View File

@@ -385,10 +385,10 @@ function _propertiesUpdate(properties: object) {
* Closes connection.
*
* @param {boolean} isRedirect - Indicates if the action has been dispatched as part of visitor promotion.
*
* @param {boolean} shouldLeave - Indicates whether to call JitsiConference.leave().
* @returns {Function}
*/
export function disconnect(isRedirect?: boolean) {
export function disconnect(isRedirect?: boolean, shouldLeave = true) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']): Promise<void> => {
const state = getState();
@@ -407,20 +407,26 @@ export function disconnect(isRedirect?: boolean) {
// intention to leave the conference.
dispatch(conferenceWillLeave(conference_, isRedirect));
promise
= conference_.leave()
.catch((error: Error) => {
logger.warn(
'JitsiConference.leave() rejected with:',
error);
if (!shouldLeave) {
// we are skipping JitsiConference.leave(), but will still dispatch the normal leave flow events
dispatch(conferenceLeft(conference_));
promise = Promise.resolve();
} else {
promise
= conference_.leave()
.catch((error: Error) => {
logger.warn(
'JitsiConference.leave() rejected with:',
error);
// The library lib-jitsi-meet failed to make the
// JitsiConference leave. Which may be because
// JitsiConference thinks it has already left.
// Regardless of the failure reason, continue in
// jitsi-meet as if the leave has succeeded.
dispatch(conferenceLeft(conference_));
});
// The library lib-jitsi-meet failed to make the
// JitsiConference leave. Which may be because
// JitsiConference thinks it has already left.
// Regardless of the failure reason, continue in
// jitsi-meet as if the leave has succeeded.
dispatch(conferenceLeft(conference_));
});
}
} else {
promise = Promise.resolve();
}

View File

@@ -14,6 +14,7 @@ import logger from './logger';
/**
* Signals Dialog to close its dialog.
*
* @param {string|undefined} name - The name of the component for logging purposes.
* @param {Object} [component] - The {@code Dialog} component to close/hide. If
* {@code undefined}, closes/hides {@code Dialog} regardless of which
* component it's rendering; otherwise, closes/hides {@code Dialog} only if
@@ -23,8 +24,8 @@ import logger from './logger';
* component: (React.Component | undefined)
* }}
*/
export function hideDialog(component?: ComponentType<any>) {
logger.info(`Hide dialog: ${getComponentDisplayName(component)}`);
export function hideDialog(name?: string, component?: ComponentType<any>) {
logger.info(`Hide dialog: ${name}`);
return {
type: HIDE_DIALOG,
@@ -48,6 +49,7 @@ export function hideSheet() {
/**
* Signals Dialog to open dialog.
*
* @param {string} name - The name of the component for logging purposes.
* @param {Object} component - The component to display as dialog.
* @param {Object} [componentProps] - The React {@code Component} props of the
* specified {@code component}.
@@ -57,8 +59,8 @@ export function hideSheet() {
* componentProps: (Object | undefined)
* }}
*/
export function openDialog(component: ComponentType<any>, componentProps?: Object) {
logger.info(`Open dialog: ${getComponentDisplayName(component)}`);
export function openDialog(name: string, component: ComponentType<any>, componentProps?: Object) {
logger.info(`Open dialog: ${name}`);
return {
type: OPEN_DIALOG,
@@ -92,35 +94,18 @@ export function openSheet(component: ComponentType<any>, componentProps?: Object
* is not already open. If it is open, then Dialog is signaled to close its
* dialog.
*
* @param {string} name - The name of the component for logging purposes.
* @param {Object} component - The component to display as dialog.
* @param {Object} [componentProps] - The React {@code Component} props of the
* specified {@code component}.
* @returns {Function}
*/
export function toggleDialog(component: ComponentType<any>, componentProps?: Object) {
export function toggleDialog(name: string, component: ComponentType<any>, componentProps?: Object) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
if (isDialogOpen(getState, component)) {
dispatch(hideDialog(component));
dispatch(hideDialog(name, component));
} else {
dispatch(openDialog(component, componentProps));
dispatch(openDialog(name, component, componentProps));
}
};
}
/**
* Extracts a printable name for a dialog component.
*
* @param {Object} component - The component to extract the name for.
*
* @returns {string} The display name.
*/
function getComponentDisplayName(component?: ComponentType<any>) {
if (!component) {
return '';
}
const name = component.displayName ?? component.name ?? 'Component';
return name.replace('withI18nextTranslation(Connect(', '') // dialogs with translations
.replace('))', ''); // dialogs with translations suffix
}

View File

@@ -78,12 +78,6 @@ export const CHAT_ENABLED = 'chat.enabled';
*/
export const FILMSTRIP_ENABLED = 'filmstrip.enabled';
/**
* Flag indicating if fullscreen (immersive) mode should be enabled.
* Default: enabled (true).
*/
export const FULLSCREEN_ENABLED = 'fullscreen.enabled';
/**
* Flag indicating if the Help button should be enabled.
* Default: enabled (true).

View File

@@ -80,7 +80,7 @@ const options: i18next.InitOptions = {
interpolation: {
escapeValue: false // not needed for react as it escapes by default
},
load: 'languageOnly',
load: 'all',
ns: [ 'main', 'languages', 'countries', 'translation-languages' ],
react: {
// re-render when a new resource bundle is added

View File

@@ -3,13 +3,14 @@ import { jitsiLocalStorage } from '@jitsi/js-utils/jitsi-local-storage';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import { safeJsonParse } from '@jitsi/js-utils/json';
import { pick } from 'lodash-es';
import { browser } from '../lib-jitsi-meet';
import { isEmbedded } from '../util/embedUtils';
import { parseURLParams } from '../util/parseURLParams';
import logger from './logger';
import WHITELIST from './whitelist';
/**
* Handles changes of the fake local storage.
@@ -61,7 +62,7 @@ function setupJitsiLocalStorage() {
if (shouldUseHostPageLocalStorage(urlParams)) {
try {
const localStorageContent = safeJsonParse(urlParams['appData.localStorageContent']);
let localStorageContent = safeJsonParse(urlParams['appData.localStorageContent']);
// We need to disable the local storage before setting the data in case the browser local storage doesn't
// throw exception (in some cases when this happens the local storage may be cleared for every session.
@@ -71,6 +72,10 @@ function setupJitsiLocalStorage() {
jitsiLocalStorage.setLocalStorageDisabled(true);
if (typeof localStorageContent === 'object') {
if (!isEmbedded()) {
localStorageContent = pick(localStorageContent, WHITELIST);
}
Object.keys(localStorageContent).forEach(key => {
jitsiLocalStorage.setItem(key, localStorageContent[key]);
});

View File

@@ -0,0 +1,11 @@
/**
* Keys of localStorage that are used by jibri.
*/
export default [
'callStatsUserName',
'displayname',
'email',
'xmpp_username_override',
'xmpp_password_override',
'xmpp_conference_password_override'
];

View File

@@ -186,6 +186,9 @@ function _initLogging({ dispatch, getState }: IStore,
Logger.addGlobalTransport(debugLogCollector);
JitsiMeetJS.addGlobalLogTransport(debugLogCollector);
debugLogCollector.start();
Logger.removeGlobalTransport(console);
JitsiMeetJS.removeGlobalLogTransport(console);
}
} else if (logCollector && loggingConfig.disableLogCollector) {
Logger.removeGlobalTransport(logCollector);

View File

@@ -26,7 +26,7 @@ MiddlewareRegistry.register((store: IStore) => (next: Function) => (action: AnyA
case SET_VIDEO_MUTED: {
if (LocalRecordingManager.isRecordingLocally() && LocalRecordingManager.selfRecording.on) {
if (action.muted && LocalRecordingManager.selfRecording.withVideo) {
dispatch(openDialog(StopRecordingDialog, { localRecordingVideoStop: true }));
dispatch(openDialog('StopRecordingDialog', StopRecordingDialog, { localRecordingVideoStop: true }));
return;
} else if (!action.muted && !LocalRecordingManager.selfRecording.withVideo) {

View File

@@ -827,17 +827,30 @@ export const setShareDialogVisiblity = (addPeopleFeatureEnabled: boolean, dispat
};
/**
* Checks if private chat is enabled for the given participant.
* Checks if private chat is enabled for the given participant or local participant.
*
* @param {IParticipant|IVisitorChatParticipant|undefined} participant - The participant to check.
* @param {IReduxState} state - The Redux state.
* @param {boolean} [checkSelf=false] - Whether to check for local participant's ability to send messages.
* @returns {boolean} - True if private chat is enabled, false otherwise.
*/
export function isPrivateChatEnabled(participant: IParticipant | IVisitorChatParticipant | undefined, state: IReduxState) {
export function isPrivateChatEnabled(
participant: IParticipant | IVisitorChatParticipant | undefined,
state: IReduxState,
checkSelf: boolean = false
): boolean {
const { remoteVideoMenu = {} } = state['features/base/config'];
const { disablePrivateChat } = remoteVideoMenu;
if ((!isVisitorChatParticipant(participant) && participant?.local) || disablePrivateChat === 'all') {
// If checking self capability (if the local participant can send messages) ignore the local participant blocking rule
const isLocal = !isVisitorChatParticipant(participant) && participant?.local;
if (isLocal && !checkSelf) {
return false;
}
// Check if private chat is disabled globally
if (disablePrivateChat === 'all') {
return false;
}
@@ -857,3 +870,15 @@ export function isPrivateChatEnabled(participant: IParticipant | IVisitorChatPar
return !disablePrivateChat;
}
/**
* Checks if private chat is enabled for the local participant (can they send private messages).
*
* @param {IReduxState} state - The Redux state.
* @returns {boolean} - True if the local participant can send private messages, false otherwise.
*/
export function isPrivateChatEnabledSelf(state: IReduxState): boolean {
const localParticipant = getLocalParticipant(state);
return isPrivateChatEnabled(localParticipant, state, true);
}

View File

@@ -27,6 +27,7 @@ import {
isRemoteScreenshareParticipant,
isScreenShareParticipant
} from './functions';
import logger from './logger';
import { FakeParticipant, ILocalParticipant, IParticipant, ISourceInfo } from './types';
/**
@@ -364,6 +365,8 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
sortedRemoteVirtualScreenshareParticipants.sort((a, b) => a[1].localeCompare(b[1]));
state.sortedRemoteVirtualScreenshareParticipants = new Map(sortedRemoteVirtualScreenshareParticipants);
logger.debug('Remote screenshare participant joined', id);
}
// Exclude the screenshare participant from the fake participant count to avoid duplicates.
@@ -448,6 +451,8 @@ ReducerRegistry.register<IParticipantsState>('features/base/participants',
if (sortedRemoteVirtualScreenshareParticipants.has(id)) {
sortedRemoteVirtualScreenshareParticipants.delete(id);
state.sortedRemoteVirtualScreenshareParticipants = new Map(sortedRemoteVirtualScreenshareParticipants);
logger.debug('Remote screenshare participant left', id);
}
if (oldParticipant && !oldParticipant.fakeParticipant && !isLocalScreenShare) {

View File

@@ -21,6 +21,7 @@ import {
getRemoteScreensharesBasedOnPresence,
getVirtualScreenshareParticipantOwnerId
} from './functions';
import logger from './logger';
import { FakeParticipant } from './types';
StateListenerRegistry.register(
@@ -69,14 +70,19 @@ function _createOrRemoveVirtualParticipants(
const addedScreenshareSourceNames = difference(newScreenshareSourceNames, oldScreenshareSourceNames);
if (removedScreenshareSourceNames.length) {
removedScreenshareSourceNames.forEach(id => dispatch(participantLeft(id, conference, {
fakeParticipant: FakeParticipant.RemoteScreenShare
})));
removedScreenshareSourceNames.forEach(id => {
logger.debug('Dispatching participantLeft for virtual screenshare', id);
dispatch(participantLeft(id, conference, {
fakeParticipant: FakeParticipant.RemoteScreenShare
}));
});
}
if (addedScreenshareSourceNames.length) {
addedScreenshareSourceNames.forEach(id => dispatch(
createVirtualScreenshareParticipant(id, false, conference)));
addedScreenshareSourceNames.forEach(id => {
logger.debug('Creating virtual screenshare participant', id);
dispatch(createVirtualScreenshareParticipant(id, false, conference));
});
}
}

View File

@@ -282,15 +282,18 @@ const PreMeetingScreen = ({
* @returns {Object}
*/
function mapStateToProps(state: IReduxState, ownProps: Partial<IProps>) {
const { hiddenPremeetingButtons } = state['features/base/config'];
const { hiddenPremeetingButtons, prejoinConfig } = state['features/base/config'];
const { toolbarButtons } = state['features/toolbox'];
const { showHangUp = true } = getLobbyConfig(state);
const { knocking } = state['features/lobby'];
const { showHangUp: showHangUpLobby = true } = getLobbyConfig(state);
const { showHangUp: showHangUpPrejoin = true } = prejoinConfig || {};
const premeetingButtons = (ownProps.thirdParty
? THIRD_PARTY_PREJOIN_BUTTONS
: PREMEETING_BUTTONS).filter((b: any) => !(hiddenPremeetingButtons || []).includes(b));
if (showHangUp && knocking && !premeetingButtons.includes('hangup')) {
const shouldShowHangUp = knocking ? showHangUpLobby : showHangUpPrejoin;
if (shouldShowHangUp && !premeetingButtons.includes('hangup')) {
premeetingButtons.push('hangup');
}

View File

@@ -57,7 +57,7 @@ class Message extends Component<IProps> {
const content: any[] = [];
const { gifEnabled } = this.props;
// check if the message is a GIF
// Check if the message is a GIF
if (gifEnabled && isGifMessage(text)) {
const url = extractGifURL(text);

View File

@@ -1,6 +1,7 @@
import { IReduxState, IStore } from '../../app/types';
import { isTrackStreamingStatusActive } from '../../connection-indicator/functions';
import { VIDEO_CODEC } from '../../video-quality/constants';
import { handleToggleVideoMuted } from '../../toolbox/actions.any';
import { muteLocal } from '../../video-menu/actions.any';
import { MEDIA_TYPE, VIDEO_TYPE } from '../media/constants';
import { getParticipantById, isScreenShareParticipant } from '../participants/functions';
import {
@@ -57,75 +58,12 @@ export function isLargeVideoReceived({ getState }: IStore): boolean {
}
/**
* Returns whether the local video track is encoded in AV1.
* Returns the local video track's codec.
*
* @param {IStore} store - The redux store.
* @returns {boolean}
* @returns {string?} The local video track's codec.
*/
export function isLocalCameraEncodingAv1({ getState }: IStore): boolean {
const state = getState();
const tracks = state['features/base/tracks'];
const localtrack = getLocalVideoTrack(tracks);
if (localtrack?.codec?.toLowerCase() === VIDEO_CODEC.AV1) {
return true;
}
return false;
}
/**
* Returns whether the local video track is encoded in H.264.
*
* @param {IStore} store - The redux store.
* @returns {boolean}
*/
export function isLocalCameraEncodingH264({ getState }: IStore): boolean {
const state = getState();
const tracks = state['features/base/tracks'];
const localtrack = getLocalVideoTrack(tracks);
if (localtrack?.codec?.toLowerCase() === VIDEO_CODEC.H264) {
return true;
}
return false;
}
/**
* Returns whether the local video track is encoded in VP8.
*
* @param {IStore} store - The redux store.
* @returns {boolean}
*/
export function isLocalCameraEncodingVp8({ getState }: IStore): boolean {
const state = getState();
const tracks = state['features/base/tracks'];
const localtrack = getLocalVideoTrack(tracks);
if (localtrack?.codec?.toLowerCase() === VIDEO_CODEC.VP8) {
return true;
}
return false;
}
/**
* Returns whether the local video track is encoded in VP9.
*
* @param {IStore} store - The redux store.
* @returns {boolean}
*/
export function isLocalCameraEncodingVp9({ getState }: IStore): boolean {
const state = getState();
const tracks = state['features/base/tracks'];
const localtrack = getLocalVideoTrack(tracks);
if (localtrack?.codec?.toLowerCase() === VIDEO_CODEC.VP9) {
return true;
}
return false;
export function getLocalCameraEncoding({ getState }: IStore): string | undefined {
return getLocalVideoTrack(getState()['features/base/tracks'])?.codec?.toLowerCase();
}
/**
@@ -142,3 +80,43 @@ export function isRemoteVideoReceived({ getState }: IStore, id: string): boolean
return Boolean(videoTrack && !videoTrack.muted && isTrackStreamingStatusActive(videoTrack));
}
/**
* Mutes the local audio. Same as clicking the audio mute button.
*
* @param {IStore} store - The redux store.
* @returns {Promise} Resolves when the action is complete.
*/
export function audioMute({ dispatch }: IStore) {
return dispatch(muteLocal(true, MEDIA_TYPE.AUDIO));
}
/**
* Unmutes the local audio. Same as clicking the audio unmute button.
*
* @param {IStore} store - The redux store.
* @returns {Promise} Resolves when the action is complete.
*/
export function audioUnmute({ dispatch }: IStore) {
return dispatch(muteLocal(false, MEDIA_TYPE.AUDIO));
}
/**
* Mutes the local video. Same as clicking the video mute button.
*
* @param {IStore} store - The redux store.
* @returns {Promise} Resolves when the action is complete.
*/
export function videoMute({ dispatch }: IStore) {
return dispatch(handleToggleVideoMuted(true, true, true));
}
/**
* Unmutes the local video. Same as clicking the video unmute button.
*
* @param {IStore} store - The redux store.
* @returns {Promise} Resolves when the action is complete.
*/
export function videoUnmute({ dispatch }: IStore) {
return dispatch(handleToggleVideoMuted(false, true, true));
}

View File

@@ -8,14 +8,15 @@ import { getJitsiMeetGlobalNS } from '../util/helpers';
import { setConnectionState } from './actions';
import {
audioMute,
audioUnmute,
getLocalCameraEncoding,
getRemoteVideoType,
isLargeVideoReceived,
isLocalCameraEncodingAv1,
isLocalCameraEncodingH264,
isLocalCameraEncodingVp8,
isLocalCameraEncodingVp9,
isRemoteVideoReceived,
isTestModeEnabled
isTestModeEnabled,
videoMute,
videoUnmute
} from './functions';
import logger from './logger';
@@ -88,13 +89,14 @@ function _bindTortureHelpers(store: IStore) {
// All torture helper methods go in here
getJitsiMeetGlobalNS().testing = {
audioMute: audioMute.bind(null, store),
audioUnmute: audioUnmute.bind(null, store),
getRemoteVideoType: getRemoteVideoType.bind(null, store),
isLargeVideoReceived: isLargeVideoReceived.bind(null, store),
isLocalCameraEncodingAv1: isLocalCameraEncodingAv1.bind(null, store),
isLocalCameraEncodingH264: isLocalCameraEncodingH264.bind(null, store),
isLocalCameraEncodingVp8: isLocalCameraEncodingVp8.bind(null, store),
isLocalCameraEncodingVp9: isLocalCameraEncodingVp9.bind(null, store),
isRemoteVideoReceived: isRemoteVideoReceived.bind(null, store)
getLocalCameraEncoding: getLocalCameraEncoding.bind(null, store),
isRemoteVideoReceived: isRemoteVideoReceived.bind(null, store),
videoMute: videoMute.bind(null, store),
videoUnmute: videoUnmute.bind(null, store),
};
}

View File

@@ -6,6 +6,7 @@ import { setScreenshareMuted } from '../media/actions';
import { addLocalTrack, replaceLocalTrack } from './actions.any';
import { getLocalDesktopTrack, getTrackState } from './functions.native';
import logger from './logger';
export * from './actions.any';
@@ -63,6 +64,6 @@ async function _startScreenSharing(dispatch: IStore['dispatch'], state: IReduxSt
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
}
} catch (error: any) {
console.log('ERROR creating screen-sharing stream ', error);
logger.error('Error creating screen-sharing stream', error);
}
}

View File

@@ -294,7 +294,7 @@ export function setCameraFacingMode(facingMode: string | undefined) {
* @returns {Object} - The open dialog action.
*/
export function openAllowToggleCameraDialog(onAllow: Function, initiatorId: string) {
return openDialog(AllowToggleCameraDialog, {
return openDialog('AllowToggleCameraDialog', AllowToggleCameraDialog, {
onAllow,
initiatorId
});

View File

@@ -211,18 +211,21 @@ export function getLocalJitsiAudioTrackSettings(state: IReduxState) {
const jitsiTrack = getLocalJitsiAudioTrack(state);
if (!jitsiTrack) {
const config = state['features/base/config'];
const disableAP = Boolean(config?.disableAP);
const disableAGC = Boolean(config?.disableAGC);
const disableAEC = Boolean(config?.disableAEC);
const disableNS = Boolean(config?.disableNS);
const stereo = Boolean(config?.audioQuality?.stereo);
const {
audioQuality,
disableAEC = false,
disableAGC = false,
disableAP = false,
disableNS = false
} = state['features/base/config'] || {};
const enableStereo = Boolean(audioQuality?.stereo);
return {
autoGainControl: !disableAP && !disableAGC,
channelCount: stereo ? 2 : 1,
echoCancellation: !disableAP && !disableAEC,
noiseSuppression: !disableAP && !disableNS
autoGainControl: enableStereo ? false : !disableAP && !disableAGC,
channelCount: enableStereo ? 2 : 1,
echoCancellation: enableStereo ? false : !disableAP && !disableAEC,
noiseSuppression: enableStereo ? false : !disableAP && !disableNS
};
}

View File

@@ -71,11 +71,16 @@ const useStyles = makeStyles()(theme => {
badge: {
...theme.typography.labelBold,
color: theme.palette.text04,
padding: `0 ${theme.spacing(1)}`,
borderRadius: '100%',
alignItems: 'center',
backgroundColor: theme.palette.warning01,
marginLeft: theme.spacing(2)
borderRadius: theme.spacing(2),
color: theme.palette.text04,
display: 'inline-flex',
height: theme.spacing(3),
justifyContent: 'center',
marginLeft: theme.spacing(2),
minWidth: theme.spacing(2),
padding: `0 ${theme.spacing(1)}`
},
icon: {

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