Compare commits

...

68 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé
a62cddff73 fix(rnsdk) update README 2023-07-18 11:18:45 +02:00
Saúl Ibarra Corretgé
555be6c229 chore(deps) simplify overrides 2023-07-18 11:10:58 +02:00
Saúl Ibarra Corretgé
3f5e6883b5 chore(deps) redux@7.2.9
Fixes a warning due to the React version dependency
2023-07-18 11:10:58 +02:00
Saúl Ibarra Corretgé
ddcf90e95c feat(rnsdk) add npm ignore file 2023-07-18 11:10:58 +02:00
Saúl Ibarra Corretgé
683e9e72b9 fix(rnsdk,deps) update dependencies 2023-07-18 11:10:58 +02:00
Saúl Ibarra Corretgé
123eaf77fa fix(rnsdk) drop unnecessary Swift files and dependencies 2023-07-18 11:10:58 +02:00
damencho
bb29f20a07 fix: Fixes joining visitor.
The dispatches were not ordered and sometimes disconnect was executed just after connect and you end up in disconnected state.
2023-07-17 14:52:01 -05:00
Saúl Ibarra Corretgé
866390ece1 fix(android) fix crash when pending intent is created without flags
Fix for this crash:

~~~
Fatal Exception: java.lang.IllegalArgumentException: org.jitsi.meet: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
       at android.app.PendingIntent.checkFlags(PendingIntent.java:377)
       at android.app.PendingIntent.getActivityAsUser(PendingIntent.java:460)
       at android.app.PendingIntent.getActivity(PendingIntent.java:446)
       at android.app.PendingIntent.getActivity(PendingIntent.java:410)
       at com.google.android.gms.common.GoogleApiAvailabilityLight.getErrorResolutionPendingIntent(GoogleApiAvailabilityLight.java:25)
       at com.google.android.gms.common.GoogleApiAvailabilityLight.getErrorResolutionPendingIntent(GoogleApiAvailabilityLight.java:21)
       at com.google.android.gms.common.GoogleApiAvailability.getErrorResolutionPendingIntent(GoogleApiAvailability.java:97)
       at com.google.android.gms.common.GoogleApiAvailability.getErrorResolutionPendingIntent(GoogleApiAvailability.java:100)
       at com.google.android.gms.common.GoogleApiAvailability.zaa(GoogleApiAvailability.java:41)
       at com.google.android.gms.common.api.internal.GoogleApiManager.zac(GoogleApiManager.java:214)
       at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.onConnectionFailed(GoogleApiManager.java:86)
       at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.connect(GoogleApiManager.java:219)
       at com.google.android.gms.common.api.internal.GoogleApiManager$zaa.zaa(GoogleApiManager.java:112)
       at com.google.android.gms.common.api.internal.GoogleApiManager.handleMessage(GoogleApiManager.java:145)
       at android.os.Handler.dispatchMessage(Handler.java:107)
       at com.google.android.gms.internal.base.zap.dispatchMessage(zap.java:8)
       at android.os.Looper.loopOnce(Looper.java:238)
       at android.os.Looper.loop(Looper.java:357)
       at android.os.HandlerThread.run(HandlerThread.java:67)
