Compare commits

...

116 Commits

Author SHA1 Message Date
Jaya Allamsetty
4219d9ad4d chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2087.0.0+8eccb59f...v2089.0.0+75c1c6ff
2025-09-17 14:55:51 -04:00
Jaya Allamsetty
d68b9b1cad chore(deps) Update @jitsi/logger to 2.1.1 2025-09-16 22:45:59 -04:00
Jaya Allamsetty
8f0b9575c4 ref(logging) Rename logger ids to facilitate proper filtering of logs. 2025-09-16 22:45:59 -04:00
damencho
f780207c22 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2086.0.0+bc389f3b...v2087.0.0+8eccb59f
2025-09-16 13:05:49 -05:00
Jaya Allamsetty
ce19e6d40b fix(logging) Update the logger ids for default log levels 2025-09-16 12:32:19 -05:00
Jaya Allamsetty
b108db832f chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2084.0.0+819cdfbb...v2086.0.0+bc389f3b
2025-09-16 12:32:19 -05:00
damencho
e4283e61dd fix(wait-for-host): Fixes missing param. 2025-09-16 07:04:16 -05:00
Calinteodor
50e2458124 fix(chat): disable reactions for reaction messages (#16425)
*Removed the ability to react to reactions inside the chat panel.
2025-09-16 10:59:13 +03:00
damencho
329df31811 feat: Requires a moderator to start a moderated room without a tenant. 2025-09-15 20:39:05 -05:00
Joan Montané
fce39be9d2 lang: Update Sardinian
* Update main-sc.json

* Fix main-sc.json

---------

Co-authored-by: adrmzz <adrmzz@users.noreply.github.com>
2025-09-15 07:41:14 -05:00
Calinteodor
6c5a9ea199 feat(react-native-sdk): Remove JavaScriptSandboxModule from package 2025-09-11 16:15:15 +03:00
Calinteodor
196192c97f feat(react-native-sdk): Update update_dependencies.js
Removed code that merges package overrides from RNSDK. We no longer use them.
2025-09-11 15:15:02 +03:00
nbeck.indy
71f358c62a fix (lobby): Remove _onSendMessage base method from LobbyChatScreen 2025-09-10 13:51:23 -05:00
Calinteodor
7aa7e76ccd .github: fix CI iOS SDK step
*Add step to install iOS platform related simulators needed by Xcode.
2025-09-10 14:25:34 +03:00
Calin-Teodor
cd77b6bbe4 feat(react-native-sdk): update scripts to add worklets babel plugin deps 2025-09-10 11:30:09 +03:00
Дамян Минков
e94df6799e fix(tests): Fixes error because of not waiting for conference left event.
Try to fix the error we see: 
Error: waitUntil condition failed with the following reason: Command script.callFunction with id 116 (with the following parameter: {"functionDeclaration":"function anonymous(\n) {\nreturn (/* __wdio script__ */()=>typeof APP!==\"undefined\"&&APP.conference?.isJoined()/* __wdio script end__ */).apply(this, arguments);\n}","awaitPromise":true,"arguments":[],"target":{"context":"10352FFE685AC1D0503E1ECA3BFD33B2"}}) timed out

Seems like we do not wait for all checks to happen and start joining again in the middle of switching/checking.
2025-09-09 17:59:43 -05:00
damencho
2e92818b53 fix(lobby): Clear any params set on destroy lobby. 2025-09-09 15:39:49 -05:00
damencho
8a3129f7bf fix(visitors): Fixes checking for group.
moderator_id can have a user id or a group id, that will make all users from that group be moderators.
2025-09-09 12:17:34 -05:00
Jaya Allamsetty
eb03642ea6 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2076.0.0+69f68d36...v2084.0.0+819cdfbb
2025-09-09 10:29:11 -04:00
Calin-Teodor
c436e48956 feat(react-native-sdk): add react-native-worklets-core as a peer dep 2025-09-09 16:47:28 +03:00
Mihaela Dumitru
58db02bab8 feat(visitor) confirm raised hand sent to mods (#16388) 2025-09-09 16:19:39 +03:00
Calinteodor
abc1f3d33b dep(react-native-worklets-core): Replace duktape to align with Android 16kb page size alignment (#16393)
* Replaced duktape lib with react-native-worklets-core and checked for compatibility with Android 16kb page-size requirement.
2025-09-09 12:46:11 +03:00
Matteo
b2166d9874 lang: Update main-it.json (#16363)
- Translated new strings
- Improved translation
2025-09-08 16:04:44 -05:00
Florian
901a13a99a Added hint to desktop sharing frame rate config 2025-09-08 09:48:41 -04:00
Hugo Lavernhe
1e15d9421b feat(settings) Add advanced audio settings checkboxes (#16316)
* Add checkboxes to toggle audio settings

* Sync checkboxes with audio mixer effect

* Add tooltips

* Move previewAudioTrack to redux

* Add translation

* Add audio settings state to redux

* Update docs

* Apply review comments

* Create local track with audio contraints when unmuting

* Refactor functions and naming

* Add enableAdvancedAudioSettings config

* Fix mobile imports

* Add tooltips content

* Update react/features/base/config/functions.any.ts

* Layout checkboxes in a two-column grid

* Fix web imports

* Sort translation alphabetically

* Separate audio mute implementation for mobile and web

* Apply review comments

* squash: Add imports for middleware.any

* squash: fix linter errors

* Remove tooltips

* Lint

* Refactored setting of audio constraints in createLocalTracksF with checks for feature flag and desktop

---------

Co-authored-by: Jaya Allamsetty <54324652+jallamsetty1@users.noreply.github.com>
Co-authored-by: Jaya Allamsetty <jaya.allamsetty@8x8.com>
2025-09-05 16:52:35 -04:00
Дамян Минков
9252bbb036 fix: Fixes log message about meeting id. 2025-09-05 10:42:30 -05:00
Hristo Terezov
f1bae8bc10 feat(chat): Add Open chat button to chat notifications 2025-09-04 16:27:18 -05:00
Дамян Минков
5a54511d2c fix: Fixes missing string for shortcut. 2025-09-04 08:25:12 -05:00
bgrozev
61764273b2 ref: Refactor tests (#16399)
* ref: Inline enterTileView.
* ref: Refactor tileView, remove tileView.LastN.
    The "last n" cases are not related to tile view and are covered in lastN.spec.ts.
* ref: Remove redundant "skipInMeetingChecks: true".
    skipInMeetingChecks is only used in ensureTwoParticipants, ensureThreeParticipants and ensureFourParticipants.
* ref: Move recording test to jaas/, more refactoring.
* ref: Rename and document switchToAPI() and switchInPage().
* ref: Move the tileView into 2way (temp).
2025-09-03 15:31:43 -05:00
Pelle Hanses
e39f38f75b lang: Update swedish (#16396)
Changed to a more business-like tone.
2025-09-03 13:36:54 -05:00
Edgars Voroboks
2d25f48c72 lang: Update Latvian language translation (#16395) 2025-09-03 13:36:48 -05:00
damencho
2cb727fc58 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2051.0.0+ccc06e83...v2076.0.0+69f68d36
2025-09-03 08:07:11 -05:00
damencho
c069c0d7c3 feat(display-name): Handles new display-name extension in messages.
The display name is used in messages when messages are coming from visitors or from the history. The display name is used only when the participant is not available in the meeting to get its name.
2025-09-03 08:07:11 -05:00
damencho
5de69d501d feat(displayname): Adds new feature name-readonly.
This enforces display names from jwt tokens.
2025-09-03 08:07:11 -05:00
damencho
599c88a71d fix: Drops hideDisplayNameForAll. 2025-09-03 08:07:11 -05:00
Mihaela Dumitru
5476321df6 fix(recordings): conditionally render learn more link in consent dialog (#16386) 2025-08-28 17:23:42 +03:00
damencho
076b6a2a7e fix(permissions): Fixes grant moderator after being in lobby. 2025-08-27 17:13:27 -05:00
damencho
8b9df0cd37 fix(av-moderation): Update initial whitelists when auto enabling. 2025-08-27 17:13:19 -05:00
Calin-Teodor
44f5de3db4 feat(recording): explicitly convert visible value to true or false 2025-08-26 17:48:47 +03:00
Calin-Teodor
fb69225d42 feat(notifications): style adjustments 2025-08-26 17:31:02 +03:00
Mihaela Dumitru
32df284277 fix(accessibility) improve file actions with focus management and ARIA roles (#16322) 2025-08-26 16:29:05 +03:00
José Luís Andrade
253679cfb9 lang: Update Portuguese (#16331) 2025-08-25 21:40:45 -05:00
damencho
057c19f4dd feat(metadata): Adds logging when metadata is modified or sent. 2025-08-25 12:56:38 -05:00
damencho
6159a23c55 fix(tests): Fixes participantRoleChanged event handling. 2025-08-25 07:40:47 -05:00
damencho
1685c39c5d fix(tests): Fix passing correct participant options. 2025-08-22 15:09:53 -05:00
damencho
2cecc61b97 fix(tests): Make sure first participant is moderator. 2025-08-22 15:09:53 -05:00
damencho
df2262ae53 feat(tests): Return early if jaas tests not configured. 2025-08-22 15:09:53 -05:00
damencho
d61deab163 feat(tests): Make sure we add a single listener for iframeAPI events. 2025-08-22 15:09:53 -05:00
damencho
e7eab72c0c feat(tests): Clear previous videoConferenceLeft events. 2025-08-22 15:09:53 -05:00
damencho
c1e803c6e3 feat(tests): Increase wait time for webhooks. 2025-08-22 15:09:53 -05:00
damencho
dc1f20e059 fix(localrecording): Local recording is not supported in embedded mode.
It is not available due to cross-origin or not able to start setCaptureHandleConfig in iframe.
error 1: Failed to execute 'showSaveFilePicker' on 'Window': Cross origin sub frames aren't allowed to show a file picker.
error 2: Failed to execute 'setCaptureHandleConfig' on 'MediaDevices': Can only be called from the top-level document.
2025-08-22 06:51:12 -05:00
bgrozev
61ee9af304 test: Add a test for visitors with single sender (PLI). (#16364) 2025-08-21 16:31:03 -05:00
bgrozev
d75de3642e Fix jaas tests (#16360)
* fix: Fix jaas joinMuc(), it remove now redundant calls to hangup().

* fix: Fix jaas passcode tests.

* ref: make joinParticipant private again.
2025-08-20 14:46:52 -05:00
Calinteodor
1ae1729545 chore(android): add top and bottom margin insets for API 35 (#16359)
* Once we started targeting SDK 35 on a device running Android 15 or higher, by default, we display edge-to-edge.
  We can handle overlaps by using insets.
2025-08-20 17:22:33 +03:00
Saúl Ibarra Corretgé
8cea505417 fix(dynamic-branding) cleanup custom icon SVGs 2025-08-20 15:49:12 +02:00
damencho
b0a96b32d2 fix(jiconop): Fixes loading it under different virtual hosts. 2025-08-19 15:59:34 -05:00
bgrozev
dac9b5e244 test: Check for send/receive independently. (#16356)
This allows the logs to show which one definitely failed.
2025-08-19 15:31:52 -05:00
damencho
d15cfd845a fix(config): Drops legacy config prejoinPageEnabled. 2025-08-19 08:41:04 -05:00
bgrozev
91e4ac1665 ref: Extract test configuration code to TestsConfig.ts (#16329)
* ref: Move iFrameUsesJaas to TestsConfig.

* ref: Move room name prefix/suffix to config.

* ref: Move JaaS configuration to TestsConfig.

* ref: Move iframe config to TestsConfig.

* ref: Move webproxy config to TestsConfig.

* ref: Move JWT config to TestsConfig.

* doc: Document some of the IContext fields.

* Add a debug config option.
2025-08-18 13:32:41 -05:00
damencho
fda42e5230 fix: More fixes sending metadata to jicofo.
f1a0012 was not enough to address the issue.
2025-08-18 11:24:07 -05:00
Calin-Teodor
142d4441c1 feat(chat): add tooltip for each chat screen tab 2025-08-18 16:33:15 +03:00
Mihaela Dumitru
5814c4dda7 fix(dynamic-branding) expand background color option to support a wider range of configurations (#16334) 2025-08-18 11:38:09 +03:00
Jaya Allamsetty
8c1dc03363 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2048.0.0+4d9a138b...v2051.0.0+ccc06e83
2025-08-14 10:49:20 -04:00
Jaya Allamsetty
ff6fc198f1 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2044.0.0+437abe32...v2048.0.0+4d9a138b
2025-08-13 20:22:14 -04:00
damencho
f1a0012fc1 fix: Fixes sending metadata to jicofo.
In cases like waiting-for-host lobby, jicofo can leave the room and rejoin later, without the room being destroyed. We need to make sure the metadata will reach jicofo on second attempt.
2025-08-11 16:32:25 +03:00
Дамян Минков
85522aea25 feat(tests): Updates join logic. (#16320)
* fix: Fix example file.

* fix: Fix using webhook proxy with iframe and jaas tests.

* fix: Fixes detecting max users notification.

* ref: Clear _joinParticipant to not depend on participant names.

* ref: Use joinParticipant in jaas tests.

* ref: Drops JAAS_DOMAIN as BASE_URL is used.

* fix: Drops ctx from function parameters.

* ref: Drops not needed context members.

* ref: Drops extra function.

* ref: Participant.joinConference to use roomName from options.

* doc: Updates docs.

* fix: Adds roomName to joinOptions.

Make it possible to override the generated value.
2025-08-11 06:52:16 -05:00
Saúl Ibarra Corretgé
000c370c64 fix(prejoin) no initial tracks when using URL override to disable it
It's still possible to disable it, but when not in an iframe, audio and
video tracks will not be created.

When in an iframe, it's ok to let it happen, since the host sit is the
one where permissions need to be granted, thanks to permission
delegation.

Fixes: https://github.com/jitsi/jitsi-meet/issues/16262
Ref: https://zimzi.substack.com/p/jitsi-privacy-flaw-that-enables-one
2025-08-08 23:06:01 +02:00
Mihaela Dumitru
a762d585b8 fix(accessibility) return focus to share file button after upload modal closes (#16312) 2025-08-08 19:34:10 +03:00
Mihaela Dumitru
ded8f22363 fix(accessibility) add ARIA attributes to file upload progress bar (#16311) 2025-08-08 19:33:24 +03:00
Mihaela Dumitru
c3e1c9d568 fix(accessibility) show upload successful notification (#16309) 2025-08-08 17:15:03 +03:00
Mihaela Dumitru
8901132af9 fix(accessibility) announce error and warning notifications immediately (#16307) 2025-08-08 17:14:35 +03:00
Mihaela Dumitru
71f92f6e17 fix(accessibility) improve notification action button accessibility (#16306) 2025-08-08 17:14:17 +03:00
Mihaela Dumitru
76166df81a fix(accessibility) remove nested button structure in file sharing drop zone (#16304) 2025-08-08 17:13:06 +03:00
Mihaela Dumitru
eb2ba39289 fix(accessibility) use semantic list for uploaded files (#16317) 2025-08-08 17:12:34 +03:00
bgrozev
048b089acd ref: Refactor tests (#16315)
* ref: Move iframe tests to iframe/.

* ref: Pass iFrameApi as Participant option.

* ref: Extract IParticipantJoinOptions.

* ref: Remove displayName from IJoinOptions (unused).

* ref: Move preferGenerateToken out of Participant.
2025-08-08 01:58:44 -05:00
Jaya Allamsetty
b774f18f80 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2036.0.0+b6142c70...v2044.0.0+437abe32
2025-08-07 19:29:39 -04:00
Zaid0412
dbe4e6a784 feat: disable Giphy analytics to prevent beforeunload handlers (#16314) 2025-08-07 16:34:07 +02:00
raduanastase8x8
d2e52d2c2a ref(Theme): Changes typography values to rem (#16021)
Replaces hard-coded pixel values with relative rem units across UI components to improve typography responsiveness and maintainability.

Co-authored-by: Hristo Terezov <hristo@jitsi.org>
2025-08-06 19:07:27 -05:00
bgrozev
b5ad984dab ref: Allow tests to specify the browsers they use in TestProperties. (#16313)
* ref: Allow tests to specify the browsers they use in TestProperties.
2025-08-06 08:47:50 -05:00
Mihaela Dumitru
81ce664ad7 fix(i18n) improve label (#16301) 2025-08-06 12:19:03 +03:00
bgrozev
181ef92e1f Add a test for jaas passcode, refactor tests. (#16303)
* ref: Don't use global context for local state.

* ref: Don't use global context to store the pin.

* feat: Add a test for setting passcode via settings provisioning.

* Use local state.

* Remove "data" from context.

* ref: Rename a function.

* test: Fail quick when join muc fails, assert specific errors (e.g. "token expired").
2025-08-06 04:00:59 -05:00
Horatiu Muresan
79dbc2d1ee feat(chat-web) add chat recipient picker (#16298) 2025-08-05 10:06:04 +03:00
Jaya Allamsetty
f56ce78b9d chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2033.0.0+bf3e3a8e...v2036.0.0+b6142c70
2025-08-04 16:29:32 -04:00
Дамян Минков
8269b88796 feat(prosody): Adds docs for added room fields. (#16299)
* feat(prosody): Adds docs for added room fields.

* squash: Drop comment.
2025-08-04 14:56:21 -05:00
bgrozev
252ef4604a test: Add JaaS-specific tests: join MUC, visitors, maxOccupants. (#16270)
* test: Add tests for joining a JaaS MUC with different token options.
* ref: Refactor token generation and usage
* ref: Reduce usage of global context 
* test: Add a maxOccupants jaas test.
2025-08-04 04:28:38 -05:00
Hristo Terezov
fc816aa149 fix(ChatMessage): context menu position
Before the chat message context menu was appearing on the left if the private chat message was disabled. The fix makes the context menu appear on the left only for messages from the local partcipant which are the only messages rendered to the right (therefore the context menu have to appear on the left side). For all other messages the context menu should appear on the right side because the message is positioned on the left side.
2025-08-02 10:19:16 -05:00
Hristo Terezov
6de18fe82d fix(participants-pane): restore scrolling and fix context menu clipping
The participant pane lost its scrolling capability when commit 2305ae85a removed the overflowY: 'auto' property from the container styles. This prevented users from scrolling through long lists of participants, breakout rooms, or visitors when the content exceeded the available height.

Additionally, context menus were being clipped on the left side due to the overflow constraints. This became apparent after the av-moderation feature added longer menu items like "Stop screen-sharing for everyone else".

Fix:
- Restore overflowY: 'auto' to enable vertical scrolling
- Add maxWidth constraint (285px) to context menus to prevent horizontal clipping
- Allow menu text to wrap to multiple lines instead of being cut off
- Add TODO comment for future portal-based implementation

This temporary solution provides both functional scrolling and fully readable context menus until a proper architectural change can be implemented to portal context menus outside the scrollable container.
2025-08-01 09:48:06 -05:00
Hristo Terezov
5b7e3bb2d7 doc(config): disablePrivateChat visitor value 2025-07-31 14:39:17 -05:00
Mihaela Dumitru
bc08b38791 fix(config) revise option description 2025-07-31 14:47:58 +03:00
Edgars Voroboks
6613f630d7 fix(lang): Update Latvian language translation 2025-07-31 10:14:14 +03:00
Calinteodor
719b6d68c8 chore(android): 16 kb page size alignment (#16276)
* Most libraries are aligned, only duktape needs to be replaced.
2025-07-30 15:52:40 +03:00
val11n1
6a62c5120f fix(rn) fix iOS rendering when launched locked 2025-07-28 23:59:26 +02:00
Oğuzhan Selim Temiz
64270f3015 fix(react-native-sdk): resolve Android build configuration issues
- Move namespace declaration to correct location in build.gradle
- Remove deprecated package attribute from AndroidManifest.xml
- Update README with gradle plugin version requirement
- Fix Android namespace configuration for React Native SDK

These changes resolve installation and build errors when integrating
the Jitsi Meet React Native SDK into new projects.

Fixes: SDK installation failures on Android with newer Gradle versions
2025-07-28 10:55:55 +03:00
Hristo Terezov
cb621f8e32 feat(visitors): Private messages to main participants. 2025-07-25 17:26:06 -05:00
Hristo Terezov
3c80cfddd7 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v2030.0.0+b225c920...v2033.0.0+bf3e3a8e
2025-07-25 17:26:06 -05:00
Horatiu Muresan
557f6defb8 chore(analytics) Add getter for amplitude deviceId (#16268) 2025-07-25 20:41:29 +03:00
raduanastase8x8
52fa36f930 chore(wcag) Create valid structure for audio menu (#16007) 2025-07-24 19:40:50 +03:00
damencho
b050e5f5e8 fix: Fixes table equals missing param name. 2025-07-24 15:00:09 +03:00
damencho
bf8d83953b fix: Fixes table equals.
Was checking only for added or removed keys, but not for modified values.
2025-07-24 14:11:50 +03:00
Horatiu Muresan
f16bf466eb feat(external-api) Add camera capture function (#16238) 2025-07-23 17:22:48 +03:00
damencho
29ea811527 fix(av-moderation): Updates the whitelist with every moderator.
When a moderator joins or someone is granted moderation we update the whitelist for any media type for which moderation is enabled. The updated whitelist is sent to all the moderators including the newly joined or granted one.
2025-07-23 10:53:15 +03:00
Calin-Teodor
435d034fdb fix(toolbox/native): update SvgCssUri import 2025-07-23 10:50:59 +03:00
Calinteodor
419baa7ab7 feat(android): init RIMHs app before on create (#15887)
Initialise ReactInstanceManagerHolder during application startup, making it ready before onCreate() is called.
2025-07-22 13:05:54 +03:00
damencho
9eb7b7bb01 fix: Showing go-live notification.
Handle the case when a local participant becomes moderator after metadata is updated.
2025-07-22 11:19:59 +03:00
Hristo Terezov
19ee989cda fix(visitors): Add fallback display names for empty visitor names
Visitors with empty or undefined names now show the configured
defaultRemoteDisplayName or 'Fellow Jitster' as fallback, matching
the behavior of regular remote participants.
2025-07-22 07:27:52 +03:00
ltorje-8x8
ab1dcc5375 fix(go-live): unsubscribe from topics before closing if not done already (#16244) 2025-07-21 16:47:24 -05:00
damencho
3047b4c8c4 fix: Fixes updating local UI startMuted state. 2025-07-21 22:49:35 +03:00
damencho
2afce3d151 fix: Fixes restoring startmuted in av mod. 2025-07-21 16:37:23 +03:00
damencho
1cea9b1786 fix: Avoids sending two metadata updates.
When setting startMuted we are sending two metadata updates.
2025-07-21 16:37:23 +03:00
damencho
2b7299ae05 fix: Drops not needed default values when filtering. 2025-07-21 16:37:09 +03:00
damencho
4b50f13e96 fix: Filters stanza on cloned copy. 2025-07-21 16:37:09 +03:00
Saúl Ibarra Corretgé
c639acebcf fix(polls) more resilient parsing of payloads, take 2 2025-07-21 15:10:56 +02:00
Horatiu Muresan
1a34ed9a2d fix(i18n) Fix showing Afrikaans when set language is not found (#16245)
- fix translates sort
2025-07-17 15:14:52 +03:00
Hristo Terezov
0939e207eb fix(go-live): waiting not updated correctly.
We were comparing if the number of waiting participants have changed with the wrong property from the state - the number of visitors. The result was that we won't update the state when the new waiting value matches the number of visitors already in the state. Most of the times this will be 0 and we would never go to 0.
2025-07-15 20:54:12 -05:00
Hristo Terezov
8c3ea05ae6 fix(go-live): Disconnect on page close.
Currently we don't close the socket for the participants in the queue when the page is closed.
2025-07-15 18:32:21 -05:00
bgrozev
daf8a929b1 fix: Fix hideDisplayNameForAll. (#16239)
Remove filtering on the receive side, because:
1. It's not applied to visitors, and should be for the "all" case
2. We don't want to strip stats-id from stanzas sent to jicofo
2025-07-15 10:49:04 -05:00
393 changed files with 6391 additions and 2710 deletions

View File

@@ -152,12 +152,13 @@ jobs:
xcodebuild clean \
-workspace ios/jitsi-meet.xcworkspace \
-scheme JitsiMeetSDK
xcodebuild -downloadPlatform iOS -buildVersion 18.2
xcodebuild archive \
-workspace ios/jitsi-meet.xcworkspace \
-scheme JitsiMeetSDK \
-configuration Release \
-sdk iphoneos \
-destination='generic/platform=iOS' \
-destination 'generic/platform=iOS' \
-archivePath ios/sdk/out/ios-device \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES

View File

@@ -28,6 +28,14 @@ android {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
externalNativeBuild {
cmake {
arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", "-DANDROID_STL=c++_shared"
cppFlags "-std=c++17"
cFlags "-DANDROID_PLATFORM=android-26"
}
}
}
signingConfigs {
@@ -46,8 +54,8 @@ android {
applicationIdSuffix ".debug"
}
release {
// Uncomment the following line for singing a test release build.
//signingConfig signingConfigs.debug
// Uncomment the following line for signing a test release build.
// signingConfig signingConfigs.debug
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-release.pro'
buildConfigField "boolean", "GOOGLE_SERVICES_ENABLED", "${googleServicesEnabled}"
@@ -102,8 +110,6 @@ dependencies {
gradle.projectsEvaluated {
// Dropbox integration
//
def dropboxAppKey
if (project.file('dropbox.key').exists()) {
dropboxAppKey = project.file('dropbox.key').text.trim() - 'db-'
@@ -174,7 +180,6 @@ gradle.projectsEvaluated {
packageTask.dependsOn(currentRunPackagerTask)
}
}
if (googleServicesEnabled) {

View File

@@ -6,6 +6,5 @@
-keep public class * extends java.lang.Exception
# R8 missing classes - suppress warnings
-dontwarn com.facebook.fresco.ui.common.LoggingListener
-dontwarn com.facebook.memory.config.MemorySpikeConfig
-dontwarn kotlinx.parcelize.Parcelize

View File

@@ -96,8 +96,3 @@
# Rule to avoid build errors related to SVGs.
-keep public class com.horcrux.svg.** {*;}
# https://github.com/facebook/fresco/issues/2638
-keep public class com.facebook.imageutils.** {
public *;
}

View File

@@ -7,11 +7,11 @@ import org.gradle.util.VersionNumber
buildscript {
ext {
kotlinVersion = "2.0.21"
gradlePluginVersion = "8.4.2"
buildToolsVersion = "34.0.0"
compileSdkVersion = 34
gradlePluginVersion = "8.6.0"
buildToolsVersion = "35.0.0"
compileSdkVersion = 35
minSdkVersion = 26
targetSdkVersion = 34
targetSdkVersion = 35
supportLibVersion = "28.0.0"
ndkVersion = "27.1.12297006"
@@ -75,26 +75,6 @@ allprojects {
}
}
// Due to a dependency conflict between React Native and the Fresco library used by GiphySDK,
// GIFs appear as static images instead of animating
// https://github.com/Giphy/giphy-react-native-sdk/commit/7fe466ed6fddfaec95f9cbc959d33bd75ad8f900
configurations.configureEach {
resolutionStrategy {
forcedModules = [
'com.facebook.fresco:fresco:3.2.0',
'com.facebook.fresco:animated-gif:3.2.0',
'com.facebook.fresco:animated-base:3.2.0',
'com.facebook.fresco:animated-drawable:3.2.0',
'com.facebook.fresco:animated-webp:3.2.0',
'com.facebook.fresco:webpsupport:3.2.0',
'com.facebook.fresco:imagepipeline-okhttp3:3.2.0',
'com.facebook.fresco:middleware:3.2.0',
'com.facebook.fresco:nativeimagetranscoder:3.2.0'
]
}
}
// Third-party react-native modules which Jitsi Meet SDK for Android depends
// on and which are not available in third-party Maven repositories need to
// be deployed in a Maven repository of ours.

View File

@@ -0,0 +1,113 @@
#!/bin/bash
progname="${0##*/}"
progname="${progname%.sh}"
# usage: check_elf_alignment.sh [path to *.so files|path to *.apk]
cleanup_trap() {
if [ -n "${tmp}" -a -d "${tmp}" ]; then
rm -rf ${tmp}
fi
exit $1
}
usage() {
echo "Host side script to check the ELF alignment of shared libraries."
echo "Shared libraries are reported ALIGNED when their ELF regions are"
echo "16 KB or 64 KB aligned. Otherwise they are reported as UNALIGNED."
echo
echo "Usage: ${progname} [input-path|input-APK|input-APEX]"
}
if [ ${#} -ne 1 ]; then
usage
exit
fi
case ${1} in
--help | -h | -\?)
usage
exit
;;
*)
dir="${1}"
;;
esac
if ! [ -f "${dir}" -o -d "${dir}" ]; then
echo "Invalid file: ${dir}" >&2
exit 1
fi
if [[ "${dir}" == *.apk ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
if { zipalign --help 2>&1 | grep -q "\-P <pagesize_kb>"; }; then
echo "=== APK zip-alignment ==="
zipalign -v -c -P 16 4 "${dir}" | egrep 'lib/arm64-v8a|lib/x86_64|Verification'
echo "========================="
else
echo "NOTICE: Zip alignment check requires build-tools version 35.0.0-rc3 or higher."
echo " You can install the latest build-tools by running the below command"
echo " and updating your \$PATH:"
echo
echo " sdkmanager \"build-tools;35.0.0-rc3\""
fi
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apk}_out_XXXXX")
unzip "${dir}" lib/* -d "${tmp}" >/dev/null 2>&1
dir="${tmp}"
fi
if [[ "${dir}" == *.apex ]]; then
trap 'cleanup_trap' EXIT
echo
echo "Recursively analyzing $dir"
echo
dir_filename=$(basename "${dir}")
tmp=$(mktemp -d -t "${dir_filename%.apex}_out_XXXXX")
deapexer extract "${dir}" "${tmp}" || { echo "Failed to deapex." && exit 1; }
dir="${tmp}"
fi
RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"
unaligned_libs=()
echo
echo "=== ELF alignment ==="
matches="$(find "${dir}" -type f)"
IFS=$'\n'
for match in $matches; do
# We could recursively call this script or rewrite it to though.
[[ "${match}" == *".apk" ]] && echo "WARNING: doesn't recursively inspect .apk file: ${match}"
[[ "${match}" == *".apex" ]] && echo "WARNING: doesn't recursively inspect .apex file: ${match}"
[[ $(file "${match}") == *"ELF"* ]] || continue
res="$(objdump -p "${match}" | grep LOAD | awk '{ print $NF }' | head -1)"
if [[ $res =~ 2\*\*(1[4-9]|[2-9][0-9]|[1-9][0-9]{2,}) ]]; then
echo -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"
else
echo -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"
unaligned_libs+=("${match}")
fi
done
if [ ${#unaligned_libs[@]} -gt 0 ]; then
echo -e "${RED}Found ${#unaligned_libs[@]} unaligned libs (only arm64-v8a/x86_64 libs need to be aligned).${ENDCOLOR}"
elif [ -n "${dir_filename}" ]; then
echo -e "ELF Verification Successful"
fi
echo "====================="

View File

@@ -44,10 +44,8 @@ dependencies {
api "com.facebook.react:react-android:$rootProject.ext.rnVersion"
api "com.facebook.react:hermes-android:$rootProject.ext.rnVersion"
implementation 'com.facebook.fresco:animated-gif:2.5.0'
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
implementation 'com.jakewharton.timber:timber:5.0.1'
implementation 'com.squareup.duktape:duktape-android:1.3.0'
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'androidx.startup:startup-runtime:1.1.0'
implementation 'com.google.j2objc:j2objc-annotations:3.0.0'
@@ -88,6 +86,7 @@ dependencies {
implementation project(':react-native-svg')
implementation project(':react-native-video')
implementation project(':react-native-webview')
implementation project(':react-native-worklets-core')
// Use `api` here so consumers can use WebRTCModuleOptions.
api project(':react-native-webrtc')

View File

@@ -1,57 +0,0 @@
/*
* Copyright @ 2019-present 8x8, Inc.
*
* 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.
*/
package org.jitsi.meet.sdk;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import com.squareup.duktape.Duktape;
@ReactModule(name = JavaScriptSandboxModule.NAME)
class JavaScriptSandboxModule extends ReactContextBaseJavaModule {
public static final String NAME = "JavaScriptSandbox";
public JavaScriptSandboxModule(ReactApplicationContext reactContext) {
super(reactContext);
}
/**
* Evaluates the given code in a Duktape VM.
* @param code - The code that needs to evaluated.
* @param promise - Resolved with the output in case of success or rejected with an exception
* in case of failure.
*/
@ReactMethod
public void evaluate(String code, Promise promise) {
Duktape vm = Duktape.create();
try {
Object res = vm.evaluate(code);
promise.resolve(res.toString());
} catch (Throwable tr) {
promise.reject(tr);
} finally {
vm.close();
}
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -49,6 +49,10 @@ public class JitsiInitializer implements Initializer<Boolean> {
// Register activity lifecycle handler for the orientation locker module.
((Application) context).registerActivityLifecycleCallbacks(OrientationActivityLifecycle.getInstance());
// Initialize ReactInstanceManager during application startup
// This ensures it's ready before any Activity onCreate is called
ReactInstanceManagerHolder.initReactInstanceManager((Application) context);
return true;
}

View File

@@ -25,9 +25,15 @@ import android.content.IntentFilter;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.facebook.react.modules.core.PermissionListener;
@@ -87,6 +93,28 @@ public class JitsiMeetActivity extends AppCompatActivity
launch(context, options);
}
public static void addTopBottomInsets(@NonNull Window w, @NonNull View v) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM) return;
View decorView = w.getDecorView();
decorView.post(() -> {
WindowInsetsCompat insets = ViewCompat.getRootWindowInsets(decorView);
if (insets != null) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) v.getLayoutParams();
params.topMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).top;
params.bottomMargin = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
v.setLayoutParams(params);
decorView.setOnApplyWindowInsetsListener((view, windowInsets) -> {
view.setBackgroundColor(JitsiMeetView.BACKGROUND_COLOR);
return windowInsets;
});
}
});
}
// Overrides
//
@@ -102,7 +130,12 @@ public class JitsiMeetActivity extends AppCompatActivity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ReactInstanceManager is now initialized by JitsiInitializer during application startup
// Just call onHostResume since the manager is already ready
JitsiMeetActivityDelegate.onHostResume(this);
setContentView(R.layout.activity_jitsi_meet);
addTopBottomInsets(getWindow(),findViewById(android.R.id.content));
this.jitsiView = findViewById(R.id.jitsiView);
registerForBroadcastMessages();

View File

@@ -17,6 +17,7 @@
package org.jitsi.meet.sdk;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
@@ -35,7 +36,7 @@ public class JitsiMeetView extends FrameLayout {
/**
* Background color. Should match the background color set in JS.
*/
private static final int BACKGROUND_COLOR = 0xFF040404;
public static final int BACKGROUND_COLOR = 0xFF040404;
/**
* React Native root view.
@@ -196,8 +197,6 @@ public class JitsiMeetView extends FrameLayout {
}
setBackgroundColor(BACKGROUND_COLOR);
ReactInstanceManagerHolder.initReactInstanceManager((Activity) context);
}
/**

View File

@@ -17,7 +17,7 @@
package org.jitsi.meet.sdk;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import androidx.annotation.Nullable;
@@ -64,7 +64,6 @@ class ReactInstanceManagerHolder {
new AudioModeModule(reactContext),
new DropboxModule(reactContext),
new ExternalAPIModule(reactContext),
new JavaScriptSandboxModule(reactContext),
new LocaleDetector(reactContext),
new LogBridgeModule(reactContext),
new PictureInPictureModule(reactContext),
@@ -109,6 +108,7 @@ class ReactInstanceManagerHolder {
new com.horcrux.svg.SvgPackage(),
new org.wonday.orientation.OrientationPackage(),
new com.splashview.SplashViewPackage(),
new com.worklets.WorkletsCorePackage(),
new ReactPackageAdapter() {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
@@ -207,9 +207,9 @@ class ReactInstanceManagerHolder {
* time. All {@code ReactRootView} instances will be tied to the one and
* only {@code ReactInstanceManager}.
*
* @param activity {@code Activity} current running Activity.
* @param app {@code Application}
*/
static void initReactInstanceManager(Activity activity) {
static void initReactInstanceManager(Application app) {
if (reactInstanceManager != null) {
return;
}
@@ -231,14 +231,14 @@ class ReactInstanceManagerHolder {
reactInstanceManager
= ReactInstanceManager.builder()
.setApplication(activity.getApplication())
.setCurrentActivity(activity)
.setApplication(app)
.setCurrentActivity(null)
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index.android")
.setJavaScriptExecutorFactory(new HermesExecutorFactory())
.addPackages(getReactNativePackages())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.RESUMED)
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE)
.build();
}
}

View File

@@ -52,3 +52,5 @@ include ':react-native-webrtc'
project(':react-native-webrtc').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webrtc/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-worklets-core'
project(':react-native-worklets-core').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-worklets-core/android')

View File

@@ -8,9 +8,13 @@ module.exports = {
// This happens because react native has conflict with @babel/plugin-transform-private-methods plugin
// https://github.com/ethers-io/ethers.js/discussions/4309#discussioncomment-6694524
plugins: [ 'optional-require',
[ '@babel/plugin-transform-private-methods', {
'loose': true
} ]
plugins: [
'optional-require',
[
'@babel/plugin-transform-private-methods', {
'loose': true
}
],
'react-native-worklets-core/plugin'
]
};

View File

@@ -50,7 +50,8 @@ import {
commonUserJoinedHandling,
commonUserLeftHandling,
getConferenceOptions,
sendLocalParticipant
sendLocalParticipant,
updateTrackMuteState
} from './react/features/base/conference/functions';
import { getReplaceParticipant, getSsrcRewritingFeatureFlag } from './react/features/base/config/functions';
import { connect } from './react/features/base/connection/actions.web';
@@ -133,6 +134,7 @@ import {
isLocalTrackMuted,
isUserInteractionRequiredForUnmute
} from './react/features/base/tracks/functions';
import { getLocalJitsiAudioTrackSettings } from './react/features/base/tracks/functions.web';
import { downloadJSON } from './react/features/base/util/downloadJSON';
import { getJitsiMeetGlobalNSConnectionTimes } from './react/features/base/util/helpers';
import { openLeaveReasonDialog } from './react/features/conference/actions.web';
@@ -157,13 +159,14 @@ import { disableReceiver, stopReceiver } from './react/features/remote-control/a
import { setScreenAudioShareState } from './react/features/screen-share/actions.web';
import { isScreenAudioShared } from './react/features/screen-share/functions';
import { toggleScreenshotCaptureSummary } from './react/features/screenshot-capture/actions';
import { setAudioSettings } from './react/features/settings/actions.web';
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
import { createRnnoiseProcessor } from './react/features/stream-effects/rnnoise';
import { handleToggleVideoMuted } from './react/features/toolbox/actions.any';
import { transcriberJoined, transcriberLeft } from './react/features/transcribing/actions';
import { muteLocal } from './react/features/video-menu/actions.any';
const logger = Logger.getLogger(__filename);
const logger = Logger.getLogger('app:conference-web');
let room;
/*
@@ -565,7 +568,15 @@ export default {
if (browser.isWebKitBased()) {
this.muteAudio(true, true);
} else {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
localTracks = localTracks.filter(track => {
if (track.getType() === MEDIA_TYPE.AUDIO) {
track.stopStream();
return false;
}
return true;
});
}
}
@@ -1663,8 +1674,12 @@ export default {
room.on(
JitsiConferenceEvents.START_MUTED_POLICY_CHANGED,
({ audio, video }) => {
APP.store.dispatch(
onStartMutedPolicyChanged(audio, video));
APP.store.dispatch(onStartMutedPolicyChanged(audio, video));
const state = APP.store.getState();
updateTrackMuteState(state, APP.store.dispatch, true);
updateTrackMuteState(state, APP.store.dispatch, false);
}
);
@@ -1758,7 +1773,11 @@ export default {
return this.useAudioStream(stream);
})
.then(() => {
const localAudio = getLocalJitsiAudioTrack(APP.store.getState());
const state = APP.store.getState();
const localAudio = getLocalJitsiAudioTrack(state);
const settings = getLocalJitsiAudioTrackSettings(state);
APP.store.dispatch(setAudioSettings(settings));
if (localAudio && isDefaultMicSelected) {
// workaround for the default device to be shown as selected in the

View File

@@ -363,6 +363,7 @@ var config = {
// Desktop sharing
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
// Setting higher min/max values will affect the resolution, it makes it worse.
// desktopSharingFrameRate: {
// min: 5,
// max: 5,
@@ -761,7 +762,7 @@ var config = {
// hideDominantSpeakerBadge: false,
// Default language for the user interface. Cannot be overwritten.
// DEPRECATED! Use the `lang` iframe option directly instead.
// For iframe integrations, use the `lang` option directly instead.
// defaultLanguage: 'en',
// Disables profile and the edit of all fields from the profile settings (display name and email)
@@ -791,7 +792,6 @@ var config = {
// Configs for prejoin page.
// prejoinConfig: {
// // When 'true', it shows an intermediate page before joining, where the user can configure their devices.
// // This replaces `prejoinPageEnabled`. Defaults to true.
// enabled: true,
// // Hides the participant name editing field in the prejoin screen.
// // If requireDisplayName is also set as true, a name should still be provided through
@@ -1363,7 +1363,9 @@ var config = {
// disableGrantModerator: true,
// // If set to 'all' the 'Private chat' button will be disabled for all participants.
// // If set to 'allow-moderator-chat' the 'Private chat' button will be available for chats with moderators.
// disablePrivateChat: 'all' | 'allow-moderator-chat',
// // If set to 'disable-visitor-chat' the 'Private chat' button will be disabled for visitor-main participant
// // conversations.
// disablePrivateChat: 'all' | 'allow-moderator-chat' | 'disable-visitor-chat',
// },

View File

@@ -90,7 +90,7 @@ $welcomePageHeaderContainerMargin: $welcomePageHeaderContainerMarginTop auto 0;
$welcomePageHeaderTextTitleMarginBottom: 0;
$welcomePageHeaderTextTitleFontSize: 2.625rem;
$welcomePageHeaderTextTitleFontWeight: normal;
$welcomePageHeaderTextTitleLineHeight: 50px;
$welcomePageHeaderTextTitleLineHeight: 3.125rem;
$welcomePageHeaderTextTitleOpacity: 1;
$welcomePageEnterRoomDisplay: flex;

16
giphy-analytics-stub.js Normal file
View File

@@ -0,0 +1,16 @@
// Stub replacement for @giphy/js-analytics to prevent beforeunload handlers
// This completely disables all Giphy analytics functionality
export const pingback = () => {
// Completely disabled - do nothing
};
export const mergeAttributes = (attributes, newAttributes) => {
// Return merged attributes without any analytics calls
return { ...attributes,
...newAttributes };
};
// Ensure no beforeunload handlers are ever registered
export default pingback;

View File

@@ -64,11 +64,11 @@ PODS:
- GoogleUtilities/UserDefaults (~> 7.7)
- PromisesObjC (< 3.0, >= 1.2)
- fmt (11.0.2)
- Giphy (2.2.13):
- Giphy (2.2.16):
- libwebp
- giphy-react-native-sdk (3.3.1):
- giphy-react-native-sdk (4.1.0):
- DoubleConversion
- Giphy (= 2.2.13)
- Giphy (= 2.2.16)
- glog
- hermes-engine
- RCT-Folly (= 2024.11.18.00)
@@ -1382,9 +1382,9 @@ PODS:
- React-Core
- react-native-netinfo (11.1.0):
- React-Core
- react-native-orientation-locker (1.6.0):
- react-native-orientation-locker (1.5.0):
- React-Core
- react-native-pager-view (6.4.1):
- react-native-pager-view (6.8.1):
- DoubleConversion
- glog
- hermes-engine
@@ -1407,7 +1407,7 @@ PODS:
- Yoga
- react-native-performance (5.1.2):
- React-Core
- react-native-safe-area-context (5.4.0):
- react-native-safe-area-context (5.5.2):
- React-Core
- react-native-slider (4.5.6):
- DoubleConversion
@@ -1497,6 +1497,27 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-worklets-core (1.6.2):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.11.18.00)
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-ImageManager
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- React-nativeconfig (0.77.2)
- React-NativeModulesApple (0.77.2):
- glog
@@ -1794,7 +1815,7 @@ PODS:
- React-Core
- RNDefaultPreference (1.4.4):
- React-Core
- RNDeviceInfo (10.9.0):
- RNDeviceInfo (12.1.0):
- React-Core
- RNGestureHandler (2.24.0):
- DoubleConversion
@@ -1932,6 +1953,7 @@ DEPENDENCIES:
- react-native-video (from `../node_modules/react-native-video`)
- react-native-webrtc (from `../node_modules/react-native-webrtc`)
- react-native-webview (from `../node_modules/react-native-webview`)
- react-native-worklets-core (from `../node_modules/react-native-worklets-core`)
- React-nativeconfig (from `../node_modules/react-native/ReactCommon`)
- React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`)
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
@@ -2101,6 +2123,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-webrtc"
react-native-webview:
:path: "../node_modules/react-native-webview"
react-native-worklets-core:
:path: "../node_modules/react-native-worklets-core"
React-nativeconfig:
:path: "../node_modules/react-native/ReactCommon"
React-NativeModulesApple:
@@ -2201,8 +2225,8 @@ SPEC CHECKSUMS:
FirebaseCrashlytics: feb07e4e9187be3c23c6a846cce4824e5ce2dd0b
FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd
fmt: a40bb5bd0294ea969aaaba240a927bd33d878cdd
Giphy: a11dd02b51ac2ec37b881de1717ebf2cc8e9df62
giphy-react-native-sdk: 678a115ea5a47a43d39d1b61703e0d08b1e48917
Giphy: 55914215541027873875757f350530e6d8986fba
giphy-react-native-sdk: 733177b2537b527cfa55979c396cc1f2046eb457
glog: eb93e2f488219332457c3c4eafd2738ddc7e80b8
GoogleAppMeasurement: 4c19f031220c72464d460c9daa1fb5d1acce958e
GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
@@ -2249,14 +2273,15 @@ SPEC CHECKSUMS:
react-native-get-random-values: d16467cf726c618e9c7a8c3c39c31faa2244bbba
react-native-keep-awake: 03b74eebe4f2bb5e8478fc8f420651a92463b6f8
react-native-netinfo: 5364263f903da576bdef9c84a76fe243ab06812c
react-native-orientation-locker: ee8bb2177365ca74f51dc1e11218fe544634d523
react-native-pager-view: 68e8a65a607a6f91a1e25865002192c3c4f53fcf
react-native-orientation-locker: dbd3f6ddbe9e62389cb0807dc2af63f6c36dec36
react-native-pager-view: 11662c698c8f11d39e05891316d2a144fa00adc4
react-native-performance: 125a96c145e29918b55b45ce25cbba54f1e24dcd
react-native-safe-area-context: 9d72abf6d8473da73033b597090a80b709c0b2f1
react-native-safe-area-context: 0f7bf11598f9a61b7ceac8dc3f59ef98697e99e1
react-native-slider: 1205801a8d29b28cacc14eef08cb120015cdafcb
react-native-video: eb861d67a71dfef1bbf6086a811af5f338b13781
react-native-webrtc: 2261a482150195092246fe70b3aff976f2e11ec5
react-native-webview: 079eca50edf657503318b66687dadfb903731aa8
react-native-worklets-core: b59cf88762c8fb6132d8796babd4cec15217d6f0
React-nativeconfig: ecf4dc92c40b97e2b3f0c619938f78bfd6507b08
React-NativeModulesApple: f457bbfb30fb3bc41979b1a87b99d292d7340d39
React-perflogger: 1111b5feb064c4cc83df88fb403efda54b387951
@@ -2290,7 +2315,7 @@ SPEC CHECKSUMS:
RNCAsyncStorage: aa75595c1aefa18f868452091fa0c411a516ce11
RNCClipboard: 7c3e3b5f71d84ef61690ad377b6c50cf27864ff5
RNDefaultPreference: ee13d69e6693d193cd223d10e15e5b3c012d31ba
RNDeviceInfo: 8af23685571b7867d8dc15fb89e7fb5fa8607e1e
RNDeviceInfo: 723e97dd98af9b7913477e7a40252c15517c258c
RNGestureHandler: 9f3109e11ed88fe5bed280bf7762b25e4c52f396
RNGoogleSignin: 30e1aee80140dc0706cd78a4951c411376c88329
RNScreens: 9ef996b6041d0960a4794a845f7d0808b171b4ef

View File

@@ -30,6 +30,14 @@
<string>35F9.1</string>
</array>
</dict>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryDiskSpace</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>85F4.1</string>
</array>
</dict>
</array>
<key>NSPrivacyCollectedDataTypes</key>
<array/>

View File

@@ -51,7 +51,6 @@
C81E9AB925AC5AD800B134D9 /* ExternalAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */; };
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
C8AFD2802462C613000293D2 /* InfoPlistUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */; };
DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AAC92317FFCD00290BEC /* LogUtils.h */; };
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */; };
DE762DB422AFDE76000DEBD6 /* JitsiMeetUserInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DE762DB322AFDE76000DEBD6 /* JitsiMeetUserInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -98,7 +97,6 @@
DE9A015C289A9A9A00E41CBB /* JitsiMeetLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = DE81A2D32316AC4D00AE1940 /* JitsiMeetLogger.m */; };
DE9A015E289A9A9A00E41CBB /* JitsiMeetView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */; };
DE9A015F289A9A9A00E41CBB /* JitsiMeet.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFE535321FB1BF800011A3A /* JitsiMeet.m */; };
DE9A0160289A9A9A00E41CBB /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
DE9A0162289A9A9A00E41CBB /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB9AD781F5EC6D7001C08DB /* Intents.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
DE9A0163289A9A9A00E41CBB /* CallKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB9AD761F5EC6CE001C08DB /* CallKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
DE9A0166289A9A9A00E41CBB /* CallKitIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 0BC4B8681F8C01E100CE8B21 /* CallKitIcon.png */; };
@@ -161,7 +159,6 @@
C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExternalAPI.h; sourceTree = "<group>"; };
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
DE438CD82350934700DD541D /* JavaScriptSandbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JavaScriptSandbox.m; sourceTree = "<group>"; };
DE65AAC92317FFCD00290BEC /* LogUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LogUtils.h; sourceTree = "<group>"; };
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetBaseLogHandler+Private.h"; sourceTree = "<group>"; };
DE762DB322AFDE76000DEBD6 /* JitsiMeetUserInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetUserInfo.h; sourceTree = "<group>"; };
@@ -250,7 +247,6 @@
C69EFA02209A0EFD0027712B /* callkit */,
A4A934E7212F3AB8001E9388 /* dropbox */,
0BD906E91EC0C00300C8C18E /* Info.plist */,
DE438CD82350934700DD541D /* JavaScriptSandbox.m */,
0BD906E81EC0C00300C8C18E /* JitsiMeet.h */,
DEFE535821FB311F00011A3A /* JitsiMeet+Private.h */,
DEA9F283258A5D9900D4CD74 /* JitsiMeetSDK.h */,
@@ -681,7 +677,6 @@
DE81A2D52316AC4D00AE1940 /* JitsiMeetLogger.m in Sources */,
0B412F191EDEC65D00B1A0A6 /* JitsiMeetView.m in Sources */,
DEFE535421FB1BF800011A3A /* JitsiMeet.m in Sources */,
DE438CDA2350934700DD541D /* JavaScriptSandbox.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -714,7 +709,6 @@
4E0EF63328CA2FB3005D1B03 /* JMCallKitEmitter.m in Sources */,
DE9A015E289A9A9A00E41CBB /* JitsiMeetView.m in Sources */,
DE9A015F289A9A9A00E41CBB /* JitsiMeet.m in Sources */,
DE9A0160289A9A9A00E41CBB /* JavaScriptSandbox.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@@ -1,55 +0,0 @@
/*
* Copyright @ 2019-present 8x8, Inc.
*
* 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 JavaScriptCore;
#import <React/RCTBridgeModule.h>
@interface JavaScriptSandbox : NSObject<RCTBridgeModule>
@end
@implementation JavaScriptSandbox
RCT_EXPORT_MODULE();
+ (BOOL)requiresMainQueueSetup {
return NO;
}
#pragma mark - Exported methods
RCT_EXPORT_METHOD(evaluate:(NSString *)code
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
__block BOOL hasError = NO;
JSContext *ctx = [[JSContext alloc] init];
ctx.exceptionHandler = ^(JSContext *context, JSValue *exception) {
hasError = YES;
reject(@"evaluate", [exception toString], nil);
};
JSValue *ret = [ctx evaluateScript:code];
if (!hasError) {
NSString *result = [ret toString];
if (result == nil) {
reject(@"evaluate", @"Error in string coercion", nil);
} else {
resolve(result);
}
}
}
@end

View File

@@ -112,7 +112,9 @@
"disabled": "L'invio di messaggi in chat è disabilitato.",
"enter": "Entra nella conversazione",
"error": "Errore: il tuo messaggio non è stato inviato. Motivo: {{error}}",
"everyone": "Tutti",
"fieldPlaceHolder": "Scrivi qui il tuo messaggio",
"guestsChatIndicator": "(ospite)",
"lobbyChatMessageTo": "Messaggio a {{recipient}} in sala d'attesa",
"message": "Messaggio",
"messageAccessibleTitle": "{{user}} dice:",
@@ -154,7 +156,7 @@
"installExtensionText": "Installa un'estensione per integrare Google Calendar e Office 365"
},
"closedCaptionsTab": {
"emptyState": "Il contenuto dei sottotitoli sarà disponibile una volta che l'organizzatore lo attiva",
"emptyState": "Il contenuto dei sottotitoli sarà disponibile una volta che l'organizzatore lo attiverà",
"startClosedCaptionsButton": "Attiva sottotitoli"
},
"connectingOverlay": {
@@ -300,6 +302,12 @@
"alreadySharedVideoTitle": "È permessa una sola condivisione video alla volta",
"applicationWindow": "Finestra dell'applicazione",
"authenticationRequired": "Richiesta autenticazione",
"cameraCaptureDialog": {
"description": "Scatta ed invia una foto usando la fotocamera del telefono",
"ok": "Apri la fotocamera",
"reject": "Non adesso",
"title": "Scatta una foto"
},
"cameraConstraintFailedError": "La tua videocamera non soddisfa alcuni dei requisiti.",
"cameraNotFoundError": "Videocamera non trovata.",
"cameraNotSendingData": "Impossibile accedere alla videocamera. Controlla che non sia in uso in un'altra applicazione, seleziona un altro dispositivo dalle impostazioni o prova a ricaricare l'applicazione.",
@@ -323,7 +331,7 @@
"contactSupport": "Contatta il supporto",
"copied": "Copiato",
"copy": "Copia",
"demoteParticipantDialog": "Sei sicuro di voler far diventare questo partecipante uno spettatore?",
"demoteParticipantDialog": "Vuoi far diventare questo partecipante uno spettatore?",
"demoteParticipantTitle": "Fai diventare spettatore",
"dismiss": "Scarta",
"displayNameRequired": "Ciao, qual è il tuo nome?",
@@ -338,8 +346,8 @@
"error": "Errore",
"errorRoomCreationRestriction": "Hai provato ad accedere alla riunione troppo presto, torna tra un po'.",
"gracefulShutdown": "Il nostro servizio è al momento inattivo per manutenzione. Si prega di riprovare più tardi.",
"grantModeratorDialog": "Sei sicuro di voler rendere organizzatore questo partecipante?",
"grantModeratorTitle": "Fai diventare organizzatore",
"grantModeratorDialog": "Vuoi rendere relatore questo partecipante?",
"grantModeratorTitle": "Fai diventare relatore",
"hide": "Nascondi",
"hideShareAudioHelper": "Non mostrare più questa finestra",
"incorrectPassword": "Nome utente o password errati",
@@ -348,7 +356,7 @@
"internalErrorTitle": "Errore interno",
"kickMessage": "Puoi contattare {{participantDisplayName}} per maggiori dettagli.",
"kickParticipantButton": "Espelli",
"kickParticipantDialog": "Sei sicuro di voler espellere questo partecipante?",
"kickParticipantDialog": "Vuoi espellere questo partecipante?",
"kickParticipantTitle": "Espellere questo partecipante?",
"kickSystemTitle": "Oh! Sei stato espulso dalla riunione",
"kickTitle": "Oh! {{participantDisplayName}} ti ha espulso dalla riunione.",
@@ -362,8 +370,8 @@
"lockRoom": "Aggiungi una $t(lockRoomPassword) alla riunione",
"lockTitle": "Blocco fallito",
"login": "Accesso",
"loginQuestion": "Sei sicuro di voler fare l'accesso e abbandonare la riunione?",
"logoutQuestion": "Sei sicuro di volerti disconnettere e abbandonare la riunione?",
"loginQuestion": "Vuoi fare l'accesso e abbandonare la riunione?",
"logoutQuestion": "Vuoi disconnetterti e abbandonare la riunione?",
"logoutTitle": "Disconnessione",
"maxUsersLimitReached": "È stato raggiunto il numero massimo di partecipanti. La riunione è al completo. Contatta l'organizzatore o riprova più tardi!",
"maxUsersLimitReachedTitle": "Raggiunto limite massimo partecipanti",
@@ -375,27 +383,39 @@
"micTimeoutError": "Impossibile avviare la sorgente audio. Tempo di attesa scaduto.",
"micUnknownError": "Impossibile usare il microfono per un motivo sconosciuto.",
"moderationAudioLabel": "Consenti ai partecipanti di attivare il microfono",
"moderationDesktopLabel": "Consenti ai partecipanti di condividere lo schermo",
"moderationVideoLabel": "Consenti ai partecipanti di attivare la videocamera",
"muteEveryoneDialog": "I partecipanti possono attivare il microfono in qualsiasi momento.",
"muteEveryoneDialogModerationOn": "I partecipanti possono chiedere di parlare in qualsiasi momento.",
"muteEveryoneElseDialog": "Una volta spenti i microfoni non potrai riattivarli, ma ogni partecipante potrà farlo da sé in qualsiasi momento.",
"muteEveryoneElseTitle": "Spegnere il microfono a tutti, tranne che a {{whom}}?",
"muteEveryoneElsesDesktopDialog": "Una volta interrotta la condivisione dello schermo non potrai riattivarla, ma ogni partecipante potrà farlo da sé in qualsiasi momento.",
"muteEveryoneElsesDesktopTitle": "Interrompere la condivisione dello schermo a tutti, tranne che a {{whom}}?",
"muteEveryoneElsesVideoDialog": "Una volta spente le videocamere non potrai riaccenderle, ma ogni partecipante potrà farlo da sé in qualsiasi momento.",
"muteEveryoneElsesVideoTitle": "Spegnere la videocamera a tutti, tranne che a {{whom}}?",
"muteEveryoneSelf": "tu",
"muteEveryoneStartMuted": "Tutti iniziano a microfono spento da adesso in avanti",
"muteEveryoneTitle": "Spegnere il microfono a tutti?",
"muteEveryonesDesktopDialog": "I partecipanti potranno condividere lo schermo in qualsiasi momento.",
"muteEveryonesDesktopDialogModerationOn": "I partecipanti possono inviare una richiesta per condividere lo schermo in ogni momento.",
"muteEveryonesDesktopTitle": "Interrompere la condivisione dello schermo a tutti?",
"muteEveryonesVideoDialog": "Ogni partecipante potrà riavviare il video da sé in qualsiasi momento.",
"muteEveryonesVideoDialogModerationOn": "I partecipanti possono chiedere di attivare il video in qualsiasi momento.",
"muteEveryonesVideoDialogOk": "Spegni",
"muteEveryonesVideoTitle": "Spegnere la videocamera a tutti?",
"muteParticipantBody": "Non potrai riattivare il loro microfono, ma loro potranno farlo in qualsiasi momento.",
"muteParticipantButton": "Silenzia",
"muteParticipantsDesktopBody": "Non potrai riavviare la loro condivisione dello schermo, ma loro potranno farlo in qualsiasi momento.",
"muteParticipantsDesktopBodyModerationOn": "Non potrai riavviare la loro condivisione dello schermo e nemmeno loro potranno.",
"muteParticipantsDesktopButton": "Interrompi la condivisione dello schermo",
"muteParticipantsDesktopDialog": "Vuoi interrompere la condivisione dello schermo di questo partecipante? Non potrai riattivarla, ma lui potrà farlo in qualsiasi momento.",
"muteParticipantsDesktopDialogModerationOn": "Vuoi interrompere la condivisione dello schermo di questo partecipante? Non potrai riattivarla e nemmeno loro potranno.",
"muteParticipantsDesktopTitle": "Disattivare la condivisione dello schermo di questo partecipante?",
"muteParticipantsVideoBody": "Non potrai riattivare le videocamere, ma loro potranno farlo in qualsiasi momento.",
"muteParticipantsVideoBodyModerationOn": "Non potrai riattivare le videocamere e nemmeno loro potranno.",
"muteParticipantsVideoButton": "Spegni videocamere",
"muteParticipantsVideoDialog": "Sei sicuro di voler spegnere la videocamera di questo partecipante? Non potrai riattivarla, ma lui potrà farlo in qualsiasi momento.",
"muteParticipantsVideoDialogModerationOn": "Sei sicuro di voler spegnere la videocamera di questo partecipante? Non potrai riattivarla e nemmeno lui potrà farlo.",
"muteParticipantsVideoDialog": "Vuoi spegnere la videocamera di questo partecipante? Non potrai riattivarla, ma lui potrà farlo in qualsiasi momento.",
"muteParticipantsVideoDialogModerationOn": "Vuoi spegnere la videocamera di questo partecipante? Non potrai riattivarla e nemmeno lui potrà farlo.",
"muteParticipantsVideoTitle": "Spegnere la videocamera di questo partecipante?",
"noDropboxToken": "Token Dropbox non valido",
"password": "Password",
@@ -424,7 +444,7 @@
"remoteControlTitle": "Connessione desktop remoto",
"remoteUserControls": "Controlli dell'utente remoto {{username}}",
"removePassword": "Rimuovi la $t(lockRoomPassword)",
"removeSharedVideoMsg": "Sei sicuro di voler rimuovere il tuo video condiviso?",
"removeSharedVideoMsg": "Vuoi rimuovere il tuo video condiviso?",
"removeSharedVideoTitle": "Rimuovi video condiviso",
"renameBreakoutRoomLabel": "Nome della stanza",
"renameBreakoutRoomTitle": "Rinomina stanza",
@@ -477,8 +497,8 @@
"startRemoteControlErrorMessage": "Si è verificato un errore nel tentativo di avviare la sessione di controllo remoto!",
"stopLiveStreaming": "Ferma la diretta",
"stopRecording": "Ferma registrazione",
"stopRecordingWarning": "Sei sicuro di voler interrompere la registrazione?",
"stopStreamingWarning": "Sei sicuro di voler interrompere la diretta?",
"stopRecordingWarning": "Vuoi interrompere la registrazione?",
"stopStreamingWarning": "Vuoi interrompere la diretta?",
"streamKey": "Chiave della diretta",
"thankYou": "Grazie per aver usato {{appName}}!",
"token": "token",
@@ -547,11 +567,15 @@
"downloadFailedDescription": "Si prega di riprovare.",
"downloadFailedTitle": "Download non riuscito",
"downloadFile": "Download",
"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.",
"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",
"removeFile": "Rimuovi",
"removeFileSuccess": "File rimosso con successo",
"uploadFailedDescription": "Si prega di riprovare.",
"uploadFailedTitle": "Caricamento non riuscito",
"uploadFile": "Condividi file"
@@ -683,7 +707,7 @@
"signInCTA": "Accedi o inserisci la tua chiave della diretta su YouTube.",
"signOut": "Disconnetti",
"signedInAs": "Hai effettuato l'accesso come:",
"start": "Inizia una diretta",
"start": "Avvia una diretta",
"streamIdHelp": "Cos'è questo?",
"title": "Diretta",
"unavailableTitle": "La diretta non è disponibile",
@@ -744,9 +768,9 @@
"engaged": "Registrazione avviata.",
"finished": "La registrazione della sessione {{token}} è terminata. Invia il file della registrazione all'organizzatore.",
"finishedModerator": "La registrazione della sessione {{token}} è terminata. La registrazione della traccia è stata salvata. Chiedi ai partecipanti di inviare le loro registrazioni.",
"notModerator": "Non sei un organizzatore. Non puoi avviare o interrompere la registrazione."
"notModerator": "Non sei un relatore. Non puoi avviare o interrompere la registrazione."
},
"moderator": "Organizzatore",
"moderator": "Relatore",
"no": "No",
"participant": "Partecipante",
"participantStats": "Statistiche partecipante",
@@ -767,8 +791,9 @@
"me": "io",
"notify": {
"OldElectronAPPTitle": "Falla di sicurezza!",
"allowAll": "Consenti tutto",
"allowAudio": "Consenti l'audio",
"allowBoth": "Entrambi",
"allowDesktop": "Consenti la condivisione dello schermo",
"allowVideo": "Consenti il video",
"allowedUnmute": "Puoi accendere il microfono, avviare la videocamera o condividere il tuo schermo.",
"audioUnmuteBlockedDescription": "L'accensione dei microfoni è stata temporaneamente bloccata per i limiti del sistema.",
@@ -782,6 +807,7 @@
"dataChannelClosedDescription": "Il canale bridge è inattivo, quindi la qualità video potrebbe essere limitata all'impostazione più bassa.",
"dataChannelClosedDescriptionWithAudio": "Il canale bridge è inattivo, quindi potrebbero esserci interruzioni di audio e video",
"dataChannelClosedWithAudio": "La qualità audio e video potrebbe essere scarsa",
"desktopMutedRemotelyTitle": "La tua condivisione dello schermo è stata interrotta da {{participantDisplayName}}",
"disabledIframe": "L'incorporamento serve solo come dimostrazione, quindi questa chiamata si disconnetterà tra {{timeout}} minuti.",
"disabledIframeSecondaryNative": "L'incorporamento {{domain}} serve solo come dimostrazione, quindi questa chiamata si disconnetterà tra {{timeout}} minuti.",
"disabledIframeSecondaryWeb": "L'incorporamento {{domain}} serve solo come dimostrazione, quindi questa chiamata si disconnetterà tra {{timeout}} minuti. Si prega di usare <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> per la produzione di riunioni incorporate!",
@@ -792,7 +818,7 @@
"focusFail": "{{component}} non disponibile - nuovo tentativo tra {{ms}} sec",
"gifsMenu": "GIPHY",
"groupTitle": "Notifiche",
"hostAskedUnmute": "L'organizzatore ti chiede di intervenire.",
"hostAskedUnmute": "Il relatore ti chiede di intervenire.",
"invalidTenant": "Nome non valido",
"invalidTenantHyphenDescription": "Il nome che hai scelto non è valido (inizia o finisce con '-').",
"invalidTenantLengthDescription": "Il nome che hai scelto è troppo lungo.",
@@ -814,17 +840,17 @@
"localRecordingStopped": "{{name}} ha smesso di registrare.",
"me": "Io",
"moderationInEffectCSDescription": "Alza la mano, se vuoi condividere lo schermo.",
"moderationInEffectCSTitle": "La condivisione schermo è stata bloccata dall'organizzatore",
"moderationInEffectCSTitle": "La condivisione schermo è stata bloccata dal relatore",
"moderationInEffectDescription": "Alza la mano, se vuoi prendere la parola.",
"moderationInEffectTitle": "Il tuo microfono è stato spento dall'organizzatore",
"moderationInEffectTitle": "Il tuo microfono è stato spento dal relatore",
"moderationInEffectVideoDescription": "Alza la mano, se vuoi avviare la tua videocamera.",
"moderationInEffectVideoTitle": "La tua videocamera è stata spenta dall'organizzatore",
"moderationRequestFromModerator": "L'organizzatore vorrebbe che tu accendessi il microfono",
"moderationInEffectVideoTitle": "La tua videocamera è stata spenta dal relatore",
"moderationRequestFromModerator": "Il relatore vorrebbe che tu accendessi il microfono",
"moderationRequestFromParticipant": "Vuole parlare",
"moderationStartedTitle": "Moderazione in corso",
"moderationStoppedTitle": "Moderazione interrotta",
"moderationToggleDescription": "da {{participantDisplayName}}",
"moderator": "Ora sei un organizzatore!",
"moderator": "Ora sei un relatore!",
"muted": "Hai iniziato la conversazione con il microfono disattivato.",
"mutedRemotelyDescription": "Puoi sempre attivare il microfono quando vuoi parlare. Spegni il microfono quando hai finito, per evitare rumori di fondo nella riunione.",
"mutedRemotelyTitle": "{{participantDisplayName}} ti ha spento il microfono",
@@ -839,6 +865,7 @@
"oldElectronClientDescription1": "Sembra che tu stia usando una versione obsoleta del client Jitsi Meet, che ha vulnerabilità note. Assicurati di aggiornarlo alla nostra ",
"oldElectronClientDescription2": "ultima versione",
"oldElectronClientDescription3": " ora!",
"openChat": "Apri chat",
"participantWantsToJoin": "Vuole unirsi alla riunione",
"participantsWantToJoin": "Vogliono unirsi alla riunione",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) è stata rimossa da un altro partecipante",
@@ -862,6 +889,7 @@
"suggestRecordingDescription": "Vuoi avviare la registrazione?",
"suggestRecordingTitle": "Registra questa riunione",
"unmute": "Accendi il microfono",
"unmuteScreen": "Iniziata la condivisione dello schermo",
"unmuteVideo": "Accendi la videocamera",
"videoMutedRemotelyDescription": "Puoi riaccenderla in qualsiasi momento.",
"videoMutedRemotelyTitle": "{{participantDisplayName}} ti ha spento la videocamera",
@@ -881,11 +909,14 @@
"admit": "Ammetti",
"admitAll": "Ammetti tutti",
"allow": "Permetti ai partecipanti di:",
"allowDesktop": "Consenti la condivisione dello schermo",
"allowVideo": "Permetti videocamere",
"askDesktop": "Chiedi di condividere lo schermo",
"askUnmute": "Chiedi di accendere il microfono",
"audioModeration": "Riattivare il microfono",
"blockEveryoneMicCamera": "Blocca microfono e videocamera a tutti",
"breakoutRooms": "Stanze",
"desktopModeration": "Avvia la condivisione dello schermo",
"goLive": "Vai alla diretta",
"invite": "Invita partecipanti",
"lowerAllHands": "Abbassa tutte le mani",
@@ -897,6 +928,8 @@
"muteAll": "Silenzia tutti",
"muteEveryoneElse": "Silenzia tutti gli altri",
"reject": "Respingi",
"stopDesktop": "Interrompi la condivisione dello schermo",
"stopEveryonesDesktop": "Interrompi la condivisione dello schermo agli altri",
"stopEveryonesVideo": "Ferma il video di tutti",
"stopVideo": "Ferma il video",
"unblockEveryoneMicCamera": "Sblocca microfono e videocamera a tutti",
@@ -906,6 +939,7 @@
"headings": {
"lobby": "Sala d'attesa ({{count}})",
"participantsList": "Partecipanti alla riunione ({{count}})",
"viewerRequests": "Richieste spettatori ({{count}})",
"visitorInQueue": " ({{count}} in attesa)",
"visitorRequests": " ({{count}} richiesta/e)",
"visitors": "Spettatori {{count}}",
@@ -1073,7 +1107,7 @@
"fileSharingdescription": "Condividi la registrazione con i partecipanti alla riunione",
"highlight": "Evidenzia",
"highlightMoment": "Evidenzia momento",
"highlightMomentDisabled": "Puoi evidenziare dei momenti quando inizia la registrazione",
"highlightMomentDisabled": "Puoi evidenziare i momenti in cui inizia la registrazione",
"highlightMomentSuccess": "Momento evidenziato",
"highlightMomentSucessDescription": "Il tuo momento evidenziato sarà aggiunto al riepilogo della riunione.",
"inProgress": "Registrazione o diretta in corso",
@@ -1084,7 +1118,7 @@
"localRecordingNoVideo": "Il video non sta venendo registrato",
"localRecordingStartWarning": "Assicurati di interrompere la registrazione prima di uscire dalla riunione, altrimenti la registrazione non verrà salvata.",
"localRecordingStartWarningTitle": "Interrompi la registrazione per salvarla",
"localRecordingVideoStop": "Interrompere il video fermerà anche la registrazione. Sei sicuro di voler continuare?",
"localRecordingVideoStop": "Interrompere il video fermerà anche la registrazione. Vuoi continuare?",
"localRecordingVideoWarning": "Per registrare il video, deve essere già avviato prima dell'inizio della registrazione",
"localRecordingWarning": "Assicurati di aver selezionato la scheda corrente, per registrare gli audio e video corretti.",
"loggedIn": "Accesso effettuato come {{userName}}",
@@ -1153,8 +1187,8 @@
"loggedIn": "Connesso come {{name}}",
"maxStageParticipants": "Numero massimo di partecipanti che possono essere messi in evidenza nella schermata principale",
"microphones": "Microfoni",
"moderator": "Organizzatore",
"moderatorOptions": "Opzioni organizzatore",
"moderator": "Relatore",
"moderatorOptions": "Opzioni relatore",
"more": "Generali",
"name": "Nome",
"noDevice": "Nessuno",
@@ -1190,7 +1224,7 @@
"conferenceSection": "Riunione",
"disableCallIntegration": "Disattiva l'integrazione nativa delle chiamate",
"disableCrashReporting": "Disattiva la diagnostica dei crash",
"disableCrashReportingWarning": "Sei sicuro di voler disattivare la diagnostica dei crash? Quest'impostazione verrà applicata al prossimo avvio dell'app.",
"disableCrashReportingWarning": "Vuoi disattivare la diagnostica dei crash? Quest'impostazione verrà applicata al prossimo avvio dell'app.",
"disableP2P": "Disattiva la modalità Peer-to-Peer",
"displayName": "Nome visualizzato",
"displayNamePlaceholderText": "Es: Mario Rossi",
@@ -1207,8 +1241,8 @@
"serverURL": "URL del server",
"showAdvanced": "Mostra impostazioni avanzate",
"startCarModeInLowBandwidthMode": "Avvia modalità auto in modalità larghezza di banda limitata",
"startWithAudioMuted": "Inizia con audio disattivato",
"startWithVideoMuted": "Inizia con video disattivato",
"startWithAudioMuted": "Avvia con audio disattivato",
"startWithVideoMuted": "Avvia con video disattivato",
"terms": "Termini",
"version": "Versione"
},
@@ -1283,7 +1317,7 @@
"feedback": "Lascia un feedback",
"fullScreen": "Attiva modalità a schermo intero",
"giphy": "Mostra menu GIPHY",
"grantModerator": "Concedi permessi di organizzatore",
"grantModerator": "Concedi permessi da relatore",
"hangup": "Lascia la riunione",
"heading": "Barra degli strumenti",
"help": "Aiuto",
@@ -1346,6 +1380,20 @@
"videounmute": "Accendi videocamera"
},
"addPeople": "Aggiungi partecipanti alla chiamata",
"advancedAudioSettings": {
"aec": {
"label": "Cancellazione dell'eco"
},
"agc": {
"label": "Controllo del guadagno automatico"
},
"ns": {
"label": "Cancellazione del rumore"
},
"stereo": {
"label": "Stereo"
}
},
"audioOnlyOff": "Disabilita modalità larghezza di banda limitata",
"audioOnlyOn": "Abilita modalità larghezza di banda limitata",
"audioRoute": "Scegli il dispositivo audio",
@@ -1412,11 +1460,12 @@
"profile": "Modifica profilo",
"raiseHand": "Alza la mano",
"raiseYourHand": "Alza la mano",
"reactionBoo": "Invia buu",
"reactionClap": "Invia applauso",
"reactionHeart": "Invia cuore",
"reactionLaugh": "Invia risata",
"reactionLike": "Invia mi piace",
"reactionBoo": "Invia Buu",
"reactionClap": "Invia Applauso",
"reactionHeart": "Invia Cuore",
"reactionLaugh": "Invia Risata",
"reactionLike": "Invia Mi piace",
"reactionLove": "Invia Love",
"reactionSilence": "Invia senza parole",
"reactionSurprised": "Invia a bocca aperta",
"reactions": "Reazioni",
@@ -1502,15 +1551,17 @@
"connectionInfo": "Informazioni connessione",
"demote": "Fai diventare spettatore",
"domute": "Disattiva microfono",
"domuteDesktop": "Interrompi la condivisione dello schermo",
"domuteDesktopOfOthers": "Interrompi la condivisione dello schermo agli altri",
"domuteOthers": "Disattiva microfono a tutti gli altri",
"domuteVideo": "Disattiva videocamera",
"domuteVideoOfOthers": "Disattiva videocamera a tutti gli altri",
"flip": "Specchia",
"grantModerator": "Concedi permessi da organizzatore",
"grantModerator": "Concedi permessi da relatore",
"hideSelfView": "Nascondi la tua immagine",
"kick": "Espelli",
"mirrorVideo": "Specchia il tuo video",
"moderator": "Organizzatore",
"moderator": "Relatore",
"mute": "Il partecipante ha il microfono spento",
"muted": "Microfono spento",
"pinToStage": "Metti in primo piano",
@@ -1557,7 +1608,7 @@
"description": "Adesso sei uno spettatore in questa riunione.",
"raiseHand": "Alza la mano",
"title": "Ingresso nella riunione in corso",
"wishToSpeak": "Se vuoi parlare, si prega di alzare la mano sotto e aspettare l'autorizzazione dell'organizzatore."
"wishToSpeak": "Se vuoi parlare, si prega di alzare la mano sotto e aspettare l'autorizzazione del relatore."
},
"labelTooltip": "Numero di spettatori: {{count}}",
"notification": {
@@ -1618,7 +1669,7 @@
"roomnameHint": "Inserisci il nome o l'URL della riunione a cui vuoi accedere. Puoi anche inventarti un nome, assicurati solo che le persone con cui vuoi collegarti lo conoscano, così che possano inserire lo stesso nome.",
"sendFeedback": "Invia feedback",
"settings": "Impostazioni",
"startMeeting": "Inizia riunione",
"startMeeting": "Avvia riunione",
"terms": "Termini di utilizzo",
"title": "Il sistema di videoconferenza sicuro, funzionale e completamente gratuito.",
"upcomingMeetings": "Prossime riunioni"

View File

@@ -109,9 +109,12 @@
}
},
"chat": {
"disabled": "Tērzēšanas ziņojumu sūtīšana ir atspējota.",
"enter": "Ienākt istabā",
"error": "Kļūda: Jūsu ziņa netika nosūtīta. Cēlonis: {{error}}",
"everyone": "Visi",
"fieldPlaceHolder": "Rakstiet ziņu šeit",
"guestsChatIndicator": "(viesis)",
"lobbyChatMessageTo": "Vestibila tērzēšanas ziņa adresātam {{recipient}}",
"message": "Ziņa",
"messageAccessibleTitle": "{{user}} saka:",
@@ -124,7 +127,8 @@
"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"
"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"
},
"noMessagesMessage": "Sapulcē pagaidām nav nevienas ziņas. Uzsāciet saraksti!",
"privateNotice": "Privāta ziņa adresātam {{recipient}}",
@@ -134,12 +138,14 @@
"tabs": {
"chat": "Tērzēšana",
"closedCaptions": "Slēptie subtitri",
"fileSharing": "Faili",
"polls": "Aptaujas"
},
"title": "Tērzēšana",
"titleWithCC": "Tērzēšana un slēptie subtitri",
"titleWithCC": "Tērzēšana un Slēptie subtitri",
"titleWithFeatures": "Tērzēšana un",
"titleWithFileSharing": "Faili",
"titleWithPolls": "Tērzēšana un Aptaujas",
"titleWithPollsAndCC": "Tērzēšana, Aptaujas un Slēptie subtitri",
"you": "jūs"
},
"chromeExtensionBanner": {
@@ -296,6 +302,12 @@
"alreadySharedVideoTitle": "Atļauts tikai viens kopīgots videoklips",
"applicationWindow": "Lietotnes logs",
"authenticationRequired": "Nepieciešama autentifikācija",
"cameraCaptureDialog": {
"description": "Uzņemt un nosūtīt attēlu, izmantojot mobilā tālruņa kameru",
"ok": "Atvērt kameru",
"reject": "Ne tagad",
"title": "Uzņemt attēlu"
},
"cameraConstraintFailedError": "Kamera neatbilst noteiktajām prasībām.",
"cameraNotFoundError": "Kamera nav atrasta.",
"cameraNotSendingData": "Nevar piekļūt jūsu kamerai. Lūdzu, pārbaudiet, vai šo ierīci neizmanto cita programma, iestatījumu izvēlnē atlasiet citu ierīci vai mēģiniet atkārtoti ielādēt programmu.",
@@ -371,22 +383,34 @@
"micTimeoutError": "Nevarēja palaist audio avotu. Iestājās noildze!",
"micUnknownError": "Nevar izmantot mikrofonu nezināma iemesla dēļ.",
"moderationAudioLabel": "Atļaut dalībniekiem ieslēgt savu mikrofonu",
"moderationDesktopLabel": "Atļaut lietotājiem, kas nav moderatori, kopīgot savu ekrānu",
"moderationVideoLabel": "Atļaut dalībniekiem ieslēgt savu kameru",
"muteEveryoneDialog": "Dalībnieki paši var ieslēgt savu mikrofonu.",
"muteEveryoneDialogModerationOn": "Dalībnieki var nosūtīt pieprasījumu ieslēgt savu mikrofonu.",
"muteEveryoneElseDialog": "Kad skaņa būs izslēgta, jūs nevarēsiet to ieslēgt atpakaļ, taču dalībnieki to varēs izdarīt paši.",
"muteEveryoneElseTitle": "Vai izslēgt skaņu visiem, izņemot {{whom}}?",
"muteEveryoneElsesDesktopDialog": "Kad kopīgošana būs apturēta, jūs vairs nevarēsiet to ieslēgt atpakaļ, bet viņi to varēs izdarīt jebkurā laikā.",
"muteEveryoneElsesDesktopTitle": "Apturēt ekrāna kopīgošanu visiem, izņemot {{kam}}?",
"muteEveryoneElsesVideoDialog": "Kad video būs izslēgts, jūs nevarēsiet to ieslēgt atpakaļ, taču dalībnieki to varēs izdarīt paši.",
"muteEveryoneElsesVideoTitle": "Vai izslēgt video visiem, izņemot {{whom}}?",
"muteEveryoneSelf": "jūs",
"muteEveryoneStartMuted": "No šī brīža visi jauni dalībnieki pieslēdzas ar izslēgt skaņu",
"muteEveryoneTitle": "Vai izslēgt skaņu visiem?",
"muteEveryonesDesktopDialog": "Dalībnieki var kopīgot savu ekrānu jebkurā laikā.",
"muteEveryonesDesktopDialogModerationOn": "Dalībnieki jebkurā laikā var nosūtīt pieprasījumu kopīgot savu ekrānu.",
"muteEveryonesDesktopTitle": "Vai pārtraukt ekrāna kopīgošanu visiem?",
"muteEveryonesVideoDialog": "Dalībnieki var ieslēgt savu video.",
"muteEveryonesVideoDialogModerationOn": "Dalībnieki var nosūtīt pieprasījumu ieslēgt viņu video.",
"muteEveryonesVideoDialogOk": "Atspējot",
"muteEveryonesVideoTitle": "Vai apturēt ikviena video?",
"muteParticipantBody": "Jūs nevariet viņiem ieslēgt skaņu, bet viņi paši to var izdarīt jebkurā laikā.",
"muteParticipantButton": "Izslēgt skaņu",
"muteParticipantsDesktopBody": "Jūs nevarēsiet sākt viņu ekrāna kopīgošanu, bet viņi to varēs izdarīt jebkurā laikā.",
"muteParticipantsDesktopBodyModerationOn": "Jūs nevarēsiet sākt viņu ekrāna kopīgošanu, un arī viņi to nevarēs izdarīt.",
"muteParticipantsDesktopButton": "Pārtraukt ekrāna kopīgošanu",
"muteParticipantsDesktopDialog": "Vai tiešām vēlaties izslēgt šī dalībnieka ekrāna kopīgošanu? Jūs vairs nevarēsiet ieslēgt to atpakaļ, bet viņš to varēs izdarīt jebkurā laikā.",
"muteParticipantsDesktopDialogModerationOn": "Vai tiešām vēlaties izslēgt šī dalībnieka ekrāna kopīgošanu? Jūs vairs nevarēsiet ieslēgt to atpakaļ, un arī viņš to nevarēs izdarīt.",
"muteParticipantsDesktopTitle": "Atspējot ekrāna kopīgošanu šim dalībniekam?",
"muteParticipantsVideoBody": "Jūs nevarēsiet kameru ieslēgt atpakaļ, taču viņi paši to varēs izdarīt jebkurā laikā.",
"muteParticipantsVideoBodyModerationOn": "Ne Jūs, ne dalībnieki nevarēsiet ieslēgt kameru atpakaļ.",
"muteParticipantsVideoButton": "Pārtraukt video",
@@ -539,6 +563,23 @@
"veryBad": "Ļoti Slikta",
"veryGood": "Ļoti Laba"
},
"fileSharing": {
"downloadFailedDescription": "Lūdzu, mēģiniet vēlreiz.",
"downloadFailedTitle": "Lejuplādes kļūda",
"downloadFile": "Lejuplādēt",
"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ē.",
"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",
"removeFile": "Noņemt",
"removeFileSuccess": "Fails veiksmīgi noņemts",
"uploadFailedDescription": "Lūdzu, mēģiniet vēlreiz.",
"uploadFailedTitle": "Augšuplādes kļūda",
"uploadFile": "Kopīgot failu"
},
"filmstrip": {
"accessibilityLabel": {
"heading": "Video sīktēli"
@@ -750,8 +791,9 @@
"me": "es",
"notify": {
"OldElectronAPPTitle": "Drošības ievainojamība!",
"allowAll": "Atļaut visu",
"allowAudio": "Atļaut audio",
"allowBoth": "Abus",
"allowDesktop": "Atļaut ekrāna kopīgošanu",
"allowVideo": "Atļaut video",
"allowedUnmute": "Varat ieslēgt mikrofona skaņu, ieslēgt kameru vai kopīgot ekrānu.",
"audioUnmuteBlockedDescription": "Mikrofona ieslēgšanas darbība ir īslaicīgi bloķēta sistēmas ierobežojumu dēļ.",
@@ -765,6 +807,7 @@
"dataChannelClosedDescription": "Savienojuma kanāls nedarbojas, tāpēc video kvalitāte var būt ierobežota līdz zemākajam iestatījumam.",
"dataChannelClosedDescriptionWithAudio": "Savienojuma kanāls nedarbojas, tāpēc var rasties audio un video traucējumi.",
"dataChannelClosedWithAudio": "Audio un video kvalitāte var būt traucēta",
"desktopMutedRemotelyTitle": "",
"disabledIframe": "Iegulšana ir paredzēta tikai demonstrācijas nolūkiem, tāpēc šis zvans tiks atvienots pēc {{timeout}} minūtēm.",
"disabledIframeSecondaryNative": "Domēna {{domain}} iegulšana ir paredzēta tikai demonstrācijas nolūkiem, tāpēc šis zvans tiks pārtraukts pēc {{timeout}} minūtēm.",
"disabledIframeSecondaryWeb": "Domēna {{domain}} iegulšana ir paredzēta tikai demonstrācijas nolūkiem, tāpēc šis zvans tiks pārtraukts pēc {{timeout}} minūtēm. Lūdzu, produkcijas videi izmantojiet <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a>!",
@@ -845,6 +888,7 @@
"suggestRecordingDescription": "Vai vēlaties sākt ierakstīšanu?",
"suggestRecordingTitle": "Ierakstīt sanāksmi",
"unmute": "Ieslēgt mikrofonu",
"unmuteScreen": "",
"unmuteVideo": "Ieslēgt video",
"videoMutedRemotelyDescription": "Jūs vienmēr varat to atkal ieslēgt.",
"videoMutedRemotelyTitle": "{{participantDisplayName}} izslēdza jūsu video",
@@ -864,11 +908,14 @@
"admit": "Apstiprināt",
"admitAll": "Apstiprināt visus",
"allow": "Atļaut dalībniekiem:",
"allowDesktop": "Atļaut ekrāna kopīgošanu",
"allowVideo": "Atļaut video",
"askDesktop": "Lūgt kopīgot ekrānu",
"askUnmute": "Lūgt ieslēgt skaņu",
"audioModeration": "Ieslēgt savu skaņu",
"blockEveryoneMicCamera": "Bloķēt visiem mikrofonu un kameru",
"breakoutRooms": "Grupu istabas",
"desktopModeration": "Sākt ekrāna kopīgošanu",
"goLive": "Sākt",
"invite": "Uzaicināt",
"lowerAllHands": "Nolaist visas paceltās rokas",
@@ -880,6 +927,8 @@
"muteAll": "Apklusināt visus",
"muteEveryoneElse": "Apklusināt pārējos",
"reject": "Noraidīt",
"stopDesktop": "Pārtraukt ekrāna kopīgošanu",
"stopEveryonesDesktop": "Pārtraukt visiem ekrāna kopīgošanu",
"stopEveryonesVideo": "Izslēgt visiem video",
"stopVideo": "Izslēgt video",
"unblockEveryoneMicCamera": "Atbloķēt visiem mikrofonu un kameru",
@@ -889,9 +938,11 @@
"headings": {
"lobby": "Vestibils ({{count}})",
"participantsList": "Sapulces dalībnieki ({{count}})",
"viewerRequests": "Apmeklētāju pieprasījumi {{count}}",
"visitorInQueue": " (gaida {{count}})",
"visitorRequests": " (pieprasījumi {{count}})",
"visitors": "Apmeklētāji ({{count}})",
"visitors": "Apmeklētāji {{count}}",
"visitorsList": "Apmeklētāji ({{count}})",
"waitingLobby": "Gaida vestibilā ({{count}})"
},
"search": "Meklēt dalībniekus",
@@ -1484,6 +1535,8 @@
"connectionInfo": "Informācija par savienojumu",
"demote": "Pārveidot par apmeklētāju",
"domute": "Izlsēgt skaņu",
"domuteDesktop": "Pārtraukt ekrāna kopīgošanu",
"domuteDesktopOfOthers": "Pārtraukt ekrāna kopīgošanu visiem pārējiem",
"domuteOthers": "Izslēgt skaņu visiem pārējiem",
"domuteVideo": "Izslēgt kameru",
"domuteVideoOfOthers": "Izslēgt video visiem pārējiem",

View File

@@ -109,8 +109,10 @@
}
},
"chat": {
"disabled": "O envio de mensagens de chat está desativado.",
"enter": "Entrar na sala",
"error": "Erro: a sua mensagem não foi enviada. Motivo: {{error}}",
"everyone": "Todos",
"fieldPlaceHolder": "Aa",
"lobbyChatMessageTo": "Mensagem de chat na sala de espera para {{recipient}}",
"message": "Mensagem",
@@ -122,7 +124,10 @@
"nickname": {
"popover": "Escolha um apelido",
"title": "Introduza um apelido para usar o chat",
"titleWithPolls": "Introduza um apelido para usar o chat e as sondagens"
"titleWithCC": "Insira um apelido para usar o chat e as legendas ocultas",
"titleWithPolls": "Digite um apelido para usar o chat e as sondagens",
"titleWithPollsAndCC": "Insira um apelido para utilizar o chat, as sondagens e as legendas ocultas",
"titleWithPollsAndCCAndFileSharing": "Insira um apelido para utilizar o chat, as sondagens, as legendas e os ficheiros"
},
"noMessagesMessage": "Ainda não há mensagens na reunião. Comece aqui uma conversa!",
"privateNotice": "Mensagem privada para {{recipient}}",
@@ -131,10 +136,15 @@
"systemDisplayName": "Sistema",
"tabs": {
"chat": "Chat",
"closedCaptions": "LO",
"fileSharing": "Ficheiros",
"polls": "Sondagens"
},
"title": "Chat",
"titleWithPolls": "Chat e Sondagens",
"titleWithCC": "LO",
"titleWithFeatures": "Chat e",
"titleWithFileSharing": "Ficheiros",
"titleWithPolls": "Sondagens",
"you": "você"
},
"chromeExtensionBanner": {
@@ -144,6 +154,10 @@
"dontShowAgain": "Não me mostre isto outra vez",
"installExtensionText": "Instalar a extensão para a integração Google Calendar e Office 365"
},
"closedCaptionsTab": {
"emptyState": "O conteúdo das legendas ocultas estará disponível assim que um moderador iniciar a sessão.",
"startClosedCaptionsButton": "Iniciar legendas ocultas"
},
"connectingOverlay": {
"joiningRoom": "A ligá-lo à reunião…"
},
@@ -263,6 +277,8 @@
"Remove": "Remover",
"Share": "Partilhar",
"Submit": "Submeter",
"Understand": "Entendo, mantenha-me em silêncio por enquanto.",
"UnderstandAndUnmute": "Entendo, por favor, desative o silêncio.",
"WaitForHostMsg": "A conferência ainda não começou porque ainda não chegaram moderadores. Se quiser ser um moderador, inicie a sessão. Caso contrário, aguarde.",
"WaitForHostNoAuthMsg": "A conferência ainda não começou porque ainda não chegaram os moderadores. Por favor, aguarde.",
"WaitingForHostButton": "Esperar pelo moderador",
@@ -285,6 +301,12 @@
"alreadySharedVideoTitle": "Só é permitido um vídeo partilhado de cada vez",
"applicationWindow": "Janela de aplicação",
"authenticationRequired": "Autenticação necessária",
"cameraCaptureDialog": {
"description": "Tire e envie uma foto usando a câmara do seu telemóvel",
"ok": "Ligar a câmara",
"reject": "Agora não",
"title": "Tire uma foto"
},
"cameraConstraintFailedError": "A sua câmara não satisfaz algumas das restrições exigidas.",
"cameraNotFoundError": "A câmara não foi encontrada.",
"cameraNotSendingData": "Não podemos aceder à sua câmara. Verifique se outra aplicação está a utilizar este dispositivo, seleccione outro dispositivo do menu de definições ou tente recarregar a aplicação.",
@@ -299,6 +321,7 @@
"conferenceReloadMsg": "Estamos a tentar resolver isto. Reconexão em {{seconds}} seg…",
"conferenceReloadTitle": "Infelizmente, algo correu mal.",
"confirm": "Confirme",
"confirmBack": "Voltar",
"confirmNo": "Não",
"confirmYes": "Sim",
"connectError": "Oops! Algo correu mal e não conseguimos estabelecer uma ligação com a conferência.",
@@ -307,8 +330,8 @@
"contactSupport": "Contacte o suporte",
"copied": "Copiado",
"copy": "Cópia",
"demoteParticipantDialog": "Tem a certeza de que pretende passar este participante para visitante?",
"demoteParticipantTitle": "Passar a visitante",
"demoteParticipantDialog": "Tem a certeza de que deseja mover este participante para espectador?",
"demoteParticipantTitle": "Mover para espectador",
"dismiss": "Dispensar",
"displayNameRequired": "Olá! Qual é o seu nome?",
"done": "Feito",
@@ -334,7 +357,9 @@
"kickParticipantButton": "Expulsar",
"kickParticipantDialog": "Tem a certeza que quer expulsar este participante?",
"kickParticipantTitle": "Expulsar este participante?",
"kickSystemTitle": "Ai! Foste expulso da reunião.",
"kickTitle": "Ai! {{participantDisplayName}} expulsou-o da reunião",
"learnMore": "saiba mais",
"linkMeeting": "Link da reunião",
"linkMeetingTitle": "Link da reunião à Força de Vendas",
"liveStreaming": "Transmissão em direto",
@@ -356,23 +381,35 @@
"micPermissionDeniedError": "Não concedeu autorização para utilizar o seu microfone. Ainda pode participar na conferência, mas outros não o ouvirão. Use o botão da câmara na barra de endereço para corrigir isto.",
"micTimeoutError": "Não foi possível iniciar a fonte de áudio. Tempo limite expirado!",
"micUnknownError": "Não pode usar microfone por uma razão desconhecida.",
"moderationAudioLabel": "Permitir aos participantes ligar o som",
"moderationVideoLabel": "Permitir aos participantes ligar a câmara",
"moderationAudioLabel": "Permitir aos não moderadores ligar o som",
"moderationDesktopLabel": "Permitir que não moderadores partilhem o seu ecrã",
"moderationVideoLabel": "Permitir que não moderadores iniciem os seus vídeos",
"muteEveryoneDialog": "Os participantes podem ligar o som a qualquer momento.",
"muteEveryoneDialogModerationOn": "Os participantes podem enviar um pedido para falar a qualquer momento.",
"muteEveryoneElseDialog": "Uma vez silenciados, não poderá reativá-los, mas eles podem ligar o microfone a qualquer momento.",
"muteEveryoneElseTitle": "Silenciar todos excepto {{whom}}?",
"muteEveryoneElsesDesktopDialog": "Depois que o compartilhamento for interrompido, não será possível reiniciá-lo, mas eles poderão fazê-lo a qualquer momento.",
"muteEveryoneElsesDesktopTitle": "SInterromper a partilha de ecrã de todos, exceto {{whom}}?",
"muteEveryoneElsesVideoDialog": "Quando a câmara for desligada, não poderá voltar a ligá-la, mas eles podem voltar a ligá-la em qualquer momento.",
"muteEveryoneElsesVideoTitle": "Parar o vídeo de todos excepto {{whom}}?",
"muteEveryoneSelf": "você mesmo",
"muteEveryoneStartMuted": "A partir de agora, toda a gente começa a ficar calada",
"muteEveryoneTitle": "Silenciar toda a gente?",
"muteEveryonesDesktopDialog": "Os participantes podem partilhar o seu ecrã a qualquer momento.",
"muteEveryonesDesktopDialogModerationOn": "Os participantes podem enviar um pedido para partilhar o seu ecrã a qualquer momento.",
"muteEveryonesDesktopTitle": "Interromper a partilha de ecrã de todos?",
"muteEveryonesVideoDialog": "Os participantes podem ligar a sua câmara a qualquer momento.",
"muteEveryonesVideoDialogModerationOn": "Os participantes podem enviar um pedido para ligar a sua câmara a qualquer momento.",
"muteEveryonesVideoDialogOk": "Desativar",
"muteEveryonesVideoTitle": "Desligar a câmara de todos?",
"muteParticipantBody": "Não poderá reativá-los, mas eles podem reativar-se a qualquer momento.",
"muteParticipantButton": "Silenciar",
"muteParticipantsDesktopBody": "Não poderá iniciar a partilha de ecrã deles, mas eles podem fazê-lo a qualquer momento.",
"muteParticipantsDesktopBodyModerationOn": "Não será possível iniciar a partilha de ecrã nem para si nem para eles.",
"muteParticipantsDesktopButton": "Parar a partilha de ecrã",
"muteParticipantsDesktopDialog": "Tem a certeza de que deseja desativar a partilha de ecrã deste participante? Não será possível reiniciá-la, mas ele poderá fazê-lo a qualquer momento.",
"muteParticipantsDesktopDialogModerationOn": "Tem a certeza de que deseja desativar a partilha de ecrã deste participante? Não será possível reativar o ecrã, nem para si nem para ele.",
"muteParticipantsDesktopTitle": "Desativar a partilha de ecrã deste participante?",
"muteParticipantsVideoBody": "Não poderá voltar a ligar a câmara, mas eles podem voltar a ligá-la a qualquer momento.",
"muteParticipantsVideoBodyModerationOn": "Não será capaz de voltar a ligar a câmara e eles também não.",
"muteParticipantsVideoButton": "Parar vídeo",
@@ -392,6 +429,10 @@
"recentlyUsedObjects": "Os seus objetos recentemente utilizados",
"recording": "A gravar",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Não possível enquanto a transmissão em direto estiver activa",
"recordingInProgressDescription": "Esta reunião está a ser gravada e analisada pela IA{{learnMore}}. O seu áudio e vídeo foram silenciados. Se optar por ativar o som, concorda em ser gravado.",
"recordingInProgressDescriptionFirstHalf": "Esta reunião está a ser gravada e analisada por IA.",
"recordingInProgressDescriptionSecondHalf": ". Your audio and video have been muted. If you choose to unmute, you consent to being recorded.",
"recordingInProgressTitle": "Gravação em andamento",
"rejoinNow": "Reingressar agora",
"remoteControlAllowedMessage": "{{user}} aceitou o seu pedido de controlo remoto!",
"remoteControlDeniedMessage": "{{user}} rejeitou o seu pedido de controlo remoto!",
@@ -439,7 +480,10 @@
"shareScreenWarningD2": "é necessário parar a partilha de áudio, iniciar a partilha de ecrã e verificar a opção \"partilhar áudio\".",
"shareScreenWarningH1": "Se quiser partilhar apenas o seu ecrã:",
"shareScreenWarningTitle": "Tem de parar a partilha de áudio antes de partilhar o seu ecrã",
"shareVideoLinkError": "Por favor, forneça um link correcto do vídeo.",
"shareVideoConfirmPlay": "Está prestes a abrir um site externo. Deseja continuar?",
"shareVideoConfirmPlayTitle": "{{name}} partilhou um vídeo consigo.",
"shareVideoLinkError": "Oops, este vídeo não pode ser reproduzido.",
"shareVideoLinkStopped": "O vídeo de {{name}} foi interrompido.",
"shareVideoTitle": "Partilhar vídeo",
"shareYourScreen": "Partilhe o seu ecrã",
"shareYourScreenDisabled": "Partilha de ecrã desactivada.",
@@ -518,6 +562,21 @@
"veryBad": "Muito má",
"veryGood": "Muito boa"
},
"fileSharing": {
"downloadFailedDescription": "Por favor, tente novamente.",
"downloadFailedTitle": "Falha no descarregar",
"downloadFile": "Descarregar",
"dragAndDrop": "Arraste e solte os ficheiros aqui ou em qualquer lugar do ecrã",
"fileAlreadyUploaded": "O ficheiro já foi carregado para esta reunião.",
"fileTooLargeDescription": "Certifique-se de que o ficheiro não exceda {{ maxFileSize }}.",
"fileTooLargeTitle": "O ficheiro selecionado é muito grande",
"fileUploadProgress": "Progresso do envio do ficheiro",
"fileUploadedSuccessfully": "Ficheiro carregado com sucesso",
"removeFile": "Remover",
"uploadFailedDescription": "Por favor, tente novamente.",
"uploadFailedTitle": "Falha ao carregar",
"uploadFile": "Partilhar ficheiro"
},
"filmstrip": {
"accessibilityLabel": {
"heading": "Miniaturas de vídeo"
@@ -638,6 +697,7 @@
"on": "Iniciada a transmissão em direto",
"onBy": "{{name}} iniciou a transmissão em direto",
"pending": "Início da transmissão em direto…",
"policyError": "Tentou iniciar uma transmissão ao vivo muito rapidamente. Por favor, tente novamente mais tarde!",
"serviceName": "Serviço de Transmissão em Direto",
"sessionAlreadyActive": "Esta sessão já está a ser gravada ou transmitida em direto.",
"signIn": "Iniciar sessão com o Google",
@@ -728,7 +788,10 @@
"me": "eu",
"notify": {
"OldElectronAPPTitle": "Vulnerabilidade de segurança!",
"allowAction": "Permitir",
"allowAll": "Permitir tudo",
"allowAudio": "Permitir áudio",
"allowDesktop": "Permitir partilha de ecrã",
"allowVideo": "Permitir vídeo",
"allowedUnmute": "Pode ligar o seu microfone, ligar a sua câmara ou partilhar o seu ecrã.",
"audioUnmuteBlockedDescription": "A operação de ligar o microfone foi temporariamente bloqueada devido aos limites do sistema.",
"audioUnmuteBlockedTitle": "Ligar microfone bloqueado!",
@@ -736,12 +799,15 @@
"connectedOneMember": "{{name}} entrou na reunião",
"connectedThreePlusMembers": "{{name}} e muitos outros entraram na reunião",
"connectedTwoMembers": "{{first}} e {{second}} entraram na reunião",
"connectionFailed": "Falha na ligação. Por favor, tente novamente mais tarde!",
"dataChannelClosed": "A qualidade do vídeo pode ser afetada",
"dataChannelClosedDescription": "O canal de ponte está em baixo e, por isso, a qualidade de vídeo pode estar limitada à sua definição mais baixa.",
"dataChannelClosedDescriptionWithAudio": "O canal de ponte está em baixo, pelo que podem ocorrer interrupções no áudio e no vídeo.",
"dataChannelClosedWithAudio": "A qualidade do áudio e do vídeo pode ser afetada",
"desktopMutedRemotelyTitle": "A partilha do seu ecrã foi interrompida por {{participantDisplayName}}",
"disabledIframe": "A incorporação destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos.",
"disabledIframeSecondary": "A incorporação de {{domain}} destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos. Por favor, use <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> para incorporação em produção!",
"disabledIframeSecondaryNative": "A incorporação de {{domain}} destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos.",
"disabledIframeSecondaryWeb": "A incorporação de {{domain}} destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos. Utilize <a href='{{jaasDomain}}' rel='noopener noreferrer' target='_blank'>Jitsi as a Service</a> para incorporação em produção!",
"disconnected": "desconectado",
"displayNotifications": "Mostrar notificações para",
"dontRemindMe": "Não me lembre",
@@ -749,7 +815,10 @@
"focusFail": "{{component}} não disponĩvel - tente em {{ms}} seg.",
"gifsMenu": "GIPHY",
"groupTitle": "Notificações",
"hostAskedUnmute": "O moderador gostaria que você falasse",
"hostAskedUnmute": "O moderador gostaria que participasse.",
"invalidTenant": "Tenant inválido",
"invalidTenantHyphenDescription": "O tenant que está a utilizar é inválido (começa ou termina com '-').",
"invalidTenantLengthDescription": "O tenant que está a utilizar é demasiado longo.",
"invitedOneMember": "{{displayName}} foi convidado",
"invitedThreePlusMembers": "{{name}} e {{count}} outros foram convidados",
"invitedTwoMembers": "{{first}} e {{second}} foram convidados",
@@ -787,9 +856,9 @@
"newDeviceAudioTitle": "Novo dispositivo de áudio detetado",
"newDeviceCameraTitle": "Nova câmara detetada",
"nextToSpeak": "É o próximo na fila para falar",
"noiseSuppressionDesktopAudioDescription": "A supressão de ruído não pode ser ativada enquanto se partilha o áudio do ambiente de trabalho, por favor desative-o e tente novamente.",
"noiseSuppressionFailedTitle": "Falha ao iniciar a supressão de ruído",
"noiseSuppressionStereoDescription": "A supressão do ruído de áudio estéreo não é atualmente suportada.",
"noiseSuppressionDesktopAudioDescription": "A supressão de ruído extra não pode ser ativada enquanto estiver a partilhar o áudio do ambiente de trabalho. Desative-a e tente novamente.",
"noiseSuppressionFailedTitle": "Falha ao iniciar a supressão de ruído extra",
"noiseSuppressionStereoDescription": "Atualmente, a supressão extra de ruído não é suportada com áudio estéreo.",
"oldElectronClientDescription1": "Parece estar a utilizar uma versão antiga do cliente Jitsi Meet que tem vulnerabilidades de segurança conhecidas. Por favor, certifique-se de que actualiza a nossa ",
"oldElectronClientDescription2": "compilação mais recente",
"oldElectronClientDescription3": " agora!",
@@ -798,7 +867,7 @@
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removido por outro participante",
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) definido por outro participante",
"raiseHandAction": "Levantar a mão",
"raisedHand": "Gostaria de falar.",
"raisedHand": "Gostaria de participar.",
"raisedHands": "{{participantName}} e mais {{raisedHands}} pessoas",
"reactionSounds": "Desactivar sons",
"reactionSoundsForAll": "Desativar sons para todos",
@@ -816,15 +885,17 @@
"suggestRecordingDescription": "Gostaria de iniciar uma gravação?",
"suggestRecordingTitle": "Gravar esta reunião",
"unmute": "Ligar microfone",
"unmuteScreen": "Iniciar partilha de ecrã",
"unmuteVideo": "Ligar câmara",
"videoMutedRemotelyDescription": "Pode sempre ligá-la novamente.",
"videoMutedRemotelyTitle": "A sua câmara foi desligada pelo {{participantDisplayName}}.",
"videoUnmuteBlockedDescription": "A operação de ligar a câmara e partilhar o ambiente de trabalho foi temporariamente bloqueada devido aos limites do sistema.",
"videoUnmuteBlockedTitle": "Está bloqueado ligar a câmara e partilhar o ambiente de trabalho!",
"viewLobby": "Ver sala de espera",
"viewParticipants": "Ver participantes",
"viewVisitors": "Ver visitantes",
"viewVisitors": "Visualizar espectadores",
"waitingParticipants": "{{waitingParticipants}} pessoas",
"waitingVisitors": "Visitantes em fila de espera: {{waitingVisitors}}",
"waitingVisitors": "Espectadores em fila de espera: {{waitingVisitors}}",
"waitingVisitorsTitle": "A reunião ainda não está em direto!",
"whiteboardLimitDescription": "Guarde o seu progresso, pois o limite de utilizadores será atingido em breve e o quadro branco será encerrado.",
"whiteboardLimitTitle": "Utilização do quadro branco"
@@ -833,14 +904,17 @@
"actions": {
"admit": "Aceitar",
"admitAll": "Aceitar todos",
"allow": "Permitir aos participantes:",
"allow": "Permitir que os não moderadores:",
"allowDesktop": "Permitir partilha de ecrã",
"allowVideo": "Permitir vídeo",
"askDesktop": "Pedir para partilhar o ecrã",
"askUnmute": "Pedir para ligar o som",
"audioModeration": "Ligar o microfone deles",
"blockEveryoneMicCamera": "Bloquear o microfone e a câmara de todos",
"breakoutRooms": "Salas simultâneas",
"desktopModeration": "Iniciar partilha de ecrã",
"goLive": "Aceder ao vivo",
"invite": "Convidar alguém",
"invite": "Convide alguém",
"lowerAllHands": "Baixar todas as mãos",
"lowerHand": "Baixar a mão",
"moreModerationActions": "Mais opções de moderação",
@@ -850,6 +924,8 @@
"muteAll": "Silenciar todos",
"muteEveryoneElse": "Silenciar todos os outros",
"reject": "Rejeitar",
"stopDesktop": "Parar a partilha de ecrã",
"stopEveryonesDesktop": "Interromper a partilha de ecrã de todos",
"stopEveryonesVideo": "Desligar a câmara de todos",
"stopVideo": "Desligar a câmara",
"unblockEveryoneMicCamera": "Desbloquear o microfone e a câmara de todos",
@@ -859,12 +935,15 @@
"headings": {
"lobby": "Sala de espera ({{count}})",
"participantsList": "Participantes da reunião ({{count}})",
"viewerRequests": "Pedidos dos espectadores {{count}}",
"visitorInQueue": " (à espera {{count}})",
"visitorRequests": " (pedidos {{count}})",
"visitors": "Visitantes ({{count}})",
"visitors": "Espectadores ({{count}})",
"visitorsList": "Espectadores ({{count}})",
"waitingLobby": "Aguardam na sala de espera ({{count}})"
},
"search": "Pesquisar participantes",
"searchDescription": "Comece a digitar para filtrar os participantes",
"title": "Participantes"
},
"passwordDigitsOnly": "Até {{number}} dígitos",
@@ -901,7 +980,7 @@
},
"results": {
"changeVote": "Mudar o voto",
"empty": "Ainda não há sondagens na reunião. Comece aqui uma sondagem!",
"empty": "Ainda não há sondagens na reunião.",
"hideDetailedResults": "Ocultar detalhes",
"showDetailedResults": "Mostrar detalhes",
"vote": "Voto"
@@ -919,9 +998,11 @@
"configuringDevices": "A configurar os dispositivos…",
"connectedWithAudioQ": "Está ligado com áudio?",
"connection": {
"failed": "Falha no teste de ligação!",
"good": "A sua ligação à Internet parece boa!",
"nonOptimal": "A sua ligação à Internet não é óptima",
"poor": "Tem uma ligação à Internet"
"poor": "Tem uma ligação à Internet fraca",
"running": "A realizar teste de ligação..."
},
"connectionDetails": {
"audioClipping": "Prevemos que o seu áudio tenha cortes.",
@@ -930,6 +1011,7 @@
"goodQuality": "Fantástico! A qualidade dos seus meios de comunicação vai ser óptima.",
"noMediaConnectivity": "Não foi possível encontrar uma forma de estabelecer a conectividade dos meios de comunicação para este teste. Isto é tipicamente causado por uma firewall ou NAT.",
"noVideo": "Prevemos que o seu vídeo seja terrível.",
"testFailed": "O teste de ligação encontrou problemas inesperados, mas isso pode não afetar a sua experiência.",
"undetectable": "Se mesmo assim não conseguir fazer chamadas no browser, recomendamos que se certifique de que os seus altifalantes, microfone e câmara estão devidamente configurados, que concedeu ao seu browser direitos de utilização do seu microfone e câmara, e que a versão do seu browser está actualizada. Se mesmo assim tiver problemas em telefonar, deverá contactar o criador da aplicação web.",
"veryPoorConnection": "Prevemos que a qualidade da sua chamada seja realmente terrível.",
"videoFreezing": "Prevemos que o seu vídeo congele, fique preto, e seja pixelizado.",
@@ -958,7 +1040,7 @@
"joinWithoutAudio": "Entrar sem áudio",
"keyboardShortcuts": "Ativar os atalhos de teclado",
"linkCopied": "Link copiado para a área de transferência",
"lookGood": "Tudo está a funcionar corretamente",
"lookGood": "Os seus dispositivos estão a funcionar corretamente",
"or": "ou",
"premeeting": "Pré-reunião",
"proceedAnyway": "Continuar na mesma",
@@ -1044,6 +1126,7 @@
"onBy": "{{name}} iniciou a gravação",
"onlyRecordSelf": "Gravar apenas as minhas transmissões áudio e vídeo",
"pending": "Preparando para gravar a reunião…",
"policyError": "Tentou iniciar uma gravação muito rapidamente. Por favor, tente novamente mais tarde!",
"recordAudioAndVideo": "Gravar áudio e vídeo",
"recordTranscription": "Gravar transcrições",
"saveLocalRecording": "Guardar ficheiro de gravação localmente (Beta)",
@@ -1087,11 +1170,13 @@
"signedIn": "Atualmente a aceder a eventos de calendário por {{email}}. Clique no botão Desconectar abaixo para parar de aceder a eventos de calendário.",
"title": "Calendário"
},
"chatWithPermissions": "O chat requer permissão",
"desktopShareFramerate": "Taxa de fotogramas para partilha do ambiente de trabalho",
"desktopShareHighFpsWarning": "Uma taxa de fotogramas mais elevada para a partilha do ambiente de trabalho pode afectar a sua largura de banda. É necessário reiniciar a partilha de ecrã para que as novas definições entrem em vigor.",
"desktopShareWarning": "É necessário reiniciar a partilha do ecrã para que as novas definições entrem em vigor.",
"devices": "Dispositivos",
"followMe": "Todos me seguem",
"followMeRecorder": "O gravador segue-me",
"framesPerSecond": "fotogramas-por-segundo",
"incomingMessage": "Receber uma mensagem",
"language": "Idioma",
@@ -1115,6 +1200,7 @@
"selectMic": "Microfone",
"selfView": "Autovisualização",
"shortcuts": "Atalhos",
"showSubtitlesOnStage": "Mostrar legendas",
"speakers": "Altifalantes",
"startAudioMuted": "Todos começam com microfone desligado",
"startReactionsMuted": "Todos começam com os sons de reação desativados",
@@ -1168,11 +1254,13 @@
"fearful": "Temeroso",
"happy": "Feliz",
"hours": "{{count}}h",
"labelTooltip": "Número de participantes: {{count}}",
"minutes": "{{count}}m",
"name": "Nome",
"neutral": "Neutro",
"sad": "Triste",
"search": "Pesquisar",
"searchDescription": "Comece a digitar para filtrar os participantes",
"searchHint": "Pesquisar participantes",
"seconds": "{{count}}s",
"speakerStats": "Estatísticas dos Participantes",
@@ -1209,6 +1297,7 @@
"closeChat": "Fechar chat",
"closeMoreActions": "Fechar menu de mais ações",
"closeParticipantsPane": "Fechar painel de participantes",
"closedCaptions": "Legendas ocultas",
"collapse": "Colapsar",
"document": "Mudar para documento partilhado",
"documentClose": "Fechar documento partilhado",
@@ -1238,6 +1327,7 @@
"lobbyButton": "Ativar/desativar sala de espera",
"localRecording": "Mudar os controlos locais de gravação",
"lockRoom": "Mudar palavra-chave de reunião",
"love": "Coração",
"lowerHand": "Baixar a mão",
"moreActions": "Mais ações",
"moreActionsMenu": "Menu de mais ações",
@@ -1248,13 +1338,14 @@
"muteEveryoneElsesVideo": "Parar o vídeo de todos os outros",
"muteEveryonesVideo": "Parar o vídeo de todos",
"muteGUMPending": "A ligar o seu microfone",
"noiseSuppression": "Supressão de ruído",
"noiseSuppression": "Supressão extra de ruído (BETA)",
"openChat": "Abrir chat",
"participants": "Abrir painel de participantes",
"participants": "Abrir painel de participantes. {{participantsCount}} participantes",
"pip": "Mudar para o modo Picture-in-Picture",
"privateMessage": "Enviar mensagem privada",
"profile": "Editar o seu perfil",
"raiseHand": "Levantar a mão",
"react": "Reações às mensagens",
"reactions": "Reações",
"reactionsMenu": "Menu de reações",
"recording": "Mudar gravação",
@@ -1297,14 +1388,15 @@
"closeChat": "Fechar chat",
"closeParticipantsPane": "Fechar painel de participantes",
"closeReactionsMenu": "Fechar menu de reações",
"disableNoiseSuppression": "Desativar a supressão de ruído",
"closedCaptions": "Legendas ocultas",
"disableNoiseSuppression": "Desativar supressão de ruído extra (BETA)",
"disableReactionSounds": "Pode desactivar os sons de reacção para esta reunião",
"documentClose": "Fechar documento partilhado",
"documentOpen": "Abrir documento partilhado",
"download": "Descarregar as nossas aplicações",
"e2ee": "Criptografia ponta a ponta",
"embedMeeting": "Incorporar reunião",
"enableNoiseSuppression": "Ativar a supressão de ruído",
"enableNoiseSuppression": "Ativar supressão extra de ruído (BETA)",
"endConference": "Terminar reunião para todos",
"enterFullScreen": "Ver em ecrã completo",
"enterTileView": "Ver em quadrícula",
@@ -1326,6 +1418,7 @@
"lobbyButtonEnable": "Ativar sala de espera",
"login": "Iniciar sessão",
"logout": "Terminar sessão",
"love": "Coração",
"lowerYourHand": "Baixar a mão",
"moreActions": "Mais ações",
"moreOptions": "Mais opções",
@@ -1338,7 +1431,7 @@
"noAudioSignalDialInDesc": "Também pode marcar usando:",
"noAudioSignalDialInLinkDesc": "Números de marcação",
"noAudioSignalTitle": "Não há nenhuma entrada vinda do seu microfone!",
"noiseSuppression": "Supressão de ruído",
"noiseSuppression": "Supressão extra de ruído (BETA)",
"noisyAudioInputDesc": "Parece que o seu microfone está a fazer barulho, por favor considere silenciar ou mudar de dispositivo.",
"noisyAudioInputTitle": "Seu microfone parece estar barulhento!",
"openChat": "Abrir chat",
@@ -1351,6 +1444,7 @@
"raiseYourHand": "Levantar a mão",
"reactionBoo": "Enviar reação de vaia",
"reactionClap": "Enviar reação de aplausos",
"reactionHeart": "Enviar reação com coração",
"reactionLaugh": "Enviar reação de risos",
"reactionLike": "Enviar reação de aprovado",
"reactionSilence": "Enviar reação de silêncio",
@@ -1384,15 +1478,19 @@
"transcribing": {
"ccButtonTooltip": "Iniciar/parar legendas",
"expandedLabel": "Transcrição ativada",
"failedToStart": "Transcrição falhou ao iniciar",
"labelToolTip": "A reunião esta sendo transcrita",
"failed": "Falha na transcrição",
"labelTooltip": "Esta reunião está a ser transcrita.",
"labelTooltipExtra": "Além disso, uma transcrição estará disponível posteriormente.",
"openClosedCaptions": "Abrir legendas ocultas",
"original": "Original",
"sourceLanguageDesc": "Atualmente a língua da reunião está definida para <b>{{sourceLanguage}}</b>. <br/> Pode alterá-la a partir ",
"sourceLanguageHere": "daqui",
"start": "Exibir legendas",
"stop": "Não exibir legendas",
"subtitles": "Legendas",
"subtitlesOff": "Desligado",
"tr": "TR"
"tr": "TR",
"translateTo": "Traduzir para"
},
"unpinParticipant": "{{participantName}} - Desafixar",
"userMedia": {
@@ -1424,7 +1522,7 @@
"ldTooltip": "Ver vídeo em baixa definição",
"lowDefinition": "Baixa definição (LD)",
"performanceSettings": "Definições de desempenho",
"recording": "Gravação em curso",
"recording": "Esta reunião está a ser gravada.",
"sd": "SD",
"sdTooltip": "Ver vídeo em definição padrão",
"standardDefinition": "Definição padrão",
@@ -1432,8 +1530,10 @@
},
"videothumbnail": {
"connectionInfo": "Informações sobre a ligação",
"demote": "Passar a visitante",
"demote": "Passar a espectador",
"domute": "Sem som",
"domuteDesktop": "Parar a partilha de ecrã",
"domuteDesktopOfOthers": "Interromper a partilha de ecrã para todos os outros",
"domuteOthers": "Silenciar todos os outros",
"domuteVideo": "Desativar a câmara",
"domuteVideoOfOthers": "Desactivar a câmara de todos os outros",
@@ -1484,21 +1584,21 @@
"webAssemblyWarningDescription": "WebAssembly desactivado ou não suportado por este navegador"
},
"visitors": {
"chatIndicator": "(visitante)",
"chatIndicator": "(espectador)",
"joinMeeting": {
"description": "Atualmente, é um observador nesta conferência.",
"description": "Atualmente, é um espectador nesta conferência.",
"raiseHand": "Levantar a mão",
"title": "Participar na reunião",
"wishToSpeak": "Se deseja intervir, levante a mão e aguarde a aprovação do moderador."
},
"labelTooltip": "Número de visitantes: {{count}}",
"labelTooltip": "Número de espectadores: {{count}}",
"notification": {
"demoteDescription": "Enviado aqui pelo {{actor}}, levante a mão para participar",
"noMainParticipantsDescription": "Um participante precisa de iniciar a reunião. Tente novamente daqui a pouco.",
"noMainParticipantsTitle": "Esta reunião ainda não começou.",
"noVisitorLobby": "Não é possível aderir enquanto houver uma sala de espera activada para a reunião.",
"notAllowedPromotion": "É necessário que um participante autorize primeiro o seu pedido.",
"title": "É um visitante na reunião"
"title": "É um espectador na reunião"
},
"waitingMessage": "Participará na reunião assim que esta estiver em direto!"
},

File diff suppressed because it is too large Load Diff

View File

@@ -331,11 +331,11 @@
"internalError": "Ett fel uppstod. Fel: {{error}}",
"internalErrorTitle": "Internt fel",
"kickMessage": "Du kan kontakta {{participantDisplayName}} för mer information.",
"kickParticipantButton": "Sparka ut",
"kickParticipantDialog": "Vill du sparka ut den här deltagaren?",
"kickParticipantButton": "Ta bort från mötet",
"kickParticipantDialog": "Vill du ta bort denna deltagaren från mötet?",
"kickParticipantTitle": "Tysta deltagaren?",
"kickSystemTitle": "Aj! du blev utsparkad ur mötet",
"kickTitle": "Aj! {{participantDisplayName}} sparkade ut dig ur mötet",
"kickSystemTitle": "Du har blivit borttagen från mötet",
"kickTitle": "{{participantDisplayName}} tog bort dig från mötet",
"linkMeeting": "Länka möte",
"linkMeetingTitle": "Länka möte till Salesforce",
"liveStreaming": "Streama",
@@ -763,7 +763,7 @@
"invitedThreePlusMembers": "{{name}} och {{count}} andra har bjudits in",
"invitedTwoMembers": "{{first}} och {{second}} har bjudits in",
"joinMeeting": "Delta",
"kickParticipant": "{{kicked}} sparkades ut av {{kicker}}",
"kickParticipant": "{{kicked}} togs bort av {{kicker}}",
"leftOneMember": "{{name}} lämnade mötet",
"leftThreePlusMembers": "{{name}} och många andra lämnade mötet",
"leftTwoMembers": "{{first}} och {{second}} lämnade mötet",
@@ -1245,7 +1245,7 @@
"help": "Hjälp",
"hideWhiteboard": "Dölj whiteboard",
"invite": "Bjud in personer",
"kick": "Sparka ut deltagare",
"kick": "Ta bort deltagare",
"laugh": "Skratta",
"leaveConference": "Lämna mötet",
"like": "Tummen upp",
@@ -1459,7 +1459,7 @@
"flip": "Vänd",
"grantModerator": "Godkänn moderator",
"hideSelfView": "Dölj självvyn",
"kick": "Sparka ut",
"kick": "Ta bort",
"mirrorVideo": "Spegelvänd video",
"moderator": "Moderator",
"mute": "Deltagaren har avstängd mikrofon",

View File

@@ -112,7 +112,9 @@
"disabled": "Sending chat messages is disabled.",
"enter": "Enter room",
"error": "Error: your message was not sent. Reason: {{error}}",
"everyone": "Everyone",
"fieldPlaceHolder": "Aa",
"guestsChatIndicator": "(guest)",
"lobbyChatMessageTo": "Lobby chat message to {{recipient}}",
"message": "Message",
"messageAccessibleTitle": "{{user}} says:",
@@ -300,6 +302,12 @@
"alreadySharedVideoTitle": "Only one shared video is allowed at a time",
"applicationWindow": "Application window",
"authenticationRequired": "Authentication required",
"cameraCaptureDialog": {
"description": "Take and send a picture using your mobile camera",
"ok": "Open camera",
"reject": "Not now",
"title": "Take a picture"
},
"cameraConstraintFailedError": "Your camera does not satisfy some of the required constraints.",
"cameraNotFoundError": "Camera was not found.",
"cameraNotSendingData": "We are unable to access your camera. Please check if another application is using this device, select another device from the settings menu or try to reload the application.",
@@ -374,12 +382,9 @@
"micPermissionDeniedError": "You have not granted permission to use your microphone. You can still join the conference but others won't hear you. Use the camera button in the address bar to fix this.",
"micTimeoutError": "Could not start audio source. Timeout occurred!",
"micUnknownError": "Cannot use microphone for an unknown reason.",
"moderationAudioLabel": "Allow attendees to unmute themselves",
"moderationAudioLabel": "Allow non-moderators to unmute themselves",
"moderationDesktopLabel": "Allow non-moderators to share their screen",
"moderationVideoLabel": "Allow non-moderators to start their video",
"muteEveryonesDesktopDialog": "The participants can share their screen at any time.",
"muteEveryonesDesktopDialogModerationOn": "The participants can send a request to share their screen at any time.",
"muteEveryonesDesktopTitle": "Stop everyone's screen share?",
"muteEveryoneDialog": "The participants can unmute themselves at any time.",
"muteEveryoneDialogModerationOn": "The participants can send a request to speak at any time.",
"muteEveryoneElseDialog": "Once muted, you won't be able to unmute them, but they can unmute themselves at any time.",
@@ -391,6 +396,9 @@
"muteEveryoneSelf": "yourself",
"muteEveryoneStartMuted": "Everyone starts muted from now on",
"muteEveryoneTitle": "Mute everyone?",
"muteEveryonesDesktopDialog": "The participants can share their screen at any time.",
"muteEveryonesDesktopDialogModerationOn": "The participants can send a request to share their screen at any time.",
"muteEveryonesDesktopTitle": "Stop everyone's screen share?",
"muteEveryonesVideoDialog": "The participants can turn on their video at any time.",
"muteEveryonesVideoDialogModerationOn": "The participants can send a request to turn on their video at any time.",
"muteEveryonesVideoDialogOk": "Disable",
@@ -559,11 +567,15 @@
"downloadFailedDescription": "Please try again.",
"downloadFailedTitle": "Download failed",
"downloadFile": "Download",
"downloadStarted": "File download started",
"dragAndDrop": "Drag and drop files here or anywhere on screen",
"fileAlreadyUploaded": "File has already been uploaded to this meeting.",
"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",
"removeFile": "Remove",
"removeFileSuccess": "File removed successfully",
"uploadFailedDescription": "Please try again.",
"uploadFailedTitle": "Upload failed",
"uploadFile": "Share file"
@@ -853,6 +865,7 @@
"oldElectronClientDescription1": "You appear to be using an old version of the Jitsi Meet client which has known security vulnerabilities. Please make sure you update to our ",
"oldElectronClientDescription2": "latest build",
"oldElectronClientDescription3": " now!",
"openChat": "Open chat",
"participantWantsToJoin": "Wants to join the meeting",
"participantsWantToJoin": "Want to join the meeting",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removed by another participant",
@@ -1367,6 +1380,20 @@
"videounmute": "Start camera"
},
"addPeople": "Add people to your call",
"advancedAudioSettings": {
"aec": {
"label": "Acoustic echo cancellation"
},
"agc": {
"label": "Automatic gain control"
},
"ns": {
"label": "Noise suppression"
},
"stereo": {
"label": "Stereo"
}
},
"audioOnlyOff": "Disable low bandwidth mode",
"audioOnlyOn": "Enable low bandwidth mode",
"audioRoute": "Select the sound device",
@@ -1438,6 +1465,7 @@
"reactionHeart": "Send heart reaction",
"reactionLaugh": "Send laugh reaction",
"reactionLike": "Send thumbs up reaction",
"reactionLove": "Send love reaction",
"reactionSilence": "Send silence reaction",
"reactionSurprised": "Send surprised reaction",
"reactions": "Reactions",
@@ -1589,6 +1617,8 @@
"noMainParticipantsTitle": "This meeting hasn't started yet.",
"noVisitorLobby": "You cannot join while there is a lobby enabled for the meeting.",
"notAllowedPromotion": "A participant needs to allow your request first.",
"requestToJoin": "Hand Raised",
"requestToJoinDescription": "Your request was sent to the moderators. Hang tight!",
"title": "You are a viewer in the meeting"
},
"waitingMessage": "You'll join the meeting as soon as it is live!"

View File

@@ -30,6 +30,7 @@ import { overwriteConfig } from '../../react/features/base/config/actions';
import { getWhitelistedJSON } from '../../react/features/base/config/functions.any';
import { toggleDialog } from '../../react/features/base/dialog/actions';
import { isSupportedBrowser } from '../../react/features/base/environment/environment';
import { isMobileBrowser } from '../../react/features/base/environment/utils';
import { parseJWTFromURLParams } from '../../react/features/base/jwt/functions';
import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
import { MEDIA_TYPE, VIDEO_TYPE } from '../../react/features/base/media/constants';
@@ -113,7 +114,10 @@ import { RECORDING_METADATA_ID, RECORDING_TYPES } from '../../react/features/rec
import { getActiveSession, supportsLocalRecording } from '../../react/features/recording/functions';
import { startAudioScreenShareFlow, startScreenShareFlow } from '../../react/features/screen-share/actions';
import { isScreenAudioSupported } from '../../react/features/screen-share/functions';
import { toggleScreenshotCaptureSummary } from '../../react/features/screenshot-capture/actions';
import {
openCameraCaptureDialog,
toggleScreenshotCaptureSummary
} from '../../react/features/screenshot-capture/actions';
import { isScreenshotCaptureEnabled } from '../../react/features/screenshot-capture/functions';
import SettingsDialog from '../../react/features/settings/components/web/SettingsDialog';
import { SETTINGS_TABS } from '../../react/features/settings/constants';
@@ -134,7 +138,7 @@ import {
ENDPOINT_TEXT_MESSAGE_NAME
} from './constants';
const logger = Logger.getLogger(__filename);
const logger = Logger.getLogger('api:core');
/**
* List of the available commands.
@@ -940,6 +944,20 @@ function initCommands() {
});
});
break;
case 'capture-camera-picture' : {
const { cameraFacingMode, descriptionText, titleText } = request;
if (!isMobileBrowser()) {
logger.error('This feature is only supported on mobile');
return;
}
APP.store.dispatch(openCameraCaptureDialog(callback, { cameraFacingMode,
descriptionText,
titleText }));
break;
}
case 'deployment-info':
callback(APP.store.getState()['features/base/config'].deploymentInfo);
break;

View File

@@ -820,6 +820,27 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
});
}
/**
* Captures a picture through OS camera.
*
* @param {string} cameraFacingMode - The OS camera facing mode (environment/user).
* @param {string} descriptionText - The OS camera facing mode (environment/user).
* @param {string} titleText - The OS camera facing mode (environment/user).
* @returns {Promise<string>} - Resolves with a base64 encoded image data of the screenshot.
*/
captureCameraPicture(
cameraFacingMode,
descriptionText,
titleText
) {
return this._transport.sendRequest({
name: 'capture-camera-picture',
cameraFacingMode,
descriptionText,
titleText
});
}
/**
* Removes the listeners and removes the Jitsi Meet frame.
*

View File

@@ -1,6 +1,6 @@
import Logger from '@jitsi/logger';
const logger = Logger.getLogger(__filename);
const logger = Logger.getLogger('api:external');
/**
* Returns Promise that resolves with result an list of available devices.

View File

@@ -28,7 +28,7 @@ import EtherpadManager from './etherpad/Etherpad';
import UIUtil from './util/UIUtil';
import VideoLayout from './videolayout/VideoLayout';
const logger = Logger.getLogger(__filename);
const logger = Logger.getLogger('ui:core');
let etherpadManager;

View File

@@ -45,7 +45,7 @@ import AudioLevels from '../audio_levels/AudioLevels';
import { VIDEO_CONTAINER_TYPE, VideoContainer } from './VideoContainer';
const logger = Logger.getLogger(__filename);
const logger = Logger.getLogger('ui:videolayout');
const DESKTOP_CONTAINER_TYPE = 'desktop';

View File

@@ -24,7 +24,7 @@ export const VIDEO_CONTAINER_TYPE = 'camera';
// Corresponds to animation duration from the animatedFadeIn and animatedFadeOut CSS classes.
const FADE_DURATION_MS = 300;
const logger = Logger.getLogger(__filename);
const logger = Logger.getLogger('ui:VideoContainer');
/**
* List of container events that we are going to process for the large video.

View File

@@ -16,7 +16,7 @@ import {
import LargeVideoManager from './LargeVideoManager';
import { VIDEO_CONTAINER_TYPE } from './VideoContainer';
const logger = Logger.getLogger(__filename);
const logger = Logger.getLogger('ui:VideoLayout');
let largeVideo;
const VideoLayout = {

View File

@@ -1,4 +1,4 @@
const logger = require('@jitsi/logger').getLogger(__filename);
const logger = require('@jitsi/logger').getLogger('app:utils');
/**
* Manages a queue of functions where the current function in progress will

746
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,10 +23,10 @@
"@emotion/styled": "11.10.6",
"@giphy/js-fetch-api": "4.9.3",
"@giphy/react-components": "6.9.4",
"@giphy/react-native-sdk": "3.3.1",
"@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/logger": "2.0.2",
"@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",
"@microsoft/microsoft-graph-client": "3.0.1",
@@ -57,8 +57,10 @@
"clipboard-copy": "4.0.1",
"clsx": "1.1.1",
"dayjs": "1.11.13",
"dompurify": "3.2.6",
"dropbox": "10.7.0",
"focus-visible": "5.1.0",
"glob": "11.0.3",
"grapheme-splitter": "1.0.4",
"i18n-iso-countries": "6.8.0",
"i18next": "17.0.6",
@@ -70,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/v2030.0.0+b225c920/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v2089.0.0+75c1c6ff/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
@@ -87,16 +89,16 @@
"react-native-background-timer": "https://github.com/jitsi/react-native-background-timer.git#d180dfaa4486ae3ee17d01242db92cb3195f4718",
"react-native-calendar-events": "https://github.com/jitsi/react-native-calendar-events.git#47f068dedfed7c0f72042e093f688eb11624eb7b",
"react-native-default-preference": "https://github.com/jitsi/react-native-default-preference.git#c9bf63bdc058e3fa2aa0b87b1ee1af240f44ed02",
"react-native-device-info": "10.9.0",
"react-native-device-info": "12.1.0",
"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": "1.6.0",
"react-native-pager-view": "6.4.1",
"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",
"react-native-performance": "5.1.2",
"react-native-safe-area-context": "5.4.0",
"react-native-safe-area-context": "5.5.2",
"react-native-screens": "4.11.1",
"react-native-sound": "https://github.com/jitsi/react-native-sound.git#ea13c97b5c2a4ff5e0d9bacbd9ff5e4457fe2c3c",
"react-native-splash-view": "0.0.18",
@@ -108,10 +110,11 @@
"react-native-watch-connectivity": "1.1.0",
"react-native-webrtc": "124.0.4",
"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",
"react-redux": "7.2.9",
"react-textarea-autosize": "8.3.0",
"react-virtualized-auto-sizer": "^1.0.26",
"react-virtualized-auto-sizer": "1.0.26",
"react-window": "1.8.6",
"react-youtube": "10.1.0",
"redux": "4.0.4",
@@ -129,6 +132,8 @@
},
"devDependencies": {
"@babel/core": "7.25.9",
"@babel/plugin-proposal-nullish-coalescing-operator": "7.18.6",
"@babel/plugin-proposal-optional-chaining": "7.21.0",
"@babel/plugin-transform-private-methods": "7.25.9",
"@babel/preset-env": "7.25.9",
"@babel/preset-react": "7.25.9",

View File

@@ -1,14 +0,0 @@
diff --git a/node_modules/@giphy/js-analytics/dist/send-pingback.js b/node_modules/@giphy/js-analytics/dist/send-pingback.js
index 989f0ff..52471cb 100644
--- a/node_modules/@giphy/js-analytics/dist/send-pingback.js
+++ b/node_modules/@giphy/js-analytics/dist/send-pingback.js
@@ -10,6 +10,9 @@ var global_1 = __importDefault(require("./global"));
var environment = (global_1.default === null || global_1.default === void 0 ? void 0 : global_1.default.GIPHY_PINGBACK_URL) || 'https://pingback.giphy.com';
var pingBackUrl = "".concat(environment, "/v2/pingback?apikey=l0HlIwPWyBBUDAUgM");
var sendPingback = function (events) {
+ // Disabled.
+ return Promise.resolve();
+
var headers = (0, js_util_1.getGiphySDKRequestHeaders)();
/* istanbul ignore next */
headers === null || headers === void 0 ? void 0 : headers.set('Content-Type', 'application/json');

View File

@@ -70,6 +70,7 @@ cd ios && pod install && cd ..
## Android
- In your build.gradle have at least `minSdkVersion = 26`
- In your build.gradle have `gradlePluginVersion = "8.4.2"` or higher
- In `android/app/src/debug/AndroidManifest.xml` and `android/app/src/main/AndroidManifest.xml`, under the `</application>` tag, include
```xml
<uses-permission android:name="android.permission.RECORD_AUDIO" />

View File

@@ -7,7 +7,6 @@ buildscript {
dependencies {
classpath "com.android.tools.build:gradle:$rootProject.ext.gradlePluginVersion"
}
namespace 'org.jitsi.meet.reactnativesdk'
}
def isNewArchitectureEnabled() {
@@ -29,6 +28,7 @@ def getExtOrIntegerDefault(name) {
}
android {
namespace 'org.jitsi.meet.sdk'
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
defaultConfig {
@@ -124,12 +124,11 @@ repositories {
dependencies {
//noinspection GradleDynamicVersion
// noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+"
implementation 'com.squareup.duktape:duktape-android:1.3.0'
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
implementation 'com.jakewharton.timber:timber:4.7.1'
// From node_modules
// From node_modules
}
if (isNewArchitectureEnabled()) {

View File

@@ -1,4 +1,3 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.jitsi.meet.sdk">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
</manifest>

View File

@@ -22,7 +22,6 @@ public class JitsiMeetReactNativePackage implements ReactPackage {
new AppInfoModule(reactContext),
new AudioModeModule(reactContext),
new JMOngoingConferenceModule(reactContext),
new JavaScriptSandboxModule(reactContext),
new LocaleDetector(reactContext),
new LogBridgeModule(reactContext),
new PictureInPictureModule(reactContext),

View File

@@ -85,7 +85,12 @@
"react-native-video": "0.0.0",
"react-native-watch-connectivity": "0.0.0",
"react-native-webrtc": "0.0.0",
"react-native-webview": "0.0.0"
"react-native-webview": "0.0.0",
"react-native-worklets-core": "0.0.0"
},
"devDependencies": {
"@babel/plugin-proposal-nullish-coalescing-operator": "0.0.0",
"@babel/plugin-proposal-optional-chaining": "0.0.0"
},
"scripts": {
"postinstall": "node sdk_instructions.js",

View File

@@ -100,10 +100,6 @@ fs.copyFileSync(
`${iosSrcPath}/InfoPlistUtil.h`,
`${iosDestPath}/InfoPlistUtil.h`
);
fs.copyFileSync(
`${iosSrcPath}/JavaScriptSandbox.m`,
`${iosDestPath}/JavaScriptSandbox.m`
);
fs.copyFileSync(
`${iosSrcPath}/JitsiAudioSession.m`,
`${iosDestPath}/JitsiAudioSession.m`
@@ -184,10 +180,6 @@ fs.copyFileSync(
`${androidSourcePath}/ConnectionService.java`,
`${androidTargetPath}/ConnectionService.java`
);
fs.copyFileSync(
`${androidSourcePath}/JavaScriptSandboxModule.java`,
`${androidTargetPath}/JavaScriptSandboxModule.java`
);
fs.copyFileSync(
`${androidSourcePath}/LocaleDetector.java`,
`${androidTargetPath}/LocaleDetector.java`

View File

@@ -60,12 +60,12 @@ This is now set on your end.`
);
}
}
packageJSON.devDependencies = packageJSON.devDependencies || {};
packageJSON.overrides = packageJSON.overrides || {};
for (const key in RNSDKpackageJSON.overrides) {
if (!packageJSON.overrides.hasOwnProperty(key)) {
packageJSON.overrides[key] = RNSDKpackageJSON.overrides[key];
for (const key in RNSDKpackageJSON.devDependencies) {
if (!packageJSON.devDependencies.hasOwnProperty(key)) {
packageJSON.devDependencies[key] = RNSDKpackageJSON.devDependencies[key];
updated = true;
}
}
@@ -91,6 +91,14 @@ This is now set on your end.`
return item;
}, {});
packageJSON.devDependencies = Object.keys(packageJSON.devDependencies)
.sort()
.reduce((item, itemKey) => {
item[itemKey] = packageJSON.devDependencies[itemKey];
return item;
}, {});
fs.writeFileSync(pathToPackageJSON, JSON.stringify(packageJSON, null, 2));

View File

@@ -26,6 +26,13 @@ function mergeDependencyVersions() {
SDKPackageJSON.peerDependencies[key] = packageJSON.dependencies[key];
}
}
// Updates SDK dev dependencies(used by react-native-worklets-core lib. babel plugin)
for (const key in packageJSON.devDependencies) {
if (SDKPackageJSON.devDependencies.hasOwnProperty(key)) {
SDKPackageJSON.devDependencies[key] = packageJSON.devDependencies[key];
}
}
// Set RN peer dependency.
const rnVersion = semver.parse(packageJSON.dependencies['react-native']);

View File

@@ -35,3 +35,12 @@ export function fixDeviceID(amplitude: Types.BrowserClient) {
}
}
}
/**
* Returns the amplitude shared deviceId.
*
* @returns {string} - The amplitude deviceId.
*/
export function getDeviceID() {
return jitsiLocalStorage.getItem(DEVICE_ID_KEY);
}

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../base/logging/functions';
export default getLogger('features/analytics');
export default getLogger('app:analytics');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../base/logging/functions';
export default getLogger('features/app');
export default getLogger('app:core');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../base/logging/functions';
export default getLogger('features/authentication');
export default getLogger('app:authentication');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/app');
export default getLogger('app:base-app');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/audio-only');
export default getLogger('app:audio-only');

View File

@@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
import { makeStyles } from 'tss-react/mui';
import Icon from '../../../icons/components/Icon';
import { withPixelLineHeight } from '../../../styles/functions.web';
import { pixelsToRem } from '../../../ui/functions.any';
import { isIcon } from '../../functions';
import { IAvatarProps } from '../../types';
import { PRESENCE_AVAILABLE_COLOR, PRESENCE_AWAY_COLOR, PRESENCE_BUSY_COLOR, PRESENCE_IDLE_COLOR } from '../styles';
@@ -50,9 +50,8 @@ const useStyles = makeStyles()(theme => {
avatar: {
backgroundColor: '#AAA',
borderRadius: '50%',
fontWeight: '600',
color: theme.palette?.text01 || '#fff',
...withPixelLineHeight(theme.typography?.heading1 ?? {}),
...(theme.typography?.heading1 ?? {}),
fontSize: 'inherit',
objectFit: 'cover',
textAlign: 'center',
@@ -137,7 +136,7 @@ const StatelessAvatar = ({
const _getAvatarStyle = (backgroundColor?: string) => {
return {
background: backgroundColor || undefined,
fontSize: size ? size * 0.4 : '180%',
fontSize: size ? pixelsToRem(size * 0.4) : '180%',
height: size || '100%',
width: size || '100%'
};

View File

@@ -4,13 +4,12 @@ import { makeStyles } from 'tss-react/mui';
import Icon from '../icons/components/Icon';
import { IconCheck, IconCopy } from '../icons/svg';
import { withPixelLineHeight } from '../styles/functions.web';
import { copyText } from '../util/copyText.web';
const useStyles = makeStyles()(theme => {
return {
copyButton: {
...withPixelLineHeight(theme.typography.bodyShortBold),
...theme.typography.bodyShortBold,
borderRadius: theme.shape.borderRadius,
display: 'flex',
justifyContent: 'flex-start',

View File

@@ -83,7 +83,8 @@ import {
getConferenceState,
getCurrentConference,
getVisitorOptions,
sendLocalParticipant
sendLocalParticipant,
updateTrackMuteState
} from './functions';
import logger from './logger';
import { IConferenceMetadata, IJitsiConference } from './reducer';
@@ -186,6 +187,15 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
(disableVideoMuteChange: boolean) => {
dispatch(setVideoUnmutePermissions(disableVideoMuteChange));
});
conference.on(
JitsiConferenceEvents.START_MUTED_POLICY_CHANGED,
({ audio, video }: { audio: boolean; video: boolean; }) => {
dispatch(onStartMutedPolicyChanged(audio, video));
updateTrackMuteState(state, dispatch, true);
updateTrackMuteState(state, dispatch, false);
}
);
// Dispatches into features/base/tracks follow:
@@ -1013,6 +1023,8 @@ export function setStartMutedPolicy(
audio: startAudioMuted,
video: startVideoMuted
});
dispatch(onStartMutedPolicyChanged(startAudioMuted, startVideoMuted));
};
}

View File

@@ -40,3 +40,8 @@ export const CONFERENCE_LEAVE_REASONS = {
SWITCH_ROOM: 'switch_room',
UNRECOVERABLE_ERROR: 'unrecoverable_error'
};
/**
* The ID of the notification that is shown when the user is muted by focus.
*/
export const START_MUTED_NOTIFICATION_ID = 'start-muted';

View File

@@ -3,9 +3,13 @@ import { upperFirst, words } from 'lodash-es';
import { getName } from '../../app/functions';
import { IReduxState, IStore } from '../../app/types';
import { showNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import { determineTranscriptionLanguage } from '../../transcribing/functions';
import { IStateful } from '../app/types';
import { JitsiTrackErrors } from '../lib-jitsi-meet';
import { setAudioMuted, setVideoMuted } from '../media/actions';
import { VIDEO_MUTISM_AUTHORITY } from '../media/constants';
import {
participantJoined,
participantLeft
@@ -22,7 +26,8 @@ import { setObfuscatedRoom } from './actions';
import {
AVATAR_URL_COMMAND,
EMAIL_COMMAND,
JITSI_CONFERENCE_URL_KEY
JITSI_CONFERENCE_URL_KEY,
START_MUTED_NOTIFICATION_ID
} from './constants';
import logger from './logger';
import { IJitsiConference } from './reducer';
@@ -574,3 +579,42 @@ function safeStartCase(s = '') {
(result, word, index) => result + (index ? ' ' : '') + upperFirst(word)
, '');
}
/**
* Updates the mute state of the track based on the start muted policy.
*
* @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 {boolean} isAudio - Whether the track is audio or video.
* @returns {void}
*/
export function updateTrackMuteState(stateful: IStateful, dispatch: IStore['dispatch'], isAudio: boolean) {
const state = toState(stateful);
const mutedPolicyKey = isAudio ? 'startAudioMutedPolicy' : 'startVideoMutedPolicy';
const mutedPolicyValue = state['features/base/conference'][mutedPolicyKey];
// Currently, the policy only supports force muting others, not unmuting them.
if (!mutedPolicyValue) {
return;
}
let muteStateUpdated = false;
const { muted } = isAudio ? state['features/base/media'].audio : state['features/base/media'].video;
if (isAudio && !Boolean(muted)) {
dispatch(setAudioMuted(mutedPolicyValue, true));
muteStateUpdated = true;
} else if (!isAudio && !Boolean(muted)) {
// TODO: Add a new authority for video mutism for the moderator case.
dispatch(setVideoMuted(mutedPolicyValue, VIDEO_MUTISM_AUTHORITY.USER, true));
muteStateUpdated = true;
}
if (muteStateUpdated) {
dispatch(showNotification({
titleKey: 'notify.mutedTitle',
descriptionKey: 'notify.muted',
uid: START_MUTED_NOTIFICATION_ID // use the same id, to make sure we show one notification
}, NOTIFICATION_TIMEOUT_TYPE.SHORT));
}
}

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/conference');
export default getLogger('app:base-conference');

View File

@@ -72,7 +72,6 @@ import {
} from './functions';
import logger from './logger';
import { IConferenceMetadata } from './reducer';
import './subscriber';
/**
* Handler for before unload event.

View File

@@ -1,61 +0,0 @@
import { IStore } from '../../app/types';
import { showNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import { setAudioMuted, setVideoMuted } from '../media/actions';
import { VIDEO_MUTISM_AUTHORITY } from '../media/constants';
import StateListenerRegistry from '../redux/StateListenerRegistry';
let hasShownNotification = false;
/**
* Handles changes in the start muted policy for audio and video tracks in the meta data set for the conference.
*/
StateListenerRegistry.register(
/* selector */ state => state['features/base/conference'].startAudioMutedPolicy,
/* listener */ (startAudioMutedPolicy, store) => {
_updateTrackMuteState(store, true);
});
StateListenerRegistry.register(
/* selector */ state => state['features/base/conference'].startVideoMutedPolicy,
/* listener */(startVideoMutedPolicy, store) => {
_updateTrackMuteState(store, false);
});
/**
* Updates the mute state of the track based on the start muted policy.
*
* @param {IStore} store - The redux store.
* @param {boolean} isAudio - Whether the track is audio or video.
* @returns {void}
*/
function _updateTrackMuteState(store: IStore, isAudio: boolean) {
const { dispatch, getState } = store;
const mutedPolicyKey = isAudio ? 'startAudioMutedPolicy' : 'startVideoMutedPolicy';
const mutedPolicyValue = getState()['features/base/conference'][mutedPolicyKey];
// Currently, the policy only supports force muting others, not unmuting them.
if (!mutedPolicyValue) {
return;
}
let muteStateUpdated = false;
const { muted } = isAudio ? getState()['features/base/media'].audio : getState()['features/base/media'].video;
if (isAudio && !Boolean(muted)) {
dispatch(setAudioMuted(mutedPolicyValue, true));
muteStateUpdated = true;
} else if (!isAudio && !Boolean(muted)) {
// TODO: Add a new authority for video mutism for the moderator case.
dispatch(setVideoMuted(mutedPolicyValue, VIDEO_MUTISM_AUTHORITY.USER, true));
muteStateUpdated = true;
}
if (!hasShownNotification && muteStateUpdated) {
hasShownNotification = true;
dispatch(showNotification({
titleKey: 'notify.mutedTitle',
descriptionKey: 'notify.muted'
}, NOTIFICATION_TIMEOUT_TYPE.SHORT));
}
}

View File

@@ -1,5 +1,6 @@
import { ToolbarButton } from '../../toolbox/types';
import { ILoggingConfig } from '../logging/types';
import { IAudioSettings } from '../settings/reducer';
import { DesktopSharingSourceType } from '../tracks/types';
type ButtonsWithNotifyClick = 'camera' |
@@ -191,6 +192,7 @@ export interface IConfig {
appId?: string;
audioLevelsInterval?: number;
audioQuality?: {
enableAdvancedAudioSettings?: boolean;
opusMaxAverageBitrate?: number | null;
stereo?: boolean;
};
@@ -237,6 +239,7 @@ export interface IConfig {
inactiveDisabled?: boolean;
};
constraints?: {
audio?: IAudioSettings;
video?: {
height?: {
ideal?: number;
@@ -521,7 +524,6 @@ export interface IConfig {
preCallTestEnabled?: boolean;
preCallTestICEUrl?: string;
};
prejoinPageEnabled?: boolean;
raisedHands?: {
disableLowerHandByModerator?: boolean;
disableLowerHandNotification?: boolean;
@@ -553,7 +555,7 @@ export interface IConfig {
disableDemote?: boolean;
disableGrantModerator?: boolean;
disableKick?: boolean;
disablePrivateChat?: 'all' | 'allow-moderator-chat';
disablePrivateChat?: 'all' | 'allow-moderator-chat' | 'disable-visitor-chat';
disabled?: boolean;
};
replaceParticipant?: string;

View File

@@ -202,7 +202,6 @@ export default [
'prejoinConfig.enabled',
'prejoinConfig.hideDisplayName',
'prejoinConfig.hideExtraJoinButtons',
'prejoinPageEnabled',
'raisedHands',
'recordingService',
'requireDisplayName',

View File

@@ -6,7 +6,9 @@ import { safeJsonParse } from '@jitsi/js-utils/json';
import { isEmpty, mergeWith, pick } from 'lodash-es';
import { IReduxState } from '../../app/types';
import { browser } from '../lib-jitsi-meet';
import { getLocalParticipant } from '../participants/functions';
import { isEmbedded } from '../util/embedUtils';
import { parseURLParams } from '../util/parseURLParams';
import { IConfig } from './configType';
@@ -255,6 +257,17 @@ export function isDisplayNameVisible(state: IReduxState): boolean {
return !state['features/base/config'].hideDisplayName;
}
/**
* Selector for determining if the advanced audio settings are enabled.
*
* @param {Object} state - The state of the app.
* @returns {boolean}
*/
export function isAdvancedAudioSettingsEnabled(state: IReduxState): boolean {
return !browser.isWebKitBased() && Boolean(state['features/base/config']?.audioQuality?.enableAdvancedAudioSettings);
}
/**
* Restores a Jitsi Meet config.js from {@code localStorage} if it was
* previously downloaded from a specific {@code baseURL} and stored with
@@ -335,7 +348,7 @@ export function setConfigFromURLParams(
overrideConfigJSON(config, interfaceConfig, json);
// Print warning about depricated URL params
// Print warning about deprecated URL params
if ('interfaceConfig.SUPPORT_URL' in params) {
logger.warn('Using SUPPORT_URL interfaceConfig URL overwrite is deprecated.'
+ ' Please use supportUrl from advanced branding!');
@@ -371,6 +384,13 @@ export function setConfigFromURLParams(
logger.warn('Using liveStreaming config URL overwrite and/or LIVE_STREAMING_HELP_LINK interfaceConfig URL'
+ ' overwrite is deprecated. Please use liveStreaming from advanced branding!');
}
// When not in an iframe, start without media if the pre-join page is not enabled.
if (!isEmbedded()
&& 'config.prejoinConfig.enabled' in params && config.prejoinConfig?.enabled === false) {
logger.warn('Using prejoinConfig.enabled config URL overwrite implies starting without media.');
config.disableInitialGUM = true;
}
}
/* eslint-enable max-params */

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/config');
export default getLogger('app:config');

View File

@@ -405,13 +405,6 @@ function _translateLegacyConfig(oldValue: IConfig) {
newValue.welcomePage.disabled = !oldValue.enableWelcomePage;
}
newValue.prejoinConfig = oldValue.prejoinConfig || {};
if (oldValue.hasOwnProperty('prejoinPageEnabled')
&& !newValue.prejoinConfig.hasOwnProperty('enabled')
) {
newValue.prejoinConfig.enabled = oldValue.prejoinPageEnabled;
}
newValue.disabledSounds = newValue.disabledSounds || [];
if (oldValue.disableJoinLeaveSounds) {

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/connection');
export default getLogger('app:connection');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/devices');
export default getLogger('app:devices');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/dialog');
export default getLogger('app:dialog');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/i18n');
export default getLogger('app:i18n');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/jitsi-local-storage');
export default getLogger('app:jitsi-local-storage');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/jwt');
export default getLogger('app:jwt');

View File

@@ -2,7 +2,6 @@ import React, { useCallback } from 'react';
import { makeStyles } from 'tss-react/mui';
import Icon from '../../../icons/components/Icon';
import { withPixelLineHeight } from '../../../styles/functions.web';
import { COLORS } from '../../constants';
interface IProps {
@@ -55,7 +54,7 @@ interface IProps {
const useStyles = makeStyles()(theme => {
return {
label: {
...withPixelLineHeight(theme.typography.labelRegular),
...theme.typography.labelRegular,
alignItems: 'center',
background: theme.palette.ui04,
borderRadius: '4px',

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/lastn');
export default getLogger('app:lastn');

View File

@@ -1,6 +1,7 @@
// @ts-ignore
import { safeJsonParse } from '@jitsi/js-utils/json';
import { NativeModules } from 'react-native';
// @ts-ignore
import { Worklets } from 'react-native-worklets-core';
import { loadScript } from '../util/loadScript.native';
@@ -8,7 +9,12 @@ import logger from './logger';
export * from './functions.any';
const { JavaScriptSandbox } = NativeModules;
/**
* Worklet context usefull for running small tasks off the JS thread.
*/
export const workletContext = Worklets.createContext('ConfigParser');
/**
* Loads config.js from a specific remote server.
@@ -18,14 +24,46 @@ const { JavaScriptSandbox } = NativeModules;
*/
export async function loadConfig(url: string): Promise<Object> {
try {
const configTxt = await loadScript(url, 10 * 1000 /* Timeout in ms */, true /* skipeval */);
const configJson = await JavaScriptSandbox.evaluate(`${configTxt}\nJSON.stringify(config);`);
const config = safeJsonParse(configJson);
const configTxt = await loadScript(url, 10 * 1000, true);
if (typeof config !== 'object') {
throw new Error('config is not an object');
const parseConfigAsync = workletContext.createRunAsync(function parseConfig(configText: string): string {
'worklet';
try {
// Used IIFE wrapper to capture config object from config.js
const configObj = eval(
'(function(){\n'
+ configText
+ '\n; return (typeof config !== "undefined" ? config : globalThis.config); })()'
);
if (configObj == void 0) {
return 'Worklet_Error: config is undefined after eval()';
}
if (typeof configObj !== 'object') {
return 'Worklet_Error: config is not an object';
}
return JSON.stringify(configObj);
} catch (err) {
return 'Worklet_Error:' + ((err as Error)?.message ?? String(err));
}
});
const workletConfig = await parseConfigAsync(configTxt);
if (typeof workletConfig !== 'string') {
throw new Error('Worklet error: workletConfig is not a string');
}
if (workletConfig.startsWith('Worklet_Error:')) {
const msg = workletConfig.slice('Worklet_Error:'.length);
throw new Error(`Worklet error: ${msg}`);
}
const config = safeJsonParse(workletConfig);
logger.info(`Config loaded from ${url}`);
return config;

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/lib-jitsi-meet');
export default getLogger('app:lib-jitsi-meet');

View File

@@ -17,8 +17,8 @@ const DEFAULT_LOGGING_CONFIG: ILoggingConfig = {
loggers: {
// The following are too verbose in their logging with the
// {@link #defaultLogLevel}:
'modules/RTC/TraceablePeerConnection': 'info',
'modules/xmpp/strophe.util': 'log'
'rtc:TraceablePeerConnection': 'info',
'xmpp:strophe.util': 'log'
}
};
@@ -41,10 +41,10 @@ const DEFAULT_STATE = {
// Reduce default verbosity on mobile, it kills performance.
if (navigator.product === 'ReactNative') {
const RN_LOGGERS: { [key: string]: LogLevel; } = {
'modules/sdp/SDPUtil': 'info',
'modules/xmpp/ChatRoom': 'warn',
'modules/xmpp/JingleSessionPC': 'info',
'modules/xmpp/strophe.jingle': 'info'
'sdp:SDPUtils': 'info',
'xmpp:ChatRoom': 'warn',
'xmpp:JingleSessionPC': 'info',
'xmpp:strophe.jingle': 'info'
};
DEFAULT_STATE.config.loggers = {

View File

@@ -3,7 +3,7 @@
*
* @enum {string}
*/
export const CAMERA_FACING_MODE = {
export const CAMERA_FACING_MODE: Record<string, string> = {
ENVIRONMENT: 'environment',
USER: 'user'
};

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/media');
export default getLogger('app:media');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/net-info');
export default getLogger('app:net-info');

View File

@@ -2,10 +2,12 @@
import { getGravatarURL } from '@jitsi/js-utils/avatar';
import { IReduxState, IStore } from '../../app/types';
import { isVisitorChatParticipant } from '../../chat/functions';
import { isStageFilmstripAvailable } from '../../filmstrip/functions';
import { isAddPeopleEnabled, isDialOutEnabled } from '../../invite/functions';
import { toggleShareDialog } from '../../share-room/actions';
import { iAmVisitor } from '../../visitors/functions';
import { IVisitorChatParticipant } from '../../visitors/types';
import { IStateful } from '../app/types';
import { GRAVATAR_BASE_URL } from '../avatar/constants';
import { isCORSAvatarURL } from '../avatar/functions';
@@ -827,18 +829,28 @@ export const setShareDialogVisiblity = (addPeopleFeatureEnabled: boolean, dispat
/**
* Checks if private chat is enabled for the given participant.
*
* @param {IParticipant|undefined} participant - The participant to check.
* @param {IParticipant|IVisitorChatParticipant|undefined} participant - The participant to check.
* @param {IReduxState} state - The Redux state.
* @returns {boolean} - True if private chat is enabled, false otherwise.
*/
export function isPrivateChatEnabled(participant: IParticipant | undefined, state: IReduxState) {
export function isPrivateChatEnabled(participant: IParticipant | IVisitorChatParticipant | undefined, state: IReduxState) {
const { remoteVideoMenu = {} } = state['features/base/config'];
const { disablePrivateChat } = remoteVideoMenu;
if (participant?.local || state['features/visitors'].iAmVisitor || disablePrivateChat === 'all') {
if ((!isVisitorChatParticipant(participant) && participant?.local) || disablePrivateChat === 'all') {
return false;
}
if (disablePrivateChat === 'disable-visitor-chat') {
// Block if the participant we're trying to message is a visitor
// OR if the local user is a visitor
if (isVisitorChatParticipant(participant) || iAmVisitor(state)) {
return false;
}
return true; // should allow private chat for other participants
}
if (disablePrivateChat === 'allow-moderator-chat') {
return isLocalParticipantModerator(state) || isParticipantModerator(participant);
}

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/participants');
export default getLogger('app:participants');

View File

@@ -24,12 +24,14 @@ import { hideNotification, showNotification } from '../../notifications/actions'
import {
LOCAL_RECORDING_NOTIFICATION_ID,
NOTIFICATION_TIMEOUT_TYPE,
RAISE_HAND_NOTIFICATION_ID
RAISE_HAND_NOTIFICATION_ID,
VISITOR_ASKED_TO_JOIN_NOTIFICATION_ID
} from '../../notifications/constants';
import { open as openParticipantsPane } from '../../participants-pane/actions';
import { CALLING, INVITED } from '../../presence-status/constants';
import { RAISE_HAND_SOUND_ID } from '../../reactions/constants';
import { RECORDING_OFF_SOUND_ID, RECORDING_ON_SOUND_ID } from '../../recording/constants';
import { iAmVisitor } from '../../visitors/functions';
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes';
import { CONFERENCE_JOINED, CONFERENCE_WILL_JOIN } from '../conference/actionTypes';
import { forEachConference, getCurrentConference } from '../conference/functions';
@@ -167,7 +169,10 @@ MiddlewareRegistry.register(store => next => action => {
case LOCAL_PARTICIPANT_RAISE_HAND: {
const { raisedHandTimestamp } = action;
const localId = getLocalParticipant(store.getState())?.id;
const localParticipant = getLocalParticipant(store.getState());
const localId = localParticipant?.id;
const _iAmVisitor = iAmVisitor(store.getState());
const isHandRaised = hasRaisedHand(localParticipant);
store.dispatch(participantUpdated({
// XXX Only the local participant is allowed to update without
@@ -186,6 +191,18 @@ MiddlewareRegistry.register(store => next => action => {
raisedHandTimestamp
}));
if (_iAmVisitor) {
const notifyAction = isHandRaised
? hideNotification(VISITOR_ASKED_TO_JOIN_NOTIFICATION_ID)
: showNotification({
titleKey: 'visitors.notification.requestToJoin',
descriptionKey: 'visitors.notification.requestToJoinDescription',
uid: VISITOR_ASKED_TO_JOIN_NOTIFICATION_ID
}, NOTIFICATION_TIMEOUT_TYPE.STICKY);
store.dispatch(notifyAction);
}
if (typeof APP !== 'undefined') {
APP.API.notifyRaiseHandUpdated(localId, raisedHandTimestamp);
}

View File

@@ -3,7 +3,6 @@ import { makeStyles } from 'tss-react/mui';
import Icon from '../../../icons/components/Icon';
import { IconArrowDown } from '../../../icons/svg';
import { withPixelLineHeight } from '../../../styles/functions.web';
interface IProps {
@@ -82,7 +81,7 @@ interface IProps {
const useStyles = makeStyles()(theme => {
return {
actionButton: {
...withPixelLineHeight(theme.typography.bodyLongBold),
...theme.typography.bodyLongBold,
borderRadius: theme.shape.borderRadius,
boxSizing: 'border-box',
color: theme.palette.text01,
@@ -115,7 +114,7 @@ const useStyles = makeStyles()(theme => {
'&.text': {
width: 'auto',
fontSize: '13px',
fontSize: '0.875rem',
margin: '0',
padding: '0'
},
@@ -135,7 +134,7 @@ const useStyles = makeStyles()(theme => {
[theme.breakpoints.down(400)]: {
fontSize: 16,
fontSize: '1rem',
marginBottom: 8,
padding: '11px 16px'
}

View File

@@ -5,7 +5,6 @@ import { makeStyles } from 'tss-react/mui';
import Icon from '../../../icons/components/Icon';
import { IconArrowDown, IconCloseCircle, IconWifi1Bar, IconWifi2Bars, IconWifi3Bars } from '../../../icons/svg';
import { withPixelLineHeight } from '../../../styles/functions.web';
import { PREJOIN_DEFAULT_CONTENT_WIDTH } from '../../../ui/components/variables';
import Spinner from '../../../ui/components/web/Spinner';
import { runPreCallTest } from '../../actions.web';
@@ -16,7 +15,7 @@ const useStyles = makeStyles()(theme => {
return {
connectionStatus: {
color: '#fff',
...withPixelLineHeight(theme.typography.bodyShortRegular),
...theme.typography.bodyShortRegular,
position: 'absolute',
width: '100%',

View File

@@ -10,7 +10,6 @@ import Toolbox from '../../../../toolbox/components/web/Toolbox';
import { isButtonEnabled } from '../../../../toolbox/functions.web';
import { getConferenceName } from '../../../conference/functions';
import { PREMEETING_BUTTONS, THIRD_PARTY_PREJOIN_BUTTONS } from '../../../config/constants';
import { withPixelLineHeight } from '../../../styles/functions.web';
import Tooltip from '../../../tooltip/components/Tooltip';
import { isPreCallTestEnabled } from '../../functions';
@@ -152,7 +151,7 @@ const useStyles = makeStyles()(theme => {
width: '100%'
},
title: {
...withPixelLineHeight(theme.typography.heading4),
...theme.typography.heading4,
color: `${theme.palette.text01}!important`,
marginBottom: theme.spacing(3),
textAlign: 'center',
@@ -168,7 +167,7 @@ const useStyles = makeStyles()(theme => {
},
roomName: {
...withPixelLineHeight(theme.typography.heading5),
...theme.typography.heading5,
color: theme.palette.text01,
display: 'inline-block',
overflow: 'hidden',

View File

@@ -2,8 +2,6 @@ import React from 'react';
import { useTranslation } from 'react-i18next';
import { makeStyles } from 'tss-react/mui';
import { withPixelLineHeight } from '../../../styles/functions.web';
const useStyles = makeStyles()(theme => {
return {
warning: {
@@ -11,7 +9,7 @@ const useStyles = makeStyles()(theme => {
color: theme.palette.text03,
display: 'flex',
justifyContent: 'center',
...withPixelLineHeight(theme.typography.bodyShortRegular),
...theme.typography.bodyShortRegular,
marginBottom: theme.spacing(3),
marginTop: theme.spacing(2),
paddingLeft: theme.spacing(3),

View File

@@ -4,7 +4,6 @@ import { useDispatch, useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import { IReduxState } from '../../../../app/types';
import { withPixelLineHeight } from '../../../styles/functions.web';
import Checkbox from '../../../ui/components/web/Checkbox';
import getUnsafeRoomText from '../../../util/getUnsafeRoomText.web';
import { setUnsafeRoomConsent } from '../../actions.web';
@@ -14,7 +13,7 @@ const useStyles = makeStyles()(theme => {
warning: {
backgroundColor: theme.palette.warning01,
color: theme.palette.text04,
...withPixelLineHeight(theme.typography.bodyShortRegular),
...theme.typography.bodyShortRegular,
padding: theme.spacing(3),
borderRadius: theme.shape.borderRadius,
marginBottom: theme.spacing(3)

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/premeeting');
export default getLogger('app:premeeting');

View File

@@ -6,6 +6,7 @@ import { translate } from '../../../i18n/functions';
import Icon from '../../../icons/components/Icon';
import Tooltip from '../../../tooltip/components/Tooltip';
import { TOOLTIP_POSITION } from '../../../ui/constants.any';
import { pixelsToRem } from '../../../ui/functions.any';
/**
* The type of the React {@code Component} props of {@link BaseIndicator}.
@@ -40,7 +41,7 @@ interface IProps extends WithTranslation {
/**
* The font size for the icon.
*/
iconSize: string | number;
iconSize: number;
/**
* The ID attribute to set on the root element of the component.
@@ -88,10 +89,10 @@ const BaseIndicator = ({
tooltipPosition = 'top'
}: IProps) => {
const { classes: styles } = useStyles();
const style: { fontSize?: string | number; } = {};
const style: { fontSize?: string; } = {};
if (iconSize) {
style.fontSize = iconSize;
style.fontSize = pixelsToRem(iconSize);
}
return (

View File

@@ -3,7 +3,6 @@ import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { makeStyles } from 'tss-react/mui';
import { withPixelLineHeight } from '../../../styles/functions.web';
import Button from '../../../ui/components/web/Button';
import { getSupportUrl } from '../../functions';
@@ -15,7 +14,7 @@ const useStyles = makeStyles()(theme => {
borderRadius: `${Number(theme.shape.borderRadius)}px`,
boxShadow: '0px 1px 2px rgba(41, 41, 41, 0.25)',
color: theme.palette.text01,
...withPixelLineHeight(theme.typography.bodyShortRegular),
...theme.typography.bodyShortRegular,
padding: `${theme.spacing(3)} 10`,
'& .retry-button': {
margin: '16px auto 0 auto'

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/react');
export default getLogger('app:react');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/redux');
export default getLogger('app:redux');

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/settings');
export default getLogger('app:settings');

View File

@@ -51,8 +51,15 @@ const DEFAULT_STATE: ISettingsState = {
userSelectedMicDeviceLabel: undefined
};
export interface IAudioSettings {
autoGainControl?: boolean;
channelCount?: 1 | 2;
echoCancellation?: boolean;
noiseSuppression?: boolean;
}
export interface ISettingsState {
audioOutputDeviceId?: string;
audioSettings?: IAudioSettings;
audioSettingsVisible?: boolean;
avatarURL?: string;
cameraDeviceId?: string | boolean;
@@ -66,6 +73,7 @@ export interface ISettingsState {
localFlipX?: boolean;
maxStageParticipants?: number;
micDeviceId?: string | boolean;
previewAudioTrack?: any | null;
serverURL?: string;
showSubtitlesOnStage?: boolean;
soundsIncomingMessage?: boolean;

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/sounds');
export default getLogger('app:sounds');

View File

@@ -22,17 +22,3 @@ export function getFixedPlatformStyle(style?: StyleType | StyleType[]) {
return style;
}
/**
* Sets the line height of a CSS Object group in pixels.
* By default lineHeight is unitless in CSS, but not in RN.
*
* @param {Object} base - The base object containing the `lineHeight` property.
* @returns {Object}
*/
export function withPixelLineHeight(base: any) {
return {
...base,
lineHeight: `${base.lineHeight}px`
};
}

View File

@@ -1,3 +1,3 @@
import { getLogger } from '../logging/functions';
export default getLogger('features/base/testing');
export default getLogger('app:testing');

View File

@@ -6,7 +6,6 @@ import { makeStyles } from 'tss-react/mui';
import { IReduxState } from '../../../app/types';
import { isMobileBrowser } from '../../environment/utils';
import Popover from '../../popover/components/Popover.web';
import { withPixelLineHeight } from '../../styles/functions.web';
import { TOOLTIP_POSITION } from '../../ui/constants.any';
import { hideTooltip, showTooltip } from '../actions';
@@ -26,7 +25,7 @@ const useStyles = makeStyles()(theme => {
backgroundColor: theme.palette.uiBackground,
borderRadius: '3px',
padding: theme.spacing(2),
...withPixelLineHeight(theme.typography.labelRegular),
...theme.typography.labelRegular,
color: theme.palette.text01,
position: 'relative',

View File

@@ -164,6 +164,7 @@ export function createLocalTracksA(options: ITrackOptions = {}) {
= createLocalTracksF(
{
cameraDeviceId: options.cameraDeviceId,
constraints: options?.constraints,
devices: [ device ],
facingMode:
options.facingMode || getCameraFacingMode(state),

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