Compare commits

..

1 Commits

Author SHA1 Message Date
Saúl Ibarra Corretgé
d2521bc67a feat(android) bump minimum API level to 24
Some of our dependencies (most notably WebRTC) have dropped it and we
can no longer claim to support API level 23).
2023-05-01 11:06:44 +02:00
499 changed files with 6122 additions and 8057 deletions

View File

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

16
.github/stale.yml vendored Normal file
View File

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

View File

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

View File

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

5
.gitignore vendored
View File

@@ -61,9 +61,8 @@ buck-out/
# fastlane
#
**/fastlane/report.xml
**/fastlane/Preview.html
**/fastlane/test_output
*/fastlane/report.xml
*/fastlane/Preview.html
# Build artifacts
*.jsbundle

View File

@@ -16,8 +16,7 @@
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleInstance"
android:taskAffinity=""
android:launchMode="singleTask"
android:name=".MainActivity"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -87,7 +87,6 @@ import {
} from './react/features/base/lib-jitsi-meet';
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
import {
gumPending,
setAudioAvailable,
setAudioMuted,
setAudioUnmutePermissions,
@@ -101,7 +100,6 @@ import {
getStartWithVideoMuted,
isVideoMutedByUser
} from './react/features/base/media/functions';
import { IGUMPendingState } from './react/features/base/media/types';
import {
dominantSpeakerChanged,
localParticipantAudioLevelChanged,
@@ -363,11 +361,11 @@ class ConferenceConnector {
const [ vnode ] = params;
APP.store.dispatch(overwriteConfig(newConfig))
.then(() => this._conference.leaveRoom())
.then(() => APP.store.dispatch(setIAmVisitor(Boolean(vnode))))
.then(this._conference.leaveRoom())
.then(APP.store.dispatch(setIAmVisitor(Boolean(vnode))))
// we do not clear local tracks on error, so we need to manually clear them
.then(() => APP.store.dispatch(destroyLocalTracks()))
.then(APP.store.dispatch(destroyLocalTracks()))
.then(() => {
// Reset VideoLayout. It's destroyed in features/video-layout/middleware.web.js so re-initialize it.
VideoLayout.initLargeVideo();
@@ -420,7 +418,7 @@ class ConferenceConnector {
if (newConfig) {
APP.store.dispatch(overwriteConfig(newConfig))
.then(() => this._conference.leaveRoom())
.then(this._conference.leaveRoom())
.then(() => {
_connectionPromise = connect(this._conference.roomName);
@@ -495,21 +493,6 @@ function disconnect() {
return connection.disconnect().then(onDisconnected, onDisconnected);
}
/**
* Sets the GUM pending state for the tracks that have failed.
*
* NOTE: Some of the track that we will be setting to GUM pending state NONE may not have failed but they may have
* been requested. This won't be a problem because their current GUM pending state will be NONE anyway.
* @param {JitsiLocalTrack} tracks - The tracks that have been created.
* @returns {void}
*/
function setGUMPendingStateOnFailedTracks(tracks) {
const tracksTypes = tracks.map(track => track.getType());
const nonPendingTracks = [ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ].filter(type => !tracksTypes.includes(type));
APP.store.dispatch(gumPending(nonPendingTracks, IGUMPendingState.NONE));
}
/**
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
*
@@ -576,7 +559,7 @@ export default {
);
}
let tryCreateLocalTracks = Promise.resolve([]);
let tryCreateLocalTracks;
// On Electron there is no permission prompt for granting permissions. That's why we don't need to
// spend much time displaying the overlay screen. If GUM is not resolved within 15 seconds it will
@@ -617,66 +600,76 @@ export default {
return [];
});
} else if (requestedAudio || requestedVideo) {
APP.store.dispatch(gumPending(initialDevices, IGUMPendingState.PENDING_UNMUTE));
} else if (!requestedAudio && !requestedVideo) {
// Resolve with no tracks
tryCreateLocalTracks = Promise.resolve([]);
} else {
tryCreateLocalTracks = createLocalTracksF({
devices: initialDevices,
timeout,
firePermissionPromptIsShownEvent: true
})
.catch(async error => {
if (error.name === JitsiTrackErrors.TIMEOUT && !browser.isElectron()) {
errors.audioAndVideoError = error;
.catch(err => {
if (requestedAudio && requestedVideo) {
// Try audio only...
errors.audioAndVideoError = err;
if (err.name === JitsiTrackErrors.TIMEOUT && !browser.isElectron()) {
// In this case we expect that the permission prompt is still visible. There is no point of
// executing GUM with different source. Also at the time of writing the following
// inconsistency have been noticed in some browsers - if the permissions prompt is visible
// and another GUM is executed the prompt does not change its content but if the user
// clicks allow the user action isassociated with the latest GUM call.
errors.audioOnlyError = err;
errors.videoOnlyError = err;
return [];
}
return createLocalTracksF(audioOptions);
} else if (requestedAudio && !requestedVideo) {
errors.audioOnlyError = err;
return [];
} else if (requestedVideo && !requestedAudio) {
errors.videoOnlyError = err;
return [];
}
logger.error('Should never happen');
})
.catch(err => {
// Log this just in case...
if (!requestedAudio) {
logger.error('The impossible just happened', err);
}
errors.audioOnlyError = err;
// Try video only...
return requestedVideo
? createLocalTracksF({
devices: [ MEDIA_TYPE.VIDEO ],
firePermissionPromptIsShownEvent: true
})
: [];
})
.catch(err => {
// Log this just in case...
if (!requestedVideo) {
logger.error('The impossible just happened', err);
}
errors.videoOnlyError = err;
return [];
}
// Retry with separate gUM calls.
const gUMPromises = [];
const tracks = [];
if (requestedAudio) {
gUMPromises.push(createLocalTracksF(audioOptions));
}
if (requestedVideo) {
gUMPromises.push(createLocalTracksF({
devices: [ MEDIA_TYPE.VIDEO ],
timeout,
firePermissionPromptIsShownEvent: true
}));
}
const results = await Promise.allSettled(gUMPromises);
let errorMsg;
results.forEach((result, idx) => {
if (result.status === 'fulfilled') {
tracks.push(result.value[0]);
} else {
errorMsg = result.reason;
const isAudio = idx === 0;
logger.error(`${isAudio ? 'Audio' : 'Video'} track creation failed with error ${errorMsg}`);
if (isAudio) {
errors.audioOnlyError = errorMsg;
} else {
errors.videoOnlyError = errorMsg;
}
}
});
if (errors.audioOnlyError && errors.videoOnlyError) {
errors.audioAndVideoError = errorMsg;
}
return tracks;
});
}
// Hide the permissions prompt/overlay as soon as the tracks are created. Don't wait for the connection to
// be established, as in some cases like when auth is required, connection won't be established until the user
// inputs their credentials, but the dialog would be overshadowed by the overlay.
// Hide the permissions prompt/overlay as soon as the tracks are
// created. Don't wait for the connection to be made, since in some
// cases, when auth is required, for instance, that won't happen until
// the user inputs their credentials, but the dialog would be
// overshadowed by the overlay.
tryCreateLocalTracks.then(tracks => {
APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false));
@@ -817,51 +810,43 @@ export default {
const initialOptions = {
startAudioOnly: config.startAudioOnly,
startScreenSharing: config.startScreenSharing,
startWithAudioMuted: getStartWithAudioMuted(state) || isUserInteractionRequiredForUnmute(state),
startWithVideoMuted: getStartWithVideoMuted(state) || isUserInteractionRequiredForUnmute(state)
startWithAudioMuted: getStartWithAudioMuted(state)
|| isUserInteractionRequiredForUnmute(state),
startWithVideoMuted: getStartWithVideoMuted(state)
|| isUserInteractionRequiredForUnmute(state)
};
this.roomName = roomName;
try {
// Initialize the device list first. This way, when creating tracks based on preferred devices, loose label
// matching can be done in cases where the exact ID match is no longer available, such as -
// 1. When the camera device has switched USB ports.
// 2. When in startSilent mode we want to start with audio muted
// Initialize the device list first. This way, when creating tracks
// based on preferred devices, loose label matching can be done in
// cases where the exact ID match is no longer available, such as
// when the camera device has switched USB ports.
// when in startSilent mode we want to start with audio muted
await this._initDeviceList();
} catch (error) {
logger.warn('initial device list initialization failed', error);
}
// Filter out the local tracks based on various config options, i.e., when user joins muted or is muted by
// focus. However, audio track will always be created even though it is not added to the conference since we
// want audio related features (noisy mic, talk while muted, etc.) to work even if the mic is muted.
const handleInitialTracks = (options, tracks) => {
let localTracks = tracks;
// No local tracks are added when user joins as a visitor.
if (iAmVisitor(state)) {
return [];
}
if (options.startWithAudioMuted || room?.isStartAudioMuted()) {
const handleStartAudioMuted = (options, tracks) => {
if (options.startWithAudioMuted) {
// Always add the track on Safari because of a known issue where audio playout doesn't happen
// if the user joins audio and video muted, i.e., if there is no local media capture.
if (browser.isWebKitBased()) {
this.muteAudio(true, true);
} else {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
return tracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
}
}
if (room?.isStartVideoMuted()) {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.VIDEO);
}
return localTracks;
return tracks;
};
if (isPrejoinPageVisible(state)) {
_connectionPromise = connect(roomName).then(c => {
// We want to initialize it early, in case of errors to be able to gather logs.
// we want to initialize it early, in case of errors to be able
// to gather logs
APP.connection = c;
return c;
@@ -874,38 +859,48 @@ export default {
APP.store.dispatch(makePrecallTest(this._getConferenceOptions()));
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
const localTracks = await tryCreateLocalTracks;
const tracks = await tryCreateLocalTracks;
// Initialize device list a second time to ensure device labels get populated in case of an initial gUM
// acceptance; otherwise they may remain as empty strings.
// Initialize device list a second time to ensure device labels
// get populated in case of an initial gUM acceptance; otherwise
// they may remain as empty strings.
this._initDeviceList(true);
if (isPrejoinPageVisible(state)) {
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
return APP.store.dispatch(initPrejoin(localTracks, errors));
return APP.store.dispatch(initPrejoin(tracks, errors));
}
logger.debug('Prejoin screen no longer displayed at the time when tracks were created');
this._displayErrorsForCreateInitialLocalTracks(errors);
const tracks = handleInitialTracks(initialOptions, localTracks);
let localTracks = handleStartAudioMuted(initialOptions, tracks);
setGUMPendingStateOnFailedTracks(tracks);
// In case where gUM is slow and resolves after the startAudio/VideoMuted coming from jicofo, we can be
// join unmuted even though jicofo had instruct us to mute, so let's respect that before passing the tracks
if (!browser.isWebKitBased()) {
if (room?.isStartAudioMuted()) {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
}
}
return this._setLocalAudioVideoStreams(tracks);
if (room?.isStartVideoMuted()) {
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.VIDEO);
}
// Do not add the tracks if the user has joined the call as a visitor.
if (iAmVisitor(state)) {
return Promise.resolve();
}
return this._setLocalAudioVideoStreams(localTracks);
}
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(roomName, initialOptions);
this._initDeviceList(true);
const filteredTracks = handleInitialTracks(initialOptions, tracks);
setGUMPendingStateOnFailedTracks(filteredTracks);
return this.startConference(con, filteredTracks);
return this.startConference(con, handleStartAudioMuted(initialOptions, tracks));
},
/**
@@ -1028,7 +1023,6 @@ export default {
showUI && APP.store.dispatch(notifyMicError(error));
};
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.PENDING_UNMUTE));
createLocalTracksF({ devices: [ 'audio' ] })
.then(([ audioTrack ]) => audioTrack)
.catch(error => {
@@ -1040,10 +1034,7 @@ export default {
.then(async audioTrack => {
await this._maybeApplyAudioMixerEffect(audioTrack);
return this.useAudioStream(audioTrack);
})
.finally(() => {
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.NONE));
this.useAudioStream(audioTrack);
});
} else {
muteLocalAudio(mute);
@@ -1082,7 +1073,7 @@ export default {
*/
muteVideo(mute, showUI = true) {
if (this.videoSwitchInProgress) {
logger.warn('muteVideo - unable to perform operations while video switch is in progress');
console.warn('muteVideo - unable to perform operations while video switch is in progress');
return;
}
@@ -1123,8 +1114,6 @@ export default {
this.isCreatingLocalTrack = true;
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.PENDING_UNMUTE));
// Try to create local video if there wasn't any.
// This handles the case when user joined with no video
// (dismissed screen sharing screen or in audio only mode), but
@@ -1149,7 +1138,6 @@ export default {
})
.finally(() => {
this.isCreatingLocalTrack = false;
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
});
} else {
// FIXME show error dialog if it fails (should be handled by react)
@@ -1462,16 +1450,11 @@ export default {
* @private
*/
_setLocalAudioVideoStreams(tracks = []) {
const { dispatch } = APP.store;
const pendingGUMDevicesToRemove = [];
const promises = tracks.map(track => {
if (track.isAudioTrack()) {
pendingGUMDevicesToRemove.push(MEDIA_TYPE.AUDIO);
return this.useAudioStream(track);
} else if (track.isVideoTrack()) {
logger.debug(`_setLocalAudioVideoStreams is calling useVideoStream with track: ${track}`);
pendingGUMDevicesToRemove.push(MEDIA_TYPE.VIDEO);
return this.useVideoStream(track);
}
@@ -1483,10 +1466,6 @@ export default {
});
return Promise.allSettled(promises).then(() => {
if (pendingGUMDevicesToRemove.length > 0) {
dispatch(gumPending(pendingGUMDevicesToRemove, IGUMPendingState.NONE));
}
this._localTracksInitialized = true;
logger.log(`Initialized with ${tracks.length} local tracks`);
});
@@ -2664,22 +2643,17 @@ export default {
async leaveRoom(doDisconnect = true, reason = '') {
APP.store.dispatch(conferenceWillLeave(room));
const maybeDisconnect = () => {
if (doDisconnect) {
return disconnect();
}
};
if (room && room.isJoined()) {
return room.leave(reason).then(() => maybeDisconnect())
.catch(e => {
logger.error(e);
return maybeDisconnect();
return room.leave(reason).finally(() => {
if (doDisconnect) {
return disconnect();
}
});
}
return maybeDisconnect();
if (doDisconnect) {
return disconnect();
}
},
/**

View File

@@ -74,6 +74,10 @@
a:active {
color: black;
}
&::-webkit-scrollbar-corner {
background: #3a3a3a;
}
}

View File

@@ -32,14 +32,6 @@
pointer-events: none;
z-index: $toolbarZ + 2;
&.shift-up {
bottom: calc(((#{$newToolbarSize} + 30px) * 2) * -1);
.toolbox-content {
margin-bottom: 46px;
}
}
&.visible {
bottom: 0;
}

View File

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

View File

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

View File

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

View File

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

View File

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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

View File

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

View File

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

View File

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

View File

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

1
globals.d.ts vendored
View File

@@ -21,7 +21,6 @@ declare global {
JitsiMeetElectron?: any;
// selenium tests handler
_sharedVideoPlayer: any;
alwaysOnTop: { api: any };
}
interface Document {

1
globals.native.d.ts vendored
View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -156,7 +156,6 @@
"localport_plural": "Portas locais:",
"maxEnabledResolution": "enviar máx",
"more": "Mostrar mais",
"no": "não",
"packetloss": "Perda de pacote:",
"participant_id": "Participante id:",
"quality": {
@@ -175,8 +174,7 @@
"status": "Ligação:",
"transport": "Transporte:",
"transport_plural": "Transportes:",
"video_ssrc": "Vídeo SSRC:",
"yes": "sim"
"video_ssrc": "Vídeo SSRC:"
},
"dateUtils": {
"earlier": "Mais cedo",
@@ -321,13 +319,13 @@
"micPermissionDeniedError": "Não concedeu autorização para utilizar o seu microfone. Ainda pode participar na conferência, mas outros não o ouvirão. Use o botão da câmara na barra de endereço para corrigir isto.",
"micTimeoutError": "Não foi possível iniciar a fonte de áudio. Tempo limite expirado!",
"micUnknownError": "Não pode usar microfone por uma razão desconhecida.",
"moderationAudioLabel": "Permitir aos participantes ligar o som",
"moderationVideoLabel": "Permitir aos participantes ligar a câmara",
"muteEveryoneDialog": "Os participantes podem ligar o som a qualquer momento.",
"moderationAudioLabel": "Permitir aos participantes reativar o som",
"moderationVideoLabel": "Permitir aos participantes reativar o vídeo",
"muteEveryoneDialog": "Os participantes podem reativar o som a qualquer momento.",
"muteEveryoneDialogModerationOn": "Os participantes podem enviar um pedido para falar a qualquer momento.",
"muteEveryoneElseDialog": "Uma vez silenciados, não poderá reativá-los, mas eles podem ligar o microfone a qualquer momento.",
"muteEveryoneElseDialog": "Uma vez silenciados, não poderá reativá-los, mas eles podem reativar-se a qualquer momento.",
"muteEveryoneElseTitle": "Silenciar todos excepto {{whom}}?",
"muteEveryoneElsesVideoDialog": "Quando a câmara for desligada, não poderá voltar a ligá-la, mas eles podem voltar a ligá-la em qualquer momento.",
"muteEveryoneElsesVideoDialog": "Quando a câmara for desativada, não poderá voltar a ligá-la, mas eles podem voltar a ligá-la em qualquer momento.",
"muteEveryoneElsesVideoTitle": "Parar o vídeo de todos excepto {{whom}}?",
"muteEveryoneSelf": "você mesmo",
"muteEveryoneStartMuted": "A partir de agora, toda a gente começa a ficar calada",
@@ -675,10 +673,8 @@
"connectedTwoMembers": "{{first}} e {{second}} entraram na reunião",
"dataChannelClosed": "Deficiência na qualidade do vídeo",
"dataChannelClosedDescription": "O canal de ponte foi desconectado e, portanto, a qualidade do vídeo está limitada à sua configuração mais baixa.",
"disabledIframe": "A incorporação destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos.",
"disconnected": "desconectado",
"displayNotifications": "Mostrar notificações para",
"dontRemindMe": "Não me lembre",
"focus": "Foco da conferência",
"focusFail": "{{component}} não disponĩvel - tente em {{ms}} seg.",
"gifsMenu": "GIPHY",
@@ -758,8 +754,8 @@
"actions": {
"allow": "Permitir aos participantes:",
"allowVideo": "Permitir vídeo",
"askUnmute": "Pedir para ligar o som",
"audioModeration": "Ligar o microfone deles",
"askUnmute": "Pedir para ligar o microfone",
"audioModeration": "Ativar o microfone deles",
"blockEveryoneMicCamera": "Bloquear o microfone e a câmara de todos",
"invite": "Convidar alguém",
"moreModerationActions": "Mais opções de moderação",
@@ -870,11 +866,9 @@
"lookGood": "O seu microfone funciona corretamente",
"or": "ou",
"premeeting": "Pré-reunião",
"proceedAnyway": "Continuar na mesma",
"screenSharingError": "Erro de partilha de ecrã:",
"showScreen": "Ativar o ecrã de pré-reunião",
"startWithPhone": "Iniciar com o áudio do telefone",
"unsafeRoomConsent": "Compreendo os riscos, quero participar na reunião",
"videoOnlyError": "Erro de vídeo:",
"videoTrackError": "Não foi possível criar a pista de vídeo.",
"viewAllNumbers": "ver todos os números"
@@ -950,7 +944,7 @@
"noStreams": "Não foi detetado nenhum sinal áudio ou vídeo.",
"off": "Gravação parada",
"offBy": "{{name}} parou a gravação",
"on": "Começou a gravação",
"on": "Gravando",
"onBy": "{{name}} iniciou a gravação",
"onlyRecordSelf": "Gravar apenas as minhas transmissões áudio e vídeo",
"pending": "Preparando para gravar a reunião...",
@@ -976,14 +970,8 @@
"security": {
"about": "Pode adicionar uma $t(lockRoomPassword) à sua reunião. Os participantes terão de fornecer a $t(lockRoomPassword) antes de serem autorizados a participar na reunião.",
"aboutReadOnly": "Os participantes moderadores podem acrescentar uma $t(lockRoomPassword) à reunião. Os participantes terão de fornecer a $t(lockRoomPassword) antes de serem autorizados a participar na reunião.",
"insecureRoomNameWarningNative": "O nome da sala não é seguro. Participantes indesejados podem juntar-se à sua reunião. {{recommendAction}} Saiba mais sobre como proteger a sua reunião ",
"insecureRoomNameWarningWeb": "O nome da sala não é seguro. Participantes indesejados podem juntar-se à sua reunião. {{recommendAction}} Saiba mais sobre como proteger a sua reunião <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">here</a>.",
"title": "Opções de Segurança",
"unsafeRoomActions": {
"meeting": "Considere a possibilidade de proteger a sua reunião utilizando o botão de segurança.",
"prejoin": "Considere a utilização de um nome de reunião mais personalizado.",
"welcome": "Considere utilizar um nome de reunião mais personalizado ou selecione uma das sugestões."
}
"insecureRoomNameWarning": "O nome da sala é inseguro. Participantes indesejados podem juntar-se à sua conferência. Considere proteger a sua reunião utilizando o botão de segurança.",
"title": "Opções de segurança"
},
"settings": {
"audio": "Áudio",
@@ -1158,7 +1146,6 @@
"privateMessage": "Enviar mensagem privada",
"profile": "Editar o seu perfil",
"raiseHand": "Levantar a mão",
"reactions": "Reações",
"reactionsMenu": "Menu de reações",
"recording": "Mudar gravação",
"remoteMute": "Participante sem som",
@@ -1256,7 +1243,6 @@
"reactionLike": "Enviar reação de aprovado",
"reactionSilence": "Enviar reação de silêncio",
"reactionSurprised": "Enviar reação de surpreendido",
"reactions": "Reações",
"security": "Opções de segurança",
"selectBackground": "Selecionar plano de fundo",
"shareRoom": "Convidar alguém",
@@ -1390,14 +1376,7 @@
"webAssemblyWarning": "WebAssembly não suportado",
"webAssemblyWarningDescription": "WebAssembly desactivado ou não suportado por este navegador"
},
"visitors": {
"chatIndicator": "(visitante)",
"labelTooltip": "Número de visitantes: {{count}}",
"notification": {
"description": "Para participar levante a sua mão",
"title": "É um visitante na reunião"
}
},
"visitorsLabel": "Número de visitantes: {{count}}",
"volumeSlider": "Controlo de volume",
"welcomepage": {
"accessibilityLabel": {

View File

@@ -870,11 +870,9 @@
"lookGood": "Your microphone is working properly",
"or": "or",
"premeeting": "Pre meeting",
"proceedAnyway": "Proceed anyway",
"screenSharingError": "Screen sharing error:",
"showScreen": "Enable pre meeting screen",
"startWithPhone": "Start with phone audio",
"unsafeRoomConsent": "I understand the risks, I want to join the meeting",
"videoOnlyError": "Video error:",
"videoTrackError": "Could not create video track.",
"viewAllNumbers": "view all numbers"
@@ -976,14 +974,8 @@
"security": {
"about": "You can add a $t(lockRoomPassword) to your meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
"aboutReadOnly": "Moderator participants can add a $t(lockRoomPassword) to the meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
"insecureRoomNameWarningNative": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting ",
"insecureRoomNameWarningWeb": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">here</a>.",
"title": "Security Options",
"unsafeRoomActions": {
"meeting": "Consider securing your meeting using the security button.",
"prejoin": "Consider using a more unique meeting name.",
"welcome": "Consider using a more unique meeting name, or pick one of the suggestions."
}
"insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button.",
"title": "Security Options"
},
"settings": {
"audio": "Audio",
@@ -1151,7 +1143,6 @@
"muteEveryoneElse": "Mute everyone else",
"muteEveryoneElsesVideoStream": "Stop everyone else's video",
"muteEveryonesVideoStream": "Stop everyone's video",
"muteGUMPending": "Connecting your microphone",
"noiseSuppression": "Noise suppression",
"openChat": "Open chat",
"participants": "Open participants pane",
@@ -1159,7 +1150,6 @@
"privateMessage": "Send private message",
"profile": "Edit your profile",
"raiseHand": "Raise your hand",
"reactions": "Reactions",
"reactionsMenu": "Reactions menu",
"recording": "Toggle recording",
"remoteMute": "Mute participant",
@@ -1185,7 +1175,6 @@
"unmute": "Unmute",
"videoblur": "Toggle video blur",
"videomute": "Stop camera",
"videomuteGUMPending": "Connecting your camera",
"videounmute": "Start camera"
},
"addPeople": "Add people to your call",
@@ -1236,7 +1225,6 @@
"mute": "Mute",
"muteEveryone": "Mute everyone",
"muteEveryonesVideo": "Disable everyone's camera",
"muteGUMPending": "Connecting your microphone",
"noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider switching the device.",
"noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider switching to the suggested device.",
"noAudioSignalDialInDesc": "You can also dial-in using:",
@@ -1259,7 +1247,6 @@
"reactionLike": "Send thumbs up reaction",
"reactionSilence": "Send silence reaction",
"reactionSurprised": "Send surprised reaction",
"reactions": "Reactions",
"security": "Security options",
"selectBackground": "Select background",
"shareRoom": "Invite someone",
@@ -1282,7 +1269,6 @@
"unmute": "Unmute",
"videoSettings": "Video settings",
"videomute": "Stop camera",
"videomuteGUMPending": "Connecting your camera",
"videounmute": "Start camera"
},
"transcribing": {

View File

@@ -1,4 +1,5 @@
/* global APP */
// @flow
import Logger from '@jitsi/logger';
import { createApiEvent } from '../../react/features/analytics/AnalyticsEvents';
@@ -112,7 +113,6 @@ import { isAudioMuteButtonDisabled } from '../../react/features/toolbox/function
import { setTileView, toggleTileView } from '../../react/features/video-layout/actions.any';
import { muteAllParticipants } from '../../react/features/video-menu/actions';
import { setVideoQuality } from '../../react/features/video-quality/actions';
import { toggleWhiteboard } from '../../react/features/whiteboard/actions.any';
import { getJitsiMeetTransport } from '../transport';
import {
@@ -123,6 +123,8 @@ import {
const logger = Logger.getLogger(__filename);
declare var APP: Object;
/**
* List of the available commands.
*/
@@ -342,16 +344,15 @@ function initCommands() {
},
'set-large-video-participant': (participantId, videoType) => {
logger.debug('Set large video participant command received');
const { getState, dispatch } = APP.store;
if (!participantId) {
sendAnalytics(createApiEvent('largevideo.participant.set'));
dispatch(selectParticipantInLargeVideo());
APP.store.dispatch(selectParticipantInLargeVideo());
return;
}
const state = getState();
const state = APP.store.getState();
const participant = videoType === VIDEO_TYPE.DESKTOP
? getVirtualScreenshareParticipantByOwnerId(state, participantId)
: getParticipantById(state, participantId);
@@ -362,9 +363,8 @@ function initCommands() {
return;
}
dispatch(setTileView(false));
sendAnalytics(createApiEvent('largevideo.participant.set'));
dispatch(selectParticipantInLargeVideo(participant.id));
APP.store.dispatch(selectParticipantInLargeVideo(participant.id));
},
'set-participant-volume': (participantId, volume) => {
APP.store.dispatch(setVolume(participantId, volume));
@@ -833,9 +833,6 @@ function initCommands() {
} else {
logger.error(' End Conference not supported');
}
},
'toggle-whiteboard': () => {
APP.store.dispatch(toggleWhiteboard());
}
};
transport.on('event', ({ data, name }) => {
@@ -1033,7 +1030,7 @@ function toggleScreenSharing(enable) {
* @param {MouseEvent} event - The mouse event to sanitize.
* @returns {Object}
*/
function sanitizeMouseEvent(event) {
function sanitizeMouseEvent(event: MouseEvent) {
const {
clientX,
clientY,
@@ -1071,7 +1068,7 @@ function sanitizeMouseEvent(event) {
* Jitsi Meet.
*/
class API {
_enabled;
_enabled: boolean;
/**
* Initializes the API. Setups message event listeners that will receive
@@ -1106,7 +1103,7 @@ class API {
* otherwise.
* @returns {void}
*/
notifyLargeVideoVisibilityChanged(isHidden) {
notifyLargeVideoVisibilityChanged(isHidden: boolean) {
this._sendEvent({
name: 'large-video-visibility-changed',
isVisible: !isHidden
@@ -1120,7 +1117,7 @@ class API {
* @param {Object} event - The message to pass onto spot.
* @returns {void}
*/
sendProxyConnectionEvent(event) {
sendProxyConnectionEvent(event: Object) {
this._sendEvent({
name: 'proxy-connection-event',
...event
@@ -1133,7 +1130,7 @@ class API {
* @param {Object} event - The event to be sent.
* @returns {void}
*/
_sendEvent(event = {}) {
_sendEvent(event: Object = {}) {
if (this._enabled) {
transport.sendEvent(event);
}
@@ -1146,7 +1143,7 @@ class API {
* @param {boolean} isOpen - True if the chat panel is open.
* @returns {void}
*/
notifyChatUpdated(unreadCount, isOpen) {
notifyChatUpdated(unreadCount: number, isOpen: boolean) {
this._sendEvent({
name: 'chat-updated',
unreadCount,
@@ -1161,7 +1158,7 @@ class API {
* @param {boolean} privateMessage - True if the message was a private message.
* @returns {void}
*/
notifySendingChatMessage(message, privateMessage) {
notifySendingChatMessage(message: string, privateMessage: boolean) {
this._sendEvent({
name: 'outgoing-message',
message,
@@ -1175,7 +1172,7 @@ class API {
* @param {MouseEvent} event - The mousemove event.
* @returns {void}
*/
notifyMouseEnter(event) {
notifyMouseEnter(event: MouseEvent) {
this._sendEvent({
name: 'mouse-enter',
event: sanitizeMouseEvent(event)
@@ -1188,7 +1185,7 @@ class API {
* @param {MouseEvent} event - The mousemove event.
* @returns {void}
*/
notifyMouseLeave(event) {
notifyMouseLeave(event: MouseEvent) {
this._sendEvent({
name: 'mouse-leave',
event: sanitizeMouseEvent(event)
@@ -1201,7 +1198,7 @@ class API {
* @param {MouseEvent} event - The mousemove event.
* @returns {void}
*/
notifyMouseMove(event) {
notifyMouseMove(event: MouseEvent) {
this._sendEvent({
name: 'mouse-move',
event: sanitizeMouseEvent(event)
@@ -1215,7 +1212,7 @@ class API {
* @param {boolean} enabled - Whether or not the new moderation status is enabled.
* @returns {void}
*/
notifyModerationChanged(mediaType, enabled) {
notifyModerationChanged(mediaType: string, enabled: boolean) {
this._sendEvent({
name: 'moderation-status-changed',
mediaType,
@@ -1230,7 +1227,7 @@ class API {
* @param {string} mediaType - Media type for which the participant was approved.
* @returns {void}
*/
notifyParticipantApproved(participantId, mediaType) {
notifyParticipantApproved(participantId: string, mediaType: string) {
this._sendEvent({
name: 'moderation-participant-approved',
id: participantId,
@@ -1245,7 +1242,7 @@ class API {
* @param {string} mediaType - Media type for which the participant was rejected.
* @returns {void}
*/
notifyParticipantRejected(participantId, mediaType) {
notifyParticipantRejected(participantId: string, mediaType: string) {
this._sendEvent({
name: 'moderation-participant-rejected',
id: participantId,
@@ -1261,7 +1258,7 @@ class API {
*
* @returns {void}
*/
notifyNotificationTriggered(title, description) {
notifyNotificationTriggered(title: string, description: string) {
this._sendEvent({
description,
name: 'notification-triggered',
@@ -1275,7 +1272,7 @@ class API {
* @param {number} videoQuality - The video quality. The number represents the maximum height of the video streams.
* @returns {void}
*/
notifyVideoQualityChanged(videoQuality) {
notifyVideoQualityChanged(videoQuality: number) {
this._sendEvent({
name: 'video-quality-changed',
videoQuality
@@ -1290,7 +1287,9 @@ class API {
* @returns {void}
*/
notifyReceivedChatMessage(
{ body, id, nick, privateMessage, ts } = {}) {
{ body, id, nick, privateMessage, ts }: {
body: *, id: string, nick: string, privateMessage: boolean, ts: *
} = {}) {
if (APP.conference.isLocalId(id)) {
return;
}
@@ -1313,7 +1312,7 @@ class API {
* @param {Object} props - The display name of the user.
* @returns {void}
*/
notifyUserJoined(id, props) {
notifyUserJoined(id: string, props: Object) {
this._sendEvent({
name: 'participant-joined',
id,
@@ -1328,7 +1327,7 @@ class API {
* @param {string} id - User id.
* @returns {void}
*/
notifyUserLeft(id) {
notifyUserLeft(id: string) {
this._sendEvent({
name: 'participant-left',
id
@@ -1343,7 +1342,7 @@ class API {
* @param {string} role - The new user role.
* @returns {void}
*/
notifyUserRoleChanged(id, role) {
notifyUserRoleChanged(id: string, role: string) {
this._sendEvent({
name: 'participant-role-changed',
id,
@@ -1359,7 +1358,7 @@ class API {
* @param {string} avatarURL - The new avatar URL of the participant.
* @returns {void}
*/
notifyAvatarChanged(id, avatarURL) {
notifyAvatarChanged(id: string, avatarURL: string) {
this._sendEvent({
name: 'avatar-changed',
avatarURL,
@@ -1374,7 +1373,7 @@ class API {
* @param {Object} data - The event data.
* @returns {void}
*/
notifyEndpointTextMessageReceived(data) {
notifyEndpointTextMessageReceived(data: Object) {
this._sendEvent({
name: 'endpoint-text-message-received',
data
@@ -1388,7 +1387,7 @@ class API {
* @param {string} faceExpression - Detected face expression.
* @returns {void}
*/
notifyFaceLandmarkDetected(faceBox, faceExpression) {
notifyFaceLandmarkDetected(faceBox: Object, faceExpression: string) {
this._sendEvent({
name: 'face-landmark-detected',
faceBox,
@@ -1402,7 +1401,7 @@ class API {
* @param {Object} data - The event data.
* @returns {void}
*/
notifySharingParticipantsChanged(data) {
notifySharingParticipantsChanged(data: Object) {
this._sendEvent({
name: 'content-sharing-participants-changed',
data
@@ -1416,7 +1415,7 @@ class API {
* @param {Object} devices - The new device list.
* @returns {void}
*/
notifyDeviceListChanged(devices) {
notifyDeviceListChanged(devices: Object) {
this._sendEvent({
name: 'device-list-changed',
devices
@@ -1434,8 +1433,8 @@ class API {
* @returns {void}
*/
notifyDisplayNameChanged(
id,
{ displayName, formattedDisplayName }) {
id: string,
{ displayName, formattedDisplayName }: Object) {
this._sendEvent({
name: 'display-name-change',
displayname: displayName,
@@ -1453,8 +1452,8 @@ class API {
* @returns {void}
*/
notifyEmailChanged(
id,
{ email }) {
id: string,
{ email }: Object) {
this._sendEvent({
name: 'email-change',
email,
@@ -1466,10 +1465,10 @@ class API {
* Notify external application (if API is enabled) that the an error has been logged.
*
* @param {string} logLevel - The message log level.
* @param {Array<string>} args - Array of strings composing the log message.
* @param {Array} args - Array of strings composing the log message.
* @returns {void}
*/
notifyLog(logLevel, args) {
notifyLog(logLevel: string, args: Array<string>) {
this._sendEvent({
name: 'log',
logLevel,
@@ -1487,7 +1486,7 @@ class API {
* user and the type of the room.
* @returns {void}
*/
notifyConferenceJoined(roomName, id, props) {
notifyConferenceJoined(roomName: string, id: string, props: Object) {
this._sendEvent({
name: 'video-conference-joined',
roomName,
@@ -1502,7 +1501,7 @@ class API {
* @param {string} roomName - User id.
* @returns {void}
*/
notifyConferenceLeft(roomName) {
notifyConferenceLeft(roomName: string) {
this._sendEvent({
name: 'video-conference-left',
roomName
@@ -1517,7 +1516,7 @@ class API {
*
* @returns {void}
*/
notifyDataChannelClosed(code, reason) {
notifyDataChannelClosed(code: number, reason: string) {
this._sendEvent({
name: 'data-channel-closed',
code,
@@ -1560,7 +1559,7 @@ class API {
* @param {boolean} muted - The new muted status.
* @returns {void}
*/
notifyAudioMutedStatusChanged(muted) {
notifyAudioMutedStatusChanged(muted: boolean) {
this._sendEvent({
name: 'audio-mute-status-changed',
muted
@@ -1574,7 +1573,7 @@ class API {
* @param {boolean} muted - The new muted status.
* @returns {void}
*/
notifyVideoMutedStatusChanged(muted) {
notifyVideoMutedStatusChanged(muted: boolean) {
this._sendEvent({
name: 'video-mute-status-changed',
muted
@@ -1588,7 +1587,7 @@ class API {
* @param {boolean} available - True if available and false otherwise.
* @returns {void}
*/
notifyAudioAvailabilityChanged(available) {
notifyAudioAvailabilityChanged(available: boolean) {
audioAvailable = available;
this._sendEvent({
name: 'audio-availability-changed',
@@ -1603,7 +1602,7 @@ class API {
* @param {boolean} available - True if available and false otherwise.
* @returns {void}
*/
notifyVideoAvailabilityChanged(available) {
notifyVideoAvailabilityChanged(available: boolean) {
videoAvailable = available;
this._sendEvent({
name: 'video-availability-changed',
@@ -1618,7 +1617,7 @@ class API {
* @param {string} id - User id of the new on stage participant.
* @returns {void}
*/
notifyOnStageParticipantChanged(id) {
notifyOnStageParticipantChanged(id: string) {
this._sendEvent({
name: 'on-stage-participant-changed',
id
@@ -1632,7 +1631,7 @@ class API {
* @param {boolean} isVisible - Whether the prejoin video is visible.
* @returns {void}
*/
notifyPrejoinVideoVisibilityChanged(isVisible) {
notifyPrejoinVideoVisibilityChanged(isVisible: boolean) {
this._sendEvent({
name: 'on-prejoin-video-changed',
isVisible
@@ -1666,7 +1665,7 @@ class API {
* @param {string} message - Additional information about the error.
* @returns {void}
*/
notifyOnCameraError(type, message) {
notifyOnCameraError(type: string, message: string) {
this._sendEvent({
name: 'camera-error',
type,
@@ -1682,7 +1681,7 @@ class API {
* @param {string} message - Additional information about the error.
* @returns {void}
*/
notifyOnMicError(type, message) {
notifyOnMicError(type: string, message: string) {
this._sendEvent({
name: 'mic-error',
type,
@@ -1698,7 +1697,7 @@ class API {
* @param {string} error - A failure message, if any.
* @returns {void}
*/
notifyFeedbackSubmitted(error) {
notifyFeedbackSubmitted(error: string) {
this._sendEvent({
name: 'feedback-submitted',
error
@@ -1723,7 +1722,7 @@ class API {
* be displayed or hidden.
* @returns {void}
*/
notifyFilmstripDisplayChanged(visible) {
notifyFilmstripDisplayChanged(visible: boolean) {
this._sendEvent({
name: 'filmstrip-display-changed',
visible
@@ -1740,7 +1739,7 @@ class API {
* other participant.
* @returns {void}
*/
notifyKickedOut(kicked, kicker) {
notifyKickedOut(kicked: Object, kicker: Object) {
this._sendEvent({
name: 'participant-kicked-out',
kicked,
@@ -1769,7 +1768,7 @@ class API {
* share is capturing.
* @returns {void}
*/
notifyScreenSharingStatusChanged(on, details) {
notifyScreenSharingStatusChanged(on: boolean, details: Object) {
this._sendEvent({
name: 'screen-sharing-status-changed',
on,
@@ -1784,7 +1783,7 @@ class API {
* @param {string} id - Id of the dominant participant.
* @returns {void}
*/
notifyDominantSpeakerChanged(id) {
notifyDominantSpeakerChanged(id: string) {
this._sendEvent({
name: 'dominant-speaker-changed',
id
@@ -1798,7 +1797,7 @@ class API {
* @param {string} subject - Conference subject.
* @returns {void}
*/
notifySubjectChanged(subject) {
notifySubjectChanged(subject: string) {
this._sendEvent({
name: 'subject-change',
subject
@@ -1813,7 +1812,7 @@ class API {
* otherwise.
* @returns {void}
*/
notifyTileViewChanged(enabled) {
notifyTileViewChanged(enabled: boolean) {
this._sendEvent({
name: 'tile-view-changed',
enabled
@@ -1826,7 +1825,7 @@ class API {
* @param {string} localStorageContent - The new localStorageContent.
* @returns {void}
*/
notifyLocalStorageChanged(localStorageContent) {
notifyLocalStorageChanged(localStorageContent: string) {
this._sendEvent({
name: 'local-storage-changed',
localStorageContent
@@ -1840,7 +1839,7 @@ class API {
* @param {boolean} handRaised - Whether user has raised hand.
* @returns {void}
*/
notifyRaiseHandUpdated(id, handRaised) {
notifyRaiseHandUpdated(id: string, handRaised: boolean) {
this._sendEvent({
name: 'raise-hand-updated',
handRaised,
@@ -1856,7 +1855,7 @@ class API {
* @param {string} error - Error type or null if success.
* @returns {void}
*/
notifyRecordingStatusChanged(on, mode, error) {
notifyRecordingStatusChanged(on: boolean, mode: string, error?: string) {
this._sendEvent({
name: 'recording-status-changed',
on,
@@ -1873,7 +1872,7 @@ class API {
* @param {number} ttl - The recording download link time to live.
* @returns {void}
*/
notifyRecordingLinkAvailable(link, ttl) {
notifyRecordingLinkAvailable(link: string, ttl: number) {
this._sendEvent({
name: 'recording-link-available',
link,
@@ -1887,7 +1886,7 @@ class API {
* @param {Object} participant - Participant data such as id and name.
* @returns {void}
*/
notifyKnockingParticipant(participant) {
notifyKnockingParticipant(participant: Object) {
this._sendEvent({
name: 'knocking-participant',
participant
@@ -1900,7 +1899,7 @@ class API {
* @param {Object} error - The error.
* @returns {void}
*/
notifyError(error) {
notifyError(error: Object) {
this._sendEvent({
name: 'error-occurred',
error
@@ -1914,7 +1913,7 @@ class API {
* @param {boolean} preventExecution - Whether execution of the button click was prevented or not.
* @returns {void}
*/
notifyToolbarButtonClicked(key, preventExecution) {
notifyToolbarButtonClicked(key: string, preventExecution: boolean) {
this._sendEvent({
name: 'toolbar-button-clicked',
key,
@@ -1928,7 +1927,7 @@ class API {
* @param {boolean} supported - If browser is supported or not.
* @returns {void}
*/
notifyBrowserSupport(supported) {
notifyBrowserSupport(supported: boolean) {
this._sendEvent({
name: 'browser-support',
supported
@@ -2015,20 +2014,6 @@ class API {
});
}
/**
* Notify external application (if API is enabled) if whiteboard state is
* changed.
*
* @param {WhiteboardStatus} status - The new whiteboard status.
* @returns {void}
*/
notifyWhiteboardStatusChanged(status) {
this._sendEvent({
name: 'whiteboard-status-changed',
status
});
}
/**
* Disposes the allocated resources.
*

View File

@@ -36,6 +36,7 @@ const commands = {
cancelPrivateChat: 'cancel-private-chat',
closeBreakoutRoom: 'close-breakout-room',
displayName: 'display-name',
e2eeKey: 'e2ee-key',
endConference: 'end-conference',
email: 'email',
grantModerator: 'grant-moderator',
@@ -89,8 +90,7 @@ const commands = {
toggleSubtitles: 'toggle-subtitles',
toggleTileView: 'toggle-tile-view',
toggleVirtualBackgroundDialog: 'toggle-virtual-background',
toggleVideo: 'toggle-video',
toggleWhiteboard: 'toggle-whiteboard'
toggleVideo: 'toggle-video'
};
/**
@@ -154,8 +154,7 @@ const events = {
'subject-change': 'subjectChange',
'suspend-detected': 'suspendDetected',
'tile-view-changed': 'tileViewChanged',
'toolbar-button-clicked': 'toolbarButtonClicked',
'whiteboard-status-changed': 'whiteboardStatusChanged'
'toolbar-button-clicked': 'toolbarButtonClicked'
};
/**
@@ -315,7 +314,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
* @param {string} [options.e2eeKey] - The key used for End-to-End encryption.
* THIS IS EXPERIMENTAL.
* @param {string} [options.release] - The key used for specifying release if enabled on the backend.
* @param {string} [options.sandbox] - Sandbox directive for the created iframe, if desired.
*/
constructor(domain, ...args) {
super();
@@ -333,8 +331,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
devices,
userInfo,
e2eeKey,
release,
sandbox = ''
release
} = parseArguments(args);
const localStorageContent = jitsiLocalStorage.getItem('jitsiLocalStorage');
@@ -352,7 +349,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
},
release
});
this._createIFrame(height, width, onload, sandbox);
this._createIFrame(height, width, onload);
this._transport = new Transport({
backend: new PostMessageTransportBackend({
postisOptions: {
@@ -385,12 +382,11 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
* parseSizeParam for format details.
* @param {Function} onload - The function that will listen
* for onload event.
* @param {string} sandbox - Sandbox directive for the created iframe, if desired.
* @returns {void}
*
* @private
*/
_createIFrame(height, width, onload, sandbox) {
_createIFrame(height, width, onload) {
const frameName = `jitsiConferenceFrame${id}`;
this._frame = document.createElement('iframe');
@@ -401,10 +397,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
this._frame.setAttribute('allowFullScreen', 'true');
this._frame.style.border = 0;
if (sandbox) {
this._frame.sandbox = sandbox;
}
if (onload) {
// waits for iframe resources to load
// and fires event when it is done
@@ -560,22 +552,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
switch (name) {
case 'video-conference-joined': {
if (typeof this._tmpE2EEKey !== 'undefined') {
const hexToBytes = hex => {
const bytes = [];
for (let c = 0; c < hex.length; c += 2) {
bytes.push(parseInt(hex.substring(c, c + 2), 16));
}
return bytes;
};
this.executeCommand('setMediaEncryptionKey', JSON.stringify({
exportedKey: hexToBytes(this._tmpE2EEKey),
index: 0
}));
this.executeCommand(commands.e2eeKey, this._tmpE2EEKey);
this._tmpE2EEKey = undefined;
}

View File

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

View File

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

View File

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

View File

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

5570
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -20,9 +20,9 @@
"@emotion/styled": "11.10.6",
"@giphy/js-fetch-api": "4.7.1",
"@giphy/react-components": "6.8.1",
"@giphy/react-native-sdk": "2.3.0",
"@giphy/react-native-sdk": "1.7.0",
"@hapi/bourne": "2.0.0",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.12/jitsi-excalidraw-0.0.12.tgz",
"@jitsi/js-utils": "2.0.5",
"@jitsi/logger": "2.0.0",
"@jitsi/rnnoise-wasm": "0.1.0",
@@ -65,7 +65,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/v1639.0.0+d2179f31/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1626.0.0+a41aa571/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -73,13 +73,13 @@
"optional-require": "1.0.3",
"promise.allsettled": "1.0.4",
"punycode": "2.1.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-emoji-render": "1.2.4",
"react-focus-lock": "2.9.4",
"react-focus-lock": "2.5.1",
"react-i18next": "10.11.4",
"react-linkify": "1.0.0-alpha",
"react-native": "0.69.10",
"react-native": "0.68.6",
"react-native-background-timer": "2.4.1",
"react-native-calendar-events": "2.2.0",
"react-native-callstats": "3.73.7",
@@ -104,7 +104,7 @@
"react-native-url-polyfill": "1.3.0",
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
"react-native-watch-connectivity": "1.0.11",
"react-native-webrtc": "111.0.1",
"react-native-webrtc": "111.0.0",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
"react-redux": "7.1.0",
@@ -125,9 +125,10 @@
},
"devDependencies": {
"@babel/core": "7.16.0",
"@babel/eslint-parser": "7.21.8",
"@babel/eslint-parser": "7.16.0",
"@babel/plugin-proposal-export-default-from": "7.16.0",
"@babel/preset-env": "7.16.0",
"@babel/preset-flow": "7.16.0",
"@babel/preset-react": "7.16.0",
"@jitsi/eslint-config": "4.1.5",
"@types/amplitude-js": "8.16.2",
@@ -138,8 +139,7 @@
"@types/react": "17.0.14",
"@types/react-dom": "17.0.14",
"@types/react-linkify": "1.0.1",
"@types/react-native": "0.69.20",
"@types/react-native-keep-awake": "2.0.3",
"@types/react-native": "0.68.9",
"@types/react-native-video": "5.0.14",
"@types/react-redux": "7.1.24",
"@types/react-window": "1.8.5",
@@ -149,28 +149,29 @@
"@types/w3c-image-capture": "1.0.6",
"@types/w3c-web-hid": "1.0.3",
"@types/zxcvbn": "4.4.1",
"@typescript-eslint/eslint-plugin": "5.59.5",
"@typescript-eslint/parser": "5.59.5",
"@typescript-eslint/eslint-plugin": "5.30.5",
"@typescript-eslint/parser": "5.30.4",
"babel-loader": "8.2.3",
"babel-plugin-optional-require": "0.3.1",
"circular-dependency-plugin": "5.2.0",
"clean-css-cli": "4.3.0",
"css-loader": "3.6.0",
"eslint": "8.40.0",
"eslint-plugin-import": "2.27.5",
"eslint": "8.35.0",
"eslint-plugin-flowtype": "8.0.3",
"eslint-plugin-import": "2.25.2",
"eslint-plugin-jsdoc": "37.0.3",
"eslint-plugin-react": "7.32.2",
"eslint-plugin-react-native": "4.0.0",
"eslint-plugin-typescript-sort-keys": "2.3.0",
"eslint-plugin-react": "7.26.1",
"eslint-plugin-react-native": "3.11.0",
"eslint-plugin-typescript-sort-keys": "2.1.0",
"jetifier": "1.6.4",
"metro-react-native-babel-preset": "0.70.3",
"metro-react-native-babel-preset": "0.67.0",
"patch-package": "6.4.7",
"process": "0.11.10",
"sass": "1.26.8",
"style-loader": "3.3.1",
"traverse": "0.6.6",
"ts-loader": "9.4.2",
"typescript": "5.0.4",
"ts-loader": "9.4.1",
"typescript": "4.7.4",
"unorm": "1.6.0",
"webpack": "5.76.0",
"webpack-bundle-analyzer": "4.4.2",
@@ -178,7 +179,7 @@
"webpack-dev-server": "4.7.3"
},
"overrides": {
"strophe.js@1.5.0": {
"strophe.js@1.6.0": {
"@xmldom/xmldom": "0.8.7"
}
},
@@ -192,7 +193,7 @@
"tsc:web": "tsc --noEmit --project tsconfig.web.json",
"tsc:native": "tsc --noEmit --project tsconfig.native.json",
"tsc:ci": "npm run tsc:web && npm run tsc:native",
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 .",
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 . && npm run tsc:ci && npm run lint:lang",
"lint:lang": "for file in lang/*.json; do npx --yes jsonlint -q $file || exit 1; done",
"lang-sort": "./resources/lang-sort.sh",
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",

View File

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

View File

@@ -26,5 +26,10 @@ module.exports = {
ios: null
}
}
},
project: {
ios: {
project: '.ios/jitsi-meet.xcworkspace'
}
}
};

View File

@@ -1,6 +1,7 @@
module.exports = {
'extends': [
'../.eslintrc.js',
'@jitsi/eslint-config/flow',
'@jitsi/eslint-config/jsdoc',
'@jitsi/eslint-config/react',
'.eslintrc-react-native.js'
@@ -29,10 +30,15 @@ module.exports = {
}
],
'rules': {
'flowtype/no-types-missing-file-annotation': 0,
// XXX remove this eventually.
'react/jsx-indent-props': 0
},
'settings': {
'flowtype': {
'onlyFilesWithFlowAnnotation': true
},
'react': {
'version': 'detect'
}

View File

@@ -1,3 +1,5 @@
// @flow
import React, { Component } from 'react';
// We need to reference these files directly to avoid loading things that are not available
@@ -17,15 +19,15 @@ const TOOLBAR_TIMEOUT = 4000;
/**
* The type of the React {@code Component} state of {@link AlwaysOnTop}.
*/
interface IState {
avatarURL: string;
customAvatarBackgrounds: Array<string>;
displayName: string;
formattedDisplayName: string;
isVideoDisplayed: boolean;
userID: string;
visible: boolean;
}
type State = {
avatarURL: string,
customAvatarBackgrounds: Array<string>,
displayName: string,
formattedDisplayName: string,
isVideoDisplayed: boolean,
userID: string,
visible: boolean
};
/**
* Represents the always on top page.
@@ -33,7 +35,7 @@ interface IState {
* @class AlwaysOnTop
* @augments Component
*/
export default class AlwaysOnTop extends Component<any, IState> {
export default class AlwaysOnTop extends Component<*, State> {
_hovered: boolean;
/**
@@ -42,7 +44,7 @@ export default class AlwaysOnTop extends Component<any, IState> {
* @param {*} props - The read-only properties with which the new instance
* is to be initialized.
*/
constructor(props: any) {
constructor(props: *) {
super(props);
this.state = {
@@ -66,25 +68,28 @@ export default class AlwaysOnTop extends Component<any, IState> {
this._onMouseOver = this._onMouseOver.bind(this);
}
_avatarChangedListener: () => void;
/**
* Handles avatar changed api events.
*
* @returns {void}
*/
_avatarChangedListener({ avatarURL, id }: { avatarURL: string; id: string; }) {
_avatarChangedListener({ avatarURL, id }) {
if (api._getOnStageParticipant() === id
&& avatarURL !== this.state.avatarURL) {
this.setState({ avatarURL });
}
}
_displayNameChangedListener: () => void;
/**
* Handles display name changed api events.
*
* @returns {void}
*/
_displayNameChangedListener({ displayname, formattedDisplayName, id }: { displayname: string;
formattedDisplayName: string; id: string; }) {
_displayNameChangedListener({ displayname, formattedDisplayName, id }) {
if (api._getOnStageParticipant() === id
&& (formattedDisplayName !== this.state.formattedDisplayName
|| displayname !== this.state.displayName)) {
@@ -113,6 +118,8 @@ export default class AlwaysOnTop extends Component<any, IState> {
TOOLBAR_TIMEOUT);
}
_videoChangedListener: () => void;
/**
* Handles large video changed api events.
*
@@ -134,6 +141,8 @@ export default class AlwaysOnTop extends Component<any, IState> {
});
}
_mouseMove: () => void;
/**
* Handles mouse move events.
*
@@ -143,6 +152,8 @@ export default class AlwaysOnTop extends Component<any, IState> {
this.state.visible || this.setState({ visible: true });
}
_onMouseOut: () => void;
/**
* Toolbar mouse out handler.
*
@@ -152,6 +163,8 @@ export default class AlwaysOnTop extends Component<any, IState> {
this._hovered = false;
}
_onMouseOver: () => void;
/**
* Toolbar mouse over handler.
*
@@ -216,7 +229,7 @@ export default class AlwaysOnTop extends Component<any, IState> {
this._hideToolbarAfterTimeout();
api.getCustomAvatarBackgrounds()
.then((res: { avatarBackgrounds?: string[]; }) =>
.then(res =>
this.setState({
customAvatarBackgrounds: res.avatarBackgrounds || []
}))
@@ -229,7 +242,7 @@ export default class AlwaysOnTop extends Component<any, IState> {
* @inheritdoc
* @returns {void}
*/
componentDidUpdate(_prevProps: any, prevState: IState) {
componentDidUpdate(prevProps: *, prevState: State) {
if (!prevState.visible && this.state.visible) {
this._hideToolbarAfterTimeout();
}

View File

@@ -1,9 +1,11 @@
// @flow
import React, { Component } from 'react';
// We need to reference these files directly to avoid loading things that are not available
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
import { IconMic, IconMicSlash } from '../base/icons/svg';
import { IProps } from '../base/toolbox/components/AbstractButton';
import type { Props } from '../base/toolbox/components/AbstractButton';
import ToolbarButton from './ToolbarButton';
@@ -12,25 +14,23 @@ const { api } = window.alwaysOnTop;
/**
* The type of the React {@code Component} state of {@link AudioMuteButton}.
*/
interface IState {
type State = {
/**
* Whether audio is available is not.
*/
audioAvailable: boolean;
audioAvailable: boolean,
/**
* Whether audio is muted or not.
*/
audioMuted: boolean;
}
type Props = Partial<IProps>;
audioMuted: boolean
};
/**
* Stateless "mute/unmute audio" button for the Always-on-Top windows.
*/
export default class AudioMuteButton extends Component<Props, IState> {
export default class AudioMuteButton extends Component<Props, State> {
icon = IconMic;
toggledIcon = IconMicSlash;
accessibilityLabel = 'Audio mute';
@@ -38,7 +38,7 @@ export default class AudioMuteButton extends Component<Props, IState> {
/**
* Initializes a new {@code AudioMuteButton} instance.
*
* @param {IProps} props - The React {@code Component} props to initialize
* @param {Props} props - The React {@code Component} props to initialize
* the new {@code AudioMuteButton} instance with.
*/
constructor(props: Props) {
@@ -94,23 +94,27 @@ export default class AudioMuteButton extends Component<Props, IState> {
this._audioMutedListener);
}
_audioAvailabilityListener: ({ available: boolean }) => void;
/**
* Handles audio available api events.
*
* @param {{ available: boolean }} status - The new available status.
* @returns {void}
*/
_audioAvailabilityListener({ available }: { available: boolean; }) {
_audioAvailabilityListener({ available }) {
this.setState({ audioAvailable: available });
}
_audioMutedListener: ({ muted: boolean }) => void;
/**
* Handles audio muted api events.
*
* @param {{ muted: boolean }} status - The new muted status.
* @returns {void}
*/
_audioMutedListener({ muted }: { muted: boolean; }) {
_audioMutedListener({ muted }) {
this.setState({ audioMuted: muted });
}
@@ -140,14 +144,16 @@ export default class AudioMuteButton extends Component<Props, IState> {
* Changes the muted state.
*
* @override
* @param {boolean} _audioMuted - Whether audio should be muted or not.
* @param {boolean} audioMuted - Whether audio should be muted or not.
* @protected
* @returns {void}
*/
_setAudioMuted(_audioMuted: boolean) {
_setAudioMuted(audioMuted: boolean) { // eslint-disable-line no-unused-vars
this.state.audioAvailable && api.executeCommand('toggleAudio');
}
_onClick: () => {};
/**
* Handles clicking / pressing the button, and toggles the audio mute state
* accordingly.
@@ -167,13 +173,11 @@ export default class AudioMuteButton extends Component<Props, IState> {
render() {
const toggled = this._isAudioMuted();
return (
<ToolbarButton
accessibilityLabel = { this.accessibilityLabel }
disabled = { this._isDisabled() }
icon = { toggled ? this.toggledIcon : this.icon }
onClick = { this._onClick }
toggled = { toggled } />
);
return (<ToolbarButton
accessibilityLabel = { this.accessibilityLabel }
disabled = { this._isDisabled() }
icon = { toggled ? this.toggledIcon : this.icon }
onClick = { this._onClick }
toggled = { toggled } />);
}
}

View File

@@ -1,20 +1,19 @@
// @flow
import React, { Component } from 'react';
// We need to reference these files directly to avoid loading things that are not available
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
import { IconHangup } from '../base/icons/svg';
import { IProps } from '../base/toolbox/components/AbstractButton';
import type { Props } from '../base/toolbox/components/AbstractButton';
import ToolbarButton from './ToolbarButton';
const { api } = window.alwaysOnTop;
type Props = Partial<IProps>;
/**
* Stateless hangup button for the Always-on-Top windows.
*/
export default class HangupButton extends Component<Props> {
export default class HangupButton extends Component<Props, *> {
accessibilityLabel = 'Hangup';
icon = IconHangup;
@@ -22,7 +21,7 @@ export default class HangupButton extends Component<Props> {
/**
* Initializes a new {@code HangupButton} instance.
*
* @param {IProps} props - The React {@code Component} props to initialize
* @param {Props} props - The React {@code Component} props to initialize
* the new {@code HangupButton} instance with.
*/
constructor(props: Props) {
@@ -32,6 +31,8 @@ export default class HangupButton extends Component<Props> {
this._onClick = this._onClick.bind(this);
}
_onClick: () => {};
/**
* Handles clicking / pressing the button, and disconnects the conference.
*
@@ -49,12 +50,10 @@ export default class HangupButton extends Component<Props> {
* @returns {ReactElement}
*/
render() {
return (
<ToolbarButton
accessibilityLabel = { this.accessibilityLabel }
customClass = 'hangup-button'
icon = { this.icon }
onClick = { this._onClick } />
);
return (<ToolbarButton
accessibilityLabel = { this.accessibilityLabel }
customClass = 'hangup-button'
icon = { this.icon }
onClick = { this._onClick } />);
}
}

View File

@@ -1,3 +1,5 @@
// @flow
import React, { Component } from 'react';
import AudioMuteButton from './AudioMuteButton';
@@ -7,30 +9,30 @@ import VideoMuteButton from './VideoMuteButton';
/**
* The type of the React {@code Component} props of {@link Toolbar}.
*/
interface IProps {
type Props = {
/**
* Additional CSS class names to add to the root of the toolbar.
*/
className: string;
className: string,
/**
* Callback invoked when no longer moused over the toolbar.
*/
onMouseOut: (e?: React.MouseEvent) => void;
onMouseOut: Function,
/**
* Callback invoked when the mouse has moved over the toolbar.
*/
onMouseOver: (e?: React.MouseEvent) => void;
}
onMouseOver: Function
};
/**
* Represents the toolbar in the Always On Top window.
*
* @augments Component
*/
export default class Toolbar extends Component<IProps> {
export default class Toolbar extends Component<Props> {
/**
* Implements React's {@link Component#render()}.
*

View File

@@ -2,38 +2,38 @@ import React, { useCallback } from 'react';
import Icon from '../base/icons/components/Icon';
interface IProps {
type Props = {
/**
* Accessibility label for button.
*/
accessibilityLabel: string;
accessibilityLabel: string,
/**
* An extra class name to be added at the end of the element's class name
* in order to enable custom styling.
*/
customClass?: string;
customClass?: string,
/**
* Whether or not the button is disabled.
*/
disabled?: boolean;
/**
* Button icon.
*/
icon: Function;
disabled?: boolean,
/**
* Click handler.
*/
onClick: (e?: React.MouseEvent) => void;
onClick: Function,
/**
* Button icon.
*/
icon: Object,
/**
* Whether or not the button is toggled.
*/
toggled?: boolean;
toggled?: boolean
}
const ToolbarButton = ({
@@ -43,7 +43,7 @@ const ToolbarButton = ({
onClick,
icon,
toggled = false
}: IProps) => {
}: Props) => {
const onKeyPress = useCallback(event => {
if (event.key === 'Enter' || event.key === ' ') {
event.preventDefault();

View File

@@ -1,16 +1,15 @@
// @flow
import React, { Component } from 'react';
// We need to reference these files directly to avoid loading things that are not available
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
import { IconVideo, IconVideoOff } from '../base/icons/svg';
import { IProps } from '../base/toolbox/components/AbstractButton';
import type { Props } from '../base/toolbox/components/AbstractButton';
import ToolbarButton from './ToolbarButton';
const { api } = window.alwaysOnTop;
type Props = Partial<IProps>;
/**
* The type of the React {@code Component} state of {@link VideoMuteButton}.
*/
@@ -19,12 +18,12 @@ type State = {
/**
* Whether video is available is not.
*/
videoAvailable: boolean;
videoAvailable: boolean,
/**
* Whether video is muted or not.
*/
videoMuted: boolean;
videoMuted: boolean
};
/**
@@ -120,34 +119,40 @@ export default class VideoMuteButton extends Component<Props, State> {
* Changes the muted state.
*
* @override
* @param {boolean} _videoMuted - Whether video should be muted or not.
* @param {boolean} videoMuted - Whether video should be muted or not.
* @protected
* @returns {void}
*/
_setVideoMuted(_videoMuted: boolean) {
_setVideoMuted(videoMuted: boolean) { // eslint-disable-line no-unused-vars
this.state.videoAvailable && api.executeCommand('toggleVideo', false, true);
}
_videoAvailabilityListener: ({ available: boolean }) => void;
/**
* Handles video available api events.
*
* @param {{ available: boolean }} status - The new available status.
* @returns {void}
*/
_videoAvailabilityListener({ available }: { available: boolean; }) {
_videoAvailabilityListener({ available }) {
this.setState({ videoAvailable: available });
}
_videoMutedListener: ({ muted: boolean }) => void;
/**
* Handles video muted api events.
*
* @param {{ muted: boolean }} status - The new muted status.
* @returns {void}
*/
_videoMutedListener({ muted }: { muted: boolean; }) {
_videoMutedListener({ muted }) {
this.setState({ videoMuted: muted });
}
_onClick: () => {};
/**
* Handles clicking / pressing the button, and toggles the video mute state
* accordingly.
@@ -168,13 +173,11 @@ export default class VideoMuteButton extends Component<Props, State> {
render() {
const toggled = this._isVideoMuted();
return (
<ToolbarButton
accessibilityLabel = { this.accessibilityLabel }
disabled = { this._isDisabled() }
icon = { toggled ? this.toggledIcon : this.icon }
onClick = { this._onClick }
toggled = { toggled } />
);
return (<ToolbarButton
accessibilityLabel = { this.accessibilityLabel }
disabled = { this._isDisabled() }
icon = { toggled ? this.toggledIcon : this.icon }
onClick = { this._onClick }
toggled = { toggled } />);
}
}

View File

@@ -1,11 +1,14 @@
// @flow
import React from 'react';
import ReactDOM from 'react-dom';
import AlwaysOnTop from './AlwaysOnTop';
// Render the main/root Component.
// $FlowExpectedError
ReactDOM.render(<AlwaysOnTop />, document.getElementById('react'));
window.addEventListener(
'beforeunload',
() => ReactDOM.unmountComponentAtNode(document.getElementById('react') ?? document.body));
() => ReactDOM.unmountComponentAtNode(document.getElementById('react')));

View File

@@ -173,15 +173,7 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
const { group, server } = state['features/base/jwt'];
const { locationURL = { href: '' } } = state['features/base/connection'];
const { tenant } = parseURIString(locationURL.href) || {};
const permanentProperties: {
appName?: string;
externalApi?: boolean;
group?: string;
inIframe?: boolean;
server?: string;
tenant?: string;
websocket?: boolean;
} & typeof deploymentInfo = {};
const permanentProperties: any = {};
if (server) {
permanentProperties.server = server;
@@ -210,8 +202,7 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
if (deploymentInfo) {
for (const key in deploymentInfo) {
if (deploymentInfo.hasOwnProperty(key)) {
permanentProperties[key as keyof typeof deploymentInfo] = deploymentInfo[
key as keyof typeof deploymentInfo];
permanentProperties[key] = deploymentInfo[key as keyof typeof deploymentInfo];
}
}
}
@@ -244,7 +235,7 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
* @returns {Promise} Resolves with the handlers that have been successfully loaded and rejects if there are no handlers
* loaded or the analytics is disabled.
*/
function _loadHandlers(scriptURLs: string[] = [], handlerConstructorOptions: Object) {
function _loadHandlers(scriptURLs: any[] = [], handlerConstructorOptions: Object) {
const promises: Promise<{ error?: Error; type: string; url?: string; }>[] = [];
for (const url of scriptURLs) {

View File

@@ -1,4 +1,3 @@
import { Amplitude } from '@amplitude/react-native';
import DefaultPreference from 'react-native-default-preference';
import DeviceInfo from 'react-native-device-info';
@@ -8,7 +7,7 @@ import DeviceInfo from 'react-native-device-info';
* @param {AmplitudeClient} amplitude - The amplitude instance.
* @returns {void}
*/
export async function fixDeviceID(amplitude: Amplitude) {
export async function fixDeviceID(amplitude: any) {
await DefaultPreference.setName('jitsi-preferences');
const current = await DefaultPreference.get('amplitudeDeviceId');

View File

@@ -1,11 +1,9 @@
import { AmplitudeClient } from 'amplitude-js';
/**
* Custom logic for setting the correct device id.
*
* @param {AmplitudeClient} _amplitude - The amplitude instance.
* @returns {void}
*/
export function fixDeviceID(_amplitude: AmplitudeClient): Promise<any> {
export function fixDeviceID(_amplitude: any): Promise<any> {
return new Promise(resolve => resolve(true));
}

View File

@@ -1,3 +1,4 @@
/* eslint-disable lines-around-comment */
import { setRoom } from '../base/conference/actions';
import {
configWillLoad,
@@ -12,7 +13,6 @@ import {
import { connect, disconnect, setLocationURL } from '../base/connection/actions';
import { loadConfig } from '../base/lib-jitsi-meet/functions.native';
import { createDesiredLocalTracks } from '../base/tracks/actions';
import isInsecureRoomName from '../base/util/isInsecureRoomName';
import { parseURLParams } from '../base/util/parseURLParams';
import {
appendURLParam,
@@ -20,11 +20,14 @@ import {
parseURIString,
toURLString
} from '../base/util/uri';
// @ts-ignore
import { isPrejoinPageEnabled } from '../mobile/navigation/functions';
import {
goBackToRoot,
navigateRoot
// @ts-ignore
} from '../mobile/navigation/rootNavigationContainerRef';
// @ts-ignore
import { screen } from '../mobile/navigation/routes';
import { clearNotifications } from '../notifications/actions';
@@ -52,7 +55,7 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
// If the specified location (URI) does not identify a host, use the app's
// default.
if (!location?.host) {
if (!location || !location.host) {
const defaultLocation = parseURIString(getDefaultURL(getState));
if (location) {
@@ -137,14 +140,10 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
dispatch(setRoom(room));
if (room) {
if (isInsecureRoomName(room)) {
navigateRoot(screen.unsafeRoomWarning);
return;
}
dispatch(createDesiredLocalTracks());
dispatch(clearNotifications());
// @ts-ignore
const { hidePrejoin } = options;
if (!hidePrejoin && isPrejoinPageEnabled(getState())) {

View File

@@ -49,7 +49,7 @@ export function appNavigate(uri?: string) {
// If the specified location (URI) does not identify a host, use the app's
// default.
if (!location?.host) {
if (!location || !location.host) {
const defaultLocation = parseURIString(getDefaultURL(getState));
if (location) {

View File

@@ -12,7 +12,7 @@ export interface IProps {
* XXX Refer to the implementation of loadURLObject: in
* ios/sdk/src/JitsiMeetView.m for further information.
*/
timestamp: number;
timestamp: any;
/**
* The URL, if any, with which the app was launched.

View File

@@ -42,7 +42,7 @@ export class App extends AbstractApp {
*
* @override
*/
_createMainElement(component: React.ComponentType, props?: Object) {
_createMainElement(component: React.ComponentType, props: any) {
return (
<JitsiThemeProvider>
<GlobalStyles />

View File

@@ -5,6 +5,8 @@ import { IStateful } from '../base/app/types';
import { isRoomValid } from '../base/conference/functions';
import { isSupportedBrowser } from '../base/environment/environment';
import { toState } from '../base/redux/functions';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
import Conference from '../conference/components/web/Conference';
import { getDeepLinkingPage } from '../deep-linking/functions';
import UnsupportedDesktopBrowser from '../unsupported-browser/components/UnsupportedDesktopBrowser';

View File

@@ -1,5 +1,4 @@
import '../base/devices/reducer';
import '../base/premeeting/reducer';
import '../base/tooltip/reducer';
import '../e2ee/reducer';
import '../face-landmarks/reducer';

View File

@@ -20,7 +20,6 @@ import { ILoggingState } from '../base/logging/reducer';
import { IMediaState } from '../base/media/reducer';
import { INetInfoState } from '../base/net-info/reducer';
import { IParticipantsState } from '../base/participants/reducer';
import { IPreMeetingState } from '../base/premeeting/types';
import { IResponsiveUIState } from '../base/responsive-ui/reducer';
import { ISettingsState } from '../base/settings/reducer';
import { ISoundsState } from '../base/sounds/reducer';
@@ -111,7 +110,6 @@ export interface IReduxState {
'features/base/net-info': INetInfoState;
'features/base/no-src-data': INoSrcDataState;
'features/base/participants': IParticipantsState;
'features/base/premeeting': IPreMeetingState;
'features/base/responsive-ui': IResponsiveUIState;
'features/base/settings': ISettingsState;
'features/base/sounds': ISoundsState;

View File

@@ -27,13 +27,13 @@ export function cancelLogin() {
// a reaction to CONNECTION_FAILED). Since the
// app/user is going to navigate to WelcomePage, the SDK
// clients/consumers need an event.
const { error = { recoverable: undefined }, passwordRequired }
const { error, passwordRequired }
= getState()['features/base/connection'];
passwordRequired
&& dispatch(
connectionFailed(
passwordRequired,
passwordRequired, // @ts-ignore
set(error, 'recoverable', false) as any));
};
}

View File

@@ -1,2 +1,4 @@
export { default as LoginDialog } from './native/LoginDialog';
// eslint-disable-next-line lines-around-comment
// @ts-ignore
export { default as WaitForOwnerDialog } from './native/WaitForOwnerDialog';

View File

@@ -203,7 +203,7 @@ class LoginDialog extends Component<IProps, IState> {
t
} = this.props;
const { username, password } = this.state;
const messageOptions: { msg?: string; } = {};
const messageOptions: any = {};
let messageKey;
if (progress && progress < 1) {

View File

@@ -24,7 +24,7 @@ import {
openLoginDialog,
openWaitForOwnerDialog,
stopWaitForOwner,
waitForOwner } from './actions.native';
waitForOwner } from './actions.native'; // @ts-ignore
import { LoginDialog, WaitForOwnerDialog } from './components';
/**

View File

@@ -239,7 +239,7 @@ class Avatar<P extends IProps> extends PureComponent<P, IState> {
* @param {boolean} params.dontRetry - If false we will retry to load the Avatar with different CORS mode.
* @returns {void}
*/
_onAvatarLoadError(params: { dontRetry?: boolean; } = {}) {
_onAvatarLoadError(params: any = {}) {
const { dontRetry = false } = params;
if (Boolean(this.props.useCORS) === this.state.isUsingCORS && !dontRetry) {

View File

@@ -88,7 +88,7 @@ class ColorSchemeRegistry {
_applyColorScheme(
stateful: IStateful,
componentName: string,
style: StyleType | null): StyleType {
style: StyleType): StyleType {
let schemedStyle: any;
if (Array.isArray(style)) {
@@ -115,8 +115,8 @@ class ColorSchemeRegistry {
// The value is another style object, we apply the same
// transformation recursively.
schemedStyle[styleName]
= this._applyColorScheme(
stateful, componentName, styleValue as StyleType);
= this._applyColorScheme( // @ts-ignore
stateful, componentName, styleValue);
} else if (typeof styleValue === 'function') {
// The value is a function, which indicates that it's a
// dynamic, schemed color we need to resolve.

View File

@@ -98,32 +98,34 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
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)));
JitsiConferenceEvents.CONFERENCE_FAILED, // @ts-ignore
(...args: any[]) => dispatch(conferenceFailed(conference, ...args)));
conference.on(
JitsiConferenceEvents.CONFERENCE_JOINED,
(..._args: any[]) => dispatch(conferenceJoined(conference)));
JitsiConferenceEvents.CONFERENCE_JOINED, // @ts-ignore
(...args: any[]) => dispatch(conferenceJoined(conference, ...args)));
conference.on(
JitsiConferenceEvents.CONFERENCE_UNIQUE_ID_SET,
(..._args: any[]) => dispatch(conferenceUniqueIdSet(conference)));
JitsiConferenceEvents.CONFERENCE_UNIQUE_ID_SET, // @ts-ignore
(...args: any[]) => dispatch(conferenceUniqueIdSet(conference, ...args)));
conference.on(
JitsiConferenceEvents.CONFERENCE_JOIN_IN_PROGRESS,
(..._args: any[]) => dispatch(conferenceJoinInProgress(conference)));
JitsiConferenceEvents.CONFERENCE_JOIN_IN_PROGRESS, // @ts-ignore
(...args: any[]) => dispatch(conferenceJoinInProgress(conference, ...args)));
conference.on(
JitsiConferenceEvents.CONFERENCE_LEFT,
(..._args: any[]) => {
(...args: any[]) => {
dispatch(conferenceTimestampChanged(0));
dispatch(conferenceLeft(conference));
});
conference.on(JitsiConferenceEvents.SUBJECT_CHANGED,
(subject: string) => dispatch(conferenceSubjectChanged(subject)));
conference.on(JitsiConferenceEvents.CONFERENCE_CREATED_TIMESTAMP,
(timestamp: number) => dispatch(conferenceTimestampChanged(timestamp)));
// @ts-ignore
dispatch(conferenceLeft(conference, ...args));
});
conference.on(JitsiConferenceEvents.SUBJECT_CHANGED, // @ts-ignore
(...args: any[]) => dispatch(conferenceSubjectChanged(...args)));
conference.on(JitsiConferenceEvents.CONFERENCE_CREATED_TIMESTAMP, // @ts-ignore
(...args: any[]) => dispatch(conferenceTimestampChanged(...args)));
conference.on(
JitsiConferenceEvents.KICKED,
(participant: any) => dispatch(kickedOut(conference, participant)));
JitsiConferenceEvents.KICKED, // @ts-ignore
(...args: any[]) => dispatch(kickedOut(conference, ...args)));
conference.on(
JitsiConferenceEvents.PARTICIPANT_KICKED,
@@ -134,8 +136,8 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
(jitsiParticipant: IJitsiParticipant) => dispatch(participantSourcesUpdated(jitsiParticipant)));
conference.on(
JitsiConferenceEvents.LOCK_STATE_CHANGED,
(locked: boolean) => dispatch(lockStateChanged(conference, locked)));
JitsiConferenceEvents.LOCK_STATE_CHANGED, // @ts-ignore
(...args: any[]) => dispatch(lockStateChanged(conference, ...args)));
// Dispatches into features/base/media follow:
@@ -218,12 +220,12 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
});
conference.on(
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
(participant: Object, json: Object) => dispatch(endpointMessageReceived(participant, json)));
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED, // @ts-ignore
(...args: any[]) => dispatch(endpointMessageReceived(...args)));
conference.on(
JitsiConferenceEvents.NON_PARTICIPANT_MESSAGE_RECEIVED,
(id: string, json: Object) => dispatch(nonParticipantMessageReceived(id, json)));
JitsiConferenceEvents.NON_PARTICIPANT_MESSAGE_RECEIVED, // @ts-ignore
(...args: any[]) => dispatch(nonParticipantMessageReceived(...args)));
conference.on(
JitsiConferenceEvents.USER_JOINED,
@@ -232,15 +234,15 @@ function _addConferenceListeners(conference: IJitsiConference, dispatch: IStore[
JitsiConferenceEvents.USER_LEFT,
(_id: string, user: any) => commonUserLeftHandling({ dispatch }, conference, user));
conference.on(
JitsiConferenceEvents.USER_ROLE_CHANGED,
(id: string, role: string) => dispatch(participantRoleChanged(id, role)));
JitsiConferenceEvents.USER_ROLE_CHANGED, // @ts-ignore
(...args: any[]) => dispatch(participantRoleChanged(...args)));
conference.on(
JitsiConferenceEvents.USER_STATUS_CHANGED,
(id: string, presence: string) => dispatch(participantPresenceChanged(id, presence)));
JitsiConferenceEvents.USER_STATUS_CHANGED, // @ts-ignore
(...args: any[]) => dispatch(participantPresenceChanged(...args)));
conference.on(
JitsiE2ePingEvents.E2E_RTT_CHANGED,
(participant: Object, rtt: number) => dispatch(e2eRttChanged(participant, rtt)));
JitsiE2ePingEvents.E2E_RTT_CHANGED, // @ts-ignore
(...args: any[]) => dispatch(e2eRttChanged(...args)));
conference.on(
JitsiConferenceEvents.BOT_TYPE_CHANGED,
@@ -631,7 +633,7 @@ export function endConference() {
* participant: JitsiParticipant
* }}
*/
export function kickedOut(conference: IJitsiConference, participant: Object) {
export function kickedOut(conference: Object, participant: Object) {
return {
type: KICKED_OUT,
conference,
@@ -671,7 +673,7 @@ export function leaveConference() {
* locked: boolean
* }}
*/
export function lockStateChanged(conference: IJitsiConference, locked: boolean) {
export function lockStateChanged(conference: Object, locked: boolean) {
return {
type: LOCK_STATE_CHANGED,
conference,
@@ -690,7 +692,7 @@ export function lockStateChanged(conference: IJitsiConference, locked: boolean)
* json: Object
* }}
*/
export function nonParticipantMessageReceived(id: string, json: Object) {
export function nonParticipantMessageReceived(id: String, json: Object) {
return {
type: NON_PARTICIPANT_MESSAGE_RECEIVED,
id,

View File

@@ -292,7 +292,7 @@ export function getVisitorOptions(stateful: IStateful, params: Array<string>) {
const config = toState(stateful)['features/base/config'];
if (!config?.hosts) {
if (!config || !config.hosts) {
logger.warn('Wrong configuration, missing hosts.');
return;
@@ -300,8 +300,7 @@ export function getVisitorOptions(stateful: IStateful, params: Array<string>) {
if (!vnode) {
// this is redirecting back to main, lets restore config
// not updating disableFocus, as if the room capacity is full the promotion to the main room will fail
// and the visitor will be redirected back to a vnode from jicofo
// no point of updating disableFocus, we can skip the initial iq to jicofo
if (config.oldConfig && username) {
return {
hosts: {
@@ -311,7 +310,6 @@ export function getVisitorOptions(stateful: IStateful, params: Array<string>) {
focusUserJid: focusJid,
disableLocalStats: false,
bosh: config.oldConfig.bosh && appendURLParam(config.oldConfig.bosh, 'customusername', username),
p2p: config.oldConfig.p2p,
websocket: config.oldConfig.websocket
&& appendURLParam(config.oldConfig.websocket, 'customusername', username),
oldConfig: undefined // clears it up
@@ -328,7 +326,6 @@ export function getVisitorOptions(stateful: IStateful, params: Array<string>) {
},
focusUserJid: config.focusUserJid,
bosh: config.bosh,
p2p: config.p2p,
websocket: config.websocket
};
@@ -344,10 +341,6 @@ export function getVisitorOptions(stateful: IStateful, params: Array<string>) {
disableFocus: true, // This flag disables sending the initial conference request
disableLocalStats: true,
bosh: config.bosh && appendURLParam(config.bosh, 'vnode', vnode),
p2p: {
...config.p2p,
enabled: false
},
websocket: config.websocket && appendURLParam(config.websocket, 'vnode', vnode)
};
}

View File

@@ -67,7 +67,7 @@ import logger from './logger';
/**
* Handler for before unload event.
*/
let beforeUnloadHandler: (() => void) | undefined;
let beforeUnloadHandler: Function | undefined;
/**
* Implements the middleware of the feature base/conference.
@@ -289,12 +289,7 @@ function _conferenceJoined({ dispatch, getState }: IStore, next: Function, actio
dispatch(conferenceWillLeave(conference));
};
if (!iAmVisitor(getState())) {
// if a visitor is promoted back to main room and want to join an empty breakout room
// we need to send iq to jicofo, so it can join/create the breakout room
dispatch(overwriteConfig({ disableFocus: false }));
}
// @ts-ignore
window.addEventListener(disableBeforeUnloadHandlers ? 'unload' : 'beforeunload', beforeUnloadHandler);
if (requireDisplayName
@@ -512,6 +507,7 @@ function _removeUnloadHandler(getState: IStore['getState']) {
if (typeof beforeUnloadHandler !== 'undefined') {
const { disableBeforeUnloadHandlers = false } = getState()['features/base/config'];
// @ts-ignore
window.removeEventListener(disableBeforeUnloadHandlers ? 'unload' : 'beforeunload', beforeUnloadHandler);
beforeUnloadHandler = undefined;
}

View File

@@ -1,5 +1,3 @@
import { AnyAction } from 'redux';
import { FaceLandmarks } from '../../face-landmarks/types';
import { LOCKED_LOCALLY, LOCKED_REMOTELY } from '../../room-lock/constants';
import { ISpeakerStats } from '../../speaker-stats/reducer';
@@ -48,7 +46,6 @@ export interface IJitsiConference {
authenticateAndUpgradeRole: Function;
avModerationApprove: Function;
avModerationReject: Function;
callUUID?: string;
createVideoSIPGWSession: Function;
dial: Function;
disableAVModeration: Function;
@@ -150,7 +147,6 @@ export interface IConferenceState {
}
export interface IJitsiConferenceRoom {
locked: boolean;
myroomjid: string;
roomjid: string;
}
@@ -269,7 +265,7 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: {
return state;
}
let authRequired;
let authRequired: any;
let membersOnly;
let passwordRequired;
@@ -326,7 +322,7 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: {
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _conferenceJoined(state: IConferenceState, { conference }: { conference: IJitsiConference; }) {
function _conferenceJoined(state: IConferenceState, { conference }: { conference: any; }) {
// FIXME The indicator which determines whether a JitsiConference is locked
// i.e. password-protected is private to lib-jitsi-meet. However, the
// library does not fire LOCK_STATE_CHANGED upon joining a JitsiConference
@@ -465,7 +461,7 @@ function _lockStateChanged(state: IConferenceState, { conference, locked }: { co
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _p2pStatusChanged(state: IConferenceState, action: AnyAction) {
function _p2pStatusChanged(state: IConferenceState, action: any) {
return set(state, 'p2p', action.p2p);
}
@@ -479,7 +475,7 @@ function _p2pStatusChanged(state: IConferenceState, action: AnyAction) {
* reduction of the specified action.
*/
function _setPassword(state: IConferenceState, { conference, method, password }: {
conference: IJitsiConference; method: Object; password: string; }) {
conference: any; method: Object; password: string; }) {
switch (method) {
case conference.join:
return assign(state, {
@@ -526,7 +522,7 @@ function _setPassword(state: IConferenceState, { conference, method, password }:
* @returns {Object} The new state of the feature base/conference after the
* reduction of the specified action.
*/
function _setRoom(state: IConferenceState, action: AnyAction) {
function _setRoom(state: IConferenceState, action: any) {
let { room } = action;
if (!isRoomValid(room)) {

View File

@@ -1,4 +1,4 @@
// @ts-expect-error
// @ts-ignore
import { jitsiLocalStorage } from '@jitsi/js-utils';
import { IStore } from '../../app/types';

View File

@@ -18,7 +18,6 @@ type ToolbarButtons = 'camera' |
'participants-pane' |
'profile' |
'raisehand' |
'reactions' |
'recording' |
'security' |
'select-background' |
@@ -142,7 +141,6 @@ export interface IConfig {
rtcstatsEndpoint?: string;
rtcstatsPollInterval?: number;
rtcstatsSendSdp?: boolean;
rtcstatsStoreLogs?: boolean;
rtcstatsUseLegacy?: boolean;
scriptURLs?: Array<string>;
whiteListedEvents?: string[];
@@ -171,7 +169,6 @@ export interface IConfig {
}>;
callDisplayName?: string;
callFlowsEnabled?: boolean;
callHandle?: string;
callStatsConfigParams?: {
additionalIDs?: {
customerID?: string;
@@ -193,7 +190,6 @@ export interface IConfig {
};
callStatsID?: string;
callStatsSecret?: string;
callUUID?: string;
channelLastN?: number;
chromeExtensionBanner?: {
chromeExtensionsInfo?: Array<{ id: string; path: string; }>;
@@ -409,7 +405,6 @@ export interface IConfig {
legalUrls?: {
helpCentre: string;
privacy: string;
security: string;
terms: string;
};
liveStreaming?: {

View File

@@ -64,7 +64,7 @@ export const THIRD_PARTY_PREJOIN_BUTTONS = [ 'microphone', 'camera', 'select-bac
/**
* The toolbar buttons to show when in visitors mode.
*/
export const VISITORS_MODE_BUTTONS = [ 'chat', 'hangup', 'raisehand', 'settings', 'tileview' ];
export const VISITORS_MODE_BUTTONS = [ 'chat', 'hangup', 'raisehand', 'tileview' ];
/**
* The set of feature flags.

View File

@@ -1,7 +1,7 @@
// @ts-expect-error
// @ts-ignore
import Bourne from '@hapi/bourne';
// eslint-disable-next-line lines-around-comment
// @ts-expect-error
// @ts-ignore
import { jitsiLocalStorage } from '@jitsi/js-utils';
import _ from 'lodash';

View File

@@ -43,17 +43,20 @@ const INITIAL_NON_RN_STATE: IConfig = {
* @type {Object}
*/
const INITIAL_RN_STATE: IConfig = {
analytics: {},
// FIXME: Mobile codecs should probably be configurable separately, rather
// FIXME: than requiring this override here...
// TODO: Remove comments later, after next release, so that the fix is applied
p2p: {
disabledCodec: 'vp9',
preferredCodec: 'h264'
// disabledCodec: 'vp9',
// preferredCodec: 'vp8'
},
videoQuality: {
disabledCodec: 'vp9',
preferredCodec: 'vp8'
// disabledCodec: 'vp9',
// preferredCodec: 'vp8'
}
};
@@ -61,7 +64,7 @@ const INITIAL_RN_STATE: IConfig = {
* Mapping between old configs controlling the conference info headers visibility and the
* new configs. Needed in order to keep backwards compatibility.
*/
const CONFERENCE_HEADER_MAPPING = {
const CONFERENCE_HEADER_MAPPING: any = {
hideConferenceTimer: [ 'conference-timer' ],
hideConferenceSubject: [ 'subject' ],
hideParticipantsStats: [ 'participants-count' ],
@@ -81,7 +84,6 @@ export interface IConfigState extends IConfig {
domain: string;
muc: string;
};
p2p?: object;
websocket?: string;
};
}
@@ -385,10 +387,9 @@ function _translateLegacyConfig(oldValue: IConfig) {
} else {
newValue.conferenceInfo.alwaysVisible
= (newValue.conferenceInfo.alwaysVisible ?? [])
.filter(c => !CONFERENCE_HEADER_MAPPING[key as keyof typeof CONFERENCE_HEADER_MAPPING].includes(c));
.filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c));
newValue.conferenceInfo.autoHide
= (newValue.conferenceInfo.autoHide ?? []).filter(c =>
!CONFERENCE_HEADER_MAPPING[key as keyof typeof CONFERENCE_HEADER_MAPPING].includes(c));
= (newValue.conferenceInfo.autoHide ?? []).filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c));
}
});
}

View File

@@ -21,7 +21,6 @@ export interface IConnectionState {
getJid: () => string;
getLogs: () => Object;
initJitsiConference: Function;
removeFeature: Function;
};
error?: ConnectionFailedError;
locationURL?: URL;

View File

@@ -142,7 +142,7 @@ export function getAvailableDevices() {
if (mediaDevices.isDeviceListAvailable()
&& mediaDevices.isDeviceChangeAvailable()) {
mediaDevices.enumerateDevices((devices: MediaDeviceInfo[]) => {
mediaDevices.enumerateDevices((devices: any) => {
dispatch(updateDeviceList(devices));
resolve(devices);

View File

@@ -1,4 +1,4 @@
import { IReduxState, IStore } from '../../app/types';
import { IReduxState } from '../../app/types';
import JitsiMeetJS from '../lib-jitsi-meet';
import { updateSettings } from '../settings/actions';
import { ISettingsState } from '../settings/reducer';
@@ -251,7 +251,7 @@ export function getVideoDeviceIds(state: IReduxState) {
*/
export function setAudioOutputDeviceId(
newId = 'default',
dispatch: IStore['dispatch'],
dispatch: Function,
userSelection = false,
newLabel?: string): Promise<any> {

View File

@@ -2,7 +2,6 @@ import React, { PureComponent, ReactNode } from 'react';
import { SafeAreaView, ScrollView, View, ViewStyle } from 'react-native';
import { connect } from 'react-redux';
import { IStore } from '../../../../app/types';
import SlidingView from '../../../react/components/native/SlidingView';
import { hideSheet } from '../../actions';
@@ -26,7 +25,7 @@ type Props = {
/**
* Redux Dispatch function.
*/
dispatch: IStore['dispatch'];
dispatch: Function;
/**
* Handler for the cancel event, which happens when the user dismisses
@@ -37,7 +36,7 @@ type Props = {
/**
* Function to render a bottom sheet footer element, if necessary.
*/
renderFooter?: () => React.ReactNode;
renderFooter?: Function;
/**
* Function to render a bottom sheet header element, if necessary.
@@ -110,7 +109,9 @@ class BottomSheet extends PureComponent<Props> {
} = this.props;
return (
<SlidingView
<SlidingView // @ts-ignore
accessibilityRole = 'menu'
accessibilityViewIsModal = { true }
onHide = { this._onCancel }
position = 'bottom'
show = { Boolean(showSlidingView) }>

View File

@@ -18,7 +18,7 @@ interface IProps extends AbstractProps, WithTranslation {
/**
* The dialog descriptionKey.
*/
descriptionKey?: string;
descriptionKey: string;
/**
* An optional initial value to initiate the field with.

View File

@@ -1,4 +1,4 @@
// @ts-expect-error
// @ts-ignore
import { randomInt } from '@jitsi/js-utils/random';
import React, { Component } from 'react';
import { WithTranslation } from 'react-i18next';
@@ -11,6 +11,7 @@ import { isFatalJitsiConnectionError } from '../../../lib-jitsi-meet/functions.n
import { hideDialog } from '../../actions';
import logger from '../../logger';
// @ts-ignore
import ConfirmDialog from './ConfirmDialog';
@@ -38,7 +39,9 @@ interface IPageReloadDialogState {
* Shows a warning message and counts down towards the re-load.
*/
class PageReloadDialog extends Component<IPageReloadDialogProps, IPageReloadDialogState> {
_interval?: number;
// @ts-ignore
_interval: IntervalID;
_timeoutSeconds: number;
/**
@@ -102,7 +105,7 @@ class PageReloadDialog extends Component<IPageReloadDialogProps, IPageReloadDial
_onCancel() {
const { dispatch } = this.props;
clearInterval(this._interval ?? 0);
clearInterval(this._interval);
dispatch(appNavigate(undefined));
return true;
@@ -142,7 +145,7 @@ class PageReloadDialog extends Component<IPageReloadDialogProps, IPageReloadDial
_onReloadNow() {
const { dispatch } = this.props;
clearInterval(this._interval ?? 0);
clearInterval(this._interval);
dispatch(reloadNow());
return true;
@@ -197,6 +200,8 @@ function mapStateToProps(state: IReduxState) {
const { fatalError } = state['features/overlay'];
const fatalConnectionError
// @ts-ignore
= connectionError && isFatalJitsiConnectionError(connectionError);
const fatalConfigError = fatalError === configError;

View File

@@ -13,7 +13,7 @@ import { toState } from '../redux/functions';
* @returns {*} The value of the specified React {@code Component} prop of the
* currently mounted {@code App}.
*/
export function getFeatureFlag(stateful: IStateful, flag: string, defaultValue?: boolean | string) {
export function getFeatureFlag(stateful: IStateful, flag: string, defaultValue?: any) {
const state = toState(stateful)['features/base/flags'];
if (state) {

View File

@@ -1,7 +1,7 @@
// @ts-expect-error
// @ts-ignore
import Bourne from '@hapi/bourne';
// eslint-disable-next-line lines-around-comment
// @ts-expect-error
// @ts-ignore
import { jitsiLocalStorage } from '@jitsi/js-utils/jitsi-local-storage';
import { browser } from '../lib-jitsi-meet';

View File

@@ -1,4 +1,4 @@
// @ts-expect-error
// @ts-ignore
import jwtDecode from 'jwt-decode';
import { IReduxState } from '../../app/types';

View File

@@ -1,4 +1,4 @@
// @ts-expect-error
// @ts-ignore
import jwtDecode from 'jwt-decode';
import { AnyAction } from 'redux';
@@ -226,15 +226,9 @@ function _undoOverwriteLocalParticipant(
* }}
*/
function _user2participant({ avatar, avatarUrl, email, id, name, 'hidden-from-recorder': hiddenFromRecorder }:
{ avatar?: string; avatarUrl?: string; email: string; 'hidden-from-recorder': string | boolean;
{ avatar: any; avatarUrl: string; email: string; 'hidden-from-recorder': string | boolean;
id: string; name: string; }) {
const participant: {
avatarURL?: string;
email?: string;
hiddenFromRecorder?: boolean;
id?: string;
name?: string;
} = {};
const participant: any = {};
if (typeof avatarUrl === 'string') {
participant.avatarURL = avatarUrl.trim();

View File

@@ -1,9 +1,10 @@
// @ts-expect-error
// @ts-ignore
import { jitsiLocalStorage } from '@jitsi/js-utils';
import { IStore } from '../../app/types';
import { isOnline } from '../net-info/selectors';
// @ts-ignore
import JitsiMeetJS from './_';
import {
LIB_DID_DISPOSE,

View File

@@ -1,7 +1,7 @@
import { IStateful } from '../app/types';
import { ConnectionFailedError } from '../connection/actions.any';
import { toState } from '../redux/functions';
// @ts-ignore
import JitsiMeetJS from './_';
@@ -91,7 +91,7 @@ export function isFatalJitsiConferenceError(error: Error | string) {
* indicates a fatal {@code JitsiConnection} error, {@code true}; otherwise,
* {@code false}.
*/
export function isFatalJitsiConnectionError(error: Error | string | ConnectionFailedError) {
export function isFatalJitsiConnectionError(error: Error | string) {
if (typeof error !== 'string') {
error = error.name; // eslint-disable-line no-param-reassign
}

View File

@@ -1,4 +1,4 @@
// @ts-expect-error
// @ts-ignore
import Bourne from '@hapi/bourne';
import { NativeModules } from 'react-native';

View File

@@ -1,5 +1,6 @@
// Re-export JitsiMeetJS from the library lib-jitsi-meet to (the other features
// of) the project jitsi-meet.
// @ts-ignore
import JitsiMeetJS from './_';
export { JitsiMeetJS as default };

View File

@@ -6,6 +6,7 @@ import { SET_NETWORK_INFO } from '../net-info/actionTypes';
import { PARTICIPANT_LEFT } from '../participants/actionTypes';
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
// @ts-ignore
import JitsiMeetJS from './_';
import { LIB_WILL_INIT } from './actionTypes';
import { disposeLib, initLib } from './actions';

View File

@@ -1,4 +1,3 @@
import { IStore } from '../../app/types';
import RTCStats from '../../rtcstats/RTCStats';
import { canSendRtcstatsData } from '../../rtcstats/functions';
import { getCurrentConference } from '../conference/functions';
@@ -9,14 +8,14 @@ import { getCurrentConference } from '../conference/functions';
*/
export default class JitsiMeetLogStorage {
counter: number;
getState: IStore['getState'];
getState: Function;
/**
* Creates new <tt>JitsiMeetLogStorage</tt>.
*
* @param {Function} getState - The Redux store's {@code getState} method.
*/
constructor(getState: IStore['getState']) {
constructor(getState: Function) {
/**
* Counts each log entry, increases on every batch log entry stored.
*
@@ -91,7 +90,7 @@ export default class JitsiMeetLogStorage {
storeLogsCallstats(logEntries: Array<string | any>) {
const conference = getCurrentConference(this.getState());
if (!conference?.isCallstatsEnabled()) {
if (!conference || !conference.isCallstatsEnabled()) {
// Discard the logs if CallStats is not enabled.
return;
}

View File

@@ -1,6 +1,6 @@
import { NativeModules } from 'react-native';
// eslint-disable-next-line lines-around-comment
// @ts-expect-error
// @ts-ignore
import { format } from 'util';
// Some code adapted from https://github.com/houserater/react-native-lumberjack

View File

@@ -1,4 +1,4 @@
// @ts-expect-error
// @ts-ignore
import Logger, { getLogger as _getLogger } from '@jitsi/logger';
import _ from 'lodash';

View File

@@ -1,6 +1,5 @@
// @ts-expect-error
// @ts-ignore
import Logger from '@jitsi/logger';
import { AnyAction } from 'redux';
import { IStore } from '../../app/types';
import { APP_WILL_MOUNT } from '../app/actionTypes';
@@ -62,7 +61,7 @@ MiddlewareRegistry.register(store => next => action => {
* @returns {Object} The new state that is the result of the reduction of the
* specified {@code action}.
*/
function _appWillMount({ getState }: IStore, next: Function, action: AnyAction) {
function _appWillMount({ getState }: IStore, next: Function, action: any) {
const { config } = getState()['features/base/logging'];
_setLogLevels(Logger, config);
@@ -88,7 +87,7 @@ function _appWillMount({ getState }: IStore, next: Function, action: AnyAction)
* @private
* @returns {*}
*/
function _conferenceJoined({ getState }: IStore, next: Function, action: AnyAction) {
function _conferenceJoined({ getState }: IStore, next: Function, action: any) {
// Wait until the joined event is processed, so that the JitsiMeetLogStorage
// will be ready.
@@ -192,7 +191,7 @@ function _initLogging({ dispatch, getState }: IStore,
* @returns {Object} The new state that is the result of the reduction of the
* specified {@code action}.
*/
function _libWillInit({ getState }: IStore, next: Function, action: AnyAction) {
function _libWillInit({ getState }: IStore, next: Function, action: any) {
// Adding the if in order to preserve the logic for web after enabling
// LIB_WILL_INIT action for web in initLib action.
if (typeof APP === 'undefined') {
@@ -216,7 +215,7 @@ function _libWillInit({ getState }: IStore, next: Function, action: AnyAction) {
* @returns {Object} The new state that is the result of the reduction of the
* specified action.
*/
function _setConfig({ dispatch }: IStore, next: Function, action: AnyAction) {
function _setConfig({ dispatch }: IStore, next: Function, action: any) {
const result = next(action);
dispatch(setLoggingConfig(action.config?.logging));
@@ -239,7 +238,7 @@ function _setConfig({ dispatch }: IStore, next: Function, action: AnyAction) {
* specified {@code action}.
*/
function _setLoggingConfig({ dispatch, getState }: IStore,
next: Function, action: AnyAction) {
next: Function, action: any) {
const result = next(action);
const newValue = getState()['features/base/logging'].config;
const isTestingEnabled = isTestModeEnabled(getState());

View File

@@ -1,5 +1,4 @@
import _ from 'lodash';
import { AnyAction } from 'redux';
import ReducerRegistry from '../redux/ReducerRegistry';
import { equals, set } from '../redux/functions';
@@ -95,7 +94,7 @@ ReducerRegistry.register<ILoggingState>(
* @returns {Object} The new state of the feature base/logging after the
* reduction of the specified action.
*/
function _setLoggingConfig(state: ILoggingState, action: AnyAction) {
function _setLoggingConfig(state: ILoggingState, action: any) {
const newConfig = _.merge({}, DEFAULT_STATE.config, action.config);
if (equals(state.config, newConfig)) {
@@ -118,6 +117,6 @@ function _setLoggingConfig(state: ILoggingState, action: AnyAction) {
* @returns {Object} The new state of the feature base/logging after the
* reduction of the specified action.
*/
function _setLogCollector(state: ILoggingState, action: AnyAction) {
function _setLogCollector(state: ILoggingState, action: any) {
return set(state, 'logCollector', action.logCollector);
}

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