~~~
2023-07-17 18:16:46 +02:00
Robert Pintilii
5b844e45e3 ref(chat) Move styles from SCSS to JSS (#13559) 2023-07-17 16:01:24 +03:00
Saúl Ibarra Corretgé
1c80771405 chore(rn,deps) react-native@0.69.11 2023-07-17 15:00:01 +02:00
Saúl Ibarra Corretgé
d42cbbd9f8 fix(android) fix React-Native POM file when publishing
For some reason the packaging mode changed from AAR to POM after 0.68,
and dependencies are now marked optional, when they are not.

Fixes: https://github.com/jitsi/jitsi-meet/issues/13566
2023-07-17 15:00:01 +02:00
Robert Pintilii
18873a9659 ref(feedback) Convert dialog to function component (#13564) 2023-07-17 11:21:19 +03:00
Robert Pintilii
7859397790 ref(chat) Refactor ChatMessage component (#13556)
Remove Abstract class
Convert web component to function component
2023-07-17 10:47:54 +03:00
Дамян Минков
bc23f9cd33 feat: Drops connection on prejoin screen. (#13538)
* feat: Drops connection on prejoin screen.

Refactors connection logic to reuse already existing logic from mobile. Connection is now established just before joining the room.
Fixes some authentication logic with Login and Logout button in Profile tab.

* squash: Drops createInitialLocalTracksAndConnect as it no longer connects.

* squash: Shows an error on mobile and redirects to default.

* squash: Fixes review comments.

* squash: Fixes joining with prejoin disabled.

* squash: Fixes adding initial local tracks.

* squash: Fixes comments.

* squash: Drop no longer used method.

* squash: Fixes old web code imported into mobile builds.

* squash: Drop unused prop.

* squash: Drops recoverable flag on REDIRECT.

* squash: Drops unused variable and fix connection access.

* squash: Xmpp connect returns promise again.

* squash: Execute xmpp connect and creating local tracks in parallel.

* squash: Moves notification about problem jwt.

* squash: Moves startConference to conference.js for the no prejoin case.

And move the startConference in prejoin feature for the prejoin case.

* squash: Fix passing filtered tracks when starting conference with no prejoin.

* squash: Fix clearing listeners on connection established.

Keeps mobile behaviour after merging web and mobile.

* squash: Drops unused code.
2023-07-15 17:33:26 -05:00
Robert Pintilii
02f0057578 ref(styles) Move some styles from SCSS to JSS (#13565) 2023-07-14 15:58:07 +03:00
Calinteodor
63761d515a feat(base/flags): created flag to control unsafe room warning (#13560)
* feat(base/flags): created flag to control unsafe room warning
2023-07-14 11:42:15 +03:00
Jaya Allamsetty
5cc4b31f35 chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1656.0.0+e0d3459a...v1659.0.0+5d322ea5
2023-07-13 22:59:26 -04:00
Robert Pintilii
a03bf2cb8e fix(local-rec) Download recording on meeting end (#13557) 2023-07-13 16:01:53 +03:00
Calin-Teodor
312902ea77 deps(patch/react-native-immersive): replaced removeListener deprecated method 2023-07-13 15:17:01 +03:00
Robert Pintilii
961a9236fd ref: remove some Abstract components (#13553) 2023-07-13 12:27:34 +03:00
damencho
364e63da14 feat: New prosody auth module using shared secret.
The same as username and password but ignoring the username. Useful for jigasi and jibri where the instances can use different usernames, but the same shared secret/password.
2023-07-12 12:39:00 -05:00
Calinteodor
27c62b3d78 sdk(react-native-sdk): error fixes (#13549)
* feat(mobile/background/react-native-sdk): replaced removeListener deprecated method and fixed some undefined errors
2023-07-12 17:28:30 +03:00
Robert Pintilii
51623b47f0 ref(CSS): Cleanup (#13554)
Remove unused styles
2023-07-12 15:51:56 +03:00
Robert Pintilii
824cfc0c9c ref(chat): Refactor Chat components (#13550)
Remove Abstract component
Convert web component to function component
2023-07-12 15:51:38 +03:00
Saúl Ibarra Corretgé
398e170e2d fix(settings) fix when devices tab is not visible
Fixes: https://github.com/jitsi/jitsi-meet/issues/13461
2023-07-11 21:47:57 +02:00
Saúl Ibarra Corretgé
f1de6887cd chore(deps) lib-jitsi-meet@latest
https://github.com/jitsi/lib-jitsi-meet/compare/v1654.0.0+782350e0...v1656.0.0+e0d3459a
2023-07-11 17:25:38 +02:00
dependabot[bot]
7d31a838c1 chore(deps): bump semver from 5.7.1 to 5.7.2 in /react-native-sdk
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 13:34:08 +02:00
dependabot[bot]
61e3dc10dd chore(deps): bump semver from 5.7.1 to 5.7.2
Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2.
- [Release notes](https://github.com/npm/node-semver/releases)
- [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md)
- [Commits](https://github.com/npm/node-semver/compare/v5.7.1...v5.7.2)

---
updated-dependencies:
- dependency-name: semver
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-07-11 12:27:51 +02:00
Calinteodor
7877ff4528 sdk(react-native-sdk): update README file (#13545)
* sdk(react-native-sdk): update README file
2023-07-11 11:42:10 +03:00
Fatemeh Marzoughi (Saba)
e8766b265d fix: solved the flip bug in screen share video (#13542)
Fixes #13480 🐛 solved the flip bug in screen share video

* #13480 🐛 solved the flip bug in screen share video
2023-07-07 16:34:49 -05:00
Saúl Ibarra Corretgé
da5d1033c3 fix(app) simplify appNavigate on web
Loading the config can never fail since it uses SSI and it's checked
before page even loads.
2023-07-07 23:14:09 +02:00
damencho
13323e423e feat: Ignores list of domains when checking for visitors and promotion. 2023-07-07 14:44:59 -05:00
Nils Jacobsen
5297252efb feat(i18n) add i18next compatible IDE-extension for i18n handling 2023-07-07 14:59:25 +02:00
Hayato Shimizu
5ce2bef556 fix: jicofo_lock is null when restored from storage (#13517)
* Fix jicofo_lock is null when restored from storage

* revert

---------

Co-authored-by: hshim432 <hshimizusv@gmail.com>
2023-07-07 07:52:22 -05:00
Bartosz Pawlak
472c8d7808 fix(lang) updated Polish translation 2023-07-07 11:42:37 +02:00
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
193 changed files with 6852 additions and 8066 deletions

1
.gitignore vendored
View File

@@ -97,6 +97,7 @@ tsconfig.json
# React Native SDK
#
react-native-sdk/*.tgz
react-native-sdk/android/src
react-native-sdk/images
react-native-sdk/ios

View File

@@ -81,7 +81,8 @@ dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
if (!rootProject.ext.libreBuild) {
implementation 'com.google.android.gms:play-services-auth:16.0.1'
// Sync with react-native-google-signin
implementation 'com.google.android.gms:play-services-auth:19.0.2'
// Firebase
// - Crashlytics

View File

@@ -29,6 +29,10 @@ if [[ $MVN_HTTP == 1 ]]; then
# Push React Native
echo "Pushing React Native ${RN_VERSION} to the Maven repo"
pushd ${THIS_DIR}/../../node_modules/react-native/android/com/facebook/react/react-native/${RN_VERSION}
cat react-native-${RN_VERSION}.pom \
| sed "s#<packaging>pom</packaging>#<packaging>aar</packaging>#" \
| sed "/<optional>/d" \
> react-native-${RN_VERSION}-fixed.pom
mvn \
deploy:deploy-file \
-Durl=${MVN_REPO} \
@@ -36,7 +40,7 @@ if [[ $MVN_HTTP == 1 ]]; then
-Dfile=react-native-${RN_VERSION}-release.aar \
-Dpackaging=aar \
-DgeneratePom=false \
-DpomFile=react-native-${RN_VERSION}.pom || true
-DpomFile=react-native-${RN_VERSION}-fixed.pom || true
popd
# Push JSC
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
@@ -55,13 +59,17 @@ else
if [[ ! -d ${MVN_REPO}/com/facebook/react/react-native/${RN_VERSION} ]]; then
echo "Pushing React Native ${RN_VERSION} to the Maven repo"
pushd ${THIS_DIR}/../../node_modules/react-native/android/com/facebook/react/react-native/${RN_VERSION}
cat react-native-${RN_VERSION}.pom \
| sed "s#<packaging>pom</packaging>#<packaging>aar</packaging>#" \
| sed "/<optional>/d" \
> react-native-${RN_VERSION}-fixed.pom
mvn \
deploy:deploy-file \
-Durl=${MVN_REPO} \
-Dfile=react-native-${RN_VERSION}-release.aar \
-Dpackaging=aar \
-DgeneratePom=false \
-DpomFile=react-native-${RN_VERSION}.pom
-DpomFile=react-native-${RN_VERSION}-fixed.pom
popd
fi

View File

@@ -4,12 +4,8 @@ import { jitsiLocalStorage } from '@jitsi/js-utils';
import Logger from '@jitsi/logger';
import EventEmitter from 'events';
import { openConnection } from './connection';
import { ENDPOINT_TEXT_MESSAGE_NAME } from './modules/API/constants';
import { AUDIO_ONLY_SCREEN_SHARE_NO_TRACK } from './modules/UI/UIErrors';
import AuthHandler from './modules/UI/authentication/AuthHandler';
import UIUtil from './modules/UI/util/UIUtil';
import VideoLayout from './modules/UI/videolayout/VideoLayout';
import mediaDeviceHelper from './modules/devices/mediaDeviceHelper';
import Recorder from './modules/recorder/Recorder';
import { createTaskQueue } from './modules/util/helpers';
@@ -37,7 +33,7 @@ import {
conferenceSubjectChanged,
conferenceTimestampChanged,
conferenceUniqueIdSet,
conferenceWillJoin,
conferenceWillInit,
conferenceWillLeave,
dataChannelClosed,
dataChannelOpened,
@@ -57,12 +53,10 @@ import {
commonUserJoinedHandling,
commonUserLeftHandling,
getConferenceOptions,
getVisitorOptions,
restoreConferenceOptions,
sendLocalParticipant
} from './react/features/base/conference/functions';
import { overwriteConfig } from './react/features/base/config/actions';
import { getReplaceParticipant } from './react/features/base/config/functions';
import { connect } from './react/features/base/connection/actions.web';
import {
checkAndNotifyForNewDevice,
getAvailableDevices,
@@ -77,15 +71,12 @@ import {
import {
JitsiConferenceErrors,
JitsiConferenceEvents,
JitsiConnectionErrors,
JitsiConnectionEvents,
JitsiE2ePingEvents,
JitsiMediaDevicesEvents,
JitsiTrackErrors,
JitsiTrackEvents,
browser
} from './react/features/base/lib-jitsi-meet';
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
import {
gumPending,
setAudioAvailable,
@@ -145,7 +136,12 @@ import { maybeOpenFeedbackDialog, submitFeedback } from './react/features/feedba
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';
import {
hideNotification,
showErrorNotification,
showNotification,
showWarningNotification
} from './react/features/notifications/actions';
import {
DATA_CHANNEL_CLOSED_NOTIFICATION_ID,
NOTIFICATION_TIMEOUT_TYPE
@@ -153,7 +149,7 @@ import {
import { isModerationNotificationDisplayed } from './react/features/notifications/functions';
import { mediaPermissionPromptVisibilityChanged } from './react/features/overlay/actions';
import { suspendDetected } from './react/features/power-monitor/actions';
import { initPrejoin, makePrecallTest, setJoiningInProgress } from './react/features/prejoin/actions';
import { initPrejoin, makePrecallTest } from './react/features/prejoin/actions';
import { isPrejoinPageVisible } from './react/features/prejoin/functions';
import { disableReceiver, stopReceiver } from './react/features/remote-control/actions';
import { setScreenAudioShareState } from './react/features/screen-share/actions.web';
@@ -164,7 +160,6 @@ import { createRnnoiseProcessor } from './react/features/stream-effects/rnnoise'
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';
@@ -173,25 +168,6 @@ const logger = Logger.getLogger(__filename);
const eventEmitter = new EventEmitter();
let room;
let connection;
/**
* The promise is used when the prejoin screen is shown.
* While the user configures the devices the connection can be made.
*
* @type {Promise<Object>}
* @private
*/
let _connectionPromise;
/**
* We are storing the resolve function of a Promise that waits for the _connectionPromise to be created. This is needed
* when the prejoin button was pressed before the conference object was initialized and the _connectionPromise has not
* been initialized when we tried to execute prejoinStart. In this case in prejoinStart we create a new Promise, assign
* the resolve function to this variable and wait for the promise to resolve before we continue. The
* _onConnectionPromiseCreated will be called once the _connectionPromise is created.
*/
let _onConnectionPromiseCreated;
/*
* Logic to open a desktop picker put on the window global for
@@ -213,26 +189,6 @@ const commands = {
ETHERPAD: 'etherpad'
};
/**
* Open Connection. When authentication failed it shows auth dialog.
* @param roomName the room name to use
* @returns Promise<JitsiConnection>
*/
function connect(roomName) {
return openConnection({
retry: true,
roomName
})
.catch(err => {
if (err === JitsiConnectionErrors.PASSWORD_REQUIRED) {
APP.UI.notifyTokenAuthFailed();
} else {
APP.UI.notifyConnectionFailed(err);
}
throw err;
});
}
/**
* Share data to other users.
* @param command the command
@@ -326,63 +282,25 @@ class ConferenceConnector {
break;
}
// not enough rights to create conference
case JitsiConferenceErrors.AUTHENTICATION_REQUIRED: {
const replaceParticipant = getReplaceParticipant(APP.store.getState());
// Schedule reconnect to check if someone else created the room.
this.reconnectTimeout = setTimeout(() => {
APP.store.dispatch(conferenceWillJoin(room));
room.join(null, replaceParticipant);
}, 5000);
const { password }
= APP.store.getState()['features/base/conference'];
AuthHandler.requireAuth(room, password);
break;
}
case JitsiConferenceErrors.RESERVATION_ERROR: {
const [ code, msg ] = params;
APP.UI.notifyReservationError(code, msg);
break;
}
case JitsiConferenceErrors.REDIRECTED: {
const newConfig = getVisitorOptions(APP.store.getState(), params);
if (!newConfig) {
logger.warn('Not redirected missing params');
break;
}
const [ vnode ] = params;
APP.store.dispatch(overwriteConfig(newConfig))
.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(() => {
// Reset VideoLayout. It's destroyed in features/video-layout/middleware.web.js so re-initialize it.
VideoLayout.initLargeVideo();
VideoLayout.resizeVideoArea();
connect(this._conference.roomName).then(con => {
this._conference.startConference(con, []);
});
});
APP.store.dispatch(showErrorNotification({
descriptionArguments: {
code,
msg
},
descriptionKey: 'dialog.reservationErrorMsg',
titleKey: 'dialog.reservationError'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
break;
}
case JitsiConferenceErrors.GRACEFUL_SHUTDOWN:
APP.UI.notifyGracefulShutdown();
APP.store.dispatch(showErrorNotification({
descriptionKey: 'dialog.gracefulShutdown',
titleKey: 'dialog.serviceUnavailable'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
break;
// FIXME FOCUS_DISCONNECTED is a confusing event name.
@@ -408,31 +326,9 @@ class ConferenceConnector {
// FIXME the conference should be stopped by the library and not by
// the app. Both the errors above are unrecoverable from the library
// perspective.
room.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).then(() => connection.disconnect());
room.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).then(() => APP.connection.disconnect());
break;
case JitsiConferenceErrors.CONFERENCE_MAX_USERS: {
APP.UI.notifyMaxUsersLimitReached();
// in case of max users(it can be from a visitor node), let's restore
// oldConfig if any as we will be back to the main prosody
const newConfig = restoreConferenceOptions(APP.store.getState());
if (newConfig) {
APP.store.dispatch(overwriteConfig(newConfig))
.then(() => this._conference.leaveRoom())
.then(() => {
_connectionPromise = connect(this._conference.roomName);
return _connectionPromise;
})
.then(con => {
APP.connection = connection = con;
});
}
break;
}
case JitsiConferenceErrors.INCOMPATIBLE_SERVER_VERSIONS:
APP.store.dispatch(reloadWithStoredParams());
break;
@@ -488,11 +384,11 @@ function disconnect() {
return Promise.resolve();
};
if (!connection) {
if (!APP.connection) {
return onDisconnected();
}
return connection.disconnect().then(onDisconnected, onDisconnected);
return APP.connection.disconnect().then(onDisconnected, onDisconnected);
}
/**
@@ -510,25 +406,6 @@ function setGUMPendingStateOnFailedTracks(tracks) {
APP.store.dispatch(gumPending(nonPendingTracks, IGUMPendingState.NONE));
}
/**
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
*
* @param {JitsiConnectionError} error - The reported error.
* @returns {void}
* @private
*/
function _connectionFailedHandler(error) {
if (isFatalJitsiConnectionError(error)) {
APP.connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
_connectionFailedHandler);
if (room) {
APP.store.dispatch(conferenceWillLeave(room));
room.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR);
}
}
}
export default {
/**
* Flag used to delay modification of the muted status of local media tracks
@@ -547,7 +424,16 @@ export default {
/**
* Returns an object containing a promise which resolves with the created tracks &
* the errors resulting from that process.
*
* @param {object} options
* @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
* only audio track will be created and the audio only mode will be turned
* on.
* @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
* should start with screensharing instead of camera video.
* @param {boolean} options.startWithAudioMuted - will start the conference
* without any audio tracks.
* @param {boolean} options.startWithVideoMuted - will start the conference
* without any video tracks.
* @returns {Promise<JitsiLocalTrack[]>, Object}
*/
createInitialLocalTracks(options = {}) {
@@ -725,37 +611,7 @@ export default {
}
},
/**
* Creates local media tracks and connects to a room. Will show error
* dialogs in case accessing the local microphone and/or camera failed. Will
* show guidance overlay for users on how to give access to camera and/or
* microphone.
* @param {string} roomName
* @param {object} options
* @param {boolean} options.startAudioOnly=false - if <tt>true</tt> then
* only audio track will be created and the audio only mode will be turned
* on.
* @param {boolean} options.startScreenSharing=false - if <tt>true</tt>
* should start with screensharing instead of camera video.
* @param {boolean} options.startWithAudioMuted - will start the conference
* without any audio tracks.
* @param {boolean} options.startWithVideoMuted - will start the conference
* without any video tracks.
* @returns {Promise.<JitsiLocalTrack[], JitsiConnection>}
*/
createInitialLocalTracksAndConnect(roomName, options = {}) {
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(options);
return Promise.all([ tryCreateLocalTracks, connect(roomName) ])
.then(([ tracks, con ]) => {
this._displayErrorsForCreateInitialLocalTracks(errors);
return [ tracks, con ];
});
},
startConference(con, tracks) {
startConference(tracks) {
tracks.forEach(track => {
if ((track.isAudioTrack() && this.isLocalAudioMuted())
|| (track.isVideoTrack() && this.isLocalVideoMuted())) {
@@ -768,9 +624,6 @@ export default {
}
});
con.addEventListener(JitsiConnectionEvents.CONNECTION_FAILED, _connectionFailedHandler);
APP.connection = connection = con;
this._createRoom(tracks);
// if user didn't give access to mic or camera or doesn't have
@@ -860,17 +713,6 @@ export default {
};
if (isPrejoinPageVisible(state)) {
_connectionPromise = connect(roomName).then(c => {
// We want to initialize it early, in case of errors to be able to gather logs.
APP.connection = c;
return c;
});
if (_onConnectionPromiseCreated) {
_onConnectionPromiseCreated();
}
APP.store.dispatch(makePrecallTest(this._getConferenceOptions()));
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
@@ -897,41 +739,26 @@ export default {
return this._setLocalAudioVideoStreams(tracks);
}
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(roomName, initialOptions);
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
this._initDeviceList(true);
return Promise.all([
tryCreateLocalTracks.then(tr => {
this._displayErrorsForCreateInitialLocalTracks(errors);
const filteredTracks = handleInitialTracks(initialOptions, tracks);
return tr;
}).then(tr => {
this._initDeviceList(true);
setGUMPendingStateOnFailedTracks(filteredTracks);
const filteredTracks = handleInitialTracks(initialOptions, tr);
return this.startConference(con, filteredTracks);
},
setGUMPendingStateOnFailedTracks(filteredTracks);
/**
* Joins conference after the tracks have been configured in the prejoin screen.
*
* @param {Object[]} tracks - An array with the configured tracks
* @returns {void}
*/
async prejoinStart(tracks) {
if (!_connectionPromise) {
// The conference object isn't initialized yet. Wait for the promise to initialise.
await new Promise(resolve => {
_onConnectionPromiseCreated = resolve;
});
_onConnectionPromiseCreated = undefined;
}
let con;
try {
con = await _connectionPromise;
this.startConference(con, tracks);
} catch (error) {
logger.error(`An error occurred while trying to join a meeting from the prejoin screen: ${error}`);
APP.store.dispatch(setJoiningInProgress(false));
}
return filteredTracks;
}),
APP.store.dispatch(connect())
]).then(([ tracks, _ ]) => {
this.startConference(tracks).catch(logger.error);
});
},
/**
@@ -1413,9 +1240,7 @@ export default {
* Used by the Breakout Rooms feature to join a breakout room or go back to the main room.
*/
async joinRoom(roomName, options) {
// Reset VideoLayout. It's destroyed in features/video-layout/middleware.web.js so re-initialize it.
VideoLayout.initLargeVideo();
VideoLayout.resizeVideoArea();
APP.store.dispatch(conferenceWillInit());
// Restore initial state.
this._localTracksInitialized = false;
@@ -1440,7 +1265,7 @@ export default {
},
_createRoom(localTracks) {
room = connection.initJitsiConference(APP.conference.roomName, this._getConferenceOptions());
room = APP.connection.initJitsiConference(APP.conference.roomName, this._getConferenceOptions());
// Filter out the tracks that are muted (except on Safari).
const tracks = browser.isWebKitBased() ? localTracks : localTracks.filter(track => !track.isMuted());
@@ -1787,10 +1612,10 @@ export default {
titleKey = 'notify.screenShareNoAudioTitle';
}
APP.UI.messageHandler.showError({
APP.store.dispatch(showErrorNotification({
descriptionKey,
titleKey
});
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
},
/**
@@ -2184,21 +2009,6 @@ export default {
this.hangup(true);
});
// logout
APP.UI.addListener(UIEvents.LOGOUT, () => {
AuthHandler.logout(room).then(url => {
if (url) {
UIUtil.redirect(url);
} else {
this.hangup(true);
}
});
});
APP.UI.addListener(UIEvents.AUTH_CLICKED, () => {
AuthHandler.authenticate(room);
});
APP.UI.addListener(
UIEvents.VIDEO_DEVICE_CHANGED,
cameraDeviceId => {

View File

@@ -427,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
@@ -485,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
@@ -935,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).
@@ -952,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: {

View File

@@ -1,209 +0,0 @@
/* global APP, JitsiMeetJS, config */
import { jitsiLocalStorage } from '@jitsi/js-utils';
import Logger from '@jitsi/logger';
import { redirectToTokenAuthService } from './modules/UI/authentication/AuthHandler';
import { LoginDialog } from './react/features/authentication/components';
import { isTokenAuthEnabled } from './react/features/authentication/functions';
import {
connectionEstablished,
connectionFailed,
constructOptions
} from './react/features/base/connection/actions.web';
import { openDialog } from './react/features/base/dialog/actions';
import { setJWT } from './react/features/base/jwt/actions';
import {
JitsiConnectionErrors,
JitsiConnectionEvents
} from './react/features/base/lib-jitsi-meet';
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
import { getCustomerDetails } from './react/features/jaas/actions.any';
import { getJaasJWT, isVpaasMeeting } from './react/features/jaas/functions';
import {
setPrejoinDisplayNameRequired
} from './react/features/prejoin/actions';
const logger = Logger.getLogger(__filename);
/**
* The feature announced so we can distinguish jibri participants.
*
* @type {string}
*/
export const DISCO_JIBRI_FEATURE = 'http://jitsi.org/protocol/jibri';
/**
* Try to open connection using provided credentials.
* @param {string} [id]
* @param {string} [password]
* @returns {Promise<JitsiConnection>} connection if
* everything is ok, else error.
*/
export async function connect(id, password) {
const state = APP.store.getState();
let { jwt } = state['features/base/jwt'];
const { iAmRecorder, iAmSipGateway } = state['features/base/config'];
if (!iAmRecorder && !iAmSipGateway && isVpaasMeeting(state)) {
await APP.store.dispatch(getCustomerDetails());
if (!jwt) {
jwt = await getJaasJWT(state);
APP.store.dispatch(setJWT(jwt));
}
}
const connection = new JitsiMeetJS.JitsiConnection(null, jwt, constructOptions(state));
if (config.iAmRecorder) {
connection.addFeature(DISCO_JIBRI_FEATURE);
}
return new Promise((resolve, reject) => {
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_ESTABLISHED,
handleConnectionEstablished);
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
handleConnectionFailed);
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
connectionFailedHandler);
connection.addEventListener(
JitsiConnectionEvents.DISPLAY_NAME_REQUIRED,
displayNameRequiredHandler
);
/* eslint-disable max-params */
/**
*
*/
function connectionFailedHandler(error, message, credentials, details) {
/* eslint-enable max-params */
APP.store.dispatch(
connectionFailed(
connection, {
credentials,
details,
message,
name: error
}));
if (isFatalJitsiConnectionError(error)) {
connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
connectionFailedHandler);
}
}
/**
*
*/
function unsubscribe() {
connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_ESTABLISHED,
handleConnectionEstablished);
connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
handleConnectionFailed);
}
/**
*
*/
function handleConnectionEstablished() {
APP.store.dispatch(connectionEstablished(connection, Date.now()));
unsubscribe();
resolve(connection);
}
/**
*
*/
function handleConnectionFailed(err) {
unsubscribe();
logger.error('CONNECTION FAILED:', err);
reject(err);
}
/**
* Marks the display name for the prejoin screen as required.
* This can happen if a user tries to join a room with lobby enabled.
*/
function displayNameRequiredHandler() {
APP.store.dispatch(setPrejoinDisplayNameRequired());
}
connection.connect({
id,
password
});
});
}
/**
* Open JitsiConnection using provided credentials.
* If retry option is true it will show auth dialog on PASSWORD_REQUIRED error.
*
* @param {object} options
* @param {string} [options.id]
* @param {string} [options.password]
* @param {string} [options.roomName]
* @param {boolean} [retry] if we should show auth dialog
* on PASSWORD_REQUIRED error.
*
* @returns {Promise<JitsiConnection>}
*/
export function openConnection({ id, password, retry, roomName }) {
const usernameOverride
= jitsiLocalStorage.getItem('xmpp_username_override');
const passwordOverride
= jitsiLocalStorage.getItem('xmpp_password_override');
if (usernameOverride && usernameOverride.length > 0) {
id = usernameOverride; // eslint-disable-line no-param-reassign
}
if (passwordOverride && passwordOverride.length > 0) {
password = passwordOverride; // eslint-disable-line no-param-reassign
}
return connect(id, password).catch(err => {
if (retry) {
const { jwt } = APP.store.getState()['features/base/jwt'];
if (err === JitsiConnectionErrors.PASSWORD_REQUIRED && !jwt) {
return requestAuth(roomName);
}
}
throw err;
});
}
/**
* Show Authentication Dialog and try to connect with new credentials.
* If failed to connect because of PASSWORD_REQUIRED error
* then ask for password again.
* @param {string} [roomName] name of the conference room
*
* @returns {Promise<JitsiConnection>}
*/
function requestAuth(roomName) {
const config = APP.store.getState()['features/base/config'];
if (isTokenAuthEnabled(config)) {
// This Promise never resolves as user gets redirected to another URL
return new Promise(() => redirectToTokenAuthService(roomName));
}
return new Promise(resolve => {
const onSuccess = connection => {
resolve(connection);
};
APP.store.dispatch(
openDialog(LoginDialog, { onSuccess,
roomName })
);
});
}

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
}
/**
@@ -66,10 +66,6 @@ body, input, textarea, keygen, select, button {
font-family: $baseFontFamily !important;
}
#nowebrtc {
display:none;
}
button, input, select, textarea {
margin: 0;
vertical-align: baseline;
@@ -94,7 +90,7 @@ input[type='text'], input[type='password'], textarea {
button {
color: #FFF;
background-color: $buttonBackground;
background-color: #44A5FF;
border-radius: $borderRadius;
&.no-icon {
@@ -145,22 +141,7 @@ form {
font-size: 11pt;
color: rgba(255,255,255,.50);
text-decoration: none;
z-index: $poweredByZ;
}
.connected {
color: #21B9FC;
font-size: 12px;
}
.lastN, .disconnected {
color: #a3a3a3;
font-size: 12px;
}
#inviteLinkRef {
-webkit-user-select: text;
user-select: text;
z-index: 100;
}
/**
@@ -193,3 +174,16 @@ form {
.jitsi-icon svg path {
fill: inherit !important;
}
.sr-only {
border: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important;
clip-path: inset(50%) !important;
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important;
}

View File

@@ -1,35 +1,3 @@
#sideToolbarContainer {
background-color: $chatBackgroundColor;
flex-shrink: 0;
overflow: hidden;
position: relative;
transition: width .16s ease-in-out;
width: $sidebarWidth;
z-index: $sideToolbarContainerZ;
@media (max-width: 580px) {
height: 100vh;
height: -webkit-fill-available;
left: 0;
position: fixed;
right: 0;
top: 0;
width: auto;
}
}
.chat-panel {
display: flex;
flex-direction: column;
// extract header + tabs height
height: calc(100% - 119px);
}
.chat-panel-no-tabs {
// extract header height
height: calc(100% - 70px);
}
#chat-conversation-container {
// extract message input height
height: calc(100% - 64px);
@@ -76,27 +44,6 @@
}
}
.chat-header {
height: 70px;
position: relative;
width: 100%;
z-index: 1;
display: flex;
justify-content: space-between;
padding: 16px;
align-items: center;
box-sizing: border-box;
color: #fff;
font-weight: 600;
font-size: 24px;
line-height: 32px;
.jitsi-icon {
cursor: pointer;
}
}
.chat-input-container {
padding: 0 16px 24px;
}
@@ -112,61 +59,6 @@
margin-right: 8px;
}
.smiley-button {
display: flex;
align-items: center;
justify-content: center;
height: 38px;
width: 38px;
margin: 2px;
border-radius: 3px;
}
#chat-input .smiley-button {
@media (hover: hover) and (pointer: fine) {
&:hover {
background-color: #484A4F;
}
}
}
.remoteuser {
color: #B8C7E0;
}
.usrmsg-form {
flex: 1;
}
#usermsg {
-ms-overflow-style: none;
border: 0px none;
border-radius:0;
box-shadow: none;
color: white;
font-size: 14px;
padding: 10px;
overflow-y: auto;
resize: none;
scrollbar-width: none;
width: 100%;
word-break: break-word;
&::-webkit-scrollbar {
display: none;
}
}
#usermsg:hover {
border: 0px none;
box-shadow: none;
}
#usermsg:focus,
#usermsg:active {
border-bottom: 1px solid white;
padding-bottom: 8px;
}
#nickname {
text-align: center;
color: #9d9d9d;
@@ -174,11 +66,6 @@
margin: auto 0;
padding: 0 16px;
#nickname-title {
margin-bottom: 5px;
display: block;
}
label[for="nickinput"] {
> div > span {
color: #B8C7E0;
@@ -191,24 +78,6 @@
label {
line-height: 24px;
}
.enter-chat {
display: flex;
align-items: center;
justify-content: center;
margin-top: 16px;
height: 40px;
background: #1B67EC;
border-radius: 3px;
color: #fff;
cursor: pointer;
&.disabled {
color: #AFB6BC;
background: #11336E;
pointer-events: none;
}
}
}
.mobile-browser {
@@ -216,14 +85,6 @@
input {
height: 48px;
}
.enter-chat {
height: 48px;
}
}
#usermsg {
font-size: 16px;
}
.chatmessage .usermessage {
@@ -231,32 +92,7 @@
}
}
.sideToolbarContainer {
* {
-webkit-user-select: text;
user-select: text;
}
}
.sr-only {
border: 0 !important;
clip: rect(1px, 1px, 1px, 1px) !important;
clip-path: inset(50%) !important;
height: 1px !important;
margin: -1px !important;
overflow: hidden !important;
padding: 0 !important;
position: absolute !important;
width: 1px !important;
white-space: nowrap !important;
}
.chatmessage {
&.localuser {
background-color: $chatLocalMessageBackgroundColor;
border-radius: 6px 0px 6px 6px;
}
&.error {
border-radius: 0px;
@@ -288,13 +124,6 @@
padding: 2px;
}
#smileysarea {
display: flex;
max-height: 150px;
min-height: 35px;
overflow: hidden;
}
.smiley-input {
display: flex;
position: absolute;
@@ -324,7 +153,7 @@
#smileysContainer {
background-color: $chatBackgroundColor;
border-top: 1px solid $chatInputSeparatorColor;
border-top: 1px solid #A4B8D1;
}
}
@@ -340,15 +169,11 @@
}
.smileyContainer:hover {
background-color: $newToolbarButtonToggleColor;
background-color: rgba(255, 255, 255, 0.15);
border-radius: 5px;
cursor: pointer;
}
#usermsg::-webkit-scrollbar-track-piece {
background: #3a3a3a;
}
.chat-message-group {
&.local {
align-items: flex-end;

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);
}
@@ -28,18 +28,6 @@
margin-bottom: env(safe-area-inset-bottom, 0);
width: 100%;
.drawer-toggle {
display: flex;
justify-content: center;
align-items: center;
height: 44px;
cursor: pointer;
svg {
fill: none;
}
}
&#{&} .overflow-menu {
margin: auto;
font-size: 1.2em;
@@ -54,7 +42,7 @@
padding: 12px 16px;
align-items: center;
color: $overflowMenuItemColor;
color: #fff;
cursor: pointer;
display: flex;
font-size: 16px;
@@ -65,25 +53,10 @@
align-items: center;
}
&.unclickable {
cursor: default;
}
@media (hover: hover) and (pointer: fine) {
&.unclickable:hover {
background: inherit;
}
}
&.disabled {
cursor: initial;
color: #3b475c;
}
}
.profile-text {
max-width: 100%;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
}
}

View File

@@ -1,21 +0,0 @@
#e2ee-section {
display: flex;
flex-direction: column;
.description {
font-size: 13px;
margin: 15px 0;
}
.control-row {
display: flex;
flex-direction: row;
justify-content: space-between;
margin-top: 15px;
label {
font-size: 14px;
font-weight: bold;
}
}
}

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,18 +1,4 @@
/*Initialize*/
div.loginmenu {
position: absolute;
margin: 0;
padding: 5px;
top: 40px;
left: 20px;
}
a.disabled {
color: gray !important;
pointer-events: none;
}
.loginmenu.extendedToolbarPopup {
top: 20px;
left: 40px;
}

View File

@@ -1,4 +1,3 @@
.filmstrip-toolbox,
.always-on-top-toolbox {
background-color: $newToolbarBackgroundColor;
border-radius: 3px;
@@ -29,7 +28,3 @@
transform: translateX(-50%);
padding: 3px !important;
}
.filmstrip-toolbox {
flex-direction: column;
}

View File

@@ -1,29 +0,0 @@
.jqistates {
font-size: 14px;
}
.jqistates h2 {
padding-bottom: 10px;
border-bottom: 1px solid #eee;
font-size: 18px;
line-height: 25px;
text-align: center;
color: #424242;
}
.jqistates input {
margin: 10px 0;
}
.jqistates input[type='text'], input[type='password'] {
width: 100%;
}
button.jqidefaultbutton #inviteLinkRef {
color: #2c8ad2;
}
#inviteLinkRef {
-webkit-user-select: text;
user-select: text;
}

View File

@@ -75,6 +75,3 @@
margin-bottom: 36px;
width: 100%;
}
.navigate-section-list-empty {
text-align: center;
}

View File

@@ -1,15 +0,0 @@
.notice {
position: absolute;
left: 50%;
z-index: $zindex3;
margin-top: 6px;
@include transform(translateX(-50%));
&__message {
background-color: #000000;
color: white;
padding: 3px;
border-radius: 5px;
}
}

View File

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

View File

@@ -1,3 +0,0 @@
.polls-panel {
height: calc(100% - 119px);
}

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

@@ -1,7 +1,3 @@
.recordingSpinner {
vertical-align: top;
}
.recording-dialog {
flex: 0;
flex-direction: column;
@@ -50,10 +46,6 @@
}
}
.recording-switch-disabled {
opacity: 0.5;
}
.recording-icon-container {
display: inline-flex;
align-items: center;
@@ -156,8 +148,7 @@
*/
font-size: 14px;
.broadcast-dropdown,
.broadcast-dropdown-trigger {
.broadcast-dropdown {
text-align: left;
}
@@ -186,7 +177,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

@@ -34,14 +34,6 @@
}
}
.subject-info {
align-items: center;
display: flex;
margin-bottom: 4px;
max-width: 80%;
height: 28px;
}
.details-container {
width: 100%;
display: flex;

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;
@@ -58,21 +58,6 @@
z-index: $toolbarZ;
pointer-events: none;
.button-group-center,
.button-group-left,
.button-group-right {
display: flex;
width: 33%;
}
.button-group-center {
justify-content: center;
}
.button-group-right {
justify-content: flex-end;
}
.toolbox-button-wth-dialog {
display: inline-block;
}
@@ -112,16 +97,6 @@
padding-bottom: env(safe-area-inset-bottom, 0);
}
.beta-tag {
background: #36383C;
border-radius: 3px;
color: #fff;
font-size: 12px;
margin-left: 8px;
padding: 0 4px;
text-transform: uppercase;
}
.overflow-menu-hr {
border-top: 1px solid #4C4D50;
border-bottom: 0;
@@ -192,7 +167,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

@@ -3,7 +3,7 @@
}
.hidden {
display: none;
display: none;
}
/**
@@ -24,24 +24,6 @@
display: block !important;
}
/**
* Shows an inline element.
*/
.show-inline {
display: inline-block !important;
}
/**
* Shows a flex element.
*/
.show-flex {
display: -webkit-box !important;
display: -moz-box !important;
display: -ms-flexbox !important;
display: -webkit-flex !important;
display: flex !important;
}
/**
* resets default button styles,
* mostly intended to be used on interactive elements that

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

@@ -189,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;
@@ -205,27 +205,10 @@
border-radius: 50%;
-webkit-filter: blur(0.5px);
filter: blur(0.5px);
background: $audioLevelBg;
background: #44A5FF;
}
}
#reloadPresentation {
display: none;
position: absolute;
color: #FFFFFF;
top: 0;
right:0;
padding: 10px 10px;
font-size: 11pt;
cursor: pointer;
background: rgba(0, 0, 0, 0.3);
border-radius: 5px;
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!*/
}
#dominantSpeaker {
visibility: hidden;
width: 300px;
@@ -236,10 +219,6 @@
transform: translateY(-50%);
}
#mixedstream {
display:none !important;
}
#dominantSpeakerAvatarContainer,
.dynamic-shadow {
width: 200px;
@@ -309,11 +288,6 @@
object-fit: cover;
}
.videoMessageFilter {
-webkit-filter: grayscale(.5) opacity(0.8);
filter: grayscale(.5) opacity(0.8);
}
#remotePresenceMessage,
#remoteConnectionMessage {
position: absolute;
@@ -365,7 +339,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

@@ -37,7 +37,6 @@ $flagsImagePath: "../images/";
@import 'modals/screen-share/share-audio';
@import 'modals/screen-share/share-screen-warning';
@import 'videolayout_default';
@import 'notice';
@import 'subject';
@import 'popup_menu';
@import 'recording';
@@ -73,12 +72,10 @@ $flagsImagePath: "../images/";
@import 'premeeting/main';
@import 'modals/invite/invite_more';
@import 'modals/security/security';
@import 'e2ee';
@import 'responsive';
@import 'drawer';
@import 'participants-pane';
@import 'reactions-menu';
@import 'plan-limit';
@import 'polls';
/* Modules END */

View File

@@ -2,8 +2,8 @@
margin-top: 5px !important;
.input-control {
background: $modalMockAKInputBackground;
border: $modalMockAKInputBorder;
background: #fafbfc;
border: 1px solid #f4f5f7;
color: inherit;
}

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;

23
inlang.config.js Normal file
View File

@@ -0,0 +1,23 @@
/**
* @type { import("@inlang/core/config").DefineConfig }
*/
export async function defineConfig(env) {
const { default: i18nextPlugin } = await env.$import(
'https://cdn.jsdelivr.net/npm/@inlang/plugin-i18next@2/dist/index.js'
);
const { default: standardLintRules } = await env.$import(
'https://cdn.jsdelivr.net/npm/@inlang/plugin-standard-lint-rules@3/dist/index.js'
);
return {
referenceLanguage: 'main',
plugins: [
i18nextPlugin({
pathPattern: 'lang/{language}.json',
ignore: [ 'languages.json', 'translation-languages.json' ]
}),
standardLintRules()
]
};
}

View File

@@ -14,14 +14,14 @@ PODS:
- CocoaLumberjack/Core (= 3.7.2)
- CocoaLumberjack/Core (3.7.2)
- DoubleConversion (1.1.6)
- FBLazyVector (0.69.10)
- FBReactNativeSpec (0.69.10):
- FBLazyVector (0.69.11)
- FBReactNativeSpec (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- RCTRequired (= 0.69.10)
- RCTTypeSafety (= 0.69.10)
- React-Core (= 0.69.10)
- React-jsi (= 0.69.10)
- ReactCommon/turbomodule/core (= 0.69.10)
- RCTRequired (= 0.69.11)
- RCTTypeSafety (= 0.69.11)
- React-Core (= 0.69.11)
- React-jsi (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- Firebase/Analytics (8.15.0):
- Firebase/Core
- Firebase/Core (8.15.0):
@@ -164,203 +164,203 @@ PODS:
- DoubleConversion
- fmt (~> 6.2.1)
- glog
- 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):
- RCTRequired (0.69.11)
- RCTTypeSafety (0.69.11):
- FBLazyVector (= 0.69.11)
- RCTRequired (= 0.69.11)
- React-Core (= 0.69.11)
- React (0.69.11):
- React-Core (= 0.69.11)
- React-Core/DevSupport (= 0.69.11)
- React-Core/RCTWebSocket (= 0.69.11)
- React-RCTActionSheet (= 0.69.11)
- React-RCTAnimation (= 0.69.11)
- React-RCTBlob (= 0.69.11)
- React-RCTImage (= 0.69.11)
- React-RCTLinking (= 0.69.11)
- React-RCTNetwork (= 0.69.11)
- React-RCTSettings (= 0.69.11)
- React-RCTText (= 0.69.11)
- React-RCTVibration (= 0.69.11)
- React-bridging (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsi (= 0.69.10)
- React-callinvoker (0.69.10)
- React-Codegen (0.69.10):
- FBReactNativeSpec (= 0.69.10)
- React-jsi (= 0.69.11)
- React-callinvoker (0.69.11)
- React-Codegen (0.69.11):
- FBReactNativeSpec (= 0.69.11)
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- RCTRequired (= 0.69.11)
- RCTTypeSafety (= 0.69.11)
- React-Core (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-Core (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- 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)
- React-Core/Default (= 0.69.11)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/CoreModulesHeaders (0.69.10):
- React-Core/CoreModulesHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/Default (0.69.10):
- React-Core/Default (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/DevSupport (0.69.10):
- React-Core/DevSupport (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- 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)
- React-Core/Default (= 0.69.11)
- React-Core/RCTWebSocket (= 0.69.11)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-jsinspector (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTActionSheetHeaders (0.69.10):
- React-Core/RCTActionSheetHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTAnimationHeaders (0.69.10):
- React-Core/RCTAnimationHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTBlobHeaders (0.69.10):
- React-Core/RCTBlobHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTImageHeaders (0.69.10):
- React-Core/RCTImageHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTLinkingHeaders (0.69.10):
- React-Core/RCTLinkingHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTNetworkHeaders (0.69.10):
- React-Core/RCTNetworkHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTSettingsHeaders (0.69.10):
- React-Core/RCTSettingsHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTTextHeaders (0.69.10):
- React-Core/RCTTextHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTVibrationHeaders (0.69.10):
- React-Core/RCTVibrationHeaders (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-Core/Default
- React-cxxreact (= 0.69.10)
- React-jsi (= 0.69.10)
- React-jsiexecutor (= 0.69.10)
- React-perflogger (= 0.69.10)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-Core/RCTWebSocket (0.69.10):
- React-Core/RCTWebSocket (0.69.11):
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- 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)
- React-Core/Default (= 0.69.11)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsiexecutor (= 0.69.11)
- React-perflogger (= 0.69.11)
- Yoga
- React-CoreModules (0.69.10):
- React-CoreModules (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- RCTTypeSafety (= 0.69.11)
- React-Codegen (= 0.69.11)
- React-Core/CoreModulesHeaders (= 0.69.11)
- React-jsi (= 0.69.11)
- React-RCTImage (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-cxxreact (0.69.11):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- React-callinvoker (= 0.69.11)
- React-jsi (= 0.69.11)
- React-jsinspector (= 0.69.11)
- React-logger (= 0.69.11)
- React-perflogger (= 0.69.11)
- React-runtimeexecutor (= 0.69.11)
- React-jsi (0.69.11):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsi/Default (= 0.69.10)
- React-jsi/Default (0.69.10):
- React-jsi/Default (= 0.69.11)
- React-jsi/Default (0.69.11):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- React-jsiexecutor (0.69.10):
- React-jsiexecutor (0.69.11):
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-perflogger (= 0.69.11)
- React-jsinspector (0.69.11)
- React-logger (0.69.11):
- glog
- react-native-background-timer (2.4.1):
- React-Core
@@ -374,7 +374,7 @@ PODS:
- React-Core
- react-native-pager-view (5.4.9):
- React-Core
- react-native-safe-area-context (4.4.1):
- react-native-safe-area-context (4.6.4):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
@@ -390,77 +390,77 @@ PODS:
- react-native-video/Video (6.0.0-alpha.1):
- PromisesSwift
- React-Core
- react-native-webrtc (111.0.1):
- react-native-webrtc (111.0.3):
- JitsiWebRTC (~> 111.0.0)
- React-Core
- react-native-webview (11.15.1):
- React-Core
- React-perflogger (0.69.10)
- React-RCTActionSheet (0.69.10):
- React-Core/RCTActionSheetHeaders (= 0.69.10)
- React-RCTAnimation (0.69.10):
- React-perflogger (0.69.11)
- React-RCTActionSheet (0.69.11):
- React-Core/RCTActionSheetHeaders (= 0.69.11)
- React-RCTAnimation (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- RCTTypeSafety (= 0.69.11)
- React-Codegen (= 0.69.11)
- React-Core/RCTAnimationHeaders (= 0.69.11)
- React-jsi (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-RCTBlob (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- React-Codegen (= 0.69.11)
- React-Core/RCTBlobHeaders (= 0.69.11)
- React-Core/RCTWebSocket (= 0.69.11)
- React-jsi (= 0.69.11)
- React-RCTNetwork (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-RCTImage (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- RCTTypeSafety (= 0.69.11)
- React-Codegen (= 0.69.11)
- React-Core/RCTImageHeaders (= 0.69.11)
- React-jsi (= 0.69.11)
- React-RCTNetwork (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-RCTLinking (0.69.11):
- React-Codegen (= 0.69.11)
- React-Core/RCTLinkingHeaders (= 0.69.11)
- React-jsi (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-RCTNetwork (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- RCTTypeSafety (= 0.69.11)
- React-Codegen (= 0.69.11)
- React-Core/RCTNetworkHeaders (= 0.69.11)
- React-jsi (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-RCTSettings (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- RCTTypeSafety (= 0.69.11)
- React-Codegen (= 0.69.11)
- React-Core/RCTSettingsHeaders (= 0.69.11)
- React-jsi (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-RCTText (0.69.11):
- React-Core/RCTTextHeaders (= 0.69.11)
- React-RCTVibration (0.69.11):
- RCT-Folly (= 2021.06.28.00-v2)
- 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):
- React-Codegen (= 0.69.11)
- React-Core/RCTVibrationHeaders (= 0.69.11)
- React-jsi (= 0.69.11)
- ReactCommon/turbomodule/core (= 0.69.11)
- React-runtimeexecutor (0.69.11):
- React-jsi (= 0.69.11)
- ReactCommon/turbomodule/core (0.69.11):
- DoubleConversion
- glog
- RCT-Folly (= 2021.06.28.00-v2)
- 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)
- React-bridging (= 0.69.11)
- React-callinvoker (= 0.69.11)
- React-Core (= 0.69.11)
- React-cxxreact (= 0.69.11)
- React-jsi (= 0.69.11)
- React-logger (= 0.69.11)
- React-perflogger (= 0.69.11)
- RNCalendarEvents (2.2.0):
- React
- RNCAsyncStorage (1.17.3):
@@ -476,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):
@@ -706,8 +706,8 @@ SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: a8af91c2b5a0029d12ff6b32e428863d63c48991
FBReactNativeSpec: ec5e878f6452a3de5430e0b2324a4d4ae6ac63f6
FBLazyVector: 5c0975e66853436589eae7542f4b956c7e2ef465
FBReactNativeSpec: bb062293e84c33200005312d1807d8cb94a0d66a
Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
FirebaseAnalytics: 7761cbadb00a717d8d0939363eb46041526474fa
FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1
@@ -732,43 +732,43 @@ SPEC CHECKSUMS:
PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef
PromisesSwift: cf9eb58666a43bbe007302226e510b16c1e10959
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
RCTRequired: 8e9a57dddc8f8e9e816c67c2d2537271a997137a
RCTTypeSafety: 2b19e268e2036a2c2f6db6deb1ac03e28b1d607a
React: f9478e6390f177ee6b67b87a3c6afea42b39523e
React-bridging: d405ecd3ff80e1d0a4059a11063eaa9ed7a00c58
React-callinvoker: c8ffa61f3f06f486ba6647769fc98f19e25d165a
React-Codegen: 73acfdac1495b91ad5efdd3ab005568263c5def6
React-Core: 7b7c75af4b73fe0ed4e5c3cdb7d79979e81148dc
React-CoreModules: cd6e7efb38162884f08c7afa16fffaf15ff28ae4
React-cxxreact: 51157cc600c9f436a7e623913a03b775305ef86c
React-jsi: 3eeb345c4828d7b132fd38064a305f31b46d4ec3
React-jsiexecutor: 5813455a4a908fb7284aa13307a9e0386e93b0bb
React-jsinspector: 9ca5bf73ed0a195397e45fdbcd507cf7d503c428
React-logger: 700340e325f21ba2a2d6413a61ef14268c7360aa
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-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: 2702afae1e59882b423e6077768ca0d1e6fc42ed
react-native-webrtc: 4d1669c2ed29767fe70b0169428b4466589ecf8b
react-native-webview: ea4899a1056c782afa96dd082179a66cbebf5504
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
React-perflogger: fdee2a0c512167ae4c19c4e230ccf6aa66a6aff0
React-RCTActionSheet: 1cf5fef4e372f1c877969710a51bea4bb25e78fe
React-RCTAnimation: 73816e3acd1f5e3f00166fc7eedb34f6b112f734
React-RCTBlob: 6976c838fb14a1daf75d7c8bb23bae9cbbf726bb
React-RCTImage: ab8a7498f215117f32271698591e4bd932dcf812
React-RCTLinking: e8e78aed2744ab9946cc8ba5716b4938c2efb1e0
React-RCTNetwork: 796f5aed4d932655d292bdc6b40f9502dcdb9542
React-RCTSettings: 7e1cd2a384b45c90caf67464572abe3833b9da3b
React-RCTText: fd6162890828f0761e03c59058fa23c3a21b2e10
React-RCTVibration: 302cfd5cc33669d7abdb7ec6790123baba66e62e
React-runtimeexecutor: 59407514818b2afbb1d7507e4e1ac834d24b0fbd
ReactCommon: b8487da74723562d7368dab27135fd182f00a91c
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: d24d6184b6b85f742536bd93bd07d69d7b9bb4c1
Yoga: 7f5ad94937ba3fc58c151ad1b7bbada2c275b28e
PODFILE CHECKSUM: e3579df5272b8b697c9fdc0e55aa0845b189c4dd
COCOAPODS: 1.11.3
COCOAPODS: 1.12.1

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",
@@ -254,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"
@@ -459,6 +464,9 @@
"title": "Diese Konferenz einbetten"
},
"feedback": {
"accessibilityLabel": {
"yourChoice": "Ihre Auswahl: {{rating}}"
},
"average": "Durchschnittlich",
"bad": "Schlecht",
"detailsLabel": "Sagen Sie uns mehr dazu.",
@@ -1065,6 +1073,7 @@
"links": "Links",
"privacy": "Datenschutz",
"profileSection": "Profil",
"sdkVersion": "SDK-Version",
"serverURL": "Server-URL",
"showAdvanced": "Erweiterte Einstellungen anzeigen",
"startCarModeInLowBandwidthMode": "Automodus mit Datensparmodus starten",
@@ -1383,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.",

File diff suppressed because it is too large Load Diff

View File

@@ -78,7 +78,6 @@
},
"carmode": {
"actions": {
"leaveMeeting": " Opuść spotkanie",
"selectSoundDevice": "Wybierz urządzenie dźwiękowe"
},
"labels": {
@@ -97,6 +96,7 @@
"messageAccessibleTitleMe": "mówię:",
"messageTo": "Prywatna wiadomość do {{recipient}}",
"messagebox": "Wpisz wiadomość",
"newMessages": "Nowe wiadomości",
"nickname": {
"popover": "Wybierz swój nick",
"title": "Wpisz swoją nazwę, aby użyć rozmowy",
@@ -107,12 +107,12 @@
"sendButton": "Wyślij",
"smileysPanel": "Panel emoji",
"tabs": {
"chat": "Chat",
"chat": "Czat",
"polls": "Ankiety"
},
"title": "Rozmowa",
"titleWithPolls": "Rozmowa",
"you": "Ty"
"title": "Czat",
"titleWithPolls": "Czat i Ankiety",
"you": "ja"
},
"chromeExtensionBanner": {
"buttonText": "Zainstaluj rozszerzenie Chrome",
@@ -137,7 +137,7 @@
"FETCH_SESSION_ID": "Uzyskiwanie id sesji...",
"GET_SESSION_ID_ERROR": "Nie można uzyskać id sesji. Błąd: {{code}}",
"GOT_SESSION_ID": "Uzyskiwanie id sesji... Gotowe",
"LOW_BANDWIDTH": "Wideo {{displayName}} zostało wyłączone w celu oszczędności zasobów"
"LOW_BANDWIDTH": "Wideo {{displayName}} zostało wyłączone w celu zaoszczędzenia przepustowości sieci"
},
"connectionindicator": {
"address": "Adres:",
@@ -147,6 +147,7 @@
"bridgeCount": "Liczba serwerów: ",
"codecs": "Kodeki (A/V): ",
"connectedTo": "Podłączone do:",
"e2eeVerified": "E2EE zweryfikowane:",
"framerate": "Klatek na sekundę:",
"less": "Pokaż mniej",
"localaddress": "Adres lokalny:",
@@ -155,6 +156,7 @@
"localport_plural": "Porty lokalne:",
"maxEnabledResolution": "wyślij maksymalną",
"more": "Pokaż więcej",
"no": "nie",
"packetloss": "Utrata pakietów:",
"participant_id": "ID uczestnika:",
"quality": {
@@ -173,7 +175,8 @@
"status": "Połączenie:",
"transport": "Transport:",
"transport_plural": "Transporty:",
"video_ssrc": "Video SSRC:"
"video_ssrc": "Video SSRC:",
"yes": "tak"
},
"dateUtils": {
"earlier": "Wcześniej",
@@ -183,13 +186,21 @@
"deepLinking": {
"appNotInstalled": "Potrzebujesz aplikacji mobilnej {{app}}, aby móc dołączyć do tego spotkania przez telefon.",
"description": "Nic się nie wydarzyło? Spróbowaliśmy uruchomić Twoje spotkanie w aplikacji stacjonarnej {{app}}. Spróbuj ponownie lub uruchom spotkanie w aplikacji webowej {{app}}.",
"descriptionNew": "Nic się nie stało? Próbowaliśmy uruchomić Twoje spotkanie w aplikacji stacjonarnej {{app}}. <br /><br /> Spróbuj ponownie lub uruchom spotkanie w aplikacji webowej.",
"descriptionWithoutWeb": "Nic się nie wydarzyło? Spróbowaliśmy uruchomić Twoje spotkanie w aplikacji stacjonarnej {{app}}.",
"downloadApp": "Pobierz aplikację",
"downloadMobileApp": "Pobierz ze sklepu App Store",
"ifDoNotHaveApp": "Jeśli nie masz jeszcze aplikacji:",
"ifHaveApp": "Jeśli już masz aplikację:",
"joinInApp": "Dołącz do spotkania używając aplikacji",
"joinInAppNew": "Dołącz w aplikacji",
"joinInBrowser": "Dołącz w przeglądarce",
"launchMeetingLabel": "Jak chcesz dołączyć do tego spotkania?",
"launchWebButton": "Uruchom przez przeglądarkę",
"noMobileApp": "Nie masz aplikacji?",
"termsAndConditions": "Kontynuując zgadzasz się na nasze <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>Zasady i Warunki.</a>",
"title": "Trwa uruchamianie Twojego spotkania w {{app}}...",
"titleNew": "Rozpoczynam spotkanie...",
"tryAgainButton": "Spróbuj ponownie w aplikacji stacjonarnej",
"unsupportedBrowser": "Wygląda na to, że używasz przeglądarki, której nie wspieramy."
},
@@ -202,6 +213,12 @@
"microphonePermission": "Błąd podczas otrzymywania uprawnień do mikrofonu"
},
"deviceSelection": {
"hid": {
"callControl": "Kontrola połączeń",
"connectedDevices": "Połączone urządzenia:",
"deleteDevice": "Usuń urządzenie",
"pairDevice": "Sparuj urządzenie"
},
"noPermission": "Nie przyznano uprawnienia",
"previewUnavailable": "Podgląd niedostępny",
"selectADevice": "Wybierz urządzenie",
@@ -225,7 +242,9 @@
"WaitingForHostTitle": "Oczekiwanie na gospodarza...",
"Yes": "Tak",
"accessibilityLabel": {
"liveStreaming": "Transmisja na żywo"
"close": "Zamknij okno dialogowe",
"liveStreaming": "Transmisja na żywo",
"sharingTabs": "Opcje udostępniania"
},
"add": "Dodaj",
"addMeetingNote": "Dodaj notatkę o tym spotkaniu",
@@ -245,7 +264,7 @@
"cameraUnsupportedResolutionError": "Twoja kamera nie obsługuje wymaganej rozdzielczości.",
"close": "Zamknij",
"conferenceDisconnectMsg": "Być może należy sprawdzić połączenie sieciowe. Ponowne połączenie za {{seconds}} sekund...",
"conferenceDisconnectTitle": "Zostałeś rozłączony.",
"conferenceDisconnectTitle": "Nastąpiło rozłączenie.",
"conferenceReloadMsg": "Staramy się to naprawić. Ponowne połączenie za {{seconds}} sekund...",
"conferenceReloadTitle": "Niestety, coś poszło nie tak.",
"confirm": "Potwierdź",
@@ -271,6 +290,7 @@
"gracefulShutdown": "Usługa aktualnie jest niedostępna. Prosze spróbować później.",
"grantModeratorDialog": "Czy na pewno chcesz przyznać temu uczestnikowi prawa moderatora?",
"grantModeratorTitle": "Przyznaj prawa moderatora",
"hide": "Ukryj",
"hideShareAudioHelper": "Nie pokazuj więcej",
"incorrectPassword": "Niepoprawna nazwa użytkownika lub hasło",
"incorrectRoomLockPassword": "Hasło nieprawidłowe",
@@ -301,8 +321,8 @@
"micPermissionDeniedError": "Nie udzieliłeś pozwolenia na użycie twojego mikrofonu. Nadal możesz uczestniczyc w konferencji ale inni nie będą cię słyszeli. Użyj przycisku kamera aby to naprawić.",
"micTimeoutError": "Nie udało się uruchomić źródła dźwięku. Przekroczono limit czasu",
"micUnknownError": "Z nieznanej przyczyny nie można użyć mikrofonu.",
"moderationAudioLabel": "Zezwalaj uczestnikom na wyłączanie wyciszenia",
"moderationVideoLabel": "Zezwalaj uczestnikom na rozpoczęcie wideo",
"moderationAudioLabel": "Zezwalaj uczestnikom na włączenie mikrofonów",
"moderationVideoLabel": "Zezwalaj uczestnikom na włączenie kamer",
"muteEveryoneDialog": "Uczestnicy mogą w dowolnym momencie wyłączyć wyciszenie.",
"muteEveryoneDialogModerationOn": "Uczestnicy mogą w każdej chwili wysłać prośbę o zabranie głosu.",
"muteEveryoneElseDialog": "Gdy wyciszysz wszystkich nie będziesz miał możliwości wyłączyć ich wyciszenia, ale oni będą mogli samodzielnie wyłączyć wyciszenie w dowolnym momencie.",
@@ -312,15 +332,15 @@
"muteEveryoneSelf": "siebie",
"muteEveryoneStartMuted": "Od tego momentu wszyscy są wyciszeni",
"muteEveryoneTitle": "Wyciszyć wszystkich?",
"muteEveryonesVideoDialog": "Uczestnicy mogą w każdej chwili włączyć swoje wideo.",
"muteEveryonesVideoDialogModerationOn": "Uczestnicy mogą w dowolnym momencie wysłać prośbę o włączenie ich wideo.",
"muteEveryonesVideoDialog": "Uczestnicy mogą w każdej chwili włączyć swoje kamery.",
"muteEveryonesVideoDialogModerationOn": "Uczestnicy mogą w dowolnym momencie wysłać prośbę o włączenie ich kamer.",
"muteEveryonesVideoDialogOk": "Wyłącz",
"muteEveryonesVideoTitle": "Wyłączyć kamery pozostałych uczestników?",
"muteParticipantBody": "Nie możesz wyłączyć ich wyciszenia, ale oni mogą samodzielnie wyłączyć wyciszenie w dowolnym momencie.",
"muteParticipantButton": "Wycisz",
"muteParticipantsVideoBody": "Nie będziesz mógł włączyć jego kamery ponownie, ale uczestnik samodzielnie może włączyć kamerę w dowolnym momencie.",
"muteParticipantsVideoBodyModerationOn": "Nie będziesz w stanie ponownie włączyć kamery i oni też nie.",
"muteParticipantsVideoButton": "Wyłącz kamerę",
"muteParticipantsVideoButton": "Wyłącz kamery",
"muteParticipantsVideoDialog": "Czy na pewno chcesz wyłączyć kamerę tego uczestnika? Nie będziesz mógł ponownie włączyć jego kamery, ale będzie on mógł samodzielnie włączyć kamerę w dowolnym momencie.",
"muteParticipantsVideoDialogModerationOn": "Czy na pewno chcesz wyłączyć kamerę tego uczestnika? Nie będziesz w stanie ponownie włączyć aparatu i oni też nie.",
"muteParticipantsVideoTitle": "Wyłączyć kamerę tego uczestnika?",
@@ -388,6 +408,7 @@
"shareYourScreenDisabled": "Udostępnianie ekranu wyłączone.",
"sharedVideoDialogError": "Błąd: nieprawidłowy adres URL",
"sharedVideoLinkPlaceholder": "Link do YouTube lub bezpośredni link do wideo",
"show": "Pokaż",
"start": "Rozpocznij ",
"startLiveStreaming": "Rozpocznij transmisję na żywo",
"startRecording": "Rozpocznij nagrywanie",
@@ -406,6 +427,10 @@
"user": "Użytkownik",
"userIdentifier": "Nazwa użytkownika",
"userPassword": "hasło użytkownika",
"verifyParticipantConfirm": "Pasują",
"verifyParticipantDismiss": "Nie pasują",
"verifyParticipantQuestion": "EKSPERYMENT: Zapytaj uczestnika {{participantName}}, czy widzi tę samą treść, w tej samej kolejności.",
"verifyParticipantTitle": "Weryfikacja użytkownika",
"videoLink": "Link do video",
"viewUpgradeOptions": "Pokaż opcje aktualizacji",
"viewUpgradeOptionsContent": "Musisz uaktualnić swój plan, aby korzystać z funkcji premium, takich jak nagrywanie, transkrypcja, przesyłanie strumieniowe RTMP i nie tylko.",
@@ -416,7 +441,7 @@
"title": "Udostępniony dokument"
},
"e2ee": {
"labelToolTip": "To połączenie audio i wideo jest szyfrowane"
"labelToolTip": "To połączenie audio i wideo jest szyfrowane end-to-end"
},
"embedMeeting": {
"title": "Osadź to spotkanie"
@@ -431,13 +456,15 @@
"veryBad": "Bardzo źle",
"veryGood": "Bardzo dobrze"
},
"filmstrip": {
"accessibilityLabel": {
"heading": "Miniatury wideo"
}
},
"giphy": {
"noResults": "Nie znaleziono wyników :(",
"search": "Szukaj GIPHY"
},
"helpView": {
"title": "Centrum pomocy"
},
"incomingCall": {
"answer": "Odbierz",
"audioCallTitle": "Przychodzące połączenie",
@@ -478,9 +505,11 @@
"noRoom": "Nie podano pokoju do wdzwonienia.",
"numbers": "Numery do wdzwonienia",
"password": "$t(lockRoomPasswordUppercase):",
"reachedLimit": "Osiągnąłeś limit swojego planu.",
"sip": "Adres SIP",
"title": "Udostępnij",
"tooltip": "Udostępnij odnośnik i informacje do wdzwonienia się na to spotkanie"
"tooltip": "Udostępnij odnośnik i informacje do wdzwonienia się na to spotkanie",
"upgradeOptions": "Sprawdź opcje aktualizacji na"
},
"inlineDialogFailure": {
"msg": "Nieco niedopisaliśmy.",
@@ -515,6 +544,10 @@
"toggleShortcuts": "Wyświetl lub ukryj skróty klawiaturowe",
"videoMute": "Uruchom lub zatrzymaj kamerę"
},
"largeVideo": {
"screenIsShared": "Udostępniasz swój ekran",
"showMeWhatImSharing": "Pokaż mi, co udostępniam"
},
"liveStreaming": {
"busy": "Pracujemy nad zwolnieniem zasobów transmisyjnych. Spróbuj ponownie za kilka minut.",
"busyTitle": "Wszyscy transmitujący są aktualnie zajęci",
@@ -555,7 +588,6 @@
"lobby": {
"admit": "Pozwól",
"admitAll": "Pozwól wszystkim",
"allow": "Zezwól",
"backToKnockModeButton": "Brak hasła, poproś o dołączenie",
"chat": "Chat",
"dialogTitle": "Lobby",
@@ -618,6 +650,7 @@
"no": "Nie",
"participant": "Uczestnik",
"participantStats": "Statystyki uczestników",
"selectTabTitle": "🎥 Wybierz tę zakładkę do nagrywania",
"sessionToken": "Token sesji",
"start": "Rozpocznij nagrywanie",
"stop": "Zatrzymaj nagrywanie",
@@ -640,8 +673,12 @@
"connectedOneMember": "{{name}} dołączył do spotkania",
"connectedThreePlusMembers": "{{name}} i {{count}} innych osób dołączyło do spotkania",
"connectedTwoMembers": "{{first}} i {{second}} dołączyli do spotkania",
"dataChannelClosed": "Pogorszona jakość wideo",
"dataChannelClosedDescription": "Kanał bridge został odłączony, przez co jakość wideo jest ograniczona do najniższego ustawienia.",
"disabledIframe": "Osadzanie jest przeznaczone wyłącznie do celów demonstracyjnych, więc to połączenie zostanie rozłączone za {{timeout}} minut.",
"disconnected": "Rozłączono",
"displayNotifications": "Wyświetlaj powiadomienia dla",
"dontRemindMe": "Nie przypominaj mi",
"focus": "Fokus konferencji",
"focusFail": "{{component}} jest niedostępny - ponowienie w ciągu {{ms}} sec",
"gifsMenu": "GIPHY",
@@ -650,6 +687,7 @@
"invitedOneMember": "{{name}} został zaproszony",
"invitedThreePlusMembers": "{{name}} i {{count}} innych osób zostało zaproszone",
"invitedTwoMembers": "{{first}} i {{second}} zostali zaproszeni",
"joinMeeting": "Dołącz",
"kickParticipant": "{{kicked}} został usunięty przez {{kicker}}",
"leftOneMember": "{{name}} opuścił spotkanie",
"leftThreePlusMembers": "{{name}} i wielu innych opuściło spotkanie",
@@ -700,7 +738,9 @@
"reactionSoundsForAll": "Wyłącz dźwięki dla wszystkich",
"screenShareNoAudio": "Opcja \"Udostępnij dźwięk\" nie została zaznaczona podczas wyboru okna.",
"screenShareNoAudioTitle": "Nie można udostępnić dźwięku",
"selfViewTitle": "Zawsze możesz odkryć własny podgląd w ustawieniach",
"screenSharingAudioOnlyDescription": "Pamiętaj, że udostępniając swój ekran, wpływasz na tryb \"Najlepsza wydajność\" i zużywasz więcej przepustowości.",
"screenSharingAudioOnlyTitle": "Tryb \"Najlepsza wydajność\"",
"selfViewTitle": "Zawsze możesz włączyć podgląd własnej kamery w ustawieniach",
"somebody": "Ktoś",
"startSilentDescription": "Ponownie dołącz do spotkania, aby włączyć dźwięk",
"startSilentTitle": "Dołączyłeś bez wyjścia dźwiękowego!",
@@ -736,7 +776,8 @@
"close": "Zamknij",
"headings": {
"lobby": "Lobby ({{count}})",
"participantsList": "Obecnych ({{count}})",
"participantsList": "Obecni uczestnicy ({{count}})",
"visitors": "Goście ({{count}})",
"waitingLobby": "Oczekujących ({{count}})"
},
"search": "Wyszukaj uczestników",
@@ -744,6 +785,7 @@
},
"passwordDigitsOnly": "Do {{number}} cyfr",
"passwordSetRemotely": "Ustawione przez innego uczestnika",
"pinParticipant": "{{participantName}} - Przypnij",
"pinnedParticipant": "Uczestnik jest przypięty",
"polls": {
"answer": {
@@ -828,9 +870,11 @@
"lookGood": "Wygląda na to, że Twój mikrofon działa poprawnie",
"or": "lub",
"premeeting": "Przed spotkaniem",
"proceedAnyway": "Kontynuuj mimo to",
"screenSharingError": "Błąd udostępniania ekranu:",
"showScreen": "Włącz ekran Przed spotkaniem",
"showScreen": "Tryb osobistej poczekalni przed spotkaniem",
"startWithPhone": "Uruchom przez telefon",
"unsafeRoomConsent": "Rozumiem ryzyko, chcę dołączyć do spotkania",
"videoOnlyError": "Błąd wideo:",
"videoTrackError": "Nie można utworzyć ścieżki wideo.",
"viewAllNumbers": "zobacz numery"
@@ -849,9 +893,6 @@
"rejected": "Odrzucony",
"ringing": "Dzwonek..."
},
"privacyView": {
"title": "Prywatność"
},
"profile": {
"avatar": "awatar",
"setDisplayNameLabel": "Podaj swoją wyświetlaną nazwę",
@@ -905,6 +946,7 @@
"localRecordingVideoWarning": "Aby nagrać film, musisz go mieć na początku nagrywania",
"localRecordingWarning": "Upewnij się, że wybrałeś bieżącą kartę, aby użyć odpowiedniego obrazu i dźwięku. Nagranie jest obecnie ograniczone do 1 GB, czyli około 100 minut.",
"loggedIn": "Zalogowano jako {{userName}}",
"noMicPermission": "Nie można utworzyć ścieżki mikrofonu. Zezwól na korzystanie z mikrofonu.",
"noStreams": "Nie wykryto strumienia audio lub wideo.",
"off": "Nagrywanie zatrzymane",
"offBy": "{{name}} zatrzymał nagrywanie",
@@ -934,10 +976,17 @@
"security": {
"about": "Możesz dodać $t(lockRoomPassword) do spotkania. Uczestnicy będą musieli wprowadzić $t(lockRoomPassword) przed dołączeniem do spotkania.",
"aboutReadOnly": "Uczestnicy posiadający uprawnienia do moderacji mogą ustawić $t(lockRoomPassword) do spotkania. Uczestnicy będą musieli wprowadzić $t(lockRoomPassword) zanim zostaną dołączeni do spotkania.",
"insecureRoomNameWarning": "Nazwa pokoju nie jest bezpieczna. Niepowołaniu uczestnicy mogą dołączyć do spotkania. Proszę rozważyć ustawienie hasła spotkania używając przycisku Opcje zabezpieczeń.",
"title": "Opcje zabezpieczeń"
"insecureRoomNameWarningNative": "Nazwa pokoju jest niebezpieczna. Niechciani uczestnicy mogą dołączyć do Twojego spotkania. {{recommendAction}} Dowiedz się więcej o zabezpieczeniu spotkania ",
"insecureRoomNameWarningWeb": "Nazwa pokoju jest niebezpieczna. Niechciani uczestnicy mogą dołączyć do Twojego spotkania. {{recommendAction}} Dowiedz się więcej o zabezpieczeniu spotkania <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">tutaj</a>.",
"title": "Opcje zabezpieczeń",
"unsafeRoomActions": {
"meeting": "Rozważ zabezpieczenie spotkania za pomocą przycisku bezpieczeństwa.",
"prejoin": "Rozważ użycie bardziej unikalnej nazwy spotkania.",
"welcome": "Rozważ użycie bardziej unikalnej nazwy spotkania lub wybierz jedną z sugestii."
}
},
"settings": {
"audio": "Audio",
"buttonLabel": "Ustawienia",
"calendar": {
"about": "{{appName}} integracji kalendarza służy do bezpiecznego dostępu do kalendarza, aby można było odczytywać nadchodzące wydarzenia.",
@@ -958,26 +1007,29 @@
"maxStageParticipants": "Maksymalna liczba uczestników, których można przypiąć do sceny głównej",
"microphones": "Mikrofony",
"moderator": "Moderacja",
"moderatorOptions": "Opcje moderatora",
"more": "Więcej",
"name": "Nazwa",
"noDevice": "Brak",
"notifications": "Powiadomienia",
"participantJoined": "Dołączył nowy uczestnik",
"participantKnocking": "Uczestnik wszedł do poczekalni",
"participantLeft": "Uczestnik opuścił spotkanie",
"playSounds": "Włącz dźwięki",
"playSounds": "Włącz powiadomienia dźwiękowe dla:",
"reactions": "Reakcje",
"sameAsSystem": "Jak system ({{label}})",
"selectAudioOutput": "Wyjście audio",
"selectCamera": "Kamera",
"selectMic": "Mikrofon",
"selfView": "Własnego podgląd",
"sounds": "Dźwięki",
"shortcuts": "Skróty",
"speakers": "Głośniki",
"startAudioMuted": "Wycisz wszystkich dołączających",
"startReactionsMuted": "Wycisz dźwięki reakcji dla wszystkich",
"startVideoMuted": "Ukryj wszystkich dołączających",
"startVideoMuted": "Wyłącz kamery wszystkich dołączających",
"talkWhileMuted": "Jesteś wyciszony",
"title": "Ustawienia"
"title": "Ustawienia",
"video": "Wideo"
},
"settingsView": {
"advanced": "Zaawansowane",
@@ -994,6 +1046,7 @@
"displayName": "Wyświetlana nazwa",
"displayNamePlaceholderText": "Np. Jan Kowalski",
"email": "Email",
"emailPlaceholderText": "email@example.com",
"goTo": "Idź do",
"header": "Ustawienia",
"help": "Pomoc",
@@ -1002,6 +1055,7 @@
"profileSection": "Profil",
"serverURL": "Adres URL serwera",
"showAdvanced": "Pokaż ustawienia zawansowane",
"startCarModeInLowBandwidthMode": "Uruchom tryb samochodowy w trybie niskiej przepustowości",
"startWithAudioMuted": "Rozpocznij z wyciszonym dźwiękiem",
"startWithVideoMuted": "Rozpocznij z wyłączonym obrazem",
"terms": "Warunki",
@@ -1056,25 +1110,39 @@
"cc": "Przełączanie napisów",
"chat": "Przełączanie okna rozmowy",
"clap": "Klaskanie",
"closeChat": "Zamknij czat",
"closeMoreActions": "Zamknij rozszerzone menu opcji",
"closeParticipantsPane": "Zamknij okno uczestników",
"collapse": "Zwiń",
"document": "Przełączanie wspólnego dokumentu",
"documentClose": "Zamknij udostępniony dokument",
"documentOpen": "Otwórz udostępniony dokument",
"download": "Pobierz nasze aplikacje",
"embedMeeting": "Osadź spotkanie",
"endConference": "Zakończ spotkanie",
"enterFullScreen": "Wyświetl w trybie pełnego ekranu",
"enterTileView": "Wyświetl w trybie kafelkowym",
"exitFullScreen": "Zamknij tryb pełnego ekranu",
"exitTileView": "Zamknij tryb kafelkowy",
"expand": "Rozwiń",
"feedback": "Zostaw swoją opinię",
"fullScreen": "Przełączanie trybu pełnoekranowego",
"giphy": "Przełącz menu GIPHY",
"grantModerator": "Przyznaj prawa moderowania",
"hangup": "Zostaw rozmowę",
"heading": "Pasek narzędzi",
"help": "Pomoc",
"hideWhiteboard": "Ukryj tablicę",
"invite": "Zaproś uczestników",
"kick": "Usuń uczestnika",
"laugh": "Śmiech",
"leaveConference": "Opuść spotkanie",
"like": "Kciuk w górę",
"linkToSalesforce": "Link do Salesforce",
"lobbyButton": "Włącz/wyłącz tryb lobby",
"localRecording": "Przełączanie lokalnych urządzeń sterujących zapisem danych",
"lockRoom": "Przełączenie hasła spotkania",
"lowerHand": "Opuść rękę",
"moreActions": "Przełączanie menu więcej działań",
"moreActionsMenu": "Więcej działań w menu",
"moreOptions": "Pokaż więcej opcji",
@@ -1083,12 +1151,15 @@
"muteEveryoneElse": "Wycisz pozostałych",
"muteEveryoneElsesVideoStream": "Wyłącz kamery pozostałym",
"muteEveryonesVideoStream": "Wyłącz wszystkim kamery",
"muteGUMPending": "Podłączanie mikrofonu",
"noiseSuppression": "Tłumienie szumów",
"openChat": "Otwórz czat",
"participants": "Uczestnicy",
"pip": "Tryb przełączania obrazu-w-obrazie",
"privateMessage": "Wyślij wiadomość prywatną",
"profile": "Edytuj swój profil",
"raiseHand": "Przełączyć rękę w górę",
"reactions": "Reakcje",
"reactionsMenu": "Otwórz / Zamknij reakcje",
"recording": "Przełączanie nagrywania",
"remoteMute": "Wycisz uczestnika",
@@ -1102,14 +1173,20 @@
"sharedvideo": "Przełącz udostępnianie obrazu",
"shortcuts": "Przełączanie skrótów klawiszowych",
"show": "Pokaż na scenie",
"showWhiteboard": "Pokaż tablicę",
"silence": "Cisza",
"speakerStats": "Przełączanie statystyk dotyczących mówców",
"stopScreenSharing": "Zatrzymaj udostępnianie ekranu",
"stopSharedVideo": "Zatrzymaj wideo",
"surprised": "Zaskoczony",
"tileView": "Przełącz widok kafelkowy",
"toggleCamera": "Przełączanie kamery",
"toggleFilmstrip": "Przełącz filmstrip",
"unmute": "Wyłącz wyciszenie",
"videoblur": "Przełącz rozmazanie obrazu",
"videomute": "Przełączanie wyciszonego filmu wideo"
"videomute": "Przełączanie wyciszonego filmu wideo",
"videomuteGUMPending": "Podłączanie kamery",
"videounmute": "Uruchom kamerę"
},
"addPeople": "Dodaj ludzi do swojej rozmowy",
"audioOnlyOff": "Wyłącz tryb słabego łącza",
@@ -1122,6 +1199,7 @@
"chat": "Otwórz / Zamknij okno czatu",
"clap": "Klaskanie",
"closeChat": "Zamknij czat",
"closeParticipantsPane": "Zamknij okno uczestników",
"closeReactionsMenu": "Zamknij reakcje",
"disableNoiseSuppression": "Wyłącz tłumienie szumów",
"disableReactionSounds": "Wyłącz dźwięki reakcji dla tego spotkania",
@@ -1130,6 +1208,8 @@
"download": "Pobierz nasze aplikacje",
"e2ee": "Szyfrowanie End-to-End",
"embedMeeting": "Osadź spotkanie",
"enableNoiseSuppression": "Włącz tłumienie szumów",
"endConference": "Zakończ spotkanie",
"enterFullScreen": "Wyświetl na pełnym ekranie",
"enterTileView": "Wyświetl widok kafelkowy",
"exitFullScreen": "Zamknij pełny ekran",
@@ -1138,10 +1218,12 @@
"giphy": "Przełącz menu GIPHY",
"hangup": "Opuść spotkanie",
"help": "Pomoc",
"hideWhiteboard": "Ukryj tablicę",
"invite": "Zaproś uczestników",
"joinBreakoutRoom": "Dołącz do pokoju podgrupy",
"laugh": "Śmiech",
"leaveBreakoutRoom": "Opuść pokój spotkań",
"leaveConference": "Opuść spotkanie",
"like": "Kciuk w górę",
"linkToSalesforce": "Link do Salesforce",
"lobbyButtonDisable": "Wyłącz tryb lobby",
@@ -1154,6 +1236,7 @@
"mute": "Włącz / Wyłącz mikrofon",
"muteEveryone": "Wycisz wszystkich",
"muteEveryonesVideo": "Wyłącz wszystkim kamery",
"muteGUMPending": "Podłączanie mikrofonu",
"noAudioSignalDesc": "Jeżeli celowo nie wyciszyłeś mikrofonu w ustawieniach systemowych spróbuj innego urządzenia.",
"noAudioSignalDescSuggestion": "Jeżeli celowo nie wyciszyłeś mikrofonu w ustawieniach systemowych spróbuj sugerowanego urządzenia.",
"noAudioSignalDialInDesc": "Możesz się również wdzwonić korzystając z numerów:",
@@ -1176,12 +1259,14 @@
"reactionLike": "Wyślij kciuk w górę",
"reactionSilence": "Wyślij cisza",
"reactionSurprised": "Wyślij zaskoczony",
"reactions": "Reakcje",
"security": "Opcje zabezpieczeń",
"selectBackground": "Wybierz tło",
"shareRoom": "Zaproś kogoś",
"shareaudio": "Udostępnij audio",
"sharedvideo": "Udostępnij wideo",
"shortcuts": "Wyświetl skróty",
"showWhiteboard": "Pokaż tablicę",
"silence": "Cisza",
"speakerStats": "Statystyki mówców",
"startScreenSharing": "Zacznij współdzielenie ekranu",
@@ -1192,10 +1277,13 @@
"stopSubtitles": "Zatrzymaj napisy",
"surprised": "Zaskoczony",
"talkWhileMutedPopup": "Próbujesz mówić? Jesteś wyciszony.",
"tileViewToggle": "Przełączanie kafelkowego widoku",
"tileViewToggle": "Przełączanie widoku kafelkowego",
"toggleCamera": "Przełączanie kamery",
"unmute": "Wyłącz wyciszenie",
"videoSettings": "Ustawienia video",
"videomute": "Włącz / Wyłącz kamerę"
"videomute": "Włącz / Wyłącz kamerę",
"videomuteGUMPending": "Podłączanie kamery",
"videounmute": "Uruchom kamerę"
},
"transcribing": {
"ccButtonTooltip": "Uruchom / Zatrzymaj napisy",
@@ -1205,10 +1293,15 @@
"labelToolTip": "Spotkanie jest transkrybowane",
"off": "Transkrypcja została zatrzymana",
"pending": "Przygotowanie do transkrypcji spotkania...",
"sourceLanguageDesc": "Obecnie język spotkania jest ustawiony na <b>{{sourceLanguage}}</b>. <br/> Możesz to zmienić ",
"sourceLanguageHere": "tutaj",
"start": "Rozpocznij wyświetlanie napisów",
"stop": "Zatrzymaj wyświetlanie napisów",
"subtitles": "Napisy",
"subtitlesOff": "Wyłączone",
"tr": "TR"
},
"unpinParticipant": "{{participantName}} - Odepnij",
"userMedia": {
"androidGrantPermissions": "Wybierz <b><i>Pozwól</i></b>, gdy przeglądarka zapyta o pozwolenie.",
"chromeGrantPermissions": "Wybierz <b><i>Pozwól</i></b>, gdy przeglądarka zapyta o pozwolenie.",
@@ -1247,9 +1340,11 @@
"ldTooltip": "Podgląd obrazu w niskiej rozdzielczości",
"lowDefinition": "Niska rozdzielczość",
"performanceSettings": "Ustawienia wydajności",
"recording": "Trwa nagrywanie",
"sd": "SD",
"sdTooltip": "Podgląd obrazu w standardowej rozdzielczości",
"standardDefinition": "Standardowa rozdzielczość"
"standardDefinition": "Standardowa rozdzielczość",
"streaming": "Trwa transmisja"
},
"videothumbnail": {
"connectionInfo": "Informacje o połączeniu",
@@ -1261,6 +1356,7 @@
"grantModerator": "Przyznaj prawa moderatora",
"hideSelfView": "Ukryj widok własnego podglądu",
"kick": "Wyrzuć",
"mirrorVideo": "Lustrzane odbicie",
"moderator": "Moderator",
"mute": "Uczestnik ma wyciszone audio",
"muted": "Wyciszony",
@@ -1270,6 +1366,7 @@
"show": "Pokaż na scenie",
"showSelfView": "Pokaż własny widok",
"unpinFromStage": "Odepnij",
"verify": "Zweryfikuj uczestnika",
"videoMuted": "Kamera wyłączona",
"videomute": "Uczestnik zatrzymał kamerę"
},
@@ -1297,6 +1394,14 @@
"webAssemblyWarning": "WebAssembly nie jest obsługiwany",
"webAssemblyWarningDescription": "WebAssembly wyłączony lub nieobsługiwany przez tę przeglądarkę"
},
"visitors": {
"chatIndicator": "(visitor)",
"labelTooltip": "Liczba odwiedzających: {{count}}",
"notification": {
"description": "Aby wziąć udział, podnieś rękę",
"title": "Jesteś gościem na spotkaniu"
}
},
"volumeSlider": "Kontrola głośności",
"welcomepage": {
"accessibilityLabel": {
@@ -1329,6 +1434,7 @@
"microsoftLogo": "Logo Microsoftu",
"policyLogo": "Logo polityki"
},
"meetingsAccessibilityLabel": "Spotkania",
"mobileDownLoadLinkAndroid": "Pobierz appkę dla systemu Android",
"mobileDownLoadLinkFDroid": "Pobierz appkę dla systemu F-Droid",
"mobileDownLoadLinkIos": "Pobierz appkę dla systemu iOS",
@@ -1337,6 +1443,7 @@
"recentList": "Niedawno",
"recentListDelete": "Usuń",
"recentListEmpty": "Twoja ostatnia lista jest obecnie pusta. Rozmawiaj ze swoim zespołem, a wszystkie ostatnie spotkania znajdziesz tutaj.",
"recentMeetings": "Twoje ostatnie spotkania",
"reducedUIText": "Witamy w {{app}}!",
"roomNameAllowedChars": "Nazwa spotkania nie powinna zawierać znaków: ?, &, :, ', \", %, #.",
"roomname": "Podaj nazwę sali konferencyjnej",
@@ -1345,6 +1452,12 @@
"settings": "Ustawienia",
"startMeeting": "Rozpocznij spotkanie",
"terms": "Warunki korzystania",
"title": "Bezpieczna, w pełni funkcjonalna i całkowicie bezpłatna wideokonferencja"
"title": "Bezpieczna, w pełni funkcjonalna i całkowicie bezpłatna wideokonferencja",
"upcomingMeetings": "Twoje nadchodzące spotkania"
},
"whiteboard": {
"accessibilityLabel": {
"heading": "Tablica"
}
}
}

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",
@@ -242,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"
@@ -447,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.",
@@ -1151,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",
@@ -1184,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",
@@ -1234,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:",
@@ -1279,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": {
@@ -1325,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)",
@@ -1367,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.",

View File

@@ -370,8 +370,6 @@
"permissionCameraRequiredError": "Camera permission is required to participate in conferences with video. Please grant it in Settings",
"permissionErrorTitle": "Permission required",
"permissionMicRequiredError": "Microphone permission is required to participate in conferences with audio. Please grant it in Settings",
"popupError": "Your browser is blocking pop-up windows from this site. Please enable pop-ups in your browser's security settings and try again.",
"popupErrorTitle": "Pop-up blocked",
"readMore": "more",
"recentlyUsedObjects": "Your recently used objects",
"recording": "Recording",
@@ -439,6 +437,7 @@
"token": "token",
"tokenAuthFailed": "Sorry, you're not allowed to join this call.",
"tokenAuthFailedTitle": "Authentication failed",
"tokenAuthUnsupported": "Token URL is not supported.",
"transcribing": "Transcribing",
"unlockRoom": "Remove meeting $t(lockRoomPassword)",
"user": "User",
@@ -674,6 +673,8 @@
"sessionToken": "Session Token",
"start": "Start Recording",
"stop": "Stop Recording",
"stopping": "Stopping Recording",
"wait": "Please wait while we save your recording",
"yes": "Yes"
},
"lockRoomPassword": "password",
@@ -1073,13 +1074,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}}",

View File

@@ -396,7 +396,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
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);

View File

@@ -6,6 +6,9 @@ const UI = {};
import Logger from '@jitsi/logger';
import EventEmitter from 'events';
import {
conferenceWillInit
} from '../../react/features/base/conference/actions';
import { isMobileBrowser } from '../../react/features/base/environment/utils';
import { setColorAlpha } from '../../react/features/base/util/helpers';
import { setDocumentUrl } from '../../react/features/etherpad/actions';
@@ -24,14 +27,11 @@ import {
import UIEvents from '../../service/UI/UIEvents';
import EtherpadManager from './etherpad/Etherpad';
import messageHandler from './util/MessageHandler';
import UIUtil from './util/UIUtil';
import VideoLayout from './videolayout/VideoLayout';
const logger = Logger.getLogger(__filename);
UI.messageHandler = messageHandler;
const eventEmitter = new EventEmitter();
UI.eventEmitter = eventEmitter;
@@ -58,30 +58,6 @@ UI.isFullScreen = function() {
return UIUtil.isFullScreen();
};
/**
* Notify user that server has shut down.
*/
UI.notifyGracefulShutdown = function() {
messageHandler.showError({
descriptionKey: 'dialog.gracefulShutdown',
titleKey: 'dialog.serviceUnavailable'
});
};
/**
* Notify user that reservation error happened.
*/
UI.notifyReservationError = function(code, msg) {
messageHandler.showError({
descriptionArguments: {
code,
msg
},
descriptionKey: 'dialog.reservationErrorMsg',
titleKey: 'dialog.reservationError'
});
};
/**
* Initialize conference UI.
*/
@@ -91,18 +67,9 @@ UI.initConference = function() {
/**
* Starts the UI module and initializes all related components.
*
* @returns {boolean} true if the UI is ready and the conference should be
* established, false - otherwise (for example in the case of welcome page)
*/
UI.start = function() {
VideoLayout.initLargeVideo();
// Do not animate the video area on UI start (second argument passed into
// resizeVideoArea) because the animation is not visible anyway. Plus with
// the current dom layout, the quality label is part of the video layout and
// will be seen animating in.
VideoLayout.resizeVideoArea();
APP.store.dispatch(conferenceWillInit());
if (isMobileBrowser()) {
document.body.classList.add('mobile-browser');
@@ -292,40 +259,6 @@ UI.showToolbar = timeout => APP.store.dispatch(showToolbox(timeout));
// Used by torture.
UI.dockToolbar = dock => APP.store.dispatch(dockToolbox(dock));
/**
* Notify user that connection failed.
* @param {string} stropheErrorMsg raw Strophe error message
*/
UI.notifyConnectionFailed = function(stropheErrorMsg) {
let descriptionKey;
let descriptionArguments;
if (stropheErrorMsg) {
descriptionKey = 'dialog.connectErrorWithMsg';
descriptionArguments = { msg: stropheErrorMsg };
} else {
descriptionKey = 'dialog.connectError';
}
messageHandler.showError({
descriptionArguments,
descriptionKey,
titleKey: 'connection.CONNFAIL'
});
};
/**
* Notify user that maximum users limit has been reached.
*/
UI.notifyMaxUsersLimitReached = function() {
messageHandler.showError({
hideErrorSupportLink: true,
descriptionKey: 'dialog.maxUsersLimitReached',
titleKey: 'dialog.maxUsersLimitReachedTitle'
});
};
UI.handleLastNEndpoints = function(leavingIds, enteringIds) {
VideoLayout.onLastNEndpointsChanged(leavingIds, enteringIds);
};
@@ -337,13 +270,6 @@ UI.handleLastNEndpoints = function(leavingIds, enteringIds) {
*/
UI.setAudioLevel = (id, lvl) => VideoLayout.setAudioLevel(id, lvl);
UI.notifyTokenAuthFailed = function() {
messageHandler.showError({
descriptionKey: 'dialog.tokenAuthFailed',
titleKey: 'dialog.tokenAuthFailedTitle'
});
};
/**
* Update list of available physical devices.
*/

View File

@@ -1,227 +0,0 @@
/* global APP */
import Logger from '@jitsi/logger';
import { openConnection } from '../../../connection';
import {
openAuthDialog,
openLoginDialog } from '../../../react/features/authentication/actions.web';
import {
LoginDialog,
WaitForOwnerDialog
} from '../../../react/features/authentication/components';
import {
getTokenAuthUrl,
isTokenAuthEnabled
} from '../../../react/features/authentication/functions';
import { getReplaceParticipant } from '../../../react/features/base/config/functions';
import { isDialogOpen } from '../../../react/features/base/dialog/functions';
import { setJWT } from '../../../react/features/base/jwt/actions';
import UIUtil from '../util/UIUtil';
import ExternalLoginDialog from './LoginDialog';
let externalAuthWindow;
const logger = Logger.getLogger(__filename);
/**
* Authenticate using external service or just focus
* external auth window if there is one already.
*
* @param {JitsiConference} room
* @param {string} [lockPassword] password to use if the conference is locked
*/
function doExternalAuth(room, lockPassword) {
const config = APP.store.getState()['features/base/config'];
if (externalAuthWindow) {
externalAuthWindow.focus();
return;
}
if (room.isJoined()) {
let getUrl;
if (isTokenAuthEnabled(config)) {
getUrl = Promise.resolve(getTokenAuthUrl(config)(room.getName(), true));
initJWTTokenListener(room);
} else {
getUrl = room.getExternalAuthUrl(true);
}
getUrl.then(url => {
externalAuthWindow = ExternalLoginDialog.showExternalAuthDialog(
url,
() => {
externalAuthWindow = null;
if (!isTokenAuthEnabled(config)) {
room.join(lockPassword);
}
}
);
});
} else if (isTokenAuthEnabled(config)) {
redirectToTokenAuthService(room.getName());
} else {
room.getExternalAuthUrl().then(UIUtil.redirect);
}
}
/**
* Redirect the user to the token authentication service for the login to be
* performed. Once complete it is expected that the service will bring the user
* back with "?jwt={the JWT token}" query parameter added.
* @param {string} [roomName] the name of the conference room.
*/
export function redirectToTokenAuthService(roomName) {
const config = APP.store.getState()['features/base/config'];
// FIXME: This method will not preserve the other URL params that were
// originally passed.
UIUtil.redirect(getTokenAuthUrl(config)(roomName, false));
}
/**
* Initializes 'message' listener that will wait for a JWT token to be received
* from the token authentication service opened in a popup window.
* @param room the name of the conference room.
*/
function initJWTTokenListener(room) {
/**
*
*/
function listener({ data, source }) {
if (externalAuthWindow !== source) {
logger.warn('Ignored message not coming '
+ 'from external authnetication window');
return;
}
let jwt;
if (data && (jwt = data.jwtToken)) {
logger.info('Received JSON Web Token (JWT):', jwt);
APP.store.dispatch(setJWT(jwt));
const roomName = room.getName();
openConnection({
retry: false,
roomName
}).then(connection => {
// Start new connection
const newRoom = connection.initJitsiConference(
roomName, APP.conference._getConferenceOptions());
// Authenticate from the new connection to get
// the session-ID from the focus, which will then be used
// to upgrade current connection's user role
newRoom.room.moderator.authenticate()
.then(() => {
connection.disconnect();
// At this point we'll have session-ID stored in
// the settings. It will be used in the call below
// to upgrade user's role
room.room.moderator.authenticate()
.then(() => {
logger.info('User role upgrade done !');
// eslint-disable-line no-use-before-define
unregister();
})
.catch((err, errCode) => {
logger.error('Authentication failed: ',
err, errCode);
unregister();
});
})
.catch((error, code) => {
unregister();
connection.disconnect();
logger.error(
'Authentication failed on the new connection',
error, code);
});
}, err => {
unregister();
logger.error('Failed to open new connection', err);
});
}
}
/**
*
*/
function unregister() {
window.removeEventListener('message', listener);
}
if (window.addEventListener) {
window.addEventListener('message', listener, false);
}
}
/**
* Authenticate for the conference.
* Uses external service for auth if conference supports that.
* @param {JitsiConference} room
* @param {string} [lockPassword] password to use if the conference is locked
*/
function authenticate(room, lockPassword) {
const config = APP.store.getState()['features/base/config'];
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
doExternalAuth(room, lockPassword);
} else {
APP.store.dispatch(openLoginDialog());
}
}
/**
* Notify user that authentication is required to create the conference.
* @param {JitsiConference} room
* @param {string} [lockPassword] password to use if the conference is locked
*/
function requireAuth(room, lockPassword) {
if (isDialogOpen(APP.store, WaitForOwnerDialog) || isDialogOpen(APP.store, LoginDialog)) {
return;
}
APP.store.dispatch(
openAuthDialog(
room.getName(), authenticate.bind(null, room, lockPassword))
);
}
/**
* De-authenticate local user.
*
* @param {JitsiConference} room
* @param {string} [lockPassword] password to use if the conference is locked
* @returns {Promise}
*/
function logout(room) {
return new Promise(resolve => {
room.room.moderator.logout(resolve);
}).then(url => {
// de-authenticate conference on the fly
if (room.isJoined()) {
const replaceParticipant = getReplaceParticipant(APP.store.getState());
room.join(null, replaceParticipant);
}
return url;
});
}
export default {
authenticate,
logout,
requireAuth
};

View File

@@ -1,28 +0,0 @@
/* global APP */
export default {
/**
* Show notification that external auth is required (using provided url).
* @param {string} url - URL to use for external auth.
* @param {function} callback - callback to invoke when auth popup is closed.
* @returns auth dialog
*/
showExternalAuthDialog(url, callback) {
const dialog = APP.UI.messageHandler.openCenteredPopup(
url, 910, 660,
// On closed
callback
);
if (!dialog) {
APP.UI.messageHandler.showWarning({
descriptionKey: 'dialog.popupError',
titleKey: 'dialog.popupErrorTitle'
});
}
return dialog;
}
};

View File

@@ -1,61 +0,0 @@
/* global APP */
import { showErrorNotification, showWarningNotification } from '../../../react/features/notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../../react/features/notifications/constants';
const messageHandler = {
/**
* Opens new popup window for given <tt>url</tt> centered over current
* window.
*
* @param url the URL to be displayed in the popup window
* @param w the width of the popup window
* @param h the height of the popup window
* @param onPopupClosed optional callback function called when popup window
* has been closed.
*
* @returns {object} popup window object if opened successfully or undefined
* in case we failed to open it(popup blocked)
*/
// eslint-disable-next-line max-params
openCenteredPopup(url, w, h, onPopupClosed) {
const l = window.screenX + (window.innerWidth / 2) - (w / 2);
const t = window.screenY + (window.innerHeight / 2) - (h / 2);
const popup = window.open(
url, '_blank',
String(`top=${t}, left=${l}, width=${w}, height=${h}`));
if (popup && onPopupClosed) {
const pollTimer = window.setInterval(() => {
if (popup.closed !== false) {
window.clearInterval(pollTimer);
onPopupClosed();
}
}, 200);
}
return popup;
},
/**
* Shows an error dialog to the user.
*
* @param {object} props - The properties to pass to the
* showErrorNotification action.
*/
showError(props) {
APP.store.dispatch(showErrorNotification(props, NOTIFICATION_TIMEOUT_TYPE.LONG));
},
/**
* Shows a warning dialog to the user.
*
* @param {object} props - The properties to pass to the
* showWarningNotification action.
*/
showWarning(props) {
APP.store.dispatch(showWarningNotification(props, NOTIFICATION_TIMEOUT_TYPE.LONG));
}
};
export default messageHandler;

View File

@@ -31,18 +31,6 @@ const UIUtil = {
return result;
},
/**
* Redirects to a given URL.
*
* @param {string} url - The redirect URL.
* NOTE: Currently used to redirect to 3rd party location for
* authentication. In most cases redirectWithStoredParams action must be
* used instead of this method in order to preserve current URL params.
*/
redirect(url) {
window.location.href = url;
},
/**
* Indicates if we're currently in full screen mode.
*

View File

@@ -508,7 +508,7 @@ export class VideoContainer extends LargeContainer {
*/
setLocalFlipX(val) {
this.localFlipX = val;
if (!this.video || !this.stream || !this.stream.isLocal()) {
if (!this.video || !this.stream || !this.stream.isLocal() || this.isScreenSharing()) {
return;
}
this.video.style.transform = this.localFlipX ? 'scaleX(-1)' : 'none';

468
package-lock.json generated
View File

@@ -31,11 +31,11 @@
"@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",
@@ -60,21 +60,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/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1659.0.0+5d322ea5/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",
"punycode": "2.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-emoji-render": "1.2.4",
"react-focus-on": "3.8.1",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "0.69.10",
"react-native": "0.69.11",
"react-native-background-timer": "2.4.1",
"react-native-calendar-events": "2.2.0",
"react-native-callstats": "3.73.7",
@@ -89,8 +89,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",
@@ -99,10 +99,10 @@
"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.1",
"react-native-webrtc": "111.0.3",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",
"react-redux": "7.2.9",
"react-textarea-autosize": "8.3.0",
"react-window": "1.8.6",
"react-youtube": "10.1.0",
@@ -2176,9 +2176,9 @@
}
},
"node_modules/@babel/register/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"bin": {
"semver": "bin/semver"
}
@@ -3243,9 +3243,9 @@
}
},
"node_modules/@mapbox/node-pre-gyp/node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"optional": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -4704,11 +4704,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"node_modules/@react-navigation/bottom-tabs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.3.tgz",
"integrity": "sha512-ZA2Ko9fNwNaaSNn7738KpEk8Doi+yjRfTg8Wb/WvduIaK/28qNLAYWBCUEVjBC55y/9zJOzwc4R8Av2J2MG/4g==",
"version": "6.5.8",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.8.tgz",
"integrity": "sha512-0aa/jXea+LyBgR5NoRNWGKw0aFhjHwCkusigMRXIrCA4kINauDcAO0w0iFbZeKfaTCVAix5kK5UxDJJ2aJpevg==",
"dependencies": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -4749,11 +4749,11 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-navigation/core": {
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
"integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"version": "6.4.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.9.tgz",
"integrity": "sha512-G9GH7bP9x0qqupxZnkSftnkn4JoXancElTvFc8FVGfEvxnxP+gBo3wqcknyBi7M5Vad4qecsYjCOa9wqsftv9g==",
"dependencies": {
"@react-navigation/routers": "^6.1.6",
"@react-navigation/routers": "^6.1.9",
"escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.23",
"query-string": "^7.1.3",
@@ -4770,9 +4770,9 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/@react-navigation/elements": {
"version": "1.3.13",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
"integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA==",
"version": "1.3.18",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q==",
"peerDependencies": {
"@react-navigation/native": "^6.0.0",
"react": "*",
@@ -4781,9 +4781,9 @@
}
},
"node_modules/@react-navigation/material-top-tabs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.5.2.tgz",
"integrity": "sha512-i/R3bEXVE5pygWP0dOMdFNOVzrQyHXL0lbqLfQx5HZXwbvCrpUBFqOED3bWLBrBOUhHQSXfYgTuteAfIF5hzzg==",
"version": "6.6.3",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.6.3.tgz",
"integrity": "sha512-7rbBUUvVSKD8jV/a7iV2BTSQ83G7W8grGSwBNojdeXdeZpsUa+wmmKnPtBFhdPv7DDQp7nzAYRx6RCOPtjZSCw==",
"dependencies": {
"color": "^4.2.3",
"warn-once": "^0.1.0"
@@ -4825,11 +4825,11 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-navigation/native": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
"integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.7.tgz",
"integrity": "sha512-W6E3+AtTombMucCRo6q7vPmluq8hSjS+IxfazJ/SokOe7ChJX7eLvvralIsJkjFj3iWV1KgOSnHxa6hdiFasBw==",
"dependencies": {
"@react-navigation/core": "^6.4.6",
"@react-navigation/core": "^6.4.9",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.1.23"
@@ -4840,19 +4840,19 @@
}
},
"node_modules/@react-navigation/routers": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.6.tgz",
"integrity": "sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==",
"version": "6.1.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
"integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==",
"dependencies": {
"nanoid": "^3.1.23"
}
},
"node_modules/@react-navigation/stack": {
"version": "6.3.11",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
"integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"version": "6.3.17",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.17.tgz",
"integrity": "sha512-8/8ZvJROK3fp6PRmQ9MrXd9epBowA8NkfCaWW/N9H5arqwNX9lTXAkmcjicRhjpX+UNlMBR9dTLkWvPRe2vY9A==",
"dependencies": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -5661,7 +5661,6 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dev": true,
"dependencies": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
@@ -5842,7 +5841,6 @@
"version": "7.1.24",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz",
"integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==",
"dev": true,
"dependencies": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
@@ -6024,9 +6022,9 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": {
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -6165,9 +6163,9 @@
}
},
"node_modules/@typescript-eslint/experimental-utils/node_modules/semver": {
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -6291,9 +6289,9 @@
}
},
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -6332,9 +6330,9 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/semver": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -6681,14 +6679,6 @@
"node": ">=0.4.0"
}
},
"node_modules/adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==",
"engines": {
"node": ">=6.0"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -7793,6 +7783,7 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"optional": true,
"engines": {
"node": ">=10"
}
@@ -9376,9 +9367,9 @@
}
},
"node_modules/eslint-plugin-jsdoc/node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -9917,9 +9908,9 @@
}
},
"node_modules/execa/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"bin": {
"semver": "bin/semver"
}
@@ -10541,6 +10532,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"optional": true,
"dependencies": {
"minipass": "^3.0.0"
},
@@ -12768,8 +12760,8 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"integrity": "sha512-HtLhGkrSHEztTcMZ1iJmG7a5Bj8KvsT8bGL/h3G+4kro5JRp/E40XJPPWiaGT0e9av4RQZa4u1giSgF/50ssoQ==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1659.0.0+5d322ea5/lib-jitsi-meet.tgz",
"integrity": "sha512-kTBN3NlI3RLxeQeq5uppU557kJPQWwFMq1NweGr0CH8TCJdnKt30Lqx/X+DGP7Js6286JDmpg4EWZa9wW7lLXQ==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
@@ -12949,9 +12941,9 @@
}
},
"node_modules/lib-jitsi-meet/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"bin": {
"semver": "bin/semver"
}
@@ -13894,6 +13886,7 @@
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
"optional": true,
"dependencies": {
"yallist": "^4.0.0"
},
@@ -13905,6 +13898,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"optional": true,
"dependencies": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
@@ -14013,9 +14007,15 @@
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
},
"node_modules/nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==",
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.cjs"
},
@@ -14822,9 +14822,9 @@
}
},
"node_modules/patch-package/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true,
"bin": {
"semver": "bin/semver"
@@ -15403,9 +15403,9 @@
}
},
"node_modules/punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
"engines": {
"node": ">=6"
}
@@ -15665,9 +15665,10 @@
}
},
"node_modules/react-native": {
"version": "0.69.10",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.10.tgz",
"integrity": "sha512-zBsJmFsjyx9zC0JDRH6F6hib3BWbIu65EYPsJBQMDHMSGJ9fL7C6ZV49O7Abockn/dbCHhIWpiSyCuda/bhV8g==",
"version": "0.69.11",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.11.tgz",
"integrity": "sha512-lYSzyDicrE5FLag+Vaq1XmPscQFKFqiUCsDMNkgd+wW9139u3hDEnbEWnXfM/kgF3vrKQUfyLMwfkuLV8EQfug==",
"deprecated": "Issues and pull requests filed against this version are not supported. See the React Native release support policy to learn more: https://github.com/reactwg/react-native-releases#releases-support-policy",
"dependencies": {
"@jest/create-cache-key-function": "^27.0.1",
"@react-native-community/cli": "^8.0.4",
@@ -15863,18 +15864,18 @@
}
},
"node_modules/react-native-safe-area-context": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz",
"integrity": "sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA==",
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.6.4.tgz",
"integrity": "sha512-UWYsokTLZmj8g0cluzoUeGUjQrCTW4slKr2xKmuwQCurAuvSJq/QvfhCrqyea++XrXo46+1Q3wSoP50YXG24jA==",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-screens": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.13.1.tgz",
"integrity": "sha512-xcrnuUs0qUrGpc2gOTDY4VgHHADQwp80mwR1prU/Q0JqbZN5W3koLhuOsT6FkSRKjR5t40l+4LcjhHdpqRB2HA==",
"version": "3.22.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.22.0.tgz",
"integrity": "sha512-csLypBSXIt/egh37YJmokETptZJCtZdoZBsZNLR9n31GesDyVogprT+MM22dEPDuxPxt/mFWq+lSpVwk7khuTw==",
"dependencies": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -16027,15 +16028,13 @@
}
},
"node_modules/react-native-webrtc": {
"version": "111.0.1",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.1.tgz",
"integrity": "sha512-yMRmLFtKRDXaK5b/s92+ArsMElEEjZnGW2cE+GqTHxLka0Kj0qq/sgNS2sMTuJuZRhW4oT6ryMLwTYzIrGM1lQ==",
"version": "111.0.3",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.3.tgz",
"integrity": "sha512-flharkWM5QTSlik+ppK5tf5W86IeabHnrMI7bKkhUJJyibDDMz6X3ReH3dtHWFbiRjDGLktZ4FGwqOCGhL68DA==",
"dependencies": {
"adm-zip": "0.5.9",
"base64-js": "1.5.1",
"debug": "4.3.4",
"event-target-shim": "6.0.2",
"tar": "6.1.11"
"event-target-shim": "6.0.2"
},
"peerDependencies": {
"react-native": ">=0.60.0"
@@ -16123,27 +16122,29 @@
}
},
"node_modules/react-redux": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.1.0.tgz",
"integrity": "sha512-hyu/PoFK3vZgdLTg9ozbt7WF3GgX5+Yn3pZm5/96/o4UueXA+zj08aiSC9Mfj2WtD1bvpIb3C5yvskzZySzzaw==",
"version": "7.2.9",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
"integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==",
"dependencies": {
"@babel/runtime": "^7.4.5",
"hoist-non-react-statics": "^3.3.0",
"invariant": "^2.2.4",
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^16.8.6"
"react-is": "^17.0.2"
},
"peerDependencies": {
"react": "^16.8.3",
"redux": "^2.0.0 || ^3.0.0 || ^4.0.0-0"
"react": "^16.8.3 || ^17 || ^18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/react-redux/node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-refresh": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
@@ -16818,9 +16819,9 @@
}
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"bin": {
"semver": "bin/semver.js"
}
@@ -17962,6 +17963,7 @@
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"optional": true,
"dependencies": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -17978,6 +17980,7 @@
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"optional": true,
"bin": {
"mkdirp": "bin/cmd.js"
},
@@ -18345,9 +18348,9 @@
}
},
"node_modules/ts-loader/node_modules/semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -18798,9 +18801,12 @@
}
},
"node_modules/use-latest-callback": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.5.tgz",
"integrity": "sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ=="
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz",
"integrity": "sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg==",
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/use-sidecar": {
"version": "1.1.2",
@@ -19809,7 +19815,8 @@
"node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
},
"node_modules/yaml": {
"version": "1.10.2",
@@ -21254,9 +21261,9 @@
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
}
}
},
@@ -22134,9 +22141,9 @@
},
"dependencies": {
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"optional": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -23148,11 +23155,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"@react-navigation/bottom-tabs": {
"version": "6.5.3",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.3.tgz",
"integrity": "sha512-ZA2Ko9fNwNaaSNn7738KpEk8Doi+yjRfTg8Wb/WvduIaK/28qNLAYWBCUEVjBC55y/9zJOzwc4R8Av2J2MG/4g==",
"version": "6.5.8",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.8.tgz",
"integrity": "sha512-0aa/jXea+LyBgR5NoRNWGKw0aFhjHwCkusigMRXIrCA4kINauDcAO0w0iFbZeKfaTCVAix5kK5UxDJJ2aJpevg==",
"requires": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -23182,11 +23189,11 @@
}
},
"@react-navigation/core": {
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
"integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"version": "6.4.9",
"resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.9.tgz",
"integrity": "sha512-G9GH7bP9x0qqupxZnkSftnkn4JoXancElTvFc8FVGfEvxnxP+gBo3wqcknyBi7M5Vad4qecsYjCOa9wqsftv9g==",
"requires": {
"@react-navigation/routers": "^6.1.6",
"@react-navigation/routers": "^6.1.9",
"escape-string-regexp": "^4.0.0",
"nanoid": "^3.1.23",
"query-string": "^7.1.3",
@@ -23202,14 +23209,14 @@
}
},
"@react-navigation/elements": {
"version": "1.3.13",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
"integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA=="
"version": "1.3.18",
"resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.18.tgz",
"integrity": "sha512-/0hwnJkrr415yP0Hf4PjUKgGyfshrvNUKFXN85Mrt1gY49hy9IwxZgrrxlh0THXkPeq8q4VWw44eHDfAcQf20Q=="
},
"@react-navigation/material-top-tabs": {
"version": "6.5.2",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.5.2.tgz",
"integrity": "sha512-i/R3bEXVE5pygWP0dOMdFNOVzrQyHXL0lbqLfQx5HZXwbvCrpUBFqOED3bWLBrBOUhHQSXfYgTuteAfIF5hzzg==",
"version": "6.6.3",
"resolved": "https://registry.npmjs.org/@react-navigation/material-top-tabs/-/material-top-tabs-6.6.3.tgz",
"integrity": "sha512-7rbBUUvVSKD8jV/a7iV2BTSQ83G7W8grGSwBNojdeXdeZpsUa+wmmKnPtBFhdPv7DDQp7nzAYRx6RCOPtjZSCw==",
"requires": {
"color": "^4.2.3",
"warn-once": "^0.1.0"
@@ -23240,30 +23247,30 @@
}
},
"@react-navigation/native": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
"integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"version": "6.1.7",
"resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.7.tgz",
"integrity": "sha512-W6E3+AtTombMucCRo6q7vPmluq8hSjS+IxfazJ/SokOe7ChJX7eLvvralIsJkjFj3iWV1KgOSnHxa6hdiFasBw==",
"requires": {
"@react-navigation/core": "^6.4.6",
"@react-navigation/core": "^6.4.9",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.1.23"
}
},
"@react-navigation/routers": {
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.6.tgz",
"integrity": "sha512-Z5DeCW3pUvMafbU9Cjy1qJYC2Bvl8iy3+PfsB0DsAwQ6zZ3WAXW5FTMX4Gb9H+Jg6qHWGbMFFwlYpS3UJ3tlVQ==",
"version": "6.1.9",
"resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-6.1.9.tgz",
"integrity": "sha512-lTM8gSFHSfkJvQkxacGM6VJtBt61ip2XO54aNfswD+KMw6eeZ4oehl7m0me3CR9hnDE4+60iAZR8sAhvCiI3NA==",
"requires": {
"nanoid": "^3.1.23"
}
},
"@react-navigation/stack": {
"version": "6.3.11",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
"integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"version": "6.3.17",
"resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.17.tgz",
"integrity": "sha512-8/8ZvJROK3fp6PRmQ9MrXd9epBowA8NkfCaWW/N9H5arqwNX9lTXAkmcjicRhjpX+UNlMBR9dTLkWvPRe2vY9A==",
"requires": {
"@react-navigation/elements": "^1.3.13",
"@react-navigation/elements": "^1.3.18",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -23845,7 +23852,6 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
"integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
"dev": true,
"requires": {
"@types/react": "*",
"hoist-non-react-statics": "^3.3.0"
@@ -24026,7 +24032,6 @@
"version": "7.1.24",
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz",
"integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==",
"dev": true,
"requires": {
"@types/hoist-non-react-statics": "^3.3.0",
"@types/react": "*",
@@ -24192,9 +24197,9 @@
},
"dependencies": {
"semver": {
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -24273,9 +24278,9 @@
"dev": true
},
"semver": {
"version": "7.3.7",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -24339,9 +24344,9 @@
},
"dependencies": {
"semver": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -24366,9 +24371,9 @@
},
"dependencies": {
"semver": {
"version": "7.5.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz",
"integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -24658,11 +24663,6 @@
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
"dev": true
},
"adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg=="
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@@ -25510,7 +25510,8 @@
"chownr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
"optional": true
},
"chrome-trace-event": {
"version": "1.0.3",
@@ -26890,9 +26891,9 @@
},
"dependencies": {
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -27111,9 +27112,9 @@
"integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
},
"shebang-command": {
"version": "1.2.0",
@@ -27612,6 +27613,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
"optional": true,
"requires": {
"minipass": "^3.0.0"
}
@@ -29266,8 +29268,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"integrity": "sha512-HtLhGkrSHEztTcMZ1iJmG7a5Bj8KvsT8bGL/h3G+4kro5JRp/E40XJPPWiaGT0e9av4RQZa4u1giSgF/50ssoQ==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1659.0.0+5d322ea5/lib-jitsi-meet.tgz",
"integrity": "sha512-kTBN3NlI3RLxeQeq5uppU557kJPQWwFMq1NweGr0CH8TCJdnKt30Lqx/X+DGP7Js6286JDmpg4EWZa9wW7lLXQ==",
"requires": {
"@jitsi/js-utils": "2.0.0",
"@jitsi/logger": "2.0.0",
@@ -29406,9 +29408,9 @@
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
},
"shebang-command": {
"version": "1.2.0",
@@ -30167,6 +30169,7 @@
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz",
"integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==",
"optional": true,
"requires": {
"yallist": "^4.0.0"
}
@@ -30175,6 +30178,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
"optional": true,
"requires": {
"minipass": "^3.0.0",
"yallist": "^4.0.0"
@@ -30263,9 +30267,9 @@
}
},
"nanoid": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz",
"integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw=="
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA=="
},
"nanomatch": {
"version": "1.2.13",
@@ -30842,9 +30846,9 @@
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"dev": true
},
"shebang-command": {
@@ -31286,9 +31290,9 @@
}
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
},
"qs": {
"version": "6.9.7",
@@ -31455,9 +31459,9 @@
}
},
"react-native": {
"version": "0.69.10",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.10.tgz",
"integrity": "sha512-zBsJmFsjyx9zC0JDRH6F6hib3BWbIu65EYPsJBQMDHMSGJ9fL7C6ZV49O7Abockn/dbCHhIWpiSyCuda/bhV8g==",
"version": "0.69.11",
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.11.tgz",
"integrity": "sha512-lYSzyDicrE5FLag+Vaq1XmPscQFKFqiUCsDMNkgd+wW9139u3hDEnbEWnXfM/kgF3vrKQUfyLMwfkuLV8EQfug==",
"requires": {
"@jest/create-cache-key-function": "^27.0.1",
"@react-native-community/cli": "^8.0.4",
@@ -31609,14 +31613,14 @@
"integrity": "sha512-Q3dFPN7whBCY7X8nvQe7TBw4F5g1PyB78KwyKDXpJENcDrBodlFtj9/c5T2ZkRwAPb+bxr39b+lq9FyT6WQWtg=="
},
"react-native-safe-area-context": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz",
"integrity": "sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA=="
"version": "4.6.4",
"resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.6.4.tgz",
"integrity": "sha512-UWYsokTLZmj8g0cluzoUeGUjQrCTW4slKr2xKmuwQCurAuvSJq/QvfhCrqyea++XrXo46+1Q3wSoP50YXG24jA=="
},
"react-native-screens": {
"version": "3.13.1",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.13.1.tgz",
"integrity": "sha512-xcrnuUs0qUrGpc2gOTDY4VgHHADQwp80mwR1prU/Q0JqbZN5W3koLhuOsT6FkSRKjR5t40l+4LcjhHdpqRB2HA==",
"version": "3.22.0",
"resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.22.0.tgz",
"integrity": "sha512-csLypBSXIt/egh37YJmokETptZJCtZdoZBsZNLR9n31GesDyVogprT+MM22dEPDuxPxt/mFWq+lSpVwk7khuTw==",
"requires": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -31725,15 +31729,13 @@
}
},
"react-native-webrtc": {
"version": "111.0.1",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.1.tgz",
"integrity": "sha512-yMRmLFtKRDXaK5b/s92+ArsMElEEjZnGW2cE+GqTHxLka0Kj0qq/sgNS2sMTuJuZRhW4oT6ryMLwTYzIrGM1lQ==",
"version": "111.0.3",
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.3.tgz",
"integrity": "sha512-flharkWM5QTSlik+ppK5tf5W86IeabHnrMI7bKkhUJJyibDDMz6X3ReH3dtHWFbiRjDGLktZ4FGwqOCGhL68DA==",
"requires": {
"adm-zip": "0.5.9",
"base64-js": "1.5.1",
"debug": "4.3.4",
"event-target-shim": "6.0.2",
"tar": "6.1.11"
"event-target-shim": "6.0.2"
},
"dependencies": {
"base64-js": {
@@ -31773,23 +31775,16 @@
}
},
"react-redux": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.1.0.tgz",
"integrity": "sha512-hyu/PoFK3vZgdLTg9ozbt7WF3GgX5+Yn3pZm5/96/o4UueXA+zj08aiSC9Mfj2WtD1bvpIb3C5yvskzZySzzaw==",
"version": "7.2.9",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
"integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==",
"requires": {
"@babel/runtime": "^7.4.5",
"hoist-non-react-statics": "^3.3.0",
"invariant": "^2.2.4",
"@babel/runtime": "^7.15.4",
"@types/react-redux": "^7.1.20",
"hoist-non-react-statics": "^3.3.2",
"loose-envify": "^1.4.0",
"prop-types": "^15.7.2",
"react-is": "^16.8.6"
},
"dependencies": {
"react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
}
"react-is": "^17.0.2"
}
},
"react-refresh": {
@@ -32272,9 +32267,9 @@
}
},
"semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw=="
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
},
"send": {
"version": "0.17.2",
@@ -33172,6 +33167,7 @@
"version": "6.1.11",
"resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz",
"integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==",
"optional": true,
"requires": {
"chownr": "^2.0.0",
"fs-minipass": "^2.0.0",
@@ -33184,7 +33180,8 @@
"mkdirp": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"optional": true
}
}
},
@@ -33458,9 +33455,9 @@
"dev": true
},
"semver": {
"version": "7.3.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz",
"integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==",
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"requires": {
"lru-cache": "^6.0.0"
@@ -33774,9 +33771,9 @@
}
},
"use-latest-callback": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.5.tgz",
"integrity": "sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ=="
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.1.6.tgz",
"integrity": "sha512-VO/P91A/PmKH9bcN9a7O3duSuxe6M14ZoYXgA6a8dab8doWNdhiIHzEkX/jFeTTRBsX0Ubk6nG4q2NIjNsj+bg=="
},
"use-sidecar": {
"version": "1.1.2",
@@ -34497,7 +34494,8 @@
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"devOptional": true
},
"yaml": {
"version": "1.10.2",

View File

@@ -36,11 +36,11 @@
"@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",
@@ -65,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/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1659.0.0+5d322ea5/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",
"punycode": "2.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-emoji-render": "1.2.4",
"react-focus-on": "3.8.1",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "0.69.10",
"react-native": "0.69.11",
"react-native-background-timer": "2.4.1",
"react-native-calendar-events": "2.2.0",
"react-native-callstats": "3.73.7",
@@ -94,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",
@@ -104,10 +104,10 @@
"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.1",
"react-native-webrtc": "111.0.3",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",
"react-redux": "7.2.9",
"react-textarea-autosize": "8.3.0",
"react-window": "1.8.6",
"react-youtube": "10.1.0",
@@ -179,9 +179,7 @@
"webpack-dev-server": "4.7.3"
},
"overrides": {
"strophe.js@1.5.0": {
"@xmldom/xmldom": "0.8.7"
}
"@xmldom/xmldom": "0.8.7"
},
"engines": {
"node": ">=14.0.0",

View File

@@ -0,0 +1,19 @@
diff --git a/node_modules/react-native-immersive/index.js b/node_modules/react-native-immersive/index.js
index 55dab57..110260b 100644
--- a/node_modules/react-native-immersive/index.js
+++ b/node_modules/react-native-immersive/index.js
@@ -18,7 +18,13 @@ const Immersive = Platform.OS === 'android' ? {
isListenerEnabled = true
RNImmersive.addImmersiveListener()
},
- removeImmersiveListener: (listener) => DeviceEventEmitter.removeListener('@@IMMERSIVE_STATE_CHANGED', listener)
+ removeImmersiveListener: (listener) => {
+ const immersiveListener = DeviceEventEmitter.addListener('@@IMMERSIVE_STATE_CHANGED', listener);
+
+ return () => {
+ immersiveListener.remove();
+ }
+ }
} : {
on: unSupportedError,
off: unSupportedError,

View File

@@ -0,0 +1 @@
*.tgz

View File

@@ -1,3 +1,2 @@
package-lock=true
; FIXME Set legacy-peer-deps=false when we upgrade RN.
legacy-peer-deps=true

View File

@@ -2,11 +2,48 @@
## 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`
Inside your project, run `npm i @jitsi/react-native-sdk`.<br/><br/>Additionally, if not already installed, some dependencies will need to be added.
This can be done by running the following script:
```
node node_modules/@jitsi/react-native-sdk/update_dependencies.js
```
This will check and update all your dependencies.<br/><br/>
[comment]: # (These deps definitely need to be added manually, more could be neccesary)
Because of SVG use in react native, you need to update metro.config your project's file:
```
const { getDefaultConfig } = require('metro-config');
module.exports = (async () => {
const {
resolver: {
sourceExts,
assetExts
}
} = await getDefaultConfig();
return {
transformer: {
babelTransformerPath: require.resolve('react-native-svg-transformer'),
getTransformOptions: async () => ({
transform: {
experimentalImportSupport: false,
inlineRequires: true,
},
}),
},
resolver: {
assetExts: assetExts.filter(ext => ext !== 'svg'),
sourceExts: [...sourceExts, 'svg']
}
}
})();
```
### iOS
#### Project Info.plist
@@ -20,29 +57,21 @@
- Voice over IP
- Background fetch
- Add Copy Sounds step:
1. Open XCode, go to Build Phases and add this step and the script below.
```
SOUNDS_DIR="${PROJECT_DIR}/../node_modules/rnsdk/sounds"
SOUNDS_DIR="${PROJECT_DIR}/../node_modules/@jitsi/react-native-sdk/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
- In `android/app/src/debug/AndroidManifest.xml` and `android/app/src/main/AndroidManifest.xml`, under the `</application>` tag, include
```
<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

@@ -1,7 +0,0 @@
module.exports = {
androidSourcePath: '../android/sdk/src/main/java/org/jitsi/meet/sdk',
androidTargetPath: './android/src/main/java/org/jitsi/meet/sdk',
iosSrcPath: '../ios/sdk/src',
iosDestPath: './ios/src'
};

View File

@@ -1,8 +0,0 @@
/**
* Converts the meetingOptions domain and roomName to a URL that can be passed to the App component.
* @param {*} domain domain address from props.
* @param {*} roomName room name from props.
*/
export function convertPropsToURL(domain, roomName) {
return `${domain}/${roomName}`;
}

View File

@@ -4,18 +4,17 @@ import 'react-native-gesture-handler';
// Apply all necessary polyfills as early as possible
// to make sure anything imported henceforth sees them.
import 'react-native-get-random-values';
import '../react/features/mobile/polyfills';
import './react/features/mobile/polyfills';
// @ts-ignore
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { View } from 'react-native';
import { convertPropsToURL } from '../functions';
import { appNavigate } from '../react/features/app/actions.native';
import { App } from '../react/features/app/components/App.native';
import { setAudioMuted, setVideoMuted } from '../react/features/base/media/actions';
import { appNavigate } from './react/features/app/actions.native';
import { App } from './react/features/app/components/App.native';
import { setAudioMuted, setVideoMuted } from './react/features/base/media/actions';
// @ts-ignore
import JitsiThemePaperProvider from '../react/features/base/ui/components/JitsiThemeProvider';
import JitsiThemePaperProvider from './react/features/base/ui/components/JitsiThemeProvider.native';
interface IAppProps {
@@ -40,7 +39,7 @@ interface IAppProps {
/**
* Main React Native SDK component that displays a Jitsi Meet conference and gets all required params as props
*/
const JitsiMeet = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref) => {
export const JitsiMeeting = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref) => {
const [ appProps, setAppProps ] = useState({});
const app = useRef(null);
@@ -65,7 +64,7 @@ const JitsiMeet = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref)
useEffect(
() => {
const url = convertPropsToURL(meetingOptions.domain, meetingOptions.roomName);
const url = `${meetingOptions.domain}/${meetingOptions.roomName}`;
setAppProps({
'url': {
@@ -95,5 +94,3 @@ const JitsiMeet = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref)
</View>
);
});
export default JitsiMeet;

View File

@@ -3,7 +3,7 @@ require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = package['name']
s.name = 'jitsi-meet-rnsdk'
s.version = package['version']
s.summary = package['description']
s.description = package['description']
@@ -16,11 +16,10 @@ Pod::Spec.new do |s|
s.platform = :ios, '12.4'
s.preserve_paths = 'ios/**/*'
s.source_files = 'ios/**/*.{h,m,swift}'
s.source_files = 'ios/**/*.{h,m}'
s.dependency 'React-Core'
s.dependency 'ObjectiveDropboxOfficial', '6.2.3'
s.dependency 'JitsiWebRTC', '~> 111.0.0'
s.dependency 'react-native-webrtc'
s.dependency 'ObjectiveDropboxOfficial', '6.2.3'
end

File diff suppressed because it is too large Load Diff

View File

@@ -2,51 +2,50 @@
"name": "@jitsi/react-native-sdk",
"version": "0.1.0",
"description": "React Native SDK for Jitsi Meet.",
"main": "index.js",
"main": "index.tsx",
"license": "Apache-2.0",
"author": "",
"homepage": "https://jitsi.org",
"repository": {
"type": "git",
"url": "git://github.com/jitsi/jitsi-meet.git"
"url": "git+https://github.com/jitsi/jitsi-meet.git"
},
"dependencies": {
"@amplitude/react-native": "2.7.0",
"@giphy/react-components": "6.8.1",
"@giphy/react-native-sdk": "2.3.0",
"@hapi/bourne": "2.0.0",
"@jitsi/js-utils": "2.0.5",
"@jitsi/logger": "2.0.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",
"@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",
"@xmldom/xmldom": "0.8.7",
"base64-js": "1.3.1",
"grapheme-splitter": "1.0.4",
"i18n-iso-countries": "6.8.0",
"i18next": "17.0.6",
"i18next-browser-languagedetector": "3.0.1",
"i18next-xhr-backend": "3.0.0",
"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/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1659.0.0+5d322ea5/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
"optional-require": "1.0.3",
"promise.allsettled": "1.0.4",
"punycode": "2.1.1",
"punycode": "2.3.0",
"react-emoji-render": "1.2.4",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-redux": "7.1.0",
"react-window": "1.8.6",
"react-youtube": "10.1.0",
"react-native-callstats": "3.73.7",
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
"react-native-svg-transformer": "1.0.0",
"react-native-tab-view": "3.1.1",
"react-native-url-polyfill": "1.3.0",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.2.9",
"redux": "4.0.4",
"redux-thunk": "2.4.1",
"unorm": "1.6.0",
@@ -55,47 +54,42 @@
"zxcvbn": "4.4.2"
},
"peerDependencies": {
"@react-native-async-storage/async-storage": "1.17.3",
"@amplitude/react-native": "2.7.0",
"@giphy/react-native-sdk": "2.3.0",
"@react-native-async-storage/async-storage": "1.18.2",
"@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": "7.0.4",
"@react-native-masked-view/masked-view": "0.2.6",
"react-native": "*",
"react": "*",
"react-dom": "*",
"react-native-background-timer": "2.4.1",
"react-native-calendar-events": "2.2.0",
"react-native-callstats": "3.73.7",
"react-native-collapsible": "1.6.0",
"react-native-default-preference": "1.4.4",
"react-native-device-info": "8.4.8",
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
"react-native-get-random-values": "1.7.2",
"react-native-gesture-handler": "2.9.0",
"react-native-immersive": "2.0.0",
"react-native-keep-awake": "4.0.0",
"react-native-pager-view": "5.4.9",
"react-native-paper": "4.11.1",
"react-native-performance": "2.1.0",
"react-native-orientation-locker": "1.5.0",
"react-native-orientation-locker": "https://git@github.com/wonday/react-native-orientation-locker#f483520ea6b64b97002374a9e9f053a5299a062a",
"react-native-safe-area-context": "4.4.1",
"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",
"react-native-svg-transformer": "1.0.0",
"react-native-tab-view": "3.1.1",
"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-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1"
"react-native-webrtc": "111.0.1",
"react-native-webview": "11.15.1"
},
"overrides": {
"strophe.js@1.5.0": {
"@xmldom/xmldom": "0.8.7"
}
"@xmldom/xmldom": "0.8.7"
},
"scripts": {
"postinstall": "node sdk_instructions.js",
"prepare": "node prepare_sdk.js"
},
"bugs": {

View File

@@ -3,14 +3,13 @@ const path = require('path');
const packageJSON = require('../package.json');
const {
androidSourcePath,
androidTargetPath,
iosDestPath,
iosSrcPath
} = require('./constants.ts');
const SDKPackageJSON = require('./package.json');
const androidSourcePath = '../android/sdk/src/main/java/org/jitsi/meet/sdk';
const androidTargetPath = './android/src/main/java/org/jitsi/meet/sdk';
const iosSrcPath = '../ios/sdk/src';
const iosDestPath = './ios/src';
/**
* Copies a specified file in a way that recursive copy is possible.
@@ -108,10 +107,6 @@ copyFolderRecursiveSync(
`${iosSrcPath}/dropbox`,
iosDestPath
);
copyFolderRecursiveSync(
'../ios/sdk/src/picture-in-picture',
iosDestPath
);
fs.copyFileSync(
`${iosSrcPath}/AppInfo.m`,
`${iosDestPath}/AppInfo.m`

2
react-native-sdk/sdk_instructions.js vendored Normal file
View File

@@ -0,0 +1,2 @@
console.log('Run node node_modules/@jitsi/react-native-sdk/update_dependencies.js '
+ 'script to update the necessary dependencies');

62
react-native-sdk/update_dependencies.js vendored Normal file
View File

@@ -0,0 +1,62 @@
/* eslint-disable guard-for-in */
/* global __dirname */
const fs = require('fs');
const path = require('path');
const pathToPackageJSON = path.resolve(__dirname, '../../../package.json');
const packageJSON = require(pathToPackageJSON);
const RNSDKpackageJSON = require(path.resolve(__dirname, './package.json'));
/**
* Updates dependencies from the app package.json with the peer dependencies of the RNSDK package.json.
*/
function updateDependencies() {
let updated = false;
for (const key in RNSDKpackageJSON.peerDependencies) {
if (!packageJSON.dependencies.hasOwnProperty(key)) {
packageJSON.dependencies[key] = RNSDKpackageJSON.peerDependencies[key];
updated = true;
}
}
packageJSON.overrides = packageJSON.overrides || {};
for (const key in RNSDKpackageJSON.overrides) {
if (!packageJSON.overrides.hasOwnProperty(key)) {
packageJSON.overrides[key] = RNSDKpackageJSON.overrides[key];
updated = true;
}
}
if (!updated) {
return;
}
console.log(`
=========================
🚀 Your project was updated!
🛠 Make sure you run npm install
📱 If you are building for iOS run cd ios && pod install to link them.
=========================
`);
packageJSON.dependencies = Object.keys(packageJSON.dependencies)
.sort()
.reduce((item, itemKey) => {
item[itemKey] = packageJSON.dependencies[itemKey];
return item;
}, {});
fs.writeFileSync(pathToPackageJSON, JSON.stringify(packageJSON, null, 2));
console.log(
'All needed dependencies have been updated. \nPlease run npm install.'
);
}
updateDependencies();

View File

@@ -8,10 +8,10 @@ import {
import {
createFakeConfig,
restoreConfig
} from '../base/config/functions';
import { connect, disconnect, setLocationURL } from '../base/connection/actions';
} from '../base/config/functions.native';
import { connect, disconnect, setLocationURL } from '../base/connection/actions.native';
import { loadConfig } from '../base/lib-jitsi-meet/functions.native';
import { createDesiredLocalTracks } from '../base/tracks/actions';
import { createDesiredLocalTracks } from '../base/tracks/actions.native';
import isInsecureRoomName from '../base/util/isInsecureRoomName';
import { parseURLParams } from '../base/util/parseURLParams';
import {
@@ -27,6 +27,7 @@ import {
} from '../mobile/navigation/rootNavigationContainerRef';
import { screen } from '../mobile/navigation/routes';
import { clearNotifications } from '../notifications/actions';
import { isUnsafeRoomWarningEnabled } from '../prejoin/functions';
import { addTrackStateToURL, getDefaultURL } from './functions.native';
import logger from './logger';
@@ -137,7 +138,7 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
dispatch(setRoom(room));
if (room) {
if (isInsecureRoomName(room)) {
if (isUnsafeRoomWarningEnabled(getState()) && isInsecureRoomName(room)) {
navigateRoot(screen.unsafeRoomWarning);
return;

View File

@@ -3,20 +3,12 @@ import { API_ID } from '../../../modules/API';
import { setRoom } from '../base/conference/actions';
import {
configWillLoad,
loadConfigError,
setConfig,
storeConfig
setConfig
} from '../base/config/actions';
import { createFakeConfig, restoreConfig } from '../base/config/functions.web';
import { setLocationURL } from '../base/connection/actions.web';
import { loadConfig } from '../base/lib-jitsi-meet/functions.web';
import { inIframe } from '../base/util/iframeUtils';
import { parseURLParams } from '../base/util/parseURLParams';
import {
appendURLParam,
getBackendSafeRoomName,
parseURIString
} from '../base/util/uri';
import { parseURIString } from '../base/util/uri';
import { isVpaasMeeting } from '../jaas/functions';
import { clearNotifications, showNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
@@ -68,7 +60,8 @@ export function appNavigate(uri?: string) {
}
location.protocol || (location.protocol = 'https:');
const { contextRoot, host, room } = location;
const { room } = location;
const locationURL = new URL(location.toString());
// There are notifications now that gets displayed after we technically left
@@ -77,55 +70,7 @@ export function appNavigate(uri?: string) {
dispatch(configWillLoad(locationURL, room));
let protocol = location.protocol.toLowerCase();
// The React Native app supports an app-specific scheme which is sure to not
// be supported by fetch.
protocol !== 'http:' && protocol !== 'https:' && (protocol = 'https:');
const baseURL = `${protocol}//${host}${contextRoot || '/'}`;
let url = `${baseURL}config.js`;
// XXX In order to support multiple shards, tell the room to the deployment.
room && (url = appendURLParam(url, 'room', getBackendSafeRoomName(room) ?? ''));
const { release } = parseURLParams(location, true, 'search');
release && (url = appendURLParam(url, 'release', release));
let config;
// Avoid (re)loading the config when there is no room.
if (!room) {
config = restoreConfig(baseURL);
}
if (!config) {
try {
config = await loadConfig(url);
dispatch(storeConfig(baseURL, config));
} catch (error: any) {
config = restoreConfig(baseURL);
if (!config) {
if (room) {
dispatch(loadConfigError(error, locationURL));
return;
}
// If there is no room (we are on the welcome page), don't fail, just create a fake one.
logger.warn('Failed to load config but there is no room, applying a fake one');
config = createFakeConfig(baseURL);
}
}
}
if (getState()['features/base/config'].locationURL !== locationURL) {
dispatch(loadConfigError(new Error('Config no longer needed!'), locationURL));
return;
}
const config = await loadConfig();
dispatch(setLocationURL(locationURL));
dispatch(setConfig(config));

View File

@@ -1,4 +1,5 @@
import '../analytics/middleware';
import '../authentication/middleware';
import '../av-moderation/middleware';
import '../base/conference/middleware';
import '../base/config/middleware';

View File

@@ -1,4 +1,3 @@
import '../authentication/middleware';
import '../dynamic-branding/middleware';
import '../gifs/middleware';
import '../mobile/audio-mode/middleware';

View File

@@ -1,4 +1,4 @@
import '../authentication/middleware';
import '../base/connection/middleware';
import '../base/i18n/middleware';
import '../base/devices/middleware';
import '../base/media/middleware';

View File

@@ -8,6 +8,24 @@
*/
export const CANCEL_LOGIN = 'CANCEL_LOGIN';
/**
* The type of (redux) action which signals to login.
*
* {
* type: LOGOUT
* }
*/
export const LOGIN = 'LOGIN';
/**
* The type of (redux) action which signals to logout.
*
* {
* type: LOGOUT
* }
*/
export const LOGOUT = 'LOGOUT';
/**
* The type of (redux) action which signals that the cyclic operation of waiting
* for conference owner has been aborted.

View File

@@ -1,7 +1,7 @@
import { IStore } from '../app/types';
import { checkIfCanJoin } from '../base/conference/actions';
import { IJitsiConference } from '../base/conference/reducer';
import { openDialog } from '../base/dialog/actions';
import { hideDialog, openDialog } from '../base/dialog/actions';
import {
STOP_WAIT_FOR_OWNER,
@@ -126,6 +126,16 @@ function _upgradeRoleStarted(thenableWithCancel: Object) {
};
}
/**
* Hides an authentication dialog where the local participant
* should authenticate.
*
* @returns {Function}.
*/
export function hideLoginDialog() {
return hideDialog(LoginDialog);
}
/**
* Opens {@link WaitForOnwerDialog}.
*

View File

@@ -1,4 +1,4 @@
import { appNavigate } from '../app/actions';
import { appNavigate } from '../app/actions.native';
import { IStore } from '../app/types';
import { conferenceLeft } from '../base/conference/actions';
import { connectionFailed } from '../base/connection/actions.native';
@@ -61,4 +61,11 @@ export function cancelWaitForOwner() {
};
}
/** .
* Redirect to the default location (e.g. Welcome page).
*
* @returns {Function}
*/
export function redirectToDefaultLocation() {
return (dispatch: IStore['dispatch']) => dispatch(appNavigate(undefined));
}

View File

@@ -1,12 +1,11 @@
import { maybeRedirectToWelcomePage } from '../app/actions.web';
import { IStore } from '../app/types';
import { hideDialog, openDialog } from '../base/dialog/actions';
import {
CANCEL_LOGIN
CANCEL_LOGIN,
LOGIN,
LOGOUT
} from './actionTypes';
import LoginDialog from './components/web/LoginDialog';
import WaitForOwnerDialog from './components/web/WaitForOwnerDialog';
export * from './actions.any';
@@ -35,31 +34,37 @@ export function cancelWaitForOwner() {
};
}
/**
* Hides a authentication dialog where the local participant
* should authenticate.
/** .
* Redirect to the default location (e.g. Welcome page).
*
* @returns {Function}.
* @returns {Function}
*/
export function hideLoginDialog() {
return hideDialog(LoginDialog);
export function redirectToDefaultLocation() {
return (dispatch: IStore['dispatch']) => dispatch(maybeRedirectToWelcomePage());
}
/**
* Shows a notification dialog that authentication is required to create the.
* Conference.
* This is used for external auth.
* Login.
*
* @param {string} room - The room name.
* @param {Function} onAuthNow - The function to be invoked when external authentication.
*
* @returns {Function}.
* @returns {{
* type: LOGIN
* }}
*/
export function openAuthDialog(room: String, onAuthNow?: Function) {
return openDialog(WaitForOwnerDialog, {
room,
onAuthNow
});
export function login() {
return {
type: LOGIN
};
}
/**
* Logout.
*
* @returns {{
* type: LOGOUT
* }}
*/
export function logout() {
return {
type: LOGOUT
};
}

View File

@@ -31,7 +31,7 @@ interface IProps {
domain: string;
focus?: string;
muc: string;
visitorFocus: string;
visitorFocus?: string;
};
/**

View File

@@ -2,11 +2,10 @@ import React, { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import { connect as reduxConnect } from 'react-redux';
// @ts-expect-error
import { connect } from '../../../../../connection';
import { IReduxState, IStore } from '../../../app/types';
import { IJitsiConference } from '../../../base/conference/reducer';
import { IConfig } from '../../../base/config/configType';
import { connect } from '../../../base/connection/actions.web';
import { toJid } from '../../../base/connection/functions';
import { translate, translateToHTML } from '../../../base/i18n/functions';
import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet';
@@ -54,11 +53,6 @@ interface IProps extends WithTranslation {
*/
dispatch: IStore['dispatch'];
/**
* Invoked when username and password are submitted.
*/
onSuccess: Function;
/**
* Conference room name.
*/
@@ -70,11 +64,6 @@ interface IProps extends WithTranslation {
*/
interface IState {
/**
* Authentication process starts before joining the conference room.
*/
loginStarted: boolean;
/**
* The user entered password for the conference.
*/
@@ -102,8 +91,7 @@ class LoginDialog extends Component<IProps, IState> {
this.state = {
username: '',
password: '',
loginStarted: false
password: ''
};
this._onCancelLogin = this._onCancelLogin.bind(this);
@@ -135,8 +123,6 @@ class LoginDialog extends Component<IProps, IState> {
const {
_conference: conference,
_configHosts: configHosts,
roomName,
onSuccess,
dispatch
} = this.props;
const { password, username } = this.state;
@@ -148,19 +134,7 @@ class LoginDialog extends Component<IProps, IState> {
if (conference) {
dispatch(authenticateAndUpgradeRole(jid, password, conference));
} else {
this.setState({
loginStarted: true
});
connect(jid, password, roomName)
.then((connection: any) => {
onSuccess?.(connection);
})
.catch(() => {
this.setState({
loginStarted: false
});
});
dispatch(connect(jid, password));
}
}
@@ -249,7 +223,7 @@ class LoginDialog extends Component<IProps, IState> {
_connecting: connecting,
t
} = this.props;
const { password, loginStarted, username } = this.state;
const { password, username } = this.state;
return (
<Dialog
@@ -258,7 +232,6 @@ class LoginDialog extends Component<IProps, IState> {
hideCloseButton = { true }
ok = {{
disabled: connecting
|| loginStarted
|| !password
|| !username,
translationKey: 'dialog.login'
@@ -315,7 +288,7 @@ function mapStateToProps(state: IReduxState) {
return {
_conference: authRequired || conference,
_configHosts: configHosts,
_connecting: connecting || thenableWithCancel,
_connecting: Boolean(connecting) || Boolean(thenableWithCancel),
_error: connectionError || authenticateAndUpgradeRoleError,
_progress: progress
};

View File

@@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import { IStore } from '../../../app/types';
import { translate } from '../../../base/i18n/functions';
import Dialog from '../../../base/ui/components/web/Dialog';
import { cancelWaitForOwner } from '../../actions.web';
import { cancelWaitForOwner, login } from '../../actions.web';
/**
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
@@ -16,11 +16,6 @@ interface IProps extends WithTranslation {
* Redux store dispatch method.
*/
dispatch: IStore['dispatch'];
/**
* Function to be invoked after click.
*/
onAuthNow?: Function;
}
/**
@@ -61,9 +56,7 @@ class WaitForOwnerDialog extends PureComponent<IProps> {
* @returns {void}
*/
_onIAmHost() {
const { onAuthNow } = this.props;
onAuthNow?.();
this.props.dispatch(login());
}
/**

View File

@@ -1,4 +1,3 @@
import { appNavigate } from '../app/actions.native';
import { IStore } from '../app/types';
import {
CONFERENCE_FAILED,
@@ -6,6 +5,7 @@ import {
CONFERENCE_LEFT
} from '../base/conference/actionTypes';
import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../base/connection/actionTypes';
import { hangup } from '../base/connection/actions';
import { hideDialog } from '../base/dialog/actions';
import { isDialogOpen } from '../base/dialog/functions';
import {
@@ -13,19 +13,28 @@ import {
JitsiConnectionErrors
} from '../base/lib-jitsi-meet';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { getBackendSafeRoomName } from '../base/util/uri';
import { showErrorNotification } from '../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../notifications/constants';
import { openLogoutDialog } from '../settings/actions';
import {
CANCEL_LOGIN,
LOGIN,
LOGOUT,
STOP_WAIT_FOR_OWNER,
UPGRADE_ROLE_FINISHED,
WAIT_FOR_OWNER
} from './actionTypes';
import {
hideLoginDialog,
openLoginDialog,
openWaitForOwnerDialog,
redirectToDefaultLocation,
stopWaitForOwner,
waitForOwner } from './actions.native';
waitForOwner } from './actions';
import { LoginDialog, WaitForOwnerDialog } from './components';
import { getTokenAuthUrl, isTokenAuthEnabled } from './functions';
/**
* Middleware that captures connection or conference failed errors and controls
@@ -40,7 +49,8 @@ MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case CANCEL_LOGIN: {
const { dispatch, getState } = store;
const { thenableWithCancel } = getState()['features/authentication'];
const state = getState();
const { thenableWithCancel } = state['features/authentication'];
thenableWithCancel?.cancel();
@@ -57,10 +67,8 @@ MiddlewareRegistry.register(store => next => action => {
return result;
}
// Go back to the app's entry point.
_hideLoginDialog(store);
dispatch(hideLoginDialog());
const state = getState();
const { authRequired, conference } = state['features/base/conference'];
const { passwordRequired } = state['features/base/connection'];
@@ -68,7 +76,7 @@ MiddlewareRegistry.register(store => next => action => {
// NOTE: Despite it's confusing name, `passwordRequired` implies an XMPP
// connection auth error.
if ((passwordRequired || authRequired) && !conference) {
dispatch(appNavigate(undefined));
dispatch(redirectToDefaultLocation());
}
}
break;
@@ -100,7 +108,7 @@ MiddlewareRegistry.register(store => next => action => {
if (_isWaitingForOwner(store)) {
store.dispatch(stopWaitForOwner());
}
_hideLoginDialog(store);
store.dispatch(hideLoginDialog());
break;
case CONFERENCE_LEFT:
@@ -108,18 +116,43 @@ MiddlewareRegistry.register(store => next => action => {
break;
case CONNECTION_ESTABLISHED:
_hideLoginDialog(store);
store.dispatch(hideLoginDialog());
break;
case CONNECTION_FAILED: {
const { error } = action;
const state = store.getState();
const { jwt } = state['features/base/jwt'];
if (error
&& error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
&& typeof error.recoverable === 'undefined') {
&& typeof error.recoverable === 'undefined'
&& !jwt) {
error.recoverable = true;
store.dispatch(openLoginDialog());
_handleLogin(store);
}
break;
}
case LOGIN: {
_handleLogin(store);
break;
}
case LOGOUT: {
const { conference } = store.getState()['features/base/conference'];
if (!conference) {
break;
}
store.dispatch(openLogoutDialog(() =>
conference.room.moderator.logout(() => store.dispatch(hangup(true)))
));
break;
}
@@ -132,7 +165,7 @@ MiddlewareRegistry.register(store => next => action => {
const { error, progress } = action;
if (!error && progress === 1) {
_hideLoginDialog(store);
store.dispatch(hideLoginDialog());
}
break;
}
@@ -144,7 +177,7 @@ MiddlewareRegistry.register(store => next => action => {
action.waitForOwnerTimeoutID = setTimeout(handler, timeoutMs);
// The WAIT_FOR_OWNER action is cyclic and we don't want to hide the
// The WAIT_FOR_OWNER action is cyclic, and we don't want to hide the
// login dialog every few seconds.
isDialogOpen(store, LoginDialog)
|| store.dispatch(openWaitForOwnerDialog());
@@ -162,22 +195,12 @@ MiddlewareRegistry.register(store => next => action => {
* @param {Object} store - The redux store.
* @returns {void}
*/
function _clearExistingWaitForOwnerTimeout(
{ getState }: IStore) {
function _clearExistingWaitForOwnerTimeout({ getState }: IStore) {
const { waitForOwnerTimeoutID } = getState()['features/authentication'];
waitForOwnerTimeoutID && clearTimeout(waitForOwnerTimeoutID);
}
/**
* Hides {@link LoginDialog} if it's currently displayed.
*
* @param {Object} store - The redux store.
* @returns {void}
*/
function _hideLoginDialog({ dispatch }: IStore) {
dispatch(hideDialog(LoginDialog));
}
/**
* Checks if the cyclic "wait for conference owner" task is currently scheduled.
@@ -188,3 +211,35 @@ function _hideLoginDialog({ dispatch }: IStore) {
function _isWaitingForOwner({ getState }: IStore) {
return Boolean(getState()['features/authentication'].waitForOwnerTimeoutID);
}
/**
* Handles login challenge. Opens login dialog or redirects to token auth URL.
*
* @param {Store} store - The redux store in which the specified {@code action}
* is being dispatched.
* @returns {void}
*/
function _handleLogin({ dispatch, getState }: IStore) {
const state = getState();
const config = state['features/base/config'];
const room = getBackendSafeRoomName(state['features/base/conference'].room);
if (isTokenAuthEnabled(config)) {
if (typeof APP === 'undefined') {
dispatch(showErrorNotification({
descriptionKey: 'dialog.tokenAuthUnsupported',
titleKey: 'dialog.tokenAuthFailedTitle'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
dispatch(redirectToDefaultLocation());
return;
}
// FIXME: This method will not preserve the other URL params that were originally passed.
// redirectToTokenAuthService
window.location.href = getTokenAuthUrl(config)(room, false);
} else {
dispatch(openLoginDialog());
}
}

View File

@@ -1,152 +0,0 @@
import { maybeRedirectToWelcomePage } from '../app/actions.web';
import { IStore } from '../app/types';
import {
CONFERENCE_FAILED,
CONFERENCE_JOINED,
CONFERENCE_LEFT
} from '../base/conference/actionTypes';
import { CONNECTION_ESTABLISHED } from '../base/connection/actionTypes';
import { hideDialog } from '../base/dialog/actions';
import { isDialogOpen } from '../base/dialog/functions';
import {
JitsiConferenceErrors
} from '../base/lib-jitsi-meet';
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import {
CANCEL_LOGIN,
STOP_WAIT_FOR_OWNER,
UPGRADE_ROLE_FINISHED,
WAIT_FOR_OWNER
} from './actionTypes';
import {
hideLoginDialog,
openWaitForOwnerDialog,
stopWaitForOwner
} from './actions.web';
import LoginDialog from './components/web/LoginDialog';
import WaitForOwnerDialog from './components/web/WaitForOwnerDialog';
/**
* Middleware that captures connection or conference failed errors and controls
* {@link WaitForOwnerDialog} and {@link LoginDialog}.
*
* FIXME Some of the complexity was introduced by the lack of dialog stacking.
*
* @param {Store} store - Redux store.
* @returns {Function}
*/
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case CANCEL_LOGIN: {
const { dispatch, getState } = store;
if (!isDialogOpen(store, WaitForOwnerDialog)) {
if (_isWaitingForOwner(store)) {
dispatch(openWaitForOwnerDialog());
return next(action);
}
dispatch(hideLoginDialog());
const { authRequired, conference } = getState()['features/base/conference'];
const { passwordRequired } = getState()['features/base/connection'];
// Only end the meeting if we are not already inside and trying to upgrade.
if ((authRequired && !conference) || passwordRequired) {
dispatch(maybeRedirectToWelcomePage());
}
}
break;
}
case CONFERENCE_FAILED: {
const { error } = action;
let recoverable;
if (error.name === JitsiConferenceErrors.AUTHENTICATION_REQUIRED) {
if (typeof error.recoverable === 'undefined') {
error.recoverable = true;
}
recoverable = error.recoverable;
}
if (recoverable) {
// we haven't migrated all the code from AuthHandler, and we need for now conference.js to trigger
// the dialog to pass all required parameters to WaitForOwnerDialog
// keep it commented, so we do not trigger sending iqs to jicofo twice
// and showing the broken dialog with no handler
// store.dispatch(waitForOwner());
} else {
store.dispatch(stopWaitForOwner());
}
break;
}
case CONFERENCE_JOINED:
store.dispatch(stopWaitForOwner());
store.dispatch(hideLoginDialog());
break;
case CONFERENCE_LEFT:
store.dispatch(stopWaitForOwner());
break;
case CONNECTION_ESTABLISHED:
store.dispatch(hideLoginDialog());
break;
case STOP_WAIT_FOR_OWNER:
_clearExistingWaitForOwnerTimeout(store);
store.dispatch(hideDialog(WaitForOwnerDialog));
break;
case UPGRADE_ROLE_FINISHED: {
const { error, progress } = action;
if (!error && progress === 1) {
store.dispatch(hideLoginDialog());
}
break;
}
case WAIT_FOR_OWNER: {
_clearExistingWaitForOwnerTimeout(store);
const { handler, timeoutMs }: { handler: () => void; timeoutMs: number; } = action;
action.waitForOwnerTimeoutID = setTimeout(handler, timeoutMs);
isDialogOpen(store, LoginDialog)
|| store.dispatch(openWaitForOwnerDialog());
break;
}
}
return next(action);
});
/**
* Will clear the wait for conference owner timeout handler if any is currently
* set.
*
* @param {Object} store - The redux store.
* @returns {void}
*/
function _clearExistingWaitForOwnerTimeout(
{ getState }: IStore) {
const { waitForOwnerTimeoutID } = getState()['features/authentication'];
waitForOwnerTimeoutID && clearTimeout(waitForOwnerTimeoutID);
}
/**
* Checks if the cyclic "wait for conference owner" task is currently scheduled.
*
* @param {Object} store - The redux store.
* @returns {void}
*/
function _isWaitingForOwner({ getState }: IStore) {
return getState()['features/authentication'].waitForOwnerTimeoutID;
}

View File

@@ -106,6 +106,15 @@ export const CONFERENCE_UNIQUE_ID_SET = 'CONFERENCE_UNIQUE_ID_SET';
*/
export const E2E_RTT_CHANGED = 'E2E_RTT_CHANGED'
/**
* The type of (redux) action which signals that a conference will be initialized.
*
* {
* type: CONFERENCE_WILL_INIT
* }
*/
export const CONFERENCE_WILL_INIT = 'CONFERENCE_WILL_INIT';
/**
* The type of (redux) action which signals that a specific conference will be
* joined.

View File

@@ -1,11 +1,10 @@
import { createStartMutedConfigurationEvent } from '../../analytics/AnalyticsEvents';
import { sendAnalytics } from '../../analytics/functions';
import { appNavigate } from '../../app/actions';
import { IReduxState, IStore } from '../../app/types';
import { endpointMessageReceived } from '../../subtitles/actions.any';
import { iAmVisitor } from '../../visitors/functions';
import { getReplaceParticipant } from '../config/functions';
import { disconnect } from '../connection/actions';
import { hangup } from '../connection/actions';
import { JITSI_CONNECTION_CONFERENCE_KEY } from '../connection/constants';
import { JitsiConferenceEvents, JitsiE2ePingEvents } from '../lib-jitsi-meet';
import { setAudioMuted, setAudioUnmutePermissions, setVideoMuted, setVideoUnmutePermissions } from '../media/actions';
@@ -41,6 +40,7 @@ import {
CONFERENCE_SUBJECT_CHANGED,
CONFERENCE_TIMESTAMP_CHANGED,
CONFERENCE_UNIQUE_ID_SET,
CONFERENCE_WILL_INIT,
CONFERENCE_WILL_JOIN,
CONFERENCE_WILL_LEAVE,
DATA_CHANNEL_CLOSED,
@@ -463,6 +463,19 @@ export function _conferenceWillJoin(conference: IJitsiConference) {
};
}
/**
* Signals the intention of the application to have a conference initialized.
*
* @returns {{
* type: CONFERENCE_WILL_INIT
* }}
*/
export function conferenceWillInit() {
return {
type: CONFERENCE_WILL_INIT
};
}
/**
* Signals the intention of the application to have the local participant
* join the specified conference.
@@ -647,18 +660,9 @@ export function kickedOut(conference: IJitsiConference, participant: Object) {
* @returns {Function}
*/
export function leaveConference() {
return async (dispatch: IStore['dispatch']) => {
// FIXME: these should be unified.
if (navigator.product === 'ReactNative') {
dispatch(appNavigate(undefined));
} else {
dispatch(disconnect(true));
}
};
return async (dispatch: IStore['dispatch']) => dispatch(hangup(true));
}
/**
* Signals that the lock state of a specific JitsiConference changed.
*

View File

@@ -16,6 +16,8 @@ import { openDisplayNamePrompt } from '../../display-name/actions';
import { readyToClose } from '../../mobile/external-api/actions';
import { showErrorNotification, showWarningNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import { stopLocalVideoRecording } from '../../recording/actions.any';
import LocalRecordingManager from '../../recording/components/Recording/LocalRecordingManager';
import { setIAmVisitor } from '../../visitors/actions';
import { iAmVisitor } from '../../visitors/functions';
import { overwriteConfig } from '../config/actions';
@@ -47,6 +49,7 @@ import {
} from './actionTypes';
import {
conferenceFailed,
conferenceWillInit,
conferenceWillLeave,
createConference,
leaveConference,
@@ -71,7 +74,7 @@ import logger from './logger';
/**
* Handler for before unload event.
*/
let beforeUnloadHandler: (() => void) | undefined;
let beforeUnloadHandler: ((e?: any) => void) | undefined;
/**
* Implements the middleware of the feature base/conference.
@@ -142,12 +145,6 @@ MiddlewareRegistry.register(store => next => action => {
function _conferenceFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
const { conference, error } = action;
if (error.name === JitsiConferenceErrors.REDIRECTED) {
if (typeof error.recoverable === 'undefined') {
error.recoverable = true;
}
}
const result = next(action);
const { enableForcedReload } = getState()['features/base/config'];
@@ -195,18 +192,22 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio
break;
}
case JitsiConferenceErrors.CONFERENCE_MAX_USERS: {
if (typeof APP === 'undefined') {
// in case of max users(it can be from a visitor node), let's restore
// oldConfig if any as we will be back to the main prosody
const newConfig = restoreConferenceOptions(getState);
dispatch(showErrorNotification({
hideErrorSupportLink: true,
descriptionKey: 'dialog.maxUsersLimitReached',
titleKey: 'dialog.maxUsersLimitReachedTitle'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
if (newConfig) {
dispatch(overwriteConfig(newConfig)) // @ts-ignore
.then(dispatch(conferenceWillLeave(conference)))
.then(conference.leave())
.then(dispatch(disconnect()))
.then(dispatch(connect()));
}
// In case of max users(it can be from a visitor node), let's restore
// oldConfig if any as we will be back to the main prosody.
const newConfig = restoreConferenceOptions(getState);
if (newConfig) {
dispatch(overwriteConfig(newConfig)) // @ts-ignore
.then(dispatch(conferenceWillLeave(conference)))
.then(conference.leave())
.then(dispatch(disconnect()))
.then(dispatch(connect()));
}
break;
@@ -214,45 +215,48 @@ function _conferenceFailed({ dispatch, getState }: IStore, next: Function, actio
case JitsiConferenceErrors.OFFER_ANSWER_FAILED:
sendAnalytics(createOfferAnswerFailedEvent());
break;
case JitsiConferenceErrors.REDIRECTED: {
// once conference.js is gone this can be removed and both
// redirect logics to be merged
if (typeof APP === 'undefined') {
const newConfig = getVisitorOptions(getState, error.params);
const newConfig = getVisitorOptions(getState, error.params);
if (!newConfig) {
logger.warn('Not redirected missing params');
break;
}
const [ vnode ] = error.params;
dispatch(overwriteConfig(newConfig)) // @ts-ignore
.then(dispatch(conferenceWillLeave(conference)))
.then(conference.leave())
.then(dispatch(disconnect()))
.then(dispatch(setIAmVisitor(Boolean(vnode))))
// we do not clear local tracks on error, so we need to manually clear them
.then(dispatch(destroyLocalTracks()))
.then(dispatch(connect()));
if (!newConfig) {
logger.warn('Not redirected missing params');
break;
}
const [ vnode ] = error.params;
dispatch(overwriteConfig(newConfig)) // @ts-ignore
.then(() => dispatch(conferenceWillLeave(conference)))
.then(() => dispatch(disconnect()))
.then(() => dispatch(setIAmVisitor(Boolean(vnode))))
// we do not clear local tracks on error, so we need to manually clear them
.then(() => dispatch(destroyLocalTracks()))
.then(() => dispatch(conferenceWillInit()))
.then(() => dispatch(connect()))
.then(() => {
// FIXME: Workaround for the web version. To be removed once we get rid of conference.js
if (typeof APP !== 'undefined') {
APP.conference.startConference([]);
}
});
break;
}
}
if (typeof APP === 'undefined') {
!error.recoverable
&& conference
&& conference.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).catch((reason: Error) => {
// Even though we don't care too much about the failure, it may be
// good to know that it happen, so log it (on the info level).
logger.info('JitsiConference.leave() rejected with:', reason);
});
} else {
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js and appropriate failure handlers
// are set there.
!error.recoverable
&& conference
&& conference.leave(CONFERENCE_LEAVE_REASONS.UNRECOVERABLE_ERROR).catch((reason: Error) => {
// Even though we don't care too much about the failure, it may be
// good to know that it happen, so log it (on the info level).
logger.info('JitsiConference.leave() rejected with:', reason);
});
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js and appropriate failure handlers
// are set there.
if (typeof APP !== 'undefined') {
_removeUnloadHandler(getState);
}
@@ -295,7 +299,14 @@ function _conferenceJoined({ dispatch, getState }: IStore, next: Function, actio
// handles the process of leaving the conference. This is temporary solution
// that should cover the described use case as part of the effort to
// implement the conferenceWillLeave action for web.
beforeUnloadHandler = () => {
beforeUnloadHandler = (e?: any) => {
if (LocalRecordingManager.isRecordingLocally()) {
dispatch(stopLocalVideoRecording());
if (e) {
e.preventDefault();
e.returnValue = null;
}
}
dispatch(conferenceWillLeave(conference));
};
@@ -330,12 +341,16 @@ function _conferenceJoined({ dispatch, getState }: IStore, next: Function, actio
* @private
* @returns {Object} The value returned by {@code next(action)}.
*/
function _connectionEstablished({ dispatch }: IStore, next: Function, action: AnyAction) {
async function _connectionEstablished({ dispatch }: IStore, next: Function, action: AnyAction) {
const result = next(action);
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js.
typeof APP === 'undefined' && dispatch(createConference());
if (typeof APP === 'undefined') {
dispatch(createConference());
return result;
}
return result;
}
@@ -377,45 +392,45 @@ function _logJwtErrors(message: string, state: IReduxState) {
function _connectionFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
_logJwtErrors(action.error.message, getState());
dispatch(showErrorNotification({
descriptionKey: 'dialog.tokenAuthFailed',
titleKey: 'dialog.tokenAuthFailedTitle'
}, NOTIFICATION_TIMEOUT_TYPE.LONG));
const result = next(action);
_removeUnloadHandler(getState);
// FIXME: Workaround for the web version. Currently, the creation of the
// conference is handled by /conference.js and appropriate failure handlers
// are set there.
if (typeof APP === 'undefined') {
const { connection } = action;
const { error } = action;
const { connection } = action;
const { error } = action;
forEachConference(getState, conference => {
// It feels that it would make things easier if JitsiConference
// in lib-jitsi-meet would monitor it's connection and emit
// CONFERENCE_FAILED when it's dropped. It has more knowledge on
// whether it can recover or not. But because the reload screen
// and the retry logic is implemented in the app maybe it can be
// left this way for now.
if (conference.getConnection() === connection) {
// XXX Note that on mobile the error type passed to
// connectionFailed is always an object with .name property.
// This fact needs to be checked prior to enabling this logic on
// web.
const conferenceAction
= conferenceFailed(conference, error.name);
forEachConference(getState, conference => {
// TODO: revisit this
// It feels that it would make things easier if JitsiConference
// in lib-jitsi-meet would monitor it's connection and emit
// CONFERENCE_FAILED when it's dropped. It has more knowledge on
// whether it can recover or not. But because the reload screen
// and the retry logic is implemented in the app maybe it can be
// left this way for now.
if (conference.getConnection() === connection) {
// XXX Note that on mobile the error type passed to
// connectionFailed is always an object with .name property.
// This fact needs to be checked prior to enabling this logic on
// web.
const conferenceAction = conferenceFailed(conference, error.name);
// Copy the recoverable flag if set on the CONNECTION_FAILED
// action to not emit recoverable action caused by
// a non-recoverable one.
if (typeof error.recoverable !== 'undefined') {
conferenceAction.error.recoverable = error.recoverable;
}
dispatch(conferenceAction);
// Copy the recoverable flag if set on the CONNECTION_FAILED
// action to not emit recoverable action caused by
// a non-recoverable one.
if (typeof error.recoverable !== 'undefined') {
conferenceAction.error.recoverable = error.recoverable;
}
return true;
});
}
dispatch(conferenceAction);
}
return true;
});
return result;
}

View File

@@ -9,7 +9,8 @@ import {
CONFERENCE_FAILED,
CONFERENCE_JOINED,
CONFERENCE_JOIN_IN_PROGRESS,
CONFERENCE_LEFT, KICKED_OUT
CONFERENCE_LEFT,
KICKED_OUT
} from './actionTypes';
import logger from './logger';
import './middleware.any';

View File

@@ -155,6 +155,9 @@ export interface IConferenceState {
export interface IJitsiConferenceRoom {
locked: boolean;
moderator: {
logout: Function;
};
myroomjid: string;
roomjid: string;
}

View File

@@ -390,7 +390,7 @@ export interface IConfig {
domain: string;
focus?: string;
muc: string;
visitorFocus: string;
visitorFocus?: string;
};
iAmRecorder?: boolean;
iAmSipGateway?: boolean;
@@ -441,10 +441,10 @@ export interface IConfig {
opusMaxAverageBitrate?: number;
p2p?: {
backToP2PDelay?: number;
disabledCodec?: string;
codecPreferenceOrder?: Array<string>;
enabled?: boolean;
iceTransportPolicy?: string;
preferredCodec?: string;
mobileCodecPreferenceOrder?: Array<string>;
stunServers?: Array<{ urls: string; }>;
};
participantsPane?: {
@@ -545,8 +545,7 @@ export interface IConfig {
useHostPageLocalStorage?: boolean;
useTurnUdp?: boolean;
videoQuality?: {
disabledCodec?: string;
enforcePreferredCodec?: boolean;
codecPreferenceOrder?: Array<string>;
maxBitratesVideo?: {
[key: string]: {
high?: number;
@@ -557,8 +556,8 @@ export interface IConfig {
minHeightForQualityLvl?: {
[key: number]: string;
};
mobileCodecPreferenceOrder?: Array<string>;
persist?: boolean;
preferredCodec?: string;
};
webhookProxyUrl?: string;
webrtcIceTcpDisable?: boolean;

View File

@@ -195,7 +195,6 @@ export default [
'p2p',
'participantsPane',
'pcStatsInterval',
'preferredCodec',
'prejoinConfig',
'prejoinPageEnabled',
'recordingService',

View File

@@ -43,18 +43,6 @@ const INITIAL_NON_RN_STATE: IConfig = {
* @type {Object}
*/
const INITIAL_RN_STATE: IConfig = {
// FIXME: Mobile codecs should probably be configurable separately, rather
// FIXME: than requiring this override here...
p2p: {
disabledCodec: 'vp9',
preferredCodec: 'h264'
},
videoQuality: {
disabledCodec: 'vp9',
preferredCodec: 'vp8'
}
};
/**

View File

@@ -1,6 +1,10 @@
import _ from 'lodash';
import { IReduxState } from '../../app/types';
import { IReduxState, IStore } from '../../app/types';
import { setPrejoinDisplayNameRequired } from '../../prejoin/actions.any';
import { conferenceLeft, conferenceWillLeave } from '../conference/actions';
import { getCurrentConference } from '../conference/functions';
import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet';
import {
appendURLParam,
getBackendSafeRoomName
@@ -10,8 +14,10 @@ import {
CONNECTION_DISCONNECTED,
CONNECTION_ESTABLISHED,
CONNECTION_FAILED,
CONNECTION_WILL_CONNECT,
SET_LOCATION_URL
} from './actionTypes';
import { JITSI_CONNECTION_URL_KEY } from './constants';
import logger from './logger';
/**
@@ -194,3 +200,194 @@ export function setLocationURL(locationURL?: URL) {
locationURL
};
}
/**
* Opens new connection.
*
* @param {string} [id] - The XMPP user's ID (e.g. {@code user@server.com}).
* @param {string} [password] - The XMPP user's password.
* @returns {Function}
*/
export function _connectInternal(id?: string, password?: string) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const options = constructOptions(state);
const { locationURL } = state['features/base/connection'];
const { jwt } = state['features/base/jwt'];
const connection = new JitsiMeetJS.JitsiConnection(options.appId, jwt, options);
connection[JITSI_CONNECTION_URL_KEY] = locationURL;
dispatch(_connectionWillConnect(connection));
return new Promise((resolve, reject) => {
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_DISCONNECTED,
_onConnectionDisconnected);
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_ESTABLISHED,
_onConnectionEstablished);
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
_onConnectionFailed);
/**
* Marks the display name for the prejoin screen as required.
* This can happen if a user tries to join a room with lobby enabled.
*/
connection.addEventListener(
JitsiConnectionEvents.DISPLAY_NAME_REQUIRED,
() => dispatch(setPrejoinDisplayNameRequired())
);
/**
* Unsubscribe the connection instance from
* {@code CONNECTION_DISCONNECTED} and {@code CONNECTION_FAILED} events.
*
* @returns {void}
*/
function unsubscribe() {
connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_DISCONNECTED, _onConnectionDisconnected);
connection.removeEventListener(JitsiConnectionEvents.CONNECTION_FAILED, _onConnectionFailed);
}
/**
* Dispatches {@code CONNECTION_DISCONNECTED} action when connection is
* disconnected.
*
* @private
* @returns {void}
*/
function _onConnectionDisconnected() {
unsubscribe();
dispatch(connectionDisconnected(connection));
resolve(connection);
}
/**
* Rejects external promise when connection fails.
*
* @param {JitsiConnectionErrors} err - Connection error.
* @param {string} [message] - Error message supplied by lib-jitsi-meet.
* @param {Object} [credentials] - The invalid credentials that were
* used to authenticate and the authentication failed.
* @param {string} [credentials.jid] - The XMPP user's ID.
* @param {string} [credentials.password] - The XMPP user's password.
* @param {Object} details - Additional information about the error.
* @private
* @returns {void}
*/
function _onConnectionFailed( // eslint-disable-line max-params
err: string,
message: string,
credentials: any,
details: Object) {
unsubscribe();
dispatch(connectionFailed(connection, {
credentials,
details,
name: err,
message
}));
reject(err);
}
/**
* Resolves external promise when connection is established.
*
* @private
* @returns {void}
*/
function _onConnectionEstablished() {
connection.removeEventListener(JitsiConnectionEvents.CONNECTION_ESTABLISHED, _onConnectionEstablished);
dispatch(connectionEstablished(connection, Date.now()));
resolve(connection);
}
connection.connect({
id,
password
});
});
};
}
/**
* Create an action for when a connection will connect.
*
* @param {JitsiConnection} connection - The {@code JitsiConnection} which will
* connect.
* @private
* @returns {{
* type: CONNECTION_WILL_CONNECT,
* connection: JitsiConnection
* }}
*/
function _connectionWillConnect(connection: Object) {
return {
type: CONNECTION_WILL_CONNECT,
connection
};
}
/**
* Closes connection.
*
* @returns {Function}
*/
export function disconnect() {
return (dispatch: IStore['dispatch'], getState: IStore['getState']): Promise<void> => {
const state = getState();
// The conference we have already joined or are joining.
const conference_ = getCurrentConference(state);
// Promise which completes when the conference has been left and the
// connection has been disconnected.
let promise;
// Leave the conference.
if (conference_) {
// In a fashion similar to JitsiConference's CONFERENCE_LEFT event
// (and the respective Redux action) which is fired after the
// conference has been left, notify the application about the
// intention to leave the conference.
dispatch(conferenceWillLeave(conference_));
promise
= conference_.leave()
.catch((error: Error) => {
logger.warn(
'JitsiConference.leave() rejected with:',
error);
// The library lib-jitsi-meet failed to make the
// JitsiConference leave. Which may be because
// JitsiConference thinks it has already left.
// Regardless of the failure reason, continue in
// jitsi-meet as if the leave has succeeded.
dispatch(conferenceLeft(conference_));
});
} else {
promise = Promise.resolve();
}
// Disconnect the connection.
const { connecting, connection } = state['features/base/connection'];
// The connection we have already connected or are connecting.
const connection_ = connection || connecting;
if (connection_) {
promise = promise.then(() => connection_.disconnect());
} else {
logger.info('No connection found while disconnecting.');
}
return promise;
};
}

View File

@@ -1,19 +1,7 @@
import { appNavigate } from '../../app/actions.native';
import { IStore } from '../../app/types';
import { conferenceLeft, conferenceWillLeave } from '../conference/actions';
import { getCurrentConference } from '../conference/functions';
import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet';
import {
CONNECTION_WILL_CONNECT
} from './actionTypes';
import {
connectionDisconnected,
connectionEstablished,
connectionFailed,
constructOptions
} from './actions.any';
import { JITSI_CONNECTION_URL_KEY } from './constants';
import logger from './logger';
import { _connectInternal } from './actions.any';
export * from './actions.any';
@@ -25,178 +13,16 @@ export * from './actions.any';
* @returns {Function}
*/
export function connect(id?: string, password?: string) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const state = getState();
const options = constructOptions(state);
const { locationURL } = state['features/base/connection'];
const { jwt } = state['features/base/jwt'];
const connection = new JitsiMeetJS.JitsiConnection(options.appId, jwt, options);
connection[JITSI_CONNECTION_URL_KEY] = locationURL;
dispatch(_connectionWillConnect(connection));
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_DISCONNECTED,
_onConnectionDisconnected);
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_ESTABLISHED,
_onConnectionEstablished);
connection.addEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
_onConnectionFailed);
connection.connect({
id,
password
});
/**
* Dispatches {@code CONNECTION_DISCONNECTED} action when connection is
* disconnected.
*
* @private
* @returns {void}
*/
function _onConnectionDisconnected() {
unsubscribe();
dispatch(connectionDisconnected(connection));
}
/**
* Resolves external promise when connection is established.
*
* @private
* @returns {void}
*/
function _onConnectionEstablished() {
connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_ESTABLISHED,
_onConnectionEstablished);
dispatch(connectionEstablished(connection, Date.now()));
}
/**
* Rejects external promise when connection fails.
*
* @param {JitsiConnectionErrors} err - Connection error.
* @param {string} [msg] - Error message supplied by lib-jitsi-meet.
* @param {Object} [credentials] - The invalid credentials that were
* used to authenticate and the authentication failed.
* @param {string} [credentials.jid] - The XMPP user's ID.
* @param {string} [credentials.password] - The XMPP user's password.
* @param {Object} details - Additional information about the error.
* @private
* @returns {void}
*/
function _onConnectionFailed( // eslint-disable-line max-params
err: string,
msg: string,
credentials: any,
details: Object) {
unsubscribe();
dispatch(
connectionFailed(
connection, {
credentials,
details,
name: err,
message: msg
}
));
}
/**
* Unsubscribe the connection instance from
* {@code CONNECTION_DISCONNECTED} and {@code CONNECTION_FAILED} events.
*
* @returns {void}
*/
function unsubscribe() {
connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_DISCONNECTED,
_onConnectionDisconnected);
connection.removeEventListener(
JitsiConnectionEvents.CONNECTION_FAILED,
_onConnectionFailed);
}
};
return (dispatch: IStore['dispatch']) => dispatch(_connectInternal(id, password));
}
/**
* Create an action for when a connection will connect.
* Hangup.
*
* @param {JitsiConnection} connection - The {@code JitsiConnection} which will
* connect.
* @private
* @returns {{
* type: CONNECTION_WILL_CONNECT,
* connection: JitsiConnection
* }}
*/
function _connectionWillConnect(connection: Object) {
return {
type: CONNECTION_WILL_CONNECT,
connection
};
}
/**
* Closes connection.
*
* @param {boolean} _ - Used in web.
* @param {boolean} [_requestFeedback] - Whether to attempt showing a
* request for call feedback.
* @returns {Function}
*/
export function disconnect(_?: boolean) {
/* eslint-enable @typescript-eslint/no-unused-vars */
return (dispatch: IStore['dispatch'], getState: IStore['getState']): Promise<void> => {
const state = getState();
// The conference we have already joined or are joining.
const conference_ = getCurrentConference(state);
// Promise which completes when the conference has been left and the
// connection has been disconnected.
let promise;
// Leave the conference.
if (conference_) {
// In a fashion similar to JitsiConference's CONFERENCE_LEFT event
// (and the respective Redux action) which is fired after the
// conference has been left, notify the application about the
// intention to leave the conference.
dispatch(conferenceWillLeave(conference_));
promise
= conference_.leave()
.catch((error: Error) => {
logger.warn(
'JitsiConference.leave() rejected with:',
error);
// The library lib-jitsi-meet failed to make the
// JitsiConference leave. Which may be because
// JitsiConference thinks it has already left.
// Regardless of the failure reason, continue in
// jitsi-meet as if the leave has succeeded.
dispatch(conferenceLeft(conference_));
});
} else {
promise = Promise.resolve();
}
// Disconnect the connection.
const { connecting, connection } = state['features/base/connection'];
// The connection we have already connected or are connecting.
const connection_ = connection || connecting;
if (connection_) {
promise = promise.then(() => connection_.disconnect());
} else {
logger.info('No connection found while disconnecting.');
}
return promise;
};
export function hangup(_requestFeedback = false) {
return (dispatch: IStore['dispatch']) => dispatch(appNavigate(undefined));
}

View File

@@ -1,47 +1,81 @@
import { IStore } from '../../app/types';
import { configureInitialDevices } from '../devices/actions';
import { getBackendSafeRoomName } from '../util/uri';
// @ts-expect-error
import { jitsiLocalStorage } from '@jitsi/js-utils';
export {
connectionDisconnected,
connectionEstablished,
connectionFailed,
setLocationURL
} from './actions.any';
import logger from './logger';
import { IStore } from '../../app/types';
import { getCustomerDetails } from '../../jaas/actions.any';
import { getJaasJWT, isVpaasMeeting } from '../../jaas/functions';
import { showWarningNotification } from '../../notifications/actions';
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
import { stopLocalVideoRecording } from '../../recording/actions.any';
import LocalRecordingManager from '../../recording/components/Recording/LocalRecordingManager.web';
import { setJWT } from '../jwt/actions';
import { _connectInternal } from './actions.any';
export * from './actions.any';
/**
* Opens new connection.
*
* @returns {Promise<JitsiConnection>}
* @param {string} [id] - The XMPP user's ID (e.g. {@code user@server.com}).
* @param {string} [password] - The XMPP user's password.
* @returns {Function}
*/
export function connect() {
export function connect(id?: string, password?: string) {
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
const room = getBackendSafeRoomName(getState()['features/base/conference'].room);
const state = getState();
const { jwt } = state['features/base/jwt'];
const { iAmRecorder, iAmSipGateway } = state['features/base/config'];
// XXX For web based version we use conference initialization logic
// from the old app (at the moment of writing).
return dispatch(configureInitialDevices()).then(
() => APP.conference.init({
roomName: room
}).catch((error: Error) => {
APP.API.notifyConferenceLeft(APP.conference.roomName);
logger.error(error);
}));
if (!iAmRecorder && !iAmSipGateway && isVpaasMeeting(state)) {
return dispatch(getCustomerDetails())
.then(() => {
if (!jwt) {
return getJaasJWT(state);
}
})
.then(j => j && dispatch(setJWT(j)))
.then(() => _connectInternal(id, password));
}
// used by jibri
const usernameOverride = jitsiLocalStorage.getItem('xmpp_username_override');
const passwordOverride = jitsiLocalStorage.getItem('xmpp_password_override');
if (usernameOverride && usernameOverride.length > 0) {
id = usernameOverride; // eslint-disable-line no-param-reassign
}
if (passwordOverride && passwordOverride.length > 0) {
password = passwordOverride; // eslint-disable-line no-param-reassign
}
return dispatch(_connectInternal(id, password));
};
}
/**
* Closes connection.
*
* @param {boolean} [requestFeedback] - Whether or not to attempt showing a
* @param {boolean} [requestFeedback] - Whether to attempt showing a
* request for call feedback.
* @returns {Function}
*/
export function disconnect(requestFeedback = false) {
// XXX For web based version we use conference hanging up logic from the old
// app.
return () => APP.conference.hangup(requestFeedback);
export function hangup(requestFeedback = false) {
// XXX For web based version we use conference hanging up logic from the old app.
return async (dispatch: IStore['dispatch']) => {
if (LocalRecordingManager.isRecordingLocally()) {
dispatch(stopLocalVideoRecording());
dispatch(showWarningNotification({
titleKey: 'localRecording.stopping',
descriptionKey: 'localRecording.wait'
}, NOTIFICATION_TIMEOUT_TYPE.STICKY));
// wait 1000ms for the recording to end and start downloading
await new Promise(res => {
setTimeout(res, 1000);
});
}
return APP.conference.hangup(requestFeedback);
};
}

View File

@@ -0,0 +1,30 @@
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
import { CONNECTION_WILL_CONNECT } from './actionTypes';
/**
* The feature announced so we can distinguish jibri participants.
*
* @type {string}
*/
export const DISCO_JIBRI_FEATURE = 'http://jitsi.org/protocol/jibri';
MiddlewareRegistry.register(({ getState }) => next => action => {
switch (action.type) {
case CONNECTION_WILL_CONNECT: {
const { connection } = action;
const { iAmRecorder } = getState()['features/base/config'];
if (iAmRecorder) {
connection.addFeature(DISCO_JIBRI_FEATURE);
}
// @ts-ignore
APP.connection = connection;
break;
}
}
return next(action);
});

View File

@@ -192,7 +192,7 @@ export const brandedDialog = {
*/
ColorSchemeRegistry.register('Dialog', {
button: {
backgroundColor: schemeColor('buttonBackground'),
backgroundColor: '#44A5FF',
flex: 1,
padding: BoxModel.padding * 1.5
},

View File

@@ -243,6 +243,12 @@ export const TOOLBOX_ALWAYS_VISIBLE = 'toolbox.alwaysVisible';
*/
export const TOOLBOX_ENABLED = 'toolbox.enabled';
/**
* Flag indicating if the unsafe room warning should be enabled.
* Default: disabled (false).
*/
export const UNSAFE_ROOM_WARNING = 'unsaferoomwarning.enabled';
/**
* Flag indicating if the video mute button should be displayed.
* Default: enabled (true).

View File

@@ -160,6 +160,11 @@ const _LANGUAGES = {
main: require('../../../../lang/main-tr')
},
// Ukrainian
'uk': {
main: require('../../../../lang/main-uk')
},
// Vietnamese
'vi': {
main: require('../../../../lang/main-vi')

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