Compare commits

...

198 Commits
7204 ... 7378

Author SHA1 Message Date
MrAndriy
a51b377d6b fix(lang, rn) add Ukrainian lang to builtinLanguages
Fixes: https://github.com/jitsi/jitsi-meet/issues/13401
2023-07-06 13:09:12 +02:00
Calin-Teodor
f5d764e3df feat(react-native-sdk): updated dependencies 2023-07-06 09:46:16 +03:00
Jaya Allamsetty
f71f6d9a0d chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1652.0.0+90da4884...v1654.0.0+782350e0
2023-07-05 11:56:52 -04:00
Calin-Teodor
78b8c811af deps(react-navigation): updated to latest 2023-07-05 15:55:31 +03:00
Calin-Teodor
10d8d71d8b deps(react-native-screens): updated to latest 2023-07-05 14:10:33 +03:00
Calinteodor
9e48943daf sdk(react-native-sdk): fixes (#13525)
* sdk(react-native-sdk): fix path, logs and dependency values.
2023-07-05 14:10:01 +03:00
Christoph Settgast
9f118c6b82 lang: update German translation 2023-07-04 22:12:37 +02:00
Robert Pintilii
2c8dedcb85 ref(scss) Variables cleanup (#13521)
Remove some unused variables
Replace variables that are only used once with their value
2023-07-04 12:34:41 +03:00
Calinteodor
f950dc90b9 sdk(react-native-sdk): added script that updates app dependencies (#13516)
* sdk(react-native-sdk): created script for missing dependencies
2023-07-04 11:09:58 +03:00
Saúl Ibarra Corretgé
92ca7a598a fix(jwt) fix not processing features if avatar, name, email are missing 2023-07-04 07:00:02 +02:00
Jaya Allamsetty
97f9d747c0 fix(config): Remove the deprecated configs. (#13500)
* fix(config): Remove the deprecated configs.
Add the new codec selection settings for desktop and mobile endpoints.

* fix(config): Use the new codec selection settings for RN.

* Address review comments.

* chore(deps) Update lib-jitsi-meet@latest.
https://github.com/jitsi/lib-jitsi-meet/compare/v1649.0.0+17ade96a...v1652.0.0+90da4884.
2023-07-03 18:25:44 -04:00
Hristo Terezov
159dd13c2d fix(chat-URLs): Use punycode only on host name.
This is workaround for PunycodeJS which truncates parts of the URL when
it contains '@'.
2023-07-03 11:16:27 -05:00
Saúl Ibarra Corretgé
98c6df0c10 deps(rn) update react-native-webrtc to 111.0.3
Fixes an issue where the transceiverf mid wasn't set.
2023-07-03 15:53:23 +02:00
Robert Pintilii
8acce9a2f5 fix(keyboard-shortcuts) Check modifier key (#13520) 2023-07-03 14:33:06 +03:00
Robert Pintilii
52fbd3aeb8 ref(toolbar) Convert to function component (#13511)
Extract keyboard shortcuts logic to custom hook
2023-07-03 12:58:58 +03:00
Saúl Ibarra Corretgé
e9b2d8ecdf deps(rn) update react-native-webrtc to 111.0.2
Fixes not receiving video in P2P mode when the mobile user starts with
video muted and is also the offerer.
2023-07-03 11:58:08 +02:00
Saúl Ibarra Corretgé
cdc4154cdf fix(android) remove no longer needed view clipping hack
This should no longer be necessary since we added it for Android 6
devices a long time ago but we no longer support those.

Fixes: https://github.com/jitsi/jitsi-meet/issues/13514
2023-07-03 11:57:50 +02:00
Calinteodor
16cacec43c sdk(react-native-sdk): moved some dependencies to peer dependencies (#13498)
* sdk(react-native-sdk): moved some dependencies to peer dependencies

https://github.com/react-native-community/cli/issues/870

https://github.com/callstack/react-native-builder-bob#how-do-i-add-a-react-native-library-containing-native-code-as-a-dependency-in-my-library
2023-06-30 16:12:00 +03:00
Robert Pintilii
877fbe63c1 fix(dialog) Fix close on backdrop (#13512) 2023-06-30 10:59:33 +03:00
Дамян Минков
322d846bd9 fix: Drop events if conn is closed while waiting for jicofo. 2023-06-29 11:31:31 -05:00
Gabriel Borlea
ca8c055a58 fix(shortcuts): reactions description translations (#13504)
* fix(shortscuts): reactions description translations

* fix lint
2023-06-29 15:58:46 +03:00
Robert Pintilii
2d8014775a ref(toolbar) Move getButtons to functions (#13502)
Move visible logic inside each button
Move click functionality inside each button
Extract getButtons function from Toolbox components to functions file
2023-06-29 14:59:12 +03:00
Saúl Ibarra Corretgé
699b797e0f feat(rn,settings) add field with SDK version
This helps us know it at a glance, from applications using it, without
having to look at any logs.
2023-06-29 11:30:45 +02:00
Saúl Ibarra Corretgé
a8e2fcdfea fix(ios) fix UUID comparison
Fixes: https://github.com/jitsi/jitsi-meet/issues/12716
2023-06-29 10:52:40 +02:00
Jaya Allamsetty
99016baa42 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1643.0.0+0748d89a...v1649.0.0+17ade96a
2023-06-28 12:27:11 -04:00
Hristo Terezov
6187bb928a fix(Popup): Invalid reference. 2023-06-28 09:13:24 -05:00
Hristo Terezov
fab8a98cf7 fix(iframe): Add allow screen-wake-lock. 2023-06-27 11:45:11 -05:00
Calinteodor
00092b79af sdk(react-native-sdk): react native sdk updates (#13482)
* sdk(react-native-sdk): minor updates
2023-06-27 15:38:12 +03:00
D1eter
ba26407469 fix: store only "clean" URLs in recent-list (#13489)
* store only "clean" URLs in recent-list

* remove spaces in parentheses
2023-06-26 08:30:17 -05:00
Mohammad Kazemi
63e40c9e03 lang: Farsi (Persian) translation (#13463)
* Translated using Weblate (Persian)

Currently translated at 4.0% (52 of 1272 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 7.8% (100 of 1272 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 32.0% (408 of 1272 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 51.0% (654 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 66.1% (848 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 67.2% (862 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 72.0% (924 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 75.6% (970 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (1282 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (1282 of 1282 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/

* Translated using Weblate (Persian)

Currently translated at 100.0% (1288 of 1288 strings)

Translation: Jitsi/Jitsi-meet
Translate-URL: https://translate.codeberg.org/projects/jitsi/jitsi-meet/fa/
2023-06-24 14:28:09 -05:00
Aaron van Meerten
cbac122525 feature: allowlist checking for token verification module (#13488) 2023-06-23 15:48:19 -04:00
damencho
9af56d52c2 fix: Adds one more check for iframes. 2023-06-23 11:05:37 -05:00
José Luís Andrade
2a9c40f0d2 lang: Update Portuguese translation (#13481) 2023-06-23 09:18:46 -05:00
Jaya Allamsetty
3ae18be21f fix(lastn) Update lastN on virtual screenshare updates.
Fixes https://github.com/jitsi/jitsi-meet/issues/13448.
2023-06-21 12:30:16 -04:00
Calinteodor
9f5dbb21a7 feat(base/media): fixed movement inside zoomed screenshare (#13476)
* feat(base/media): fixed movement inside zoomed screenshare
2023-06-21 11:59:03 +03:00
Mihaela Dumitru
2d14990b9e chore(deps) update excalidraw to fix load issues with bigger whiteboards (#13474) 2023-06-20 17:43:22 +03:00
Calin-Teodor
169c8ecb62 sdk(react-native-sdk): added generated folders to gitignore 2023-06-20 16:23:19 +03:00
Horatiu Muresan
d608cf40f5 fix(prejoin) Check for valid url for prejoin (#13468)
- `getPropertyValue` calls `parseUrlParam` with the connection URL from store, which is not yet defined
2023-06-19 15:52:38 +03:00
Emmanuel Pelletier
51a4e7daa3 Globally improve accessibility for screen reader users (#12969)
feat(a11y): Globally improve accessibility for screen reader users
2023-06-19 14:34:41 +03:00
arunnadesh
7538bfc713 fix(AudioTrack) fix currentMuted
Co-authored-by: Arun Nadesh <arun.raveendran@hg.ninjavan.co>
2023-06-19 09:51:46 +02:00
Saúl Ibarra Corretgé
48e1f443ea fix(password) use the numeric input mode when only digits are required
Fixes: https://github.com/jitsi/brave-tracker/issues/101
2023-06-16 15:50:27 +02:00
Robert Pintilii
2292ebe762 fix(transcriptions) Open correct settings tab (#13460) 2023-06-15 16:02:12 +03:00
Hristo Terezov
5425b52615 fix(horizontal-filmstrip): JS error.
Fixes the following JS error which prevents the whole page from
rendering:
TypeError: Cannot read properties of null (reading 'offsetHeight')
2023-06-14 18:28:32 -05:00
Hristo Terezov
74f605e045 fix(screenLock): Improve.
- Add debug logs.
 - Re-request wake lock if it is released by the OS because of page
visibility.
2023-06-14 11:15:37 -05:00
Alexander Bigga
1918566581 fix(lang) update German translation 2023-06-13 11:21:36 -05:00
Saúl Ibarra Corretgé
ee8ba6696d fix(full-screen) drop no longer needed checks
The vendored prefix on Firefox was removed on version 64.

We still need the vendored version for Safari since the prefix got
dropped in 16.4.
2023-06-12 13:55:45 +02:00
Saúl Ibarra Corretgé
15df3cb11e fix(toolbox) drop unneeded checks
These are web files, no need to check if APP is undefined.
2023-06-12 13:55:45 +02:00
Robert Pintilii
b77db024f5 fix(settings-dialog) On mobile open on the correct tab (#13443) 2023-06-12 13:55:32 +03:00
Robert Pintilii
c8a87e368a fix(local-rec) Fix audio only recording (self) (#13442) 2023-06-12 11:21:20 +03:00
garysmith058
277ca23c52 feat(external-api) Forward non participant message to iframe (#13440)
* Forward non-participant-message-received to iFrame API

* Updated comment

* Fix lint errors
2023-06-12 11:10:42 +03:00
Eze Posada
55f66e236e fix(lang) update Spanish translation 2023-06-11 08:53:48 +02:00
Hristo Terezov
70be08212d fix(RN): broken build after AV pending changes. 2023-06-09 17:38:03 -05:00
Horatiu Muresan
acb91990bf fix(notif-sounds) Set correct audio output device for notifs (#13436) 2023-06-09 13:20:20 +03:00
Mihaela Dumitru
cd37cdd675 feat(bwe) support setting the bandwidth from the client (#13335)
* feat(bwe) support setting the bandwidth from the client
2023-06-08 17:44:01 +03:00
Filip Rejmus
935a391525 feat(rnsdk) add initial React Native SDK
Co-authored-by: Calin-Teodor <calin.chitu@8x8.com>
Co-authored-by: Saúl Ibarra Corretgé <saghul@jitsi.org>
2023-06-08 15:22:11 +02:00
Robert Pintilii
d0f9231603 fix(moderation) Show Screensharing blocked notification (#13433)
When video moderation is on and the participant tries to share their screen show a notification saying the screen sharing is blocked
2023-06-08 11:52:36 +03:00
Saúl Ibarra Corretgé
e461ec7027 fix(e2ee) fix config migration of e2eeLabels 2023-06-08 10:39:09 +02:00
Avram Tudor
5dc63f0632 fix: remove harcoded url (#13426) 2023-06-08 09:33:21 +03:00
damencho
f3dbf34842 fix(visitors): Move some logs to debug. 2023-06-07 09:41:16 -05:00
Daniel Hansson
66a9c4df25 lang: Improve Swedish translation (#13356)
* Update main-sv.json

* fix typo

* CI fixes

* untranslate string

* add missing translation

* fix CI

ok, foundthe issue....
2023-06-07 08:58:06 -05:00
Mihaela Dumitru
e95a31c114 feat(external-api) add function and event to check p2p status (#13406) 2023-06-07 09:45:17 +03:00
Robert Pintilii
8565208d30 fix(chat-input) Autofocus when sending private message (#13400) 2023-06-07 09:27:49 +03:00
Hristo Terezov
c1573057df feat(screen-lock): request on conference join. 2023-06-06 12:57:47 -05:00
damencho
904f820555 feat: Adds a stat for limited ips. 2023-06-06 11:22:35 -05:00
Horatiu Muresan
5172eda6b9 fix(toolbar) Fix auto-hide toolbar in tileview (#13424) 2023-06-06 15:32:50 +03:00
Jaya Allamsetty
594a05a097 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1642.0.0+7661b564...v1643.0.0+0748d89a
2023-06-05 13:25:49 -04:00
damencho
9ccdb62872 fix(visitors): Fixes delivering visitors presence to jicofo. 2023-06-02 10:46:46 -05:00
Jaya Allamsetty
28d32cf740 fix(visitors): Ignore push-to-talk shortcut. 2023-06-02 10:49:36 -04:00
Jaya Allamsetty
ecc9b991ab fix(device-selection): Do not create multiple tracks for the same deviceId.
Also, log an error when when the application fails to switch to the selected audio output device.
2023-06-01 20:41:49 -04:00
Jaya Allamsetty
5b83a91f9b chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1639.0.0+d2179f31...v1642.0.0+7661b564
2023-06-01 16:04:06 -04:00
Hristo Terezov
bb7ae777b0 feat(unmute/track creation): pending indicator. 2023-06-01 14:07:56 -05:00
damencho
06e86a2f3e fix(visitors): Fixes s2s multiple connections.
We cannot use filters with s2s as not sending a stanza will result skipping existing connection and creating a new one.
This also clears some of the "No hosts[from_host] (please report)" errors, but there is still one (easy to repro is we disable the jicofo locking) on join we see a presence trying to be routed using the wrong from (virtual  tenant jid).
2023-05-31 18:20:05 -05:00
Jaya Allamsetty
0a84dbb302 fix(participants): Ignore orphan tracks in ssrc-rewriting mode.
Gets rid of an unwanted error that gets printed in the log when there are orphan tracks.
2023-05-31 12:05:28 -04:00
Horatiu Muresan
804f9041a6 chore(settings) Move language to general tab (#13405) 2023-05-31 12:19:16 +03:00
damencho
7e8756a536 fix(visitors): Fixes rate limit module.
Rate limit to ignore outgoing sessions, otherwise it fails to discover ip and fails with an error.
2023-05-30 09:04:22 -05:00
Mohammad Kazemi
3b91e79675 fix(lang) update Farsi translation 2023-05-30 12:08:31 +02:00
Calinteodor
dfc25e4519 sdk(android): modules rework to not depend on our instance manager holder (#13346)
* sdk(android): rework events and variables inside modules to not depend on our instance manager holder
2023-05-26 11:46:15 +03:00
Robert Pintilii
d40aecb05d feat(toolbox) Shift up to make tile name visible 2023-05-25 15:26:04 +02:00
Saúl Ibarra Corretgé
34e0b0392f Fix build after Giphy update (#13393)
* fix(android/ios): fix build after Giphy update
2023-05-25 14:45:20 +03:00
damencho
8cc4a3c8b9 fix(visitors): Fixes patch. 2023-05-24 22:53:21 -05:00
Дамян Минков
354a3c002a fix(visitors): Fixes leaking s2s connections. (#13391)
* fix(visitors): Fixes leaking s2s connections.

* squash: Split patches in two.

* squash: Adds some comments in patch.

* squash: Fix patch destination.
2023-05-24 15:12:41 -05:00
Jaya Allamsetty
7d5eec779e chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1637.0.0+8f836678...v1639.0.0+d2179f31
2023-05-23 16:05:15 -04:00
damencho
90029003be fix: Fix matching user affiliation. 2023-05-23 14:48:49 -05:00
damencho
c781884532 fix(visitors): Filters some more presences coming back to main prosody.
When the first visitor joins and the jicofo-lock was activated some presences had wrong from (the tenant form that needs to be only between clients and server) and was processed and sent over s2s causing some errors on the other side.
2023-05-23 09:35:03 -05:00
damencho
7272fd62a0 fix(visitors): Filters some presences coming back to main prosody.
Still is not filtering stanzas coming on s2s and it directly routes it back to the main prosody when it goes through jicofo lock feature.
2023-05-23 09:35:03 -05:00
damencho
f21bd62ed0 fix(visitors): Change log level. 2023-05-23 09:35:03 -05:00
damencho
842d0a9aef fix(visitors): Do not send error replies for errors. 2023-05-23 09:35:03 -05:00
Saúl Ibarra Corretgé
e06645a631 feat(rn,config) use more efficient codecs on mobile 2023-05-23 15:33:06 +02:00
Mihaela Dumitru
ebb65ea90c chore(deps) update @giphy/react-native-sdk to latest (#13383) 2023-05-23 14:01:45 +03:00
Saúl Ibarra Corretgé
a7831ad809 chore(deps) react-native-webrtc@111.0.1
GCM ciphers are now enabled by default.
2023-05-23 11:38:52 +02:00
Hristo Terezov
80cfb80397 fix(API)setLargeVideoParticipant ensure stage view 2023-05-22 16:10:26 -05:00
Robert Pintilii
ae281e9935 ref(TS) Improve TS (#13370)
Use correct types for action, dispatch and getState
2023-05-22 09:54:11 +03:00
Jaya Allamsetty
b800ad8427 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1636.0.0+f429c05f...v1637.0.0+8f836678
2023-05-19 09:48:00 -04:00
Horatiu Muresan
051cf67ce9 aesthetics 2023-05-18 17:30:24 -05:00
Horatiu Muresan
85e1333ad9 fix(toolbox-visible) Fix hiding toolbox
- clicking toolbox button was keeping focus on toolbox even after mouse move(as focus would only be changed when clicking on some other element), so .toolbox-content-items:focus-within selector was returning a value even when mouse was moved from toolbox
- .filmstrip:focus-within did not seem to ever activate, I replaced with :hover since the intent was probably to keep the toolbox open while filmstrip is hovered
2023-05-18 17:30:24 -05:00
Hristo Terezov
f02c7557af fix(CI): Eslint warning for testing ignored files. 2023-05-18 17:09:16 -05:00
Hristo Terezov
e82a5cf150 fix(web-hid): Fully disable from config 2023-05-18 13:42:12 -05:00
Saúl Ibarra Corretgé
c92ce56110 fix(stale) migrate stale to GH actions 2023-05-18 06:59:49 -05:00
Horatiu Muresan
4cae954eba fix(reactions-popup) Fix tooltip not closing correctly (#13367)
- tooltip was reopening in an inconsistent state(without the tooltip text visible), taking the focus from the reactions popup
- removed duplicate store prop from ReactionsMenuButton
2023-05-18 12:18:36 +03:00
damencho
b9d5838398 feat(jaas-example): Uses conf-id generated from token generator. 2023-05-17 14:42:22 -05:00
damencho
fcf723c679 fix: Adds visitor messages to the room history. 2023-05-17 13:24:46 -05:00
Robert Pintilii
06b67dcf44 ref(TS) Improve TS (#13365)
Change some any types to the correct types
2023-05-17 13:05:47 +03:00
Robert Pintilii
61e9cacceb feat(CI) Improve CI (#13360)
Only run lang steps (sort and jsonlint) if there is at least one changed lang file
Run eslint only on the changed files (.js, .ts, .tsx)
2023-05-17 09:45:55 +03:00
Дамян Минков
475c2f4606 fix(visitors): Leave and disconnect before connecting. (#13362)
* fix(visitors): Leave and disconnect before connecting.

The finally was causing the disconnect to be executed after the connect method.

* squash: disconnect and on error.

* squash: updates ljm with a fix that can break strophe listeners.
2023-05-16 16:24:26 -05:00
Calin-Teodor
20f2bfa449 feat(ios): podfile.lock update 2023-05-16 19:56:30 +03:00
kerem
4c0c36d233 feat(deps,rn) update React Native to version 0.69.9 (#13241)
* feat(deps,rn) update React Native to version 0.69
2023-05-16 19:12:51 +03:00
Robert Pintilii
59f1ee1e1e ref(TS) Improve TS (#13355) 2023-05-16 12:34:30 +03:00
Jaya Allamsetty
1af90a208e chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1633.0.0+6eb33daf...v1635.0.0+152fdb21
2023-05-15 21:44:33 -04:00
damencho
22c6b72a75 fix: Do not allow visitors while lobby is enabled. 2023-05-15 16:19:16 -05:00
Дамян Минков
d8c7f8de81 feat: Jaas example that uses local jitsi-meet (#13350)
* feat: Adds an example to convert a deployment to use jaas.

* squash: Generates the daily asap token with expiration of 1 day.

The default is 1 hour.

* squash: Use local deployment UI with jaas, not 8x8.vc one.

- We load config.js from 8x8.vc with the tenant, to allow release pinning to work.

- We sed the vpass_cookie in the custom nginx conf as variables are not allowed in location matching.

- The jaas-vars need to be global as it will overwrite config.js location and index html.

* squash: Enables e2ee for the meetings.

* squash: Bump node version check.

* squash: Fix filename.

* squash: Updates the readme.

* squash: Checks whether node is installed.

* squash: Fixes initial configuration.

The jaas-vars is required to reload nginx, done by update-asap-daily script.

* squash: More fixes of misspelled config file.

* squash: Fixes serving the pub key.
2023-05-15 14:52:27 -05:00
José Luís Andrade
f76122f0b0 fix(lang) update Portuguese translation 2023-05-15 11:08:37 +02:00
Robert Pintilii
63927db9e4 ref(self-view) Move Hide self view to General tab (#13339) 2023-05-12 16:40:36 +03:00
Robert Pintilii
6b28af8329 ref(flow) Remove flow (#13343)
Remove flow-related packages
Remove type annotations from JS files
2023-05-12 16:39:18 +03:00
Jaya Allamsetty
ccebccf8e6 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1632.0.0+e4966db9...v1633.0.0+6eb33daf
2023-05-12 08:43:08 -04:00
Gabriel Borlea
279a4efb83 fix(prejoin): avoid bypass unsafe consent when enter is pressed in name input (#13344) 2023-05-12 15:13:35 +03:00
Mihaela Dumitru
ceac1ab25f chore(deps) bump excalidraw version 2023-05-12 14:00:47 +02:00
Robert Pintilii
2ba6bcf172 chore(deps) Upgrade eslint (#13341)
Upgrade eslint related packages
Fix new errors
2023-05-12 13:24:50 +03:00
Robert Pintilii
ae0669fa07 ref(TS) Convert always-on-top to TS (#13332) 2023-05-12 10:28:50 +03:00
Saúl Ibarra Corretgé
71627f97f7 fix(android) set MainActivity launch mode to singleInstance 2023-05-11 13:49:22 +02:00
Jaya Allamsetty
e35338b73d chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1631.0.0+f0dd4039...v1632.0.0+e4966db9
2023-05-09 15:31:28 -04:00
Gabriel Borlea
a112d38943 feat(prejoin) add unsafe room name warning 2023-05-09 20:04:58 +02:00
Horatiu Muresan
b705c63a65 fix(local-recording) Enable local rec for non-moderators (#13334) 2023-05-09 17:52:20 +03:00
Saúl Ibarra Corretgé
b4c8f7d097 feat(external-api) optional sandbox
Add optional "sandbox" option to the external API which will be applied
to the iframe.
2023-05-09 15:18:28 +02:00
Robert Pintilii
74bac9806f fix(virtual-background) Use correct video device (#13329)
In the case when the user selects a new video device then goes to Virtual Background without saving first, use the newly selected device for the virtual background preview instead of the saved one
2023-05-09 15:39:51 +03:00
Robert Pintilii
65248d7d29 chore(deps) Upgrade TS (#13331)
Upgrade typescript related packages
Fix new errors and warnings
2023-05-09 15:39:31 +03:00
Robert Pintilii
dc037bc8dd ref(TS) Convert some native components to TS (#13307) 2023-05-09 12:10:46 +03:00
Robert Pintilii
a22db037c7 ref(TS) Improve TS (#13282)
Remove unnecessary @ts-ignores
Use @ts-expect-error instead of @ts-ignore for external dependencies
2023-05-09 11:05:11 +03:00
Horatiu Muresan
44cc0f7e9a fix(toolbar-buttons) Hide rec and livestream buttons for non-moderators (#13328) 2023-05-08 19:17:01 +03:00
Calinteodor
eafb337cd1 feat(video-menu): native track volume control updates (#13305)
* feat(video-menu/native): added volume slider control for remote participants
2023-05-08 16:33:45 +03:00
damencho
9b3be66287 feat: Updates unsupported desktop to tsx.
Easier to apply branding.
2023-05-05 12:44:33 -05:00
Jaya Allamsetty
1a10a00f74 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1629.0.0+1714bf07...v1631.0.0+f0dd4039
2023-05-05 11:05:50 -04:00
George Politis
a196bc27b8 Update RTCStats.ts
Addresses an issue where the client is sending malformed stats messages to the server.

Introduced in 78ce68160a .
2023-05-05 11:30:04 +02:00
damencho
ac8e4d9828 fix: Fixes notifying vnodes to destroy rooms.
It may happen we receive the disconnect iq after the main room is already destroyed. We now send disconnect on destroy to all vnodes or when receiving disconnect iq per vnode.
2023-05-04 15:10:02 -05:00
damencho
a6ade336b7 fix: Fix measure messages.
This just counts messages and should not block processing messages. Breaks visitor messages coming from s2s and no session params are available.
2023-05-04 15:09:52 -05:00
Hristo Terezov
350443ad34 fix(large-video): Attempt to fix jumping.
When the toolbox is hidden and due to a ReactFocusLock instance the
focus is returned to the toolbox the whole page scrolls to the toolbox
which is positioned outside of the viewport in the bottom.
Then when the animation for displaying the toolbox is started the
scenario looks like the large video is jumping.
Now we don't return the focus from ReactFocusLock to elements which are
not part of the viewport.
2023-05-03 17:31:54 -05:00
Jaya Allamsetty
4c37ef7a2c ref(conference) Simplify track creation. (#13209)
* ref(conference) Simplify track creation.
If gUM fails, we do not have to retry gUM with mic only and camera only constraints. gUM has come a long way and this is not needed anymore.

* ref(conference) Filter tracks that are added to conference.

* squash: Address review comments

* fix(prejoin): Display the exact gUM error in prejoin.

* squash: Address review comments
2023-05-03 18:16:48 -04:00
damencho
3eedc2a49d fix: Restore old config for promoted visitors.
In case a visitor is promoted to main room and want to join an empty breakout room we want to send conference iq to jicofo.
2023-05-03 11:04:40 -05:00
FIKRAT HUSEYNKHANOV
aaeb1a90e5 feat: add toggleWhiteboard to Jitsi API (#13292)
* add toggleWhiteboard to Jitsi API

* eslint recommendations applied

* Prevent to send whiteboard status change notifications for mobile

* Fix code style errors (eslint)

* Requested changes (by mihhu) have been made.

---------

Co-authored-by: Fikret Huseynkhanov <fikret.huseynkhanov@simbrella.com>
2023-05-03 09:52:44 -05:00
Saúl Ibarra Corretgé
ed89f9af20 feat(android) add support for Hearing Aid devices 2023-05-03 09:09:10 +02:00
Saúl Ibarra Corretgé
863ad0b0e6 fix(ios) bump WebRTC version to fix crash
Fix a crash in Metal rendering: 0c9cc42025
2023-05-02 23:12:56 +02:00
Дамян Минков
e2d701a8cc feat: Audio output settings in visitor mode. (#13315)
* feat: Audio output settings in visitor mode.

* squash: Fix lint errors.
2023-05-02 16:06:19 -05:00
damencho
2710273069 feat: Sets meeting id using the connect method. 2023-05-02 12:40:08 -05:00
damencho
07af18e284 fix: Handles disconnect coming from jicofo to destroy visitor rooms.
Drops destroy room for no main participants from vnode. In case of breakout rooms we can end up with nobody in the main room for some time, till they are back from the breakout rooms.
2023-05-02 12:40:08 -05:00
damencho
519e37f567 fix: Drops console warn for logger. 2023-05-02 12:40:08 -05:00
damencho
7cf61eb776 fix: Disables p2p for visitors as it doesn't make sense.
The usecase is breakout rooms when main room is empty, but then one of the participants come back.
2023-05-02 12:40:08 -05:00
Jaya Allamsetty
f81446909c chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1626.0.0+a41aa571...v1629.0.0+1714bf07
2023-05-02 10:01:10 -04:00
damencho
b4115593c0 fix: Fix xmldom version to be used. 2023-05-02 08:29:10 -05:00
Hristo Terezov
f8bd8b616e feat(reactions): New button for web. 2023-05-02 08:20:35 -05:00
Hristo Terezov
be55ccd6f4 fix(main-Toolbox): Display the correct buttons.
If some of the buttons from the main toolbar are disabled we were
displaying buttons from the overflow menu in their place.
2023-05-02 08:20:35 -05:00
Horatiu Muresan
e7db18bd80 fix(dial-in) Place PIN on a new line (#13309) 2023-05-02 16:02:51 +03:00
Robert Pintilii
dff41e0fcb fix(chat) Fix horizontal scroll (#13308) 2023-05-02 15:53:30 +03:00
damencho
43be4324af fix: Fix room locking without visitors. 2023-05-02 06:25:37 -05:00
Saúl Ibarra Corretgé
c33baf4c96 fix(ios) avoid rejecting builds in progress in TestFlight 2023-05-02 10:21:30 +02:00
Saúl Ibarra Corretgé
f95a356025 feat(android) bump minimum API level to 24
Some of our dependencies (most notably WebRTC) have dropped it and we
can no longer claim to support API level 23).
2023-05-02 10:19:19 +02:00
Robert Pintilii
1ba7765898 ref(TS) Convert some native components to TS (#13281)
Remove some @ts-ignores
2023-05-02 11:09:38 +03:00
Robert Pintilii
0346fca434 fix(checkbox) Fix misalign when label has multiple lines (#13304) 2023-05-02 10:23:04 +03:00
Robert Pintilii
d267b2499d fix(chat) Fix name overflows chat bubble (#13303)
Revert color change of scroll corner
2023-05-02 10:22:49 +03:00
Дамян Минков
e3e5f1fbfa feat(visitors): Handles locked rooms for visitors. (#13296)
* feat(visitors): Handles locked rooms for visitors.

* squash: Handle locked room password on promotion.

* squash: quotes.

* squash: Renames main_domain to local_domain.

* squash: Renames fmuc_main_domain to main_domain.

Adds required config to point to the main virtual host of the main prosody. There are cases when the first visitor tries to join and there are not main participants as they are in the queue waiting for the vnode connect message and we cannot get dynamically the main domain.

* squash: Fix check for main_domain config.
2023-05-01 17:16:16 -05:00
robertpin
4697192b43 fix(keyboard-a11y) Remove space from click trigger 2023-05-01 16:50:23 +02:00
damencho
38a293f8f6 fix(chat): Fixes long display name that overflow the message bubble. 2023-04-28 13:31:14 -05:00
damencho
13e8f992b5 fix(chat): White square when both scrolls are visible. 2023-04-28 13:31:14 -05:00
damencho
c384d0d3a9 Revert "fix(chat) Make the name fit the chat bubble"
This reverts commit e56c7070c2.
2023-04-28 13:31:14 -05:00
Дамян Минков
2b71fa512b feat: Adds conference duration to the amplitude stat. (#13294) 2023-04-28 11:09:13 -05:00
damencho
d381ceb040 feat: Shows html in notification warning. 2023-04-27 12:42:28 -05:00
damencho
e18c428f52 fix: Hide virtual background for unsupported browsers from vide preview. 2023-04-27 12:42:12 -05:00
Gabriel Borlea
9fc32dc59b fix: multiselect for invite people (#13287)
* fix: multiselect duplicates

* set multiselect height to 200px
2023-04-27 10:14:16 -05:00
robertpin
6f45622ef1 fix(dialog) Fix close animation moves whole body 2023-04-27 10:06:17 -05:00
robertpin
e56c7070c2 fix(chat) Make the name fit the chat bubble 2023-04-27 09:40:27 -05:00
damencho
0aef7a36aa fix: Fixes unresolved function. 2023-04-27 09:25:07 -05:00
damencho
c030cf941e feat: Implements amplitude events for messages count. 2023-04-27 09:24:59 -05:00
Robert Pintilii
f6760e4ac7 fix(chat) Focus input on chat open (#13285) 2023-04-27 17:23:47 +03:00
Robert Pintilii
9060c77307 ref(TS) Convert some native components to TS (#13266) 2023-04-27 08:44:20 +03:00
Дамян Минков
a1d018eef4 feat: Disables sending localstats in visitor mode. (#13279) 2023-04-27 07:38:57 +02:00
Jaya Allamsetty
3f724d8fb7 fix(visitors) Do not add tracks in redux to conference. 2023-04-26 16:51:19 -04:00
Jaya Allamsetty
49d69a5a02 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1623.0.0+c520877a...v1624.0.0+e3a8472f
2023-04-26 13:04:01 -04:00
damencho
6db9e42876 fix: Allows jicofo entering rooms without requiring a password.
The case where the main room is locked and everyone leaves it to a breakout room and then coming back allows jicofo entering without a password.
2023-04-26 09:04:55 -05:00
Jaya Allamsetty
ad3e8f9f53 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1620.0.0+7f0012f7...v1623.0.0+c520877a
2023-04-26 09:26:34 -04:00
Mihaela Dumitru
9f39caa247 feat(external-api) support assumed bandwidth bps config and command (#13164) 2023-04-26 15:32:53 +03:00
Avram Tudor
1402a63324 ref(keyboard-shortcuts) refactor keyboard shortcuts to use redux (#13260)
* ref(keyboard-shortcuts) refactor keyboard shortcuts to use redux

fix unsynced default value between config flag and local storage

* code review

* fix build
2023-04-26 11:21:42 +03:00
robertpin
a9863e65c3 fix(dial-in) Make text selectable on Dial In page 2023-04-25 19:41:27 -05:00
Robert Pintilii
646c58f7d1 ref(TS) Convert some native components to TS (#13264) 2023-04-25 13:50:52 +03:00
Дамян Минков
a78ea7ca9c fix: Updates the option for disabling iframe to show a warning. (#13263)
* fix: Updates the option for disabling iframe to show a warning.

It will give a timeout of 5 mins for the conference, before navigating away from it.

* squash: Fix lint error.

* squash: Fix mobile build.
2023-04-24 14:59:25 -05:00
Robert Pintilii
8b8565bf60 ref(TS) Convert some native components to TS (#13259) 2023-04-24 20:14:02 +03:00
Saúl Ibarra Corretgé
b9e30f3c1b ref(android) remove unused code
This basically reverts
e61ccc956f
since we are no longer interested in using Detox.

In addition, the WebRTC initialization code was only placed in the RAN
instance manager holder's App initialization path, which is now gone, so
add it to the Activity initialization path.
2023-04-24 14:08:50 +02:00
Robert Pintilii
96b6edccf8 ref(TS) Remove flow comments in TS files (#13258) 2023-04-24 14:49:56 +03:00
Robert Pintilii
2af9dc88e6 ref|(TS) Convert some native components to TS (#13239) 2023-04-24 14:09:50 +03:00
Robert Pintilii
eda25ca3c9 fix(toolbar) Remove focus on hide (#13256) 2023-04-24 14:07:42 +03:00
Amga
c99da17973 fix(lang) update Mongolian translation 2023-04-24 11:58:07 +02:00
Saúl Ibarra Corretgé
9e147d7842 fix(android) fix JitsiMeetActivity.onDestroy not leaving the room
When we refactored the external API to use broadcast actions leave() was
changes to use the hangup broadcast action.

This mechanism does not seem to work while onDestroy is getting
executed, however.

There is another way to accomplish the same, for the particular case of
hangup: to pass empty props to the running RN application. This was the
previous behavior too.

This PR introduces a new abort() method on JitsiMeetView, which does
exactly that, passes empty props to RN. This allows cleanup to happen
and the meeting properly ends when the activity is swipped from the
recents list.

Fixes: https://github.com/jitsi/jitsi-meet/issues/13175
2023-04-24 10:14:06 +02:00
Jaya Allamsetty
d7afaf871f fix(visitor): Do not add media tracks in visitor mode.
When gUM resolves after the user has joined as a visitor, skip adding the local tracks to the conference.
2023-04-21 15:25:21 -04:00
Calin-Teodor
c4f6d37aa1 feat(conference): fixed raisedhandcountlabel and filmstrip conflict 2023-04-21 15:58:51 +03:00
Calinteodor
a5663872d9 feat(invite/native): add people functionality fixes (#13240)
feat(invite/native): add people functionality fixes
2023-04-21 14:13:25 +03:00
Robert Pintilii
007283aab3 chore(deps) Cleanup (#13246)
Remove @atlaskit and styled-components
Upgrade @emotion and @mui packages
Move @types packages to devDeps
2023-04-21 10:11:56 +03:00
Saúl Ibarra Corretgé
3b612376f2 chore(deps,giphy) update @giphy/react-components (#13243)
Also update the patches to match the new package versions.
2023-04-21 09:31:50 +03:00
Amga
1a312e2140 lang: update translation for mongolian language (#13237) 2023-04-20 22:46:15 -05:00
Saúl Ibarra Corretgé
6f5d0400b8 fix(deps) override xmldom dependency from strophe.js
lib-jitsi-meet does not bundle xmldom anyway, and we are providing it
here. strophe seems to be stuck in a slightly old version which creates
spurious security warnings.
2023-04-20 19:13:43 +02:00
Gabriel Borlea
aec86cecc0 ref(invite): add people form (#13207) 2023-04-20 14:00:42 +03:00
Robert Pintilii
bf1dde7cd1 ref(TS) Convert some files to TS (#13223) 2023-04-20 12:06:45 +03:00
873 changed files with 23778 additions and 14342 deletions

View File

@@ -1,6 +1,8 @@
# The build artifacts of the jitsi-meet project.
build/*
doc/*
# Third-party source code which we (1) do not want to modify or (2) try to
# modify as little as possible.
libs/*

16
.github/stale.yml vendored
View File

@@ -1,16 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 90
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- confirmed
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@@ -12,14 +12,24 @@ jobs:
with:
node-version: 16
cache: 'npm'
- name: Get changed files
id: changed-files
uses: tj-actions/changed-files@v35
- name: Get changed lang files
id: lang-files
run: echo "all=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | grep -oE 'lang\/\S+' | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
- run: npm install
- name: Check git status
run: git status
- name: Normalize lang files to ensure sorted
if: steps.lang-files.outputs.all
run: npm run lang-sort
- name: Check lang files are formatted correctly
if: steps.lang-files.outputs.all
run: npm run lint:lang
- name: Check if the git repository is clean
run: $(exit $(git status --porcelain --untracked-files=no | head -255 | wc -l)) || (echo "Dirty git tree"; git diff; exit 1)
- run: npm run lint:ci
- run: npm run lint:ci && npm run tsc:ci
linux-build:
name: Build Frontend (Linux)
runs-on: ubuntu-latest

21
.github/workflows/stale.yml vendored Normal file
View File

@@ -0,0 +1,21 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v8
with:
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-issue-label: 'stale'
stale-pr-label: 'stale'
exempt-issue-labels: 'confirmed,help-needed'
exempt-pr-labels: 'confirmed'
days-before-issue-stale: 60
days-before-pr-stale: 90
days-before-issue-close: 10
days-before-pr-close: 10

18
.gitignore vendored
View File

@@ -61,8 +61,9 @@ buck-out/
# fastlane
#
*/fastlane/report.xml
*/fastlane/Preview.html
**/fastlane/report.xml
**/fastlane/Preview.html
**/fastlane/test_output
# Build artifacts
*.jsbundle
@@ -93,3 +94,16 @@ twa/*.aab
twa/assetlinks.json
tsconfig.json
# React Native SDK
#
react-native-sdk/*.tgz
react-native-sdk/android/src
react-native-sdk/images
react-native-sdk/ios
react-native-sdk/lang
react-native-sdk/modules
react-native-sdk/node_modules
react-native-sdk/react
react-native-sdk/service
react-native-sdk/sounds

3
.npmrc
View File

@@ -1,6 +1,3 @@
package-lock=true
; FIXME Set legacy-peer-deps=false when we upgrade RN.
legacy-peer-deps=true
; Omit optional dependencies
omit=optional

View File

@@ -7,7 +7,6 @@
android:extractNativeLibs="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name=".MainApplication"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme">
<meta-data
@@ -17,7 +16,8 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTask"
android:launchMode="singleInstance"
android:taskAffinity=""
android:name=".MainActivity"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"

View File

@@ -1,47 +0,0 @@
/*
* Copyright @ 2022-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;
import android.app.Application;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
import org.jitsi.meet.sdk.JitsiReactNativeHost;
/**
* Application class for Jitsi Meet. The only reason why this exists is for Detox
* to believe our app is a "greenfield" app. SDK users need not use this.
*/
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost = new JitsiReactNativeHost(this);
@Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
// Initialize RN
Log.d(this.getClass().getCanonicalName(), "app onCreate");
getReactNativeHost().getReactInstanceManager();
}
}

View File

@@ -10,16 +10,17 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.0.4'
classpath 'com.android.tools.build:gradle:7.1.1'
classpath 'com.google.gms:google-services:4.3.14'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
}
}
ext {
kotlinVersion = "1.7.0"
buildToolsVersion = "31.0.0"
compileSdkVersion = 32
minSdkVersion = 23
minSdkVersion = 24
targetSdkVersion = 32
supportLibVersion = "28.0.0"

View File

@@ -33,7 +33,7 @@ if [[ $MVN_HTTP == 1 ]]; then
deploy:deploy-file \
-Durl=${MVN_REPO} \
-DrepositoryId=${MVN_REPO_ID} \
-Dfile=react-native-${RN_VERSION}.aar \
-Dfile=react-native-${RN_VERSION}-release.aar \
-Dpackaging=aar \
-DgeneratePom=false \
-DpomFile=react-native-${RN_VERSION}.pom || true
@@ -58,7 +58,7 @@ else
mvn \
deploy:deploy-file \
-Durl=${MVN_REPO} \
-Dfile=react-native-${RN_VERSION}.aar \
-Dfile=react-native-${RN_VERSION}-release.aar \
-Dpackaging=aar \
-DgeneratePom=false \
-DpomFile=react-native-${RN_VERSION}.pom

View File

@@ -25,6 +25,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.module.annotations.ReactModule;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
@@ -32,7 +33,10 @@ import java.util.Map;
class AppInfoModule
extends ReactContextBaseJavaModule {
private static final String BUILD_CONFIG = "org.jitsi.meet.sdk.BuildConfig";
public static final String NAME = "AppInfo";
public static final boolean GOOGLE_SERVICES_ENABLED = getGoogleServicesEnabled();
public static final boolean LIBRE_BUILD = getLibreBuild();
public AppInfoModule(ReactApplicationContext reactContext) {
super(reactContext);
@@ -75,8 +79,8 @@ class AppInfoModule
constants.put(
"version",
packageInfo == null ? "" : packageInfo.versionName);
constants.put("LIBRE_BUILD", BuildConfig.LIBRE_BUILD);
constants.put("GOOGLE_SERVICES_ENABLED", BuildConfig.GOOGLE_SERVICES_ENABLED);
constants.put("LIBRE_BUILD", LIBRE_BUILD);
constants.put("GOOGLE_SERVICES_ENABLED", GOOGLE_SERVICES_ENABLED);
return constants;
}
@@ -85,4 +89,47 @@ class AppInfoModule
public String getName() {
return NAME;
}
/**
* Checks if libre google services object is null based on build configuration.
*/
private static boolean getGoogleServicesEnabled() {
Object googleServicesEnabled = getBuildConfigValue("GOOGLE_SERVICES_ENABLED");
if (googleServicesEnabled !=null) {
return (Boolean) googleServicesEnabled;
}
return false;
}
/**
* Checks if libre build field is null based on build configuration.
*/
private static boolean getLibreBuild() {
Object libreBuild = getBuildConfigValue("LIBRE_BUILD");
if (libreBuild !=null) {
return (Boolean) libreBuild;
}
return false;
}
/**
* Gets build config value of a certain field.
*
* @param fieldName Field from build config.
*/
private static Object getBuildConfigValue(String fieldName) {
try {
Class<?> c = Class.forName(BUILD_CONFIG);
Field f = c.getDeclaredField(fieldName);
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View File

@@ -45,6 +45,12 @@ class AudioDeviceHandlerGeneric implements
*/
private AudioModeModule module;
/**
* Constant defining a Hearing Aid. Only available on API level >= 28.
* The value of: AudioDeviceInfo.TYPE_HEARING_AID
*/
private static final int TYPE_HEARING_AID = 23;
/**
* Constant defining a USB headset. Only available on API level >= 26.
* The value of: AudioDeviceInfo.TYPE_USB_HEADSET
@@ -85,6 +91,7 @@ class AudioDeviceHandlerGeneric implements
break;
case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
case AudioDeviceInfo.TYPE_WIRED_HEADSET:
case TYPE_HEARING_AID:
case TYPE_USB_HEADSET:
devices.add(AudioModeModule.DEVICE_HEADPHONES);
break;

View File

@@ -13,6 +13,7 @@ import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import androidx.annotation.RequiresApi;
import com.facebook.react.bridge.Promise;
@@ -357,7 +358,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
JitsiMeetLogger.i(TAG + " onDisconnect " + getCallUUID());
WritableNativeMap data = new WritableNativeMap();
data.putString("callUUID", getCallUUID());
ReactInstanceManagerHolder.emitEvent(
RNConnectionService.getInstance().emitEvent(
"org.jitsi.meet:features/connection_service#disconnect",
data);
// The JavaScript side will not go back to the native with
@@ -377,7 +378,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
JitsiMeetLogger.i(TAG + " onAbort " + getCallUUID());
WritableNativeMap data = new WritableNativeMap();
data.putString("callUUID", getCallUUID());
ReactInstanceManagerHolder.emitEvent(
RNConnectionService.getInstance().emitEvent(
"org.jitsi.meet:features/connection_service#abort",
data);
// The JavaScript side will not go back to the native with
@@ -406,7 +407,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
@Override
public void onCallAudioStateChanged(CallAudioState state) {
JitsiMeetLogger.d(TAG + " onCallAudioStateChanged: " + state);
RNConnectionService module = ReactInstanceManagerHolder.getNativeModule(RNConnectionService.class);
RNConnectionService module = RNConnectionService.getInstance();
if (module != null) {
module.onCallAudioStateChange(state);
}

View File

@@ -16,6 +16,7 @@
package org.jitsi.meet.sdk;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -177,8 +178,11 @@ public class JitsiMeetActivity extends AppCompatActivity
}
protected void leave() {
Intent hangupBroadcastIntent = BroadcastIntentHelper.buildHangUpIntent();
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(hangupBroadcastIntent);
if (this.jitsiView != null) {
this.jitsiView.abort();
} else {
JitsiMeetLogger.w("Cannot leave, view is null");
}
}
private @Nullable
@@ -295,6 +299,7 @@ public class JitsiMeetActivity extends AppCompatActivity
JitsiMeetActivityDelegate.requestPermissions(this, permissions, requestCode, listener);
}
@SuppressLint("MissingSuperCall")
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
JitsiMeetActivityDelegate.onRequestPermissionsResult(requestCode, permissions, grantResults);

View File

@@ -157,6 +157,14 @@ public class JitsiMeetView extends FrameLayout {
setProps(options != null ? options.asProps() : new Bundle());
}
/**
* Internal method which aborts running RN by passing empty props.
* This is only meant to be used from the enclosing Activity's onDestroy.
*/
public void abort() {
setProps(new Bundle());
}
/**
* Creates the {@code ReactRootView} for the given app name with the given
* props. Once created it's set as the view of this {@code FrameLayout}.

View File

@@ -1,41 +0,0 @@
package org.jitsi.meet.sdk;
import android.app.Application;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import java.util.List;
/**
* This is the minimal implementation of ReactNativeHost that will make things like the
* Detox testing framework believe we are a "greenfield" app.
*
* Generally speaking, apps using the SDK (other than the Jitsi Meet app itself) should not
* need to use this because the
*/
public class JitsiReactNativeHost extends ReactNativeHost {
public JitsiReactNativeHost(Application application) {
super(application);
}
@Override
public boolean getUseDeveloperSupport() {
// Unused since we override `createReactInstanceManager`.
return false;
}
@Override
protected List<ReactPackage> getPackages() {
// Unused since we override `createReactInstanceManager`.
return null;
}
@Override
protected ReactInstanceManager createReactInstanceManager() {
ReactInstanceManagerHolder.initReactInstanceManager(this.getApplication());
return ReactInstanceManagerHolder.getReactInstanceManager();
}
}

View File

@@ -10,14 +10,19 @@ import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telecom.VideoProfile;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
@@ -35,6 +40,7 @@ class RNConnectionService extends ReactContextBaseJavaModule {
private static final String TAG = ConnectionService.TAG;
private static RNConnectionService sRNConnectionServiceInstance;
/**
* Handler for dealing with call state changes. We are acting as a proxy between ConnectionService
* and other modules such as {@link AudioModeModule}.
@@ -57,6 +63,11 @@ class RNConnectionService extends ReactContextBaseJavaModule {
RNConnectionService(ReactApplicationContext reactContext) {
super(reactContext);
sRNConnectionServiceInstance = this;
}
static RNConnectionService getInstance() {
return sRNConnectionServiceInstance;
}
@ReactMethod
@@ -226,4 +237,22 @@ class RNConnectionService extends ReactContextBaseJavaModule {
interface CallAudioStateListener {
void onCallAudioStateChange(android.telecom.CallAudioState callAudioState);
}
/**
* Helper function to send an event to JavaScript.
*
* @param eventName {@code String} containing the event name.
* @param data {@code Object} optional ancillary data for the event.
*/
void emitEvent(
String eventName,
@Nullable Object data) {
ReactContext reactContext = getReactApplicationContext();
if (reactContext != null) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, data);
}
}
}

View File

@@ -17,7 +17,6 @@
package org.jitsi.meet.sdk;
import android.app.Activity;
import android.app.Application;
import android.util.Log;
import androidx.annotation.Nullable;
@@ -227,11 +226,9 @@ class ReactInstanceManagerHolder {
* time. All {@code ReactRootView} instances will be tied to the one and
* only {@code ReactInstanceManager}.
*
* This method is only meant to be called when integrating with {@code JitsiReactNativeHost}.
*
* @param app {@code Application} current running Application.
* @param activity {@code Activity} current running Activity.
*/
static void initReactInstanceManager(Application app) {
static void initReactInstanceManager(Activity activity) {
if (reactInstanceManager != null) {
return;
}
@@ -244,34 +241,7 @@ class ReactInstanceManagerHolder {
options.videoDecoderFactory = new H264AndSoftwareVideoDecoderFactory(eglContext);
options.videoEncoderFactory = new H264AndSoftwareVideoEncoderFactory(eglContext);
Log.d(TAG, "initializing RN with Application");
reactInstanceManager
= ReactInstanceManager.builder()
.setApplication(app)
.setBundleAssetName("index.android.bundle")
.setJSMainModulePath("index.android")
.setJavaScriptExecutorFactory(getReactNativeJSFactory())
.addPackages(getReactNativePackages())
.setUseDeveloperSupport(BuildConfig.DEBUG)
.setInitialLifecycleState(LifecycleState.BEFORE_CREATE)
.build();
}
/**
* Internal method to initialize the React Native instance manager. We
* create a single instance in order to load the JavaScript bundle a single
* time. All {@code ReactRootView} instances will be tied to the one and
* only {@code ReactInstanceManager}.
*
* @param activity {@code Activity} current running Activity.
*/
static void initReactInstanceManager(Activity activity) {
if (reactInstanceManager != null) {
return;
}
Log.d(ReactInstanceManagerHolder.class.getCanonicalName(), "initializing RN with Activity");
Log.d(TAG, "initializing RN with Activity");
reactInstanceManager
= ReactInstanceManager.builder()

2
app.js
View File

@@ -18,7 +18,6 @@ import './react/features/base/jitsi-local-storage/setup';
import conference from './conference';
import API from './modules/API';
import UI from './modules/UI/UI';
import keyboardshortcut from './modules/keyboardshortcut/keyboardshortcut';
import translation from './modules/translation/translation';
// Initialize Olm as early as possible.
@@ -38,7 +37,6 @@ window.APP = {
'index.loaded': window.indexLoadedTime
},
keyboardshortcut,
translation,
UI
};

View File

@@ -87,6 +87,7 @@ import {
} from './react/features/base/lib-jitsi-meet';
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
import {
gumPending,
setAudioAvailable,
setAudioMuted,
setAudioUnmutePermissions,
@@ -100,6 +101,7 @@ import {
getStartWithVideoMuted,
isVideoMutedByUser
} from './react/features/base/media/functions';
import { IGUMPendingState } from './react/features/base/media/types';
import {
dominantSpeakerChanged,
localParticipantAudioLevelChanged,
@@ -140,6 +142,7 @@ import { downloadJSON } from './react/features/base/util/downloadJSON';
import { showDesktopPicker } from './react/features/desktop-picker/actions';
import { appendSuffix } from './react/features/display-name/functions';
import { maybeOpenFeedbackDialog, submitFeedback } from './react/features/feedback/actions';
import { initKeyboardShortcuts } from './react/features/keyboard-shortcuts/actions';
import { maybeSetLobbyChatMessageListener } from './react/features/lobby/actions.any';
import { setNoiseSuppressionEnabled } from './react/features/noise-suppression/actions';
import { hideNotification, showNotification, showWarningNotification } from './react/features/notifications/actions';
@@ -162,6 +165,7 @@ import { endpointMessageReceived } from './react/features/subtitles/actions.any'
import { handleToggleVideoMuted } from './react/features/toolbox/actions.any';
import { muteLocal } from './react/features/video-menu/actions.any';
import { setIAmVisitor } from './react/features/visitors/actions';
import { iAmVisitor } from './react/features/visitors/functions';
import UIEvents from './service/UI/UIEvents';
const logger = Logger.getLogger(__filename);
@@ -359,11 +363,11 @@ class ConferenceConnector {
const [ vnode ] = params;
APP.store.dispatch(overwriteConfig(newConfig))
.then(this._conference.leaveRoom())
.then(APP.store.dispatch(setIAmVisitor(Boolean(vnode))))
.then(() => this._conference.leaveRoom())
.then(() => APP.store.dispatch(setIAmVisitor(Boolean(vnode))))
// we do not clear local tracks on error, so we need to manually clear them
.then(APP.store.dispatch(destroyLocalTracks()))
.then(() => APP.store.dispatch(destroyLocalTracks()))
.then(() => {
// Reset VideoLayout. It's destroyed in features/video-layout/middleware.web.js so re-initialize it.
VideoLayout.initLargeVideo();
@@ -416,7 +420,7 @@ class ConferenceConnector {
if (newConfig) {
APP.store.dispatch(overwriteConfig(newConfig))
.then(this._conference.leaveRoom())
.then(() => this._conference.leaveRoom())
.then(() => {
_connectionPromise = connect(this._conference.roomName);
@@ -491,6 +495,21 @@ function disconnect() {
return connection.disconnect().then(onDisconnected, onDisconnected);
}
/**
* Sets the GUM pending state for the tracks that have failed.
*
* NOTE: Some of the track that we will be setting to GUM pending state NONE may not have failed but they may have
* been requested. This won't be a problem because their current GUM pending state will be NONE anyway.
* @param {JitsiLocalTrack} tracks - The tracks that have been created.
* @returns {void}
*/
function setGUMPendingStateOnFailedTracks(tracks) {
const tracksTypes = tracks.map(track => track.getType());
const nonPendingTracks = [ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ].filter(type => !tracksTypes.includes(type));
APP.store.dispatch(gumPending(nonPendingTracks, IGUMPendingState.NONE));
}
/**
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
*
@@ -557,7 +576,7 @@ export default {
);
}
let tryCreateLocalTracks;
let tryCreateLocalTracks = Promise.resolve([]);
// On Electron there is no permission prompt for granting permissions. That's why we don't need to
// spend much time displaying the overlay screen. If GUM is not resolved within 15 seconds it will
@@ -598,76 +617,66 @@ export default {
return [];
});
} else if (!requestedAudio && !requestedVideo) {
// Resolve with no tracks
tryCreateLocalTracks = Promise.resolve([]);
} else {
} else if (requestedAudio || requestedVideo) {
APP.store.dispatch(gumPending(initialDevices, IGUMPendingState.PENDING_UNMUTE));
tryCreateLocalTracks = createLocalTracksF({
devices: initialDevices,
timeout,
firePermissionPromptIsShownEvent: true
})
.catch(err => {
if (requestedAudio && requestedVideo) {
// Try audio only...
errors.audioAndVideoError = err;
if (err.name === JitsiTrackErrors.TIMEOUT && !browser.isElectron()) {
// In this case we expect that the permission prompt is still visible. There is no point of
// executing GUM with different source. Also at the time of writing the following
// inconsistency have been noticed in some browsers - if the permissions prompt is visible
// and another GUM is executed the prompt does not change its content but if the user
// clicks allow the user action isassociated with the latest GUM call.
errors.audioOnlyError = err;
errors.videoOnlyError = err;
return [];
}
return createLocalTracksF(audioOptions);
} else if (requestedAudio && !requestedVideo) {
errors.audioOnlyError = err;
return [];
} else if (requestedVideo && !requestedAudio) {
errors.videoOnlyError = err;
return [];
}
logger.error('Should never happen');
})
.catch(err => {
// Log this just in case...
if (!requestedAudio) {
logger.error('The impossible just happened', err);
}
errors.audioOnlyError = err;
// Try video only...
return requestedVideo
? createLocalTracksF({
devices: [ MEDIA_TYPE.VIDEO ],
firePermissionPromptIsShownEvent: true
})
: [];
})
.catch(err => {
// Log this just in case...
if (!requestedVideo) {
logger.error('The impossible just happened', err);
}
errors.videoOnlyError = err;
.catch(async error => {
if (error.name === JitsiTrackErrors.TIMEOUT && !browser.isElectron()) {
errors.audioAndVideoError = error;
return [];
}
// Retry with separate gUM calls.
const gUMPromises = [];
const tracks = [];
if (requestedAudio) {
gUMPromises.push(createLocalTracksF(audioOptions));
}
if (requestedVideo) {
gUMPromises.push(createLocalTracksF({
devices: [ MEDIA_TYPE.VIDEO ],
timeout,
firePermissionPromptIsShownEvent: true
}));
}
const results = await Promise.allSettled(gUMPromises);
let errorMsg;
results.forEach((result, idx) => {
if (result.status === 'fulfilled') {
tracks.push(result.value[0]);
} else {
errorMsg = result.reason;
const isAudio = idx === 0;
logger.error(`${isAudio ? 'Audio' : 'Video'} track creation failed with error ${errorMsg}`);
if (isAudio) {
errors.audioOnlyError = errorMsg;
} else {
errors.videoOnlyError = errorMsg;
}
}
});
if (errors.audioOnlyError && errors.videoOnlyError) {
errors.audioAndVideoError = errorMsg;
}
return tracks;
});
}
// Hide the permissions prompt/overlay as soon as the tracks are
// created. Don't wait for the connection to be made, since in some
// cases, when auth is required, for instance, that won't happen until
// the user inputs their credentials, but the dialog would be
// overshadowed by the overlay.
// Hide the permissions prompt/overlay as soon as the tracks are created. Don't wait for the connection to
// be established, as in some cases like when auth is required, connection won't be established until the user
// inputs their credentials, but the dialog would be overshadowed by the overlay.
tryCreateLocalTracks.then(tracks => {
APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false));
@@ -804,46 +813,55 @@ export default {
* @returns {Promise}
*/
async init({ roomName }) {
const state = APP.store.getState();
const initialOptions = {
startAudioOnly: config.startAudioOnly,
startScreenSharing: config.startScreenSharing,
startWithAudioMuted: getStartWithAudioMuted(APP.store.getState())
|| isUserInteractionRequiredForUnmute(APP.store.getState()),
startWithVideoMuted: getStartWithVideoMuted(APP.store.getState())
|| isUserInteractionRequiredForUnmute(APP.store.getState())
startWithAudioMuted: getStartWithAudioMuted(state) || isUserInteractionRequiredForUnmute(state),
startWithVideoMuted: getStartWithVideoMuted(state) || isUserInteractionRequiredForUnmute(state)
};
this.roomName = roomName;
try {
// Initialize the device list first. This way, when creating tracks
// based on preferred devices, loose label matching can be done in
// cases where the exact ID match is no longer available, such as
// when the camera device has switched USB ports.
// when in startSilent mode we want to start with audio muted
// Initialize the device list first. This way, when creating tracks based on preferred devices, loose label
// matching can be done in cases where the exact ID match is no longer available, such as -
// 1. When the camera device has switched USB ports.
// 2. When in startSilent mode we want to start with audio muted
await this._initDeviceList();
} catch (error) {
logger.warn('initial device list initialization failed', error);
}
const handleStartAudioMuted = (options, tracks) => {
if (options.startWithAudioMuted) {
// Filter out the local tracks based on various config options, i.e., when user joins muted or is muted by
// focus. However, audio track will always be created even though it is not added to the conference since we
// want audio related features (noisy mic, talk while muted, etc.) to work even if the mic is muted.
const handleInitialTracks = (options, tracks) => {
let localTracks = tracks;
// No local tracks are added when user joins as a visitor.
if (iAmVisitor(state)) {
return [];
}
if (options.startWithAudioMuted || room?.isStartAudioMuted()) {
// Always add the track on Safari because of a known issue where audio playout doesn't happen
// if the user joins audio and video muted, i.e., if there is no local media capture.
if (browser.isWebKitBased()) {
this.muteAudio(true, true);
} else {
return tracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
}
}
if (room?.isStartVideoMuted()) {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.VIDEO);
}
return tracks;
return localTracks;
};
if (isPrejoinPageVisible(APP.store.getState())) {
if (isPrejoinPageVisible(state)) {
_connectionPromise = connect(roomName).then(c => {
// we want to initialize it early, in case of errors to be able
// to gather logs
// We want to initialize it early, in case of errors to be able to gather logs.
APP.connection = c;
return c;
@@ -856,43 +874,38 @@ export default {
APP.store.dispatch(makePrecallTest(this._getConferenceOptions()));
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
const tracks = await tryCreateLocalTracks;
const localTracks = await tryCreateLocalTracks;
// Initialize device list a second time to ensure device labels
// get populated in case of an initial gUM acceptance; otherwise
// they may remain as empty strings.
// Initialize device list a second time to ensure device labels get populated in case of an initial gUM
// acceptance; otherwise they may remain as empty strings.
this._initDeviceList(true);
if (isPrejoinPageVisible(APP.store.getState())) {
return APP.store.dispatch(initPrejoin(tracks, errors));
if (isPrejoinPageVisible(state)) {
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
return APP.store.dispatch(initPrejoin(localTracks, errors));
}
logger.debug('Prejoin screen no longer displayed at the time when tracks were created');
this._displayErrorsForCreateInitialLocalTracks(errors);
let localTracks = handleStartAudioMuted(initialOptions, tracks);
const tracks = handleInitialTracks(initialOptions, localTracks);
// in case where gum is slow and resolves after the startAudio/VideoMuted coming from jicofo, we can be
// join unmuted even though jicofo had instruct us to mute, so let's respect that before passing the tracks
if (!browser.isWebKitBased()) {
if (room?.isStartAudioMuted()) {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
}
}
setGUMPendingStateOnFailedTracks(tracks);
if (room?.isStartVideoMuted()) {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.VIDEO);
}
return this._setLocalAudioVideoStreams(localTracks);
return this._setLocalAudioVideoStreams(tracks);
}
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(roomName, initialOptions);
this._initDeviceList(true);
return this.startConference(con, handleStartAudioMuted(initialOptions, tracks));
const filteredTracks = handleInitialTracks(initialOptions, tracks);
setGUMPendingStateOnFailedTracks(filteredTracks);
return this.startConference(con, filteredTracks);
},
/**
@@ -1015,6 +1028,7 @@ export default {
showUI && APP.store.dispatch(notifyMicError(error));
};
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.PENDING_UNMUTE));
createLocalTracksF({ devices: [ 'audio' ] })
.then(([ audioTrack ]) => audioTrack)
.catch(error => {
@@ -1026,7 +1040,10 @@ export default {
.then(async audioTrack => {
await this._maybeApplyAudioMixerEffect(audioTrack);
this.useAudioStream(audioTrack);
return this.useAudioStream(audioTrack);
})
.finally(() => {
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.NONE));
});
} else {
muteLocalAudio(mute);
@@ -1065,7 +1082,7 @@ export default {
*/
muteVideo(mute, showUI = true) {
if (this.videoSwitchInProgress) {
console.warn('muteVideo - unable to perform operations while video switch is in progress');
logger.warn('muteVideo - unable to perform operations while video switch is in progress');
return;
}
@@ -1106,6 +1123,8 @@ export default {
this.isCreatingLocalTrack = true;
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.PENDING_UNMUTE));
// Try to create local video if there wasn't any.
// This handles the case when user joined with no video
// (dismissed screen sharing screen or in audio only mode), but
@@ -1130,6 +1149,7 @@ export default {
})
.finally(() => {
this.isCreatingLocalTrack = false;
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
});
} else {
// FIXME show error dialog if it fails (should be handled by react)
@@ -1442,11 +1462,16 @@ export default {
* @private
*/
_setLocalAudioVideoStreams(tracks = []) {
const { dispatch } = APP.store;
const pendingGUMDevicesToRemove = [];
const promises = tracks.map(track => {
if (track.isAudioTrack()) {
pendingGUMDevicesToRemove.push(MEDIA_TYPE.AUDIO);
return this.useAudioStream(track);
} else if (track.isVideoTrack()) {
logger.debug(`_setLocalAudioVideoStreams is calling useVideoStream with track: ${track}`);
pendingGUMDevicesToRemove.push(MEDIA_TYPE.VIDEO);
return this.useVideoStream(track);
}
@@ -1458,6 +1483,10 @@ export default {
});
return Promise.allSettled(promises).then(() => {
if (pendingGUMDevicesToRemove.length > 0) {
dispatch(gumPending(pendingGUMDevicesToRemove, IGUMPendingState.NONE));
}
this._localTracksInitialized = true;
logger.log(`Initialized with ${tracks.length} local tracks`);
});
@@ -2000,7 +2029,10 @@ export default {
room.on(
JitsiConferenceEvents.NON_PARTICIPANT_MESSAGE_RECEIVED,
(...args) => APP.store.dispatch(nonParticipantMessageReceived(...args)));
(...args) => {
APP.store.dispatch(nonParticipantMessageReceived(...args));
APP.API.notifyNonParticipantMessageReceived(...args);
});
room.on(
JitsiConferenceEvents.LOCK_STATE_CHANGED,
@@ -2171,6 +2203,11 @@ export default {
UIEvents.VIDEO_DEVICE_CHANGED,
cameraDeviceId => {
const videoWasMuted = this.isLocalVideoMuted();
const localVideoTrack = getLocalJitsiVideoTrack(APP.store.getState());
if (localVideoTrack?.getDeviceId() === cameraDeviceId) {
return;
}
sendAnalytics(createDeviceChangedEvent('video', 'input'));
@@ -2301,10 +2338,7 @@ export default {
APP.UI.initConference();
if (!config.disableShortcuts) {
APP.keyboardshortcut.init();
}
dispatch(initKeyboardShortcuts());
dispatch(conferenceJoined(room));
const jwt = APP.store.getState()['features/base/jwt'];
@@ -2418,7 +2452,9 @@ export default {
const { dispatch } = APP.store;
const setAudioOutputPromise
= setAudioOutputDeviceId(newDevices.audiooutput, dispatch)
.catch(); // Just ignore any errors in catch block.
.catch(err => {
logger.error(`Failed to set the audio output device to ${newDevices.audiooutput} - ${err}`);
});
promises.push(setAudioOutputPromise);
}
@@ -2456,7 +2492,7 @@ export default {
}
// check for video
if (!requestedInput.video) {
if (requestedInput.video) {
APP.store.dispatch(checkAndNotifyForNewDevice(newAvailDevices.videoInput, oldDevices.videoInput));
}
@@ -2500,14 +2536,15 @@ export default {
// Create the tracks and replace them only if the user is unmuted.
if (requestedInput.audio || requestedInput.video) {
let tracks = [];
const realAudioDeviceId = hasDefaultMicChanged
? getDefaultDeviceId(APP.store.getState(), 'audioInput') : newDevices.audioinput;
try {
tracks = await mediaDeviceHelper.createLocalTracksAfterDeviceListChanged(
createLocalTracksF,
newDevices.videoinput,
hasDefaultMicChanged
? getDefaultDeviceId(APP.store.getState(), 'audioInput')
: newDevices.audioinput);
requestedInput.video ? newDevices.videoinput : null,
requestedInput.audio ? realAudioDeviceId : null
);
} catch (error) {
logger.error(`Track creation failed on device change, ${error}`);
@@ -2638,17 +2675,22 @@ export default {
async leaveRoom(doDisconnect = true, reason = '') {
APP.store.dispatch(conferenceWillLeave(room));
const maybeDisconnect = () => {
if (doDisconnect) {
return disconnect();
}
};
if (room && room.isJoined()) {
return room.leave(reason).finally(() => {
if (doDisconnect) {
return disconnect();
}
return room.leave(reason).then(() => maybeDisconnect())
.catch(e => {
logger.error(e);
return maybeDisconnect();
});
}
if (doDisconnect) {
return disconnect();
}
return maybeDisconnect();
},
/**

View File

@@ -74,6 +74,9 @@ var config = {
//
testing: {
// Allows the setting of a custom bandwidth value from the UI.
// assumeBandwidth: true,
// Disables the End to End Encryption feature. Useful for debugging
// issues related to insertable streams.
// disableE2EE: false,
@@ -424,25 +427,9 @@ var config = {
// Specify the settings for video quality optimizations on the client.
// videoQuality: {
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
// disabledCodec: 'H264',
//
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
// // to take effect.
// preferredCodec: 'VP8',
//
// // Provides a way to enforce the preferred codec for the conference even when the conference has endpoints
// // that do not support the preferred codec. For example, older versions of Safari do not support VP9 yet.
// // This will result in Safari not being able to decode video from endpoints sending VP9 video.
// // When set to false, the conference falls back to VP8 whenever there is an endpoint that doesn't support the
// // preferred codec and goes back to the preferred codec when that endpoint leaves.
// enforcePreferredCodec: false,
// // Provides a way to set the codec preference on desktop based endpoints.
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264' ],
//
// // Provides a way to configure the maximum bitrates that will be enforced on the simulcast streams for
// // video tracks. The keys in the object represent the type of the stream (LD, SD or HD) and the values
@@ -482,6 +469,24 @@ var config = {
// 720: 'high',
// },
//
// // Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based endpoint
// mobileCodecPreferenceOrder: [ 'VP8', 'VP9', 'H264' ],
//
// // DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
// disabledCodec: 'H264',
//
// // DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
// // to take effect.
// preferredCodec: 'VP8',
//
// },
// Notification timeouts
@@ -932,12 +937,12 @@ var config = {
// If not set, the effective value is 'all'.
// iceTransportPolicy: 'all',
// Provides a way to set the video codec preference on the p2p connection. Acceptable
// codec values are 'VP8', 'VP9' and 'H264'.
// preferredCodec: 'H264',
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
// disabledCodec: '',
// Provides a way to set the codec preference on mobile devices, both on RN and mobile browser based
// endpoints.
// mobileCodecPreferenceOrder: [ 'H264', 'VP8', 'VP9' ],
//
// Provides a way to set the codec preference on desktop based endpoints.
// codecPreferenceOrder: [ 'VP9', 'VP8', 'H264 ],
// How long we're going to wait, before going back to P2P after the 3rd
// participant has left the conference (to filter out page reload).
@@ -949,6 +954,15 @@ var config = {
// { urls: 'stun:jitsi-meet.example.com:3478' },
{ urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' },
],
// DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// Provides a way to set the video codec preference on the p2p connection. Acceptable
// codec values are 'VP8', 'VP9' and 'H264'.
// preferredCodec: 'H264',
// DEPRECATED! Use `codecPreferenceOrder/mobileCodecPreferenceOrder` instead.
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
// disabledCodec: '',
},
analytics: {
@@ -1065,7 +1079,12 @@ var config = {
// },
// e2ee: {
// labels,
// labels: {
// description: '',
// label: '',
// tooltip: '',
// warning: '',
// },
// externallyManagedKey: false,
// },
@@ -1375,7 +1394,6 @@ var config = {
dialOutRegionUrl
disableRemoteControl
displayJids
e2eeLabels
firefox_fake_device
googleApiApplicationClientID
iAmRecorder
@@ -1406,6 +1424,7 @@ var config = {
disableAGC
disableAP
disableHPF
disableLocalStats
disableNS
enableTalkWhileMuted
forceJVB121Ratio

View File

@@ -31,8 +31,8 @@ body {
font-size: 12px;
font-weight: 400;
overflow: hidden;
color: $defaultColor;
background: $defaultBackground;
color: #F1F1F1;
background: #040404; // should match DEFAULT_BACKGROUND from interface_config
}
/**
@@ -94,7 +94,7 @@ input[type='text'], input[type='password'], textarea {
button {
color: #FFF;
background-color: $buttonBackground;
background-color: #44A5FF;
border-radius: $borderRadius;
&.no-icon {
@@ -145,7 +145,7 @@ form {
font-size: 11pt;
color: rgba(255,255,255,.50);
text-decoration: none;
z-index: $poweredByZ;
z-index: 100;
}
.connected {

View File

@@ -5,7 +5,7 @@
position: relative;
transition: width .16s ease-in-out;
width: $sidebarWidth;
z-index: $sideToolbarContainerZ;
z-index: 300;
@media (max-width: 580px) {
height: 100vh;
@@ -253,7 +253,7 @@
.chatmessage {
&.localuser {
background-color: $chatLocalMessageBackgroundColor;
background-color: #484A4F;
border-radius: 6px 0px 6px 6px;
}
@@ -324,7 +324,7 @@
#smileysContainer {
background-color: $chatBackgroundColor;
border-top: 1px solid $chatInputSeparatorColor;
border-top: 1px solid #A4B8D1;
}
}
@@ -340,7 +340,7 @@
}
.smileyContainer:hover {
background-color: $newToolbarButtonToggleColor;
background-color: rgba(255, 255, 255, 0.15);
border-radius: 5px;
cursor: pointer;
}

View File

@@ -3,17 +3,17 @@
left: 0;
right: 0;
bottom: 0;
z-index: $drawerZ;
z-index: 351;
border-radius: 16px 16px 0 0;
&.notification-portal {
z-index: $dropdownZ;
z-index: 901;
}
}
.drawer-portal::after {
content: '';
background-color: $participantsPaneBgColor;
background-color: #141414;
margin-bottom: env(safe-area-inset-bottom, 0);
}
@@ -54,7 +54,7 @@
padding: 12px 16px;
align-items: center;
color: $overflowMenuItemColor;
color: #fff;
cursor: pointer;
display: flex;
font-size: 16px;

View File

@@ -3,20 +3,20 @@
@include border-radius(4px);
padding: 40px 38px 44px;
color: #fff;
background: $inlayColorBg;
background: lighten(#474747, 20%);
text-align: center;
&__title {
margin: 17px 0;
padding-bottom: 17px;
color: $popoverFontColor;
color: #ffffff;
font-size: 21px;
letter-spacing: 0.3px;
border-bottom: 1px solid $inlayBorderColor;
border-bottom: 1px solid lighten(#FFFFFF, 10%);
}
&__text {
color: $popoverFontColor;
color: #ffffff;
display: block;
margin-top: 22px;
font-size: 16px;

View File

@@ -1,5 +1,5 @@
.participants_pane {
background-color: $participantsPaneBgColor;
background-color: #141414;
flex-shrink: 0;
overflow: hidden;
position: relative;

View File

@@ -1,5 +1,5 @@
.popover {
z-index: $popoverZ;
z-index: 8;
.popover-content {
position: relative;

View File

@@ -2,7 +2,7 @@
.reactions-menu {
width: 280px;
background: $menuBG;
background: #242528;
box-shadow: 0px 3px 16px rgba(0, 0, 0, 0.6), 0px 0px 4px 1px rgba(0, 0, 0, 0.25);
border-radius: 6px;
padding: 16px;

View File

@@ -186,7 +186,7 @@
}
.google-error {
color: $errorColor;
color: #c61600;
}
.google-panel {

View File

@@ -5,7 +5,7 @@
font-size: 24px;
.thanks-msg {
border-bottom: 1px solid $selectBg;
border-bottom: 1px solid #FFFFFF;
padding-left: 30px;
padding-right: 30px;
p {
@@ -28,7 +28,7 @@
width: 120px;
height: 86px;
margin: 0 auto;
background: $happySoftwareBackground;
background: transparent;
}
}
}

View File

@@ -2,10 +2,10 @@
* Round badge.
*/
.badge-round {
background-color: $toolbarBadgeBackground;
background-color: #165ECC;
border-radius: 50%;
box-sizing: border-box;
color: $toolbarBadgeColor;
color: #FFFFFF;
// Do not inherit the font-family from the toolbar button, because it's an
// icon style.
font-family: $baseFontFamily;
@@ -32,6 +32,14 @@
pointer-events: none;
z-index: $toolbarZ + 2;
&.shift-up {
bottom: calc(((#{$newToolbarSize} + 30px) * 2) * -1);
.toolbox-content {
margin-bottom: 46px;
}
}
&.visible {
bottom: 0;
}
@@ -184,7 +192,7 @@ div.hangup-menu-button {
background: none;
&:hover {
background: $newToolbarButtonHoverColor;
background: rgba(255, 255, 255, 0.2);
}
}

View File

@@ -13,7 +13,7 @@
1px 0px 1px rgba(0,0,0,0.3),
0px 0px 1px rgba(0,0,0,0.3);
transform: translateX(-50%);
z-index: $subtitlesZ;
z-index: 7;
&.lifted {
// Lift subtitle above toolbar+dominant speaker box.

View File

@@ -41,3 +41,36 @@
display: -webkit-flex !important;
display: flex !important;
}
/**
* resets default button styles,
* mostly intended to be used on interactive elements that
* differ from their default styles (e.g. <a>) or have custom styles
*/
.invisible-button {
background: none;
border: none;
color: inherit;
cursor: pointer;
padding: 0;
}
/**
* style an element the same as an <a>
* useful on some cases where we visually have a link but it's actually a <button>
*/
.as-link {
@extend .invisible-button;
display: inline;
color: #44A5FF;
text-decoration: none;
font-weight: bold;
&:focus,
&:hover,
&:active {
text-decoration: underline;
}
}

View File

@@ -1,5 +1,3 @@
@import "themes/light";
/**
* Style variables
*/
@@ -10,83 +8,26 @@ $baseFontFamily: -apple-system, BlinkMacSystemFont, 'open_sanslight', 'Helvetica
*/
// Video layout.
$thumbnailVideoMargin: 2px;
$thumbnailsBorder: 2px;
$thumbnailVideoBorder: 2px;
$filmstripToggleButtonWidth: 17px;
/**
* Color variables.
*/
$defaultColor: #F1F1F1;
$defaultSideBarFontColor: #44A5FF;
$defaultSemiDarkColor: #ACACAC;
$defaultDarkColor: #2b3d5c;
$defaultWarningColor: rgb(215, 121, 118);
$participantsPaneBgColor: #141414;
/**
* Toolbar
*/
$newToolbarBackgroundColor: #131519;
$newToolbarButtonHoverColor: rgba(255, 255, 255, 0.2);
$newToolbarButtonToggleColor: rgba(255, 255, 255, 0.15);
$menuBG:#242528;
$newToolbarFontSize: 24px;
$newToolbarHangupFontSize: 32px;
$newToolbarSize: 48px;
$newToolbarSizeMobile: 60px;
$newToolbarSizeWithPadding: calc(#{$newToolbarSize} + 24px);
$toolbarTitleFontSize: 19px;
$overflowMenuItemColor: #fff;
/**
* Video layout
*/
$participantNameColor: #fff;
$audioLevelBg: #44A5FF;
$audioLevelShadow: rgba(9, 36, 77, 0.9);
$videoStateIndicatorColor: $defaultColor;
$videoStateIndicatorBackground: $toolbarBackground;
$videoStateIndicatorSize: 40px;
/**
* Feedback Modal
*/
$feedbackContentBg: #fff;
$feedbackInputBg: #fff;
$feedbackTextColor: #000;
$feedbackInputTextColor: #333;
$feedbackInputPlaceholderColor: #777;
/**
* Modals
*/
$modalButtonFontSize: 14px;
$modalMockAKInputBackground: #fafbfc;
$modalMockAKInputBorder: 1px solid #f4f5f7;
$modalTextColor: #333;
/**
* Chat
*/
$chatActionsSeparatorColor: rgb(173, 105, 112);
$chatBackgroundColor: #131519;
$chatInputSeparatorColor: #A4B8D1;
$chatLobbyActionsSeparatorColor: #6A50D3;
$chatLocalMessageBackgroundColor: #484A4F;
$chatPrivateMessageBackgroundColor: rgb(153, 69, 77);
$chatRemoteMessageBackgroundColor: #242528;
$sidebarWidth: 315px;
/**
* Misc.
*/
$borderRadius: 4px;
$happySoftwareBackground: transparent;
$desktopAppDragBarHeight: 25px;
$scrollHeight: 7px;
/**
@@ -96,38 +37,11 @@ $zindex0: 0;
$zindex1: 1;
$zindex2: 2;
$zindex3: 3;
$subtitlesZ: 7;
$popoverZ: 8;
$reloadZ: 20;
$poweredByZ: 100;
$ringingZ: 300;
$sideToolbarContainerZ: 300;
$toolbarZ: 250;
$drawerZ: 351;
$dropdownZ: 901;
$overlayZ: 1016;
// Place filmstrip videos over toolbar in order
// to make connection info visible.
$filmstripVideosZ: $toolbarZ + 1;
/**
* Font Colors
*/
$defaultFontColor: #777;
$defaultLightFontColor: #F1F1F1;
$defaultDarkFontColor: #000;
/**
* Forms
*/
//inputs
$inputControlEmColor: #f29424;
//buttons
$linkFontColor: #489afe;
$linkHoverFontColor: #287ade;
$formPadding: 16px;
/**
* Unsupported browser
*/

View File

@@ -108,6 +108,10 @@
#largeVideoContainer {
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
margin: 0 !important;
}
#largeVideoWrapper {
@@ -185,7 +189,7 @@
opacity: 0;
display: inline-block;
@include circle(5px);
background: $audioLevelShadow;
background: rgba(9, 36, 77, 0.9);
margin: 1px 0 1px 0;
transition: opacity .25s ease-in-out;
-moz-transition: opacity .25s ease-in-out;
@@ -201,7 +205,7 @@
border-radius: 50%;
-webkit-filter: blur(0.5px);
filter: blur(0.5px);
background: $audioLevelBg;
background: #44A5FF;
}
}
@@ -219,7 +223,7 @@
background-clip: padding-box;
-webkit-border-radius: 5px;
-webkit-background-clip: padding-box;
z-index: $reloadZ; /*The reload button should appear on top of the header!*/
z-index: 20; /*The reload button should appear on top of the header!*/
}
#dominantSpeaker {
@@ -361,7 +365,7 @@
}
.presence-label {
color: $participantNameColor;
color: #fff;
font-size: 12px;
font-weight: 100;
left: 0;

View File

@@ -63,7 +63,7 @@ body.welcome-page {
.insecure-room-name-warning {
align-items: center;
color: $defaultWarningColor;
color: rgb(215, 121, 118);
font-weight: 600;
display: flex;
flex-direction: row;
@@ -75,7 +75,7 @@ body.welcome-page {
margin-right: 15px;
svg {
fill: $defaultWarningColor;
fill: rgb(215, 121, 118);
& > *:first-child {
fill: none !important;

View File

@@ -19,7 +19,7 @@ input[type=range]:focus {
* Include the mixin for a range input style.
*/
@include slider {
background: $sliderTrackBackground;
background: #474747;
border: none;
border-radius: 3px;
cursor: pointer;
@@ -33,9 +33,9 @@ input[type=range]:focus {
@include slider-thumb {
-webkit-appearance: none;
background: white;
border: 1px solid $sliderThumbBackground;
border: 1px solid #3572b0;
border-radius: 50%;
box-shadow: 0px 0px 1px $sliderThumbBackground;
box-shadow: 0px 0px 1px #3572b0;
cursor: pointer;
height: 14px;
margin-top: -4px;

View File

@@ -5,7 +5,7 @@
width: auto;
&__title {
border-bottom: 1px solid $inlayBorderColor;
border-bottom: 1px solid lighten(#FFFFFF, 10%);
color: $unsupportedBrowserTitleColor;
font-weight: 400;
letter-spacing: 0.5px;

View File

@@ -2,9 +2,9 @@
display: inline-block;
position: relative;
background-size: contain;
border: $thumbnailVideoBorder solid transparent;
border: 2px solid transparent;
border-radius: $borderRadius;
margin: 0 $thumbnailVideoMargin;
margin: 0 2px;
&:hover {
cursor: hand;

View File

@@ -60,7 +60,6 @@ $flagsImagePath: "../images/";
@import 'filmstrip/vertical_filmstrip';
@import 'filmstrip/vertical_filmstrip_overrides';
@import 'unsupported-browser/main';
@import 'modals/invite/add-people';
@import 'deep-linking/main';
@import 'transcription-subtitles';
@import '_meetings_list.scss';

View File

@@ -2,8 +2,8 @@
margin-top: 5px !important;
.input-control {
background: $modalMockAKInputBackground;
border: $modalMockAKInputBorder;
background: #fafbfc;
border: 1px solid #f4f5f7;
color: inherit;
}
@@ -12,24 +12,6 @@
}
}
/**
* Styling inline dialog errors.
*/
.inline-dialog-error {
margin-top: 16px;
&-text {
color: $dialogErrorText;
margin-bottom: 8px;
text-align: center;
}
&-button {
display: block;
margin: 16px auto 0 auto;
}
}
/**
* Styling shared video dialog errors.
*/

View File

@@ -41,10 +41,3 @@
}
}
}
/**
* Styles errors in the MultiSelectAutocomplete.
*/
.autocomplete-error {
min-width: 260px;
}

View File

@@ -57,6 +57,10 @@
line-height: 24px;
border-collapse: collapse;
* {
user-select: text;
}
thead {
text-align: left;
}

View File

@@ -1,57 +1,4 @@
.invite-more {
&-container {
margin-bottom: 8px;
transition: margin-bottom 0.3s;
&.elevated {
margin-bottom: 36px;
}
}
&-content {
display: flex;
flex-direction: column;
align-items: center;
padding: 16px;
background: rgba(0, 0, 0, 0.7);
border-radius: 8px;
color: #fff;
font-size: 14px;
line-height: 24px;
font-weight: 600;
}
&-header {
max-width: 100%;
margin-bottom: 16px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
&-button {
display: flex;
max-width: 100%;
height: 40px;
box-sizing: border-box;
padding: 8px 16px;
background: #0376DA;
border-radius: 3px;
cursor: pointer;
@media (hover: hover) and (pointer: fine) {
&:hover {
background: #278ADF;
}
}
&-text {
margin-left: 8px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
&-dialog {
color: #fff;
font-size: 15px;
@@ -65,59 +12,6 @@
background: #5E6D7A;
}
&.email-container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 8px 8px 16px;
margin-top: 24px;
width: calc(100% - 26px);
height: 22px;
background: #2A3A4B;
border: 1px solid #5E6D7A;
border-radius: 3px;
cursor: pointer;
&.active {
border-radius: 3px 3px 0 0;
}
}
&.invite-buttons {
width: 100%;
text-align: right;
margin-top: 8px;
& > a {
display: inline-block;
height: 24px;
min-width: 48px;
border-radius: 3px;
text-align: center;
text-decoration: none;
cursor: pointer;
}
&-cancel {
margin-right: 16px;
padding: 7px 15px;
background: #2A3A4B;
border: 1px solid #5E6D7A;
}
&-add {
padding: 8px 16px;
background: #0376DA;
}
&.disabled {
& > a {
pointer-events: none;
}
}
}
&.stream {
display: flex;
justify-content: space-between;
@@ -158,14 +52,3 @@
}
}
}
.mobile-browser {
.invite-more-content {
font-size: 16px;
}
.invite-more-button {
height: 48px;
padding: 12px 16px;
}
}

View File

@@ -21,7 +21,7 @@
&-actions {
margin-top: 10px;
a {
button {
cursor: pointer;
text-decoration: none;
font-size: 14px;

View File

@@ -6,12 +6,12 @@
width: 100%;
height: 100%;
position: fixed;
z-index: $overlayZ;
background: $defaultBackground;
z-index: 1016;
background: #474747;
}
&__container-light {
@include transparentBg($defaultBackground, 0.7);
@include transparentBg(#474747, 0.7);
}
&__content {

View File

@@ -19,7 +19,7 @@
width: 180px;
.progress-indicator-fill {
background: $reloadProgressBarBg;
background: #0074E0;
height: 100%;
transition: width .5s;
}

View File

@@ -5,11 +5,11 @@
width: 100%;
height: 100%;
position: fixed;
z-index: $ringingZ;
z-index: 300;
@include transparentBg(#283447, 0.95);
&.solidBG {
background: $defaultBackground;
background: #040404;
}
&__content {

View File

@@ -1,77 +0,0 @@
/**
* Base
*/
$baseLight: #FFFFFF;
/**
* Controls
*/
$sliderTrackBackground: #474747;
$sliderThumbBackground: #3572b0;
/**
* Buttons
*/
$buttonBackground: #44A5FF;
$buttonHoverBackground: #2c4062;
$buttonBorder: transparent;
$buttonHoverBorder: transparent;
$buttonColor: #eceef1;
$buttonLightBackground: #f5f5f5;
$buttonLightHoverBackground: #e9e9e9;
$buttonLightBorder: #ccc;
$buttonLightHoverBorder: #999;
$buttonLinkBackground: transparent;
$buttonLinkColor: #0090e8;
$primaryButtonBackground: #3572b0;
$primaryButtonHoverBackground: #2a67a5;
$primaryButtonColor: $baseLight;
$primaryButtonFontWeight: 400;
$buttonShadowColor: #192d4f;
$overlayButtonBg: #0074E0;
/**
* Color variables
**/
$defaultBackground: #474747;
$reloadProgressBarBg: #0074E0;
/**
* Dialog colors
**/
$dialogErrorText: #344563;
/**
* Inlay colors
**/
$inlayColorBg: lighten($defaultBackground, 20%);
$inlayBorderColor: lighten($baseLight, 10%);
// Main controls
$placeHolderColor: #a7a7a7;
$readOnlyInputColor: #a7a7a7;
$defaultDarkSelectionColor: #ccc;
$buttonFontWeight: 400;
$labelFontWeight: 400;
$linkFontColor: #3572b0;
$linkHoverFontColor: darken(#3572b0, 10%);
$errorColor: #c61600;
// Popover colors
$popoverFontColor: #ffffff !important;
// Toolbar
$toolbarBackground: rgba(0, 0, 0, 0.5);
$toolbarBadgeBackground: #165ECC;
$toolbarBadgeColor: #FFFFFF;
/**
* Forms
*/
$selectBg: $baseLight;

View File

@@ -25,11 +25,11 @@
}
&__link {
color: $linkFontColor;
color: #489afe;
@include transition(color .1s ease-out);
&:hover {
color: $linkHoverFontColor;
color: #287ade;
cursor: pointer;
text-decoration: none;

View File

@@ -1,3 +1,6 @@
doc/debian/jitsi-meet/jitsi-meet.example /usr/share/jitsi-meet-web-config/
doc/debian/jitsi-meet/jitsi-meet.example-apache /usr/share/jitsi-meet-web-config/
config.js /usr/share/jitsi-meet-web-config/
doc/jaas/nginx-jaas.conf /usr/share/jitsi-meet-web-config/
doc/jaas/index-jaas.html /usr/share/jitsi-meet-web-config/
doc/jaas/8x8.vc-config.js /usr/share/jitsi-meet-web-config/

View File

@@ -12,3 +12,5 @@ resources/robots.txt /usr/share/jitsi-meet/
resources/*.sh /usr/share/jitsi-meet/scripts/
pwa-worker.js /usr/share/jitsi-meet/
manifest.json /usr/share/jitsi-meet/
doc/jaas/move-to-jaas.sh /usr/share/jitsi-meet/scripts/
doc/jaas/update-asap-daily.sh /usr/share/jitsi-meet/scripts/

View File

@@ -84,8 +84,12 @@ Component "conference.jitmeet.example.com" "muc"
"polls";
--"token_verification";
"muc_rate_limit";
"muc_password_whitelist";
}
admins = { "focusUser@auth.jitmeet.example.com" }
muc_password_whitelist = {
"focusUser@auth.jitmeet.example.com"
}
muc_room_locking = false
muc_room_default_public_jids = true

View File

@@ -58,6 +58,8 @@ server {
add_header Strict-Transport-Security "max-age=63072000" always;
set $prefix "";
set $custom_index "";
set $config_js_location /etc/jitsi/meet/jitsi-meet.example.com-config.js;
ssl_certificate /etc/jitsi/meet/jitsi-meet.example.com.crt;
ssl_certificate_key /etc/jitsi/meet/jitsi-meet.example.com.key;
@@ -77,8 +79,10 @@ server {
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 512;
include /etc/jitsi/meet/jaas/*.conf;
location = /config.js {
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
alias $config_js_location;
}
location = /external_api.js {
@@ -92,6 +96,11 @@ server {
proxy_set_header Host $http_host;
}
location ~ ^/_api/public/(.*)$ {
autoindex off;
alias /etc/jitsi/meet/public/$1;
}
# ensure all static content can always be found first
location ~ ^/(libs|css|static|images|fonts|lang|sounds|.well-known)/(.*)$
{
@@ -142,11 +151,12 @@ server {
#}
location ~ ^/([^/?&:'"]+)$ {
set $roomname "$1";
try_files $uri @root_path;
}
location @root_path {
rewrite ^/(.*)$ / break;
rewrite ^/(.*)$ /$custom_index break;
}
location ~ ^/([^/?&:'"]+)/config.js$
@@ -154,7 +164,7 @@ server {
set $subdomain "$1.";
set $subdir "$1/";
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
alias $config_js_location;
}
# Matches /(TENANT)/pwa-worker.js or /(TENANT)/manifest.json to rewrite to / and look for file

View File

@@ -0,0 +1,7 @@
</script>
<script src="https://8x8.vc/<!--# echo var="subdir" default="" -->config.js" onload="{
config.p2p.disabledCodec='VP9';
config.videoQuality.disabledCodec='VP9';
config.e2ee = { externallyManagedKey: true };
}"/>
<script>

22
doc/jaas/README.md Normal file
View File

@@ -0,0 +1,22 @@
## How to switch your deployment to [JaaS](https://jaas.8x8.vc) in one easy step
Note: By default it will have e2ee(end-to-end) encryption enabled that works only on chromium based browsers (Chrome, Edge, ...). If a participant joins from another browser or mobile the e2ee is turned off.
In order to use your deployment with JaaS you first need to login to your [JaaS Developer console](https://jaas.8x8.vc/#/apikeys) and generate a key pair.
Use `Add API key` button and then `Generate API key pair`. Make sure you download the generated private key from:
<img src="generated_key_dialog.png" height="250">
Make sure you transfer this downloaded private key to your server. Copy the key id from:
<img src="api_keys_kid.png" height="200">
Now on your server run the helper script passing the private key file and the key id:
```
sudo /usr/share/jitsi-meet/scripts/move-to-jaas.sh /my/path/test-key.pk <key_id>
```
More information about JaaS Api keys at: https://developer.8x8.com/jaas/docs/jaas-console-api-keys
If you want to adjust the enabled services you can do that in /etc/jits/meet/jaas/nginx-jaas.conf. The part after `proxy_set_body` is the jwt token content that will be used for the client tokens. More info about the JaaS tokens: https://developer.8x8.com/jaas/docs/api-keys-jwt

BIN
doc/jaas/api_keys_kid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

33
doc/jaas/index-jaas.html Normal file
View File

@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<head>
<script src='external_api.js' async></script>
<style>html, body, #jaas-container { height: 100%; }</style>
<script type="text/javascript">
function getRoomName(pathname) {
const contextRootEndIndex = pathname.lastIndexOf('/');
return pathname.substring(contextRootEndIndex + 1);
}
window.onload = () => {
const jaasJwt = <!--#include virtual="/jaas-jwt" -->;
const api = new JitsiMeetExternalAPI(
window.location.host, {
roomName: `${jaasJwt.tenant}/${jaasJwt.confId}`,
parentNode: document.querySelector('#jaas-container'),
jwt: jaasJwt.token,
e2eeKey: jaasJwt.e2eeKey
});
api.addListener('videoConferenceJoined', () => {
if (jaasJwt.e2eeKey) {
console.info('Toggling e2ee on!')
api.executeCommand('toggleE2EE', true);
}
});
}
</script>
</head>
<body>
<div id="jaas-container" />
</body>
</html>

59
doc/jaas/move-to-jaas.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/bash
set -e
PRIVATE_KEY=$1
JAAS_KEY_ID=$2
if [ ! -f "${PRIVATE_KEY}" ] ; then
echo "You need to specify a correct path for the private key as a first argument."
exit 1;
fi
if [[ ! "${JAAS_KEY_ID}" =~ ^vpaas-magic-cookie-[0-9a-z]+/[0-9a-z]+$ ]]; then
echo "Invalid key id passed as a second argument."
exit 2;
fi
command -v node >/dev/null 2>&1 || { echo >&2 "You must install node first, go to https://nodejs.org. Aborting."; exit 4; }
NODE_VER=$(node -v);
NODE_MAJOR_VER=$(echo ${NODE_VER:1} | cut -d. -f1);
if [ "$NODE_MAJOR_VER" -lt "18" ]; then
echo "Please install latest LTS version of node (18+)";
exit 3;
fi
# we need this util for debconf-set-selections
sudo apt install debconf-utils
# Let's pre-set some settings for token-generator
cat << EOF | sudo debconf-set-selections
token-generator token-generator/private-key string ${PRIVATE_KEY}
token-generator token-generator/kid string ${JAAS_KEY_ID}
EOF
apt install token-generator
mkdir -p /etc/jitsi/meet/jaas
VPASS_COOKIE=$(echo -n ${JAAS_KEY_ID}| cut -d/ -f1)
cp /usr/share/jitsi-meet-web-config/nginx-jaas.conf /etc/jitsi/meet/jaas
sed -i "s/jaas_magic_cookie/${VPASS_COOKIE}/g" /etc/jitsi/meet/jaas/nginx-jaas.conf
cp /usr/share/jitsi-meet-web-config/8x8.vc-config.js /etc/jitsi/meet/jaas/
echo "set \$config_js_location /etc/jitsi/meet/jaas/8x8.vc-config.js;" >> /etc/jitsi/meet/jaas/jaas-vars
echo "set \$custom_index index-jaas.html;" >> /etc/jitsi/meet/jaas/jaas-vars
ln -s /usr/share/jitsi-meet-web-config/index-jaas.html /usr/share/jitsi-meet/index-jaas.html
# let's create the daily key now
/usr/share/jitsi-meet/scripts/update-asap-daily.sh
# let's add to cron daily the update of the asap key
if [ -d /etc/cron.daily ]; then
ln -s /usr/share/jitsi-meet/scripts/update-asap-daily.sh /etc/cron.daily/update-jaas-asap.sh
else
echo "No /etc/cron.daily. Please add to your cron jobs to execute as root daily the script: /usr/share/jitsi-meet/scripts/update-asap-daily.sh"
fi

23
doc/jaas/nginx-jaas.conf Normal file
View File

@@ -0,0 +1,23 @@
include /etc/jitsi/meet/jaas/jaas-vars;
location = /jaas-jwt {
include /etc/jitsi/token-generator/daily-key;
ssi on;
proxy_method POST;
proxy_set_header content-type "application/json";
proxy_set_header Accept-Encoding "";
proxy_set_header Authorization "Bearer $jaas_asap_key";
proxy_pass_request_body off;
proxy_set_body '{"sub":"jaas_magic_cookie","context":{"features":{"livestreaming":false,"outbound-call":false,"sip-outbound-call":false,"transcription":false,"recording":false},"user":{"moderator":true}},"room": "$roomname"}';
proxy_pass http://127.0.0.1:8017/generate/client?e2eeKey=true&confId=true;
}
location @magic_root_path {
rewrite ^/(.*)$ /index.html break;
}
# Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
location ~ ^/jaas_magic_cookie/(.*)$ {
set $subdomain "jaas_magic_cookie.";
set $subdir "jaas_magic_cookie/";
try_files $1 @magic_root_path;
}

9
doc/jaas/update-asap-daily.sh Executable file
View File

@@ -0,0 +1,9 @@
JWT_KID=$(cat /etc/jitsi/token-generator/config | grep SYSTEM_ASAP_BASE_URL_MAPPINGS | cut -d= -f2- | jq -r .[].kid)
JWT_DATE=$(echo -n $JWT_KID | cut -d/ -f2-)
JWT_DATE=${JWT_DATE#jwt-}
KEY_FILE=/etc/jitsi/token-generator/daily-key
echo -n "set \$jaas_asap_key " > ${KEY_FILE}
ASAP_KEY=$(ASAP_SIGNING_KEY_FILE=/etc/jitsi/token-generator/asap-${JWT_DATE}.key ASAP_JWT_KID="${JWT_KID}" ASAP_EXPIRES_IN="1 day" node /usr/share/token-generator/jwt.js| tail -n1)
echo -n "${ASAP_KEY};" >> ${KEY_FILE}
service nginx reload

7
globals.d.ts vendored
View File

@@ -10,12 +10,6 @@ declare global {
API: any;
conference: any;
debugLogs: any;
keyboardshortcut: {
registerShortcut: Function;
unregisterShortcut: Function;
openDialog: Function;
enable: Function;
}
};
const interfaceConfig: any;
@@ -27,6 +21,7 @@ declare global {
JitsiMeetElectron?: any;
// selenium tests handler
_sharedVideoPlayer: any;
alwaysOnTop: { api: any };
}
interface Document {

1
globals.native.d.ts vendored
View File

@@ -30,6 +30,7 @@ interface IWindow {
setImmediate: typeof setImmediate;
clearImmediate: typeof clearImmediate;
addEventListener: Function;
removeEventListener: Function;
}
interface INavigator {

View File

@@ -1,11 +1,13 @@
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
platform :ios, '12.0'
platform :ios, '12.4'
workspace 'jitsi-meet'
install! 'cocoapods', :deterministic_uuids => false
production = ENV["PRODUCTION"] == "1"
target 'JitsiMeet' do
project 'app/app.xcodeproj'
@@ -21,8 +23,10 @@ target 'JitsiMeetSDK' do
#
config = use_native_modules!
flags = get_default_flags()
use_react_native!(
:path => config["reactNativePath"],
:path => config[:reactNativePath],
:production => production,
:hermes_enabled => false,
:fabric_enabled => false,
# An absolute path to your application root.
@@ -81,7 +85,7 @@ post_install do |installer|
end
target.build_configurations.each do |config|
config.build_settings['SUPPORTS_MACCATALYST'] = 'NO'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.4'
end
end
end

View File

@@ -14,14 +14,14 @@ PODS:
- CocoaLumberjack/Core (= 3.7.2)
- CocoaLumberjack/Core (3.7.2)
- DoubleConversion (1.1.6)
- FBLazyVector (0.68.6)
- FBReactNativeSpec (0.68.6):
- FBLazyVector (0.69.10)
- FBReactNativeSpec (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.68.6)
- RCTTypeSafety (= 0.68.6)
- React-Core (= 0.68.6)
- React-jsi (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- RCTRequired (= 0.69.10)
- RCTTypeSafety (= 0.69.10)
- React-Core (= 0.69.10)
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- Firebase/Analytics (8.15.0):
- Firebase/Core
- Firebase/Core (8.15.0):
@@ -77,10 +77,10 @@ PODS:
- GoogleUtilities/UserDefaults (~> 7.7)
- PromisesObjC (< 3.0, >= 1.2)
- fmt (6.2.1)
- Giphy (2.1.20):
- Giphy (2.2.4):
- libwebp
- giphy-react-native-sdk (1.7.0):
- Giphy (= 2.1.20)
- giphy-react-native-sdk (2.3.0):
- Giphy (= 2.2.4)
- React-Core
- glog (0.3.5)
- GoogleAppMeasurement (8.15.0):
@@ -134,7 +134,7 @@ PODS:
- AppAuth/Core (~> 1.6)
- GTMSessionFetcher/Core (< 3.0, >= 1.5)
- GTMSessionFetcher/Core (2.3.0)
- JitsiWebRTC (111.0.1)
- JitsiWebRTC (111.0.2)
- libwebp (1.2.4):
- libwebp/demux (= 1.2.4)
- libwebp/mux (= 1.2.4)
@@ -164,201 +164,203 @@ PODS:
- DoubleConversion
- fmt (~> 6.2.1)
- glog
- RCTRequired (0.68.6)
- RCTTypeSafety (0.68.6):
- FBLazyVector (= 0.68.6)
- RCTRequired (0.69.10)
- RCTTypeSafety (0.69.10):
- FBLazyVector (= 0.69.10)
- RCTRequired (= 0.69.10)
- React-Core (= 0.69.10)
- React (0.69.10):
- React-Core (= 0.69.10)
- React-Core/DevSupport (= 0.69.10)
- React-Core/RCTWebSocket (= 0.69.10)
- React-RCTActionSheet (= 0.69.10)
- React-RCTAnimation (= 0.69.10)
- React-RCTBlob (= 0.69.10)
- React-RCTImage (= 0.69.10)
- React-RCTLinking (= 0.69.10)
- React-RCTNetwork (= 0.69.10)
- React-RCTSettings (= 0.69.10)
- React-RCTText (= 0.69.10)
- React-RCTVibration (= 0.69.10)
- React-bridging (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.68.6)
- React-Core (= 0.68.6)
- React (0.68.6):
- React-Core (= 0.68.6)
- React-Core/DevSupport (= 0.68.6)
- React-Core/RCTWebSocket (= 0.68.6)
- React-RCTActionSheet (= 0.68.6)
- React-RCTAnimation (= 0.68.6)
- React-RCTBlob (= 0.68.6)
- React-RCTImage (= 0.68.6)
- React-RCTLinking (= 0.68.6)
- React-RCTNetwork (= 0.68.6)
- React-RCTSettings (= 0.68.6)
- React-RCTText (= 0.68.6)
- React-RCTVibration (= 0.68.6)
- React-callinvoker (0.68.6)
- React-Codegen (0.68.6):
- FBReactNativeSpec (= 0.68.6)
- React-jsi (= 0.69.10)
- React-callinvoker (0.69.10)
- React-Codegen (0.69.10):
- FBReactNativeSpec (= 0.69.10)
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.68.6)
- RCTTypeSafety (= 0.68.6)
- React-Core (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-Core (0.68.6):
- RCTRequired (= 0.69.10)
- RCTTypeSafety (= 0.69.10)
- React-Core (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-Core (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.68.6)
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-Core/Default (= 0.69.10)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/CoreModulesHeaders (0.68.6):
- React-Core/CoreModulesHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/Default (0.68.6):
- React-Core/Default (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/DevSupport (0.68.6):
- React-Core/DevSupport (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.68.6)
- React-Core/RCTWebSocket (= 0.68.6)
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-jsinspector (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-Core/Default (= 0.69.10)
- React-Core/RCTWebSocket (= 0.69.10)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-jsinspector (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTActionSheetHeaders (0.68.6):
- React-Core/RCTActionSheetHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTAnimationHeaders (0.68.6):
- React-Core/RCTAnimationHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTBlobHeaders (0.68.6):
- React-Core/RCTBlobHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTImageHeaders (0.68.6):
- React-Core/RCTImageHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTLinkingHeaders (0.68.6):
- React-Core/RCTLinkingHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTNetworkHeaders (0.68.6):
- React-Core/RCTNetworkHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTSettingsHeaders (0.68.6):
- React-Core/RCTSettingsHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTTextHeaders (0.68.6):
- React-Core/RCTTextHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTVibrationHeaders (0.68.6):
- React-Core/RCTVibrationHeaders (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-Core/RCTWebSocket (0.68.6):
- React-Core/RCTWebSocket (0.69.10):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default (= 0.68.6)
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsiexecutor (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-Core/Default (= 0.69.10)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- Yoga
- React-CoreModules (0.68.6):
- React-CoreModules (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.6)
- React-Codegen (= 0.68.6)
- React-Core/CoreModulesHeaders (= 0.68.6)
- React-jsi (= 0.68.6)
- React-RCTImage (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-cxxreact (0.68.6):
- RCTTypeSafety (= 0.69.10)
- React-Codegen (= 0.69.10)
- React-Core/CoreModulesHeaders (= 0.69.10)
- React-jsi (= 0.69.10)
- React-RCTImage (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-cxxreact (0.69.10):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.68.6)
- React-jsi (= 0.68.6)
- React-jsinspector (= 0.68.6)
- React-logger (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-runtimeexecutor (= 0.68.6)
- React-jsi (0.68.6):
- React-callinvoker (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsinspector (= 0.69.10)
- React-logger (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-runtimeexecutor (= 0.69.10)
- React-jsi (0.69.10):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsi/Default (= 0.68.6)
- React-jsi/Default (0.68.6):
- React-jsi/Default (= 0.69.10)
- React-jsi/Default (0.69.10):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsiexecutor (0.68.6):
- React-jsiexecutor (0.69.10):
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-jsinspector (0.68.6)
- React-logger (0.68.6):
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-jsinspector (0.69.10)
- React-logger (0.69.10):
- glog
- react-native-background-timer (2.4.1):
- React-Core
@@ -372,9 +374,7 @@ PODS:
- React-Core
- react-native-pager-view (5.4.9):
- React-Core
- react-native-performance (2.1.0):
- React-Core
- react-native-safe-area-context (4.4.1):
- react-native-safe-area-context (4.6.4):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
@@ -390,76 +390,77 @@ PODS:
- react-native-video/Video (6.0.0-alpha.1):
- PromisesSwift
- React-Core
- react-native-webrtc (111.0.0):
- react-native-webrtc (111.0.3):
- JitsiWebRTC (~> 111.0.0)
- React-Core
- react-native-webview (11.15.1):
- React-Core
- React-perflogger (0.68.6)
- React-RCTActionSheet (0.68.6):
- React-Core/RCTActionSheetHeaders (= 0.68.6)
- React-RCTAnimation (0.68.6):
- React-perflogger (0.69.10)
- React-RCTActionSheet (0.69.10):
- React-Core/RCTActionSheetHeaders (= 0.69.10)
- React-RCTAnimation (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.6)
- React-Codegen (= 0.68.6)
- React-Core/RCTAnimationHeaders (= 0.68.6)
- React-jsi (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-RCTBlob (0.68.6):
- RCTTypeSafety (= 0.69.10)
- React-Codegen (= 0.69.10)
- React-Core/RCTAnimationHeaders (= 0.69.10)
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-RCTBlob (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- React-Codegen (= 0.68.6)
- React-Core/RCTBlobHeaders (= 0.68.6)
- React-Core/RCTWebSocket (= 0.68.6)
- React-jsi (= 0.68.6)
- React-RCTNetwork (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-RCTImage (0.68.6):
- React-Codegen (= 0.69.10)
- React-Core/RCTBlobHeaders (= 0.69.10)
- React-Core/RCTWebSocket (= 0.69.10)
- React-jsi (= 0.69.10)
- React-RCTNetwork (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-RCTImage (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.6)
- React-Codegen (= 0.68.6)
- React-Core/RCTImageHeaders (= 0.68.6)
- React-jsi (= 0.68.6)
- React-RCTNetwork (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-RCTLinking (0.68.6):
- React-Codegen (= 0.68.6)
- React-Core/RCTLinkingHeaders (= 0.68.6)
- React-jsi (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-RCTNetwork (0.68.6):
- RCTTypeSafety (= 0.69.10)
- React-Codegen (= 0.69.10)
- React-Core/RCTImageHeaders (= 0.69.10)
- React-jsi (= 0.69.10)
- React-RCTNetwork (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-RCTLinking (0.69.10):
- React-Codegen (= 0.69.10)
- React-Core/RCTLinkingHeaders (= 0.69.10)
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-RCTNetwork (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.6)
- React-Codegen (= 0.68.6)
- React-Core/RCTNetworkHeaders (= 0.68.6)
- React-jsi (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-RCTSettings (0.68.6):
- RCTTypeSafety (= 0.69.10)
- React-Codegen (= 0.69.10)
- React-Core/RCTNetworkHeaders (= 0.69.10)
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-RCTSettings (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTTypeSafety (= 0.68.6)
- React-Codegen (= 0.68.6)
- React-Core/RCTSettingsHeaders (= 0.68.6)
- React-jsi (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-RCTText (0.68.6):
- React-Core/RCTTextHeaders (= 0.68.6)
- React-RCTVibration (0.68.6):
- RCTTypeSafety (= 0.69.10)
- React-Codegen (= 0.69.10)
- React-Core/RCTSettingsHeaders (= 0.69.10)
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-RCTText (0.69.10):
- React-Core/RCTTextHeaders (= 0.69.10)
- React-RCTVibration (0.69.10):
- RCT-Folly (= 2021.06.28.00-v2)
- React-Codegen (= 0.68.6)
- React-Core/RCTVibrationHeaders (= 0.68.6)
- React-jsi (= 0.68.6)
- ReactCommon/turbomodule/core (= 0.68.6)
- React-runtimeexecutor (0.68.6):
- React-jsi (= 0.68.6)
- ReactCommon/turbomodule/core (0.68.6):
- React-Codegen (= 0.69.10)
- React-Core/RCTVibrationHeaders (= 0.69.10)
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- React-runtimeexecutor (0.69.10):
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (0.69.10):
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-callinvoker (= 0.68.6)
- React-Core (= 0.68.6)
- React-cxxreact (= 0.68.6)
- React-jsi (= 0.68.6)
- React-logger (= 0.68.6)
- React-perflogger (= 0.68.6)
- React-bridging (= 0.69.10)
- React-callinvoker (= 0.69.10)
- React-Core (= 0.69.10)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-logger (= 0.69.10)
- React-perflogger (= 0.69.10)
- RNCalendarEvents (2.2.0):
- React
- RNCAsyncStorage (1.17.3):
@@ -475,7 +476,7 @@ PODS:
- RNGoogleSignin (9.0.2):
- GoogleSignIn (~> 6.2)
- React-Core
- RNScreens (3.13.1):
- RNScreens (3.22.0):
- React-Core
- React-RCTImage
- RNSound (0.11.1):
@@ -507,10 +508,10 @@ DEPENDENCIES:
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
- React-bridging (from `../node_modules/react-native/ReactCommon`)
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Codegen (from `build/generated/ios`)
- React-Core (from `../node_modules/react-native/`)
- React-Core/DevSupport (from `../node_modules/react-native/`)
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
@@ -524,7 +525,6 @@ DEPENDENCIES:
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
- react-native-performance (from `../node_modules/react-native-performance/ios`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
@@ -606,6 +606,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/TypeSafety"
React:
:path: "../node_modules/react-native/"
React-bridging:
:path: "../node_modules/react-native/ReactCommon"
React-callinvoker:
:path: "../node_modules/react-native/ReactCommon/callinvoker"
React-Codegen:
@@ -636,8 +638,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-orientation-locker"
react-native-pager-view:
:path: "../node_modules/react-native-pager-view"
react-native-performance:
:path: "../node_modules/react-native-performance/ios"
react-native-safe-area-context:
:path: "../node_modules/react-native-safe-area-context"
react-native-slider:
@@ -705,9 +705,9 @@ SPEC CHECKSUMS:
AppAuth: e48b432bb4ba88b10cb2bcc50d7f3af21e78b9c2
boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: 74b042924fe14da854ac4e87cefc417f583b22b1
FBReactNativeSpec: cc0037b9914b9b1d92a15f179bc3e2e2c7cc0c6f
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: a8af91c2b5a0029d12ff6b32e428863d63c48991
FBReactNativeSpec: ec5e878f6452a3de5430e0b2324a4d4ae6ac63f6
Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
FirebaseAnalytics: 7761cbadb00a717d8d0939363eb46041526474fa
FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1
@@ -716,59 +716,59 @@ SPEC CHECKSUMS:
FirebaseDynamicLinks: 1dc816ef789c5adac6fede0b46d11478175c70e4
FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
Giphy: b6d5087521d251bb8c99cdc0eb07bbdf86d142d5
giphy-react-native-sdk: 7abccf2b52123a0f30ce99da895ab6288023680c
glog: 476ee3e89abb49e07f822b48323c51c57124b572
Giphy: 6b5f6986c8df4f71e01a8ef86595f426b3439fb5
giphy-react-native-sdk: fcda9639f8ca2cc47e0517b6ef11c19359db5f5a
glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
GoogleAppMeasurement: 4c19f031220c72464d460c9daa1fb5d1acce958e
GoogleDataTransport: 8378d1fa8ac49753ea6ce70d65a7cb70ce5f66e6
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2
JitsiWebRTC: 9619c1f71cc16eeca76df68aa2d213c6d63274a8
JitsiWebRTC: 80f62908fcf2a1160e0d14b584323fb6e6be630b
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
ObjectiveDropboxOfficial: fe206ce8c0bc49976c249d472db7fdbc53ebbd53
PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef
PromisesSwift: cf9eb58666a43bbe007302226e510b16c1e10959
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
RCTRequired: 92cbd71369a2de6add25fd2403ac39838f1b694f
RCTTypeSafety: 494e8af41d7410ed0b877210859ee3984f37e6b4
React: 59989499c0e8926a90d34a9ae0bdb2d1b5b53406
React-callinvoker: 8187db1c71cf2c1c66e8f7328a0cf77a2b255d94
React-Codegen: e806dc2f10ddae645d855cb58acf73ce41eb8ea5
React-Core: fc7339b493e368ae079850a4721bdf716cf3dba2
React-CoreModules: 2f54f6bbf2764044379332089fcbdaf79197021e
React-cxxreact: ee119270006794976e1ab271f0111a5a88b16bcf
React-jsi: ec691b2a475d13b1fd39f697145a526eeeb6661c
React-jsiexecutor: b4ce4afc5dd9c8fdd2ac59049ccf420f288ecef7
React-jsinspector: e396d5e56af08fce39f50571726b68a40f1e302d
React-logger: cec52b3f8fb0be0d47b2cb75dec69de60f2de3b6
RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
RCTRequired: 3581db0757e7ff9be10718a56b3d79b6a6bd3bdf
RCTTypeSafety: ce13e630c48340401ebfb28710959913f74b8b36
React: cca8f2b7cce018f79847ca79847fa367b206e8a1
React-bridging: b893643f09d3964afba6c347e00dd86cf10691e5
React-callinvoker: 9ac7cba30428eddf7a06d1253f8e7561b5c97334
React-Codegen: 65ff9fbddf8a17a6d4f495f71d365288f934a93a
React-Core: 550b694774bc778b5c7bf7608fc12a484e01ec05
React-CoreModules: c332d5b416cb3ccf972e7af79d496498a700e073
React-cxxreact: c5c4106bfd2d0cee80b848e33b7ff4e35a721b16
React-jsi: 6ff3fb9b9764a499c959e0096c0d384fa2b4beef
React-jsiexecutor: 388f1c99404c848141d7ea162f61233d04829ede
React-jsinspector: a4463b3411b8b9b37153255ef694a84c77ba3c7f
React-logger: 2a0497622cbabc47fb769d97620952df14c1f814
react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe
react-native-get-random-values: 30b3f74ca34e30e2e480de48e4add2706a40ac8f
react-native-keep-awake: afad8a51dfef9fe9655a6344771be32c8596d774
react-native-netinfo: 27f287f2d191693f3b9d01a4273137fcf91c3b5d
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
react-native-pager-view: 3ee7d4c7697fb3ef788346e834a60cca97ed8540
react-native-performance: f4b6604a9d5a8a7407e34a82fab6c641d9a3ec12
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
react-native-safe-area-context: 68b07eabfb0d14547d36f6929c0e98d818064f02
react-native-slider: 6e9b86e76cce4b9e35b3403193a6432ed07e0c81
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
react-native-video: bb6f12a7198db53b261fefb5d609dc77417acc8b
react-native-webrtc: a9d4d8ef61adb634e006ffd956c494ad8318d95c
react-native-webrtc: 4d1669c2ed29767fe70b0169428b4466589ecf8b
react-native-webview: ea4899a1056c782afa96dd082179a66cbebf5504
React-perflogger: 46620fc6d1c3157b60ed28434e08f7fd7f3f3353
React-RCTActionSheet: b1f7e72a0ba760ec684df335c61f730b5179f5ff
React-RCTAnimation: d73b62d42867ab608dfb10e100d8b91106275b18
React-RCTBlob: b5f59693721d50967c35598158e6ca01b474c7de
React-RCTImage: 37cf34d0c2fbef2e0278d42a7c5e8ea06a9fed6b
React-RCTLinking: a11dced20019cf1c2ec7fd120f18b08f2851f79e
React-RCTNetwork: ba097188e5eac42e070029e7cedd9b978940833a
React-RCTSettings: 147073708a1c1bde521cf3af045a675682772726
React-RCTText: 23f76ebfb2717d181476432e5ecf1c6c4a104c5e
React-RCTVibration: be5f18ffc644f96f904e0e673ab639ca5d673ee8
React-runtimeexecutor: d5498cfb7059bf8397b6416db4777843f3f4c1e7
ReactCommon: 1974dab5108c79b40199f12a4833d2499b9f6303
React-perflogger: bc57c4a953c1ec913b0d984cf4f2b9842a12bde0
React-RCTActionSheet: 3efa3546119a1050f6c34a461b386dd9e36eaf0b
React-RCTAnimation: e58fb9f1adf7b38af329881ea2740f43ffeea854
React-RCTBlob: d2238645553c3ec787324268c0676148d86e6cc4
React-RCTImage: e6d7c9ab978cae99364fcc96b9238fc7740a13da
React-RCTLinking: 329e88ce217dad464ef34b5d0c40b3ceaac6c9ec
React-RCTNetwork: c8967f2382aac31761ddb750fee53fa34cf7a4ee
React-RCTSettings: 8a825b4b5ea58f6713a7c97eea6cc82e9895188b
React-RCTText: ffcaac5c66bc065f2ccf79b6fe34585adb9e589b
React-RCTVibration: 0039c986626b78242401931bb23c803935fae9d1
React-runtimeexecutor: 5ebf1ddaa706bf2986123f22d2cad905443c2c5f
ReactCommon: 65754b8932ea80272714988268bbfb9f303264a5
RNCalendarEvents: 7e65eb4a94f53c1744d1e275f7fafcfaa619f7a3
RNCAsyncStorage: 005c0e2f09575360f142d0d1f1f15e4ec575b1af
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
@@ -776,12 +776,12 @@ SPEC CHECKSUMS:
RNDeviceInfo: 0400a6d0c94186d1120c3cbd97b23abc022187a9
RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
RNGoogleSignin: 22e468a9474dbcb8618d8847205ad4f0b2575d13
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
RNScreens: 68fd1060f57dd1023880bf4c05d74784b5392789
RNSound: 27e8268bdb0a1f191f219a33267f7e0445e8d62f
RNSVG: f3b60aeeaa81960e2e0536c3a9eef50b667ef3a9
RNWatch: dae6c858a2051dbdcfb00b9a86cf4d90400263b4
Yoga: 7929b92b1828675c1bebeb114dae8cb8fa7ef6a3
Yoga: d24d6184b6b85f742536bd93bd07d69d7b9bb4c1
PODFILE CHECKSUM: d9116cb59cd7e921956e45de7cbbd75bef3862c1
PODFILE CHECKSUM: e3579df5272b8b697c9fdc0e55aa0845b189c4dd
COCOAPODS: 1.11.3

View File

@@ -439,7 +439,7 @@
};
};
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "app" */;
compatibilityVersion = "Xcode 3.2";
compatibilityVersion = "Xcode 12.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@@ -1025,9 +1025,10 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
);
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -1078,8 +1079,9 @@
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
);
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = NO;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
TARGETED_DEVICE_FAMILY = "1,2";

View File

@@ -98,7 +98,6 @@ platform :ios do
demo_account_required: false,
distribute_external: true,
groups: ENV["JITSI_BETA_TESTING_GROUPS"],
reject_build_waiting_for_review: true,
uses_non_exempt_encryption: false
)

View File

@@ -472,7 +472,7 @@
};
};
buildConfigurationList = 0BD906DF1EC0C00300C8C18E /* Build configuration list for PBXProject "sdk" */;
compatibilityVersion = "Xcode 3.2";
compatibilityVersion = "Xcode 12.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
@@ -526,7 +526,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\nexport NODE_ARGS=\"--max_old_space_size=4096\"\n../../node_modules/react-native/scripts/react-native-xcode.sh\n";
shellScript = "WITH_ENVIRONMENT=\"../../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
};
26796D8589142D80C8AFDA51 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
@@ -551,17 +551,12 @@
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK-resources.sh",
"${PODS_ROOT}/Amplitude/Sources/Resources/ComodoRsaDomainValidationCA.der",
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleSignIn/GoogleSignIn.bundle",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoRsaDomainValidationCA.der",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -641,15 +636,12 @@
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources.sh",
"${PODS_ROOT}/Amplitude/Sources/Resources/ComodoRsaDomainValidationCA.der",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoRsaDomainValidationCA.der",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -781,9 +773,10 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
@@ -837,8 +830,9 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
MTL_ENABLE_DEBUG_INFO = NO;
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
TARGETED_DEVICE_FAMILY = "1,2";

View File

@@ -197,7 +197,7 @@ static CXProviderConfiguration *_providerConfiguration = nil;
+ (BOOL)hasActiveCallForUUID:(nonnull NSString *)callUUID {
CXCall *activeCallForUUID = [[self.callController calls] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(CXCall *evaluatedObject, NSDictionary<NSString *,id> *bindings) {
return evaluatedObject.UUID.UUIDString == callUUID;
return [evaluatedObject.UUID.UUIDString isEqualToString:callUUID];
}]].firstObject;
if (!activeCallForUUID) {

View File

@@ -1,5 +1,8 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Konferenzlink: {{url}}"
},
"add": "Einladen",
"addContacts": "Laden Sie Ihre Kontakte ein",
"contacts": "Kontakte",
@@ -39,6 +42,18 @@
"audioOnly": {
"audioOnly": "Geringe Bandbreite"
},
"bandwidthSettings": {
"assumedBandwidthBps": "z.B. 10000000 für 10 Mbps",
"assumedBandwidthBpsWarning": "Höhere Werte können zu Netzwerk-Problemen führen.",
"customValue": "spezifischer Wert",
"customValueEffect": "setzt den Wert in bps",
"leaveEmpty": "leer lassen",
"leaveEmptyEffect": "aktiviert die automatische Abschätzung",
"possibleValues": "Mögliche Werte",
"setAssumedBandwidthBps": "Angenommene Bandbreite (bps)",
"title": "Einstellungen Bandbreite",
"zeroEffect": "schaltet Video aus"
},
"breakoutRooms": {
"actions": {
"add": "Breakout-Raum hinzufügen",
@@ -156,6 +171,7 @@
"localport_plural": "Lokale Ports:",
"maxEnabledResolution": "max. senden",
"more": "Mehr anzeigen",
"no": "Nein",
"packetloss": "Paketverlust:",
"participant_id": "Personen-ID:",
"quality": {
@@ -174,7 +190,8 @@
"status": "Verbindung:",
"transport": "Protokoll:",
"transport_plural": "Protokolle:",
"video_ssrc": "Video-SSRC:"
"video_ssrc": "Video-SSRC:",
"yes": "Ja"
},
"dateUtils": {
"earlier": "Früher",
@@ -240,6 +257,8 @@
"WaitingForHostTitle": "Warten auf den Beginn der Konferenz …",
"Yes": "Ja",
"accessibilityLabel": {
"Cancel": "Abbrechen (Popup schließen)",
"Ok": "OK (Speichern und Popup schließen)",
"close": "Popup schließen",
"liveStreaming": "Livestream",
"sharingTabs": "Optionen zum Teilen"
@@ -445,6 +464,9 @@
"title": "Diese Konferenz einbetten"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "Ihre Auswahl: {{rating}}"
},
"average": "Durchschnittlich",
"bad": "Schlecht",
"detailsLabel": "Sagen Sie uns mehr dazu.",
@@ -673,6 +695,7 @@
"connectedTwoMembers": "{{first}} und {{second}} nehmen am Meeting teil",
"dataChannelClosed": "Schlechte Videoqualität",
"dataChannelClosedDescription": "Die Steuerungsverbindung (Bridge Channel) wurde unterbrochen, daher ist die Videoqulität auf die schlechteste Stufe limitiert.",
"disabledIframe": "Die Einbettung ist nur für Demo-Zwecke vorgesehen. Diese Konferenz wird in {{timeout}} Minuten beendet.",
"disconnected": "getrennt",
"displayNotifications": "Benachrichtigungen anzeigen für",
"dontRemindMe": "Nicht erinnern",
@@ -867,9 +890,11 @@
"lookGood": "Ihr Mikrofon scheint zu funktionieren.",
"or": "oder",
"premeeting": "Vorschau",
"proceedAnyway": "Trotzdem fortsetzen",
"screenSharingError": "Fehler bei Bildschirmfreigabe:",
"showScreen": "Konferenzvorschau aktivieren",
"startWithPhone": "Mit Telefonaudio starten",
"unsafeRoomConsent": "Ich verstehe das Risiko und möchte der Konferenz beitreten",
"videoOnlyError": "Videofehler:",
"videoTrackError": "Videotrack konnte nicht erstellt werden.",
"viewAllNumbers": "alle Nummern anzeigen"
@@ -971,8 +996,14 @@
"security": {
"about": "Sie können Ihre Konferenz mit einem Passwort sichern. Teilnehmer müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
"aboutReadOnly": "Mit Moderationsrechten kann die Konferenz mit einem Passwort gesichert werden. Personen müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
"insecureRoomNameWarning": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten",
"title": "Sicherheitsoptionen"
"insecureRoomNameWarningNative": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten. {{recommendAction}} Lernen Sie mehr über die Absicherung Ihrer Konferenz ",
"insecureRoomNameWarningWeb": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten {{recommendAction}} Lernen Sie <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">hier</a> mehr über die Absicherung Ihrer Konferenz.",
"title": "Sicherheitsoptionen",
"unsafeRoomActions": {
"meeting": "Erwägen Sie die Absicherung Ihrer Konferenz über den Sicherheits-Button.",
"prejoin": "Erwägen Sie einen einzigartigeren Raumnamen zu wählen.",
"welcome": "Erwägen Sie einen einzigartigeren Raumnamen zu wählen oder wählen Sie einen der Vorschläge."
}
},
"settings": {
"audio": "Audio",
@@ -1042,6 +1073,7 @@
"links": "Links",
"privacy": "Datenschutz",
"profileSection": "Profil",
"sdkVersion": "SDK-Version",
"serverURL": "Server-URL",
"showAdvanced": "Erweiterte Einstellungen anzeigen",
"startCarModeInLowBandwidthMode": "Automodus mit Datensparmodus starten",
@@ -1140,6 +1172,7 @@
"muteEveryoneElse": "Alle anderen stummschalten",
"muteEveryoneElsesVideoStream": "Alle anderen Kameras ausschalten",
"muteEveryonesVideoStream": "Alle Kameras ausschalten",
"muteGUMPending": "Verbinde Ihr Mikrofon",
"noiseSuppression": "Rauschunterdrückung",
"openChat": "Chat öffnen",
"participants": "Anwesende",
@@ -1147,6 +1180,7 @@
"privateMessage": "Private Nachricht senden",
"profile": "Profil bearbeiten",
"raiseHand": "Hand heben",
"reactions": "Interaktionen",
"reactionsMenu": "Interaktionsmenü öffnen / schließen",
"recording": "Aufzeichnung ein-/ausschalten",
"remoteMute": "Personen stummschalten",
@@ -1172,6 +1206,7 @@
"unmute": "Stummschaltung aufheben",
"videoblur": "Unscharfer Hintergrund ein-/ausschalten",
"videomute": "„Video stummschalten“ ein-/ausschalten",
"videomuteGUMPending": "Verbinde Ihre Kamera",
"videounmute": "Kamera einschalten"
},
"addPeople": "Personen zur Konferenz hinzufügen",
@@ -1222,6 +1257,7 @@
"mute": "Stummschalten",
"muteEveryone": "Alle stummschalten",
"muteEveryonesVideo": "Alle Kameras ausschalten",
"muteGUMPending": "Verbinde Ihre Kamera",
"noAudioSignalDesc": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stumm geschaltet haben, sollten Sie einen Wechsel des Geräts in Erwägung ziehen.",
"noAudioSignalDescSuggestion": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stummgeschaltet haben, sollten Sie einen Wechsel auf das vorgeschlagene Gerät in Erwägung ziehen.",
"noAudioSignalDialInDesc": "Sie können sich auch über die Einwahlnummer einwählen:",
@@ -1244,6 +1280,7 @@
"reactionLike": "Daumen hoch senden",
"reactionSilence": "Stille senden",
"reactionSurprised": "Überrascht senden",
"reactions": "Interaktionen",
"security": "Sicherheitsoptionen",
"selectBackground": "Hintergrund auswählen",
"shareRoom": "Person einladen",
@@ -1266,6 +1303,7 @@
"unmute": "Stummschaltung aufheben",
"videoSettings": "Kameraeinstellungen",
"videomute": "Kamera stoppen",
"videomuteGUMPending": "Verbinde Ihre Kamera",
"videounmute": "Kamera einschalten"
},
"transcribing": {
@@ -1354,6 +1392,10 @@
"videomute": "Person hat die Kamera angehalten"
},
"virtualBackground": {
"accessibilityLabel": {
"currentBackground": "Aktueller Hintergrund: {{background}}",
"selectBackground": "Hintergrund auswählen"
},
"addBackground": "Hintergrund hinzufügen",
"apply": "Anwenden",
"backgroundEffectError": "Hintergrund konnte nicht aktiviert werden.",
@@ -1377,7 +1419,14 @@
"webAssemblyWarning": "WebAssembly wird nicht unterstützt",
"webAssemblyWarningDescription": "WebAssembly ist deaktiviert oder wird in diesem Browser nicht unterstützt"
},
"visitorsLabel": "Anzahl Gäste: {{count}}",
"visitors": {
"chatIndicator": "(Gast)",
"labelTooltip": "Anzahl Gäste: {{count}}",
"notification": {
"description": "Bitte melden Sie sich um teilzunehmen",
"title": "Sie sind Gast in der Konferenz"
}
},
"volumeSlider": "Lautstärkeregler",
"welcomepage": {
"accessibilityLabel": {

View File

@@ -11,7 +11,6 @@
"defaultEmail": "Dirección de correo por defecto",
"disabled": "No puede invitar a otras personas.",
"failedToAdd": "Error al agregar participantes",
"footerText": "La marcación está desactivada.",
"googleEmail": "Correo electrónico de Google",
"inviteMoreHeader": "Usted se encuentra solo en la reunión",
"inviteMoreMailSubject": "Unirse a la reunión {{appName}}",
@@ -31,6 +30,7 @@
},
"audioDevices": {
"bluetooth": "Bluetooth",
"car": "Audio de automóvil",
"headphones": "Auriculares",
"none": "No hay dispositivos de audio disponibles",
"phone": "Teléfono",
@@ -39,6 +39,37 @@
"audioOnly": {
"audioOnly": "Solo sonido y pantalla compartida"
},
"bandwidthSettings": {
"assumedBandwidthBps": "por ejemplo 10000000 para 10 Mbps",
"assumedBandwidthBpsWarning": "Valores más altos podrían causar problemas de red.",
"customValue": "valor personalizado",
"customValueEffect": "para establecer el valor real de bps",
"leaveEmpty": "dejar vacío",
"leaveEmptyEffect": "para permitir que se realicen estimaciones",
"possibleValues": "Valores posibles",
"setAssumedBandwidthBps": "Ancho de banda asumido (bps)",
"title": "Ajustes de ancho de banda",
"zeroEffect": "para deshabilitar el video"
},
"breakoutRooms": {
"actions": {
"add": "Agregar sala para grupos pequeños",
"autoAssign": "Autoasignar a sala para grupos pequeños",
"close": "Cerrar",
"join": "Unirse",
"leaveBreakoutRoom": "Abandonar sala para grupos pequeños",
"more": "Más",
"remove": "Quitar",
"sendToBreakoutRoom": "Enviar participante a:"
},
"defaultName": "Sala para grupos pequeños #{{index}}",
"mainRoom": "Sala principal",
"notifications": {
"joined": "Uniéndose a la sala para grupos pequeños \"{{name}}\"",
"joinedMainRoom": "Uniéndose a la sala principal",
"joinedTitle": "Salas para grupos pequeños"
}
},
"calendarSync": {
"addMeetingURL": "Agregar un vínculo a la reunión",
"confirmAddLink": "¿Quiere añadir un enlace de Jitsi a este evento?",
@@ -57,15 +88,27 @@
"refresh": "Actualizar calendario",
"today": "Hoy"
},
"carmode": {
"actions": {
"selectSoundDevice": "Elija un dispositivo de sonido"
},
"labels": {
"buttonLabel": "Modo automóvil",
"title": "Modo automóvil",
"videoStopped": "Su video se ha detenido"
}
},
"chat": {
"enter": "Entrar en la sala",
"error": "Error: su mensaje no se envío. Motivo: {{error}}",
"fieldPlaceHolder": "Escriba su mensaje aquí",
"lobbyChatMessageTo": "Mensaje de chat de lobby a {{recipient}}",
"message": "Mensaje",
"messageAccessibleTitle": "{{user}} dice:",
"messageAccessibleTitleMe": "yo digo:",
"messageTo": "Mensaje privado para {{recipient}}",
"messagebox": "Escriba un mensaje",
"newMessages": "Mensajes nuevos",
"nickname": {
"popover": "Selecciona un apodo",
"title": "Introduce un apodo para usar el chat",
@@ -85,6 +128,7 @@
},
"chromeExtensionBanner": {
"buttonText": "Instalar extensión de Chrome",
"buttonTextEdge": "Instalar extensión de Edge",
"close": "Cerrar",
"dontShowAgain": "No mostrar nuevamente",
"installExtensionText": "Instalar la extensión para Google Calendar y la integración con Office 365"
@@ -115,6 +159,7 @@
"bridgeCount": "Contador del servidor: ",
"codecs": "Codecs (A/V):",
"connectedTo": "Conectado a:",
"e2eeVerified": "",
"framerate": "Fotogramas por segundo:",
"less": "Mostrar menos",
"localaddress": "Dirección local:",
@@ -123,6 +168,7 @@
"localport_plural": "Puertos locales:",
"maxEnabledResolution": "enviar max",
"more": "Mostrar más",
"no": "no",
"packetloss": "Pérdida de paquetes:",
"participant_id": "ID participante:",
"quality": {
@@ -141,7 +187,8 @@
"status": "Calidad:",
"transport": "Transporte:",
"transport_plural": "Transportes:",
"video_ssrc": "Video SSRC:"
"video_ssrc": "Video SSRC:",
"yes": "sí"
},
"dateUtils": {
"earlier": "Anterior",
@@ -150,15 +197,24 @@
},
"deepLinking": {
"appNotInstalled": "Necesitas la aplicación {{app}} para unirte a esta reunión en el teléfono.",
"description": "¿No pasó nada? Hemos intentado iniciar la reunión en la aplicación de escritorio {{app}}. Intenta de nuevo o inicia en la aplicación web {{app}}.",
"description": "¿No pasó nada? Intentamos iniciar la reunión en la aplicación de escritorio {{app}}. Intenta de nuevo o inicia en la aplicación web {{app}}.",
"descriptionNew": "¿No pasó nada? Intentamos iniciar la reunión en la aplicación de escritorio {{app}}. <br /><br /> Puedes volver a intentarlo o iniciar en la aplicación web.",
"descriptionWithoutWeb": "¿No pasó nada? Intentamos iniciar su reunión en la aplicación de escritorio {{app}}.",
"downloadApp": "Descargar la app",
"downloadMobileApp": "",
"ifDoNotHaveApp": "Si aún no tienes la app:",
"ifHaveApp": "Si ya tienes la app:",
"joinInApp": "Unirse a la reunion usando la app",
"joinInAppNew": "Unirse en la app",
"joinInBrowser": "Unirse en el navegador",
"launchMeetingLabel": "¿Cómo quieres unirte a la reunión?",
"launchWebButton": "Iniciar en el navegador",
"noMobileApp": "¿No tienes la aplicación?",
"termsAndConditions": "Al continuar aceptas nuestros <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>términos y condiciones.</a>",
"title": "Iniciando la reunión en {{app}}…",
"tryAgainButton": "Intentar de nuevo en el escritorio"
"titleNew": "Iniciando la reunión.",
"tryAgainButton": "Intentar de nuevo en el escritorio",
"unsupportedBrowser": "Parece que estás usando un navegador para el que no tenemos soporte."
},
"defaultLink": "ej. {{url}}",
"defaultNickname": "ej. Juan Pérez",
@@ -169,11 +225,20 @@
"microphonePermission": "Error al obtener permiso del micrófono"
},
"deviceSelection": {
"hid": {
"callControl": "Control de llamadas",
"connectedDevices": "Dispositivos conectados:",
"deleteDevice": "Eliminar dispositivo",
"pairDevice": "Emparejar dispositivo"
},
"noPermission": "Permiso no concedido",
"previewUnavailable": "Vista previa no disponible",
"selectADevice": "Seleccionar un dispositivo",
"testAudio": "Reproducir un sonido de prueba"
},
"dialIn": {
"screenTitle": ""
},
"dialOut": {
"statusMessage": "está {{status}}"
},
@@ -189,9 +254,13 @@
"WaitingForHostTitle": "Esperando al anfitrión...",
"Yes": "Sí",
"accessibilityLabel": {
"liveStreaming": "Transmisión en vivo"
"close": "Cerrar diálogo",
"liveStreaming": "Transmisión en vivo",
"sharingTabs": "Opciones para compartir"
},
"add": "Agregar",
"addMeetingNote": "Agrega una nota acerca de esta reunión",
"addOptionalNote": "Agrega una nota (opcional):",
"allow": "Permitir",
"alreadySharedVideoMsg": "Otro participante ya está compartiendo un vídeo. Esta conferencia sólo permite compartir un vídeo a la vez.",
"alreadySharedVideoTitle": "Solo se permite un vídeo compartido a la vez",
@@ -233,6 +302,7 @@
"gracefulShutdown": "Nuestro servicio se encuentra en mantenimiento. Por favor, intente más tarde.",
"grantModeratorDialog": "¿Estás seguro de que quieres convertir a este participante en moderador?",
"grantModeratorTitle": "Convertir en moderador",
"hide": "Esconder",
"hideShareAudioHelper": "No volver a mostrar este diálogo",
"incorrectPassword": "Nombre de usuario o contraseña incorrecta",
"incorrectRoomLockPassword": "Contraseña incorrecta",
@@ -243,9 +313,10 @@
"kickParticipantDialog": "¿Seguro que quiere expulsar a este participante?",
"kickParticipantTitle": "¿Expulsar a este participante?",
"kickTitle": "¡Ay! {{participantDisplayName}} te expulsó de la reunión",
"linkMeeting": "",
"linkMeetingTitle": "",
"liveStreaming": "Transmisión en vivo",
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "No es posible mientras la grabación este activa",
"liveStreamingDisabledTooltip": "Las trasmisiones están deshabilitadas.",
"localUserControls": "Controles de usuario locales",
"lockMessage": "No se pudo bloquear la conferencia.",
"lockRoom": "Agregar $t(lockRoomPasswordUppercase) a la reunión",
@@ -279,11 +350,11 @@
"muteEveryonesVideoTitle": "¿Detener el vídeo de todos?",
"muteParticipantBody": "No podrás quitarles el modo en silencio, pero ellos pueden quitárselo en cualquier momento.",
"muteParticipantButton": "Silenciar",
"muteParticipantDialog": "¿Seguro que quieres silenciar a este participante? No podrás revertir esta acción, pero el participante podrá hacerlo en cualquier momento",
"muteParticipantTitle": "¿Silenciar a este participante?",
"muteParticipantsVideoBody": "No podrás volver a encender la cámara, pero ellos pueden volver a encenderla en cualquier momento.",
"muteParticipantsVideoBodyModerationOn": "",
"muteParticipantsVideoButton": "Detener video",
"muteParticipantsVideoDialog": "¿Estás seguro de que quieres apagar la cámara de este participante? No podrás volver a encender la cámara, pero ellos pueden volver a encenderla en cualquier momento.",
"muteParticipantsVideoDialogModerationOn": "",
"muteParticipantsVideoTitle": "¿Desactivar la cámara de este participante?",
"noDropboxToken": "No hay un token válido de Dropbox",
"password": "Contraseña",
@@ -297,9 +368,9 @@
"popupError": "Su navegador está bloqueando las ventanas emergentes de este sitio. Habilite las ventanas emergentes en la configuración de seguridad de su navegador y vuelva a intentarlo.",
"popupErrorTitle": "Ventana emergente bloqueada",
"readMore": "más",
"recentlyUsedObjects": "Tus objetos usados recientemente",
"recording": "Grabando",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "No es posible mientras la transmisión en vivo este activa",
"recordingDisabledTooltip": "Inicio de grabación desactivado.",
"rejoinNow": "Reunirse ahora",
"remoteControlAllowedMessage": "¡{{user}} ha aceptado tu solicitud de control remoto!",
"remoteControlDeniedMessage": "¡{{user}} ha rechazado tu solicitud de control remoto!",
@@ -319,6 +390,12 @@
"screenSharingFailed": "¡Ups! ¡Algo salió mal, no se pudo iniciar la compartición de su pantalla!",
"screenSharingFailedTitle": "¡Fallo al compartir su pantalla!",
"screenSharingPermissionDeniedError": "¡Uy! Algo salió mal con tus permisos de extensión para compartir pantalla. Vuelve a cargar la página e intenta de nuevo.",
"searchInSalesforce": "Buscar en Salesforce",
"searchResults": "Resultados de búsqueda({{count}}",
"searchResultsDetailsError": "",
"searchResultsError": "Hubo un error recuperando los datos.",
"searchResultsNotFound": "No se encontraron resultados.",
"searchResultsTryAgain": "Vuelve a intentar usando palabras clave alternativas",
"sendPrivateMessage": "Acabas de recibir un mensaje privado. ¿Deseas responder en privado o a todos?",
"sendPrivateMessageCancel": "Enviar al grupo",
"sendPrivateMessageOk": "Enviar en privado",
@@ -341,7 +418,10 @@
"shareVideoTitle": "Compartir un vídeo",
"shareYourScreen": "Compartir pantalla",
"shareYourScreenDisabled": "Se desactivó la opción para compartir pantalla.",
"sharedVideoDialogError": "Error: URL inválido",
"sharedVideoLinkPlaceholder": "Enlace de YouTube o enlace de vídeo directo",
"show": "Mostrar",
"start": "Iniciar",
"startLiveStreaming": "Iniciar transmisión en vivo",
"startRecording": "Iniciar grabación",
"startRemoteControlErrorMessage": "Se produjo un error al intentar iniciar la sesión de control remoto.",
@@ -359,6 +439,10 @@
"user": "Usuario",
"userIdentifier": "Identificador de usuario",
"userPassword": "contraseña del usuario",
"verifyParticipantConfirm": "",
"verifyParticipantDismiss": "",
"verifyParticipantQuestion": "",
"verifyParticipantTitle": "Verificación de usuario",
"videoLink": "Enlace de vídeo",
"viewUpgradeOptions": "Ver opciones de mejora",
"viewUpgradeOptionsContent": "Para obtener acceso ilimitado a las funciones premium, como la grabación, las transcripciones, el streaming RTMP y otras, tendrás que actualizar tu plan.",
@@ -384,8 +468,14 @@
"veryBad": "Muy mala",
"veryGood": "Muy buena"
},
"helpView": {
"title": "Centro de ayuda"
"filmstrip": {
"accessibilityLabel": {
"heading": "Miniaturas de video"
}
},
"giphy": {
"noResults": "No se encontraron resultados :(",
"search": "Busca en GIPHY"
},
"incomingCall": {
"answer": "Contestar",
@@ -427,9 +517,11 @@
"noRoom": "No se especificó la sala a marcar.",
"numbers": "Números para entrar por llamada telefónica:",
"password": "$t(lockRoomPasswordUppercase):",
"reachedLimit": "Alcanzaste el límite de tu plan.",
"sip": "Dirección SIP",
"title": "Compartir",
"tooltip": "Compartir el enlace y acceso telefónico para esta reunión"
"tooltip": "Compartir el enlace y acceso telefónico para esta reunión",
"upgradeOptions": "Por favor revisa las opciones de mejora en"
},
"inlineDialogFailure": {
"msg": "Tuvimos un pequeño tropiezo.",
@@ -450,6 +542,7 @@
"focusLocal": "Ver tu cámara",
"focusRemote": "Ver la cámara de otras personas",
"fullScreen": "Entrar o salir de pantalla completa",
"giphyMenu": "Alternar menú GIPHY",
"keyboardShortcuts": "Atajos de teclado",
"localRecording": "Mostrar u ocultar controles de grabación local",
"mute": "Activar o silenciar el micrófono",
@@ -463,6 +556,10 @@
"toggleShortcuts": "Mostrar u ocultar atajos del teclado",
"videoMute": "Encender o apagar la cámara"
},
"largeVideo": {
"screenIsShared": "Estás compartiendo tu pantalla",
"showMeWhatImSharing": "Muéstrame qué estoy compartiendo"
},
"liveStreaming": {
"busy": "Nuestros servidores andan un poco ocupados. Vuelve a intentarlo en unos minutos.",
"busyTitle": "Todos los transmisores están ocupados",
@@ -479,6 +576,7 @@
"failedToStart": "La transmisión en vivo no se pudo iniciar",
"getStreamKeyManually": "No pudimos encontrar tu clave de transmisión. Por favor, obtenla de la página de YouTube y pégala.",
"googlePrivacyPolicy": "Política de Privacidad de Google",
"inProgress": "Grabación o transmisión en vivo en curso",
"invalidStreamKey": "Es posible que la clave de transmisión sea incorrecta, o no es de YouTube.",
"limitNotificationDescriptionNative": "Su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en {{app}}.",
"limitNotificationDescriptionWeb": "Debido a la alta demanda su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
@@ -488,6 +586,7 @@
"onBy": "{{name}} inició la transmisión en vivo",
"pending": "Iniciando transmisión en vivo…",
"serviceName": "Servicio de transmisión en vivo",
"sessionAlreadyActive": "Esta sesión ya está siendo grabada o transmitida en vivo.",
"signIn": "Iniciar sesión con Google",
"signInCTA": "Para transmitir a YouTube, inicia sesión o introduce la clave de transmisión. Para transmitir a otro lugar, introduce el URL (que empieza en rtmp), seguido de la clave de transmisión. Debe haber una diagonal (/) entre ambos.",
"signOut": "Cerrar sesión",
@@ -501,8 +600,8 @@
"lobby": {
"admit": "Admitir",
"admitAll": "Admitir todo",
"allow": "permitir",
"backToKnockModeButton": "No hay contraseña, pide permiso para entrar.",
"chat": "Chat",
"dialogTitle": "Sala de espera",
"disableDialogContent": "Sala de espera activada. Así no entrarán intrusos. ¿Quieres desactivarla?",
"disableDialogSubmit": "Desactivar",
@@ -515,6 +614,7 @@
"errorMissingPassword": "Por favor, introduzca la contraseña de la reunión",
"invalidPassword": "Contraseña inválida",
"joinRejectedMessage": "Tu solicitud para entrar ha sido rechazada por un moderador.",
"joinRejectedTitle": "Solicitud para entrar rechazada.",
"joinTitle": "Entrar a la reunión",
"joinWithPasswordMessage": "Tratando de entrar con contraseña, por favor espera...",
"joiningMessage": "Podrás entrar tan pronto te acepten tu solicitud.",
@@ -523,6 +623,8 @@
"knockButton": "Pedir entrar",
"knockTitle": "Alguien quiere entrar a la reunión",
"knockingParticipantList": "Participantes que quieren entrar",
"lobbyChatStartedNotification": "{{moderator}} inició un chat de lobby con {{attendee}}",
"lobbyChatStartedTitle": "{{moderator}} inició un chat de lobby contigo.",
"nameField": "Introduce tu nombre",
"notificationLobbyAccessDenied": "{{originParticipantName}} no dejó entrar a {{targetParticipantName}}",
"notificationLobbyAccessGranted": "{{originParticipantName}} permitió entrar a {{targetParticipantName}}",
@@ -560,6 +662,7 @@
"no": "No",
"participant": "Participante",
"participantStats": "Estadística de participantes",
"selectTabTitle": "🎥 Por favor seleccione esta pestaña para grabar",
"sessionToken": "Token de sesión",
"start": "Iniciar grabación",
"stop": "Detener grabación",
@@ -576,18 +679,39 @@
"OldElectronAPPTitle": "¡Aplicación obsoleta e insegura!",
"allowAction": "Permitir",
"allowedUnmute": "Puedes anular el silencio del micrófono, iniciar la cámara o compartir la pantalla.",
"audioUnmuteBlockedDescription": "La operación de activación del micrófono ha sido bloqueada temporalmente debido a límites del sistema.",
"audioUnmuteBlockedTitle": "¡Activación del micrófono bloqueado!",
"chatMessages": "Mensajes del chat",
"connectedOneMember": "{{name}} se unió a la reunión",
"connectedThreePlusMembers": "{{name}} y {{count}} más se unieron a la reunión",
"connectedTwoMembers": "{{first}} y {{second}} se unieron a la reunión",
"dataChannelClosed": "",
"dataChannelClosedDescription": "",
"disabledIframe": "",
"disconnected": "desconectado",
"displayNotifications": "Mostrar notificaciones para",
"dontRemindMe": "No me lo recuerdes",
"focus": "Enfocar conferencia",
"focusFail": "{{component}} no disponible. Vuelve a intentar en {{ms}} segundos",
"gifsMenu": "GIPHY",
"groupTitle": "Notificaciones",
"hostAskedUnmute": "El moderador quiere que hables",
"invitedOneMember": "{{name}} ha sido invitado",
"invitedThreePlusMembers": "{{name}} y {{count}} más han sido invitados",
"invitedTwoMembers": "{{first}} y {{second}} han sido invitados",
"joinMeeting": "Unirse",
"kickParticipant": "{{kicker}} sacó a {{kicked}}",
"leftOneMember": "{{name}} abandonó la reunión",
"leftThreePlusMembers": "{{name}} y muchos otros abandonaron la reunión",
"leftTwoMembers": "{{first}} y {{second}} abandonaron la reunión",
"linkToSalesforce": "Enlace a Salesforce",
"linkToSalesforceDescription": "Puedes vincular el resumen de la reunión a un objeto Salesforce",
"linkToSalesforceError": "Error al vincular la reunión a Salesforce",
"linkToSalesforceKey": "",
"linkToSalesforceProgress": "Vinculando reunión a Salesorce...",
"linkToSalesforceSuccess": "La reunión fue vinculada a Salesforce",
"localRecordingStarted": "{{name}} ha iniciado una grabación local.",
"localRecordingStopped": "{{name}} ha detenido una grabación local.",
"me": "Yo",
"moderationInEffectCSDescription": "Por favor, levante la mano si quiere compartir su pantalla.",
"moderationInEffectCSTitle": "La pantalla compartida está bloqueada por el moderador",
@@ -608,16 +732,27 @@
"newDeviceAction": "Usar",
"newDeviceAudioTitle": "Se detectó un dispositivo de audio nuevo",
"newDeviceCameraTitle": "Se detectó una cámara nueva",
"noiseSuppressionDesktopAudioDescription": "La supresión de ruido no puede ser habilitada mientras comparte audio del escritorio, por favor deshabilítelo y vuelva a intentar.",
"noiseSuppressionFailedTitle": "Error al activar la supresión de ruido",
"noiseSuppressionNoTrackDescription": "Por favor active su micrófono primero.",
"noiseSuppressionStereoDescription": "La supresión de ruido en audio estéreo no tiene soporte actualmente",
"oldElectronClientDescription1": "Estás usando una versión vieja de la aplicación de Jitsi Meet que tiene problemas de seguridad. ¡Por favor, actualiza a la ",
"oldElectronClientDescription2": "versión más reciente",
"oldElectronClientDescription3": " YA!",
"participantWantsToJoin": "Quiere unirse a la reunión",
"participantsWantToJoin": "Quieren unirse a la reunión",
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) eliminada por otro participante",
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) agregada por otro participante",
"raiseHandAction": "Levantar la mano",
"raisedHand": "{{name}} quisiera hablar.",
"raisedHands": "",
"reactionSounds": "Desactivar sonidos",
"reactionSoundsForAll": "Desactivar sonidos para todos",
"screenShareNoAudio": "La casilla Compartir audio no estaba marcada en la pantalla de selección de ventanas.",
"screenShareNoAudioTitle": "No se pudo compartir el audio del sistema.",
"screenSharingAudioOnlyDescription": "Por favor tenga en cuenta que al compartir si pantalla está afectando el modo \"Mejor rendimiento\" y usará más ancho de banda",
"screenSharingAudioOnlyTitle": "Modo \"Mejor rendimiento\"",
"selfViewTitle": "Siempre puedes reactivar la vista propia en los ajustes",
"somebody": "Alguien",
"startSilentDescription": "Vuelve a ingresar para activar el audio",
"startSilentTitle": "¡Te uniste sin audio!",
@@ -625,7 +760,11 @@
"suboptimalExperienceTitle": "¡Tu navegador no es compatible!",
"unmute": "Reactivar micrófono",
"videoMutedRemotelyDescription": "Siempre puedes volver a encenderlo.",
"videoMutedRemotelyTitle": "Su vídeo ha sido desactivado por {{moderator}}"
"videoMutedRemotelyTitle": "Su vídeo ha sido desactivado por {{moderator}}",
"videoUnmuteBlockedDescription": "Las operaciones de desactivar la cámara y compartir pantalla hansido bloqueadas temporalmente debido a límites del sistema.",
"videoUnmuteBlockedTitle": "¡Desactivar cámara y compartir pantalla bloqueados!",
"viewLobby": "Ver lobby",
"waitingParticipants": "{{waitingParticipants}} personas"
},
"participantsPane": {
"actions": {
@@ -635,6 +774,9 @@
"audioModeration": "Desmutearse a sí mismos",
"blockEveryoneMicCamera": "Bloquear el micrófono y la cámara de todos.",
"invite": "Invitar a alguien",
"moreModerationActions": "Más opciones de moderación",
"moreModerationControls": "Más controles de moderación",
"moreParticipantOptions": "Más opciones de participantes",
"mute": "Silenciar",
"muteAll": "Silenciar a todos los demás",
"muteEveryoneElse": "Silenciar al resto",
@@ -647,17 +789,22 @@
"headings": {
"lobby": "Vestíbulo ({{count}})",
"participantsList": "Participantes en la reunión ({{count}})",
"visitors": "Visitantes ({{count}})",
"waitingLobby": "Esperando en el vestíbulo ({{count}})"
},
"search": "Buscar participantes",
"title": "Participantes"
},
"passwordDigitsOnly": "Hasta {{number}} cifras",
"passwordSetRemotely": "Definida por otro participante",
"pinParticipant": "",
"pinnedParticipant": "",
"polls": {
"answer": {
"skip": "Saltar",
"submit": "Enviar"
},
"by": "Por {{ name }}",
"create": {
"addOption": "Añadir opción",
"answerPlaceholder": "Opción {{index}}",
@@ -728,15 +875,18 @@
"initiated": "Llamada iniciada",
"joinAudioByPhone": "Entrar con audio de llamada telefónica",
"joinMeeting": "Entrar a la reunión",
"joinMeetingInLowBandwidthMode": "Entrar en modo de ancho de banda bajo",
"joinWithoutAudio": "Entrar sin sonido",
"keyboardShortcuts": "Activar los atajos de teclado",
"linkCopied": "Se copió el link",
"lookGood": "Tu micrófono funciona bien.",
"or": "o",
"premeeting": "Pre-reunión",
"proceedAnyway": "Continuar de todos modos",
"screenSharingError": "Error al compartir pantalla:",
"showScreen": "Habilitar pantalla pre-reunión",
"startWithPhone": "Iniciar con audio de llamada telefónica",
"unsafeRoomConsent": "Comprendo los riesgos, quiero unirme a la reunión",
"videoOnlyError": "Error con el vídeo:",
"videoTrackError": "No se pudo crear la pista de vídeo.",
"viewAllNumbers": "ver todos los números"
@@ -763,6 +913,19 @@
"title": "Perfil"
},
"raisedHand": "Desea hablar",
"raisedHandsLabel": "Cantidad de manos levantadas",
"record": {
"already": {
"linked": "La reunión ya está vinculada a este objeto Salesforce"
},
"type": {
"account": "Cuenta",
"contact": "Contacto",
"lead": "",
"opportunity": "Oportunidad",
"owner": "Dueño"
}
},
"recording": {
"authDropboxText": "Subir a Dropbox",
"availableSpace": "Espacio disponible: {{spaceLeft}} MB (aproximadamente {{duration}} minutos de grabación)",
@@ -777,37 +940,66 @@
"expandedPending": "La grabación se está iniciando…",
"failedToStart": "No se pudo iniciar la grabación",
"fileSharingdescription": "Compartir la grabación con los participantes de la reunión",
"highlight": "Destacar",
"highlightMoment": "Destacar momento",
"highlightMomentDisabled": "Puede destacar momentos cuando inicie la grabación",
"highlightMomentSuccess": "Momento destacado",
"highlightMomentSucessDescription": "Su momento destacado será agregado al resumen de la reunión.",
"inProgress": "Grabación o transmisión en vivo en curso",
"limitNotificationDescriptionNative": "Su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <3>{{app}}</3>.",
"limitNotificationDescriptionWeb": "Debido a la alta demanda su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Hemos generado un enlace a su grabación.",
"live": "EN VIVO",
"localRecordingNoNotificationWarning": "La grabación no será anunciada al resto de participantes. Necesitarás hacerles saber que la reunión está siendo grabada.",
"localRecordingNoVideo": "El video no está siendo grabado",
"localRecordingStartWarning": "Por favor asegúrese de detener la grabación antes de abandonar la reunión para guardarla.",
"localRecordingStartWarningTitle": "Detenga la grabación para guardarla",
"localRecordingVideoStop": "Detener su video también detendrá la grabación local. ¿Está seguro de querer continuar?",
"localRecordingVideoWarning": "Para grabar su video debe tenerlo encendido al iniciar la grabación",
"localRecordingWarning": "Asegúrese de seleccionar la pestaña actual para usar el video y audio correctos. La grabación está actualmente limitada a 1GB, que son aproximadamente 100 minutos.",
"loggedIn": "Sesión iniciada como {{userName}}",
"noMicPermission": "No se pudo crear la pista de micrófono. Por favor otorgue permiso para usar el micrófono.",
"noStreams": "",
"off": "Grabación detenida",
"offBy": "{{name}} detuvo la grabación",
"on": "Grabando",
"onBy": "{{name}} comenzó la grabación",
"onlyRecordSelf": "",
"pending": "Preparando para grabar la reunión…",
"rec": "GRA",
"saveLocalRecording": "Guardar archivo de grabación localmente (Beta)",
"serviceDescription": "El servicio de grabación guardará la grabación",
"serviceDescriptionCloud": "Grabación en la nube",
"serviceDescriptionCloudInfo": "Las reuniones grabadas son limpiadas 24h luego de su horario de grabación.",
"serviceName": "Servicio de grabación",
"sessionAlreadyActive": "Esta sesión ya está siendo grabada o transmitida en vivo.",
"signIn": "Iniciar sesión",
"signOut": "Cerrar sesión",
"surfaceError": "Por favor seleccione la pestaña actual.",
"title": "Grabando",
"unavailable": "¡Uy! {{serviceName}} actualmente no está disponible. Estamos trabajando para resolver el problema. Vuelve a intentarlo más tarde.",
"unavailableTitle": "Grabación no disponible",
"uploadToCloud": "Subir a la nube"
},
"screenshareDisplayName": "Pantalla de {{name}}",
"sectionList": {
"pullToRefresh": "Mueve el dedo para abajo para actualizar."
},
"security": {
"about": "Puedes agregar una contraseña a la reunión. Los participantes necesitarán la contraseña para unirse a la reunión.",
"aboutReadOnly": "Los participantes moderadores pueden agregar una $t(lockRoomPassword) a la reunión. Los participantes deberán proporcionar la $t(lockRoomPassword) antes de que se les permita unirse a la reunión.",
"insecureRoomNameWarning": "El nombre de la sala es inseguro. Participantes no deseados pueden llegar a unirse a la reunión.",
"securityOptions": "Opciones de seguridad"
"insecureRoomNameWarningNative": "El nombre de esta sala es inseguro. Participantes indeseados podrían ingresar a su reunión. {{recommendAction}} Aprenda más sobre asegurar su reunión ",
"insecureRoomNameWarningWeb": "El nombre de esta sala es inseguro. Participantes indeseados podrían ingresar a su reunión. {{recommendAction}} Aprenda más sobre asegurar su reunión <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">aquí</a>.",
"title": "Opciones de seguridad",
"unsafeRoomActions": {
"meeting": "Considere hacer más segura su reunión utilizando el botón de seguridad.",
"prejoin": "Considere utilizar un nombre de reunión más único.",
"welcome": "Considere utilizar un nombre de reunión más único, o elija una de las sugerencias"
}
},
"settings": {
"audio": "Audio",
"buttonLabel": "Ajustes",
"calendar": {
"about": "La integración del calendario de {{appName}} se usa para acceder al calendario de manera segura para que puedas estar al tanto de los próximos eventos.",
"disconnect": "Desconectar",
@@ -824,12 +1016,16 @@
"incomingMessage": "Mensaje entrante",
"language": "Idioma",
"loggedIn": "Sesión iniciada como {{name}}",
"maxStageParticipants": "",
"microphones": "Micrófono",
"moderator": "Moderador",
"moderatorOptions": "Opciones de moderador",
"more": "Más",
"name": "Nombre",
"noDevice": "Ninguno",
"participantJoined": "Un articipante incorporado",
"notifications": "Notificaciones",
"participantJoined": "Un participante se ha unido",
"participantKnocking": "Un participante ha ingresado al lobby",
"participantLeft": "Un participante se ha ido",
"playSounds": "Reproducir sonido",
"reactions": "Reacciones de la reunión",
@@ -837,12 +1033,15 @@
"selectAudioOutput": "Salida de audio",
"selectCamera": "Cámara",
"selectMic": "Micrófono",
"sounds": "Sonidos",
"selfView": "Vista propia",
"shortcuts": "Atajos",
"speakers": "Altavoces",
"startAudioMuted": "Todos inician silenciados",
"startReactionsMuted": "Silenciar sonidos de reacción para todos",
"startVideoMuted": "Todos inician con cámara desactivada",
"talkWhileMuted": "Hablar en silencio",
"title": "Ajustes"
"title": "Ajustes",
"video": "Video"
},
"settingsView": {
"advanced": "Avanzado",
@@ -857,13 +1056,21 @@
"disableCrashReportingWarning": "¿Estás seguro que no deseas reportarnos los crasheos? La opción se activará al reiniciar la app.",
"disableP2P": "Desactivar la comunicación directa (\"Peer-To-Peer\")",
"displayName": "Nombre a mostrar",
"displayNamePlaceholderText": "Por ejemplo: Juan Pérez",
"email": "Correo electrónico",
"emailPlaceholderText": "",
"goTo": "Ir a",
"header": "Configuración",
"help": "Ayuda",
"links": "Enlaces",
"privacy": "Privacidad",
"profileSection": "Perfil",
"serverURL": "URL del servidor",
"showAdvanced": "Mostrar configuración avanzada",
"startCarModeInLowBandwidthMode": "Iniciar módo automóvil en modo ancho de banda bajo",
"startWithAudioMuted": "Iniciar con el micrófono apagado",
"startWithVideoMuted": "Iniciar con la cámara apagada",
"terms": "Términos",
"version": "Versión"
},
"share": {
@@ -872,13 +1079,21 @@
},
"speaker": "Participante",
"speakerStats": {
"angry": "Enojado",
"disgusted": "Disgustado",
"displayEmotions": "Mostrar emociones",
"fearful": "Temeroso",
"happy": "Feliz",
"hours": "{{count}} h",
"minutes": "{{count}} min",
"name": "Nombre",
"neutral": "Neutral",
"sad": "Triste",
"search": "Buscar",
"seconds": "{{count}} s",
"speakerStats": "Estadísticas de participantes",
"speakerTime": "Tiempo hablado"
"speakerTime": "Tiempo hablado",
"surprised": "Sorprendido"
},
"startupoverlay": {
"genericTitle": "La reunión debe utilizar su micrófono y su cámara.",
@@ -890,6 +1105,10 @@
"text": "Presiona el botón <i>Reconectar</i> para volver a conectarte.",
"title": "La vídeollamada se interrumpió porque la computadora estaba suspendida."
},
"termsView": {
"title": "Términos"
},
"toggleTopPanelLabel": "Alternar panel superior",
"toolbar": {
"Settings": "Configuración",
"accessibilityLabel": {
@@ -897,60 +1116,89 @@
"audioOnly": "Alternar cámaras de los demás",
"audioRoute": "Seleccionar el dispositivo de sonido",
"boo": "Boo",
"breakoutRoom": "Unirse/abandonar sala para grupos pequeños",
"callQuality": "Administrar la calidad de vídeo",
"carmode": "Modo automóvil",
"cc": "Alternar subtítulos",
"chat": "Alternar ventana de chat",
"clap": "Aplauso",
"closeChat": "Cerrar chat",
"closeMoreActions": "Cerrar el menú de más acciones",
"closeParticipantsPane": "Cerrar panel de participantes",
"collapse": "Colapsar",
"document": "Alternar documento compartido",
"documentClose": "Cerrar documento compartido",
"documentOpen": "Abrir documento compartido",
"download": "Descargar nuestras aplicaciones",
"embedMeeting": "Insertar reunión",
"endConference": "Terminar reunión para todos",
"enterFullScreen": "Ver en pantalla completa",
"enterTileView": "Ingresar en vista de mosaico",
"exitFullScreen": "Salir de pantalla completa",
"exitTileView": "Salir de vista de mosaico",
"expand": "Ampliar",
"feedback": "Dejar comentarios",
"fullScreen": "Alternar pantalla completa",
"giphy": "Alternar menú GIPHY",
"grantModerator": "Convertir en moderador",
"hangup": "Colgar",
"heading": "Barra de herramientas",
"help": "Ayuda",
"hideWhiteboard": "Esconder pizarra",
"invite": "Invitar personas",
"kick": "Expulsar participante",
"laugh": "Ríete",
"leaveConference": "Abandonar reunión",
"like": "Pulgares arriba",
"linkToSalesforce": "Enlace a Salesforce",
"lobbyButton": "Activar / desactivar el modo lobby",
"localRecording": "Alternar controles de grabación local",
"lockRoom": "Alternar contraseña de la reunión",
"lowerHand": "Bajar mano",
"moreActions": "Alternar más acciones",
"moreActionsMenu": "Menú de más acciones",
"moreOptions": "Mostrar más opciones",
"mute": "Silenciar micrófono",
"muteEveryone": "Silenciar a todos",
"muteEveryoneElse": "Silenciar a todos los demás",
"muteEveryoneElsesVideo": "Desactivar el vídeo de los demás",
"muteEveryonesVideo": "Desactivar el vídeo de todos",
"muteEveryoneElsesVideoStream": "Detener el video del resto",
"muteEveryonesVideoStream": "Detener el video de todos",
"muteGUMPending": "Conectando su micrófono",
"noiseSuppression": "Supresión de ruido",
"openChat": "Abrir chat",
"participants": "Participantes",
"pip": "Alternar modo ventana en miniatura",
"privateMessage": "Enviar mensaje privado",
"profile": "Editar perfil",
"raiseHand": "Levantar o bajar la mano",
"reactions": "Reacciones",
"reactionsMenu": "Abrir / Cerrar el menú de reacciones",
"recording": "Alternar grabación",
"remoteMute": "Silenciar participante",
"remoteVideoMute": "Desactivar la cámara del participante",
"security": "Opciones de seguridad",
"selectBackground": "Seleccione el fondo",
"selfView": "Alternar vista propia",
"shareRoom": "Invitar a alguien",
"shareYourScreen": "Comenzar / detener compartir pantalla",
"shareaudio": "Compartir audio",
"sharedvideo": "Alternar vídeo compartido",
"shortcuts": "Alternar accesos directos",
"show": "Mostrar en primer",
"showWhiteboard": "Mostrar vista propia",
"silence": "Silencio",
"speakerStats": "Alternar estadísticas del orador",
"stopScreenSharing": "Dejar de compartir pantalla",
"stopSharedVideo": "Detener video",
"surprised": "Sorprendido",
"tileView": "Alternar vista de mosaico",
"toggleCamera": "Alternar cámara",
"toggleFilmstrip": "Alternar mosaicos",
"unmute": "Activar micrófono",
"videoblur": "Alternar desenfoque de vídeo",
"videomute": "Alternar vídeo"
"videomute": "Alternar vídeo",
"videomuteGUMPending": "Conectando tu cámara",
"videounmute": "Encender cámara"
},
"addPeople": "Agregar personas a la llamada",
"audioOnlyOff": "Mostrar cámaras de los demás",
@@ -963,23 +1211,33 @@
"chat": "Abrir o cerrar chat",
"clap": "Aplauso",
"closeChat": "Cerrar chat",
"closeParticipantsPane": "Cerrar panel de participantes",
"closeReactionsMenu": "Cerrar el menú de reacciones",
"disableNoiseSuppression": "Desactivar supresión de ruido",
"disableReactionSounds": "Puede desactivar los sonidos de reacción para esta reunión",
"documentClose": "Cerrar documento compartido",
"documentOpen": "Abrir documento compartido",
"download": "Descarga nuestras aplicaciones",
"e2ee": "Cifrado de extremo a extremo",
"embedMeeting": "Insertar reunión",
"enableNoiseSuppression": "Activar supresión de ruido",
"endConference": "Terminar reunión para todos",
"enterFullScreen": "Pantalla completa",
"enterTileView": "Ver en cuadrícula",
"exitFullScreen": "Salir de pantalla completa",
"exitTileView": "Salir de vista de mosaico",
"feedback": "Dejar sugerencias",
"giphy": "Alternar menú GIPHY",
"hangup": "Colgar",
"help": "Ayuda",
"hideWhiteboard": "Esconder pizarra",
"invite": "Invitar personas",
"joinBreakoutRoom": "Unirse a sala para grupos pequeños",
"laugh": "Ríete",
"leaveBreakoutRoom": "Abandonar sala para grupos pequeños",
"leaveConference": "Abandonar reunión",
"like": "Pulgares arriba",
"linkToSalesforce": "",
"lobbyButtonDisable": "Desactivar el modo lobby",
"lobbyButtonEnable": "Activar el modo lobby",
"login": "Inicio de sesión",
@@ -990,11 +1248,13 @@
"mute": "Activar o silenciar el micrófono",
"muteEveryone": "Silenciar a todos",
"muteEveryonesVideo": "Desactivar la cámara de todos",
"muteGUMPending": "Conectando tu micrónono",
"noAudioSignalDesc": "Checa si no está silenciado en tu configuración del sistema o dispositivo, o cambia de micrófono.",
"noAudioSignalDescSuggestion": "Si no lo silenciaste a propósito desde la configuración del sistema o el dispositivo, intenta usar este otro micrófono:",
"noAudioSignalDialInDesc": "Además, puedes llamar usando:",
"noAudioSignalDialInLinkDesc": "Números de llamada",
"noAudioSignalTitle": "¡No se registra audio de tu micrófono!",
"noiseSuppression": "Supresión de ruido",
"noisyAudioInputDesc": "Tu micrófono está haciendo ruido, siléncialo, ajusta su volumen en configuración del sistema, o cambia de micrófono.",
"noisyAudioInputTitle": "Tu micrófono parece estar ruidoso",
"openChat": "Abrir chat",
@@ -1011,12 +1271,14 @@
"reactionLike": "Enviar la reacción de los pulgares hacia arriba",
"reactionSilence": "Enviar reacción de silencio",
"reactionSurprised": "Enviar reacción de sorpresa",
"reactions": "Reacciones",
"security": "Opciones de seguridad",
"selectBackground": "Seleccionar fondo",
"shareRoom": "Invitar a alguien",
"shareaudio": "Compartir audio",
"sharedvideo": "Compartir un vídeo",
"shortcuts": "Ver atajos del teclado",
"showWhiteboard": "Mostrar pizarra",
"silence": "Silencio",
"speakerStats": "Estadísticas de los participantes",
"startScreenSharing": "Comenzar a compartir pantalla",
@@ -1029,8 +1291,11 @@
"talkWhileMutedPopup": "¿Intentas hablar? Estás silenciado.",
"tileViewToggle": "Activar o desactivar vista en cuadrícula",
"toggleCamera": "Alternar cámara",
"unmute": "Activar",
"videoSettings": "Ajustes de vídeo",
"videomute": "Iniciar o detener cámara"
"videomute": "Detener cámara",
"videomuteGUMPending": "Conectando tu cámara",
"videounmute": "Iniciar cámara"
},
"transcribing": {
"ccButtonTooltip": "Iniciar o detener subtítulos",
@@ -1040,10 +1305,15 @@
"labelToolTip": "La reunión se está transcribiendo",
"off": "Transcripción detenida",
"pending": "Preparando para transcribir la reunión…",
"sourceLanguageDesc": "El lenguaje actual de la reunión es <b>{{sourceLanguage}}</b>. <br/> Puedes cambiarlo desde ",
"sourceLanguageHere": "aquí",
"start": "Mostrar subtítulos",
"stop": "Dejar de mostrar subtítulos",
"subtitles": "Subtítulos",
"subtitlesOff": "",
"tr": "TR"
},
"unpinParticipant": "",
"userMedia": {
"androidGrantPermissions": "Selecciona <b><i>Permitir</i></b> cuando el navegador solicite permisos.",
"chromeGrantPermissions": "Selecciona <b><i>Permitir</i></b> cuando el navegador solicite permisos.",
@@ -1067,20 +1337,26 @@
"pending": "{{displayName}} ha sido invitado"
},
"videoStatus": {
"adjustFor": "Ajustar para:",
"audioOnly": "AUD",
"audioOnlyExpanded": "Estás en modo de ancho de banda bajo. En este modo, sólo recibirás audio y pantalla compartida.",
"bestPerformance": "Mejor rendimiento",
"callQuality": "Calidad de vídeo",
"hd": "HD",
"hdTooltip": "Viendo vídeo en alta definición",
"highDefinition": "Alta definición",
"highestQuality": "Calidad máxima",
"labelTooiltipNoVideo": "Sin vídeo",
"labelTooltipAudioOnly": "Modo de ancho de banda bajo habilitado",
"ld": "LD",
"ldTooltip": "Viendo vídeo en baja definición",
"lowDefinition": "Baja definición",
"performanceSettings": "Ajustes de rendimiento",
"recording": "Grabación en curso",
"sd": "SD",
"sdTooltip": "Viendo vídeo en definición estándar",
"standardDefinition": "Definición estándar"
"standardDefinition": "Definición estándar",
"streaming": "Transmisión en curso"
},
"videothumbnail": {
"connectionInfo": "Información de conexión",
@@ -1090,12 +1366,19 @@
"domuteVideoOfOthers": "Desactivar la cámara de todos los demás",
"flip": "Voltear",
"grantModerator": "Convertir en moderador",
"hideSelfView": "Esconder vista propia",
"kick": "Expulsar",
"mirrorVideo": "Espejar mi video",
"moderator": "Moderador",
"mute": "Se silenció el participante",
"muted": "Silenciado",
"pinToStage": "",
"remoteControl": "Control remoto",
"screenSharing": "El participante está compartiendo su pantalla",
"show": "Mostrar en primer plano",
"showSelfView": "Mostrar vista propia",
"unpinFromStage": "",
"verify": "Verificar participante",
"videoMuted": "Cámara desactivada",
"videomute": "El participante paró su cámara"
},
@@ -1120,7 +1403,16 @@
"slightBlur": "Desenfoque Ligero",
"title": "Fondos virtuales",
"uploadedImage": "Imagen subida {{index}}",
"webAssemblyWarning": "No se admite WebAssembly"
"webAssemblyWarning": "No se admite WebAssembly",
"webAssemblyWarningDescription": "WebAssembly está desactivado o no cuenta con soporte en este navegador"
},
"visitors": {
"chatIndicator": "(visitante)",
"labelTooltip": "Cantidad de visitantes: {{count}}",
"notification": {
"description": "Levanta la mano para participar",
"title": "Eres un visitante en la reunión"
}
},
"volumeSlider": "Deslizador de volumen",
"welcomepage": {
@@ -1154,6 +1446,7 @@
"microsoftLogo": "Logotipo de Microsoft",
"policyLogo": "Logotipo de la política"
},
"meetingsAccessibilityLabel": "Reuniones",
"mobileDownLoadLinkAndroid": "Descargar la aplicación móvil para Android",
"mobileDownLoadLinkFDroid": "Descargar la aplicación móvil para F-Droid",
"mobileDownLoadLinkIos": "Descargar la aplicación móvil para iOS",
@@ -1162,13 +1455,21 @@
"recentList": "Reciente",
"recentListDelete": "Eliminar",
"recentListEmpty": "Tu historial de reuniones está vacío. Reúnete y aparecerán aquí.",
"recentMeetings": "Tus reuniones recientes",
"reducedUIText": "¡Bienvenido a {{app}}!",
"roomNameAllowedChars": "El nombre de la reunión no debe contener ninguno de estos caracteres: ?, &, :, ', \", %, #.",
"roomname": "Introduce el nombre de la sala",
"roomnameHint": "Introduce el nombre o URL de la sala a la que deseas unirte. Puedes inventar un nombre, simplemente infórmaselo a las personas con las que te reunirás para que introduzcan el mismo nombre.",
"sendFeedback": "Enviar sugerencias",
"settings": "Ajustes",
"startMeeting": "Iniciar la reunión",
"terms": "Términos",
"title": "Videoconferencias seguras, con gran variedad de funcionalidades y completamente gratuitas"
"title": "Videoconferencias seguras, con gran variedad de funcionalidades y completamente gratuitas",
"upcomingMeetings": "Tus próximas reuniones"
},
"whiteboard": {
"accessibilityLabel": {
"heading": "Pizarra"
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,8 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Link da reunião: {{url}}"
},
"add": "Convidar",
"addContacts": "Convidar os seus contactos",
"contacts": "contactos",
@@ -39,6 +42,18 @@
"audioOnly": {
"audioOnly": "Largura de banda baixa"
},
"bandwidthSettings": {
"assumedBandwidthBps": "p. ex. 10000000 para 10 Mbps",
"assumedBandwidthBpsWarning": "Valores mais elevados podem causar problemas na rede.",
"customValue": "valor personalizado",
"customValueEffect": "para definir o valor actual de bps",
"leaveEmpty": "deixar em branco",
"leaveEmptyEffect": "para permitir a realização de estimativas",
"possibleValues": "Valores possíveis",
"setAssumedBandwidthBps": "Largura de banda presumida (bps)",
"title": "Definições de largura de banda",
"zeroEffect": "para desligar o vídeo"
},
"breakoutRooms": {
"actions": {
"add": "Adicionar salas simultâneas",
@@ -156,6 +171,7 @@
"localport_plural": "Portas locais:",
"maxEnabledResolution": "enviar máx",
"more": "Mostrar mais",
"no": "não",
"packetloss": "Perda de pacote:",
"participant_id": "Participante id:",
"quality": {
@@ -174,7 +190,8 @@
"status": "Ligação:",
"transport": "Transporte:",
"transport_plural": "Transportes:",
"video_ssrc": "Vídeo SSRC:"
"video_ssrc": "Vídeo SSRC:",
"yes": "sim"
},
"dateUtils": {
"earlier": "Mais cedo",
@@ -240,6 +257,8 @@
"WaitingForHostTitle": "À espera do anfitrião ...",
"Yes": "Sim",
"accessibilityLabel": {
"Cancel": "Cancelar (sair da caixa de diálogo)",
"Ok": "OK (guardar e sair da caixa de diálogo)",
"close": "Fechar caixa de diálogo",
"liveStreaming": "Transmissão em direto",
"sharingTabs": "Opções de partilha"
@@ -319,13 +338,13 @@
"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 reativar o som",
"moderationVideoLabel": "Permitir aos participantes reativar o vídeo",
"muteEveryoneDialog": "Os participantes podem reativar o som a qualquer momento.",
"moderationAudioLabel": "Permitir aos participantes ligar o som",
"moderationVideoLabel": "Permitir aos participantes ligar a câmara",
"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 reativar-se 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}}?",
"muteEveryoneElsesVideoDialog": "Quando a câmara for desativada, não poderá voltar a ligá-la, mas eles podem voltar a ligá-la em qualquer momento.",
"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",
@@ -445,6 +464,9 @@
"title": "Incorporar esta reunião"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "A sua escolha: {{rating}}"
},
"average": "Média",
"bad": "Má",
"detailsLabel": "Conte-nos mais sobre isso.",
@@ -673,8 +695,10 @@
"connectedTwoMembers": "{{first}} e {{second}} entraram na reunião",
"dataChannelClosed": "Deficiência na qualidade do vídeo",
"dataChannelClosedDescription": "O canal de ponte foi desconectado e, portanto, a qualidade do vídeo está limitada à sua configuração mais baixa.",
"disabledIframe": "A incorporação destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos.",
"disconnected": "desconectado",
"displayNotifications": "Mostrar notificações para",
"dontRemindMe": "Não me lembre",
"focus": "Foco da conferência",
"focusFail": "{{component}} não disponĩvel - tente em {{ms}} seg.",
"gifsMenu": "GIPHY",
@@ -754,8 +778,8 @@
"actions": {
"allow": "Permitir aos participantes:",
"allowVideo": "Permitir vídeo",
"askUnmute": "Pedir para ligar o microfone",
"audioModeration": "Ativar o microfone deles",
"askUnmute": "Pedir para ligar o som",
"audioModeration": "Ligar o microfone deles",
"blockEveryoneMicCamera": "Bloquear o microfone e a câmara de todos",
"invite": "Convidar alguém",
"moreModerationActions": "Mais opções de moderação",
@@ -866,9 +890,11 @@
"lookGood": "O seu microfone funciona corretamente",
"or": "ou",
"premeeting": "Pré-reunião",
"proceedAnyway": "Continuar na mesma",
"screenSharingError": "Erro de partilha de ecrã:",
"showScreen": "Ativar o ecrã de pré-reunião",
"startWithPhone": "Iniciar com o áudio do telefone",
"unsafeRoomConsent": "Compreendo os riscos, quero participar na reunião",
"videoOnlyError": "Erro de vídeo:",
"videoTrackError": "Não foi possível criar a pista de vídeo.",
"viewAllNumbers": "ver todos os números"
@@ -944,7 +970,7 @@
"noStreams": "Não foi detetado nenhum sinal áudio ou vídeo.",
"off": "Gravação parada",
"offBy": "{{name}} parou a gravação",
"on": "Gravando",
"on": "Começou a gravação",
"onBy": "{{name}} iniciou a gravação",
"onlyRecordSelf": "Gravar apenas as minhas transmissões áudio e vídeo",
"pending": "Preparando para gravar a reunião...",
@@ -970,8 +996,14 @@
"security": {
"about": "Pode adicionar uma $t(lockRoomPassword) à sua reunião. Os participantes terão de fornecer a $t(lockRoomPassword) antes de serem autorizados a participar na reunião.",
"aboutReadOnly": "Os participantes moderadores podem acrescentar uma $t(lockRoomPassword) à reunião. Os participantes terão de fornecer a $t(lockRoomPassword) antes de serem autorizados a participar na reunião.",
"insecureRoomNameWarning": "O nome da sala é inseguro. Participantes indesejados podem juntar-se à sua conferência. Considere proteger a sua reunião utilizando o botão de segurança.",
"title": "Opções de segurança"
"insecureRoomNameWarningNative": "O nome da sala não é seguro. Participantes indesejados podem juntar-se à sua reunião. {{recommendAction}} Saiba mais sobre como proteger a sua reunião ",
"insecureRoomNameWarningWeb": "O nome da sala não é seguro. Participantes indesejados podem juntar-se à sua reunião. {{recommendAction}} Saiba mais sobre como proteger a sua reunião <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">here</a>.",
"title": "Opções de Segurança",
"unsafeRoomActions": {
"meeting": "Considere a possibilidade de proteger a sua reunião utilizando o botão de segurança.",
"prejoin": "Considere a utilização de um nome de reunião mais personalizado.",
"welcome": "Considere utilizar um nome de reunião mais personalizado ou selecione uma das sugestões."
}
},
"settings": {
"audio": "Áudio",
@@ -1139,6 +1171,7 @@
"muteEveryoneElse": "Silenciar todos os outros",
"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",
"openChat": "Abrir chat",
"participants": "Abrir painel de participantes",
@@ -1146,6 +1179,7 @@
"privateMessage": "Enviar mensagem privada",
"profile": "Editar o seu perfil",
"raiseHand": "Levantar a mão",
"reactions": "Reações",
"reactionsMenu": "Menu de reações",
"recording": "Mudar gravação",
"remoteMute": "Participante sem som",
@@ -1171,6 +1205,7 @@
"unmute": "Ligar microfone",
"videoblur": "Mudar o desfoque de vídeo",
"videomute": "Parar câmara",
"videomuteGUMPending": "A ligar a sua câmara",
"videounmute": "Iniciar câmara"
},
"addPeople": "Adicione pessoas à sua chamada",
@@ -1221,6 +1256,7 @@
"mute": "Desligar microfone",
"muteEveryone": "Silenciar todos",
"muteEveryonesVideo": "Desativar a câmara de todos",
"muteGUMPending": "A ligar o seu microfone",
"noAudioSignalDesc": "Se não o silenciou propositadamente a partir de configurações do sistema ou hardware, considere mudar de dispositivo.",
"noAudioSignalDescSuggestion": "Se não o silenciou propositadamente a partir das configurações do sistema ou hardware, considere mudar para o dispositivo sugerido.",
"noAudioSignalDialInDesc": "Também pode marcar usando:",
@@ -1243,6 +1279,7 @@
"reactionLike": "Enviar reação de aprovado",
"reactionSilence": "Enviar reação de silêncio",
"reactionSurprised": "Enviar reação de surpreendido",
"reactions": "Reações",
"security": "Opções de segurança",
"selectBackground": "Selecionar plano de fundo",
"shareRoom": "Convidar alguém",
@@ -1265,6 +1302,7 @@
"unmute": "Ligar microfone",
"videoSettings": "Definições de vídeo",
"videomute": "Parar câmara",
"videomuteGUMPending": "A ligar a sua câmara",
"videounmute": "Iniciar câmara"
},
"transcribing": {
@@ -1311,7 +1349,7 @@
"audioOnly": "AUD",
"audioOnlyExpanded": "Está em modo de baixa largura de banda. Neste modo, receberá apenas partilha de áudio e ecrã.",
"bestPerformance": "Melhor desempenho",
"callQuality": "Qualidade de vídeo",
"callQuality": "Qualidade de vídeo (0 para o melhor desempenho, 3 para a melhor qualidade)",
"hd": "HD",
"hdTooltip": "Ver vídeo em alta definição",
"highDefinition": "Alta definição (HD)",
@@ -1353,6 +1391,10 @@
"videomute": "Participante parou a câmara"
},
"virtualBackground": {
"accessibilityLabel": {
"currentBackground": "Atual imagem de fundo: {{background}}",
"selectBackground": "Selecionar uma imagem de fundo"
},
"addBackground": "Adicionar imagem de fundo",
"apply": "Aplicar",
"backgroundEffectError": "Falha ao aplicar efeito de fundo.",
@@ -1376,7 +1418,14 @@
"webAssemblyWarning": "WebAssembly não suportado",
"webAssemblyWarningDescription": "WebAssembly desactivado ou não suportado por este navegador"
},
"visitorsLabel": "Número de visitantes: {{count}}",
"visitors": {
"chatIndicator": "(visitante)",
"labelTooltip": "Número de visitantes: {{count}}",
"notification": {
"description": "Para participar levante a sua mão",
"title": "É um visitante na reunião"
}
},
"volumeSlider": "Controlo de volume",
"welcomepage": {
"accessibilityLabel": {

View File

@@ -68,9 +68,9 @@
},
"join": "Gå med",
"joinTooltip": "Gå med i mötet",
"nextMeeting": "nästa möte",
"nextMeeting": "Nästa möte",
"noEvents": "Det finns inga inbokade kommande aktiviteter.",
"ongoingMeeting": "pågående möte",
"ongoingMeeting": "Pågående möte",
"permissionButton": "Öppna inställningar",
"permissionMessage": "Tillåtelse från kalendern krävs för att se dina möten i appen.",
"refresh": "Uppdatera kalender",
@@ -147,6 +147,7 @@
"bridgeCount": "Serverantal: ",
"codecs": "Codecs (A/V):",
"connectedTo": "Ansluten till:",
"e2eeVerified": "E2EE verifierad",
"framerate": "Bildfrekvens:",
"less": "Visa mindre",
"localaddress": "Lokal adress:",
@@ -155,6 +156,7 @@
"localport_plural": "Lokala portar:",
"maxEnabledResolution": "Sänd maxiamlt",
"more": "Visa mer",
"no": "Nej",
"packetloss": "Paketförluster:",
"participant_id": "Deltagar id:",
"quality": {
@@ -173,7 +175,8 @@
"status": "Anslutning:",
"transport": "Transport:",
"transport_plural": "Transporter:",
"video_ssrc": "Video SSRC:"
"video_ssrc": "Video SSRC:",
"yes": "Ja"
},
"dateUtils": {
"earlier": "Tidigare",
@@ -183,17 +186,25 @@
"deepLinking": {
"appNotInstalled": "Du behöver mobilappen {{app}} för att gå med i det här mötet från din telefon.",
"description": "Hände inget? Vi försökte starta mötet i programmet {{app}} i din skrivbordsapp. Försök igen eller starta det i webbappen {{app}}.",
"descriptionNew": "Hände inget? Vi försökte starta mötet i programmet {{app}} i din skrivbordsapp. <br /><br /> Försök igen eller starta det på webben.",
"descriptionWithoutWeb": "Händer inget? Vi försökte starta mötet i {{app}}-skrivbordsappen.",
"downloadApp": "Hämta appen",
"downloadMobileApp": "Ladda ner mobilappen",
"ifDoNotHaveApp": "Om du inte har appen än:",
"ifHaveApp": "Om du redan har appen:",
"joinInApp": "Delta i detta möte med din app",
"joinInAppNew": "Delta i appen",
"joinInBrowser": "Delta på webben",
"launchMeetingLabel": "Hur vill du delta i detta möte?",
"launchWebButton": "Starta på webben",
"noMobileApp": "Har du inte appen?",
"termsAndConditions": "Genom att fortsätta godkänner du våra <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>villkor.</a>",
"title": "Startar ditt möte i {{app}} ...",
"titleNew": "Startar ditt möte...",
"tryAgainButton": "Försök igen på skrivbordet",
"unsupportedBrowser": "Det verkar som att du använder en webbläsare som vi inte stöder."
},
"defaultLink": "t ex. {{url}}",
"defaultLink": "t.ex. {{url}}",
"defaultNickname": "till exempel Julia Eriksson",
"deviceError": {
"cameraError": "Det gick inte att komma åt kameran",
@@ -202,6 +213,12 @@
"microphonePermission": "Fel vid begäran om åtkomst till mikrofon"
},
"deviceSelection": {
"hid": {
"callControl": "Samtalskontroll",
"connectedDevices": "Anslutna enheter",
"deleteDevice": "Radera enhet",
"pairDevice": "Para enhet"
},
"noPermission": "Behörighet nekad",
"previewUnavailable": "Förhandsgranskning inte tillgänglig",
"selectADevice": "Välj en enhet",
@@ -225,7 +242,9 @@
"WaitingForHostTitle": "Väntar på värden ...",
"Yes": "Ja",
"accessibilityLabel": {
"liveStreaming": "Livesändning"
"close": "Stäng",
"liveStreaming": "Livesändning",
"sharingTabs": "Delningsalternativ"
},
"add": "Lägg till",
"addMeetingNote": "Mötesinformation",
@@ -408,6 +427,10 @@
"user": "Användare",
"userIdentifier": "Användar-ID",
"userPassword": "Lösenord",
"verifyParticipantConfirm": "Dem matchar",
"verifyParticipantDismiss": "Dem matchar inte",
"verifyParticipantQuestion": "EXPERIMENTELLT: Fråga deltagaren; {{participantName}} om han/hon kan se samma innehåll, i samma ordning.",
"verifyParticipantTitle": "Användarverifikation",
"videoLink": "Videolänk",
"viewUpgradeOptions": "Se uppgraderings alternativ",
"viewUpgradeOptionsContent": "För att få obegränsad tillgång till premiumfunktioner som inspelning, transkriptioner, RTMP -streaming och mer måste du uppgradera din plan.",
@@ -433,13 +456,15 @@
"veryBad": "Mycket dåligt",
"veryGood": "Mycket bra"
},
"filmstrip": {
"accessibilityLabel": {
"heading": "Videomineatyrer"
}
},
"giphy": {
"noResults": "Inga resultat funna :(",
"search": "Sök efter GIPHY"
},
"helpView": {
"title": "Hjälpcenter"
},
"incomingCall": {
"answer": "Svara",
"audioCallTitle": "Inkommande samtal",
@@ -517,7 +542,8 @@
"toggleParticipantsPane": "Visa eller dölj deltagarfönstret",
"toggleScreensharing": "Växla mellan kamera och skärmdelning",
"toggleShortcuts": "Visa eller dölj kortkommandon",
"videoMute": "Aktivera / avaktivera din kamera"
"videoMute": "Aktivera / inaktivera din kamera",
"whiteboard": "Visa / dölj whiteboardtavlan"
},
"largeVideo": {
"screenIsShared": "Du delar din skärm",
@@ -563,7 +589,6 @@
"lobby": {
"admit": "Godkänn",
"admitAll": "Godkänn alla",
"allow": "Tillåt",
"backToKnockModeButton": "Tillbaka till väntrum",
"chat": "Chatt",
"dialogTitle": "Väntrum",
@@ -649,8 +674,12 @@
"connectedOneMember": "{{name}} har gått med i mötet",
"connectedThreePlusMembers": "{{name}} och {{count}} andra har gått med i mötet",
"connectedTwoMembers": "{{first}} och {{second}} har gått med i mötet",
"dataChannelClosed": "Försämrad videokvalitet",
"dataChannelClosedDescription": "Bryggkanalen har kopplats bort och därmed är videokvaliteten begränsad till sin lägsta inställning",
"disabledIframe": "Inbäddning är endast avsedd för demonstrationsändamål, så det här samtalet kommer att kopplas ner om {{timeout}} minuter.",
"disconnected": "frånkopplad",
"displayNotifications": "Visa aviseringar för",
"dontRemindMe": "Påminn mig inte",
"focus": "Konferensfokus",
"focusFail": "{{component}} inte tillgänglig försöker igen om {{ms}} sek",
"gifsMenu": "GIPHY",
@@ -659,6 +688,7 @@
"invitedOneMember": "{{name}} har bjudits in",
"invitedThreePlusMembers": "{{name}} och {{count}} andra har bjudits in",
"invitedTwoMembers": "{{first}} och {{second}} har bjudits in",
"joinMeeting": "Delta",
"kickParticipant": "{{kicked}} sparkades ut av {{kicker}}",
"leftOneMember": "{{name}} lämnade mötet",
"leftThreePlusMembers": "{{name}} och många andra lämnade mötet",
@@ -709,6 +739,8 @@
"reactionSoundsForAll": "Inaktivera ljud för alla",
"screenShareNoAudio": "\"Dela ljudrutan\" aktiverades inte i fönstret för val av fönster.",
"screenShareNoAudioTitle": "Det gick inte att dela systemljud!",
"screenSharingAudioOnlyDescription": "Observera att genom att dela din skärm påverkar du läget \"Bästa prestanda\" och du kommer att använda mer bandbredd.",
"screenSharingAudioOnlyTitle": "Läget \"Bästa prestanda\"",
"selfViewTitle": "Du kan alltid ta bort döljandet av självvyn från inställningarna",
"somebody": "Någon",
"startSilentDescription": "Anslut till mötet igen för att aktivera ljud",
@@ -746,6 +778,7 @@
"headings": {
"lobby": "Väntrum ({{count}})",
"participantsList": "Mötesdeltagare ({{count}})",
"visitors": "Gäster ({{count}})",
"waitingLobby": "Väntar i väntrum ({{count}})"
},
"search": "Sök efter deltagare",
@@ -753,6 +786,7 @@
},
"passwordDigitsOnly": "Ange max {{number}} siffror",
"passwordSetRemotely": "satt av en annan deltagare",
"pinParticipant": "{{participantName}} - Fäst",
"pinnedParticipant": "Deltagaren är fäst",
"polls": {
"answer": {
@@ -837,9 +871,11 @@
"lookGood": "Din mikrofon fungerar som den ska",
"or": "eller",
"premeeting": "Förmöte",
"proceedAnyway": "Fortsätt ändå",
"screenSharingError": "Skärmdelningsfel:",
"showScreen": "Aktivera skärmen före mötet",
"startWithPhone": "Börja med telefonljud",
"unsafeRoomConsent": "Jag förstår riskerna, jag vill vara med på mötet",
"videoOnlyError": "Videofel:",
"videoTrackError": "Det gick inte att skapa videospår.",
"viewAllNumbers": "visa alla nummer"
@@ -858,9 +894,6 @@
"rejected": "Avvisad",
"ringing": "Ringer..."
},
"privacyView": {
"title": "Privat"
},
"profile": {
"avatar": "avatar",
"setDisplayNameLabel": "Ange ditt visningsnamn",
@@ -869,7 +902,7 @@
"title": "Profil"
},
"raisedHand": "Räck upp handen",
"raisedHandsLabel": "Antal upphöjda händer",
"raisedHandsLabel": "Antal uppräckta händer",
"record": {
"already": {
"linked": "Mötet är redan länkat till detta Salesforce-objekt."
@@ -914,6 +947,7 @@
"localRecordingVideoWarning": "För att spela in din video måste du ha den på när du startar inspelningen",
"localRecordingWarning": "Se till att du väljer den aktuella fliken för att kunna använda rätt video och ljud. Inspelningen är för närvarande begränsad till 1 GB, vilket är cirka 100 minuter.",
"loggedIn": "Inloggad som {{userName}}",
"noMicPermission": "Mikrofonspåret kunde inte skapas. Vänligen ge tillstånd att använda mikrofonen.",
"noStreams": "Ingen ljud- eller videoström upptäcktes.",
"off": "Inspelningen avslutades",
"offBy": "{{name}} avslutade inspelningen",
@@ -943,10 +977,17 @@
"security": {
"about": "Du kan lägga till ett $t(lockRoomPassword) till ditt möte. Deltagarna måste ange $t(lockRoomPassword) innan de får gå med i mötet.",
"aboutReadOnly": "Moderatorn kan lägga till ett $t(lockRoomPassword) till mötet. Deltagarna måste ange $t(lockRoomPassword) innan de får gå med i mötet.",
"insecureRoomNameWarning": "Rummets namn är osäkert. Oönskade deltagare kan gå med i din konferens. Överväg att säkra ditt möte med hjälp av säkerhetsknappen.",
"title": "Säkerhetsalternativ"
"insecureRoomNameWarningNative": "Rumsnamnet är osäkert. Oönskade deltagare kan gå med i ditt möte. {{recommendAction}} Läs mer om att säkra ditt möte",
"insecureRoomNameWarningWeb": "Rumsnamnet är osäkert. Oönskade deltagare kan gå med i ditt möte. {{recommendAction}} Läs mer om hur du säkerställer att du möter <a href=\"{{securityUrl}}\" rel=\"security\"-målet =\"_blank\">här</a>.",
"title": "Säkerhetsalternativ",
"unsafeRoomActions": {
"meeting": "Överväg att göra ditt möte säkrare med hjälp av säkerhetsknappen.",
"prejoin": "Överväg att använda ett mer unikt mötesnamn.",
"welcome": "Överväg att använda ett mer unikt mötesnamn, eller välj ett av förslagen."
}
},
"settings": {
"audio": "Ljud",
"buttonLabel": "Inställningar",
"calendar": {
"about": "Kalenderintegrationen med {{appName}} används för att hämta din kalender på ett säkert sätt så att den kan läsa framtida händelser.",
@@ -967,9 +1008,11 @@
"maxStageParticipants": "Maximalt antal deltagare som kan fästas på huvudscenen",
"microphones": "Mikrofoner",
"moderator": "Moderator",
"moderatorOptions": "Moderatoralternativ",
"more": "Mer",
"name": "Namn",
"noDevice": "Inga enheter",
"notifications": "Notifikationer",
"participantJoined": "Deltagare ansluten",
"participantKnocking": "Deltagare har anslutit till lobbyn",
"participantLeft": "Deltagare lämnat mötet",
@@ -980,13 +1023,14 @@
"selectCamera": "Kamera",
"selectMic": "Mikrofon",
"selfView": "Självvy",
"sounds": "Ljud",
"shortcuts": "Genvägar",
"speakers": "Högtalare",
"startAudioMuted": "Alla börjar tystade",
"startReactionsMuted": "Stäng av reaktionsljud för alla",
"startVideoMuted": "Alla börjar osynliga",
"talkWhileMuted": "Prata medan din ljud är inaktiverad",
"title": "Inställningar"
"title": "Inställningar",
"video": "Video"
},
"settingsView": {
"advanced": "Avancerat",
@@ -1003,6 +1047,7 @@
"displayName": "Skärmnamn",
"displayNamePlaceholderText": "Exempel: John Doe",
"email": "E-post",
"emailPlaceholderText": "mejl@exempel.se",
"goTo": "Gå till",
"header": "Inställningar",
"help": "Hjälp",
@@ -1060,69 +1105,87 @@
"audioOnly": "Slå av eller på ljudet",
"audioRoute": "Välj ljudenhet",
"boo": "Bua",
"breakoutRoom": "Gå med i/lämna grupprum",
"breakoutRoom": "Anslut eller lämna grupprum",
"callQuality": "Hantera videokvalitet",
"carmode": "Billäge",
"cc": "Slå av eller på undertexter",
"chat": "Öppna eller stäng chattfönster",
"clap": "Klappa",
"collapse": "Kollaps",
"document": "Öppna eller stäng delat dokument",
"download": "Ladda ner app",
"clap": "Applådera",
"closeChat": "Stäng chatten",
"closeMoreActions": "Stäng menyn för fler åtgärder",
"closeParticipantsPane": "Stäng deltagarfönstret",
"collapse": "Minimera",
"document": "Växla delat dokument",
"documentClose": "Stäng delat dokument",
"documentOpen": "Öppna delat dokument",
"download": "Ladda ner våra appar",
"embedMeeting": "Bädda in möte",
"endConference": "Avsluta mötet för alla",
"expand": "Expandera",
"feedback": "Lämna återkoppling",
"fullScreen": "Öppna eller stäng fullskärm",
"giphy": "Växla GIPHY meny",
"grantModerator": "Godkänn moderator",
"hangup": "Lämna samtalet",
"endConference": "Avsluta möte för alla",
"enterFullScreen": "Visa helskärm",
"enterTileView": "Öppna sida vid sida",
"exitFullScreen": "Avsluta helskärm",
"exitTileView": "Avsluta sida vid sida",
"expand": "Utöka",
"feedback": "Ge feedback",
"fullScreen": "Växla helskärm",
"giphy": "Växla GIPHY-menyn",
"grantModerator": "Tilldela moderatorrättigheter",
"hangup": "Lämna mötet",
"heading": "Verktygsfält",
"help": "Hjälp",
"invite": "Bjud in andra",
"hideWhiteboard": "Dölj whiteboard",
"invite": "Bjud in personer",
"kick": "Sparka ut deltagare",
"laugh": "Skratta",
"leaveConference": "Lämna möte",
"leaveConference": "Lämna mötet",
"like": "Tummen upp",
"linkToSalesforce": "Länk till Salesforce",
"lobbyButton": "Aktivera/inaktivera väntrumsläge",
"localRecording": "Öppna eller stäng lokala inspelningsverktyg",
"lockRoom": "Slå av eller på möteslösenord",
"moreActions": "Öppna eller stäng menyn för fler åtgärder",
"moreActionsMenu": "Meny för fler åtgärder",
"lobbyButton": "Aktivera / inaktivera lobbyläge",
"localRecording": "Växla lokala inspelningskontroller",
"lockRoom": "Växla möteslösenord",
"lowerHand": "Sänk din hand",
"moreActions": "Fler åtgärder",
"moreActionsMenu": "Menyn Fler åtgärder",
"moreOptions": "Visa fler alternativ",
"mute": "Slå av eller på ljud",
"muteEveryone": "Tysta alla",
"muteEveryoneElse": "Inkativerad ljud för alla andra",
"mute": "Mute",
"muteEveryone": "Stäng av ljudet för alla",
"muteEveryoneElse": "Stäng av ljudet för alla andra",
"muteEveryoneElsesVideoStream": "Stoppa alla andras video",
"muteEveryonesVideoStream": "Stoppa allas video",
"noiseSuppression": "Brusreducering",
"participants": "Deltagare",
"pip": "Öppna eller stäng bild-i-bild-läge",
"noiseSuppression": "Brusdämpning",
"openChat": "Öppna chatt",
"participants": "Öppna deltagarfönstret",
"pip": "Växla bild-i-bild-läge",
"privateMessage": "Skicka privat meddelande",
"profile": "Redigera din profil",
"raiseHand": "Räck upp eller ta ner handen",
"reactionsMenu": "Öppna7ständ meny för reaktioner",
"recording": "Slå av eller på inspelning",
"remoteMute": "Tysta deltagare",
"remoteVideoMute": "Inaktivera kamera för deltagare",
"raiseHand": "Räck upp handen",
"reactions": "Reaktioner",
"reactionsMenu": "Reaktionsmeny",
"recording": "Växla inspelning",
"remoteMute": "Ljud av deltagare",
"remoteVideoMute": "Inaktivera kameran för deltagaren",
"security": "Säkerhetsalternativ",
"selectBackground": "Välj bakgrund",
"selfView": "Växla självvy",
"shareRoom": "Bjud in någon",
"shareYourScreen": "Slå av eller på skärmdelning",
"shareYourScreen": "Börja dela din skärm",
"shareaudio": "Dela ljud",
"sharedvideo": "Slå av eller på videodelning",
"shortcuts": "Stäng eller öppna genvägar",
"sharedvideo": "Dela video",
"shortcuts": "Växla genvägar",
"show": "Visa på scenen",
"silence": "Tyst läge",
"speakerStats": "Stäng eller öppna talarstatistik",
"surprised": "Överaskning",
"tileView": "Öppna eller stäng panelvyn",
"showWhiteboard": "Visa whiteboard",
"silence": "Tystnad",
"speakerStats": "Växla deltagarstatistik",
"stopScreenSharing": "Sluta dela din skärm",
"stopSharedVideo": "Stoppa video",
"surprised": "Förvånad",
"tileView": "Växla sida vid sida",
"toggleCamera": "Växla kamera",
"toggleFilmstrip": "Växla filmremsa",
"unmute": "Slå på ljudet",
"videoblur": "Växla videooskärpa",
"videomute": "Sätt på eller stäng av mikrofonen",
"whiteboard": "Visa/dölj whiteboardtavlan"
"videomute": "Stoppa kamera",
"videounmute": "Starta kameran"
},
"addPeople": "Lägg till personer i samtal",
"audioOnlyOff": "Avsluta ljudläget",
@@ -1135,6 +1198,7 @@
"chat": "Öppna / stäng chatten",
"clap": "Klappa",
"closeChat": "Stäng chatt",
"closeParticipantsPane": "Stäng deltagarrutan",
"closeReactionsMenu": "Stäng meny för reaktioner",
"disableNoiseSuppression": "Inaktivera brusreducering",
"disableReactionSounds": "Du kan inaktivera reaktionsljud för det här mötet",
@@ -1143,6 +1207,7 @@
"download": "Ladda ner vår app",
"e2ee": "End-to-End kryptering",
"embedMeeting": "Bädda in möte",
"enableNoiseSuppression": "Aktivera brusreducering",
"endConference": "Avsluta mötet för alla",
"enterFullScreen": "Visa fullskärm",
"enterTileView": "Öppna panelvy",
@@ -1192,6 +1257,7 @@
"reactionLike": "Skicka tummen upp",
"reactionSilence": "Skicka tyst reaktion",
"reactionSurprised": "Skicka reaktionen överaskad",
"reactions": "Reaktioner",
"security": "Säkerhetsalternativ",
"selectBackground": "Välj bakgrund",
"shareRoom": "Bjud in någon",
@@ -1211,11 +1277,13 @@
"talkWhileMutedPopup": "Försöker du tala? Din mikrofon är tystad.",
"tileViewToggle": "Öppna eller stäng panelvyn",
"toggleCamera": "Byta kamera",
"unmute": "Slå på ljud",
"videoSettings": "Video inställningar",
"videomute": "Aktivera / avaktivera kameran"
"videomute": "Inaktivera kameran",
"videounmute": "Aktivera kameran"
},
"transcribing": {
"ccButtonTooltip": "Starta / Avsluta undertexter",
"ccButtonTooltip": "Aktivera / Inaktivera undertexter",
"error": "Transkriberingen misslyckades. Försök igen.",
"expandedLabel": "Transkribering är aktiverad",
"failedToStart": "Det gick inte att starta transkribering",
@@ -1230,6 +1298,7 @@
"subtitlesOff": "Av",
"tr": "TR"
},
"unpinParticipant": "Lossa deltagare",
"userMedia": {
"androidGrantPermissions": "Välj <b><i>Tillåt</i></b> när din webbläsare begär åtkomst.",
"chromeGrantPermissions": "Välj <b><i>Tillåt</i></b> när din webbläsare begär åtkomst.",
@@ -1268,9 +1337,11 @@
"ldTooltip": "Titta på lågupplöst video",
"lowDefinition": "Låg upplösning",
"performanceSettings": "Prestandainställningar",
"recording": "Inspelning pågår",
"sd": "SD",
"sdTooltip": "Titta på video med standardupplösning",
"standardDefinition": "Normal upplösning"
"standardDefinition": "Normal upplösning",
"streaming": "Streaming pågår"
},
"videothumbnail": {
"connectionInfo": "Anslutningsinformation",
@@ -1282,6 +1353,7 @@
"grantModerator": "Godkänn moderator",
"hideSelfView": "Dölj självvyn",
"kick": "Sparka ut",
"mirrorVideo": "Spegelvänd video",
"moderator": "Moderator",
"mute": "Deltagaren har avstängd mikrofon",
"muted": "Tystad",
@@ -1291,8 +1363,9 @@
"show": "Visa på scenen",
"showSelfView": "Visa självvy",
"unpinFromStage": "Ta loss",
"videoMuted": "kamera inaktiverad",
"videomute": "Deltagaren har stäng av kameran"
"verify": "Verifiera",
"videoMuted": "Kamera inaktiverad",
"videomute": "Deltagaren har stängt av kameran"
},
"virtualBackground": {
"addBackground": "Lägg till bakgrund",
@@ -1318,6 +1391,14 @@
"webAssemblyWarning": "WebAssembly stöds inte",
"webAssemblyWarningDescription": "WebAssembly inaktiverad eller stöds inte av den här webbläsaren"
},
"visitors": {
"chatIndicator": "(besökare)",
"labelTooltip": "Antal besökare: {{count}}",
"notification": {
"description": "Räck upp handen för att delta",
"title": "Du är en besökare i mötet"
}
},
"volumeSlider": "Volymreglage",
"welcomepage": {
"accessibilityLabel": {
@@ -1338,6 +1419,7 @@
"go": "KÖR",
"goSmall": "BÖRJA",
"headerSubtitle": "Säkra möten med hög kvalitet",
"headerTitle": "Jitsi Meet",
"info": "Info",
"jitsiOnMobile": "Jitsi på mobilen - ladda ner våra appar och starta ett möte var som helst",
"join": "Gå med",
@@ -1349,6 +1431,7 @@
"microsoftLogo": "Microsoft logotyp",
"policyLogo": "Policy-logotyp"
},
"meetingsAccessibilityLabel": "Möten",
"mobileDownLoadLinkAndroid": "Ladda ner mobilappen för Android",
"mobileDownLoadLinkFDroid": "Ladda ner mobilappen för F-droid",
"mobileDownLoadLinkIos": "Ladda ner mobilappen för iOS",
@@ -1357,6 +1440,7 @@
"recentList": "Tidigare",
"recentListDelete": "Radera",
"recentListEmpty": "Inga tidigare möten. Chatta med ditt team och hitta alla tidigare möten där.",
"recentMeetings": "Dina senaste möten",
"reducedUIText": "Välkommen till {{app}}!",
"roomNameAllowedChars": "Mötesnamn kan inte innehålla dessa tecken: ?, &,:, ', \",%, #.",
"roomname": "Skriv in rumsnamn",
@@ -1365,6 +1449,12 @@
"settings": "Inställningar",
"startMeeting": "Starta möte",
"terms": "Villkor",
"title": "Säkra, välutrustade och helt kostnadsfria videokonferenser"
"title": "Säkra, välutrustade och helt kostnadsfria videokonferenser",
"upcomingMeetings": "Dina kommande möten"
},
"whiteboard": {
"accessibilityLabel": {
"heading": "Whiteboard"
}
}
}

View File

@@ -1,5 +1,8 @@
{
"addPeople": {
"accessibilityLabel": {
"meetingLink": "Meeting link: {{url}}"
},
"add": "Invite",
"addContacts": "Invite your contacts",
"contacts": "contacts",
@@ -39,6 +42,18 @@
"audioOnly": {
"audioOnly": "Low bandwidth"
},
"bandwidthSettings": {
"assumedBandwidthBps": "e.g. 10000000 for 10 Mbps",
"assumedBandwidthBpsWarning": "Higher values might cause network issues.",
"customValue": "custom value",
"customValueEffect": "to set the actual bps value",
"leaveEmpty": "leave empty",
"leaveEmptyEffect": "to allow estimations to take place",
"possibleValues": "Possible values",
"setAssumedBandwidthBps": "Assumed bandwidth (bps)",
"title": "Bandwidth settings",
"zeroEffect": "to disable video"
},
"breakoutRooms": {
"actions": {
"add": "Add breakout room",
@@ -242,6 +257,8 @@
"WaitingForHostTitle": "Waiting for the host ...",
"Yes": "Yes",
"accessibilityLabel": {
"Cancel": "Cancel (leave dialog)",
"Ok": "OK (save and leave dialog)",
"close": "Close dialog",
"liveStreaming": "Live Stream",
"sharingTabs": "Sharing options"
@@ -447,6 +464,9 @@
"title": "Embed this meeting"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "Your choice: {{rating}}"
},
"average": "Average",
"bad": "Bad",
"detailsLabel": "Tell us more about it.",
@@ -675,6 +695,7 @@
"connectedTwoMembers": "{{first}} and {{second}} joined the meeting",
"dataChannelClosed": "Video quality impaired",
"dataChannelClosedDescription": "The bridge channel has been disconnected and thus video quality is limited to its lowest setting.",
"disabledIframe": "Embedding is only meant for demo purposes, so this call will disconnect in {{timeout}} minutes.",
"disconnected": "disconnected",
"displayNotifications": "Display notifications for",
"dontRemindMe": "Do not remind me",
@@ -869,9 +890,11 @@
"lookGood": "Your microphone is working properly",
"or": "or",
"premeeting": "Pre meeting",
"proceedAnyway": "Proceed anyway",
"screenSharingError": "Screen sharing error:",
"showScreen": "Enable pre meeting screen",
"startWithPhone": "Start with phone audio",
"unsafeRoomConsent": "I understand the risks, I want to join the meeting",
"videoOnlyError": "Video error:",
"videoTrackError": "Could not create video track.",
"viewAllNumbers": "view all numbers"
@@ -973,8 +996,14 @@
"security": {
"about": "You can add a $t(lockRoomPassword) to your meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
"aboutReadOnly": "Moderator participants can add a $t(lockRoomPassword) to the meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
"insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button.",
"title": "Security Options"
"insecureRoomNameWarningNative": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting ",
"insecureRoomNameWarningWeb": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">here</a>.",
"title": "Security Options",
"unsafeRoomActions": {
"meeting": "Consider securing your meeting using the security button.",
"prejoin": "Consider using a more unique meeting name.",
"welcome": "Consider using a more unique meeting name, or pick one of the suggestions."
}
},
"settings": {
"audio": "Audio",
@@ -1044,13 +1073,14 @@
"links": "Links",
"privacy": "Privacy",
"profileSection": "Profile",
"sdkVersion": "SDK version",
"serverURL": "Server URL",
"showAdvanced": "Show advanced settings",
"startCarModeInLowBandwidthMode": "Start car mode in low bandwidth mode",
"startWithAudioMuted": "Start with audio muted",
"startWithVideoMuted": "Start with video muted",
"terms": "Terms",
"version": "Version"
"version": "App version"
},
"share": {
"dialInfoText": "\n\n=====\n\nJust want to dial in on your phone?\n\n{{defaultDialInNumber}}Click this link to see the dial in phone numbers for this meeting\n{{dialInfoPageUrl}}",
@@ -1142,6 +1172,7 @@
"muteEveryoneElse": "Mute everyone else",
"muteEveryoneElsesVideoStream": "Stop everyone else's video",
"muteEveryonesVideoStream": "Stop everyone's video",
"muteGUMPending": "Connecting your microphone",
"noiseSuppression": "Noise suppression",
"openChat": "Open chat",
"participants": "Open participants pane",
@@ -1149,6 +1180,7 @@
"privateMessage": "Send private message",
"profile": "Edit your profile",
"raiseHand": "Raise your hand",
"reactions": "Reactions",
"reactionsMenu": "Reactions menu",
"recording": "Toggle recording",
"remoteMute": "Mute participant",
@@ -1174,6 +1206,7 @@
"unmute": "Unmute",
"videoblur": "Toggle video blur",
"videomute": "Stop camera",
"videomuteGUMPending": "Connecting your camera",
"videounmute": "Start camera"
},
"addPeople": "Add people to your call",
@@ -1224,6 +1257,7 @@
"mute": "Mute",
"muteEveryone": "Mute everyone",
"muteEveryonesVideo": "Disable everyone's camera",
"muteGUMPending": "Connecting your microphone",
"noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider switching the device.",
"noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider switching to the suggested device.",
"noAudioSignalDialInDesc": "You can also dial-in using:",
@@ -1246,6 +1280,7 @@
"reactionLike": "Send thumbs up reaction",
"reactionSilence": "Send silence reaction",
"reactionSurprised": "Send surprised reaction",
"reactions": "Reactions",
"security": "Security options",
"selectBackground": "Select background",
"shareRoom": "Invite someone",
@@ -1268,6 +1303,7 @@
"unmute": "Unmute",
"videoSettings": "Video settings",
"videomute": "Stop camera",
"videomuteGUMPending": "Connecting your camera",
"videounmute": "Start camera"
},
"transcribing": {
@@ -1314,7 +1350,7 @@
"audioOnly": "AUD",
"audioOnlyExpanded": "You are in low bandwidth mode. In this mode you will receive only audio and screen sharing.",
"bestPerformance": "Best performance",
"callQuality": "Video Quality",
"callQuality": "Video Quality (0 for best performance, 3 for highest quality)",
"hd": "HD",
"hdTooltip": "Viewing high definition video",
"highDefinition": "High definition",
@@ -1356,6 +1392,10 @@
"videomute": "Participant has stopped the camera"
},
"virtualBackground": {
"accessibilityLabel": {
"currentBackground": "Current background: {{background}}",
"selectBackground": "Select a background"
},
"addBackground": "Add background",
"apply": "Apply",
"backgroundEffectError": "Failed to apply background effect.",

View File

@@ -1,5 +1,4 @@
// @flow
/* global APP */
import Logger from '@jitsi/logger';
import { createApiEvent } from '../../react/features/analytics/AnalyticsEvents';
@@ -18,12 +17,13 @@ import { isEnabledFromState } from '../../react/features/av-moderation/functions
import {
endConference,
sendTones,
setAssumedBandwidthBps,
setFollowMe,
setLocalSubject,
setPassword,
setSubject
} from '../../react/features/base/conference/actions';
import { getCurrentConference } from '../../react/features/base/conference/functions';
import { getCurrentConference, isP2pActive } from '../../react/features/base/conference/functions';
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';
@@ -113,14 +113,16 @@ import { isAudioMuteButtonDisabled } from '../../react/features/toolbox/function
import { setTileView, toggleTileView } from '../../react/features/video-layout/actions.any';
import { muteAllParticipants } from '../../react/features/video-menu/actions';
import { setVideoQuality } from '../../react/features/video-quality/actions';
import { toggleWhiteboard } from '../../react/features/whiteboard/actions.any';
import { getJitsiMeetTransport } from '../transport';
import { API_ID, ENDPOINT_TEXT_MESSAGE_NAME } from './constants';
import {
API_ID,
ENDPOINT_TEXT_MESSAGE_NAME
} from './constants';
const logger = Logger.getLogger(__filename);
declare var APP: Object;
/**
* List of the available commands.
*/
@@ -310,6 +312,17 @@ function initCommands() {
APP.store.dispatch(sendTones(tones, duration, pause));
},
'set-assumed-bandwidth-bps': value => {
logger.debug('Set assumed bandwidth bps command received', value);
if (typeof value !== 'number' || isNaN(value)) {
logger.error('Assumed bandwidth bps must be a number.');
return;
}
APP.store.dispatch(setAssumedBandwidthBps(value));
},
'set-follow-me': value => {
logger.debug('Set follow me command received');
@@ -323,15 +336,16 @@ function initCommands() {
},
'set-large-video-participant': (participantId, videoType) => {
logger.debug('Set large video participant command received');
const { getState, dispatch } = APP.store;
if (!participantId) {
sendAnalytics(createApiEvent('largevideo.participant.set'));
APP.store.dispatch(selectParticipantInLargeVideo());
dispatch(selectParticipantInLargeVideo());
return;
}
const state = APP.store.getState();
const state = getState();
const participant = videoType === VIDEO_TYPE.DESKTOP
? getVirtualScreenshareParticipantByOwnerId(state, participantId)
: getParticipantById(state, participantId);
@@ -342,8 +356,9 @@ function initCommands() {
return;
}
dispatch(setTileView(false));
sendAnalytics(createApiEvent('largevideo.participant.set'));
APP.store.dispatch(selectParticipantInLargeVideo(participant.id));
dispatch(selectParticipantInLargeVideo(participant.id));
},
'set-participant-volume': (participantId, volume) => {
APP.store.dispatch(setVolume(participantId, volume));
@@ -812,6 +827,9 @@ function initCommands() {
} else {
logger.error(' End Conference not supported');
}
},
'toggle-whiteboard': () => {
APP.store.dispatch(toggleWhiteboard());
}
};
transport.on('event', ({ data, name }) => {
@@ -963,6 +981,10 @@ function initCommands() {
callback(getRoomsInfo(APP.store.getState()));
break;
}
case 'get-p2p-status': {
callback(isP2pActive(APP.store.getState()));
break;
}
default:
return false;
}
@@ -1009,7 +1031,7 @@ function toggleScreenSharing(enable) {
* @param {MouseEvent} event - The mouse event to sanitize.
* @returns {Object}
*/
function sanitizeMouseEvent(event: MouseEvent) {
function sanitizeMouseEvent(event) {
const {
clientX,
clientY,
@@ -1047,7 +1069,7 @@ function sanitizeMouseEvent(event: MouseEvent) {
* Jitsi Meet.
*/
class API {
_enabled: boolean;
_enabled;
/**
* Initializes the API. Setups message event listeners that will receive
@@ -1082,7 +1104,7 @@ class API {
* otherwise.
* @returns {void}
*/
notifyLargeVideoVisibilityChanged(isHidden: boolean) {
notifyLargeVideoVisibilityChanged(isHidden) {
this._sendEvent({
name: 'large-video-visibility-changed',
isVisible: !isHidden
@@ -1096,7 +1118,7 @@ class API {
* @param {Object} event - The message to pass onto spot.
* @returns {void}
*/
sendProxyConnectionEvent(event: Object) {
sendProxyConnectionEvent(event) {
this._sendEvent({
name: 'proxy-connection-event',
...event
@@ -1109,7 +1131,7 @@ class API {
* @param {Object} event - The event to be sent.
* @returns {void}
*/
_sendEvent(event: Object = {}) {
_sendEvent(event = {}) {
if (this._enabled) {
transport.sendEvent(event);
}
@@ -1122,7 +1144,7 @@ class API {
* @param {boolean} isOpen - True if the chat panel is open.
* @returns {void}
*/
notifyChatUpdated(unreadCount: number, isOpen: boolean) {
notifyChatUpdated(unreadCount, isOpen) {
this._sendEvent({
name: 'chat-updated',
unreadCount,
@@ -1137,7 +1159,7 @@ class API {
* @param {boolean} privateMessage - True if the message was a private message.
* @returns {void}
*/
notifySendingChatMessage(message: string, privateMessage: boolean) {
notifySendingChatMessage(message, privateMessage) {
this._sendEvent({
name: 'outgoing-message',
message,
@@ -1151,7 +1173,7 @@ class API {
* @param {MouseEvent} event - The mousemove event.
* @returns {void}
*/
notifyMouseEnter(event: MouseEvent) {
notifyMouseEnter(event) {
this._sendEvent({
name: 'mouse-enter',
event: sanitizeMouseEvent(event)
@@ -1164,7 +1186,7 @@ class API {
* @param {MouseEvent} event - The mousemove event.
* @returns {void}
*/
notifyMouseLeave(event: MouseEvent) {
notifyMouseLeave(event) {
this._sendEvent({
name: 'mouse-leave',
event: sanitizeMouseEvent(event)
@@ -1177,7 +1199,7 @@ class API {
* @param {MouseEvent} event - The mousemove event.
* @returns {void}
*/
notifyMouseMove(event: MouseEvent) {
notifyMouseMove(event) {
this._sendEvent({
name: 'mouse-move',
event: sanitizeMouseEvent(event)
@@ -1191,7 +1213,7 @@ class API {
* @param {boolean} enabled - Whether or not the new moderation status is enabled.
* @returns {void}
*/
notifyModerationChanged(mediaType: string, enabled: boolean) {
notifyModerationChanged(mediaType, enabled) {
this._sendEvent({
name: 'moderation-status-changed',
mediaType,
@@ -1206,7 +1228,7 @@ class API {
* @param {string} mediaType - Media type for which the participant was approved.
* @returns {void}
*/
notifyParticipantApproved(participantId: string, mediaType: string) {
notifyParticipantApproved(participantId, mediaType) {
this._sendEvent({
name: 'moderation-participant-approved',
id: participantId,
@@ -1221,7 +1243,7 @@ class API {
* @param {string} mediaType - Media type for which the participant was rejected.
* @returns {void}
*/
notifyParticipantRejected(participantId: string, mediaType: string) {
notifyParticipantRejected(participantId, mediaType) {
this._sendEvent({
name: 'moderation-participant-rejected',
id: participantId,
@@ -1237,7 +1259,7 @@ class API {
*
* @returns {void}
*/
notifyNotificationTriggered(title: string, description: string) {
notifyNotificationTriggered(title, description) {
this._sendEvent({
description,
name: 'notification-triggered',
@@ -1251,7 +1273,7 @@ class API {
* @param {number} videoQuality - The video quality. The number represents the maximum height of the video streams.
* @returns {void}
*/
notifyVideoQualityChanged(videoQuality: number) {
notifyVideoQualityChanged(videoQuality) {
this._sendEvent({
name: 'video-quality-changed',
videoQuality
@@ -1266,9 +1288,7 @@ class API {
* @returns {void}
*/
notifyReceivedChatMessage(
{ body, id, nick, privateMessage, ts }: {
body: *, id: string, nick: string, privateMessage: boolean, ts: *
} = {}) {
{ body, id, nick, privateMessage, ts } = {}) {
if (APP.conference.isLocalId(id)) {
return;
}
@@ -1291,7 +1311,7 @@ class API {
* @param {Object} props - The display name of the user.
* @returns {void}
*/
notifyUserJoined(id: string, props: Object) {
notifyUserJoined(id, props) {
this._sendEvent({
name: 'participant-joined',
id,
@@ -1306,7 +1326,7 @@ class API {
* @param {string} id - User id.
* @returns {void}
*/
notifyUserLeft(id: string) {
notifyUserLeft(id) {
this._sendEvent({
name: 'participant-left',
id
@@ -1321,7 +1341,7 @@ class API {
* @param {string} role - The new user role.
* @returns {void}
*/
notifyUserRoleChanged(id: string, role: string) {
notifyUserRoleChanged(id, role) {
this._sendEvent({
name: 'participant-role-changed',
id,
@@ -1337,7 +1357,7 @@ class API {
* @param {string} avatarURL - The new avatar URL of the participant.
* @returns {void}
*/
notifyAvatarChanged(id: string, avatarURL: string) {
notifyAvatarChanged(id, avatarURL) {
this._sendEvent({
name: 'avatar-changed',
avatarURL,
@@ -1352,7 +1372,7 @@ class API {
* @param {Object} data - The event data.
* @returns {void}
*/
notifyEndpointTextMessageReceived(data: Object) {
notifyEndpointTextMessageReceived(data) {
this._sendEvent({
name: 'endpoint-text-message-received',
data
@@ -1366,7 +1386,7 @@ class API {
* @param {string} faceExpression - Detected face expression.
* @returns {void}
*/
notifyFaceLandmarkDetected(faceBox: Object, faceExpression: string) {
notifyFaceLandmarkDetected(faceBox, faceExpression) {
this._sendEvent({
name: 'face-landmark-detected',
faceBox,
@@ -1380,7 +1400,7 @@ class API {
* @param {Object} data - The event data.
* @returns {void}
*/
notifySharingParticipantsChanged(data: Object) {
notifySharingParticipantsChanged(data) {
this._sendEvent({
name: 'content-sharing-participants-changed',
data
@@ -1394,7 +1414,7 @@ class API {
* @param {Object} devices - The new device list.
* @returns {void}
*/
notifyDeviceListChanged(devices: Object) {
notifyDeviceListChanged(devices) {
this._sendEvent({
name: 'device-list-changed',
devices
@@ -1412,8 +1432,8 @@ class API {
* @returns {void}
*/
notifyDisplayNameChanged(
id: string,
{ displayName, formattedDisplayName }: Object) {
id,
{ displayName, formattedDisplayName }) {
this._sendEvent({
name: 'display-name-change',
displayname: displayName,
@@ -1431,8 +1451,8 @@ class API {
* @returns {void}
*/
notifyEmailChanged(
id: string,
{ email }: Object) {
id,
{ email }) {
this._sendEvent({
name: 'email-change',
email,
@@ -1444,10 +1464,10 @@ class API {
* Notify external application (if API is enabled) that the an error has been logged.
*
* @param {string} logLevel - The message log level.
* @param {Array} args - Array of strings composing the log message.
* @param {Array<string>} args - Array of strings composing the log message.
* @returns {void}
*/
notifyLog(logLevel: string, args: Array<string>) {
notifyLog(logLevel, args) {
this._sendEvent({
name: 'log',
logLevel,
@@ -1465,7 +1485,7 @@ class API {
* user and the type of the room.
* @returns {void}
*/
notifyConferenceJoined(roomName: string, id: string, props: Object) {
notifyConferenceJoined(roomName, id, props) {
this._sendEvent({
name: 'video-conference-joined',
roomName,
@@ -1480,7 +1500,7 @@ class API {
* @param {string} roomName - User id.
* @returns {void}
*/
notifyConferenceLeft(roomName: string) {
notifyConferenceLeft(roomName) {
this._sendEvent({
name: 'video-conference-left',
roomName
@@ -1495,7 +1515,7 @@ class API {
*
* @returns {void}
*/
notifyDataChannelClosed(code: number, reason: string) {
notifyDataChannelClosed(code, reason) {
this._sendEvent({
name: 'data-channel-closed',
code,
@@ -1538,7 +1558,7 @@ class API {
* @param {boolean} muted - The new muted status.
* @returns {void}
*/
notifyAudioMutedStatusChanged(muted: boolean) {
notifyAudioMutedStatusChanged(muted) {
this._sendEvent({
name: 'audio-mute-status-changed',
muted
@@ -1552,7 +1572,7 @@ class API {
* @param {boolean} muted - The new muted status.
* @returns {void}
*/
notifyVideoMutedStatusChanged(muted: boolean) {
notifyVideoMutedStatusChanged(muted) {
this._sendEvent({
name: 'video-mute-status-changed',
muted
@@ -1566,7 +1586,7 @@ class API {
* @param {boolean} available - True if available and false otherwise.
* @returns {void}
*/
notifyAudioAvailabilityChanged(available: boolean) {
notifyAudioAvailabilityChanged(available) {
audioAvailable = available;
this._sendEvent({
name: 'audio-availability-changed',
@@ -1581,7 +1601,7 @@ class API {
* @param {boolean} available - True if available and false otherwise.
* @returns {void}
*/
notifyVideoAvailabilityChanged(available: boolean) {
notifyVideoAvailabilityChanged(available) {
videoAvailable = available;
this._sendEvent({
name: 'video-availability-changed',
@@ -1596,7 +1616,7 @@ class API {
* @param {string} id - User id of the new on stage participant.
* @returns {void}
*/
notifyOnStageParticipantChanged(id: string) {
notifyOnStageParticipantChanged(id) {
this._sendEvent({
name: 'on-stage-participant-changed',
id
@@ -1610,7 +1630,7 @@ class API {
* @param {boolean} isVisible - Whether the prejoin video is visible.
* @returns {void}
*/
notifyPrejoinVideoVisibilityChanged(isVisible: boolean) {
notifyPrejoinVideoVisibilityChanged(isVisible) {
this._sendEvent({
name: 'on-prejoin-video-changed',
isVisible
@@ -1644,7 +1664,7 @@ class API {
* @param {string} message - Additional information about the error.
* @returns {void}
*/
notifyOnCameraError(type: string, message: string) {
notifyOnCameraError(type, message) {
this._sendEvent({
name: 'camera-error',
type,
@@ -1660,7 +1680,7 @@ class API {
* @param {string} message - Additional information about the error.
* @returns {void}
*/
notifyOnMicError(type: string, message: string) {
notifyOnMicError(type, message) {
this._sendEvent({
name: 'mic-error',
type,
@@ -1676,7 +1696,7 @@ class API {
* @param {string} error - A failure message, if any.
* @returns {void}
*/
notifyFeedbackSubmitted(error: string) {
notifyFeedbackSubmitted(error) {
this._sendEvent({
name: 'feedback-submitted',
error
@@ -1701,7 +1721,7 @@ class API {
* be displayed or hidden.
* @returns {void}
*/
notifyFilmstripDisplayChanged(visible: boolean) {
notifyFilmstripDisplayChanged(visible) {
this._sendEvent({
name: 'filmstrip-display-changed',
visible
@@ -1718,7 +1738,7 @@ class API {
* other participant.
* @returns {void}
*/
notifyKickedOut(kicked: Object, kicker: Object) {
notifyKickedOut(kicked, kicker) {
this._sendEvent({
name: 'participant-kicked-out',
kicked,
@@ -1747,7 +1767,7 @@ class API {
* share is capturing.
* @returns {void}
*/
notifyScreenSharingStatusChanged(on: boolean, details: Object) {
notifyScreenSharingStatusChanged(on, details) {
this._sendEvent({
name: 'screen-sharing-status-changed',
on,
@@ -1762,7 +1782,7 @@ class API {
* @param {string} id - Id of the dominant participant.
* @returns {void}
*/
notifyDominantSpeakerChanged(id: string) {
notifyDominantSpeakerChanged(id) {
this._sendEvent({
name: 'dominant-speaker-changed',
id
@@ -1776,7 +1796,7 @@ class API {
* @param {string} subject - Conference subject.
* @returns {void}
*/
notifySubjectChanged(subject: string) {
notifySubjectChanged(subject) {
this._sendEvent({
name: 'subject-change',
subject
@@ -1791,7 +1811,7 @@ class API {
* otherwise.
* @returns {void}
*/
notifyTileViewChanged(enabled: boolean) {
notifyTileViewChanged(enabled) {
this._sendEvent({
name: 'tile-view-changed',
enabled
@@ -1804,7 +1824,7 @@ class API {
* @param {string} localStorageContent - The new localStorageContent.
* @returns {void}
*/
notifyLocalStorageChanged(localStorageContent: string) {
notifyLocalStorageChanged(localStorageContent) {
this._sendEvent({
name: 'local-storage-changed',
localStorageContent
@@ -1818,7 +1838,7 @@ class API {
* @param {boolean} handRaised - Whether user has raised hand.
* @returns {void}
*/
notifyRaiseHandUpdated(id: string, handRaised: boolean) {
notifyRaiseHandUpdated(id, handRaised) {
this._sendEvent({
name: 'raise-hand-updated',
handRaised,
@@ -1834,7 +1854,7 @@ class API {
* @param {string} error - Error type or null if success.
* @returns {void}
*/
notifyRecordingStatusChanged(on: boolean, mode: string, error?: string) {
notifyRecordingStatusChanged(on, mode, error) {
this._sendEvent({
name: 'recording-status-changed',
on,
@@ -1851,7 +1871,7 @@ class API {
* @param {number} ttl - The recording download link time to live.
* @returns {void}
*/
notifyRecordingLinkAvailable(link: string, ttl: number) {
notifyRecordingLinkAvailable(link, ttl) {
this._sendEvent({
name: 'recording-link-available',
link,
@@ -1865,7 +1885,7 @@ class API {
* @param {Object} participant - Participant data such as id and name.
* @returns {void}
*/
notifyKnockingParticipant(participant: Object) {
notifyKnockingParticipant(participant) {
this._sendEvent({
name: 'knocking-participant',
participant
@@ -1878,7 +1898,7 @@ class API {
* @param {Object} error - The error.
* @returns {void}
*/
notifyError(error: Object) {
notifyError(error) {
this._sendEvent({
name: 'error-occurred',
error
@@ -1892,7 +1912,7 @@ class API {
* @param {boolean} preventExecution - Whether execution of the button click was prevented or not.
* @returns {void}
*/
notifyToolbarButtonClicked(key: string, preventExecution: boolean) {
notifyToolbarButtonClicked(key, preventExecution) {
this._sendEvent({
name: 'toolbar-button-clicked',
key,
@@ -1906,7 +1926,7 @@ class API {
* @param {boolean} supported - If browser is supported or not.
* @returns {void}
*/
notifyBrowserSupport(supported: boolean) {
notifyBrowserSupport(supported) {
this._sendEvent({
name: 'browser-support',
supported
@@ -1993,6 +2013,50 @@ class API {
});
}
/**
* Notify external application (if API is enabled) if whiteboard state is
* changed.
*
* @param {WhiteboardStatus} status - The new whiteboard status.
* @returns {void}
*/
notifyWhiteboardStatusChanged(status) {
this._sendEvent({
name: 'whiteboard-status-changed',
status
});
}
/**
* Notify external application (if API is enabled) if non participant message
* is received.
*
* @param {string} id - The resource id of the sender.
* @param {Object} json - The json carried by the message.
* @returns {void}
*/
notifyNonParticipantMessageReceived(id, json) {
this._sendEvent({
name: 'non-participant-message-received',
id,
message: json
});
}
/**
* Notify the external application (if API is enabled) if the connection type changed.
*
* @param {boolean} isP2p - Whether the new connection is P2P.
* @returns {void}
*/
notifyP2pStatusChanged(isP2p) {
this._sendEvent({
name: 'p2p-status-changed',
isP2p
});
}
/**
* Disposes the allocated resources.
*

View File

@@ -15,3 +15,10 @@ export const API_ID = parseURLParams(window.location).jitsi_meet_external_api_id
* The payload name for the datachannel/endpoint text message event.
*/
export const ENDPOINT_TEXT_MESSAGE_NAME = 'endpoint-text-message';
/**
* The min value that can be set for the assumed bandwidth.
* Setting it to this value means not assuming any bandwidth,
* but rather allowing the estimations to take place.
*/
export const MIN_ASSUMED_BANDWIDTH_BPS = -1;

View File

@@ -36,7 +36,6 @@ const commands = {
cancelPrivateChat: 'cancel-private-chat',
closeBreakoutRoom: 'close-breakout-room',
displayName: 'display-name',
e2eeKey: 'e2ee-key',
endConference: 'end-conference',
email: 'email',
grantModerator: 'grant-moderator',
@@ -59,6 +58,7 @@ const commands = {
sendEndpointTextMessage: 'send-endpoint-text-message',
sendParticipantToRoom: 'send-participant-to-room',
sendTones: 'send-tones',
setAssumedBandwidthBps: 'set-assumed-bandwidth-bps',
setFollowMe: 'set-follow-me',
setLargeVideoParticipant: 'set-large-video-participant',
setMediaEncryptionKey: 'set-media-encryption-key',
@@ -89,7 +89,8 @@ const commands = {
toggleSubtitles: 'toggle-subtitles',
toggleTileView: 'toggle-tile-view',
toggleVirtualBackgroundDialog: 'toggle-virtual-background',
toggleVideo: 'toggle-video'
toggleVideo: 'toggle-video',
toggleWhiteboard: 'toggle-whiteboard'
};
/**
@@ -127,8 +128,10 @@ const events = {
'mouse-enter': 'mouseEnter',
'mouse-leave': 'mouseLeave',
'mouse-move': 'mouseMove',
'non-participant-message-received': 'nonParticipantMessageReceived',
'notification-triggered': 'notificationTriggered',
'outgoing-message': 'outgoingMessage',
'p2p-status-changed': 'p2pStatusChanged',
'participant-joined': 'participantJoined',
'participant-kicked-out': 'participantKickedOut',
'participant-left': 'participantLeft',
@@ -153,7 +156,8 @@ const events = {
'subject-change': 'subjectChange',
'suspend-detected': 'suspendDetected',
'tile-view-changed': 'tileViewChanged',
'toolbar-button-clicked': 'toolbarButtonClicked'
'toolbar-button-clicked': 'toolbarButtonClicked',
'whiteboard-status-changed': 'whiteboardStatusChanged'
};
/**
@@ -313,6 +317,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
* @param {string} [options.e2eeKey] - The key used for End-to-End encryption.
* THIS IS EXPERIMENTAL.
* @param {string} [options.release] - The key used for specifying release if enabled on the backend.
* @param {string} [options.sandbox] - Sandbox directive for the created iframe, if desired.
*/
constructor(domain, ...args) {
super();
@@ -330,7 +335,8 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
devices,
userInfo,
e2eeKey,
release
release,
sandbox = ''
} = parseArguments(args);
const localStorageContent = jitsiLocalStorage.getItem('jitsiLocalStorage');
@@ -348,7 +354,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
},
release
});
this._createIFrame(height, width, onload);
this._createIFrame(height, width, onload, sandbox);
this._transport = new Transport({
backend: new PostMessageTransportBackend({
postisOptions: {
@@ -381,21 +387,26 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
* parseSizeParam for format details.
* @param {Function} onload - The function that will listen
* for onload event.
* @param {string} sandbox - Sandbox directive for the created iframe, if desired.
* @returns {void}
*
* @private
*/
_createIFrame(height, width, onload) {
_createIFrame(height, width, onload, sandbox) {
const frameName = `jitsiConferenceFrame${id}`;
this._frame = document.createElement('iframe');
this._frame.allow = 'camera; microphone; display-capture; autoplay; clipboard-write; hid';
this._frame.allow = 'camera; microphone; display-capture; autoplay; clipboard-write; hid; screen-wake-lock';
this._frame.name = frameName;
this._frame.id = frameName;
this._setSize(height, width);
this._frame.setAttribute('allowFullScreen', 'true');
this._frame.style.border = 0;
if (sandbox) {
this._frame.sandbox = sandbox;
}
if (onload) {
// waits for iframe resources to load
// and fires event when it is done
@@ -551,7 +562,22 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
switch (name) {
case 'video-conference-joined': {
if (typeof this._tmpE2EEKey !== 'undefined') {
this.executeCommand(commands.e2eeKey, this._tmpE2EEKey);
const hexToBytes = hex => {
const bytes = [];
for (let c = 0; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substring(c, c + 2), 16));
}
return bytes;
};
this.executeCommand('setMediaEncryptionKey', JSON.stringify({
exportedKey: hexToBytes(this._tmpE2EEKey),
index: 0
}));
this._tmpE2EEKey = undefined;
}
@@ -669,7 +695,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
this._numberOfParticipants = allParticipants;
}
/**
* Returns the rooms info in the conference.
*
@@ -681,6 +706,17 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
});
}
/**
* Returns whether the conference is P2P.
*
* @returns {Promise}
*/
isP2pActive() {
return this._transport.sendRequest({
name: 'get-p2p-status'
});
}
/**
* Adds event listener to Meet Jitsi.
*

View File

@@ -1,5 +1,3 @@
// @flow
import Logger from '@jitsi/logger';
const logger = Logger.getLogger(__filename);
@@ -11,7 +9,7 @@ const logger = Logger.getLogger(__filename);
* the external communication.
* @returns {Promise}
*/
export function getAvailableDevices(transport: Object) {
export function getAvailableDevices(transport) {
return transport.sendRequest({
type: 'devices',
name: 'getAvailableDevices'
@@ -29,7 +27,7 @@ export function getAvailableDevices(transport: Object) {
* the external communication.
* @returns {Promise}
*/
export function getCurrentDevices(transport: Object) {
export function getCurrentDevices(transport) {
return transport.sendRequest({
type: 'devices',
name: 'getCurrentDevices'
@@ -50,7 +48,7 @@ export function getCurrentDevices(transport: Object) {
* Default - 'input'.
* @returns {Promise}
*/
export function isDeviceChangeAvailable(transport: Object, deviceType: string) {
export function isDeviceChangeAvailable(transport, deviceType) {
return transport.sendRequest({
deviceType,
type: 'devices',
@@ -66,7 +64,7 @@ export function isDeviceChangeAvailable(transport: Object, deviceType: string) {
* the external communication.
* @returns {Promise}
*/
export function isDeviceListAvailable(transport: Object) {
export function isDeviceListAvailable(transport) {
return transport.sendRequest({
type: 'devices',
name: 'isDeviceListAvailable'
@@ -81,7 +79,7 @@ export function isDeviceListAvailable(transport: Object) {
* the external communication.
* @returns {Promise}
*/
export function isMultipleAudioInputSupported(transport: Object) {
export function isMultipleAudioInputSupported(transport) {
return transport.sendRequest({
type: 'devices',
name: 'isMultipleAudioInputSupported'
@@ -97,7 +95,7 @@ export function isMultipleAudioInputSupported(transport: Object) {
* @param {string} id - The id of the new device.
* @returns {Promise}
*/
export function setAudioInputDevice(transport: Object, label: string, id: string) {
export function setAudioInputDevice(transport, label, id) {
return _setDevice(transport, {
id,
kind: 'audioinput',
@@ -114,7 +112,7 @@ export function setAudioInputDevice(transport: Object, label: string, id: string
* @param {string} id - The id of the new device.
* @returns {Promise}
*/
export function setAudioOutputDevice(transport: Object, label: string, id: string) {
export function setAudioOutputDevice(transport, label, id) {
return _setDevice(transport, {
id,
kind: 'audiooutput',
@@ -130,7 +128,7 @@ export function setAudioOutputDevice(transport: Object, label: string, id: strin
* @param {Object} device - The new device to be used.
* @returns {Promise}
*/
function _setDevice(transport: Object, device) {
function _setDevice(transport, device) {
return transport.sendRequest({
type: 'devices',
name: 'setDevice',
@@ -147,7 +145,7 @@ function _setDevice(transport: Object, device) {
* @param {string} id - The id of the new device.
* @returns {Promise}
*/
export function setVideoInputDevice(transport: Object, label: string, id: string) {
export function setVideoInputDevice(transport, label, id) {
return _setDevice(transport, {
id,
kind: 'videoinput',

View File

@@ -11,11 +11,11 @@ import { setColorAlpha } from '../../react/features/base/util/helpers';
import { setDocumentUrl } from '../../react/features/etherpad/actions';
import { setFilmstripVisible } from '../../react/features/filmstrip/actions.any';
import {
joinLeaveNotificationsDisabled,
setNotificationsEnabled,
showNotification
} from '../../react/features/notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../react/features/notifications/constants';
import { joinLeaveNotificationsDisabled } from '../../react/features/notifications/functions';
import {
dockToolbox,
setToolboxEnabled,

View File

@@ -1,5 +1,4 @@
// @flow
/* global APP */
import Logger from '@jitsi/logger';
import { openConnection } from '../../../connection';
@@ -23,7 +22,6 @@ import ExternalLoginDialog from './LoginDialog';
let externalAuthWindow;
declare var APP: Object;
const logger = Logger.getLogger(__filename);
@@ -77,7 +75,7 @@ function doExternalAuth(room, lockPassword) {
* back with "?jwt={the JWT token}" query parameter added.
* @param {string} [roomName] the name of the conference room.
*/
export function redirectToTokenAuthService(roomName: string) {
export function redirectToTokenAuthService(roomName) {
const config = APP.store.getState()['features/base/config'];
// FIXME: This method will not preserve the other URL params that were
@@ -174,7 +172,7 @@ function initJWTTokenListener(room) {
* @param {JitsiConference} room
* @param {string} [lockPassword] password to use if the conference is locked
*/
function authenticate(room: Object, lockPassword: string) {
function authenticate(room, lockPassword) {
const config = APP.store.getState()['features/base/config'];
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
@@ -189,7 +187,7 @@ function authenticate(room: Object, lockPassword: string) {
* @param {JitsiConference} room
* @param {string} [lockPassword] password to use if the conference is locked
*/
function requireAuth(room: Object, lockPassword: string) {
function requireAuth(room, lockPassword) {
if (isDialogOpen(APP.store, WaitForOwnerDialog) || isDialogOpen(APP.store, LoginDialog)) {
return;
}
@@ -207,7 +205,7 @@ function requireAuth(room: Object, lockPassword: string) {
* @param {string} [lockPassword] password to use if the conference is locked
* @returns {Promise}
*/
function logout(room: Object) {
function logout(room) {
return new Promise(resolve => {
room.room.moderator.logout(resolve);
}).then(url => {

View File

@@ -1,6 +1,4 @@
// @flow
declare var APP: Object;
/* global APP */
export default {
@@ -10,7 +8,7 @@ export default {
* @param {function} callback - callback to invoke when auth popup is closed.
* @returns auth dialog
*/
showExternalAuthDialog(url: string, callback: ?Function) {
showExternalAuthDialog(url, callback) {
const dialog = APP.UI.messageHandler.openCenteredPopup(
url, 910, 660,

View File

@@ -15,7 +15,7 @@ const Filmstrip = {
// horizontal film strip mode for calculating how tall large video
// display should be.
if (isFilmstripVisible(APP.store) && !interfaceConfig.VERTICAL_FILMSTRIP) {
return document.querySelector('.filmstrip').offsetHeight;
return document.querySelector('.filmstrip')?.offsetHeight ?? 0;
}
return 0;

View File

@@ -1,261 +0,0 @@
/* global APP */
import { jitsiLocalStorage } from '@jitsi/js-utils';
import Logger from '@jitsi/logger';
import {
ACTION_SHORTCUT_PRESSED as PRESSED,
ACTION_SHORTCUT_RELEASED as RELEASED,
createShortcutEvent
} from '../../react/features/analytics/AnalyticsEvents';
import { sendAnalytics } from '../../react/features/analytics/functions';
import { clickOnVideo } from '../../react/features/filmstrip/actions';
import { openSettingsDialog } from '../../react/features/settings/actions';
import { SETTINGS_TABS } from '../../react/features/settings/constants';
const logger = Logger.getLogger(__filename);
/**
* Map of shortcuts. When a shortcut is registered it enters the mapping.
* @type {Map}
*/
const _shortcuts = new Map();
/**
* Map of registered keyboard keys and translation keys describing the
* action performed by the key.
* @type {Map}
*/
const _shortcutsHelp = new Map();
/**
* The key used to save in local storage if keyboard shortcuts are enabled.
*/
const _enableShortcutsKey = 'enableShortcuts';
/**
* Prefer keyboard handling of these elements over global shortcuts.
* If a button is triggered using the Spacebar it should not trigger PTT.
* If an input element is focused and M is pressed it should not mute audio.
*/
const _elementsBlacklist = [
'input',
'textarea',
'button',
'[role=button]',
'[role=menuitem]',
'[role=radio]',
'[role=tab]',
'[role=option]',
'[role=switch]',
'[role=range]',
'[role=log]'
];
/**
* An element selector for elements that have their own keyboard handling.
*/
const _focusedElementsSelector = `:focus:is(${_elementsBlacklist.join(',')})`;
/**
* Maps keycode to character, id of popover for given function and function.
*/
const KeyboardShortcut = {
init() {
this._initGlobalShortcuts();
window.onkeyup = e => {
if (!this.getEnabled()) {
return;
}
const key = this._getKeyboardKey(e).toUpperCase();
const num = parseInt(key, 10);
if (!document.querySelector(_focusedElementsSelector)) {
if (_shortcuts.has(key)) {
_shortcuts.get(key).function(e);
} else if (!isNaN(num) && num >= 0 && num <= 9) {
APP.store.dispatch(clickOnVideo(num));
}
}
};
window.onkeydown = e => {
if (!this.getEnabled()) {
return;
}
const focusedElement = document.querySelector(_focusedElementsSelector);
if (!focusedElement) {
if (this._getKeyboardKey(e).toUpperCase() === ' ') {
if (APP.conference.isLocalAudioMuted()) {
sendAnalytics(createShortcutEvent(
'push.to.talk',
PRESSED));
logger.log('Talk shortcut pressed');
APP.conference.muteAudio(false);
}
}
} else if (this._getKeyboardKey(e).toUpperCase() === 'ESCAPE') {
// Allow to remove focus from selected elements using ESC key.
if (focusedElement && focusedElement.blur) {
focusedElement.blur();
}
}
};
},
/**
* Enables/Disables the keyboard shortcuts.
* @param {boolean} value - the new value.
*/
enable(value) {
jitsiLocalStorage.setItem(_enableShortcutsKey, value);
},
getEnabled() {
// Should be enabled if not explicitly set to false
// eslint-disable-next-line no-unneeded-ternary
return jitsiLocalStorage.getItem(_enableShortcutsKey) === 'false' ? false : true;
},
getShortcutsDescriptions() {
return _shortcutsHelp;
},
/**
* Opens the {@SettingsDialog} dialog on the Shortcuts page.
*
* @returns {void}
*/
openDialog() {
APP.store.dispatch(openSettingsDialog(SETTINGS_TABS.SHORTCUTS, false));
},
/**
* Registers a new shortcut.
*
* @param shortcutChar the shortcut character triggering the action
* @param shortcutAttr the "shortcut" html element attribute mapping an
* element to this shortcut and used to show the shortcut character on the
* element tooltip
* @param exec the function to be executed when the shortcut is pressed
* @param helpDescription the description of the shortcut that would appear
* in the help menu
* @param altKey whether or not the alt key must be pressed.
*/
registerShortcut(// eslint-disable-line max-params
shortcutChar,
shortcutAttr,
exec,
helpDescription,
altKey = false) {
_shortcuts.set(altKey ? `:${shortcutChar}` : shortcutChar, {
character: shortcutChar,
function: exec,
shortcutAttr,
altKey
});
if (helpDescription) {
this._addShortcutToHelp(altKey ? `:${shortcutChar}` : shortcutChar, helpDescription);
}
},
/**
* Unregisters a shortcut.
*
* @param shortcutChar unregisters the given shortcut, which means it will
* no longer be usable
* @param altKey whether or not shortcut is combo with alt key
*/
unregisterShortcut(shortcutChar, altKey = false) {
_shortcuts.delete(altKey ? `:${shortcutChar}` : shortcutChar);
_shortcutsHelp.delete(shortcutChar);
},
/**
* @param e a KeyboardEvent
* @returns {string} e.key or something close if not supported
*/
_getKeyboardKey(e) {
// If alt is pressed a different char can be returned so this takes
// the char from the code. It also prefixes with a colon to differentiate
// alt combo from simple keypress.
if (e.altKey) {
const key = e.code.replace('Key', '');
return `:${key}`;
}
// If e.key is a string, then it is assumed it already plainly states
// the key pressed. This may not be true in all cases, such as with Edge
// and "?", when the browser cannot properly map a key press event to a
// keyboard key. To be safe, when a key is "Unidentified" it must be
// further analyzed by jitsi to a key using e.which.
if (typeof e.key === 'string' && e.key !== 'Unidentified') {
return e.key;
}
if (e.type === 'keypress'
&& ((e.which >= 32 && e.which <= 126)
|| (e.which >= 160 && e.which <= 255))) {
return String.fromCharCode(e.which);
}
// try to fallback (0-9A-Za-z and QWERTY keyboard)
switch (e.which) {
case 27:
return 'Escape';
case 191:
return e.shiftKey ? '?' : '/';
}
if (e.shiftKey || e.type === 'keypress') {
return String.fromCharCode(e.which);
}
return String.fromCharCode(e.which).toLowerCase();
},
/**
* Adds the given shortcut to the help dialog.
*
* @param shortcutChar the shortcut character
* @param shortcutDescriptionKey the description of the shortcut
* @private
*/
_addShortcutToHelp(shortcutChar, shortcutDescriptionKey) {
_shortcutsHelp.set(shortcutChar, shortcutDescriptionKey);
},
/**
* Initialise global shortcuts.
* Global shortcuts are shortcuts for features that don't have a button or
* link associated with the action. In other words they represent actions
* triggered _only_ with a shortcut.
*/
_initGlobalShortcuts() {
this.registerShortcut('?', null, () => {
sendAnalytics(createShortcutEvent('help'));
this.openDialog();
}, 'keyboardShortcuts.toggleShortcuts');
// register SPACE shortcut in two steps to insure visibility of help
// message
this.registerShortcut(' ', null, () => {
sendAnalytics(createShortcutEvent('push.to.talk', RELEASED));
logger.log('Talk shortcut released');
APP.conference.muteAudio(true);
});
this._addShortcutToHelp('SPACE', 'keyboardShortcuts.pushToTalk');
/**
* FIXME: Currently focus keys are directly implemented below in
* onkeyup. They should be moved to the SmallVideo instead.
*/
this._addShortcutToHelp('0', 'keyboardShortcuts.focusLocal');
this._addShortcutToHelp('1-9', 'keyboardShortcuts.focusRemote');
}
};
export default KeyboardShortcut;

View File

@@ -1,15 +1,8 @@
/* @flow */
import $ from 'jquery';
import jqueryI18next from 'jquery-i18next';
import i18next from '../../react/features/base/i18n/i18next';
type DocumentElement = {
lang: string
}
/**
* Notifies that the {@link i18next} instance has finished its initialization.
*
@@ -18,7 +11,7 @@ type DocumentElement = {
*/
function _onI18nInitialized() {
const documentElement: DocumentElement
const documentElement
= document.documentElement || {};
$('[data-i18n]').localize();
@@ -47,7 +40,7 @@ class Translation {
/**
*
*/
generateTranslationHTML(key: string, options: Object) {
generateTranslationHTML(key, options) {
const optAttr
= options ? ` data-i18n-options='${JSON.stringify(options)}'` : '';
@@ -60,7 +53,7 @@ class Translation {
/**
*
*/
translateElement(selector: Object, options: Object) {
translateElement(selector, options) {
// XXX i18next expects undefined if options are missing.
selector.localize(options ? options : undefined);
}

8789
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,42 +16,34 @@
"readmeFilename": "README.md",
"dependencies": {
"@amplitude/react-native": "2.7.0",
"@atlaskit/inline-dialog": "13.0.9",
"@atlaskit/inline-message": "11.0.8",
"@atlaskit/multi-select": "15.0.5",
"@atlaskit/theme": "11.0.2",
"@emotion/react": "11.10.0",
"@emotion/styled": "11.10.0",
"@emotion/react": "11.10.6",
"@emotion/styled": "11.10.6",
"@giphy/js-fetch-api": "4.7.1",
"@giphy/react-components": "5.6.0",
"@giphy/react-native-sdk": "1.7.0",
"@giphy/react-components": "6.8.1",
"@giphy/react-native-sdk": "2.3.0",
"@hapi/bourne": "2.0.0",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.12/jitsi-excalidraw-0.0.12.tgz",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
"@jitsi/js-utils": "2.0.5",
"@jitsi/logger": "2.0.0",
"@jitsi/rnnoise-wasm": "0.1.0",
"@jitsi/rtcstats": "9.5.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",
"@mui/material": "5.10.2",
"@mui/styles": "5.10.2",
"@mui/material": "5.12.1",
"@mui/styles": "5.12.0",
"@react-native-async-storage/async-storage": "1.17.3",
"@react-native-community/clipboard": "1.5.1",
"@react-native-community/netinfo": "7.1.7",
"@react-native-community/slider": "4.1.12",
"@react-native-google-signin/google-signin": "9.0.2",
"@react-navigation/bottom-tabs": "6.5.3",
"@react-navigation/elements": "1.3.13",
"@react-navigation/material-top-tabs": "6.5.2",
"@react-navigation/native": "6.1.2",
"@react-navigation/stack": "6.3.11",
"@react-navigation/bottom-tabs": "6.5.8",
"@react-navigation/elements": "1.3.18",
"@react-navigation/material-top-tabs": "6.6.3",
"@react-navigation/native": "6.1.7",
"@react-navigation/stack": "6.3.17",
"@svgr/webpack": "6.3.1",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",
"@types/amplitude-js": "8.16.2",
"@types/audioworklet": "0.0.29",
"@types/w3c-image-capture": "1.0.6",
"@types/w3c-web-hid": "1.0.3",
"@vladmandic/human": "2.6.5",
"@vladmandic/human-models": "2.5.9",
"@xmldom/xmldom": "0.8.7",
@@ -73,21 +65,21 @@
"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/v1620.0.0+7f0012f7/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1654.0.0+782350e0/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
"promise.allsettled": "1.0.4",
"punycode": "2.1.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"punycode": "2.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-emoji-render": "1.2.4",
"react-focus-lock": "2.5.1",
"react-focus-on": "3.8.1",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "0.68.6",
"react-native": "0.69.10",
"react-native-background-timer": "2.4.1",
"react-native-calendar-events": "2.2.0",
"react-native-callstats": "3.73.7",
@@ -102,8 +94,8 @@
"react-native-pager-view": "5.4.9",
"react-native-paper": "5.1.2",
"react-native-performance": "2.1.0",
"react-native-safe-area-context": "4.4.1",
"react-native-screens": "3.13.1",
"react-native-safe-area-context": "4.6.4",
"react-native-screens": "3.22.0",
"react-native-sound": "0.11.1",
"react-native-splash-screen": "3.3.0",
"react-native-svg": "12.4.3",
@@ -112,7 +104,7 @@
"react-native-url-polyfill": "1.3.0",
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
"react-native-watch-connectivity": "1.0.11",
"react-native-webrtc": "111.0.0",
"react-native-webrtc": "111.0.3",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",
@@ -123,7 +115,6 @@
"redux-thunk": "2.4.1",
"resemblejs": "4.0.0",
"seamless-scroll-polyfill": "2.1.8",
"styled-components": "3.4.9",
"tss-react": "4.4.4",
"util": "0.12.1",
"uuid": "8.3.2",
@@ -134,53 +125,64 @@
},
"devDependencies": {
"@babel/core": "7.16.0",
"@babel/eslint-parser": "7.16.0",
"@babel/eslint-parser": "7.21.8",
"@babel/plugin-proposal-export-default-from": "7.16.0",
"@babel/preset-env": "7.16.0",
"@babel/preset-flow": "7.16.0",
"@babel/preset-react": "7.16.0",
"@jitsi/eslint-config": "4.1.5",
"@types/amplitude-js": "8.16.2",
"@types/audioworklet": "0.0.29",
"@types/dom-screen-wake-lock": "1.0.1",
"@types/js-md5": "0.4.3",
"@types/lodash": "4.14.182",
"@types/punycode": "2.1.0",
"@types/react": "17.0.14",
"@types/react-dom": "17.0.14",
"@types/react-linkify": "1.0.1",
"@types/react-native": "0.68.9",
"@types/react-native": "0.69.20",
"@types/react-native-keep-awake": "2.0.3",
"@types/react-native-video": "5.0.14",
"@types/react-redux": "7.1.24",
"@types/react-window": "1.8.5",
"@types/resemblejs": "^4.1.0",
"@types/unorm": "1.3.28",
"@types/uuid": "8.3.4",
"@types/w3c-image-capture": "1.0.6",
"@types/w3c-web-hid": "1.0.3",
"@types/zxcvbn": "4.4.1",
"@typescript-eslint/eslint-plugin": "5.30.5",
"@typescript-eslint/parser": "5.30.4",
"@typescript-eslint/eslint-plugin": "5.59.5",
"@typescript-eslint/parser": "5.59.5",
"babel-loader": "8.2.3",
"babel-plugin-optional-require": "0.3.1",
"circular-dependency-plugin": "5.2.0",
"clean-css-cli": "4.3.0",
"css-loader": "3.6.0",
"eslint": "8.35.0",
"eslint-plugin-flowtype": "8.0.3",
"eslint-plugin-import": "2.25.2",
"eslint": "8.40.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-jsdoc": "37.0.3",
"eslint-plugin-react": "7.26.1",
"eslint-plugin-react-native": "3.11.0",
"eslint-plugin-typescript-sort-keys": "2.1.0",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react-native": "4.0.0",
"eslint-plugin-typescript-sort-keys": "2.3.0",
"jetifier": "1.6.4",
"metro-react-native-babel-preset": "0.67.0",
"metro-react-native-babel-preset": "0.70.3",
"patch-package": "6.4.7",
"process": "0.11.10",
"sass": "1.26.8",
"style-loader": "3.3.1",
"traverse": "0.6.6",
"ts-loader": "9.4.1",
"typescript": "4.7.4",
"ts-loader": "9.4.2",
"typescript": "5.0.4",
"unorm": "1.6.0",
"webpack": "5.76.0",
"webpack-bundle-analyzer": "4.4.2",
"webpack-cli": "4.9.0",
"webpack-dev-server": "4.7.3"
},
"overrides": {
"strophe.js@1.5.0": {
"@xmldom/xmldom": "0.8.7"
}
},
"engines": {
"node": ">=14.0.0",
"npm": ">=7.0.0"
@@ -191,12 +193,14 @@
"tsc:web": "tsc --noEmit --project tsconfig.web.json",
"tsc:native": "tsc --noEmit --project tsconfig.native.json",
"tsc:ci": "npm run tsc:web && npm run tsc:native",
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 . && npm run tsc:ci && npm run lint:lang",
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 .",
"lint:lang": "for file in lang/*.json; do npx --yes jsonlint -q $file || exit 1; done",
"lang-sort": "./resources/lang-sort.sh",
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",
"postinstall": "patch-package --error-on-fail && jetify",
"validate": "npm ls",
"tsc-test:web": "tsc --project tsconfig.web.json --listFilesOnly | grep -v node_modules | grep native",
"tsc-test:native": "tsc --project tsconfig.native.json --listFilesOnly | grep -v node_modules | grep web",
"start": "make dev"
},
"resolutions": {

View File

@@ -1,14 +1,14 @@
diff --git a/node_modules/@giphy/js-analytics/dist/send-pingback.js b/node_modules/@giphy/js-analytics/dist/send-pingback.js
index 001345a..f303443 100644
index 989f0ff..149e77c 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 = environment + "/v2/pingback?apikey=l0HlIwPWyBBUDAUgM";
var pingBackUrl = "".concat(environment, "/v2/pingback?apikey=l0HlIwPWyBBUDAUgM");
var sendPingback = function (events) {
+ // Disabled.
+ return Promise.resolve();
+
var headers = js_util_1.getGiphySDKRequestHeaders();
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

@@ -1,12 +0,0 @@
diff --git a/node_modules/@giphy/js-brand/dist/typography.js b/node_modules/@giphy/js-brand/dist/typography.js
index af796bc..585fa00 100644
--- a/node_modules/@giphy/js-brand/dist/typography.js
+++ b/node_modules/@giphy/js-brand/dist/typography.js
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
exports.css = exports.fontSize = exports.fontFamily = void 0;
var emotion_1 = require("emotion");
// eslint-disable-next-line
-emotion_1.injectGlobal(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff') format('woff');\n}\n\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: bold;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff') format('woff');\n}\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: 900;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_XBd.woff') format('woff');\n}\n@font-face {\n font-family: 'nexablack'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff') format('woff');\n}\n@font-face {\n font-family: 'SSStandard'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-standard.woff') format('woff');\n}\n@font-face {\n font-family: 'SSSocial'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-social.woff') format('woff');\n}\n"], ["\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff') format('woff');\n}\n\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: bold;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff') format('woff');\n}\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: 900;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_XBd.woff') format('woff');\n}\n@font-face {\n font-family: 'nexablack'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff') format('woff');\n}\n@font-face {\n font-family: 'SSStandard'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-standard.woff') format('woff');\n}\n@font-face {\n font-family: 'SSSocial'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-social.woff') format('woff');\n}\n"])));
exports.fontFamily = {
title: "'nexablack', sans-serif",
body: 'interface, Helvetica Neue, helvetica, sans-serif;',

View File

@@ -0,0 +1,13 @@
diff --git a/node_modules/@giphy/js-brand/dist/typography.js b/node_modules/@giphy/js-brand/dist/typography.js
index 75ad96b..815cb8b 100644
--- a/node_modules/@giphy/js-brand/dist/typography.js
+++ b/node_modules/@giphy/js-brand/dist/typography.js
@@ -6,7 +6,7 @@ var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cook
Object.defineProperty(exports, "__esModule", { value: true });
exports.css = exports.fontSize = exports.fontFamily = exports.addFonts = void 0;
var emotion_1 = require("emotion");
-var addFonts = function () { return (0, emotion_1.injectGlobal)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff') format('woff');\n}\n\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: bold;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff') format('woff');\n}\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: 900;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_XBd.woff') format('woff');\n}\n@font-face {\n font-family: 'nexablack'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff') format('woff');\n}\n@font-face {\n font-family: 'SSStandard'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-standard.woff') format('woff');\n}\n@font-face {\n font-family: 'SSSocial'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-social.woff') format('woff');\n}\n"], ["\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff') format('woff');\n}\n\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: bold;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff') format('woff');\n}\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: 900;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_XBd.woff') format('woff');\n}\n@font-face {\n font-family: 'nexablack'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff') format('woff');\n}\n@font-face {\n font-family: 'SSStandard'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-standard.woff') format('woff');\n}\n@font-face {\n font-family: 'SSSocial'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-social.woff') format('woff');\n}\n"]))); };
+var addFonts = function () { };
exports.addFonts = addFonts;
try {
// in an env where process.env exists,

View File

@@ -1,11 +0,0 @@
diff --git a/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json b/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json
index 90a0d69..2ad7d68 100644
--- a/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json
+++ b/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json
@@ -1,5 +1,5 @@
{
- "parser": "@babel/eslint",
+ "parser": "@babel/eslint-parser",
"parserOptions": {
"babelOptions": {
"plugins": [

2
react-native-sdk/.npmrc Normal file
View File

@@ -0,0 +1,2 @@
package-lock=true
legacy-peer-deps=true

View File

@@ -0,0 +1,48 @@
# <p align="center">Jitsi Meet React Native SDK</p>
## Installation
Inside your project, run `npm i @jitsi/react-native-sdk`.<br/><br/>Additionally if not already installed, the following dependencies need to be added:
<br/>`npm i @react-native-async-storage/async-storage react-native-webrtc`
[comment]: # (These deps definitely need to be added manually, more could be neccesary)
### iOS
#### Project Info.plist
- Add a *Privacy - Camera Usage Description*
- Add a *Privacy - Microphone Usage Description*
#### General
- Signing & capabilites:
- Add Background modes
- Audio
- Voice over IP
- Background fetch
- Add Copy Sounds step:
```
SOUNDS_DIR="${PROJECT_DIR}/../node_modules/rnsdk/sounds"
cp $SOUNDS_DIR/* ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/
```
#### Podfile
- At the beginning of your target step add `pod 'ObjectiveDropboxOfficial', :modular_headers => true`
Run `cd ios && pod install && cd ..`
### Android
- In your build.gradle have at least `minSdkVersion = 24`
- TODO: HOW TO ADD COPY SOUNDS STEP
- Under the `</application>` tag of your AndroidManifest.xml make sure that it includes
```
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
```
### TODOS
- Ref ConnectionService to not rely on ReactInstanceHolder anymore
- Add Copy Sounds step to build.gradle
- Include copy sounds step in podspec (if possible)
- Add ranges for dependencies
- Add Build_Config for react native to AppInfoModule

View File

@@ -0,0 +1,140 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
}
}
def isNewArchitectureEnabled() {
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
}
apply plugin: 'com.android.library'
if (isNewArchitectureEnabled()) {
apply plugin: 'com.facebook.react'
}
def getExtOrDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['JitsiMeetReactNative_' + name]
}
def getExtOrIntegerDefault(name) {
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['JitsiMeetReactNative_' + name]).toInteger()
}
android {
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
defaultConfig {
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
}
buildTypes {
release {
minifyEnabled false
}
}
lintOptions {
disable 'GradleCompatible'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
repositories {
mavenCentral()
google()
def found = false
def defaultDir = null
def androidSourcesName = 'React Native sources'
if (rootProject.ext.has('reactNativeAndroidRoot')) {
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
} else {
defaultDir = new File(
projectDir,
'/../../../node_modules/react-native/android'
)
}
if (defaultDir.exists()) {
maven {
url defaultDir.toString()
name androidSourcesName
}
logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
found = true
} else {
def parentDir = rootProject.projectDir
1.upto(5, {
if (found) return true
parentDir = parentDir.parentFile
def androidSourcesDir = new File(
parentDir,
'node_modules/react-native'
)
def androidPrebuiltBinaryDir = new File(
parentDir,
'node_modules/react-native/android'
)
if (androidPrebuiltBinaryDir.exists()) {
maven {
url androidPrebuiltBinaryDir.toString()
name androidSourcesName
}
logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
found = true
} else if (androidSourcesDir.exists()) {
maven {
url androidSourcesDir.toString()
name androidSourcesName
}
logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
found = true
}
})
}
if (!found) {
throw new GradleException(
"${project.name}: unable to locate React Native android sources. " +
"Ensure you have you installed React Native as a dependency in your project and try again."
)
}
}
dependencies {
//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
}
if (isNewArchitectureEnabled()) {
react {
jsRootDir = file("../src/")
libraryName = "JitsiMeetReactNative"
codegenJavaPackageName = "org.jitsi.meet.sdk"
}
}

View File

@@ -0,0 +1,5 @@
JitsiMeetReactNative_kotlinVersion=1.7.0
JitsiMeetReactNative_minSdkVersion=21
JitsiMeetReactNative_targetSdkVersion=31
JitsiMeetReactNative_compileSdkVersion=31
JitsiMeetReactNative_ndkversion=21.4.7075529

View File

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

View File

@@ -0,0 +1,39 @@
package org.jitsi.meet.sdk;
import androidx.annotation.NonNull;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class JitsiMeetReactNativePackage implements ReactPackage {
@NonNull
@Override
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
List<NativeModule> modules
= new ArrayList<>(Arrays.<NativeModule>asList(
new AndroidSettingsModule(reactContext),
new AppInfoModule(reactContext),
new AudioModeModule(reactContext),
new JavaScriptSandboxModule(reactContext),
new LocaleDetector(reactContext),
new LogBridgeModule(reactContext),
new PictureInPictureModule(reactContext),
new ProximityModule(reactContext),
new org.jitsi.meet.sdk.net.NAT64AddrInfoModule(reactContext)
));
return modules;
}
@NonNull
@Override
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}

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