Compare commits
78 Commits
7372
...
jitsi-meet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5af0ba621 | ||
|
|
22eff7fa21 | ||
|
|
0f57928585 | ||
|
|
7fee0297e8 | ||
|
|
df81e0fe53 | ||
|
|
c58de5c690 | ||
|
|
cf1fa52426 | ||
|
|
e58cad0464 | ||
|
|
2bf982452e | ||
|
|
891278d0b3 | ||
|
|
056226b8af | ||
|
|
f8dae86798 | ||
|
|
309f23ba94 | ||
|
|
3f93a81818 | ||
|
|
83196cda10 | ||
|
|
f3670ce86d | ||
|
|
5fd5804245 | ||
|
|
c58e557019 | ||
|
|
50515e0143 | ||
|
|
05f082ef06 | ||
|
|
20ef19ecf1 | ||
|
|
65450e36ef | ||
|
|
1b7a81afa5 | ||
|
|
470e987fad | ||
|
|
419db67267 | ||
|
|
ff70025429 | ||
|
|
7a305ef96e | ||
|
|
28efcea9d8 | ||
|
|
3927f3423f | ||
|
|
0c3b5139b1 | ||
|
|
ec9fcdf1cb | ||
|
|
d335438f12 | ||
|
|
69b536cfb9 | ||
|
|
edb4555699 | ||
|
|
8b6728c65d | ||
|
|
d3336192c3 | ||
|
|
10eadbb7e6 | ||
|
|
36a5282823 | ||
|
|
555be6c229 | ||
|
|
3f5e6883b5 | ||
|
|
ddcf90e95c | ||
|
|
683e9e72b9 | ||
|
|
123eaf77fa | ||
|
|
bb29f20a07 | ||
|
|
866390ece1 | ||
|
|
5b844e45e3 | ||
|
|
1c80771405 | ||
|
|
d42cbbd9f8 | ||
|
|
18873a9659 | ||
|
|
7859397790 | ||
|
|
bc23f9cd33 | ||
|
|
02f0057578 | ||
|
|
63761d515a | ||
|
|
5cc4b31f35 | ||
|
|
a03bf2cb8e | ||
|
|
312902ea77 | ||
|
|
961a9236fd | ||
|
|
364e63da14 | ||
|
|
27c62b3d78 | ||
|
|
51623b47f0 | ||
|
|
824cfc0c9c | ||
|
|
398e170e2d | ||
|
|
f1de6887cd | ||
|
|
7d31a838c1 | ||
|
|
61e3dc10dd | ||
|
|
7877ff4528 | ||
|
|
e8766b265d | ||
|
|
da5d1033c3 | ||
|
|
13323e423e | ||
|
|
5297252efb | ||
|
|
5ce2bef556 | ||
|
|
472c8d7808 | ||
|
|
a51b377d6b | ||
|
|
f5d764e3df | ||
|
|
f71f6d9a0d | ||
|
|
78b8c811af | ||
|
|
10d8d71d8b | ||
|
|
9e48943daf |
@@ -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.2.0'
|
||||
|
||||
// Firebase
|
||||
// - Crashlytics
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ dependencies {
|
||||
}
|
||||
implementation project(':react-native-gesture-handler')
|
||||
implementation project(':react-native-get-random-values')
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-immersive-mode')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-orientation-locker')
|
||||
implementation project(':react-native-pager-view')
|
||||
|
||||
@@ -26,7 +26,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.rnimmersive.RNImmersiveModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
@@ -229,22 +228,4 @@ public class JitsiMeetView extends FrameLayout {
|
||||
dispose();
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the window containing this view gains or loses focus.
|
||||
*
|
||||
* @param hasFocus If the window of this view now has focus, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
|
||||
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
|
||||
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
|
||||
|
||||
if (hasFocus && immersive != null) {
|
||||
immersive.emitImmersiveStateChangeEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class ReactInstanceManagerHolder {
|
||||
new com.oney.WebRTCModule.WebRTCModulePackage(),
|
||||
new com.swmansion.gesturehandler.RNGestureHandlerPackage(),
|
||||
new org.linusu.RNGetRandomValuesPackage(),
|
||||
new com.rnimmersive.RNImmersivePackage(),
|
||||
new com.rnimmersivemode.RNImmersiveModePackage(),
|
||||
new com.swmansion.rnscreens.RNScreensPackage(),
|
||||
new com.zmxv.RNSound.RNSoundPackage(),
|
||||
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),
|
||||
|
||||
@@ -27,8 +27,8 @@ include ':react-native-giphy'
|
||||
project(':react-native-giphy').projectDir = new File(rootProject.projectDir, '../node_modules/@giphy/react-native-sdk/android')
|
||||
include ':react-native-google-signin'
|
||||
project(':react-native-google-signin').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-google-signin/google-signin/android')
|
||||
include ':react-native-immersive'
|
||||
project(':react-native-immersive').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive/android')
|
||||
include ':react-native-immersive-mode'
|
||||
project(':react-native-immersive-mode').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-immersive-mode/android')
|
||||
include ':react-native-keep-awake'
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
|
||||
include ':react-native-orientation-locker'
|
||||
|
||||
310
conference.js
310
conference.js
@@ -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));
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1821,10 +1646,14 @@ export default {
|
||||
APP.store.dispatch(conferenceUniqueIdSet(room, ...args));
|
||||
});
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
|
||||
(authEnabled, authLogin) =>
|
||||
APP.store.dispatch(authStatusChanged(authEnabled, authLogin)));
|
||||
// we want to ignore this event in case of tokenAuthUrl config
|
||||
// we are deprecating this and at some point will get rid of it
|
||||
if (!config.tokenAuthUrl) {
|
||||
room.on(
|
||||
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
|
||||
(authEnabled, authLogin) =>
|
||||
APP.store.dispatch(authStatusChanged(authEnabled, authLogin)));
|
||||
}
|
||||
|
||||
room.on(JitsiConferenceEvents.PARTCIPANT_FEATURES_CHANGED, user => {
|
||||
APP.store.dispatch(updateRemoteParticipantFeatures(user));
|
||||
@@ -2184,21 +2013,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 => {
|
||||
|
||||
79
config.js
79
config.js
@@ -826,6 +826,42 @@ var config = {
|
||||
// 'whiteboard',
|
||||
// ],
|
||||
|
||||
// Participant context menu buttons which have their click/tap event exposed through the API on
|
||||
// `participantMenuButtonClick`. Passing a string for the button key will
|
||||
// prevent execution of the click/tap routine; passing an object with `key` and
|
||||
// `preventExecution` flag on false will not prevent execution of the click/tap
|
||||
// routine. Below array with mixed mode for passing the buttons.
|
||||
// participantMenuButtonsWithNotifyClick: [
|
||||
// 'allow-video',
|
||||
// {
|
||||
// key: 'ask-unmute',
|
||||
// preventExecution: false
|
||||
// },
|
||||
// 'conn-status',
|
||||
// 'flip-local-video',
|
||||
// 'grant-moderator',
|
||||
// {
|
||||
// key: 'kick',
|
||||
// preventExecution: true
|
||||
// },
|
||||
// {
|
||||
// key: 'hide-self-view',
|
||||
// preventExecution: false
|
||||
// },
|
||||
// 'mute',
|
||||
// 'mute-others',
|
||||
// 'mute-others-video',
|
||||
// 'mute-video',
|
||||
// 'pinToStage',
|
||||
// 'privateMessage',
|
||||
// {
|
||||
// key: 'remote-control',
|
||||
// preventExecution: false
|
||||
// },
|
||||
// 'send-participant-to-room',
|
||||
// 'verify',
|
||||
// ],
|
||||
|
||||
// List of pre meeting screens buttons to hide. The values must be one or more of the 5 allowed buttons:
|
||||
// 'microphone', 'camera', 'select-background', 'invite', 'settings'
|
||||
// hiddenPremeetingButtons: [],
|
||||
@@ -1008,6 +1044,11 @@ var config = {
|
||||
// "libs/analytics-ga.min.js", // google-analytics
|
||||
// "https://example.com/my-custom-analytics.js",
|
||||
// ],
|
||||
|
||||
// By enabling watchRTCEnabled option you would want to use watchRTC feature
|
||||
// This would also require to configure watchRTCConfigParams.
|
||||
// Please remember to keep rtcstatsEnabled disabled for watchRTC to work.
|
||||
// watchRTCEnabled: false,
|
||||
},
|
||||
|
||||
// Logs that should go be passed through the 'log' event if a handler is defined for it
|
||||
@@ -1306,6 +1347,9 @@ var config = {
|
||||
// hideJoinRoomButton: false,
|
||||
// },
|
||||
|
||||
// When true, virtual background feature will be disabled.
|
||||
// disableVirtualBackground: false,
|
||||
|
||||
// When true the user cannot add more images to be used as virtual background.
|
||||
// Only the default ones from will be available.
|
||||
// disableAddingBackgroundImages: false,
|
||||
@@ -1403,6 +1447,7 @@ var config = {
|
||||
peopleSearchUrl
|
||||
requireDisplayName
|
||||
tokenAuthUrl
|
||||
tokenLogoutUrl
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -1599,6 +1644,40 @@ var config = {
|
||||
// // https://github.com/jitsi/excalidraw-backend
|
||||
// collabServerBaseUrl: 'https://excalidraw-backend.example.com',
|
||||
// },
|
||||
|
||||
// The watchRTC initialize config params as described :
|
||||
// https://testrtc.com/docs/installing-the-watchrtc-javascript-sdk/#h-set-up-the-sdk
|
||||
// https://www.npmjs.com/package/@testrtc/watchrtc-sdk
|
||||
// watchRTCConfigParams: {
|
||||
// /** Watchrtc api key */
|
||||
// rtcApiKey: string;
|
||||
// /** Identifier for the session */
|
||||
// rtcRoomId?: string;
|
||||
// /** Identifier for the current peer */
|
||||
// rtcPeerId?: string;
|
||||
// /**
|
||||
// * ["tag1", "tag2", "tag3"]
|
||||
// * @deprecated use 'keys' instead
|
||||
// */
|
||||
// rtcTags?: string[];
|
||||
// /** { "key1": "value1", "key2": "value2"} */
|
||||
// keys?: any;
|
||||
// /** Enables additional logging */
|
||||
// debug?: boolean;
|
||||
// rtcToken?: string;
|
||||
// /**
|
||||
// * @deprecated No longer needed. Use "proxyUrl" instead.
|
||||
// */
|
||||
// wsUrl?: string;
|
||||
// proxyUrl?: string;
|
||||
// console?: {
|
||||
// level: string;
|
||||
// override: boolean;
|
||||
// };
|
||||
// allowBrowserLogCollection?: boolean;
|
||||
// collectionInterval?: number;
|
||||
// logGetStats?: boolean;
|
||||
// },
|
||||
};
|
||||
|
||||
// Temporary backwards compatibility with old mobile clients.
|
||||
|
||||
209
connection.js
209
connection.js
@@ -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 })
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -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;
|
||||
@@ -148,21 +144,6 @@ form {
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.connected {
|
||||
color: #21B9FC;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.lastN, .disconnected {
|
||||
color: #a3a3a3;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#inviteLinkRef {
|
||||
-webkit-user-select: text;
|
||||
user-select: text;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-style default OS scrollbar.
|
||||
*/
|
||||
@@ -185,7 +166,7 @@ form {
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(0, 0, 0, .5);
|
||||
background: #3D3D3D;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
175
css/_chat.scss
175
css/_chat.scss
@@ -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: 300;
|
||||
|
||||
@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: #484A4F;
|
||||
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;
|
||||
@@ -345,10 +174,6 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#usermsg::-webkit-scrollbar-track-piece {
|
||||
background: #3a3a3a;
|
||||
}
|
||||
|
||||
.chat-message-group {
|
||||
&.local {
|
||||
align-items: flex-end;
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -75,6 +75,3 @@
|
||||
margin-bottom: 36px;
|
||||
width: 100%;
|
||||
}
|
||||
.navigate-section-list-empty {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
.polls-panel {
|
||||
height: calc(100% - 119px);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -209,23 +209,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
#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: 20; /*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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
23
inlang.config.js
Normal file
23
inlang.config.js
Normal 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()
|
||||
]
|
||||
};
|
||||
}
|
||||
448
ios/Podfile.lock
448
ios/Podfile.lock
@@ -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
|
||||
@@ -395,72 +395,72 @@ PODS:
|
||||
- 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: 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
|
||||
|
||||
@@ -39,11 +39,6 @@
|
||||
[builder setFeatureFlag:@"ios.screensharing.enabled" withBoolean:YES];
|
||||
[builder setFeatureFlag:@"ios.recording.enabled" withBoolean:YES];
|
||||
builder.serverURL = [NSURL URLWithString:@"https://meet.jit.si"];
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
// CallKit has started to create problems starting with the iOS 16 simulator.
|
||||
// Disable it since it never worked in the simulator anyway.
|
||||
[builder setFeatureFlag:@"call-integration.enabled" withBoolean:NO];
|
||||
#endif
|
||||
}];
|
||||
|
||||
[jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
@@ -70,10 +70,7 @@ RCT_EXPORT_MODULE();
|
||||
= [[NSBundle bundleForClass:self.class] infoDictionary];
|
||||
NSString *sdkVersion = sdkInfoDictionary[@"CFBundleShortVersionString"];
|
||||
if (sdkVersion == nil) {
|
||||
sdkVersion = sdkInfoDictionary[@"CFBundleVersion"];
|
||||
if (sdkVersion == nil) {
|
||||
sdkVersion = @"";
|
||||
}
|
||||
sdkVersion = @"";
|
||||
}
|
||||
|
||||
// build number
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"defaultEmail": "Seu email padrão",
|
||||
"disabled": "Você não pode convidar pessoas.",
|
||||
"failedToAdd": "Falha em adicionar participantes",
|
||||
"footerText": "Discagem está desativada.",
|
||||
"googleEmail": "Email Google",
|
||||
"inviteMoreHeader": "Você é o único na reunião",
|
||||
"inviteMoreMailSubject": "Entre na reunião {{appName}}",
|
||||
@@ -31,6 +30,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
"car": "Áudio do carro",
|
||||
"headphones": "Fones de ouvido",
|
||||
"none": "Sem dispositivos de áudio disponível",
|
||||
"phone": "Celular",
|
||||
@@ -39,6 +39,25 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "Largura de banda baixa"
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "Adicionar sala de apoio",
|
||||
"autoAssign": "Atribuir a salas de apoio automaticamente",
|
||||
"close": "Fechar",
|
||||
"join": "Participar",
|
||||
"leaveBreakoutRoom": "Sair da sala de apoio",
|
||||
"more": "Mais",
|
||||
"remove": "Remover",
|
||||
"sendToBreakoutRoom": "Enviar participante para:"
|
||||
},
|
||||
"defaultName": "Sala de apoio #{{index}}",
|
||||
"mainRoom": "Sala principal",
|
||||
"notifications": {
|
||||
"joined": "Entrando na sala de apoio \"{{name}}\"",
|
||||
"joinedMainRoom": "Entrando na sala principal",
|
||||
"joinedTitle": "Salas de apoio"
|
||||
}
|
||||
},
|
||||
"calendarSync": {
|
||||
"addMeetingURL": "Adicionar um link da reunião",
|
||||
"confirmAddLink": "Gostaria de adicionar um link do Jitsi a esse evento?",
|
||||
@@ -57,15 +76,27 @@
|
||||
"refresh": "Atualizar calendário",
|
||||
"today": "Hoje"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"selectSoundDevice": "Selecionar dispositivo de som"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "Modo carro",
|
||||
"title": "Modo carro",
|
||||
"videoStopped": "Seu vídeo está parado"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "Entrar no bate-papo",
|
||||
"error": "Erro: sua mensagem não foi enviada. Motivo: {{error}}",
|
||||
"fieldPlaceHolder": "Digite sua mensagem aqui",
|
||||
"lobbyChatMessageTo": "Mensagem para {{recipient}}",
|
||||
"message": "Mensagem",
|
||||
"messageAccessibleTitle": "{{user}} disse:",
|
||||
"messageAccessibleTitleMe": "Você disse:",
|
||||
"messageTo": "Mensagem privada para {{recipient}}",
|
||||
"messagebox": "Digite uma mensagem",
|
||||
"newMessages": "Novas mensagens",
|
||||
"nickname": {
|
||||
"popover": "Escolha um apelido",
|
||||
"title": "Digite um apelido para usar o bate-papo",
|
||||
@@ -85,6 +116,7 @@
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "Instalar extensão do Chrome",
|
||||
"buttonTextEdge": "Instalar extensão do Edge",
|
||||
"close": "Fechar",
|
||||
"dontShowAgain": "Não me mostre isso de novo",
|
||||
"installExtensionText": "Instale a extensão para integrar com Google Calendar e Office 365"
|
||||
@@ -115,6 +147,7 @@
|
||||
"bridgeCount": "Servidores: ",
|
||||
"codecs": "Codecs (A/V): ",
|
||||
"connectedTo": "Conectado a:",
|
||||
"e2eeVerified": "Verificado via E2EE",
|
||||
"framerate": "Taxa de quadros:",
|
||||
"less": "Mostrar menos",
|
||||
"localaddress": "Endereço local:",
|
||||
@@ -123,6 +156,7 @@
|
||||
"localport_plural": "Portas locais:",
|
||||
"maxEnabledResolution": "envio máx",
|
||||
"more": "Mostrar mais",
|
||||
"no": "não",
|
||||
"packetloss": "Perda de pacote:",
|
||||
"participant_id": "Id participante:",
|
||||
"quality": {
|
||||
@@ -141,7 +175,8 @@
|
||||
"status": "Conexão:",
|
||||
"transport": "Transporte:",
|
||||
"transport_plural": "Transportes:",
|
||||
"video_ssrc": "Video SSRC:"
|
||||
"video_ssrc": "Video SSRC:",
|
||||
"yes": "sim"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "Mais cedo",
|
||||
@@ -151,14 +186,23 @@
|
||||
"deepLinking": {
|
||||
"appNotInstalled": "Você precisa do aplicativo móvel {{app}} para participar da reunião no seu telefone.",
|
||||
"description": "Nada acontece? Estamos tentando iniciar sua reunião no aplicativo desktop {{app}}. Tente novamente ou inicie ele na aplicação web {{app}}.",
|
||||
"descriptionNew": "Nada aconteceu? Tentamos iniciar sua reunião no aplicativo de desktop {{app}}. <br /><br /> Você pode tentar novamente ou abrir pela web.",
|
||||
"descriptionWithoutWeb": "Nada aconteceu? Tentamos iniciar sua reunião no aplicativo de desktop {{app}}.",
|
||||
"downloadApp": "Baixe o Aplicativo",
|
||||
"downloadMobileApp": "Baixar o app",
|
||||
"ifDoNotHaveApp": "Se você não tem o app ainda:",
|
||||
"ifHaveApp": "Se você já tem o app:",
|
||||
"joinInApp": "Entrar na reunião usando o app",
|
||||
"joinInAppNew": "Entrar usando o app",
|
||||
"joinInBrowser": "Entrar usando o navegador",
|
||||
"launchMeetingLabel": "Como deseja entrar nesta reunião?",
|
||||
"launchWebButton": "Iniciar na web",
|
||||
"noMobileApp": "Não tem o app?",
|
||||
"termsAndConditions": "Ao continuar você estará aceitando nossos <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>termos e condições.</a>",
|
||||
"title": "Iniciando sua reunião no {{app}}...",
|
||||
"tryAgainButton": "Tente novamente no desktop"
|
||||
"titleNew": "Iniciando sua reunião ...",
|
||||
"tryAgainButton": "Tente novamente no desktop",
|
||||
"unsupportedBrowser": "Parece que você está usando um navegador ao qual não temos suporte."
|
||||
},
|
||||
"defaultLink": "ex.: {{url}}",
|
||||
"defaultNickname": "ex.: João Pedro",
|
||||
@@ -169,11 +213,20 @@
|
||||
"microphonePermission": "Erro ao obter permissão para o microfone"
|
||||
},
|
||||
"deviceSelection": {
|
||||
"hid": {
|
||||
"callControl": "Controle de chamada",
|
||||
"connectedDevices": "Dispositivos conectados:",
|
||||
"deleteDevice": "Remover dispositivo",
|
||||
"pairDevice": "Emparelhar dispositivo"
|
||||
},
|
||||
"noPermission": "Permissão não concedida",
|
||||
"previewUnavailable": "Visualização indisponível",
|
||||
"selectADevice": "Selecione um dispositivo",
|
||||
"testAudio": "Tocar um som de teste"
|
||||
},
|
||||
"dialIn": {
|
||||
"screenTitle": "Sumário de discagem"
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "está agora {{status}}"
|
||||
},
|
||||
@@ -189,9 +242,13 @@
|
||||
"WaitingForHostTitle": "Esperando o anfitrião...",
|
||||
"Yes": "Sim",
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Transmissão ao vivo"
|
||||
"close": "Fechar janela",
|
||||
"liveStreaming": "Transmissão ao vivo",
|
||||
"sharingTabs": "Opções de compartilhamento"
|
||||
},
|
||||
"add": "Adicionar",
|
||||
"addMeetingNote": "Adicionar uma anotação para esta reunião",
|
||||
"addOptionalNote": "Adicionar uma anotação (opcional):",
|
||||
"allow": "Permitir",
|
||||
"alreadySharedVideoMsg": "Outro participante já está compartilhando um vídeo. Esta conferência permite apenas um vídeo compartilhado por vez.",
|
||||
"alreadySharedVideoTitle": "Somente um vídeo compartilhado é permitido por vez",
|
||||
@@ -233,6 +290,7 @@
|
||||
"gracefulShutdown": "Nosso serviço está em manutenção. Tente novamente mais tarde.",
|
||||
"grantModeratorDialog": "Tem certeza que quer participar como moderador da reunião?",
|
||||
"grantModeratorTitle": "Permitir moderador",
|
||||
"hide": "Ocultar",
|
||||
"hideShareAudioHelper": "Não mostre este diálogo novamente",
|
||||
"incorrectPassword": "Usuário ou senha incorretos",
|
||||
"incorrectRoomLockPassword": "Senha incorreta",
|
||||
@@ -243,9 +301,10 @@
|
||||
"kickParticipantDialog": "Tem certeza de que deseja remover este participante?",
|
||||
"kickParticipantTitle": "Remover este participante?",
|
||||
"kickTitle": "{{participantDisplayName}} removeu você da reunião",
|
||||
"linkMeeting": "Vincular reunião",
|
||||
"linkMeetingTitle": "Vincular reunião ao Salesforce",
|
||||
"liveStreaming": "Transmissão ao Vivo",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Não é possível transmitir enquanto a gravação está ativa",
|
||||
"liveStreamingDisabledTooltip": "Iniciar transmissão ao vivo desativada.",
|
||||
"localUserControls": "Controles de usuários locais",
|
||||
"lockMessage": "Falha ao bloquear a conferência.",
|
||||
"lockRoom": "Adicionar reunião $t(lockRoomPasswordUppercase)",
|
||||
@@ -279,11 +338,11 @@
|
||||
"muteEveryonesVideoTitle": "Desativar a câmera de todos?",
|
||||
"muteParticipantBody": "Você não está habilitado para tirar o mudo deles, mas eles podem tirar o mudo deles mesmos a qualquer tempo.",
|
||||
"muteParticipantButton": "Mudo",
|
||||
"muteParticipantDialog": "Tem certeza de que deseja silenciar este participante? Você não poderá desfazer isso, mas o participante pode reabilitar o áudio a qualquer momento.",
|
||||
"muteParticipantTitle": "Deixar mudo este participante?",
|
||||
"muteParticipantsVideoBody": "Você não poderá reativar posteriormente, mas o participante pode ativar sua própria câmera a qualquer momento.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Você e o participante não poderão reativar a câmera posteriormente.",
|
||||
"muteParticipantsVideoButton": "Desativar a câmera",
|
||||
"muteParticipantsVideoDialog": "Tem certeza de que deseja desativar a câmera deste participante? Você não poderá reativar posteriormente, mas o participante pode ativar sua própria câmera a qualquer momento.",
|
||||
"muteParticipantsVideoDialogModerationOn": "Tem certeza de que deseja desativar a câmera deste participante? Você e o participante não poderão reativar posteriormente.",
|
||||
"muteParticipantsVideoTitle": "Desativar a câmera deste participante?",
|
||||
"noDropboxToken": "Nenhum token do Dropbox válido",
|
||||
"password": "Senha",
|
||||
@@ -297,9 +356,9 @@
|
||||
"popupError": "Seu navegador está bloqueando janelas popup deste site. Habilite os popups nas configurações de segurança no seu navegador e tente novamente.",
|
||||
"popupErrorTitle": "Popup bloqueado",
|
||||
"readMore": "mais...",
|
||||
"recentlyUsedObjects": "Seus objetos usados recentemente",
|
||||
"recording": "Gravando",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Não é possível transmitir enquanto a gravação está ativa",
|
||||
"recordingDisabledTooltip": "Iniciar gravação desativada.",
|
||||
"rejoinNow": "Reconectar agora",
|
||||
"remoteControlAllowedMessage": "{{user}} aceitou sua requisição de controle remoto!",
|
||||
"remoteControlDeniedMessage": "{{user}} rejeitou sua requisição de controle remoto!",
|
||||
@@ -319,6 +378,12 @@
|
||||
"screenSharingFailed": "Oops! Alguma coisa de errado aconteceu, não é possível habilitar o compartilhamento de tela!",
|
||||
"screenSharingFailedTitle": "Falha ao compartilhar a tela!",
|
||||
"screenSharingPermissionDeniedError": "Oops! Alguma coisa está errada com suas permissões de compartilhamento de tela. Recarregue e tente de novo.",
|
||||
"searchInSalesforce": "Pesquisar no Salesforce",
|
||||
"searchResults": "Resultados da pesquisa({{count}})",
|
||||
"searchResultsDetailsError": "Algo de errado ocorreu ao recuperar os dados do proprietário.",
|
||||
"searchResultsError": "Algo de errado ocorreu ao recuperar os dados.",
|
||||
"searchResultsNotFound": "A pesquisa não trouxe resultados.",
|
||||
"searchResultsTryAgain": "Tente usar termos diferentes.",
|
||||
"sendPrivateMessage": "Você enviou uma mensagem privada recentemente. Tem intenção de responder em privado, ou deseja enviar sua mensagem para o grupo?",
|
||||
"sendPrivateMessageCancel": "Enviar para o grupo",
|
||||
"sendPrivateMessageOk": "Enviar em privado",
|
||||
@@ -341,7 +406,10 @@
|
||||
"shareVideoTitle": "Compartilhar um vídeo",
|
||||
"shareYourScreen": "Compartilhar sua tela",
|
||||
"shareYourScreenDisabled": "Compartilhamento de tela desativada.",
|
||||
"sharedVideoDialogError": "Erro: URL inválida",
|
||||
"sharedVideoLinkPlaceholder": "link do YouTube ou link direto de vídeo",
|
||||
"show": "Exibir",
|
||||
"start": "Iniciar ",
|
||||
"startLiveStreaming": "Iniciar transmissão ao vivo",
|
||||
"startRecording": "Iniciar gravação",
|
||||
"startRemoteControlErrorMessage": "Um erro ocorreu enquanto tentava iniciar uma sessão de controle remoto!",
|
||||
@@ -359,6 +427,10 @@
|
||||
"user": "Usuário",
|
||||
"userIdentifier": "identificação do usuário",
|
||||
"userPassword": "senha do usuário",
|
||||
"verifyParticipantConfirm": "Coincidem",
|
||||
"verifyParticipantDismiss": "Não coincidem",
|
||||
"verifyParticipantQuestion": "EXPERIMENTAL: Pergunta ao participante {{participantName}} se ele vê o mesmo conteúdo na mesma ordem.",
|
||||
"verifyParticipantTitle": "Verificação de usuário",
|
||||
"videoLink": "Link do vídeo",
|
||||
"viewUpgradeOptions": "Ver opções de atualização",
|
||||
"viewUpgradeOptionsContent": "Para obter acesso ilimitado a recursos premium tais como gravação, transcrição, streaming RTMP e muito mais, você precisa atualizar seu plano.",
|
||||
@@ -384,8 +456,14 @@
|
||||
"veryBad": "Muito ruim",
|
||||
"veryGood": "Muito boa"
|
||||
},
|
||||
"helpView": {
|
||||
"title": "Centro de ajuda"
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Miniaturas de vídeo"
|
||||
}
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "Nenhum resultado encontrado :(",
|
||||
"search": "Buscar GIPHY"
|
||||
},
|
||||
"incomingCall": {
|
||||
"answer": "Responder",
|
||||
@@ -427,9 +505,11 @@
|
||||
"noRoom": "Nenhuma sala foi especificada para entrar.",
|
||||
"numbers": "Números de discagem",
|
||||
"password": "$t(lockRoomPasswordUppercase):",
|
||||
"reachedLimit": "Você atingiu o limite do seu plano.",
|
||||
"sip": "endereço SIP",
|
||||
"title": "Compartilhar",
|
||||
"tooltip": "Compartilhar link e discagem para esta reunião"
|
||||
"tooltip": "Compartilhar link e discagem para esta reunião",
|
||||
"upgradeOptions": "Por favor, verifique as opções de upgrade em"
|
||||
},
|
||||
"inlineDialogFailure": {
|
||||
"msg": "Tivemos um pequeno problema.",
|
||||
@@ -450,6 +530,7 @@
|
||||
"focusLocal": "Focar no seu vídeo",
|
||||
"focusRemote": "Focar no vídeo de outro participante",
|
||||
"fullScreen": "Entrar ou sair da tela cheia",
|
||||
"giphyMenu": "Alternar menu do GIPHY",
|
||||
"keyboardShortcuts": "Atalhos de teclado",
|
||||
"localRecording": "Mostrar ou ocultar controles de gravação local",
|
||||
"mute": "Deixar mudo ou não o microfone",
|
||||
@@ -463,6 +544,10 @@
|
||||
"toggleShortcuts": "Mostrar ou ocultar atalhos de teclado",
|
||||
"videoMute": "Iniciar ou parar sua câmera"
|
||||
},
|
||||
"largeVideo": {
|
||||
"screenIsShared": "Você está compartilhando sua tela",
|
||||
"showMeWhatImSharing": "Me mostre o que estou compartilhando"
|
||||
},
|
||||
"liveStreaming": {
|
||||
"busy": "Estamos trabalhando para liberar os recursos de transmissão. Tente novamente em alguns minutos.",
|
||||
"busyTitle": "Todas as transmissões estão atualmente ocupadas",
|
||||
@@ -479,6 +564,7 @@
|
||||
"failedToStart": "Falha ao iniciar a transmissão ao vivo",
|
||||
"getStreamKeyManually": "Não conseguimos buscar nenhuma transmissão ao vivo. Tente obter sua chave de transmissão ao vivo no YouTube.",
|
||||
"googlePrivacyPolicy": "Política de Privacidade do Google",
|
||||
"inProgress": "Gravação ou live streaming em andamento",
|
||||
"invalidStreamKey": "A senha para transmissão ao vivo pode estar incorreta.",
|
||||
"limitNotificationDescriptionNative": "Sua transmissão será limitada a {{limit}} minutos. Para transmissão ilimitada tente {{app}}.",
|
||||
"limitNotificationDescriptionWeb": "Devido a alta demanda sua transmissão será limitada a {{limit}} minutos. Para transmissão ilimitada tente <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
@@ -488,6 +574,7 @@
|
||||
"onBy": "{{name}} iniciou a transmissão ao vivo",
|
||||
"pending": "Iniciando Transmissão ao Vivo...",
|
||||
"serviceName": "Serviço de Transmissão ao Vivo",
|
||||
"sessionAlreadyActive": "Esta sessão já está sendo gravada ou em live streaming.",
|
||||
"signIn": "Faça login no Google",
|
||||
"signInCTA": "Faça login ou insira sua chave de transmissão ao vivo do YouTube.",
|
||||
"signOut": "Sair",
|
||||
@@ -501,8 +588,8 @@
|
||||
"lobby": {
|
||||
"admit": "Aceitar",
|
||||
"admitAll": "Aceitar todos",
|
||||
"allow": "Permitir",
|
||||
"backToKnockModeButton": "Sem senha, peça para se juntar",
|
||||
"chat": "Chat",
|
||||
"dialogTitle": "Modo sala de espera",
|
||||
"disableDialogContent": "O modo sala de espera está habilitado. Este recurso evita que particpantes não convidados juntem-se à sua conferência. Deseja desabilitar?",
|
||||
"disableDialogSubmit": "Desabilitar",
|
||||
@@ -515,6 +602,7 @@
|
||||
"errorMissingPassword": "Por favor informe a senha da conferência",
|
||||
"invalidPassword": "Senha inválida",
|
||||
"joinRejectedMessage": "Sua solicitação de participação foi rejeitada pelo moderador.",
|
||||
"joinRejectedTitle": "Solicitação de participação recusada",
|
||||
"joinTitle": "Junte-se à conferência",
|
||||
"joinWithPasswordMessage": "Tentando entrar com a senha, por favor aguarde...",
|
||||
"joiningMessage": "Você se juntará à conferência tão logo alguém aprove sua solicitação",
|
||||
@@ -523,6 +611,8 @@
|
||||
"knockButton": "Peça para participar",
|
||||
"knockTitle": "Alguém deseja participar da conferência",
|
||||
"knockingParticipantList": "Remover lista de participantes",
|
||||
"lobbyChatStartedNotification": "{{moderator}} iniciou uma conversa na sala de espera com {{attendee}}",
|
||||
"lobbyChatStartedTitle": "{{moderator}} iniciou uma conversa na sala de espera com você.",
|
||||
"nameField": "Informe seu nome",
|
||||
"notificationLobbyAccessDenied": "{{targetParticipantName}} foi rejeitado por {{originParticipantName}}",
|
||||
"notificationLobbyAccessGranted": "{{targetParticipantName}} foi aceito por {{originParticipantName}}",
|
||||
@@ -560,6 +650,7 @@
|
||||
"no": "Não",
|
||||
"participant": "Participante",
|
||||
"participantStats": "Estatísticas dos Participantes",
|
||||
"selectTabTitle": "🎥 Por favor selecione esta aba para gravar",
|
||||
"sessionToken": "Token de Sessão",
|
||||
"start": "Iniciar gravação",
|
||||
"stop": "Parar a Gravação",
|
||||
@@ -576,18 +667,39 @@
|
||||
"OldElectronAPPTitle": "Vulnerabilidade de segurança!",
|
||||
"allowAction": "Permitir",
|
||||
"allowedUnmute": "Você pode religar seu microfone, ativar sua câmera ou compartilhar sua tela.",
|
||||
"audioUnmuteBlockedDescription": "A liberação do microfone foi temporariamente bloqueada devido a limites do sistema.",
|
||||
"audioUnmuteBlockedTitle": "Microfone bloqueado!",
|
||||
"chatMessages": "Mensagens do chat",
|
||||
"connectedOneMember": "{{name}} entrou na reunião",
|
||||
"connectedThreePlusMembers": "{{name}} e outros {{count}} entraram na reunião",
|
||||
"connectedTwoMembers": "{{first}} e {{second}} entraram na reunião",
|
||||
"dataChannelClosed": "Qualidade do vídeo prejudicada",
|
||||
"dataChannelClosedDescription": "O canal da ponte foi desconectado, assim a qualidade do vídeo foi limitada a sua configuração mais baixa.",
|
||||
"disabledIframe": "Incorporação destina-se apenas a fins de demonstração, assim esta chamada será desconectada em {{timeout}} minutos.",
|
||||
"disconnected": "desconectado",
|
||||
"displayNotifications": "Exibir notificações para",
|
||||
"dontRemindMe": "Não me lembrar",
|
||||
"focus": "Foco da conferência",
|
||||
"focusFail": "{{component}} não disponível - tente em {{ms}} seg",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Notificações",
|
||||
"hostAskedUnmute": "O anfitrião deseja que você ative o som",
|
||||
"invitedOneMember": "{{name}} foi convidado(a)",
|
||||
"invitedThreePlusMembers": "{{name}} e {{count}} outros foram convidados",
|
||||
"invitedTwoMembers": "{{first}} e {{second}} foram convidados",
|
||||
"joinMeeting": "Participar",
|
||||
"kickParticipant": "{{kicked}} foi removido por {{kicker}}",
|
||||
"leftOneMember": "{{name}} saiu da reunião",
|
||||
"leftThreePlusMembers": "{{name}} e muitos outros saíram da reunião",
|
||||
"leftTwoMembers": "{{first}} e {{second}} saíram da reunião",
|
||||
"linkToSalesforce": "Link para Salesforce",
|
||||
"linkToSalesforceDescription": "Você pode vincular o sumário da reunião a um objeto do Salesforce.",
|
||||
"linkToSalesforceError": "Falha ao vincular reunião ao Salesforce",
|
||||
"linkToSalesforceKey": "Vincular esta reunião",
|
||||
"linkToSalesforceProgress": "Vinculando reunião ao Salesforce...",
|
||||
"linkToSalesforceSuccess": "A reunião foi vinculada ao Salesforce",
|
||||
"localRecordingStarted": "{{name}} iniciou uma gravação local.",
|
||||
"localRecordingStopped": "{{name}} parou uma gravação local.",
|
||||
"me": "Eu",
|
||||
"moderationInEffectCSDescription": "Levante a mão se quiser compartilhar seu vídeo",
|
||||
"moderationInEffectCSTitle": "O compartilhamento de conteúdo foi desativado pelo moderador",
|
||||
@@ -608,16 +720,27 @@
|
||||
"newDeviceAction": "Usar",
|
||||
"newDeviceAudioTitle": "Novo dispositivo de áudio detectado",
|
||||
"newDeviceCameraTitle": "Nova câmera detectada",
|
||||
"noiseSuppressionDesktopAudioDescription": "A supressão de ruído não pode ser habilitada enquanto compartilha o áudio da área de trabalho. Por favor desabilite e tente novamente.",
|
||||
"noiseSuppressionFailedTitle": "Falha ao iniciar a supressão de ruído",
|
||||
"noiseSuppressionNoTrackDescription": "Por favor ative o microfone antes.",
|
||||
"noiseSuppressionStereoDescription": "Supressão de ruído de áudio estéreo não é suportado no momento.",
|
||||
"oldElectronClientDescription1": "Você está usando um versão antiga do cliente Jitsi Meet que possui uma conhecida vulnerabilidade de segurança. Por favor tenha certeza de atulizar para a nossa ",
|
||||
"oldElectronClientDescription2": "última versão",
|
||||
"oldElectronClientDescription3": " agora!",
|
||||
"participantWantsToJoin": "Deseja entrar na reunião",
|
||||
"participantsWantToJoin": "Desejam entrar na reunião",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) removido por outro participante",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) definido por outro participante",
|
||||
"raiseHandAction": "Levantar a mão",
|
||||
"raisedHand": "{{name}} gostaria de falar.",
|
||||
"raisedHands": "{{participantName}} e {{raisedHands}} outras pessoas",
|
||||
"reactionSounds": "Desabilitar sons",
|
||||
"reactionSoundsForAll": "Desabilitar sons para todos",
|
||||
"screenShareNoAudio": "O compartilhamento de áudio não foi selecionado na tela de escolha de janela.",
|
||||
"screenShareNoAudioTitle": "Compartilhamento de áudio não selecionado",
|
||||
"screenSharingAudioOnlyDescription": "Por favor perceba que ao compartilhar sua tela você estará afetando o modo de \"Melhor performance\" e irá usar mais banda de rede.",
|
||||
"screenSharingAudioOnlyTitle": "Modo de \"Melhor performance\"",
|
||||
"selfViewTitle": "Você pode habilitar a auto-visualização nas configurações a qualquer momento",
|
||||
"somebody": "Alguém",
|
||||
"startSilentDescription": "Volte à reunião para habilitar o áudio",
|
||||
"startSilentTitle": "Você entrou sem saída de áudio!",
|
||||
@@ -625,7 +748,11 @@
|
||||
"suboptimalExperienceTitle": "Alerta do navegador",
|
||||
"unmute": "Ativar som",
|
||||
"videoMutedRemotelyDescription": "Você pode ativar sua câmera a qualquer momento.",
|
||||
"videoMutedRemotelyTitle": "Sua câmera foi desativada por {{participantDisplayName}}!"
|
||||
"videoMutedRemotelyTitle": "Sua câmera foi desativada por {{participantDisplayName}}!",
|
||||
"videoUnmuteBlockedDescription": "A liberação da câmera e compartilhamento de tela foram temporariamente bloqueados devido a limites do sistema.",
|
||||
"videoUnmuteBlockedTitle": "Câmera e compartilhamento de tela bloqueados!",
|
||||
"viewLobby": "Ver sala de espera",
|
||||
"waitingParticipants": "{{waitingParticipants}} pessoas"
|
||||
},
|
||||
"participantsPane": {
|
||||
"actions": {
|
||||
@@ -635,6 +762,9 @@
|
||||
"audioModeration": "Reativarem seus sons",
|
||||
"blockEveryoneMicCamera": "Bloquear microfone e câmera de todos",
|
||||
"invite": "Convidar alguém",
|
||||
"moreModerationActions": "Mais opções de moderação",
|
||||
"moreModerationControls": "Mais controles de moderação",
|
||||
"moreParticipantOptions": "Mais opções de participante",
|
||||
"mute": "Silenciar",
|
||||
"muteAll": "Silenciar todos",
|
||||
"muteEveryoneElse": "Silenciar todos os demais",
|
||||
@@ -647,17 +777,22 @@
|
||||
"headings": {
|
||||
"lobby": "Sala de espera ({{count}})",
|
||||
"participantsList": "Participantes da reunião ({{count}})",
|
||||
"visitors": "Visitantes ({{count}})",
|
||||
"waitingLobby": "Aguardando na sala de espera ({{count}})"
|
||||
},
|
||||
"search": "Buscar participantes",
|
||||
"title": "Participantes"
|
||||
},
|
||||
"passwordDigitsOnly": "Até {{number}} dígitos",
|
||||
"passwordSetRemotely": "Definido por outro participante",
|
||||
"pinParticipant": "{{participantName}} - Fixar",
|
||||
"pinnedParticipant": "O participante está fixado",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"skip": "Desistir",
|
||||
"submit": "Enviar"
|
||||
},
|
||||
"by": "Por {{ name }}",
|
||||
"create": {
|
||||
"addOption": "Adicionar opção",
|
||||
"answerPlaceholder": "Opção {{index}}",
|
||||
@@ -728,15 +863,18 @@
|
||||
"initiated": "Chamada iniciada",
|
||||
"joinAudioByPhone": "Participar com o áudio via ligação",
|
||||
"joinMeeting": "Participar da reunião",
|
||||
"joinMeetingInLowBandwidthMode": "Participar no modo de banda baixa",
|
||||
"joinWithoutAudio": "Participar sem áudio",
|
||||
"keyboardShortcuts": "Habilitar atalhos de teclado",
|
||||
"linkCopied": "Link copiado para a área de transferência",
|
||||
"lookGood": "Seu microfone está funcionando corretamente",
|
||||
"or": "ou",
|
||||
"premeeting": "Pré-reunião",
|
||||
"proceedAnyway": "Prosseguir mesmo assim",
|
||||
"screenSharingError": "Erro de compartilhamento de tela:",
|
||||
"showScreen": "Habilitar tela pré-reunião",
|
||||
"startWithPhone": "Iniciar com o áudio da ligação",
|
||||
"unsafeRoomConsent": "Eu entendo os riscos, desejo ingressar na reunião",
|
||||
"videoOnlyError": "Erro de vídeo:",
|
||||
"videoTrackError": "Não é possível criar faixa de vídeo.",
|
||||
"viewAllNumbers": "veja todos os números"
|
||||
@@ -763,6 +901,19 @@
|
||||
"title": "Perfil"
|
||||
},
|
||||
"raisedHand": "Gostaria de falar",
|
||||
"raisedHandsLabel": "Número de mãos levantadas",
|
||||
"record": {
|
||||
"already": {
|
||||
"linked": "A reunião já está vinculada a este objeto do Salesforce"
|
||||
},
|
||||
"type": {
|
||||
"account": "Conta",
|
||||
"contact": "Contato",
|
||||
"lead": "Lead",
|
||||
"opportunity": "Oportunidade",
|
||||
"owner": "Proprietário"
|
||||
}
|
||||
},
|
||||
"recording": {
|
||||
"authDropboxText": "Enviar para o Dropbox",
|
||||
"availableSpace": "Espaço disponível: {{spaceLeft}} MB (aproximadamente {{duration}} minutos de gravação)",
|
||||
@@ -777,37 +928,66 @@
|
||||
"expandedPending": "Iniciando gravação...",
|
||||
"failedToStart": "Falha ao iniciar a gravação",
|
||||
"fileSharingdescription": "Compartilhar gravação com participantes da reunião",
|
||||
"highlight": "Destaque",
|
||||
"highlightMoment": "Momento de destaque",
|
||||
"highlightMomentDisabled": "Você pode destacar momentos quando a gravação começar",
|
||||
"highlightMomentSuccess": "Momento destacado",
|
||||
"highlightMomentSucessDescription": "Seu momento destacado será adicionado ao sumário da reunião.",
|
||||
"inProgress": "Gravação ou live streaming em andamento",
|
||||
"limitNotificationDescriptionNative": "Devido a demanda, sua gravação ficará limitada a {{limit}} minutos. Para gravação ilimitada tente <3>{{app}}</3>.",
|
||||
"limitNotificationDescriptionWeb": "Devido a demanda, sua gravação ficará limitada a {{limit}} minutos. Para gravação ilimitada tente <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "Geramos um link para sua gravação.",
|
||||
"live": "AOVIVO",
|
||||
"localRecordingNoNotificationWarning": "A gravação não será anunciada aos outros participantes. Você precisará avisá-los que a reunião está sendo gravada.",
|
||||
"localRecordingNoVideo": "O vídeo não está sendo gravado",
|
||||
"localRecordingStartWarning": "Por favor, certifique-se de ter parado a gravação antes de sair da reunião para garantir que será salva.",
|
||||
"localRecordingStartWarningTitle": "Parar a gravação para salvá-la",
|
||||
"localRecordingVideoStop": "Ao parar o seu vídeo a gravação local também será parada. Tem certeza que deseja continuar?",
|
||||
"localRecordingVideoWarning": "Para gravar o seu vídeo você precisa ativá-lo antes de inicar a gravação",
|
||||
"localRecordingWarning": "Tenha certeza de selecionar a aba atual para usar o áudio e vídeo corretos. A gravação está atualmente limitada a 1GB, que corresponde a aproximadamente 100 minutos.",
|
||||
"loggedIn": "Conectado como {{userName}}",
|
||||
"noMicPermission": "Trilha para o microfone não pôde ser criada. Por favor conceda permissão para usar o microfone.",
|
||||
"noStreams": "Nenhum fluxo de áudio ou vídeo detectado.",
|
||||
"off": "Gravação parada",
|
||||
"offBy": "{{name}} parou a gravação",
|
||||
"on": "Gravando",
|
||||
"onBy": "{{name}} iniciou a gravação",
|
||||
"onlyRecordSelf": "Gravar apenas o meu fluxo de áudio e vídeo",
|
||||
"pending": "Preparando para gravar a reunião...",
|
||||
"rec": "REC",
|
||||
"saveLocalRecording": "Salvar o arquivo de gravação localmente (Beta)",
|
||||
"serviceDescription": "Sua gravação será salva pelo serviço de gravação",
|
||||
"serviceDescriptionCloud": "Gravação na nuvem",
|
||||
"serviceDescriptionCloudInfo": "Reuniões gravadas são removidas automaticamente 24h após a hora da gravação.",
|
||||
"serviceName": "Serviço de gravação",
|
||||
"sessionAlreadyActive": "Esta sessão já está sendo gravada ou em live streaming",
|
||||
"signIn": "Entrar",
|
||||
"signOut": "Sair",
|
||||
"surfaceError": "Por favor selecione a aba atual.",
|
||||
"title": "Gravando",
|
||||
"unavailable": "Oops! O {{serviceName}} está indisponível. Estamos trabalhando para resolver o problema. Por favor, tente mais tarde.",
|
||||
"unavailableTitle": "Gravação indisponível",
|
||||
"uploadToCloud": "Enviar para a nuvem"
|
||||
},
|
||||
"screenshareDisplayName": "Tela: {{name}}",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Puxe para atualizar"
|
||||
},
|
||||
"security": {
|
||||
"about": "Voce pode adicionar $t(lockRoomPassword) a sua reunião. Participantes terão que fornecer $t(lockRoomPassword) antes de entrar na reunião.",
|
||||
"about": "Você pode adicionar $t(lockRoomPassword) a sua reunião. Participantes terão que fornecer $t(lockRoomPassword) antes de entrar na reunião.",
|
||||
"aboutReadOnly": "Moderadores podem adicionar $t(lockRoomPassword) à reunião. Participantes terão que fornecer $t(lockRoomPassword) antes de entrar na reunião.",
|
||||
"insecureRoomNameWarning": "A sala é insegura. Participantes não desejados podem entrar na reunião. Considere adicionar seguança no botão segurança.",
|
||||
"securityOptions": "Opções de segurança"
|
||||
"insecureRoomNameWarningNative": "O nome da sala é não é seguro. Participantes não desejados podem ingressar na reunião. {{recommendAction}} Saiba mais sobre como proteger sua reunião ",
|
||||
"insecureRoomNameWarningWeb": "O nome da sala é não é seguro. Participantes não desejados podem ingressar na reunião. {{recommendAction}} Saiba mais sobre como proteger sua reunião <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">aqui</a>.",
|
||||
"title": "Opções de segurança",
|
||||
"unsafeRoomActions": {
|
||||
"meeting": "Considere usar o botão de segurança para proteger sua reunião.",
|
||||
"prejoin": "Considere usar um nome de reunião não-comum.",
|
||||
"welcome": "Considere usar um nome de reunião não-comum ou selecione um das sugestões."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"audio": "Áudio",
|
||||
"buttonLabel": "Configurações",
|
||||
"calendar": {
|
||||
"about": "A integração do calendário {{appName}} é usada para acessar com segurança o seu calendário para que ele possa ler os próximos eventos.",
|
||||
"disconnect": "Desconectar",
|
||||
@@ -824,25 +1004,32 @@
|
||||
"incomingMessage": "Mensagem recebida",
|
||||
"language": "Idioma",
|
||||
"loggedIn": "Conectado como {{name}}",
|
||||
"maxStageParticipants": "Número máximo de participantes que podem ser fixados no palco principal (EXPERIMENTAL)",
|
||||
"microphones": "Microfones",
|
||||
"moderator": "Moderador",
|
||||
"moderatorOptions": "Opções de moderador",
|
||||
"more": "Mais",
|
||||
"name": "Nome",
|
||||
"noDevice": "Nenhum",
|
||||
"participantJoined": "Participante Entrou",
|
||||
"participantLeft": "Participante Saiu",
|
||||
"notifications": "Notificações",
|
||||
"participantJoined": "Participante entrou",
|
||||
"participantKnocking": "Participante entrou na sala de espera",
|
||||
"participantLeft": "Participante saiu",
|
||||
"playSounds": "Tocar sons",
|
||||
"reactions": "Reações da reunião",
|
||||
"sameAsSystem": "Igual ao sistema ({{label}})",
|
||||
"selectAudioOutput": "Saída de áudio",
|
||||
"selectCamera": "Câmera",
|
||||
"selectMic": "Microfone",
|
||||
"sounds": "Sons",
|
||||
"selfView": "Auto-visualização",
|
||||
"shortcuts": "Atalhos",
|
||||
"speakers": "Alto-faltantes",
|
||||
"startAudioMuted": "Todos iniciam mudos",
|
||||
"startReactionsMuted": "Silenciar sons de reações para todos",
|
||||
"startVideoMuted": "Todos iniciam ocultos",
|
||||
"talkWhileMuted": "Falar mesmo silenciado",
|
||||
"title": "Configurações"
|
||||
"title": "Configurações",
|
||||
"video": "Vídeo"
|
||||
},
|
||||
"settingsView": {
|
||||
"advanced": "Avançado",
|
||||
@@ -857,13 +1044,21 @@
|
||||
"disableCrashReportingWarning": "Tem certeza eue quer desabilitar o aviso de falha? A opção será habilitada após reiniciar o app.",
|
||||
"disableP2P": "Desativar modo ponto a ponto",
|
||||
"displayName": "Nome de exibição",
|
||||
"displayNamePlaceholderText": "Ex: João Silva",
|
||||
"email": "Email",
|
||||
"emailPlaceholderText": "email@exemplo.com.br",
|
||||
"goTo": "Ir para",
|
||||
"header": "Configurações",
|
||||
"help": "Ajuda",
|
||||
"links": "Links",
|
||||
"privacy": "Privacidade",
|
||||
"profileSection": "Perfil",
|
||||
"serverURL": "URL do servidor",
|
||||
"showAdvanced": "Mostrar configurações avançadas",
|
||||
"startCarModeInLowBandwidthMode": "Iniciar modo carro em modo de banda baixa",
|
||||
"startWithAudioMuted": "Iniciar sem áudio",
|
||||
"startWithVideoMuted": "Iniciar sem vídeo",
|
||||
"terms": "Termos",
|
||||
"version": "Versão"
|
||||
},
|
||||
"share": {
|
||||
@@ -872,13 +1067,21 @@
|
||||
},
|
||||
"speaker": "Alto-falantes",
|
||||
"speakerStats": {
|
||||
"angry": "Zangado",
|
||||
"disgusted": "Com nojo",
|
||||
"displayEmotions": "Exibir emoções",
|
||||
"fearful": "Com medo",
|
||||
"happy": "Feliz",
|
||||
"hours": "{{count}}h",
|
||||
"minutes": "{{count}}m",
|
||||
"name": "Nome",
|
||||
"neutral": "Neutro",
|
||||
"sad": "Triste",
|
||||
"search": "Busca",
|
||||
"seconds": "{{count}}s",
|
||||
"speakerStats": "Estatísticas do Apresentador",
|
||||
"speakerTime": "Tempo do Apresentador"
|
||||
"speakerStats": "Estatísticas do apresentador",
|
||||
"speakerTime": "Tempo do apresentador",
|
||||
"surprised": "Surpreso"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"genericTitle": "A reunião precisa usar seu microfone e câmera.",
|
||||
@@ -890,6 +1093,10 @@
|
||||
"text": "Pressione o botão <i>Reentrar</i> para reconectar.",
|
||||
"title": "Sua chamada de vídeo foi interrompida, porque seu computador foi dormir."
|
||||
},
|
||||
"termsView": {
|
||||
"title": "Termos"
|
||||
},
|
||||
"toggleTopPanelLabel": "Alternar painel superior",
|
||||
"toolbar": {
|
||||
"Settings": "Configurações",
|
||||
"accessibilityLabel": {
|
||||
@@ -897,60 +1104,89 @@
|
||||
"audioOnly": "Alternar para apenas áudio",
|
||||
"audioRoute": "Selecionar o dispositivo de som",
|
||||
"boo": "Vaia",
|
||||
"breakoutRoom": "Entrar/sair da sala de apoio",
|
||||
"callQuality": "Gerenciar qualidade do vídeo",
|
||||
"carmode": "Modo carro",
|
||||
"cc": "Alternar legendas",
|
||||
"chat": "Alternar para janela de chat",
|
||||
"clap": "Aplauso",
|
||||
"closeChat": "Fechar chat",
|
||||
"closeMoreActions": "Fechar o menu de mais ações",
|
||||
"closeParticipantsPane": "Fechar painel de participantes",
|
||||
"collapse": "Recolher",
|
||||
"document": "Alternar para documento compartilhado",
|
||||
"documentClose": "Fechar documento compartilhado",
|
||||
"documentOpen": "Abrir documento compartilhado",
|
||||
"download": "Baixe nossos aplicativos",
|
||||
"embedMeeting": "Reunião em formato compacto",
|
||||
"endConference": "Terminar para todos",
|
||||
"enterFullScreen": "Ver em tela-cheia",
|
||||
"enterTileView": "Entrar na visualização em blocos",
|
||||
"exitFullScreen": "Sair da tela-cheia",
|
||||
"exitTileView": "Sair da visualização em blocos",
|
||||
"expand": "Expandir",
|
||||
"feedback": "Deixar feedback",
|
||||
"fullScreen": "Alternar para tela cheia",
|
||||
"giphy": "Alternar menu do GIPHY",
|
||||
"grantModerator": "Atribuir Moderador",
|
||||
"hangup": "Sair da chamada",
|
||||
"heading": "Barra de ferramentas",
|
||||
"help": "Ajuda",
|
||||
"hideWhiteboard": "Ocultar quadro branco",
|
||||
"invite": "Convidar pessoas",
|
||||
"kick": "Remover participante",
|
||||
"laugh": "Risada",
|
||||
"leaveConference": "Sair da reunião",
|
||||
"like": "Gostei",
|
||||
"linkToSalesforce": "Link com o Salesforce",
|
||||
"lobbyButton": "Habilitar/desabilitar sala de espera",
|
||||
"localRecording": "Alternar controles de gravação local",
|
||||
"lockRoom": "Ativar/desativar senha de reunião",
|
||||
"lowerHand": "Abaixar a mão",
|
||||
"moreActions": "Alternar mais menu de ações",
|
||||
"moreActionsMenu": "Menu de mais ações",
|
||||
"moreOptions": "Mostrar mais opções",
|
||||
"mute": "Alternar mudo do áudio",
|
||||
"muteEveryone": "Silenciar todos",
|
||||
"muteEveryoneElse": "Silenciar todos os demais",
|
||||
"muteEveryoneElsesVideo": "Desativar a câmera de todos os demais",
|
||||
"muteEveryonesVideo": "Desativar a câmera de todos",
|
||||
"muteEveryoneElsesVideoStream": "Parar o vídeo de todos os outros",
|
||||
"muteEveryonesVideoStream": "Parar o vídeo de todos",
|
||||
"muteGUMPending": "Conectando seu microfone",
|
||||
"noiseSuppression": "Supressão de ruído",
|
||||
"openChat": "Abrir chat",
|
||||
"participants": "Participantes",
|
||||
"pip": "Alternar modo Picture-in-Picture",
|
||||
"privateMessage": "Enviar mensagem privada",
|
||||
"profile": "Editar seu perfil",
|
||||
"raiseHand": "Alternar levantar a mão",
|
||||
"reactions": "Reações",
|
||||
"reactionsMenu": "Abrir / fechar menu de reações",
|
||||
"recording": "Alternar gravação",
|
||||
"remoteMute": "Silenciar participante",
|
||||
"remoteVideoMute": "Desativar a câmera do participante",
|
||||
"security": "Opções de segurança",
|
||||
"selectBackground": "Selecionar Fundo",
|
||||
"selfView": "Alternar auto-visualização",
|
||||
"shareRoom": "Convidar alguém",
|
||||
"shareYourScreen": "Alternar compartilhamento de tela",
|
||||
"shareaudio": "Compartilhar áudio",
|
||||
"sharedvideo": "Alternar compartilhamento de vídeo",
|
||||
"shortcuts": "Alternar atalhos",
|
||||
"show": "Mostrar no palco",
|
||||
"showWhiteboard": "Exibir quadro branco",
|
||||
"silence": "Silenciar",
|
||||
"speakerStats": "Alternar estatísticas do apresentador",
|
||||
"stopScreenSharing": "Parar de compartilhar sua tela",
|
||||
"stopSharedVideo": "Parar vídeo",
|
||||
"surprised": "Surpresa",
|
||||
"tileView": "Alternar visualização em blocos",
|
||||
"toggleCamera": "Alternar câmera",
|
||||
"toggleFilmstrip": "Alterar tira de filme",
|
||||
"unmute": "Ativar som",
|
||||
"videoblur": "Alternar desfoque de vídeo",
|
||||
"videomute": "Alternar mudo do vídeo"
|
||||
"videomute": "Alternar mudo do vídeo",
|
||||
"videomuteGUMPending": "Conectando sua câmera",
|
||||
"videounmute": "Ativar câmera"
|
||||
},
|
||||
"addPeople": "Adicionar pessoas à sua chamada",
|
||||
"audioOnlyOff": "Desabilitar modo de largura de banda baixa",
|
||||
@@ -963,23 +1199,33 @@
|
||||
"chat": "Abrir ou fechar o bate-papo",
|
||||
"clap": "Aplauso",
|
||||
"closeChat": "Fechar chat",
|
||||
"closeParticipantsPane": "Fechar painel de participantes",
|
||||
"closeReactionsMenu": "Fechar menu de reações",
|
||||
"disableNoiseSuppression": "Desabilitar supressão de ruído",
|
||||
"disableReactionSounds": "Você pode desabilitar os sons de reação para esta reunião",
|
||||
"documentClose": "Fechar documento compartilhado",
|
||||
"documentOpen": "Abrir documento compartilhado",
|
||||
"download": "Baixe nossos aplicativos",
|
||||
"e2ee": "Encriptação ponto a ponto",
|
||||
"embedMeeting": "Reunião em formato compacto",
|
||||
"enableNoiseSuppression": "Habilitar supressão de ruído",
|
||||
"endConference": "Terminar para todos",
|
||||
"enterFullScreen": "Ver em tela cheia",
|
||||
"enterTileView": "Entrar em exibição de bloco",
|
||||
"exitFullScreen": "Sair da tela cheia",
|
||||
"exitTileView": "Sair de exibição de bloco",
|
||||
"feedback": "Deixar feedback",
|
||||
"giphy": "Alternar menu do GIPHY",
|
||||
"hangup": "Sair",
|
||||
"help": "Ajuda",
|
||||
"hideWhiteboard": "Ocultar quadro branco",
|
||||
"invite": "Convidar pessoas",
|
||||
"joinBreakoutRoom": "Ingressar na sala de apoio",
|
||||
"laugh": "Risada",
|
||||
"leaveBreakoutRoom": "Sair da sala de apoio",
|
||||
"leaveConference": "Sair da reunião",
|
||||
"like": "Gostei",
|
||||
"linkToSalesforce": "Link com o Salesforce",
|
||||
"lobbyButtonDisable": "Desabilitar sala de espera",
|
||||
"lobbyButtonEnable": "Habilitar sala de espera",
|
||||
"login": "Iniciar sessão",
|
||||
@@ -990,11 +1236,13 @@
|
||||
"mute": "Mudo / Não mudo",
|
||||
"muteEveryone": "Silenciar todos",
|
||||
"muteEveryonesVideo": "Desativar a câmera de todos",
|
||||
"muteGUMPending": "Conectando seu microfone",
|
||||
"noAudioSignalDesc": "Se você não o desativou propositalmente das configurações do sistema ou do hardware, considere trocar o dispositivo.",
|
||||
"noAudioSignalDescSuggestion": "Se você não o desativou propositalmente das configurações do sistema ou do hardware, considere trocar para o dispositivo sugerido.",
|
||||
"noAudioSignalDialInDesc": "Você também pode discar usando:",
|
||||
"noAudioSignalDialInLinkDesc": "Discar números",
|
||||
"noAudioSignalTitle": "Não há entrada de áudio vindo do seu microfone!",
|
||||
"noiseSuppression": "Supressão de ruído",
|
||||
"noisyAudioInputDesc": "Parece que o microfone está fazendo barulho, considere silenciar ou alterar o dispositivo.",
|
||||
"noisyAudioInputTitle": "O seu microfone parece estar barulhento!",
|
||||
"openChat": "Abrir chat",
|
||||
@@ -1011,12 +1259,14 @@
|
||||
"reactionLike": "Enviar reação de gostei",
|
||||
"reactionSilence": "Enviar reação de silêncio",
|
||||
"reactionSurprised": "Enviar reação de surpresa",
|
||||
"reactions": "Reações",
|
||||
"security": "Opções de segurança",
|
||||
"selectBackground": "Selecionar fundo",
|
||||
"shareRoom": "Convidar alguém",
|
||||
"shareaudio": "Compartilhar áudio",
|
||||
"sharedvideo": "Compartilhar um vídeo",
|
||||
"shortcuts": "Ver atalhos",
|
||||
"showWhiteboard": "Exibir quadro branco",
|
||||
"silence": "Silêncio",
|
||||
"speakerStats": "Estatísticas do Apresentador",
|
||||
"startScreenSharing": "Iniciar compart. de tela",
|
||||
@@ -1029,8 +1279,11 @@
|
||||
"talkWhileMutedPopup": "Tentando falar? Você está em mudo.",
|
||||
"tileViewToggle": "Alternar visualização em blocos",
|
||||
"toggleCamera": "Alternar câmera",
|
||||
"unmute": "Ativar som",
|
||||
"videoSettings": "Configurações de vídeo",
|
||||
"videomute": "Iniciar ou parar a câmera"
|
||||
"videomute": "Iniciar ou parar a câmera",
|
||||
"videomuteGUMPending": "Conectando sua câmera",
|
||||
"videounmute": "Ativar câmera"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Iniciar/parar legendas",
|
||||
@@ -1040,10 +1293,15 @@
|
||||
"labelToolTip": "A reunião esta sendo transcrita",
|
||||
"off": "Transcrição parada",
|
||||
"pending": "Preparando a transcrição da reunião...",
|
||||
"sourceLanguageDesc": "No momento o idioma da reunião está definido para <b>{{sourceLanguage}}</b>. <br/> Você pode alterar-lo ",
|
||||
"sourceLanguageHere": "aqui",
|
||||
"start": "Exibir legendas",
|
||||
"stop": "Não exibir legendas",
|
||||
"subtitles": "Legendas",
|
||||
"subtitlesOff": "Desativadas",
|
||||
"tr": "TR"
|
||||
},
|
||||
"unpinParticipant": "{{participantName}} - Desafixar",
|
||||
"userMedia": {
|
||||
"androidGrantPermissions": "Selecione <b><i>Permitir</i></b> quando seu navegador perguntar pelas permissões.",
|
||||
"chromeGrantPermissions": "Selecione <b><i>Permitir</i></b> quando seu navegador perguntar pelas permissões.",
|
||||
@@ -1067,20 +1325,26 @@
|
||||
"pending": "{{displayName}} foi convidado"
|
||||
},
|
||||
"videoStatus": {
|
||||
"adjustFor": "Ajustar para:",
|
||||
"audioOnly": "AUD",
|
||||
"audioOnlyExpanded": "Você está em modo de banda baixa. Neste modo, se recebe somente áudio e compartilhamento de tela.",
|
||||
"bestPerformance": "Melhor performance",
|
||||
"callQuality": "Qualidade de vídeo",
|
||||
"hd": "HD",
|
||||
"hdTooltip": "Ver vídeo em alta definição",
|
||||
"highDefinition": "Alta definição (HD)",
|
||||
"highestQuality": "Alta qualidade",
|
||||
"labelTooiltipNoVideo": "Sem vídeo",
|
||||
"labelTooltipAudioOnly": "Modo de largura de banda baixa habilitada",
|
||||
"ld": "LD",
|
||||
"ldTooltip": "Ver vídeo em baixa definição",
|
||||
"lowDefinition": "Baixa definição (LD)",
|
||||
"performanceSettings": "Configurações de performance",
|
||||
"recording": "Gravação em andamento",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Ver vídeo em definição padrão",
|
||||
"standardDefinition": "Definição padrão"
|
||||
"standardDefinition": "Definição padrão",
|
||||
"streaming": "Streaming em andamento"
|
||||
},
|
||||
"videothumbnail": {
|
||||
"connectionInfo": "Informações da Conexão",
|
||||
@@ -1090,12 +1354,19 @@
|
||||
"domuteVideoOfOthers": "Desativar a câmera de todos os demais",
|
||||
"flip": "Inverter",
|
||||
"grantModerator": "Atribuir Moderador",
|
||||
"hideSelfView": "Ocultar auto-visualização",
|
||||
"kick": "Remover",
|
||||
"mirrorVideo": "Espelhar meu vídeo",
|
||||
"moderator": "Moderador",
|
||||
"mute": "Participante está mudo",
|
||||
"muted": "Mudo",
|
||||
"pinToStage": "Fixar no palco",
|
||||
"remoteControl": "Controle remoto",
|
||||
"screenSharing": "O participante está compartilhando sua tela",
|
||||
"show": "Mostrar no palco",
|
||||
"showSelfView": "Exibir auto-visualização",
|
||||
"unpinFromStage": "Desafixar",
|
||||
"verify": "Verificar participante",
|
||||
"videoMuted": "Câmera desativada",
|
||||
"videomute": "O participante parou a câmera"
|
||||
},
|
||||
@@ -1120,7 +1391,16 @@
|
||||
"slightBlur": "Desfoque suave",
|
||||
"title": "Fundos virtuais",
|
||||
"uploadedImage": "Imagem enviada {{index}}",
|
||||
"webAssemblyWarning": "Não há suporte para WebAssembly"
|
||||
"webAssemblyWarning": "Não há suporte para WebAssembly",
|
||||
"webAssemblyWarningDescription": "WebAssembly desativado ou não suportado neste navegador"
|
||||
},
|
||||
"visitors": {
|
||||
"chatIndicator": "(visitante)",
|
||||
"labelTooltip": "Número de visitantes: {{count}}",
|
||||
"notification": {
|
||||
"description": "Para participar levante a mão",
|
||||
"title": "Você é um visitante na reunião"
|
||||
}
|
||||
},
|
||||
"volumeSlider": "Controle de volume",
|
||||
"welcomepage": {
|
||||
@@ -1154,6 +1434,7 @@
|
||||
"microsoftLogo": "Logo da Microsoft",
|
||||
"policyLogo": "Logo da Política de Privacidade"
|
||||
},
|
||||
"meetingsAccessibilityLabel": "Reuniões",
|
||||
"mobileDownLoadLinkAndroid": "Baixar aplicativo móvel para Android",
|
||||
"mobileDownLoadLinkFDroid": "Baixar aplicativo móvel para F-Droid",
|
||||
"mobileDownLoadLinkIos": "Baixar aplicativo móvel para iOS",
|
||||
@@ -1162,13 +1443,21 @@
|
||||
"recentList": "Recente",
|
||||
"recentListDelete": "Remover",
|
||||
"recentListEmpty": "Sua lista recente está vazia. As reuniões que você realizar serão exibidas aqui.",
|
||||
"recentMeetings": "Suas reuniões recentes",
|
||||
"reducedUIText": "Bem-vindo ao {{app}}!",
|
||||
"roomNameAllowedChars": "Nome da reunião não deve conter qualquer um destes caracteres: ?. &, :, ', \", %, #.",
|
||||
"roomname": "Digite o nome da sala",
|
||||
"roomnameHint": "Digite o nome ou a URL da sala que você deseja entrar. Você pode digitar um nome, e apenas deixe para as pessoas que você quer se reunir digitem o mesmo nome.",
|
||||
"sendFeedback": "Enviar comentários",
|
||||
"settings": "Configurações",
|
||||
"startMeeting": "Iniciar reunião",
|
||||
"terms": "Termos",
|
||||
"title": "Videoconferências mais seguras, flexíveis e totalmente gratuitas"
|
||||
"title": "Videoconferências mais seguras, flexíveis e totalmente gratuitas",
|
||||
"upcomingMeetings": "Suas próximas reuniões"
|
||||
},
|
||||
"whiteboard": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Quadro branco"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,6 +63,8 @@
|
||||
"leaveBreakoutRoom": "Leave breakout room",
|
||||
"more": "More",
|
||||
"remove": "Remove",
|
||||
"rename": "Rename",
|
||||
"renameBreakoutRoom": "Rename breakout room",
|
||||
"sendToBreakoutRoom": "Send participant to:"
|
||||
},
|
||||
"defaultName": "Breakout room #{{index}}",
|
||||
@@ -370,8 +372,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",
|
||||
@@ -388,6 +388,8 @@
|
||||
"removePassword": "Remove $t(lockRoomPassword)",
|
||||
"removeSharedVideoMsg": "Are you sure you would like to remove your shared video?",
|
||||
"removeSharedVideoTitle": "Remove shared video",
|
||||
"renameBreakoutRoomLabel": "Room name",
|
||||
"renameBreakoutRoomTitle": "Rename breakout room",
|
||||
"reservationError": "Reservation system error",
|
||||
"reservationErrorMsg": "Error code: {{code}}, message: {{msg}}",
|
||||
"retry": "Retry",
|
||||
@@ -439,6 +441,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 +677,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",
|
||||
@@ -742,7 +747,6 @@
|
||||
"newDeviceCameraTitle": "New camera detected",
|
||||
"noiseSuppressionDesktopAudioDescription": "Noise suppression can't be enabled while sharing desktop audio, please disable it and try again.",
|
||||
"noiseSuppressionFailedTitle": "Failed to start noise suppression",
|
||||
"noiseSuppressionNoTrackDescription": "Please unmute your microphone first.",
|
||||
"noiseSuppressionStereoDescription": "Stereo audio noise suppression is not currently supported.",
|
||||
"oldElectronClientDescription1": "You appear to be using an old version of the Jitsi Meet client which has known security vulnerabilities. Please make sure you update to our ",
|
||||
"oldElectronClientDescription2": "latest build",
|
||||
|
||||
@@ -2002,14 +2002,16 @@ class API {
|
||||
* Notify external application ( if API is enabled) that a participant menu button was clicked.
|
||||
*
|
||||
* @param {string} key - The key of the participant menu button.
|
||||
* @param {string} participantId - The ID of the participant for with the participant menu button was clicked.
|
||||
* @param {string} participantId - The ID of the participant for whom the participant menu button was clicked.
|
||||
* @param {boolean} preventExecution - Whether execution of the button click was prevented or not.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyParticipantMenuButtonClicked(key, participantId) {
|
||||
notifyParticipantMenuButtonClicked(key, participantId, preventExecution) {
|
||||
this._sendEvent({
|
||||
name: 'participant-menu-button-clicked',
|
||||
key,
|
||||
participantId
|
||||
participantId,
|
||||
preventExecution
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,15 @@ import { parseURLParams } from '../../react/features/base/util/parseURLParams';
|
||||
|
||||
/**
|
||||
* JitsiMeetExternalAPI id - unique for a webpage.
|
||||
* TODO: This shouldn't be computed here.
|
||||
*/
|
||||
export const API_ID = parseURLParams(window.location).jitsi_meet_external_api_id;
|
||||
let _apiID;
|
||||
|
||||
try {
|
||||
_apiID = parseURLParams(window.location).jitsi_meet_external_api_id;
|
||||
} catch (_) { /* Ignore. */ }
|
||||
|
||||
export const API_ID = _apiID;
|
||||
|
||||
/**
|
||||
* The payload name for the datachannel/endpoint text message event.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
@@ -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;
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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';
|
||||
|
||||
455
package-lock.json
generated
455
package-lock.json
generated
@@ -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,7 +60,7 @@
|
||||
"js-md5": "0.6.1",
|
||||
"js-sha512": "0.8.0",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1652.0.0+90da4884/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1669.0.0+da04ed9d/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
@@ -74,7 +74,7 @@
|
||||
"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",
|
||||
@@ -83,14 +83,14 @@
|
||||
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
|
||||
"react-native-gesture-handler": "2.9.0",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-immersive-mode": "2.0.1",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "1.5.0",
|
||||
"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",
|
||||
@@ -102,7 +102,7 @@
|
||||
"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"
|
||||
},
|
||||
@@ -5526,6 +5526,11 @@
|
||||
"yarn": ">= 1.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@testrtc/watchrtc-sdk": {
|
||||
"version": "1.36.3",
|
||||
"resolved": "https://registry.npmjs.org/@testrtc/watchrtc-sdk/-/watchrtc-sdk-1.36.3.tgz",
|
||||
"integrity": "sha512-JtcTvvh20t553n8q5ZHpWQeSUTENkQrZbGNvQ05jD8SA2V5PHBok/7my1ZDuA44sgT0y1OfUA8VT7dhcs0VxWg=="
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@@ -5661,7 +5666,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 +5846,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 +6027,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 +6168,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 +6294,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 +6335,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"
|
||||
@@ -7111,6 +7114,11 @@
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
|
||||
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
|
||||
},
|
||||
"node_modules/async-es": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async-es/-/async-es-3.2.4.tgz",
|
||||
"integrity": "sha512-GFHAAfmW7GzEiHFR6DvE5WMm6+js9pb+RLm+m1UpsyMX+I4j/R4QVw2Te664q+fvDVOz7Y0bORPDNvQS7BJ3Hw=="
|
||||
},
|
||||
"node_modules/async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
@@ -9369,9 +9377,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"
|
||||
@@ -9910,9 +9918,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"
|
||||
}
|
||||
@@ -12762,8 +12770,8 @@
|
||||
},
|
||||
"node_modules/lib-jitsi-meet": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1652.0.0+90da4884/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-QLXzAvGwQLpqpQmnbW9wOeScEf3WoBH+osLywzil6FAMsf3URoHR4jFLmkSUAvoxsLbpUSI1ziFFIprbYPnWuQ==",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1669.0.0+da04ed9d/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-DthI7nz/74yBefY1+VBgQNyjbaII3OsHfY2hTKKF6jbPUvAKw0HCYJHBK5ercQQWBtDUMB8ob5eBUtZg+R5Frg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -12771,7 +12779,8 @@
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/sdp-interop": "git+https://github.com/jitsi/sdp-interop#3d49eb4aa26863a3f8d32d7581cdb4321244266b",
|
||||
"@jitsi/sdp-simulcast": "0.4.0",
|
||||
"async": "3.2.3",
|
||||
"@testrtc/watchrtc-sdk": "1.36.3",
|
||||
"async-es": "3.2.4",
|
||||
"base64-js": "1.3.1",
|
||||
"current-executing-script": "0.1.3",
|
||||
"jquery": "3.6.1",
|
||||
@@ -12943,9 +12952,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"
|
||||
}
|
||||
@@ -14009,9 +14018,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"
|
||||
},
|
||||
@@ -14818,9 +14833,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"
|
||||
@@ -15661,9 +15676,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",
|
||||
@@ -15802,12 +15818,12 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.7.tgz",
|
||||
"integrity": "sha512-+4JpbIx42zGTONhBTIXSyfyHICHC29VTvhkkoUOJAh/XHPEixpuBduYgf6Y4y9wsN1ARlQhBBoptTvXvAFQf5g=="
|
||||
},
|
||||
"node_modules/react-native-immersive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive/-/react-native-immersive-2.0.0.tgz",
|
||||
"integrity": "sha512-9TL05nTHN/x9sN1wbUlBoGyzH4NCuZ/7WEEUp5CvOoKuUABvdYosov0O0SAMbm/5J913RRoy98VB6tGNi9lRSw==",
|
||||
"node_modules/react-native-immersive-mode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive-mode/-/react-native-immersive-mode-2.0.1.tgz",
|
||||
"integrity": "sha512-2wlL7VIHl4rr4gwgnUp9K1UvsN7J5VCGqoAvBWQXvB4xn7XaoDEl6z9vqaqOiEdC6aAh2d/7zqcJz+dfcR2ELw==",
|
||||
"peerDependencies": {
|
||||
"react-native": ">=0.47.0"
|
||||
"react-native": ">=0.60.5"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-keep-awake": {
|
||||
@@ -15859,18 +15875,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"
|
||||
@@ -16117,27 +16133,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",
|
||||
@@ -16812,9 +16830,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"
|
||||
}
|
||||
@@ -18341,9 +18359,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"
|
||||
@@ -18794,9 +18812,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",
|
||||
@@ -19707,9 +19728,9 @@
|
||||
"integrity": "sha512-rCPf3AakAAgvapnbYVvG2bQyI3g6EDbPpjDJ72fdAu+XTzB1qvX4ZC6OnZ0I2+thaspjTb+8KwdyhdBl8Lt/QA=="
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -21251,9 +21272,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=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -22131,9 +22152,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"
|
||||
@@ -23145,11 +23166,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"
|
||||
},
|
||||
@@ -23179,11 +23200,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",
|
||||
@@ -23199,14 +23220,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"
|
||||
@@ -23237,30 +23258,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"
|
||||
},
|
||||
@@ -23710,6 +23731,11 @@
|
||||
"seedrandom": "2.4.3"
|
||||
}
|
||||
},
|
||||
"@testrtc/watchrtc-sdk": {
|
||||
"version": "1.36.3",
|
||||
"resolved": "https://registry.npmjs.org/@testrtc/watchrtc-sdk/-/watchrtc-sdk-1.36.3.tgz",
|
||||
"integrity": "sha512-JtcTvvh20t553n8q5ZHpWQeSUTENkQrZbGNvQ05jD8SA2V5PHBok/7my1ZDuA44sgT0y1OfUA8VT7dhcs0VxWg=="
|
||||
},
|
||||
"@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@@ -23842,7 +23868,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"
|
||||
@@ -24023,7 +24048,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": "*",
|
||||
@@ -24189,9 +24213,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"
|
||||
@@ -24270,9 +24294,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"
|
||||
@@ -24336,9 +24360,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"
|
||||
@@ -24363,9 +24387,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"
|
||||
@@ -24981,6 +25005,11 @@
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
|
||||
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
|
||||
},
|
||||
"async-es": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async-es/-/async-es-3.2.4.tgz",
|
||||
"integrity": "sha512-GFHAAfmW7GzEiHFR6DvE5WMm6+js9pb+RLm+m1UpsyMX+I4j/R4QVw2Te664q+fvDVOz7Y0bORPDNvQS7BJ3Hw=="
|
||||
},
|
||||
"async-limiter": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
|
||||
@@ -26883,9 +26912,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"
|
||||
@@ -27104,9 +27133,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",
|
||||
@@ -29260,14 +29289,15 @@
|
||||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1652.0.0+90da4884/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-QLXzAvGwQLpqpQmnbW9wOeScEf3WoBH+osLywzil6FAMsf3URoHR4jFLmkSUAvoxsLbpUSI1ziFFIprbYPnWuQ==",
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1669.0.0+da04ed9d/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-DthI7nz/74yBefY1+VBgQNyjbaII3OsHfY2hTKKF6jbPUvAKw0HCYJHBK5ercQQWBtDUMB8ob5eBUtZg+R5Frg==",
|
||||
"requires": {
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/sdp-interop": "git+https://github.com/jitsi/sdp-interop#3d49eb4aa26863a3f8d32d7581cdb4321244266b",
|
||||
"@jitsi/sdp-simulcast": "0.4.0",
|
||||
"async": "3.2.3",
|
||||
"@testrtc/watchrtc-sdk": "1.36.3",
|
||||
"async-es": "3.2.4",
|
||||
"base64-js": "1.3.1",
|
||||
"current-executing-script": "0.1.3",
|
||||
"jquery": "3.6.1",
|
||||
@@ -29400,9 +29430,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",
|
||||
@@ -30259,9 +30289,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",
|
||||
@@ -30838,9 +30868,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": {
|
||||
@@ -31451,9 +31481,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",
|
||||
@@ -31569,10 +31599,10 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.0.7.tgz",
|
||||
"integrity": "sha512-+4JpbIx42zGTONhBTIXSyfyHICHC29VTvhkkoUOJAh/XHPEixpuBduYgf6Y4y9wsN1ARlQhBBoptTvXvAFQf5g=="
|
||||
},
|
||||
"react-native-immersive": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive/-/react-native-immersive-2.0.0.tgz",
|
||||
"integrity": "sha512-9TL05nTHN/x9sN1wbUlBoGyzH4NCuZ/7WEEUp5CvOoKuUABvdYosov0O0SAMbm/5J913RRoy98VB6tGNi9lRSw=="
|
||||
"react-native-immersive-mode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-immersive-mode/-/react-native-immersive-mode-2.0.1.tgz",
|
||||
"integrity": "sha512-2wlL7VIHl4rr4gwgnUp9K1UvsN7J5VCGqoAvBWQXvB4xn7XaoDEl6z9vqaqOiEdC6aAh2d/7zqcJz+dfcR2ELw=="
|
||||
},
|
||||
"react-native-keep-awake": {
|
||||
"version": "4.0.0",
|
||||
@@ -31605,14 +31635,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"
|
||||
@@ -31767,23 +31797,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": {
|
||||
@@ -32266,9 +32289,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",
|
||||
@@ -33454,9 +33477,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"
|
||||
@@ -33770,9 +33793,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",
|
||||
@@ -34414,9 +34437,9 @@
|
||||
"integrity": "sha512-rCPf3AakAAgvapnbYVvG2bQyI3g6EDbPpjDJ72fdAu+XTzB1qvX4ZC6OnZ0I2+thaspjTb+8KwdyhdBl8Lt/QA=="
|
||||
},
|
||||
"word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
|
||||
"integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
|
||||
"dev": true
|
||||
},
|
||||
"wrap-ansi": {
|
||||
|
||||
27
package.json
27
package.json
@@ -2,6 +2,7 @@
|
||||
"name": "jitsi-meet",
|
||||
"version": "0.0.0",
|
||||
"description": "A sample app for the Jitsi Videobridge",
|
||||
"private": true,
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jitsi/jitsi-meet"
|
||||
@@ -36,11 +37,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,7 +66,7 @@
|
||||
"js-md5": "0.6.1",
|
||||
"js-sha512": "0.8.0",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1652.0.0+90da4884/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1669.0.0+da04ed9d/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
@@ -79,7 +80,7 @@
|
||||
"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",
|
||||
@@ -88,14 +89,14 @@
|
||||
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
|
||||
"react-native-gesture-handler": "2.9.0",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-immersive-mode": "2.0.1",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "1.5.0",
|
||||
"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",
|
||||
@@ -107,7 +108,7 @@
|
||||
"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 +180,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",
|
||||
|
||||
1
react-native-sdk/.npmignore
Normal file
1
react-native-sdk/.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
*.tgz
|
||||
@@ -2,11 +2,51 @@
|
||||
|
||||
|
||||
## 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;
|
||||
```console
|
||||
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:
|
||||
```console
|
||||
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:
|
||||
|
||||
```javascript
|
||||
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
|
||||
@@ -19,30 +59,31 @@
|
||||
- Audio
|
||||
- Voice over IP
|
||||
- Background fetch
|
||||
- Add Copy Sounds step:
|
||||
|
||||
Run;
|
||||
```console
|
||||
cd ios && pod install && cd ..
|
||||
```
|
||||
SOUNDS_DIR="${PROJECT_DIR}/../node_modules/rnsdk/sounds"
|
||||
cp $SOUNDS_DIR/* ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/
|
||||
```
|
||||
#### Podfile
|
||||
- At the beginning of your target step add `pod 'ObjectiveDropboxOfficial', :modular_headers => true`
|
||||
|
||||
Run `cd ios && pod install && cd ..`
|
||||
|
||||
### Android
|
||||
|
||||
- In your build.gradle have at least `minSdkVersion = 24`
|
||||
- TODO: HOW TO ADD COPY SOUNDS STEP
|
||||
- Under the `</application>` tag of your AndroidManifest.xml make sure that it includes
|
||||
```
|
||||
- In `android/app/src/debug/AndroidManifest.xml` and `android/app/src/main/AndroidManifest.xml`, under the `</application>` tag, include
|
||||
```xml
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<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
|
||||
If you want to test all the steps before applying them to your app, you can check our React Native SDK sample app here:
|
||||
https://github.com/jitsi/jitsi-meet-sdk-samples/tree/master/react-native
|
||||
|
||||
|
||||
### Using JWT tokens
|
||||
- If you are planning to use tokens you can update your domain and room name inside meeting options.
|
||||
- For example:
|
||||
```javascript
|
||||
const meetingOptions = {
|
||||
domain: 'YOUR_DOMAIN',
|
||||
roomName: 'ROOM_NAME?jwt=JWT_TOKEN'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -138,3 +138,19 @@ if (isNewArchitectureEnabled()) {
|
||||
codegenJavaPackageName = "org.jitsi.meet.sdk"
|
||||
}
|
||||
}
|
||||
|
||||
// Copy sounds to assets directory
|
||||
android.libraryVariants.all { def variant ->
|
||||
def mergeAssetsTask = variant.mergeAssetsProvider.get()
|
||||
def mergeResourcesTask = variant.mergeResourcesProvider.get()
|
||||
mergeAssetsTask.doLast {
|
||||
def assetsDir = mergeAssetsTask.outputDir.get()
|
||||
def soundsDir = "${projectDir}/../sounds"
|
||||
copy {
|
||||
from("${soundsDir}")
|
||||
include("*.wav")
|
||||
include("*.mp3")
|
||||
into("${assetsDir}/sounds")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,20 @@ 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'
|
||||
|
||||
s.script_phase = {
|
||||
:name => 'Copy Sound Files',
|
||||
:script => '
|
||||
SOURCE_PATH="${PODS_TARGET_SRCROOT}/sounds"
|
||||
TARGET_PATH="$(dirname ${CONFIGURATION_BUILD_DIR})"
|
||||
PROJECT_NAME=$(basename $(dirname $(dirname ${PROJECT_DIR}))).app
|
||||
cp -R "${PODS_TARGET_SRCROOT}/sounds/" "${TARGET_PATH}/${PROJECT_NAME}"
|
||||
',
|
||||
}
|
||||
end
|
||||
|
||||
310
react-native-sdk/package-lock.json
generated
310
react-native-sdk/package-lock.json
generated
@@ -7,17 +7,18 @@
|
||||
"": {
|
||||
"name": "@jitsi/react-native-sdk",
|
||||
"version": "0.1.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@hapi/bourne": "2.0.0",
|
||||
"@jitsi/js-utils": "2.0.5",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/rtcstats": "9.5.1",
|
||||
"@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",
|
||||
@@ -27,13 +28,13 @@
|
||||
"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/v1649.0.0+17ade96a/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1662.0.0+6c4381c8/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",
|
||||
@@ -43,7 +44,7 @@
|
||||
"react-native-tab-view": "3.1.1",
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-youtube-iframe": "2.2.1",
|
||||
"react-redux": "7.1.0",
|
||||
"react-redux": "7.2.9",
|
||||
"redux": "4.0.4",
|
||||
"redux-thunk": "2.4.1",
|
||||
"unorm": "1.6.0",
|
||||
@@ -67,14 +68,14 @@
|
||||
"react-native-device-info": "8.4.8",
|
||||
"react-native-gesture-handler": "2.9.0",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-immersive-mode": "2.0.1",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "https://git@github.com/wonday/react-native-orientation-locker#f483520ea6b64b97002374a9e9f053a5299a062a",
|
||||
"react-native-pager-view": "5.4.9",
|
||||
"react-native-paper": "4.11.1",
|
||||
"react-native-performance": "2.1.0",
|
||||
"react-native-safe-area-context": "4.4.1",
|
||||
"react-native-screens": "3.13.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",
|
||||
@@ -145,9 +146,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/core/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"
|
||||
}
|
||||
@@ -185,9 +186,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-compilation-targets/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"
|
||||
}
|
||||
@@ -501,11 +502,11 @@
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||
},
|
||||
"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"
|
||||
},
|
||||
@@ -534,9 +535,9 @@
|
||||
}
|
||||
},
|
||||
"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": "*",
|
||||
@@ -545,9 +546,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"
|
||||
@@ -561,11 +562,11 @@
|
||||
}
|
||||
},
|
||||
"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"
|
||||
@@ -584,11 +585,11 @@
|
||||
}
|
||||
},
|
||||
"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"
|
||||
},
|
||||
@@ -830,11 +831,51 @@
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/hoist-non-react-statics": {
|
||||
"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==",
|
||||
"dependencies": {
|
||||
"@types/react": "*",
|
||||
"hoist-non-react-statics": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||
},
|
||||
"node_modules/@types/prop-types": {
|
||||
"version": "15.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
|
||||
},
|
||||
"node_modules/@types/react": {
|
||||
"version": "18.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz",
|
||||
"integrity": "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==",
|
||||
"dependencies": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-redux": {
|
||||
"version": "7.1.25",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz",
|
||||
"integrity": "sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==",
|
||||
"dependencies": {
|
||||
"@types/hoist-non-react-statics": "^3.3.0",
|
||||
"@types/react": "*",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"redux": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/scheduler": {
|
||||
"version": "0.16.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
||||
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
|
||||
},
|
||||
"node_modules/@xmldom/xmldom": {
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.7.tgz",
|
||||
@@ -919,10 +960,10 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/async": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
|
||||
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
|
||||
"node_modules/async-es": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async-es/-/async-es-3.2.4.tgz",
|
||||
"integrity": "sha512-GFHAAfmW7GzEiHFR6DvE5WMm6+js9pb+RLm+m1UpsyMX+I4j/R4QVw2Te664q+fvDVOz7Y0bORPDNvQS7BJ3Hw=="
|
||||
},
|
||||
"node_modules/at-least-node": {
|
||||
"version": "1.0.0",
|
||||
@@ -1299,6 +1340,11 @@
|
||||
"node": ">=8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/csstype": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||
},
|
||||
"node_modules/current-executing-script": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/current-executing-script/-/current-executing-script-0.1.3.tgz",
|
||||
@@ -2397,8 +2443,8 @@
|
||||
},
|
||||
"node_modules/lib-jitsi-meet": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1649.0.0+17ade96a/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-87/CvxF4ySp+PFaJVE3rFMh6nlQ9iQD3tghY/EUL4BabsbDFUtTOoDmoCR6ekqluBmHU59KMbDFHQ5aY1iGhJw==",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1662.0.0+6c4381c8/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-jEQv0imqSPHowBOsd8178fPLUNTj0SavUQnWJIjEjFW4kE4KA+jBlU2C9qryEFwqJ2NjFo7md6H/xz8u+tW1mA==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -2406,7 +2452,7 @@
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/sdp-interop": "git+https://github.com/jitsi/sdp-interop#3d49eb4aa26863a3f8d32d7581cdb4321244266b",
|
||||
"@jitsi/sdp-simulcast": "0.4.0",
|
||||
"async": "3.2.3",
|
||||
"async-es": "3.2.4",
|
||||
"base64-js": "1.3.1",
|
||||
"current-executing-script": "0.1.3",
|
||||
"jquery": "3.6.1",
|
||||
@@ -2879,9 +2925,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"
|
||||
}
|
||||
@@ -3022,22 +3068,34 @@
|
||||
}
|
||||
},
|
||||
"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": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
@@ -3152,9 +3210,9 @@
|
||||
}
|
||||
},
|
||||
"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"
|
||||
}
|
||||
@@ -3696,9 +3754,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"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=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3726,9 +3784,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"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=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3980,11 +4038,11 @@
|
||||
}
|
||||
},
|
||||
"@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"
|
||||
}
|
||||
@@ -4003,25 +4061,25 @@
|
||||
}
|
||||
},
|
||||
"@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"
|
||||
}
|
||||
},
|
||||
"@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"
|
||||
@@ -4036,11 +4094,11 @@
|
||||
}
|
||||
},
|
||||
"@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"
|
||||
}
|
||||
@@ -4147,11 +4205,51 @@
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA=="
|
||||
},
|
||||
"@types/hoist-non-react-statics": {
|
||||
"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==",
|
||||
"requires": {
|
||||
"@types/react": "*",
|
||||
"hoist-non-react-statics": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"@types/parse-json": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
|
||||
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA=="
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.7.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
|
||||
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "18.2.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.15.tgz",
|
||||
"integrity": "sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA==",
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"@types/scheduler": "*",
|
||||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"@types/react-redux": {
|
||||
"version": "7.1.25",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.25.tgz",
|
||||
"integrity": "sha512-bAGh4e+w5D8dajd6InASVIyCo4pZLJ66oLb80F9OBLO1gKESbZcRCJpTT6uLXX+HAB57zw1WTdwJdAsewuTweg==",
|
||||
"requires": {
|
||||
"@types/hoist-non-react-statics": "^3.3.0",
|
||||
"@types/react": "*",
|
||||
"hoist-non-react-statics": "^3.3.0",
|
||||
"redux": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/scheduler": {
|
||||
"version": "0.16.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz",
|
||||
"integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
|
||||
},
|
||||
"@xmldom/xmldom": {
|
||||
"version": "0.8.7",
|
||||
"resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.7.tgz",
|
||||
@@ -4220,10 +4318,10 @@
|
||||
"is-string": "^1.0.7"
|
||||
}
|
||||
},
|
||||
"async": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz",
|
||||
"integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
|
||||
"async-es": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/async-es/-/async-es-3.2.4.tgz",
|
||||
"integrity": "sha512-GFHAAfmW7GzEiHFR6DvE5WMm6+js9pb+RLm+m1UpsyMX+I4j/R4QVw2Te664q+fvDVOz7Y0bORPDNvQS7BJ3Hw=="
|
||||
},
|
||||
"at-least-node": {
|
||||
"version": "1.0.0",
|
||||
@@ -4479,6 +4577,11 @@
|
||||
"css-tree": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
|
||||
"integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
|
||||
},
|
||||
"current-executing-script": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/current-executing-script/-/current-executing-script-0.1.3.tgz",
|
||||
@@ -5246,14 +5349,14 @@
|
||||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1649.0.0+17ade96a/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-87/CvxF4ySp+PFaJVE3rFMh6nlQ9iQD3tghY/EUL4BabsbDFUtTOoDmoCR6ekqluBmHU59KMbDFHQ5aY1iGhJw==",
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1662.0.0+6c4381c8/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-jEQv0imqSPHowBOsd8178fPLUNTj0SavUQnWJIjEjFW4kE4KA+jBlU2C9qryEFwqJ2NjFo7md6H/xz8u+tW1mA==",
|
||||
"requires": {
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/sdp-interop": "git+https://github.com/jitsi/sdp-interop#3d49eb4aa26863a3f8d32d7581cdb4321244266b",
|
||||
"@jitsi/sdp-simulcast": "0.4.0",
|
||||
"async": "3.2.3",
|
||||
"async-es": "3.2.4",
|
||||
"base64-js": "1.3.1",
|
||||
"current-executing-script": "0.1.3",
|
||||
"jquery": "3.6.1",
|
||||
@@ -5609,9 +5712,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=="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "7.1.3",
|
||||
@@ -5704,16 +5807,23 @@
|
||||
}
|
||||
},
|
||||
"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"
|
||||
"react-is": "^17.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"react-is": {
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"readdirp": {
|
||||
@@ -5792,9 +5902,9 @@
|
||||
"integrity": "sha512-zR0e9ciWFezeaKLLpWCrOCiYmGIQN9jfO5Ayfs7m5k2/g9b2MEEIvQ/TTmymm167zozTNYSQoLGKDihMoTWkkw=="
|
||||
},
|
||||
"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",
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
"@jitsi/js-utils": "2.0.5",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/rtcstats": "9.5.1",
|
||||
"@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",
|
||||
@@ -29,13 +29,13 @@
|
||||
"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/v1649.0.0+17ade96a/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1662.0.0+6c4381c8/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",
|
||||
@@ -45,7 +45,7 @@
|
||||
"react-native-tab-view": "3.1.1",
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-youtube-iframe": "2.2.1",
|
||||
"react-redux": "7.1.0",
|
||||
"react-redux": "7.2.9",
|
||||
"redux": "4.0.4",
|
||||
"redux-thunk": "2.4.1",
|
||||
"unorm": "1.6.0",
|
||||
@@ -69,14 +69,14 @@
|
||||
"react-native-device-info": "8.4.8",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-gesture-handler": "2.9.0",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-immersive-mode": "2.0.1",
|
||||
"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": "https://git@github.com/wonday/react-native-orientation-locker#f483520ea6b64b97002374a9e9f053a5299a062a",
|
||||
"react-native-safe-area-context": "4.4.1",
|
||||
"react-native-screens": "3.13.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",
|
||||
@@ -86,9 +86,7 @@
|
||||
"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",
|
||||
@@ -100,4 +98,4 @@
|
||||
"keywords": [
|
||||
"react-native"
|
||||
]
|
||||
}
|
||||
}
|
||||
4
react-native-sdk/prepare_sdk.js
vendored
4
react-native-sdk/prepare_sdk.js
vendored
@@ -107,10 +107,6 @@ copyFolderRecursiveSync(
|
||||
`${iosSrcPath}/dropbox`,
|
||||
iosDestPath
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../ios/sdk/src/picture-in-picture',
|
||||
iosDestPath
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/AppInfo.m`,
|
||||
`${iosDestPath}/AppInfo.m`
|
||||
|
||||
37
react-native-sdk/update_dependencies.js
vendored
37
react-native-sdk/update_dependencies.js
vendored
@@ -1,10 +1,14 @@
|
||||
/* eslint-disable guard-for-in */
|
||||
/* global __dirname */
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const packageJSON = require('../../package.json');
|
||||
const pathToPackageJSON = path.resolve(__dirname, '../../../package.json');
|
||||
|
||||
const RNSDKpackageJSON = require('./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.
|
||||
@@ -14,8 +18,16 @@ function updateDependencies() {
|
||||
|
||||
for (const key in RNSDKpackageJSON.peerDependencies) {
|
||||
if (!packageJSON.dependencies.hasOwnProperty(key)) {
|
||||
packageJSON.dependencies[key]
|
||||
= '*' || RNSDKpackageJSON.peerDependencies[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;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +36,14 @@ function updateDependencies() {
|
||||
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) => {
|
||||
@@ -32,14 +52,7 @@ function updateDependencies() {
|
||||
return item;
|
||||
}, {});
|
||||
|
||||
console.log(
|
||||
'Updating dependencies:',
|
||||
Object.keys(packageJSON.dependencies)
|
||||
);
|
||||
|
||||
const data = JSON.stringify(packageJSON, null, 2);
|
||||
|
||||
fs.writeFileSync('../../package.json', data);
|
||||
fs.writeFileSync(pathToPackageJSON, JSON.stringify(packageJSON, null, 2));
|
||||
|
||||
console.log(
|
||||
'All needed dependencies have been updated. \nPlease run npm install.'
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import React, { ComponentType } from 'react';
|
||||
import { NativeModules, Platform, StyleSheet, View } from 'react-native';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
import SplashScreen from 'react-native-splash-screen';
|
||||
|
||||
@@ -36,7 +37,7 @@ interface IProps extends AbstractAppProps {
|
||||
/**
|
||||
* An object with the feature flags.
|
||||
*/
|
||||
flags: Object;
|
||||
flags: any;
|
||||
|
||||
/**
|
||||
* An object with user information (display name, email, avatar URL).
|
||||
@@ -95,7 +96,13 @@ export class App extends AbstractApp<IProps> {
|
||||
*/
|
||||
async _extraInit() {
|
||||
const { dispatch, getState } = this.state.store ?? {};
|
||||
const { flags } = this.props;
|
||||
const { flags = {} } = this.props;
|
||||
|
||||
// CallKit does not work on the simulator, make sure we disable it.
|
||||
if (Platform.OS === 'ios' && DeviceInfo.isEmulatorSync()) {
|
||||
flags['call-integration.enabled'] = false;
|
||||
logger.info('Disabling CallKit because this is a simulator');
|
||||
}
|
||||
|
||||
// We set these early enough so then we avoid any unnecessary re-renders.
|
||||
dispatch?.(updateFlags(flags));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import '../analytics/middleware';
|
||||
import '../authentication/middleware';
|
||||
import '../av-moderation/middleware';
|
||||
import '../base/conference/middleware';
|
||||
import '../base/config/middleware';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import '../authentication/middleware';
|
||||
import '../dynamic-branding/middleware';
|
||||
import '../gifs/middleware';
|
||||
import '../mobile/audio-mode/middleware';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '../authentication/middleware';
|
||||
import '../base/connection/middleware';
|
||||
import '../base/i18n/middleware';
|
||||
import '../base/devices/middleware';
|
||||
import '../base/media/middleware';
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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}.
|
||||
*
|
||||
|
||||
@@ -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';
|
||||
@@ -55,10 +55,21 @@ export function cancelWaitForOwner() {
|
||||
// clients/consumers need an event.
|
||||
const { authRequired } = getState()['features/base/conference'];
|
||||
|
||||
authRequired && dispatch(conferenceLeft(authRequired));
|
||||
if (authRequired) {
|
||||
dispatch(conferenceLeft(authRequired));
|
||||
|
||||
dispatch(appNavigate(undefined));
|
||||
// in case we are showing lobby and on top of it wait for owner
|
||||
// we do not want to navigate away from the conference
|
||||
dispatch(appNavigate(undefined));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/** .
|
||||
* Redirect to the default location (e.g. Welcome page).
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function redirectToDefaultLocation() {
|
||||
return (dispatch: IStore['dispatch']) => dispatch(appNavigate(undefined));
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -25,41 +24,51 @@ export function cancelLogin() {
|
||||
|
||||
/**
|
||||
* Cancels authentication, closes {@link WaitForOwnerDialog}
|
||||
* and navigates back to the welcome page.
|
||||
* and navigates back to the welcome page only in the case of authentication required error.
|
||||
* We can be showing the dialog while lobby is enabled and participant is still waiting there and hiding this dialog
|
||||
* should do nothing.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function cancelWaitForOwner() {
|
||||
return (dispatch: IStore['dispatch']) => {
|
||||
dispatch(maybeRedirectToWelcomePage());
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const { authRequired } = getState()['features/base/conference'];
|
||||
|
||||
authRequired && dispatch(maybeRedirectToWelcomePage());
|
||||
};
|
||||
}
|
||||
|
||||
/** .
|
||||
* Redirect to the default location (e.g. Welcome page).
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function redirectToDefaultLocation() {
|
||||
return (dispatch: IStore['dispatch']) => dispatch(maybeRedirectToWelcomePage());
|
||||
}
|
||||
|
||||
/**
|
||||
* Login.
|
||||
*
|
||||
* @returns {{
|
||||
* type: LOGIN
|
||||
* }}
|
||||
*/
|
||||
export function login() {
|
||||
return {
|
||||
type: LOGIN
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Hides a authentication dialog where the local participant
|
||||
* should authenticate.
|
||||
* Logout.
|
||||
*
|
||||
* @returns {Function}.
|
||||
* @returns {{
|
||||
* type: LOGOUT
|
||||
* }}
|
||||
*/
|
||||
export function hideLoginDialog() {
|
||||
return hideDialog(LoginDialog);
|
||||
export function logout() {
|
||||
return {
|
||||
type: LOGOUT
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a notification dialog that authentication is required to create the.
|
||||
* Conference.
|
||||
* This is used for external auth.
|
||||
*
|
||||
* @param {string} room - The room name.
|
||||
* @param {Function} onAuthNow - The function to be invoked when external authentication.
|
||||
*
|
||||
* @returns {Function}.
|
||||
*/
|
||||
export function openAuthDialog(room: String, onAuthNow?: Function) {
|
||||
return openDialog(WaitForOwnerDialog, {
|
||||
room,
|
||||
onAuthNow
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ interface IProps {
|
||||
domain: string;
|
||||
focus?: string;
|
||||
muc: string;
|
||||
visitorFocus: string;
|
||||
visitorFocus?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,8 +2,6 @@ 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';
|
||||
@@ -12,6 +10,7 @@ import { translate, translateToHTML } from '../../../base/i18n/functions';
|
||||
import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet';
|
||||
import Dialog from '../../../base/ui/components/web/Dialog';
|
||||
import Input from '../../../base/ui/components/web/Input';
|
||||
import { joinConference } from '../../../prejoin/actions.web';
|
||||
import {
|
||||
authenticateAndUpgradeRole,
|
||||
cancelLogin
|
||||
@@ -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,9 @@ 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));
|
||||
// FIXME: Workaround for the web version. To be removed once we get rid of conference.js
|
||||
dispatch(joinConference(undefined, false, jid, password));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,7 +225,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 +234,6 @@ class LoginDialog extends Component<IProps, IState> {
|
||||
hideCloseButton = { true }
|
||||
ok = {{
|
||||
disabled: connecting
|
||||
|| loginStarted
|
||||
|| !password
|
||||
|| !username,
|
||||
translationKey: 'dialog.login'
|
||||
@@ -315,7 +290,7 @@ function mapStateToProps(state: IReduxState) {
|
||||
return {
|
||||
_conference: authRequired || conference,
|
||||
_configHosts: configHosts,
|
||||
_connecting: connecting || thenableWithCancel,
|
||||
_connecting: Boolean(connecting) || Boolean(thenableWithCancel),
|
||||
_error: connectionError || authenticateAndUpgradeRoleError,
|
||||
_progress: progress
|
||||
};
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
@@ -81,8 +89,11 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
// CONFERENCE_FAILED caused by
|
||||
// JitsiConferenceErrors.AUTHENTICATION_REQUIRED.
|
||||
let recoverable;
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [ _lobbyJid, lobbyWaitingForHost ] = error.params;
|
||||
|
||||
if (error.name === JitsiConferenceErrors.AUTHENTICATION_REQUIRED) {
|
||||
if (error.name === JitsiConferenceErrors.AUTHENTICATION_REQUIRED
|
||||
|| (error.name === JitsiConferenceErrors.MEMBERS_ONLY_ERROR && lobbyWaitingForHost)) {
|
||||
if (typeof error.recoverable === 'undefined') {
|
||||
error.recoverable = true;
|
||||
}
|
||||
@@ -100,7 +111,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
if (_isWaitingForOwner(store)) {
|
||||
store.dispatch(stopWaitForOwner());
|
||||
}
|
||||
_hideLoginDialog(store);
|
||||
store.dispatch(hideLoginDialog());
|
||||
break;
|
||||
|
||||
case CONFERENCE_LEFT:
|
||||
@@ -108,18 +119,51 @@ 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(() => {
|
||||
const logoutUrl = store.getState()['features/base/config'].tokenLogoutUrl;
|
||||
|
||||
if (logoutUrl) {
|
||||
window.location.href = logoutUrl;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
conference.room.moderator.logout(() => store.dispatch(hangup(true)));
|
||||
}));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -132,7 +176,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
const { error, progress } = action;
|
||||
|
||||
if (!error && progress === 1) {
|
||||
_hideLoginDialog(store);
|
||||
store.dispatch(hideLoginDialog());
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -144,7 +188,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 +206,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 +222,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());
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
@@ -95,9 +95,14 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
|
||||
|
||||
// Dispatches into features/base/conference follow:
|
||||
|
||||
conference.on(
|
||||
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
|
||||
(authEnabled: boolean, authLogin: string) => dispatch(authStatusChanged(authEnabled, authLogin)));
|
||||
// we want to ignore this event in case of tokenAuthUrl config
|
||||
// we are deprecating this and at some point will get rid of it
|
||||
if (!state['features/base/config'].tokenAuthUrl) {
|
||||
conference.on(
|
||||
JitsiConferenceEvents.AUTH_STATUS_CHANGED,
|
||||
(authEnabled: boolean, authLogin: string) => dispatch(authStatusChanged(authEnabled, authLogin)));
|
||||
}
|
||||
|
||||
conference.on(
|
||||
JitsiConferenceEvents.CONFERENCE_FAILED,
|
||||
(err: string, ...args: any[]) => dispatch(conferenceFailed(conference, err, ...args)));
|
||||
@@ -463,6 +468,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 +665,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.
|
||||
*
|
||||
|
||||
@@ -16,13 +16,15 @@ 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';
|
||||
import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../connection/actionTypes';
|
||||
import { connect, connectionDisconnected, disconnect } from '../connection/actions';
|
||||
import { validateJwt } from '../jwt/functions';
|
||||
import { JitsiConferenceErrors } from '../lib-jitsi-meet';
|
||||
import { JitsiConferenceErrors, JitsiConnectionErrors } from '../lib-jitsi-meet';
|
||||
import { PARTICIPANT_UPDATED, PIN_PARTICIPANT } from '../participants/actionTypes';
|
||||
import { PARTICIPANT_ROLE } from '../participants/constants';
|
||||
import {
|
||||
@@ -33,6 +35,7 @@ import {
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
import { TRACK_ADDED, TRACK_REMOVED } from '../tracks/actionTypes';
|
||||
import { destroyLocalTracks } from '../tracks/actions.any';
|
||||
import { getLocalTracks } from '../tracks/functions.any';
|
||||
|
||||
import {
|
||||
CONFERENCE_FAILED,
|
||||
@@ -46,7 +49,9 @@ import {
|
||||
SET_ROOM
|
||||
} from './actionTypes';
|
||||
import {
|
||||
authStatusChanged,
|
||||
conferenceFailed,
|
||||
conferenceWillInit,
|
||||
conferenceWillLeave,
|
||||
createConference,
|
||||
leaveConference,
|
||||
@@ -71,7 +76,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 +147,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 +194,31 @@ 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()))
|
||||
.then(() => {
|
||||
// FIXME: Workaround for the web version. To be removed once we get rid of conference.js
|
||||
if (typeof APP !== 'undefined') {
|
||||
const localTracks = getLocalTracks(getState()['features/base/tracks']);
|
||||
const jitsiTracks = localTracks.map((t: any) => t.jitsiTrack);
|
||||
|
||||
APP.conference.startConference(jitsiTracks).catch(logger.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -214,45 +226,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 +310,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 +352,30 @@ 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, getState }: IStore, next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
|
||||
const { tokenAuthUrl = false } = getState()['features/base/config'];
|
||||
|
||||
// if there is token auth URL defined and local participant is using jwt
|
||||
// this means it is logged in when connection is established, so we can change the state
|
||||
if (tokenAuthUrl) {
|
||||
let email;
|
||||
|
||||
if (getState()['features/base/jwt'].jwt) {
|
||||
email = getLocalParticipant(getState())?.email;
|
||||
}
|
||||
|
||||
dispatch(authStatusChanged(true, email || ''));
|
||||
}
|
||||
|
||||
// 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 +417,49 @@ function _logJwtErrors(message: string, state: IReduxState) {
|
||||
function _connectionFailed({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
_logJwtErrors(action.error.message, getState());
|
||||
|
||||
const { connection, error } = action;
|
||||
|
||||
// do not show the notification when we will prompt the user
|
||||
// for username and password
|
||||
if (error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
|
||||
&& getState()['features/base/jwt'].jwt) {
|
||||
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;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -155,6 +155,9 @@ export interface IConferenceState {
|
||||
|
||||
export interface IJitsiConferenceRoom {
|
||||
locked: boolean;
|
||||
moderator: {
|
||||
logout: Function;
|
||||
};
|
||||
myroomjid: string;
|
||||
roomjid: string;
|
||||
}
|
||||
|
||||
@@ -68,6 +68,33 @@ type ButtonsWithNotifyClick = 'camera' |
|
||||
'add-passcode' |
|
||||
'__end';
|
||||
|
||||
type ParticipantMenuButtonsWithNotifyClick = 'allow-video' |
|
||||
'ask-unmute' |
|
||||
'conn-status' |
|
||||
'flip-local-video' |
|
||||
'grant-moderator' |
|
||||
'hide-self-view' |
|
||||
'kick' |
|
||||
'mute' |
|
||||
'mute-others' |
|
||||
'mute-others-video' |
|
||||
'mute-video' |
|
||||
'pinToStage' |
|
||||
'privateMessage' |
|
||||
'remote-control' |
|
||||
'send-participant-to-room' |
|
||||
'verify';
|
||||
|
||||
type NotifyClickButtonKey = string |
|
||||
ButtonsWithNotifyClick |
|
||||
ParticipantMenuButtonsWithNotifyClick;
|
||||
|
||||
export type NotifyClickButton = NotifyClickButtonKey |
|
||||
{
|
||||
key: NotifyClickButtonKey;
|
||||
preventExecution: boolean;
|
||||
};
|
||||
|
||||
export type Sounds = 'ASKED_TO_UNMUTE_SOUND' |
|
||||
'E2EE_OFF_SOUND' |
|
||||
'E2EE_ON_SOUND' |
|
||||
@@ -126,6 +153,25 @@ export interface INoiseSuppressionConfig {
|
||||
};
|
||||
}
|
||||
|
||||
export interface IWatchRTCConfiguration {
|
||||
allowBrowserLogCollection?: boolean;
|
||||
collectionInterval?: number;
|
||||
console?: {
|
||||
level: string;
|
||||
override: boolean;
|
||||
};
|
||||
debug?: boolean;
|
||||
keys?: any;
|
||||
logGetStats?: boolean;
|
||||
proxyUrl?: string;
|
||||
rtcApiKey: string;
|
||||
rtcPeerId?: string;
|
||||
rtcRoomId?: string;
|
||||
rtcTags?: string[];
|
||||
rtcToken?: string;
|
||||
wsUrl?: string;
|
||||
}
|
||||
|
||||
export interface IConfig {
|
||||
_desktopSharingSourceDevice?: string;
|
||||
_immediateReloadThreshold?: string;
|
||||
@@ -145,6 +191,7 @@ export interface IConfig {
|
||||
rtcstatsStoreLogs?: boolean;
|
||||
rtcstatsUseLegacy?: boolean;
|
||||
scriptURLs?: Array<string>;
|
||||
watchRTCEnabled?: boolean;
|
||||
whiteListedEvents?: string[];
|
||||
};
|
||||
apiLogLevels?: Array<'warn' | 'log' | 'error' | 'info' | 'debug'>;
|
||||
@@ -283,6 +330,7 @@ export interface IConfig {
|
||||
disableThirdPartyRequests?: boolean;
|
||||
disableTileEnlargement?: boolean;
|
||||
disableTileView?: boolean;
|
||||
disableVirtualBackground?: boolean;
|
||||
disabledNotifications?: Array<string>;
|
||||
disabledSounds?: Array<Sounds>;
|
||||
doNotFlipLocalVideo?: boolean;
|
||||
@@ -390,7 +438,7 @@ export interface IConfig {
|
||||
domain: string;
|
||||
focus?: string;
|
||||
muc: string;
|
||||
visitorFocus: string;
|
||||
visitorFocus?: string;
|
||||
};
|
||||
iAmRecorder?: boolean;
|
||||
iAmSipGateway?: boolean;
|
||||
@@ -447,6 +495,10 @@ export interface IConfig {
|
||||
mobileCodecPreferenceOrder?: Array<string>;
|
||||
stunServers?: Array<{ urls: string; }>;
|
||||
};
|
||||
participantMenuButtonsWithNotifyClick?: Array<string | ParticipantMenuButtonsWithNotifyClick | {
|
||||
key: string | ParticipantMenuButtonsWithNotifyClick;
|
||||
preventExecution: boolean;
|
||||
}>;
|
||||
participantsPane?: {
|
||||
hideModeratorSettingsTab?: boolean;
|
||||
hideMoreActionsButton?: boolean;
|
||||
@@ -524,6 +576,7 @@ export interface IConfig {
|
||||
numberOfVisibleTiles?: number;
|
||||
};
|
||||
tokenAuthUrl?: string;
|
||||
tokenLogoutUrl?: string;
|
||||
toolbarButtons?: Array<ToolbarButtons>;
|
||||
toolbarConfig?: {
|
||||
alwaysVisible?: boolean;
|
||||
@@ -559,6 +612,7 @@ export interface IConfig {
|
||||
mobileCodecPreferenceOrder?: Array<string>;
|
||||
persist?: boolean;
|
||||
};
|
||||
watchRTCConfigParams?: IWatchRTCConfiguration;
|
||||
webhookProxyUrl?: string;
|
||||
webrtcIceTcpDisable?: boolean;
|
||||
webrtcIceUdpDisable?: boolean;
|
||||
|
||||
@@ -15,6 +15,7 @@ export default [
|
||||
'_peerConnStatusRtcMuteTimeout',
|
||||
'analytics.disabled',
|
||||
'analytics.rtcstatsEnabled',
|
||||
'analytics.watchRTCEnabled',
|
||||
'audioLevelsInterval',
|
||||
'audioQuality',
|
||||
'autoKnockLobby',
|
||||
@@ -193,6 +194,7 @@ export default [
|
||||
'openSharedDocumentOnJoin',
|
||||
'opusMaxAverageBitrate',
|
||||
'p2p',
|
||||
'participantMenuButtonsWithNotifyClick',
|
||||
'participantsPane',
|
||||
'pcStatsInterval',
|
||||
'prejoinConfig',
|
||||
@@ -227,6 +229,7 @@ export default [
|
||||
'useHostPageLocalStorage',
|
||||
'useTurnUdp',
|
||||
'videoQuality',
|
||||
'watchRTCConfigParams',
|
||||
'webrtcIceTcpDisable',
|
||||
'webrtcIceUdpDisable',
|
||||
'whiteboard.enabled'
|
||||
|
||||
@@ -27,8 +27,10 @@ export function _cleanupConfig(config: IConfig) {
|
||||
delete config.analytics?.rtcstatsSendSdp;
|
||||
delete config.analytics?.rtcstatsUseLegacy;
|
||||
delete config.analytics?.obfuscateRoomName;
|
||||
delete config.analytics?.watchRTCEnabled;
|
||||
delete config.callStatsID;
|
||||
delete config.callStatsSecret;
|
||||
delete config.watchRTCConfigParams;
|
||||
config.giphy = { enabled: false };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { IReduxState } from '../../app/types';
|
||||
import JitsiMeetJS from '../../base/lib-jitsi-meet';
|
||||
import { NOTIFY_CLICK_MODE } from '../../toolbox/constants';
|
||||
|
||||
import { IConfig, IDeeplinkingConfig, IDeeplinkingMobileConfig, IDeeplinkingPlatformConfig } from './configType';
|
||||
import {
|
||||
IConfig,
|
||||
IDeeplinkingConfig,
|
||||
IDeeplinkingMobileConfig,
|
||||
IDeeplinkingPlatformConfig,
|
||||
NotifyClickButton
|
||||
} from './configType';
|
||||
import { TOOLBAR_BUTTONS } from './constants';
|
||||
|
||||
export * from './functions.any';
|
||||
@@ -120,14 +127,21 @@ export function _setDeeplinkingDefaults(deeplinking: IDeeplinkingConfig) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of buttons that have that notify the api when clicked.
|
||||
* Common logic to gather buttons that have to notify the api when clicked.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Array} - The list of buttons.
|
||||
* @param {Array} buttonsWithNotifyClick - The array of systme buttons that need to notify the api.
|
||||
* @param {Array} customButtons - The custom buttons.
|
||||
* @returns {Array}
|
||||
*/
|
||||
export function getButtonsWithNotifyClick(state: IReduxState): Array<{ key: string; preventExecution: boolean; }> {
|
||||
const { buttonsWithNotifyClick, customToolbarButtons } = state['features/base/config'];
|
||||
const customButtons = customToolbarButtons?.map(({ id }) => {
|
||||
const buildButtonsArray = (
|
||||
buttonsWithNotifyClick?: NotifyClickButton[],
|
||||
customButtons?: {
|
||||
icon: string;
|
||||
id: string;
|
||||
text: string;
|
||||
}[]
|
||||
): NotifyClickButton[] => {
|
||||
const customButtonsWithNotifyClick = customButtons?.map(({ id }) => {
|
||||
return {
|
||||
key: id,
|
||||
preventExecution: false
|
||||
@@ -135,13 +149,69 @@ export function getButtonsWithNotifyClick(state: IReduxState): Array<{ key: stri
|
||||
});
|
||||
|
||||
const buttons = Array.isArray(buttonsWithNotifyClick)
|
||||
? buttonsWithNotifyClick as Array<{ key: string; preventExecution: boolean; }>
|
||||
? buttonsWithNotifyClick as NotifyClickButton[]
|
||||
: [];
|
||||
|
||||
if (customButtons) {
|
||||
buttons.push(...customButtons);
|
||||
if (customButtonsWithNotifyClick) {
|
||||
buttons.push(...customButtonsWithNotifyClick);
|
||||
}
|
||||
|
||||
return buttons;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the list of toolbar buttons that have to notify the api when clicked.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Array} - The list of buttons.
|
||||
*/
|
||||
export function getButtonsWithNotifyClick(
|
||||
state: IReduxState
|
||||
): NotifyClickButton[] {
|
||||
const { buttonsWithNotifyClick, customToolbarButtons } = state['features/base/config'];
|
||||
|
||||
return buildButtonsArray(
|
||||
buttonsWithNotifyClick,
|
||||
customToolbarButtons
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of participant menu buttons that have that notify the api when clicked.
|
||||
*
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {Array} - The list of participant menu buttons.
|
||||
*/
|
||||
export function getParticipantMenuButtonsWithNotifyClick(
|
||||
state: IReduxState
|
||||
): NotifyClickButton[] {
|
||||
const { participantMenuButtonsWithNotifyClick, customParticipantMenuButtons } = state['features/base/config'];
|
||||
|
||||
return buildButtonsArray(
|
||||
participantMenuButtonsWithNotifyClick,
|
||||
customParticipantMenuButtons
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the notify mode for the specified button.
|
||||
*
|
||||
* @param {string} buttonKey - The button key.
|
||||
* @param {Array} buttonsWithNotifyClick - The buttons with notify click.
|
||||
* @returns {string|undefined}
|
||||
*/
|
||||
export const getButtonNotifyMode = (
|
||||
buttonKey: string,
|
||||
buttonsWithNotifyClick?: NotifyClickButton[]
|
||||
): string | undefined => {
|
||||
const notify = buttonsWithNotifyClick?.find(
|
||||
(btn: NotifyClickButton) =>
|
||||
(typeof btn === 'string' && btn === buttonKey) || (typeof btn === 'object' && btn.key === buttonKey)
|
||||
);
|
||||
|
||||
if (notify) {
|
||||
return typeof notify === 'string' || notify.preventExecution
|
||||
? NOTIFY_CLICK_MODE.PREVENT_AND_NOTIFY
|
||||
: NOTIFY_CLICK_MODE.ONLY_NOTIFY;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import _ from 'lodash';
|
||||
|
||||
import { IReduxState } from '../../app/types';
|
||||
import { IReduxState, IStore } from '../../app/types';
|
||||
import { conferenceLeft, conferenceWillLeave } from '../conference/actions';
|
||||
import { getCurrentConference } from '../conference/functions';
|
||||
import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet';
|
||||
import {
|
||||
appendURLParam,
|
||||
getBackendSafeRoomName
|
||||
@@ -10,8 +13,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 +199,185 @@ 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);
|
||||
|
||||
/**
|
||||
* 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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
30
react/features/base/connection/middleware.web.ts
Normal file
30
react/features/base/connection/middleware.web.ts
Normal 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);
|
||||
});
|
||||
@@ -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).
|
||||
|
||||
@@ -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')
|
||||
|
||||
3
react/features/base/icons/svg/edit.svg
Normal file
3
react/features/base/icons/svg/edit.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24">
|
||||
<path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 256 B |
@@ -25,6 +25,7 @@ export { default as IconDeviceHeadphone } from './headset.svg';
|
||||
export { default as IconDotsHorizontal } from './dots-horizontal.svg';
|
||||
export { default as IconDownload } from './download.svg';
|
||||
export { default as IconE2EE } from './e2ee.svg';
|
||||
export { default as IconEdit } from './edit.svg';
|
||||
export { default as IconEnlarge } from './enlarge.svg';
|
||||
export { default as IconEnterFullscreen } from './enter-fullscreen.svg';
|
||||
export { default as IconEnvelope } from './envelope.svg';
|
||||
|
||||
@@ -153,6 +153,13 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
|
||||
_overwriteLocalParticipant(
|
||||
store, { ...newUser,
|
||||
features: context.features });
|
||||
} else if (jwtPayload.name || jwtPayload.picture || jwtPayload.email) {
|
||||
// there are some tokens (firebase) having picture and name on the main level.
|
||||
_overwriteLocalParticipant(store, {
|
||||
avatarURL: jwtPayload.picture,
|
||||
name: jwtPayload.name,
|
||||
email: jwtPayload.email
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (typeof APP === 'undefined') {
|
||||
|
||||
@@ -3,10 +3,10 @@ export * from './functions.any';
|
||||
/**
|
||||
* Loads config.js from a specific remote server.
|
||||
*
|
||||
* @param {string} url - The URL to load.
|
||||
* @returns {Promise<Object>}
|
||||
* @param {string} _url - The URL to load.
|
||||
* @returns {Promise<IConfig>}
|
||||
*/
|
||||
export async function loadConfig(url: string) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
export async function loadConfig(_url?: string) {
|
||||
// Return "the config.js file" from the global scope - that is how the
|
||||
// Web app on both the client and the server was implemented before the
|
||||
// React Native app was even conceived.
|
||||
|
||||
@@ -337,12 +337,12 @@ export default class AbstractButton<P extends IProps, S=any> extends Component<P
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClick(e?: React.MouseEvent<HTMLElement> | GestureResponderEvent) {
|
||||
const { afterClick, handleClick, notifyMode, buttonKey } = this.props;
|
||||
_onClick(e?: React.MouseEvent | GestureResponderEvent) {
|
||||
const { afterClick, buttonKey, handleClick, notifyMode } = this.props;
|
||||
|
||||
if (typeof APP !== 'undefined' && notifyMode) {
|
||||
APP.API.notifyToolbarButtonClicked(
|
||||
buttonKey, notifyMode === NOTIFY_CLICK_MODE.PREVENT_AND_NOTIFY
|
||||
buttonKey, notifyMode === NOTIFY_CLICK_MODE.PREVENT_AND_NOTIFY
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ export function createLocalTracksA(options: ITrackOptions = {}) {
|
||||
const promises = [];
|
||||
|
||||
// The following executes on React Native only at the time of this
|
||||
// writing. The effort to port Web's createInitialLocalTracksAndConnect
|
||||
// writing. The effort to port Web's createInitialLocalTracks
|
||||
// is significant and that's where the function createLocalTracksF got
|
||||
// born. I started with the idea a porting so that we could inherit the
|
||||
// ability to getUserMedia for audio only or video only if getUserMedia
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { IStore } from '../../app/types';
|
||||
import { NoiseSuppressionEffect } from '../../stream-effects/noise-suppression/NoiseSuppressionEffect';
|
||||
import { createVirtualBackgroundEffect } from '../../stream-effects/virtual-background';
|
||||
|
||||
import logger from './logger';
|
||||
@@ -12,6 +13,9 @@ import logger from './logger';
|
||||
export default function loadEffects(store: IStore): Promise<any> {
|
||||
const state = store.getState();
|
||||
const virtualBackground = state['features/virtual-background'];
|
||||
const noiseSuppression = state['features/noise-suppression'];
|
||||
const { noiseSuppression: nsOptions } = state['features/base/config'];
|
||||
|
||||
|
||||
const backgroundPromise = virtualBackground.backgroundEffectEnabled
|
||||
? createVirtualBackgroundEffect(virtualBackground)
|
||||
@@ -22,5 +26,9 @@ export default function loadEffects(store: IStore): Promise<any> {
|
||||
})
|
||||
: Promise.resolve();
|
||||
|
||||
return Promise.all([ backgroundPromise ]);
|
||||
const noiseSuppressionPromise = noiseSuppression?.enabled
|
||||
? Promise.resolve(new NoiseSuppressionEffect(nsOptions))
|
||||
: Promise.resolve();
|
||||
|
||||
return Promise.all([ backgroundPromise, noiseSuppressionPromise ]);
|
||||
}
|
||||
|
||||
@@ -170,13 +170,13 @@ const BaseDialog = ({
|
||||
if (e.key === 'Enter' && !disableEnter) {
|
||||
submit?.();
|
||||
}
|
||||
}, []);
|
||||
}, [ disableEnter, onClose, submit ]);
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('keydown', handleKeyDown);
|
||||
|
||||
return () => window.removeEventListener('keydown', handleKeyDown);
|
||||
}, []);
|
||||
}, [ handleKeyDown ]);
|
||||
|
||||
return (
|
||||
<div className = { cx(classes.container, isUnmounting && 'unmount') }>
|
||||
|
||||
@@ -77,6 +77,25 @@ export function closeBreakoutRoom(roomId: string) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to rename a breakout room.
|
||||
*
|
||||
* @param {string} breakoutRoomJid - The jid of the breakout room to rename.
|
||||
* @param {string} name - New name / subject for the breakout room.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function renameBreakoutRoom(breakoutRoomJid: string, name = '') {
|
||||
return (_dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const trimmedName = name.trim();
|
||||
|
||||
if (trimmedName.length !== 0) {
|
||||
sendAnalytics(createBreakoutRoomsEvent('rename'));
|
||||
getCurrentConference(getState)?.getBreakoutRooms()
|
||||
?.renameBreakoutRoom(breakoutRoomJid, trimmedName);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Action to remove a breakout room.
|
||||
*
|
||||
|
||||
@@ -2,3 +2,8 @@
|
||||
* Key for this feature.
|
||||
*/
|
||||
export const FEATURE_KEY = 'features/breakout-rooms';
|
||||
|
||||
/**
|
||||
* Feature to rename breakout rooms.
|
||||
*/
|
||||
export const BREAKOUT_ROOMS_RENAME_FEATURE = 'rename';
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
import { Component } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
|
||||
import { IReduxState, IStore } from '../../app/types';
|
||||
import { getLocalParticipant } from '../../base/participants/functions';
|
||||
import { sendMessage, setIsPollsTabFocused } from '../actions';
|
||||
import { SMALL_WIDTH_THRESHOLD } from '../constants';
|
||||
import { IMessage } from '../reducer';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@code AbstractChat}.
|
||||
*/
|
||||
export interface IProps extends WithTranslation {
|
||||
|
||||
/**
|
||||
* Whether the chat is opened in a modal or not (computed based on window width).
|
||||
*/
|
||||
_isModal: boolean;
|
||||
|
||||
/**
|
||||
* True if the chat window should be rendered.
|
||||
*/
|
||||
_isOpen: boolean;
|
||||
|
||||
/**
|
||||
* True if the polls feature is enabled.
|
||||
*/
|
||||
_isPollsEnabled: boolean;
|
||||
|
||||
/**
|
||||
* Whether the poll tab is focused or not.
|
||||
*/
|
||||
_isPollsTabFocused: boolean;
|
||||
|
||||
/**
|
||||
* All the chat messages in the conference.
|
||||
*/
|
||||
_messages: IMessage[];
|
||||
|
||||
/**
|
||||
* Number of unread chat messages.
|
||||
*/
|
||||
_nbUnreadMessages: number;
|
||||
|
||||
/**
|
||||
* Number of unread poll messages.
|
||||
*/
|
||||
_nbUnreadPolls: number;
|
||||
|
||||
/**
|
||||
* Function to send a text message.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
_onSendMessage: Function;
|
||||
|
||||
/**
|
||||
* Function to toggle the chat window.
|
||||
*/
|
||||
_onToggleChat: Function;
|
||||
|
||||
/**
|
||||
* Function to display the chat tab.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
_onToggleChatTab: Function;
|
||||
|
||||
/**
|
||||
* Function to display the polls tab.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
_onTogglePollsTab: Function;
|
||||
|
||||
/**
|
||||
* Whether or not to block chat access with a nickname input form.
|
||||
*/
|
||||
_showNamePrompt: boolean;
|
||||
|
||||
/**
|
||||
* The Redux dispatch function.
|
||||
*/
|
||||
dispatch: IStore['dispatch'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements an abstract chat panel.
|
||||
*/
|
||||
export default class AbstractChat<P extends IProps> extends Component<P> {
|
||||
|
||||
/**
|
||||
* Initializes a new {@code AbstractChat} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* the new {@code AbstractChat} instance with.
|
||||
*/
|
||||
constructor(props: P) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onSendMessage = this._onSendMessage.bind(this);
|
||||
this._onToggleChatTab = this._onToggleChatTab.bind(this);
|
||||
this._onTogglePollsTab = this._onTogglePollsTab.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a text message.
|
||||
*
|
||||
* @private
|
||||
* @param {string} text - The text message to be sent.
|
||||
* @returns {void}
|
||||
* @type {Function}
|
||||
*/
|
||||
_onSendMessage(text: string) {
|
||||
this.props.dispatch(sendMessage(text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the Chat tab.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onToggleChatTab() {
|
||||
this.props.dispatch(setIsPollsTabFocused(false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the Polls tab.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onTogglePollsTab() {
|
||||
this.props.dispatch(setIsPollsTabFocused(true));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps (parts of) the redux state to {@link Chat} React {@code Component}
|
||||
* props.
|
||||
*
|
||||
* @param {Object} state - The redux store/state.
|
||||
* @param {any} _ownProps - Components' own props.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _isOpen: boolean,
|
||||
* _messages: Array<Object>,
|
||||
* _showNamePrompt: boolean
|
||||
* }}
|
||||
*/
|
||||
export function _mapStateToProps(state: IReduxState, _ownProps: any) {
|
||||
const { isOpen, isPollsTabFocused, messages, nbUnreadMessages } = state['features/chat'];
|
||||
const { nbUnreadPolls } = state['features/polls'];
|
||||
const _localParticipant = getLocalParticipant(state);
|
||||
const { disablePolls } = state['features/base/config'];
|
||||
|
||||
return {
|
||||
_isModal: window.innerWidth <= SMALL_WIDTH_THRESHOLD,
|
||||
_isOpen: isOpen,
|
||||
_isPollsEnabled: !disablePolls,
|
||||
_isPollsTabFocused: isPollsTabFocused,
|
||||
_messages: messages,
|
||||
_nbUnreadMessages: nbUnreadMessages,
|
||||
_nbUnreadPolls: nbUnreadPolls,
|
||||
_showNamePrompt: !_localParticipant?.name
|
||||
};
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
import { PureComponent } from 'react';
|
||||
import { WithTranslation } from 'react-i18next';
|
||||
|
||||
import { getLocalizedDateFormatter } from '../../base/i18n/dateUtil';
|
||||
import { MESSAGE_TYPE_ERROR, MESSAGE_TYPE_LOCAL } from '../constants';
|
||||
import { IMessage } from '../reducer';
|
||||
|
||||
/**
|
||||
* Formatter string to display the message timestamp.
|
||||
*/
|
||||
const TIMESTAMP_FORMAT = 'H:mm';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@code AbstractChatMessage}.
|
||||
*/
|
||||
export interface IProps extends WithTranslation {
|
||||
|
||||
/**
|
||||
* Whether current participant is currently knocking in the lobby room.
|
||||
*/
|
||||
knocking: boolean;
|
||||
|
||||
/**
|
||||
* The representation of a chat message.
|
||||
*/
|
||||
message: IMessage;
|
||||
|
||||
/**
|
||||
* Whether or not the avatar image of the participant which sent the message
|
||||
* should be displayed.
|
||||
*/
|
||||
showAvatar?: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the name of the participant which sent the message should
|
||||
* be displayed.
|
||||
*/
|
||||
showDisplayName: boolean;
|
||||
|
||||
/**
|
||||
* Whether or not the time at which the message was sent should be
|
||||
* displayed.
|
||||
*/
|
||||
showTimestamp: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract component to display a chat message.
|
||||
*/
|
||||
export default class AbstractChatMessage<P extends IProps> extends PureComponent<P> {
|
||||
/**
|
||||
* Returns the timestamp to display for the message.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_getFormattedTimestamp() {
|
||||
return getLocalizedDateFormatter(new Date(this.props.message.timestamp))
|
||||
.format(TIMESTAMP_FORMAT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the message text to be rendered in the component.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_getMessageText() {
|
||||
const { message } = this.props;
|
||||
|
||||
return message.messageType === MESSAGE_TYPE_ERROR
|
||||
? this.props.t('chat.error', {
|
||||
error: message.message
|
||||
})
|
||||
: message.message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the message that is displayed as a notice for private messages.
|
||||
*
|
||||
* @returns {string}
|
||||
*/
|
||||
_getPrivateNoticeMessage() {
|
||||
const { message, t } = this.props;
|
||||
|
||||
return t('chat.privateNotice', {
|
||||
recipient: message.messageType === MESSAGE_TYPE_LOCAL ? message.recipient : t('chat.you')
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component } from 'react';
|
||||
|
||||
import { IMessage } from '../reducer';
|
||||
import { IMessage } from '../types';
|
||||
|
||||
export interface IProps {
|
||||
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
/* eslint-disable react/no-multi-comp */
|
||||
import { Route, useIsFocused } from '@react-navigation/native';
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { Component, useEffect } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IReduxState } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import JitsiScreen from '../../../base/modal/components/JitsiScreen';
|
||||
import { TabBarLabelCounter } from '../../../mobile/navigation/components/TabBarLabelCounter';
|
||||
import { closeChat } from '../../actions.native';
|
||||
import AbstractChat, {
|
||||
IProps as AbstractProps,
|
||||
_mapStateToProps
|
||||
} from '../AbstractChat';
|
||||
import { closeChat, sendMessage } from '../../actions.native';
|
||||
import { IChatProps as AbstractProps } from '../../types';
|
||||
|
||||
import ChatInputBar from './ChatInputBar';
|
||||
import MessageContainer from './MessageContainer';
|
||||
@@ -34,7 +32,21 @@ interface IProps extends AbstractProps {
|
||||
* Implements a React native component that renders the chat window (modal) of
|
||||
* the mobile client.
|
||||
*/
|
||||
class Chat extends AbstractChat<IProps> {
|
||||
class Chat extends Component<IProps> {
|
||||
|
||||
/**
|
||||
* Initializes a new {@code AbstractChat} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* the new {@code AbstractChat} instance with.
|
||||
*/
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onSendMessage = this._onSendMessage.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
@@ -57,6 +69,39 @@ class Chat extends AbstractChat<IProps> {
|
||||
</JitsiScreen>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a text message.
|
||||
*
|
||||
* @private
|
||||
* @param {string} text - The text message to be sent.
|
||||
* @returns {void}
|
||||
* @type {Function}
|
||||
*/
|
||||
_onSendMessage(text: string) {
|
||||
this.props.dispatch(sendMessage(text));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps (parts of) the redux state to {@link Chat} React {@code Component}
|
||||
* props.
|
||||
*
|
||||
* @param {Object} state - The redux store/state.
|
||||
* @param {any} _ownProps - Components' own props.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _messages: Array<Object>,
|
||||
* _nbUnreadMessages: number
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state: IReduxState, _ownProps: any) {
|
||||
const { messages, nbUnreadMessages } = state['features/chat'];
|
||||
|
||||
return {
|
||||
_messages: messages,
|
||||
_nbUnreadMessages: nbUnreadMessages
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)((props: IProps) => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React from 'react';
|
||||
import React, { Component } from 'react';
|
||||
import { Text, View, ViewStyle } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
@@ -8,8 +8,13 @@ import { translate } from '../../../base/i18n/functions';
|
||||
import Linkify from '../../../base/react/components/native/Linkify';
|
||||
import { isGifMessage } from '../../../gifs/functions.native';
|
||||
import { MESSAGE_TYPE_ERROR, MESSAGE_TYPE_LOCAL } from '../../constants';
|
||||
import { replaceNonUnicodeEmojis } from '../../functions';
|
||||
import AbstractChatMessage, { IProps } from '../AbstractChatMessage';
|
||||
import {
|
||||
getFormattedTimestamp,
|
||||
getMessageText,
|
||||
getPrivateNoticeMessage,
|
||||
replaceNonUnicodeEmojis
|
||||
} from '../../functions';
|
||||
import { IChatMessageProps } from '../../types';
|
||||
|
||||
import GifMessage from './GifMessage';
|
||||
import PrivateMessageButton from './PrivateMessageButton';
|
||||
@@ -19,7 +24,7 @@ import styles from './styles';
|
||||
/**
|
||||
* Renders a single chat message.
|
||||
*/
|
||||
class ChatMessage extends AbstractChatMessage<IProps> {
|
||||
class ChatMessage extends Component<IChatMessageProps> {
|
||||
/**
|
||||
* Implements {@code Component#render}.
|
||||
*
|
||||
@@ -67,7 +72,7 @@ class ChatMessage extends AbstractChatMessage<IProps> {
|
||||
messageBubbleStyle.push(styles.lobbyMessageBubble);
|
||||
}
|
||||
|
||||
const messageText = replaceNonUnicodeEmojis(this._getMessageText());
|
||||
const messageText = replaceNonUnicodeEmojis(getMessageText(this.props.message));
|
||||
|
||||
return (
|
||||
<View style = { styles.messageWrapper as ViewStyle } >
|
||||
@@ -147,7 +152,7 @@ class ChatMessage extends AbstractChatMessage<IProps> {
|
||||
|
||||
return (
|
||||
<Text style = { message.lobbyChat ? styles.lobbyMsgNotice : styles.privateNotice }>
|
||||
{ this._getPrivateNoticeMessage() }
|
||||
{ getPrivateNoticeMessage(this.props.message) }
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
@@ -189,7 +194,7 @@ class ChatMessage extends AbstractChatMessage<IProps> {
|
||||
|
||||
return (
|
||||
<Text style = { styles.timeText }>
|
||||
{ this._getFormattedTimestamp() }
|
||||
{ getFormattedTimestamp(this.props.message) }
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { Component } from 'react';
|
||||
import { FlatList } from 'react-native';
|
||||
|
||||
import { MESSAGE_TYPE_LOCAL, MESSAGE_TYPE_REMOTE } from '../../constants';
|
||||
import { IMessage } from '../../reducer';
|
||||
import { IMessage } from '../../types';
|
||||
|
||||
import ChatMessage from './ChatMessage';
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { FlatList, Text, TextStyle, View, ViewStyle } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { IMessage } from '../../reducer';
|
||||
import { IMessage } from '../../types';
|
||||
import AbstractMessageContainer, { IProps as AbstractProps } from '../AbstractMessageContainer';
|
||||
|
||||
import ChatMessageGroup from './ChatMessageGroup';
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
import React, { useCallback } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { makeStyles } from 'tss-react/mui';
|
||||
|
||||
import { IReduxState } from '../../../app/types';
|
||||
import { translate } from '../../../base/i18n/functions';
|
||||
import { getLocalParticipant } from '../../../base/participants/functions';
|
||||
import { withPixelLineHeight } from '../../../base/styles/functions.web';
|
||||
import Tabs from '../../../base/ui/components/web/Tabs';
|
||||
import PollsPane from '../../../polls/components/web/PollsPane';
|
||||
import { toggleChat } from '../../actions.web';
|
||||
import { CHAT_TABS } from '../../constants';
|
||||
import AbstractChat, {
|
||||
IProps,
|
||||
_mapStateToProps
|
||||
} from '../AbstractChat';
|
||||
import { sendMessage, setIsPollsTabFocused, toggleChat } from '../../actions.web';
|
||||
import { CHAT_SIZE, CHAT_TABS, SMALL_WIDTH_THRESHOLD } from '../../constants';
|
||||
import { IChatProps as AbstractProps } from '../../types';
|
||||
|
||||
import ChatHeader from './ChatHeader';
|
||||
import ChatInput from './ChatInput';
|
||||
@@ -19,75 +19,167 @@ import KeyboardAvoider from './KeyboardAvoider';
|
||||
import MessageContainer from './MessageContainer';
|
||||
import MessageRecipient from './MessageRecipient';
|
||||
|
||||
/**
|
||||
* React Component for holding the chat feature in a side panel that slides in
|
||||
* and out of view.
|
||||
*/
|
||||
class Chat extends AbstractChat<IProps> {
|
||||
interface IProps extends AbstractProps {
|
||||
|
||||
/**
|
||||
* Reference to the React Component for displaying chat messages. Used for
|
||||
* scrolling to the end of the chat messages.
|
||||
* Whether the chat is opened in a modal or not (computed based on window width).
|
||||
*/
|
||||
_messageContainerRef: Object;
|
||||
_isModal: boolean;
|
||||
|
||||
/**
|
||||
* Initializes a new {@code Chat} instance.
|
||||
* True if the chat window should be rendered.
|
||||
*/
|
||||
_isOpen: boolean;
|
||||
|
||||
/**
|
||||
* True if the polls feature is enabled.
|
||||
*/
|
||||
_isPollsEnabled: boolean;
|
||||
|
||||
/**
|
||||
* Whether the poll tab is focused or not.
|
||||
*/
|
||||
_isPollsTabFocused: boolean;
|
||||
|
||||
/**
|
||||
* Number of unread poll messages.
|
||||
*/
|
||||
_nbUnreadPolls: number;
|
||||
|
||||
/**
|
||||
* Function to send a text message.
|
||||
*
|
||||
* @param {Object} props - The read-only properties with which the new
|
||||
* instance is to be initialized.
|
||||
* @protected
|
||||
*/
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
||||
this._messageContainerRef = React.createRef();
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
this._onChatTabKeyDown = this._onChatTabKeyDown.bind(this);
|
||||
this._onEscClick = this._onEscClick.bind(this);
|
||||
this._onPollsTabKeyDown = this._onPollsTabKeyDown.bind(this);
|
||||
this._onToggleChat = this._onToggleChat.bind(this);
|
||||
this._onChangeTab = this._onChangeTab.bind(this);
|
||||
}
|
||||
_onSendMessage: Function;
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
* Function to toggle the chat window.
|
||||
*/
|
||||
render() {
|
||||
const { _isOpen, _isPollsEnabled, _showNamePrompt } = this.props;
|
||||
|
||||
return (
|
||||
_isOpen ? <div
|
||||
className = 'sideToolbarContainer'
|
||||
id = 'sideToolbarContainer'
|
||||
onKeyDown = { this._onEscClick } >
|
||||
<ChatHeader
|
||||
className = 'chat-header'
|
||||
isPollsEnabled = { _isPollsEnabled }
|
||||
onCancel = { this._onToggleChat } />
|
||||
{ _showNamePrompt
|
||||
? <DisplayNameForm isPollsEnabled = { _isPollsEnabled } />
|
||||
: this._renderChat() }
|
||||
</div> : null
|
||||
);
|
||||
}
|
||||
_onToggleChat: Function;
|
||||
|
||||
/**
|
||||
* Key press handler for the chat tab.
|
||||
* Function to display the chat tab.
|
||||
*
|
||||
* @param {KeyboardEvent} event - The event.
|
||||
* @returns {void}
|
||||
* @protected
|
||||
*/
|
||||
_onChatTabKeyDown(event: React.KeyboardEvent) {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this._onToggleChatTab();
|
||||
_onToggleChatTab: Function;
|
||||
|
||||
/**
|
||||
* Function to display the polls tab.
|
||||
*
|
||||
* @protected
|
||||
*/
|
||||
_onTogglePollsTab: Function;
|
||||
|
||||
/**
|
||||
* Whether or not to block chat access with a nickname input form.
|
||||
*/
|
||||
_showNamePrompt: boolean;
|
||||
}
|
||||
|
||||
const useStyles = makeStyles()(theme => {
|
||||
return {
|
||||
container: {
|
||||
backgroundColor: theme.palette.ui01,
|
||||
flexShrink: 0,
|
||||
overflow: 'hidden',
|
||||
position: 'relative',
|
||||
transition: 'width .16s ease-in-out',
|
||||
width: `${CHAT_SIZE}px`,
|
||||
zIndex: 300,
|
||||
|
||||
'@media (max-width: 580px)': {
|
||||
height: '100vh',
|
||||
position: 'fixed',
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 0,
|
||||
width: 'auto'
|
||||
},
|
||||
|
||||
'*': {
|
||||
userSelect: 'text',
|
||||
'-webkit-user-select': 'text'
|
||||
}
|
||||
},
|
||||
|
||||
chatHeader: {
|
||||
height: '60px',
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
zIndex: 1,
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
padding: `${theme.spacing(3)} ${theme.spacing(4)}`,
|
||||
alignItems: 'center',
|
||||
boxSizing: 'border-box',
|
||||
color: theme.palette.text01,
|
||||
...withPixelLineHeight(theme.typography.heading6),
|
||||
|
||||
'.jitsi-icon': {
|
||||
cursor: 'pointer'
|
||||
}
|
||||
},
|
||||
|
||||
chatPanel: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
||||
// extract header + tabs height
|
||||
height: 'calc(100% - 110px)'
|
||||
},
|
||||
|
||||
chatPanelNoTabs: {
|
||||
// extract header height
|
||||
height: 'calc(100% - 60px)'
|
||||
},
|
||||
|
||||
pollsPanel: {
|
||||
// extract header + tabs height
|
||||
height: 'calc(100% - 110px)'
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
const Chat = ({
|
||||
_isModal,
|
||||
_isOpen,
|
||||
_isPollsEnabled,
|
||||
_isPollsTabFocused,
|
||||
_messages,
|
||||
_nbUnreadMessages,
|
||||
_nbUnreadPolls,
|
||||
_onSendMessage,
|
||||
_onToggleChat,
|
||||
_onToggleChatTab,
|
||||
_onTogglePollsTab,
|
||||
_showNamePrompt,
|
||||
dispatch,
|
||||
t
|
||||
}: IProps) => {
|
||||
const { classes, cx } = useStyles();
|
||||
|
||||
/**
|
||||
* Sends a text message.
|
||||
*
|
||||
* @private
|
||||
* @param {string} text - The text message to be sent.
|
||||
* @returns {void}
|
||||
* @type {Function}
|
||||
*/
|
||||
const onSendMessage = useCallback((text: string) => {
|
||||
dispatch(sendMessage(text));
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Toggles the chat window.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
const onToggleChat = useCallback(() => {
|
||||
dispatch(toggleChat());
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Click handler for the chat sidenav.
|
||||
@@ -95,27 +187,23 @@ class Chat extends AbstractChat<IProps> {
|
||||
* @param {KeyboardEvent} event - Esc key click to close the popup.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onEscClick(event: React.KeyboardEvent) {
|
||||
if (event.key === 'Escape' && this.props._isOpen) {
|
||||
const onEscClick = useCallback((event: React.KeyboardEvent) => {
|
||||
if (event.key === 'Escape' && _isOpen) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this._onToggleChat();
|
||||
onToggleChat();
|
||||
}
|
||||
}
|
||||
}, [ _isOpen ]);
|
||||
|
||||
/**
|
||||
* Key press handler for the polls tab.
|
||||
* Change selected tab.
|
||||
*
|
||||
* @param {KeyboardEvent} event - The event.
|
||||
* @param {string} id - Id of the clicked tab.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onPollsTabKeyDown(event: React.KeyboardEvent) {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
this._onTogglePollsTab();
|
||||
}
|
||||
}
|
||||
const onChangeTab = useCallback((id: string) => {
|
||||
dispatch(setIsPollsTabFocused(id !== CHAT_TABS.CHAT));
|
||||
}, []);
|
||||
|
||||
/**
|
||||
* Returns a React Element for showing chat messages and a form to send new
|
||||
@@ -124,33 +212,31 @@ class Chat extends AbstractChat<IProps> {
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderChat() {
|
||||
const { _isPollsEnabled, _isPollsTabFocused } = this.props;
|
||||
|
||||
function renderChat() {
|
||||
return (
|
||||
<>
|
||||
{ _isPollsEnabled && this._renderTabs() }
|
||||
{_isPollsEnabled && renderTabs()}
|
||||
<div
|
||||
aria-labelledby = { CHAT_TABS.CHAT }
|
||||
className = { clsx(
|
||||
'chat-panel',
|
||||
!_isPollsEnabled && 'chat-panel-no-tabs',
|
||||
className = { cx(
|
||||
classes.chatPanel,
|
||||
!_isPollsEnabled && classes.chatPanelNoTabs,
|
||||
_isPollsTabFocused && 'hide'
|
||||
) }
|
||||
id = { `${CHAT_TABS.CHAT}-panel` }
|
||||
role = 'tabpanel'
|
||||
tabIndex = { 0 }>
|
||||
<MessageContainer
|
||||
messages = { this.props._messages } />
|
||||
messages = { _messages } />
|
||||
<MessageRecipient />
|
||||
<ChatInput
|
||||
onSend = { this._onSendMessage } />
|
||||
onSend = { onSendMessage } />
|
||||
</div>
|
||||
{ _isPollsEnabled && (
|
||||
{_isPollsEnabled && (
|
||||
<>
|
||||
<div
|
||||
aria-labelledby = { CHAT_TABS.POLLS }
|
||||
className = { clsx('polls-panel', !_isPollsTabFocused && 'hide') }
|
||||
className = { cx(classes.pollsPanel, !_isPollsTabFocused && 'hide') }
|
||||
id = { `${CHAT_TABS.POLLS}-panel` }
|
||||
role = 'tabpanel'
|
||||
tabIndex = { 0 }>
|
||||
@@ -169,13 +255,11 @@ class Chat extends AbstractChat<IProps> {
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderTabs() {
|
||||
const { _isPollsEnabled, _isPollsTabFocused, _nbUnreadMessages, _nbUnreadPolls, t } = this.props;
|
||||
|
||||
function renderTabs() {
|
||||
return (
|
||||
<Tabs
|
||||
accessibilityLabel = { t(_isPollsEnabled ? 'chat.titleWithPolls' : 'chat.title') }
|
||||
onChange = { this._onChangeTab }
|
||||
onChange = { onChangeTab }
|
||||
selected = { _isPollsTabFocused ? CHAT_TABS.POLLS : CHAT_TABS.CHAT }
|
||||
tabs = { [ {
|
||||
accessibilityLabel: t('chat.tabs.chat'),
|
||||
@@ -194,24 +278,56 @@ class Chat extends AbstractChat<IProps> {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the chat window.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
_onToggleChat() {
|
||||
this.props.dispatch(toggleChat());
|
||||
}
|
||||
return (
|
||||
_isOpen ? <div
|
||||
className = { classes.container }
|
||||
id = 'sideToolbarContainer'
|
||||
onKeyDown = { onEscClick } >
|
||||
<ChatHeader
|
||||
className = { cx('chat-header', classes.chatHeader) }
|
||||
isPollsEnabled = { _isPollsEnabled }
|
||||
onCancel = { onToggleChat } />
|
||||
{_showNamePrompt
|
||||
? <DisplayNameForm isPollsEnabled = { _isPollsEnabled } />
|
||||
: renderChat()}
|
||||
</div> : null
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Change selected tab.
|
||||
*
|
||||
* @param {string} id - Id of the clicked tab.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onChangeTab(id: string) {
|
||||
id === CHAT_TABS.CHAT ? this._onToggleChatTab() : this._onTogglePollsTab();
|
||||
}
|
||||
/**
|
||||
* Maps (parts of) the redux state to {@link Chat} React {@code Component}
|
||||
* props.
|
||||
*
|
||||
* @param {Object} state - The redux store/state.
|
||||
* @param {any} _ownProps - Components' own props.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _isModal: boolean,
|
||||
* _isOpen: boolean,
|
||||
* _isPollsEnabled: boolean,
|
||||
* _isPollsTabFocused: boolean,
|
||||
* _messages: Array<Object>,
|
||||
* _nbUnreadMessages: number,
|
||||
* _nbUnreadPolls: number,
|
||||
* _showNamePrompt: boolean
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state: IReduxState, _ownProps: any) {
|
||||
const { isOpen, isPollsTabFocused, messages, nbUnreadMessages } = state['features/chat'];
|
||||
const { nbUnreadPolls } = state['features/polls'];
|
||||
const _localParticipant = getLocalParticipant(state);
|
||||
const { disablePolls } = state['features/base/config'];
|
||||
|
||||
return {
|
||||
_isModal: window.innerWidth <= SMALL_WIDTH_THRESHOLD,
|
||||
_isOpen: isOpen,
|
||||
_isPollsEnabled: !disablePolls,
|
||||
_isPollsTabFocused: isPollsTabFocused,
|
||||
_messages: messages,
|
||||
_nbUnreadMessages: nbUnreadMessages,
|
||||
_nbUnreadPolls: nbUnreadPolls,
|
||||
_showNamePrompt: !_localParticipant?.name
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(Chat));
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user