Compare commits

..

2 Commits

Author SHA1 Message Date
damencho
4f0f8ea019 fix(tests): Skip iframeAPI if it is disabled. 2025-02-26 14:35:11 -06:00
damencho
444f4a7abc feat(tests): Adds an option for an access jwt token.
Used only for the first participant joining/creating the room.
2025-02-25 09:17:58 -06:00
471 changed files with 2473 additions and 4327 deletions

View File

@@ -18,7 +18,7 @@ jobs:
npm -v
- name: Get changed files
id: changed-files
uses: jitsi/changed-files@main
uses: tj-actions/changed-files@v41
- 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"

View File

@@ -30,12 +30,9 @@ import android.view.KeyEvent;
import androidx.annotation.Nullable;
import com.oney.WebRTCModule.WebRTCModuleOptions;
import org.jitsi.meet.sdk.JitsiMeet;
import org.jitsi.meet.sdk.JitsiMeetActivity;
import org.jitsi.meet.sdk.JitsiMeetConferenceOptions;
import org.webrtc.Logging;
import java.lang.reflect.Method;
import java.net.URL;
@@ -82,10 +79,6 @@ public class MainActivity extends JitsiMeetActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
JitsiMeet.showSplashScreen(this);
WebRTCModuleOptions options = WebRTCModuleOptions.getInstance();
options.loggingSeverity = Logging.Severity.LS_ERROR;
super.onCreate(null);
}

View File

@@ -89,11 +89,9 @@ dependencies {
implementation project(':react-native-splash-screen')
implementation project(':react-native-svg')
implementation project(':react-native-video')
implementation project(':react-native-webrtc')
implementation project(':react-native-webview')
// Use `api` here so consumers can use WebRTCModuleOptions.
api project(':react-native-webrtc')
testImplementation 'junit:junit:4.12'
}

View File

@@ -3,6 +3,12 @@ package org.jitsi.meet.sdk;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.bridge.WritableNativeMap;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.util.HashMap;
/**
* Wraps the name and extra data for events that were broadcasted locally.
*/
@@ -10,21 +16,57 @@ public class BroadcastAction {
private static final String TAG = BroadcastAction.class.getSimpleName();
private final Type type;
private final Bundle data;
private final HashMap<String, Object> data;
public BroadcastAction(Intent intent) {
this.type = Type.buildTypeFromAction(intent.getAction());
this.data = intent.getExtras();
this.data = buildDataFromBundle(intent.getExtras());
}
public Type getType() {
return this.type;
}
public Bundle getData() {
public HashMap<String, Object> getData() {
return this.data;
}
public WritableNativeMap getDataAsWritableNativeMap() {
WritableNativeMap nativeMap = new WritableNativeMap();
for (String key : this.data.keySet()) {
try {
if (this.data.get(key) instanceof Boolean) {
nativeMap.putBoolean(key, (Boolean) this.data.get(key));
} else if (this.data.get(key) instanceof Integer) {
nativeMap.putInt(key, (Integer) this.data.get(key));
} else if (this.data.get(key) instanceof Double) {
nativeMap.putDouble(key, (Double) this.data.get(key));
} else if (this.data.get(key) instanceof String) {
nativeMap.putString(key, (String) this.data.get(key));
} else {
throw new Exception("Unsupported extra data type");
}
} catch (Exception e) {
JitsiMeetLogger.w(TAG + " invalid extra data in event", e);
}
}
return nativeMap;
}
private static HashMap<String, Object> buildDataFromBundle(Bundle bundle) {
HashMap<String, Object> map = new HashMap<>();
if (bundle != null) {
for (String key : bundle.keySet()) {
map.put(key, bundle.get(key));
}
}
return map;
}
enum Type {
SET_AUDIO_MUTED("org.jitsi.meet.SET_AUDIO_MUTED"),
HANG_UP("org.jitsi.meet.HANG_UP"),
@@ -40,9 +82,7 @@ public class BroadcastAction {
SHOW_NOTIFICATION("org.jitsi.meet.SHOW_NOTIFICATION"),
HIDE_NOTIFICATION("org.jitsi.meet.HIDE_NOTIFICATION"),
START_RECORDING("org.jitsi.meet.START_RECORDING"),
STOP_RECORDING("org.jitsi.meet.STOP_RECORDING"),
OVERWRITE_CONFIG("org.jitsi.meet.OVERWRITE_CONFIG"),
SEND_CAMERA_FACING_MODE_MESSAGE("org.jitsi.meet.SEND_CAMERA_FACING_MODE_MESSAGE");
STOP_RECORDING("org.jitsi.meet.STOP_RECORDING");
private final String action;

View File

@@ -91,9 +91,7 @@ public class BroadcastEvent {
VIDEO_MUTED_CHANGED("org.jitsi.meet.VIDEO_MUTED_CHANGED"),
READY_TO_CLOSE("org.jitsi.meet.READY_TO_CLOSE"),
TRANSCRIPTION_CHUNK_RECEIVED("org.jitsi.meet.TRANSCRIPTION_CHUNK_RECEIVED"),
CUSTOM_BUTTON_PRESSED("org.jitsi.meet.CUSTOM_BUTTON_PRESSED"),
CONFERENCE_UNIQUE_ID_SET("org.jitsi.meet.CONFERENCE_UNIQUE_ID_SET"),
RECORDING_STATUS_CHANGED("org.jitsi.meet.RECORDING_STATUS_CHANGED");
CUSTOM_BUTTON_PRESSED("org.jitsi.meet.CUSTOM_BUTTON_PRESSED");
private static final String CONFERENCE_BLURRED_NAME = "CONFERENCE_BLURRED";
private static final String CONFERENCE_FOCUSED_NAME = "CONFERENCE_FOCUSED";
@@ -112,8 +110,6 @@ public class BroadcastEvent {
private static final String READY_TO_CLOSE_NAME = "READY_TO_CLOSE";
private static final String TRANSCRIPTION_CHUNK_RECEIVED_NAME = "TRANSCRIPTION_CHUNK_RECEIVED";
private static final String CUSTOM_BUTTON_PRESSED_NAME = "CUSTOM_BUTTON_PRESSED";
private static final String CONFERENCE_UNIQUE_ID_SET_NAME = "CONFERENCE_UNIQUE_ID_SET";
private static final String RECORDING_STATUS_CHANGED_NAME = "RECORDING_STATUS_CHANGED";
private final String action;
@@ -170,10 +166,6 @@ public class BroadcastEvent {
return TRANSCRIPTION_CHUNK_RECEIVED;
case CUSTOM_BUTTON_PRESSED_NAME:
return CUSTOM_BUTTON_PRESSED;
case CONFERENCE_UNIQUE_ID_SET_NAME:
return CONFERENCE_UNIQUE_ID_SET;
case RECORDING_STATUS_CHANGED_NAME:
return RECORDING_STATUS_CHANGED;
}
return null;

View File

@@ -139,19 +139,4 @@ public class BroadcastIntentHelper {
return intent;
}
public static Intent buildOverwriteConfigIntent(Bundle config) {
Intent intent = new Intent(BroadcastAction.Type.OVERWRITE_CONFIG.getAction());
intent.putExtra("config", config);
return intent;
}
public static Intent buildSendCameraFacingModeMessageIntent(String to, String facingMode) {
Intent intent = new Intent(BroadcastAction.Type.SEND_CAMERA_FACING_MODE_MESSAGE.getAction());
intent.putExtra("to", to);
intent.putExtra("facingMode", facingMode);
return intent;
}
}

View File

@@ -3,9 +3,6 @@ package org.jitsi.meet.sdk;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import com.facebook.react.bridge.Arguments;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
@@ -31,14 +28,7 @@ public class BroadcastReceiver extends android.content.BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
BroadcastAction action = new BroadcastAction(intent);
String actionName = action.getType().getAction();
Bundle data = action.getData();
// For actions without data bundle (like hangup), we create an empty map
// instead of attempting to convert a null bundle to avoid crashes.
if (data != null) {
ReactInstanceManagerHolder.emitEvent(actionName, Arguments.fromBundle(data));
} else {
ReactInstanceManagerHolder.emitEvent(actionName, Arguments.createMap());
}
ReactInstanceManagerHolder.emitEvent(actionName, action.getDataAsWritableNativeMap());
}
}

View File

@@ -101,8 +101,6 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
constants.put("HIDE_NOTIFICATION", BroadcastAction.Type.HIDE_NOTIFICATION.getAction());
constants.put("START_RECORDING", BroadcastAction.Type.START_RECORDING.getAction());
constants.put("STOP_RECORDING", BroadcastAction.Type.STOP_RECORDING.getAction());
constants.put("OVERWRITE_CONFIG", BroadcastAction.Type.OVERWRITE_CONFIG.getAction());
constants.put("SEND_CAMERA_FACING_MODE_MESSAGE", BroadcastAction.Type.SEND_CAMERA_FACING_MODE_MESSAGE.getAction());
return constants;
}

View File

@@ -272,16 +272,8 @@ public class JitsiMeetActivity extends AppCompatActivity
// }
// protected void onCustomButtonPressed(HashMap<String, Object> extraData) {
// JitsiMeetLogger.i("Custom button pressed: " + extraData);
// }
// protected void onConferenceUniqueIdSet(HashMap<String, Object> extraData) {
// JitsiMeetLogger.i("Conference unique id set: " + extraData);
// }
// protected void onRecordingStatusChanged(HashMap<String, Object> extraData) {
// JitsiMeetLogger.i("Recording status changed: " + extraData);
// }
// JitsiMeetLogger.i("Custom button pressed: " + extraData);
// }
// Activity lifecycle methods
//
@@ -366,18 +358,12 @@ public class JitsiMeetActivity extends AppCompatActivity
case READY_TO_CLOSE:
onReadyToClose();
break;
// case TRANSCRIPTION_CHUNK_RECEIVED:
// onTranscriptionChunkReceived(event.getData());
// break;
// case CUSTOM_BUTTON_PRESSED:
// onCustomButtonPressed(event.getData());
// break;
// case CONFERENCE_UNIQUE_ID_SET:
// onConferenceUniqueIdSet(event.getData());
// break;
// case RECORDING_STATUS_CHANGED:
// onRecordingStatusChanged(event.getData());
// break;
// case TRANSCRIPTION_CHUNK_RECEIVED:
// onTranscriptionChunkReceived(event.getData());
// break;
// case CUSTOM_BUTTON_PRESSED:
// onCustomButtonPressed(event.getData());
// break;
}
}
}

View File

@@ -33,9 +33,10 @@ import org.jitsi.meet.sdk.log.JitsiMeetLogger;
public class JitsiMeetView extends FrameLayout {
/**
* Background color. Should match the background color set in JS.
* Background color used by {@code BaseReactView} and the React Native root
* view.
*/
private static final int BACKGROUND_COLOR = 0xFF040404;
private static final int BACKGROUND_COLOR = 0xFF111111;
/**
* React Native root view.

View File

@@ -1,80 +0,0 @@
package org.jitsi.meet.sdk;
/*
* Copyright 2017 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
import androidx.annotation.Nullable;
import com.oney.WebRTCModule.webrtcutils.SoftwareVideoDecoderFactoryProxy;
import org.webrtc.EglBase;
import org.webrtc.HardwareVideoDecoderFactory;
import org.webrtc.PlatformSoftwareVideoDecoderFactory;
import org.webrtc.VideoCodecInfo;
import org.webrtc.VideoDecoder;
import org.webrtc.VideoDecoderFactory;
import org.webrtc.VideoDecoderFallback;
import java.util.Arrays;
import java.util.LinkedHashSet;
/**
* Custom decoder factory which uses HW decoders and falls back to SW.
*/
public class JitsiVideoDecoderFactory implements VideoDecoderFactory {
private final VideoDecoderFactory hardwareVideoDecoderFactory;
private final VideoDecoderFactory softwareVideoDecoderFactory = new SoftwareVideoDecoderFactoryProxy();
private final @Nullable VideoDecoderFactory platformSoftwareVideoDecoderFactory;
/**
* Create decoder factory using default hardware decoder factory.
*/
public JitsiVideoDecoderFactory(@Nullable EglBase.Context eglContext) {
this.hardwareVideoDecoderFactory = new HardwareVideoDecoderFactory(eglContext);
this.platformSoftwareVideoDecoderFactory = new PlatformSoftwareVideoDecoderFactory(eglContext);
}
/**
* Create decoder factory using explicit hardware decoder factory.
*/
JitsiVideoDecoderFactory(VideoDecoderFactory hardwareVideoDecoderFactory) {
this.hardwareVideoDecoderFactory = hardwareVideoDecoderFactory;
this.platformSoftwareVideoDecoderFactory = null;
}
@Override
public @Nullable VideoDecoder createDecoder(VideoCodecInfo codecType) {
VideoDecoder softwareDecoder = softwareVideoDecoderFactory.createDecoder(codecType);
final VideoDecoder hardwareDecoder = hardwareVideoDecoderFactory.createDecoder(codecType);
if (softwareDecoder == null && platformSoftwareVideoDecoderFactory != null) {
softwareDecoder = platformSoftwareVideoDecoderFactory.createDecoder(codecType);
}
if (hardwareDecoder != null && softwareDecoder != null) {
// Both hardware and software supported, wrap it in a software fallback
return new VideoDecoderFallback(
/* fallback= */ softwareDecoder, /* primary= */ hardwareDecoder);
}
return hardwareDecoder != null ? hardwareDecoder : softwareDecoder;
}
@Override
public VideoCodecInfo[] getSupportedCodecs() {
LinkedHashSet<VideoCodecInfo> supportedCodecInfos = new LinkedHashSet<>();
supportedCodecInfos.addAll(Arrays.asList(softwareVideoDecoderFactory.getSupportedCodecs()));
supportedCodecInfos.addAll(Arrays.asList(hardwareVideoDecoderFactory.getSupportedCodecs()));
if (platformSoftwareVideoDecoderFactory != null) {
supportedCodecInfos.addAll(
Arrays.asList(platformSoftwareVideoDecoderFactory.getSupportedCodecs()));
}
return supportedCodecInfos.toArray(new VideoCodecInfo[supportedCodecInfos.size()]);
}
}

View File

@@ -1,16 +0,0 @@
package org.jitsi.meet.sdk;
import androidx.annotation.Nullable;
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoEncoderFactory;
import org.webrtc.EglBase;
/**
* Custom encoder factory which uses HW for H.264 and SW for everything else.
*/
public class JitsiVideoEncoderFactory extends H264AndSoftwareVideoEncoderFactory {
public JitsiVideoEncoderFactory(@Nullable EglBase.Context eglContext) {
super(eglContext);
}
}

View File

@@ -16,8 +16,8 @@
package org.jitsi.meet.sdk;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.util.Log;
import androidx.annotation.Nullable;
@@ -32,10 +32,12 @@ import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.ViewManager;
import com.oney.WebRTCModule.EglUtils;
import com.oney.WebRTCModule.WebRTCModuleOptions;
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoDecoderFactory;
import com.oney.WebRTCModule.webrtcutils.H264AndSoftwareVideoEncoderFactory;
import org.devio.rn.splashscreen.SplashScreenModule;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import org.webrtc.EglBase;
import org.webrtc.Logging;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
@@ -124,31 +126,31 @@ class ReactInstanceManagerHolder {
// AmplitudeReactNativePackage
try {
Class<?> amplitudePackageClass = Class.forName("com.amplitude.reactnative.AmplitudeReactNativePackage");
Constructor<?> constructor = amplitudePackageClass.getConstructor();
Constructor constructor = amplitudePackageClass.getConstructor();
packages.add((ReactPackage)constructor.newInstance());
} catch (Exception e) {
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
JitsiMeetLogger.d(TAG, "Not loading AmplitudeReactNativePackage");
Log.d(TAG, "Not loading AmplitudeReactNativePackage");
}
// GiphyReactNativeSdkPackage
try {
Class<?> giphyPackageClass = Class.forName("com.giphyreactnativesdk.GiphyReactNativeSdkPackage");
Constructor<?> constructor = giphyPackageClass.getConstructor();
Constructor constructor = giphyPackageClass.getConstructor();
packages.add((ReactPackage)constructor.newInstance());
} catch (Exception e) {
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
JitsiMeetLogger.d(TAG, "Not loading GiphyReactNativeSdkPackage");
Log.d(TAG, "Not loading GiphyReactNativeSdkPackage");
}
// RNGoogleSignInPackage
try {
Class<?> googlePackageClass = Class.forName("com.reactnativegooglesignin.RNGoogleSigninPackage");
Constructor<?> constructor = googlePackageClass.getConstructor();
Constructor constructor = googlePackageClass.getConstructor();
packages.add((ReactPackage)constructor.newInstance());
} catch (Exception e) {
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
JitsiMeetLogger.d(TAG, "Not loading RNGoogleSignInPackage");
Log.d(TAG, "Not loading RNGoogleSignInPackage");
}
return packages;
@@ -167,7 +169,7 @@ class ReactInstanceManagerHolder {
= ReactInstanceManagerHolder.getReactInstanceManager();
if (reactInstanceManager != null) {
@SuppressLint("VisibleForTests") ReactContext reactContext
ReactContext reactContext
= reactInstanceManager.getCurrentReactContext();
if (reactContext != null) {
@@ -190,7 +192,7 @@ class ReactInstanceManagerHolder {
*/
static <T extends NativeModule> T getNativeModule(
Class<T> nativeModuleClass) {
@SuppressLint("VisibleForTests") ReactContext reactContext
ReactContext reactContext
= reactInstanceManager != null
? reactInstanceManager.getCurrentReactContext() : null;
@@ -217,18 +219,15 @@ class ReactInstanceManagerHolder {
// Initialize the WebRTC module options.
WebRTCModuleOptions options = WebRTCModuleOptions.getInstance();
options.enableMediaProjectionService = true;
if (options.videoDecoderFactory == null || options.videoEncoderFactory == null) {
EglBase.Context eglContext = EglUtils.getRootEglBaseContext();
if (options.videoDecoderFactory == null) {
options.videoDecoderFactory = new JitsiVideoDecoderFactory(eglContext);
}
if (options.videoEncoderFactory == null) {
options.videoEncoderFactory = new JitsiVideoEncoderFactory(eglContext);
}
}
JitsiMeetLogger.d(TAG, "initializing RN");
EglBase.Context eglContext = EglUtils.getRootEglBaseContext();
options.videoDecoderFactory = new H264AndSoftwareVideoDecoderFactory(eglContext);
options.videoEncoderFactory = new H264AndSoftwareVideoEncoderFactory(eglContext);
options.enableMediaProjectionService = true;
// options.loggingSeverity = Logging.Severity.LS_INFO;
Log.d(TAG, "initializing RN with Activity");
reactInstanceManager
= ReactInstanceManager.builder()

View File

@@ -2278,10 +2278,8 @@ export default {
* @param {boolean} [requestFeedback=false] if user feedback should be
* @param {string} [hangupReason] the reason for leaving the meeting
* requested
* @param {boolean} [notifyOnConferenceTermination] whether to notify
* the user on conference termination
*/
hangup(requestFeedback = false, hangupReason, notifyOnConferenceTermination) {
hangup(requestFeedback = false, hangupReason) {
APP.store.dispatch(disableReceiver());
this._stopProxyConnection();
@@ -2300,7 +2298,7 @@ export default {
if (requestFeedback) {
const feedbackDialogClosed = (feedbackResult = {}) => {
if (!feedbackResult.wasDialogShown && hangupReason && notifyOnConferenceTermination) {
if (!feedbackResult.wasDialogShown && hangupReason) {
return APP.store.dispatch(
openLeaveReasonDialog(hangupReason)).then(() => feedbackResult);
}

View File

@@ -393,9 +393,6 @@ var config = {
// // showPrejoinWarning: true,
// // If true, the notification for recording start will display a link to download the cloud recording.
// // showRecordingLink: true,
// // If true, mutes audio and video when a recording begins and displays a dialog
// // explaining the effect of unmuting.
// // requireConsent: true,
// },
// recordingService: {
@@ -755,9 +752,6 @@ var config = {
// and microsoftApiApplicationClientID
// enableCalendarIntegration: false,
// Whether to notify when the conference is terminated because it was destroyed.
// notifyOnConferenceDestruction: true,
// The client id for the google APIs used for the calendar integration, youtube livestreaming, etc.
// googleApiApplicationClientID: '<client_id>',
@@ -1378,12 +1372,8 @@ var config = {
The config file should be in JSON.
None of the fields are mandatory and the response must have the shape:
{
// Whether participant can only send group chat message if `send-groupchat` feature is enabled in jwt.
groupChatRequiresPermission: false,
// Whether participant can only create polls if `create-polls` feature is enabled in jwt.
pollCreationRequiresPermission: false,
// The domain url to apply (will replace the domain in the sharing conference link/embed section)
inviteDomain: 'example-company.org',
inviteDomain: 'example-company.org,
// The hex value for the colour used as background
backgroundColor: '#fff',
// The url for the image used as background
@@ -1571,8 +1561,6 @@ var config = {
// You can enable tokenAuthUrlAutoRedirect which will detect that you have logged in successfully before
// and will automatically redirect to the token service to get the token for the meeting.
// tokenAuthUrlAutoRedirect: false
// An option to respect the context.tenant jwt field compared to the current tenant from the url
// tokenRespectTenant: false,
// You can put an array of values to target different entity types in the invite dialog.
// Valid values are "phone", "room", "sip", "user", "videosipgw" and "email"

View File

@@ -111,7 +111,7 @@ form {
height: $watermarkHeight;
background-size: contain;
background-repeat: no-repeat;
z-index: $watermarkZ;
z-index: $zindex2;
}
.leftwatermark {
@@ -142,7 +142,7 @@ form {
font-size: 11pt;
color: rgba(255,255,255,.50);
text-decoration: none;
z-index: $watermarkZ;
z-index: 100;
}
/**

View File

@@ -7,8 +7,8 @@
display: flex;
flex-direction: column;
position: relative;
overflow-y: auto;
flex-grow: 1;
overflow: auto;
width: 100%;
.meetings-list-empty {
text-align: center;
@@ -174,12 +174,4 @@
}
}
}
@media (max-width: 1024px) { /* Targets iPads and smaller devices */
.item {
.delete-meeting {
display: block !important;
}
}
}
}

View File

@@ -53,10 +53,7 @@
}
.welcome-footer-row-block {
display: flex;
flex-direction: column;
gap:12px;
align-items: center;
display: block;
}
}
}

View File

@@ -38,8 +38,6 @@ $zindex1: 1;
$zindex2: 2;
$zindex3: 3;
$toolbarZ: 250;
$watermarkZ: 253;
// Place filmstrip videos over toolbar in order
// to make connection info visible.
$filmstripVideosZ: $toolbarZ + 1;
@@ -77,12 +75,9 @@ $welcomePageHeaderBackground: linear-gradient(0deg, rgba(0, 0, 0, 0.2), rgba(0,
$welcomePageHeaderBackgroundPosition: center;
$welcomePageHeaderBackgroundRepeat: none;
$welcomePageHeaderBackgroundSize: cover;
$welcomePageHeaderPadding: 1rem;
$welcomePageHeaderPaddingBottom: 15px;
$welcomePageHeaderTitleMaxWidth: initial;
$welcomePageHeaderTextAlign: center;
$welcomePageButtonBg: #0074E0;
$welcomePageButtonHoverBg: #4687ED;
$welcomePageButtonFocusOutline: #00225A;
$welcomePageHeaderContainerMarginTop: 104px;
$welcomePageHeaderContainerDisplay: flex;

View File

@@ -18,7 +18,7 @@ body.welcome-page {
background-position: $welcomePageHeaderBackgroundPosition;
background-repeat: $welcomePageHeaderBackgroundRepeat;
background-size: $welcomePageHeaderBackgroundSize;
padding: $welcomePageHeaderPadding;
padding-bottom: $welcomePageHeaderPaddingBottom;
background-color: #131519;
overflow: hidden;
position: relative;
@@ -219,18 +219,14 @@ body.welcome-page {
.welcome-page-button {
border: 0;
font-size: 14px;
background: $welcomePageButtonBg;
background: #0074E0;
border-radius: 3px;
color: #FFFFFF;
cursor: pointer;
padding: 16px 20px;
transition: all 0.2s;
&:focus-within {
outline: auto 2px $welcomePageButtonFocusOutline;
}
&:hover {
background-color: $welcomePageButtonHoverBg;
&:focus-within {
outline: auto 2px #022e61;
}
}
@@ -268,7 +264,8 @@ body.welcome-page {
&.without-content {
.welcome-card {
max-width: 100dvw;
min-width: 500px;
max-width: 580px;
}
}
@@ -349,6 +346,6 @@ body.welcome-page {
.welcome-footer-row-1-text {
max-width: 200px;
text-align: center;
margin-right: 16px;
}
}

View File

@@ -131,6 +131,16 @@ case "$1" in
fi
fi
if [ "$PROSODY_CREATE_JICOFO_USER" = "true" ]; then
# create 'focus@auth.domain' prosody user
prosodyctl register $JICOFO_AUTH_USER $JICOFO_AUTH_DOMAIN $JICOFO_AUTH_PASSWORD
# trigger a restart
PROSODY_CONFIG_PRESENT="false"
fi
# creates the user if it does not exist
echo -e "$JVB_SECRET\n$JVB_SECRET" | prosodyctl adduser jvb@$JICOFO_AUTH_DOMAIN > /dev/null || true
# Check whether prosody config has the internal muc, if not add it,
# as we are migrating configs
if [ -f $PROSODY_HOST_CONFIG ] && ! grep -q "internal.$JICOFO_AUTH_DOMAIN" $PROSODY_HOST_CONFIG; then
@@ -174,12 +184,6 @@ case "$1" in
PROSODY_CONFIG_PRESENT="false"
fi
# Since prosody 13 admins are not automatically room owners and we expect that for jicofo
if ! grep -q -- 'component_admins_as_room_owners = ' $PROSODY_HOST_CONFIG ;then
sed -i "1s/^/component_admins_as_room_owners = true\n/" $PROSODY_HOST_CONFIG
PROSODY_CONFIG_PRESENT="false"
fi
JAAS_HOST_CONFIG="/etc/prosody/conf.avail/jaas.cfg.lua"
if [ "${JAAS_INPUT}" = "true" ] && [ ! -f $JAAS_HOST_CONFIG ]; then
sed -i "s/enabled = false -- Jitsi meet components/enabled = true -- Jitsi meet components/g" $PROSODY_HOST_CONFIG
@@ -203,6 +207,9 @@ case "$1" in
fi
fi
# Make sure the focus@auth user's roster includes the proxy component (this is idempotent)
prosodyctl mod_roster_command subscribe focus.$JVB_HOSTNAME $JICOFO_AUTH_USER@$JICOFO_AUTH_DOMAIN
if [ ! -f /var/lib/prosody/$JVB_HOSTNAME.crt ]; then
# prosodyctl takes care for the permissions
# echo for using all default values
@@ -245,29 +252,6 @@ case "$1" in
if [ "$PROSODY_CONFIG_PRESENT" = "false" ]; then
invoke-rc.d prosody restart || true
# give it some time to warm up
sleep 10
if [ "$PROSODY_CREATE_JICOFO_USER" = "true" ]; then
# create 'focus@auth.domain' prosody user
echo -e "$JICOFO_AUTH_PASSWORD\n$JICOFO_AUTH_PASSWORD" | prosodyctl adduser $JICOFO_AUTH_USER@$JICOFO_AUTH_DOMAIN > /dev/null || true
# trigger a restart
PROSODY_CONFIG_PRESENT="false"
fi
# creates the user if it does not exist
echo -e "$JVB_SECRET\n$JVB_SECRET" | prosodyctl adduser jvb@$JICOFO_AUTH_DOMAIN > /dev/null || true
# Make sure the focus@auth user's roster includes the proxy component (this is idempotent)
prosodyctl mod_roster_command subscribe focus.$JVB_HOSTNAME $JICOFO_AUTH_USER@$JICOFO_AUTH_DOMAIN
# To make sure the roster command is loaded
# Once we have https://issues.prosody.im/1908 we can start using prosodyctl shell roster subscribe
# and drop the wait and the prosody restart
sleep 1
invoke-rc.d prosody restart || true
# In case we had updated the certificates and restarted prosody, let's restart and the bridge and jicofo if possible
if [ -d /run/systemd/system ] && [ "$CERT_ADDED_TO_TRUST" = "true" ]; then
systemctl restart jitsi-videobridge2.service >/dev/null || true

View File

@@ -1,6 +1,3 @@
-- We need this for prosody 13.0
component_admins_as_room_owners = true
plugin_paths = { "/usr/share/jitsi-meet/prosody-plugins/" }
-- domain mapper options, must at least have domain base set to use the mapper

View File

@@ -97,7 +97,4 @@ post_install do |installer|
config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -no-verify-emitted-module-interface'
end
end
# Patch SocketRocket to support TLS 1.3
%x(patch Pods/SocketRocket/SocketRocket/SRSecurityPolicy.m -N < patches/ws-tls13.diff)
end

View File

@@ -2209,6 +2209,6 @@ SPEC CHECKSUMS:
SocketRocket: abac6f5de4d4d62d24e11868d7a2f427e0ef940d
Yoga: 1dd9dabb9df8fe08f12cd522eae04a2da0e252eb
PODFILE CHECKSUM: 4f6abcf3cec0d9e8e1d5f5d81a35d99adde9ae45
PODFILE CHECKSUM: 8a3e5d019861b37d4159f2d178cc534be3ac528c
COCOAPODS: 1.16.2

View File

@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
0B412F1F1EDEE6E800B1A0A6 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */; };
0B412F211EDEE95300B1A0A6 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0B412F201EDEE95300B1A0A6 /* Main.storyboard */; };
0B5418471F7C5D8C00A2DD86 /* MeetingRowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */; };
0B7001701F7C51CC005944F4 /* InCallController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B70016F1F7C51CC005944F4 /* InCallController.swift */; };
0BEA5C291F7B8F73000D0AB4 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C271F7B8F73000D0AB4 /* Interface.storyboard */; };
@@ -17,8 +19,10 @@
0BEA5C3B1F7B8F73000D0AB4 /* ComplicationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3A1F7B8F73000D0AB4 /* ComplicationController.swift */; };
0BEA5C3D1F7B8F73000D0AB4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */; };
0BEA5C411F7B8F73000D0AB4 /* JitsiMeetCompanion.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
2681BB562C7A0B42CFBA6719 /* libPods-JitsiMeet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */; };
361974E2A13624D7735D619D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */; };
4341A9062CF0D63200940D93 /* hermes.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4341A9052CF0D63200940D93 /* hermes.xcframework */; };
@@ -30,8 +34,7 @@
4EB0603C260E09D000F524C5 /* SocketConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB06039260E09D000F524C5 /* SocketConnection.swift */; };
4EB0603D260E09D000F524C5 /* DarwinNotificationCenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0603A260E09D000F524C5 /* DarwinNotificationCenter.swift */; };
4EB0603E260E09D000F524C5 /* SampleUploader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0603B260E09D000F524C5 /* SampleUploader.swift */; };
DEA0B7122D7EF16E0062A9F6 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA0B7112D7EF16E0062A9F6 /* ViewController.swift */; };
DEA0B7142D7EF7590062A9F6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEA0B7132D7EF7590062A9F6 /* AppDelegate.swift */; };
DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */; };
DEA9F289258A6EA800D4CD74 /* JitsiMeetSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */; };
DEA9F28A258A6EA800D4CD74 /* JitsiMeetSDK.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
DED016F128ECBC9D009D5E8D /* WebRTC.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */; };
@@ -118,8 +121,12 @@
/* Begin PBXFileReference section */
0B26BE6D1EC5BC3C00EEFB41 /* JitsiMeet.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JitsiMeet.framework; sourceTree = BUILT_PRODUCTS_DIR; };
0B412F1D1EDEE6E800B1A0A6 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
0B412F201EDEE95300B1A0A6 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
0B5418461F7C5D8C00A2DD86 /* MeetingRowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeetingRowController.swift; sourceTree = "<group>"; };
0B70016F1F7C51CC005944F4 /* InCallController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InCallController.swift; sourceTree = "<group>"; };
0BBD021F212EB69D00CCB19F /* Types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Types.h; sourceTree = "<group>"; };
0BD6B4361EF82A6B00D1F4CD /* WebRTC.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebRTC.framework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.framework"; sourceTree = "<group>"; };
0BEA5C251F7B8F73000D0AB4 /* JitsiMeetCompanion.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JitsiMeetCompanion.app; sourceTree = BUILT_PRODUCTS_DIR; };
0BEA5C281F7B8F73000D0AB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = "<group>"; };
@@ -132,9 +139,12 @@
0BEA5C3C1F7B8F73000D0AB4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
0BEA5C3E1F7B8F73000D0AB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* jitsi-meet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "jitsi-meet.app"; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
13B07FB21A68108700A75B9A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
3E0F4ED943C0B12BE77F6B45 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
4341A9052CF0D63200940D93 /* hermes.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = hermes.xcframework; path = "../Pods/hermes-engine/destroot/Library/Frameworks/universal/hermes.xcframework"; sourceTree = "<group>"; };
4E90F93F2632D1AB001102D4 /* Atomic.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Atomic.swift; sourceTree = "<group>"; };
@@ -147,12 +157,13 @@
4EB0603B260E09D000F524C5 /* SampleUploader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleUploader.swift; sourceTree = "<group>"; };
4EC49B8625BED71300E76218 /* ReplayKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReplayKit.framework; path = System/Library/Frameworks/ReplayKit.framework; sourceTree = SDKROOT; };
5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = ../PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
756FCE06C08D9B947653C98A /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
B3B083EB1D4955FF0069CEE7 /* app.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = app.entitlements; sourceTree = "<group>"; };
D6152FF9E9F7B0E86F70A21D /* libPods-JitsiMeet.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeet.a"; sourceTree = BUILT_PRODUCTS_DIR; };
DE050388256E904600DEE3A5 /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = "../../node_modules/react-native-webrtc/apple/WebRTC.xcframework"; sourceTree = "<group>"; };
DEA0B7112D7EF16E0062A9F6 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
DEA0B7132D7EF7590062A9F6 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FIRUtilities.m; sourceTree = "<group>"; };
DE4C456021DE1E4E00EA0709 /* FIRUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FIRUtilities.h; sourceTree = "<group>"; };
DEA9F288258A6EA800D4CD74 /* JitsiMeetSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = JitsiMeetSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DED016F028ECBC9D009D5E8D /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = ../Pods/JitsiWebRTC/WebRTC.xcframework; sourceTree = "<group>"; };
DEFDBBDB25656E3B00344B23 /* WebRTC.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = WebRTC.xcframework; path = "../../node_modules/react-native-webrtc/ios/WebRTC.xcframework"; sourceTree = "<group>"; };
@@ -247,11 +258,18 @@
13B07FAE1A68108700A75B9A /* src */ = {
isa = PBXGroup;
children = (
DEA0B7132D7EF7590062A9F6 /* AppDelegate.swift */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.m */,
DE4C456021DE1E4E00EA0709 /* FIRUtilities.h */,
DE4C455F21DE1E4E00EA0709 /* FIRUtilities.m */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
13B07FB61A68108700A75B9A /* Info.plist */,
13B07FB11A68108700A75B9A /* LaunchScreen.xib */,
DEA0B7112D7EF16E0062A9F6 /* ViewController.swift */,
13B07FB71A68108700A75B9A /* main.m */,
0B412F201EDEE95300B1A0A6 /* Main.storyboard */,
0BBD021F212EB69D00CCB19F /* Types.h */,
0B412F1D1EDEE6E800B1A0A6 /* ViewController.h */,
0B412F1E1EDEE6E800B1A0A6 /* ViewController.m */,
);
path = src;
sourceTree = "<group>";
@@ -284,6 +302,7 @@
0BEA5C351F7B8F73000D0AB4 /* WatchKit extension */,
4EB06025260E026600F524C5 /* JitsiMeetBroadcast Extension */,
CDD71F5E1157E9F283DF92A8 /* Pods */,
6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */,
5C1BE20ECD5DEEB48FED90B5 /* PrivacyInfo.xcprivacy */,
);
indentWidth = 2;
@@ -416,7 +435,6 @@
ProvisioningStyle = Automatic;
};
13B07F861A680F5B00A75B9A = {
LastSwiftMigration = 1620;
SystemCapabilities = {
com.apple.SafariKeychain = {
enabled = 1;
@@ -474,6 +492,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0B412F211EDEE95300B1A0A6 /* Main.storyboard in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */,
361974E2A13624D7735D619D /* PrivacyInfo.xcprivacy in Resources */,
@@ -641,8 +660,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DEA0B7122D7EF16E0062A9F6 /* ViewController.swift in Sources */,
DEA0B7142D7EF7590062A9F6 /* AppDelegate.swift in Sources */,
0B412F1F1EDEE6E800B1A0A6 /* ViewController.m in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */,
DE4C456121DE1E4E00EA0709 /* FIRUtilities.m in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -848,7 +869,6 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconDebug;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = app.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
@@ -873,8 +893,6 @@
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
@@ -885,7 +903,6 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIconRelease;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = app.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
@@ -909,7 +926,6 @@
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_VERSION = 6.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;

23
ios/app/src/AppDelegate.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* Copyright @ 2017-present Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, strong) UIWindow *window;
@end

139
ios/app/src/AppDelegate.m Normal file
View File

@@ -0,0 +1,139 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 2017-2018 Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "AppDelegate.h"
#import "FIRUtilities.h"
#import "Types.h"
#import "ViewController.h"
@import Firebase;
@import JitsiMeetSDK;
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
JitsiMeet *jitsiMeet = [JitsiMeet sharedInstance];
#if 0
jitsiMeet.webRtcLoggingSeverity = WebRTCLoggingSeverityVerbose;
#endif
jitsiMeet.conferenceActivityType = JitsiMeetConferenceActivityType;
jitsiMeet.customUrlScheme = @"org.jitsi.meet";
jitsiMeet.universalLinkDomains = @[@"meet.jit.si", @"alpha.jitsi.net", @"beta.meet.jit.si"];
jitsiMeet.defaultConferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
// For testing configOverrides a room needs to be set
// builder.room = @"https://meet.jit.si/test0988test";
[builder setFeatureFlag:@"welcomepage.enabled" withBoolean:YES];
[builder setFeatureFlag:@"ios.screensharing.enabled" withBoolean:YES];
[builder setFeatureFlag:@"ios.recording.enabled" withBoolean:YES];
}];
[jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
// Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided.
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
NSLog(@"Enabling Firebase");
[FIRApp configure];
// Crashlytics defaults to disabled with the FirebaseCrashlyticsCollectionEnabled Info.plist key.
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:![jitsiMeet isCrashReportingDisabled]];
}
ViewController *rootController = (ViewController *)self.window.rootViewController;
[jitsiMeet showSplashScreen:rootController.view];
return YES;
}
- (void) applicationWillTerminate:(UIApplication *)application {
NSLog(@"Application will terminate!");
// Try to leave the current meeting graceefully.
ViewController *rootController = (ViewController *)self.window.rootViewController;
[rootController terminate];
}
#pragma mark Linking delegate methods
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler {
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
// 1. Attempt to handle Universal Links through Firebase in order to support
// its Dynamic Links (which we utilize for the purposes of deferred deep
// linking).
BOOL handled
= [[FIRDynamicLinks dynamicLinks]
handleUniversalLink:userActivity.webpageURL
completion:^(FIRDynamicLink * _Nullable dynamicLink, NSError * _Nullable error) {
NSURL *firebaseUrl = [FIRUtilities extractURL:dynamicLink];
if (firebaseUrl != nil) {
userActivity.webpageURL = firebaseUrl;
[[JitsiMeet sharedInstance] application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
}];
if (handled) {
return handled;
}
}
// 2. Default to plain old, non-Firebase-assisted Universal Links.
return [[JitsiMeet sharedInstance] application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
// This shows up during a reload in development, skip it.
// https://github.com/firebase/firebase-ios-sdk/issues/233
if ([[url absoluteString] containsString:@"google/link/?dismiss=1&is_weak_match=1"]) {
return NO;
}
NSURL *openUrl = url;
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
// Process Firebase Dynamic Links
FIRDynamicLink *dynamicLink = [[FIRDynamicLinks dynamicLinks] dynamicLinkFromCustomSchemeURL:url];
NSURL *firebaseUrl = [FIRUtilities extractURL:dynamicLink];
if (firebaseUrl != nil) {
openUrl = firebaseUrl;
}
}
return [[JitsiMeet sharedInstance] application:app
openURL:openUrl
options:options];
}
- (UIInterfaceOrientationMask)application:(UIApplication *)application
supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return [[JitsiMeet sharedInstance] application:application
supportedInterfaceOrientationsForWindow:window];
}
@end

View File

@@ -1,109 +0,0 @@
import UIKit
import Firebase
import JitsiMeetSDK
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.window = UIWindow(frame: UIScreen.main.bounds)
let jitsiMeet = JitsiMeet.sharedInstance()
// jitsiMeet.webRtcLoggingSeverity = .verbose
jitsiMeet.conferenceActivityType = "org.jitsi.JitsiMeet.ios.conference" // Must match the one defined in Info.plist{}
jitsiMeet.customUrlScheme = "org.jitsi.meet"
jitsiMeet.universalLinkDomains = ["meet.jit.si", "alpha.jitsi.net", "beta.meet.jit.si"]
jitsiMeet.defaultConferenceOptions = JitsiMeetConferenceOptions.fromBuilder { builder in
// For testing configOverrides a room needs to be set
// builder.room = "https://meet.jit.si/test0988test"
builder.setFeatureFlag("welcomepage.enabled", withBoolean: true)
builder.setFeatureFlag("ios.screensharing.enabled", withBoolean: true)
builder.setFeatureFlag("ios.recording.enabled", withBoolean: true)
}
jitsiMeet.application(application, didFinishLaunchingWithOptions: launchOptions ?? [:])
if self.appContainsRealServiceInfoPlist() {
print("Enabling Firebase")
FirebaseApp.configure()
Crashlytics.crashlytics().setCrashlyticsCollectionEnabled(!jitsiMeet.isCrashReportingDisabled())
}
let vc = ViewController()
self.window?.rootViewController = vc
jitsiMeet.showSplashScreen(vc.view)
self.window?.makeKeyAndVisible()
return true
}
func applicationWillTerminate(_ application: UIApplication) {
print("Application will terminate!")
if let rootController = self.window?.rootViewController as? ViewController {
rootController.terminate()
}
}
// MARK: Linking delegate methods
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if self.appContainsRealServiceInfoPlist() {
let handled = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { dynamicLink, error in
if let firebaseUrl = self.extractURL(from: dynamicLink) {
userActivity.webpageURL = firebaseUrl
JitsiMeet.sharedInstance().application(application, continue: userActivity, restorationHandler: restorationHandler)
}
}
if handled {
return handled
}
}
return JitsiMeet.sharedInstance().application(application, continue: userActivity, restorationHandler: restorationHandler)
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if url.absoluteString.contains("google/link/?dismiss=1&is_weak_match=1") {
return false
}
var openUrl = url
if self.appContainsRealServiceInfoPlist() {
if let dynamicLink = DynamicLinks.dynamicLinks().dynamicLink(fromCustomSchemeURL: url),
let firebaseUrl = self.extractURL(from: dynamicLink) {
openUrl = firebaseUrl
}
}
return JitsiMeet.sharedInstance().application(app, open: openUrl, options: options)
}
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return JitsiMeet.sharedInstance().application(application, supportedInterfaceOrientationsFor: window)
}
}
// Firebase utilities
extension AppDelegate {
func appContainsRealServiceInfoPlist() -> Bool {
return InfoPlistUtil.containsRealServiceInfoPlist(in: Bundle.main)
}
func extractURL(from dynamicLink: DynamicLink?) -> URL? {
guard let dynamicLink = dynamicLink,
let dynamicLinkURL = dynamicLink.url,
dynamicLink.matchType == .unique || dynamicLink.matchType == .default else {
return nil
}
return dynamicLinkURL
}
}

View File

@@ -1,10 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="23504" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7702" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES">
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23506"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="u7g-vg-A8m">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="xSm-U5-Hdu">
<objects>
<viewController id="u7g-vg-A8m" customClass="ViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="d40-fc-Y8P"/>
<viewControllerLayoutGuide type="bottom" id="1KD-Ho-g0H"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="QpR-jB-WOw" customClass="JitsiMeetView">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="ZIj-K3-jVH" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="28" y="138"/>
</scene>
</scenes>
</document>

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <Foundation/Foundation.h>
@import Firebase;
@interface FIRUtilities : NSObject
+ (BOOL)appContainsRealServiceInfoPlist;
+ (NSURL *_Nullable)extractURL: (FIRDynamicLink* _Nullable)dynamicLink;
@end

View File

@@ -0,0 +1,48 @@
/*
* Copyright 2017 Google
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "FIRUtilities.h"
@import JitsiMeetSDK;
@implementation FIRUtilities
+ (BOOL)appContainsRealServiceInfoPlist {
static BOOL containsRealServiceInfoPlist = NO;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSBundle *bundle = [NSBundle mainBundle];
containsRealServiceInfoPlist = [InfoPlistUtil containsRealServiceInfoPlistInBundle:bundle];
});
return containsRealServiceInfoPlist;
}
+ (NSURL *)extractURL: (FIRDynamicLink*)dynamicLink {
NSURL *url = nil;
if (dynamicLink != nil) {
NSURL *dynamicLinkURL = dynamicLink.url;
if (dynamicLinkURL != nil
&& (dynamicLink.matchType == FIRDLMatchTypeUnique
|| dynamicLink.matchType == FIRDLMatchTypeDefault)) {
// Strong match, process it.
url = dynamicLinkURL;
}
}
return url;
}
@end

View File

@@ -88,6 +88,8 @@
</array>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
<string>Main</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>

7
ios/app/src/Types.h Normal file
View File

@@ -0,0 +1,7 @@
#import <Foundation/Foundation.h>
// This must match what's defined in the NSUserActivityTypes array in the
// Info.plist file.
static NSString *const JitsiMeetConferenceActivityType
= @"org.jitsi.JitsiMeet.ios.conference";

View File

@@ -0,0 +1,24 @@
/*
* Copyright @ 2017-present Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import UIKit;
@import JitsiMeetSDK;
@interface ViewController : UIViewController<JitsiMeetViewDelegate>
- (void)terminate;
@end

View File

@@ -0,0 +1,149 @@
/*
* Copyright @ 2017-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
@import CoreSpotlight;
@import MobileCoreServices;
@import Intents; // Needed for NSUserActivity suggestedInvocationPhrase
@import JitsiMeetSDK;
#import "Types.h"
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
JitsiMeetView *view = (JitsiMeetView *) self.view;
view.delegate = self;
[view join:[[JitsiMeet sharedInstance] getInitialConferenceOptions]];
}
// JitsiMeetViewDelegate
- (void)_onJitsiMeetViewDelegateEvent:(NSString *)name
withData:(NSDictionary *)data {
NSLog(
@"[%s:%d] JitsiMeetViewDelegate %@ %@",
__FILE__, __LINE__, name, data);
#if DEBUG
NSAssert(
[NSThread isMainThread],
@"JitsiMeetViewDelegate %@ method invoked on a non-main thread",
name);
#endif
}
- (void)conferenceJoined:(NSDictionary *)data {
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_JOINED" withData:data];
// Register a NSUserActivity for this conference so it can be invoked as a
// Siri shortcut.
NSUserActivity *userActivity
= [[NSUserActivity alloc] initWithActivityType:JitsiMeetConferenceActivityType];
NSString *urlStr = data[@"url"];
NSURL *url = [NSURL URLWithString:urlStr];
NSString *conference = [url.pathComponents lastObject];
userActivity.title = [NSString stringWithFormat:@"Join %@", conference];
userActivity.suggestedInvocationPhrase = @"Join my Jitsi meeting";
userActivity.userInfo = @{@"url": urlStr};
[userActivity setEligibleForSearch:YES];
[userActivity setEligibleForPrediction:YES];
[userActivity setPersistentIdentifier:urlStr];
// Subtitle
CSSearchableItemAttributeSet *attributes
= [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeItem];
attributes.contentDescription = urlStr;
userActivity.contentAttributeSet = attributes;
self.userActivity = userActivity;
[userActivity becomeCurrent];
}
- (void)conferenceTerminated:(NSDictionary *)data {
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_TERMINATED" withData:data];
}
- (void)conferenceWillJoin:(NSDictionary *)data {
[self _onJitsiMeetViewDelegateEvent:@"CONFERENCE_WILL_JOIN" withData:data];
}
// - (void)customButtonPressed:(NSDictionary *)data {
// [self _onJitsiMeetViewDelegateEvent:@"CUSTOM_BUTTON_PRESSED" withData:data];
// }
#if 0
- (void)enterPictureInPicture:(NSDictionary *)data {
[self _onJitsiMeetViewDelegateEvent:@"ENTER_PICTURE_IN_PICTURE" withData:data];
}
#endif
- (void)readyToClose:(NSDictionary *)data {
[self _onJitsiMeetViewDelegateEvent:@"READY_TO_CLOSE" withData:data];
}
// - (void)transcriptionChunkReceived:(NSDictionary *)data {
// [self _onJitsiMeetViewDelegateEvent:@"TRANSCRIPTION_CHUNK_RECEIVED" withData:data];
// }
- (void)participantJoined:(NSDictionary *)data {
NSLog(@"%@%@", @"Participant joined: ", data[@"participantId"]);
}
- (void)participantLeft:(NSDictionary *)data {
NSLog(@"%@%@", @"Participant left: ", data[@"participantId"]);
}
- (void)audioMutedChanged:(NSDictionary *)data {
NSLog(@"%@%@", @"Audio muted changed: ", data[@"muted"]);
}
- (void)endpointTextMessageReceived:(NSDictionary *)data {
NSLog(@"%@%@", @"Endpoint text message received: ", data);
}
- (void)screenShareToggled:(NSDictionary *)data {
NSLog(@"%@%@", @"Screen share toggled: ", data);
}
- (void)chatMessageReceived:(NSDictionary *)data {
NSLog(@"%@%@", @"Chat message received: ", data);
}
- (void)chatToggled:(NSDictionary *)data {
NSLog(@"%@%@", @"Chat toggled: ", data);
}
- (void)videoMutedChanged:(NSDictionary *)data {
NSLog(@"%@%@", @"Video muted changed: ", data[@"muted"]);
}
#pragma mark - Helpers
- (void)terminate {
JitsiMeetView *view = (JitsiMeetView *) self.view;
[view leave];
}
@end

View File

@@ -1,94 +0,0 @@
/*
* Copyright @ 2025-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import CoreSpotlight
import Intents
import MobileCoreServices
import UIKit
import JitsiMeetSDK
@objcMembers
class ViewController: UIViewController {
override func loadView() {
let jitsiView = JitsiMeetView(frame: UIScreen.main.bounds)
self.view = jitsiView
}
override func viewDidLoad() {
super.viewDidLoad()
guard let view = self.view as? JitsiMeetView else { return }
view.delegate = self
view.join(JitsiMeet.sharedInstance().getInitialConferenceOptions())
}
// MARK: - Helper Methods
func terminate() {
guard let view = self.view as? JitsiMeetView else { return }
view.leave()
}
}
extension ViewController: @preconcurrency JitsiMeetViewDelegate {
// MARK: - Private Helper Methods
private func onJitsiMeetViewDelegateEvent(_ name: String, withData data: [AnyHashable: Any]?) {
NSLog("[%@:%d] JitsiMeetViewDelegate %@ %@", #file, #line, name, data ?? [:])
#if DEBUG
assert(Thread.isMainThread, "JitsiMeetViewDelegate \(name) method invoked on a non-main thread")
#endif
}
// MARK: - JitsiMeetViewDelegate
func conferenceJoined(_ data: [AnyHashable: Any]) {
onJitsiMeetViewDelegateEvent("CONFERENCE_JOINED", withData: data)
// Register a NSUserActivity for this conference so it can be invoked as a Siri shortcut.
// Must match the one defined in Info.plist
let userActivity = NSUserActivity(activityType: "org.jitsi.JitsiMeet.ios.conference")
if let urlStr = data["url"] as? String,
let url = URL(string: urlStr),
let conference = url.pathComponents.last {
userActivity.title = "Join \(conference)"
userActivity.suggestedInvocationPhrase = "Join my Jitsi meeting"
userActivity.userInfo = ["url": urlStr]
userActivity.isEligibleForSearch = true
userActivity.isEligibleForPrediction = true
userActivity.persistentIdentifier = urlStr
// Subtitle
let attributes = CSSearchableItemAttributeSet(contentType: UTType.item)
attributes.contentDescription = urlStr
userActivity.contentAttributeSet = attributes
self.userActivity = userActivity
userActivity.becomeCurrent()
}
}
func ready(toClose data: [AnyHashable: Any]) {
onJitsiMeetViewDelegateEvent("READY_TO_CLOSE", withData: data)
}
}

28
ios/app/src/main.m Normal file
View File

@@ -0,0 +1,28 @@
/*
* Copyright @ 2017-present Atlassian Pty Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(
argc, argv,
nil,
NSStringFromClass([AppDelegate class]));
}
}

View File

@@ -1,15 +0,0 @@
diff --git a/SocketRocket/SRSecurityPolicy.m b/SocketRocket/SRSecurityPolicy.m
index 3759d26e..271477e8 100644
--- a/SocketRocket/SRSecurityPolicy.m
+++ b/SocketRocket/SRSecurityPolicy.m
@@ -56,8 +56,8 @@ - (instancetype)init
- (void)updateSecurityOptionsInStream:(NSStream *)stream
{
- // Enforce TLS 1.2
- [stream setProperty:(__bridge id)CFSTR("kCFStreamSocketSecurityLevelTLSv1_2") forKey:(__bridge id)kCFStreamPropertySocketSecurityLevel];
+ // Enforce TLS >= 1.2
+ [stream setProperty:(__bridge id)kCFStreamSocketSecurityLevelNegotiatedSSL forKey:(__bridge id)kCFStreamPropertySocketSecurityLevel];
// Validate certificate chain for this stream if enabled.
NSDictionary<NSString *, id> *sslOptions = @{ (__bridge NSString *)kCFStreamSSLValidatesCertificateChain : @(self.certificateChainValidationEnabled) };

View File

@@ -145,6 +145,7 @@
4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiAudioSession.h; sourceTree = "<group>"; };
4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiAudioSession.m; sourceTree = "<group>"; };
4ED4FFF52721BAE10074E620 /* JitsiAudioSession+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiAudioSession+Private.h"; sourceTree = "<group>"; };
6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = ../PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
86389F55993FAAF6AEB3FA3E /* Pods-JitsiMeetSDKLite.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeetSDKLite.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite.release.xcconfig"; sourceTree = "<group>"; };
891FE43DAD30BC8976683100 /* Pods-JitsiMeetSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeetSDK.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK.release.xcconfig"; sourceTree = "<group>"; };
8F48C340DE0D91D1012976C5 /* Pods-JitsiMeetSDKLite.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeetSDKLite.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite.debug.xcconfig"; sourceTree = "<group>"; };
@@ -230,6 +231,7 @@
0BD906E61EC0C00300C8C18E /* Products */,
0BCA49681EC4BBE500B793EE /* Resources */,
0BD906E71EC0C00300C8C18E /* src */,
6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */,
);
sourceTree = "<group>";
};
@@ -869,7 +871,6 @@
baseConfigurationReference = 09A78016288AF50ACD28A10D /* Pods-JitsiMeetSDK.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
@@ -893,6 +894,8 @@
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OBJC_INTERFACE_HEADER_NAME = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -904,7 +907,6 @@
baseConfigurationReference = 891FE43DAD30BC8976683100 /* Pods-JitsiMeetSDK.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
@@ -928,6 +930,8 @@
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OBJC_INTERFACE_HEADER_NAME = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
@@ -938,7 +942,6 @@
baseConfigurationReference = 8F48C340DE0D91D1012976C5 /* Pods-JitsiMeetSDKLite.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
@@ -967,6 +970,8 @@
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OBJC_INTERFACE_HEADER_NAME = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
@@ -978,7 +983,6 @@
baseConfigurationReference = 86389F55993FAAF6AEB3FA3E /* Pods-JitsiMeetSDKLite.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
@@ -1007,6 +1011,8 @@
SUPPORTS_MACCATALYST = NO;
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OBJC_INTERFACE_HEADER_NAME = "";
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};

View File

@@ -18,6 +18,11 @@
static NSString * const sendEventNotificationName = @"org.jitsi.meet.SendEvent";
typedef NS_ENUM(NSInteger, RecordingMode) {
RecordingModeFile,
RecordingModeStream
};
@interface ExternalAPI : RCTEventEmitter<RCTBridgeModule>
- (void)sendHangUp;
@@ -33,9 +38,7 @@ static NSString * const sendEventNotificationName = @"org.jitsi.meet.SendEvent";
- (void)toggleCamera;
- (void)showNotification:(NSString*)appearance :(NSString*)description :(NSString*)timeout :(NSString*)title :(NSString*)uid;
- (void)hideNotification:(NSString*)uid;
- (void)startRecording:(NSString*)mode :(NSString*)dropboxToken :(BOOL)shouldShare :(NSString*)rtmpStreamKey :(NSString*)rtmpBroadcastID :(NSString*)youtubeStreamKey :(NSString*)youtubeBroadcastID :(NSDictionary*)extraMetadata :(BOOL)transcription;
- (void)stopRecording:(NSString*)mode :(BOOL)transcription;
- (void)overwriteConfig:(NSDictionary*)config;
- (void)sendCameraFacingModeMessage:(NSString*)to :(NSString*)facingMode;
- (void)startRecording:(RecordingMode)mode :(NSString*)dropboxToken :(BOOL)shouldShare :(NSString*)rtmpStreamKey :(NSString*)rtmpBroadcastID :(NSString*)youtubeStreamKey :(NSString*)youtubeBroadcastID :(NSDictionary*)extraMetadata :(BOOL)transcription;
- (void)stopRecording:(RecordingMode)mode :(BOOL)transcription;
@end

View File

@@ -32,15 +32,13 @@ static NSString * const showNotificationAction = @"org.jitsi.meet.SHOW_NOTIFICAT
static NSString * const hideNotificationAction = @"org.jitsi.meet.HIDE_NOTIFICATION";
static NSString * const startRecordingAction = @"org.jitsi.meet.START_RECORDING";
static NSString * const stopRecordingAction = @"org.jitsi.meet.STOP_RECORDING";
static NSString * const overwriteConfigAction = @"org.jitsi.meet.OVERWRITE_CONFIG";
static NSString * const sendCameraFacingModeMessageAction = @"org.jitsi.meet.SEND_CAMERA_FACING_MODE_MESSAGE";
@implementation ExternalAPI
static NSMapTable<NSString*, void (^)(NSArray* participantsInfo)> *participantInfoCompletionHandlers;
__attribute__((constructor))
static void initializeViewsMap(void) {
static void initializeViewsMap() {
participantInfoCompletionHandlers = [NSMapTable strongToStrongObjectsMapTable];
}
@@ -62,9 +60,7 @@ RCT_EXPORT_MODULE();
@"SHOW_NOTIFICATION": showNotificationAction,
@"HIDE_NOTIFICATION": hideNotificationAction,
@"START_RECORDING": startRecordingAction,
@"STOP_RECORDING": stopRecordingAction,
@"OVERWRITE_CONFIG": overwriteConfigAction,
@"SEND_CAMERA_FACING_MODE_MESSAGE": sendCameraFacingModeMessageAction
@"STOP_RECORDING": stopRecordingAction
};
};
@@ -94,9 +90,7 @@ RCT_EXPORT_MODULE();
showNotificationAction,
hideNotificationAction,
startRecordingAction,
stopRecordingAction,
overwriteConfigAction,
sendCameraFacingModeMessageAction
stopRecordingAction
];
}
@@ -216,9 +210,21 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
[self sendEventWithName:hideNotificationAction body:data];
}
- (void)startRecording:(NSString*)mode :(NSString*)dropboxToken :(BOOL)shouldShare :(NSString*)rtmpStreamKey :(NSString*)rtmpBroadcastID :(NSString*)youtubeStreamKey :(NSString*)youtubeBroadcastID :(NSDictionary*)extraMetadata :(BOOL)transcription {
static inline NSString *RecordingModeToString(RecordingMode mode) {
switch (mode) {
case RecordingModeFile:
return @"file";
case RecordingModeStream:
return @"stream";
default:
return nil;
}
}
- (void)startRecording:(RecordingMode)mode :(NSString*)dropboxToken :(BOOL)shouldShare :(NSString*)rtmpStreamKey :(NSString*)rtmpBroadcastID :(NSString*)youtubeStreamKey :(NSString*)youtubeBroadcastID :(NSDictionary*)extraMetadata :(BOOL)transcription {
NSString *modeString = RecordingModeToString(mode);
NSDictionary *data = @{
@"mode": mode,
@"mode": modeString,
@"dropboxToken": dropboxToken,
@"shouldShare": @(shouldShare),
@"rtmpStreamKey": rtmpStreamKey,
@@ -232,29 +238,13 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
[self sendEventWithName:startRecordingAction body:data];
}
- (void)stopRecording:(NSString*)mode :(BOOL)transcription {
- (void)stopRecording:(RecordingMode)mode :(BOOL)transcription {
NSString *modeString = RecordingModeToString(mode);
NSDictionary *data = @{
@"mode": mode,
@"mode": modeString,
@"transcription": @(transcription)
};
[self sendEventWithName:stopRecordingAction body:data];
}
- (void)overwriteConfig:(NSDictionary*)config {
NSDictionary *data = @{
@"config": config
};
[self sendEventWithName:overwriteConfigAction body:data];
}
- (void)sendCameraFacingModeMessage:(NSString*)to :(NSString*)facingMode {
NSDictionary *data = @{
@"to": to,
@"facingMode": facingMode
};
[self sendEventWithName:sendCameraFacingModeMessageAction body:data];
}
@end

View File

@@ -82,7 +82,7 @@ typedef NS_ENUM(NSInteger, WebRTCLoggingSeverity) {
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *_Nonnull)options;
- (UIInterfaceOrientationMask)application:(UIApplication *_Nonnull)application
supportedInterfaceOrientationsForWindow:(UIWindow *_Nullable)window;
supportedInterfaceOrientationsForWindow:(UIWindow *_Nonnull)window;
#pragma mark - Utility methods

View File

@@ -21,10 +21,7 @@
#import "JitsiMeetConferenceOptions.h"
#import "JitsiMeetViewDelegate.h"
typedef NS_ENUM(NSInteger, RecordingMode) {
RecordingModeFile,
RecordingModeStream
};
typedef NS_ENUM(NSInteger, RecordingMode);
@interface JitsiMeetView : UIView
@@ -54,8 +51,7 @@ typedef NS_ENUM(NSInteger, RecordingMode) {
- (void)toggleCamera;
- (void)showNotification:(NSString * _Nonnull)appearance :(NSString * _Nullable)description :(NSString * _Nullable)timeout :(NSString * _Nullable)title :(NSString * _Nullable)uid;
- (void)hideNotification:(NSString * _Nullable)uid;
- (void)startRecording:(RecordingMode)mode :(NSString * _Nullable)dropboxToken :(BOOL)shouldShare :(NSString * _Nullable)rtmpStreamKey :(NSString * _Nullable)rtmpBroadcastID :(NSString * _Nullable)youtubeStreamKey :(NSString * _Nullable)youtubeBroadcastID :(NSDictionary * _Nullable)extraMetadata :(BOOL)transcription;
- (void)startRecording:(RecordingMode)mode :(NSString * _Nullable)dropboxToken :(BOOL)shouldShare :(NSString * _Nullable)rtmpStreamKey :(NSString * _Nullable)rtmpBroadcastID :(NSString * _Nullable)youtubeStreamKey :(NSString * _Nullable)youtubeBroadcastID :(NSString * _Nullable)extraMetadata :(BOOL)transcription;
- (void)stopRecording:(RecordingMode)mode :(BOOL)transcription;
- (void)overwriteConfig:(NSDictionary * _Nonnull)config;
- (void)sendCameraFacingModeMessage:(NSString * _Nonnull)to :(NSString * _Nullable)facingMode;
@end

View File

@@ -17,8 +17,6 @@
#include <mach/mach_time.h>
#import <UIKit/UIKit.h>
#import "ExternalAPI.h"
#import "JitsiMeet+Private.h"
#import "JitsiMeetConferenceOptions+Private.h"
@@ -27,43 +25,11 @@
#import "RNRootView.h"
#pragma mark UIColor helpers
@interface UIColor (Hex)
+ (UIColor *)colorWithHex:(uint32_t)hex;
+ (UIColor *)colorWithHex:(uint32_t)hex alpha:(CGFloat)alpha;
@end
@implementation UIColor (Hex)
+ (UIColor *)colorWithHex:(uint32_t)hex {
return [self colorWithHex:hex alpha:1.0];
}
+ (UIColor *)colorWithHex:(uint32_t)hex alpha:(CGFloat)alpha {
CGFloat red = ((hex >> 16) & 0xFF) / 255.0;
CGFloat green = ((hex >> 8) & 0xFF) / 255.0;
CGFloat blue = (hex & 0xFF) / 255.0;
return [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
}
@end
#pragma mark UIColor helpers end
/**
* Backwards compatibility: turn the boolean prop into a feature flag.
*/
static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
/**
* Forward declarations.
*/
static NSString *recordingModeToString(RecordingMode mode);
@implementation JitsiMeetView {
/**
@@ -99,8 +65,11 @@ static NSString *recordingModeToString(RecordingMode mode);
* - registers necessary observers
*/
- (void)doInitialize {
// Set a background color which matches the one used in JS.
self.backgroundColor = [UIColor colorWithHex:0x040404 alpha:1];
// Set a background color which is in accord with the JavaScript and Android
// parts of the application and causes less perceived visual flicker than
// the default background color.
self.backgroundColor
= [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
[self registerObservers];
}
@@ -184,25 +153,15 @@ static NSString *recordingModeToString(RecordingMode mode);
[externalAPI hideNotification:uid];
}
- (void)startRecording:(RecordingMode)mode :(NSString * _Nullable)dropboxToken :(BOOL)shouldShare :(NSString * _Nullable)rtmpStreamKey :(NSString * _Nullable)rtmpBroadcastID :(NSString * _Nullable)youtubeStreamKey :(NSString * _Nullable)youtubeBroadcastID :(NSDictionary * _Nullable)extraMetadata :(BOOL)transcription {
- (void)startRecording:(RecordingMode)mode :(NSString *)dropboxToken :(BOOL)shouldShare :(NSString *)rtmpStreamKey :(NSString *)rtmpBroadcastID :(NSString *)youtubeStreamKey :(NSString *)youtubeBroadcastID :(NSString *)extraMetadata :(BOOL)transcription {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI startRecording:recordingModeToString(mode) :dropboxToken :shouldShare :rtmpStreamKey :rtmpBroadcastID :youtubeStreamKey :youtubeBroadcastID :extraMetadata :transcription];
[externalAPI startRecording:mode :dropboxToken :shouldShare :rtmpStreamKey :rtmpBroadcastID :youtubeStreamKey :youtubeBroadcastID :extraMetadata :transcription];
}
- (void)stopRecording:(RecordingMode)mode :(BOOL)transcription {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI stopRecording:recordingModeToString(mode) :transcription];
}
- (void)overwriteConfig:(NSDictionary * _Nonnull)config {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI overwriteConfig:config];
}
- (void)sendCameraFacingModeMessage:(NSString * _Nonnull)to :(NSString * _Nullable)facingMode {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendCameraFacingModeMessage:to :facingMode];
}
[externalAPI stopRecording:mode :transcription];
}
#pragma mark Private methods
@@ -298,14 +257,3 @@ static NSString *recordingModeToString(RecordingMode mode);
}
@end
static NSString *recordingModeToString(RecordingMode mode) {
switch (mode) {
case RecordingModeFile:
return @"file";
case RecordingModeStream:
return @"stream";
default:
return nil;
}
}

View File

@@ -130,18 +130,4 @@
*/
- (void)customButtonPressed:(NSDictionary *)data;
/**
* Called when the unique identifier for conference has been set.
*
* The `data` dictionary contains a `sessionId` key.
*/
- (void)conferenceUniqueIdSet:(NSDictionary *)data;
/**
* Called when the recording status has changed.
*
* The `data` dictionary contains a `sessionData` key.
*/
- (void)recordingStatusChanged:(NSDictionary *)data;
@end

View File

@@ -39,7 +39,6 @@
"mr": "मराठी",
"nb": "Norsk bokmål",
"nl": "Nederlands",
"no": "Norsk",
"oc": "Occitan",
"pl": "Polski",
"pt": "Português",

View File

@@ -944,7 +944,6 @@
"title": "خيارات الأمان"
},
"settings": {
"audio": "الصوت",
"buttonLabel": "إعدادات",
"calendar": {
"about": "تُستعمَل الرزنامة {{appName}} المدمجة للوصل بأمان إلى رزنامتك، لذا بالإمكان معرفة الأحداث القادمة.",
@@ -968,7 +967,6 @@
"more": "المزيد",
"name": "الاسم",
"noDevice": "لا يوجد",
"notifications": "الإشعارات",
"participantJoined": "انضم مشارك",
"participantKnocking": "دخل المشارك في الردهة",
"participantLeft": "غادر المشارك",
@@ -979,15 +977,13 @@
"selectCamera": "الكاميرا",
"selectMic": "المايكروفون",
"selfView": "عرض ذاتي",
"shortcuts": "اختصارات لوحة المفاتيح",
"sounds": "اصوات",
"speakers": "المذياع (مكبر الصوت)",
"startAudioMuted": "بدء الجميع مكتومي الصوت",
"startReactionsMuted": "كتم رد فعل الصوت للجميع",
"startVideoMuted": "بدء الجميع دون فيديو",
"talkWhileMuted": "تحدث أثناء كتم الصوت",
"title": "الإعدادات",
"video": "الفيديو"
"title": "الإعدادات"
},
"settingsView": {
"advanced": "إعدادات متقدمة",

View File

@@ -70,14 +70,14 @@
"breakoutList": "Breakout-Liste",
"buttonLabel": "Breakout-Räume",
"defaultName": "Breakout-Raum #{{index}}",
"hideParticipantList": "Personenliste ausblenden",
"hideParticipantList": "Teilnehmerliste ausblenden",
"mainRoom": "Hauptraum",
"notifications": {
"joined": "Breakout-Raum \"{{name}}\" betreten",
"joinedMainRoom": "Hauptraum betreten",
"joinedTitle": "Breakout-Räume"
},
"showParticipantList": "Personenliste anzeigen",
"showParticipantList": "Teilnehmerliste anzeigen",
"title": "Breakout-Räume"
},
"calendarSync": {
@@ -89,7 +89,7 @@
"notSignedIn": "Ein Fehler ist während der Authentifizierung zur Anzeige von Kalenderterminen aufgetreten. Prüfen Sie Ihre Kalendereinstellungen oder versuchen Sie, sich erneut anzumelden."
},
"join": "Teilnehmen",
"joinTooltip": "An Konferenz teilnehmen",
"joinTooltip": "Am Konferenz teilnehmen",
"nextMeeting": "Nächste Konferenz",
"noEvents": "Es gibt keine bevorstehenden Termine.",
"ongoingMeeting": "Laufende Konferenz",
@@ -363,18 +363,18 @@
"muteEveryoneDialogModerationOn": "Die Anwesenden können eine Anfrage zum Sprechen jederzeit senden.",
"muteEveryoneElseDialog": "Einmal stummgeschaltet, können Sie deren Stummschaltung nicht mehr beenden, aber sie können ihre Stummschaltung jederzeit selbst beenden.",
"muteEveryoneElseTitle": "Alle außer {{whom}} stummschalten?",
"muteEveryoneElsesVideoDialog": "Sobald die Kamera für alle anderen Personen deaktiviert ist, können Sie diese nicht wieder für alle einschalten, die anderen Personen können ihre Kamera aber jederzeit wieder einschalten.",
"muteEveryoneElsesVideoDialog": "Sobald die Kamera deaktiviert ist, können Sie sie nicht wieder aktivieren, die Teilnehmer können dies aber jederzeit wieder ändern.",
"muteEveryoneElsesVideoTitle": "Die Kamera von allen außer {{whom}} ausschalten?",
"muteEveryoneSelf": "sich selbst",
"muteEveryoneStartMuted": "Alle beginnen von jetzt an stummgeschaltet",
"muteEveryoneTitle": "Alle stummschalten?",
"muteEveryonesVideoDialog": "Sind Sie sicher, dass Sie die Kamera von allen Personen deaktivieren möchten? Sie können dies nicht wieder rückgängig machen, jede Personen kann ihre Kamera aber jederzeit wieder einschalten.",
"muteEveryonesVideoDialog": "Sind Sie sicher, dass Sie die Kamera von allen Teilnehmern deaktivieren möchten? Sie können sie nicht wieder aktivieren, die Teilnehmer können dies aber jederzeit wieder ändern.",
"muteEveryonesVideoDialogModerationOn": "Die Anwesenden können jederzeit eine Anfrage senden, um ihre Kamera einzuschalten.",
"muteEveryonesVideoDialogOk": "deaktivieren",
"muteEveryonesVideoTitle": "Die Kamera von allen anderen ausschalten?",
"muteParticipantBody": "Sie können die Stummschaltung anderer Personen nicht aufheben, aber eine Person kann ihre eigene Stummschaltung jederzeit beenden.",
"muteParticipantButton": "Stummschalten",
"muteParticipantsVideoBody": "Sie können die Kamera nicht wieder einschalten, die Person kann ihre Kamera aber jederzeit wieder einschalten.",
"muteParticipantsVideoBody": "Sie können die Kamera nicht wieder aktivieren, die Teilnehmer können dies aber jederzeit wieder ändern.",
"muteParticipantsVideoBodyModerationOn": "Sie können die Kamera nicht wieder aktivieren und die Person selbst auch nicht.",
"muteParticipantsVideoButton": "Kamera ausschalten",
"muteParticipantsVideoDialog": "Wollen Sie die Kamera dieser Person wirklich deaktivieren? Sie können die Kamera nicht wieder aktivieren, die Person kann dies aber jederzeit selbst tun.",
@@ -562,7 +562,7 @@
"inviteTextiOSPhone": "Nutzen Sie folgende Nummer um via Telefon teilzunehmen: {{number}},,{{conferenceID}}#. Wenn Sie nach einer anderen Einwahlnummer suchen, finden Sie die vollständige Liste hier: {{didUrl}}.",
"inviteURLFirstPartGeneral": "Sie wurden zur Teilnahme an einer Konferenz eingeladen.",
"inviteURLFirstPartPersonal": "{{name}} lädt Sie zu einer Konferenz ein.\n",
"inviteURLSecondPart": "\nAn Konferenz teilnehmen:\n{{url}}\n",
"inviteURLSecondPart": "\nAm Konferenz teilnehmen:\n{{url}}\n",
"label": "Einwahlinformationen",
"liveStreamURL": "Livestream:",
"moreNumbers": "Weitere Telefonnummern",
@@ -642,7 +642,6 @@
"on": "Livestream",
"onBy": "{{name}} startete den Livestream",
"pending": "Livestream wird gestartet …",
"policyError": "Sie haben den Livestream zu schnell gestartet. Bitte versuchen Sie es später noch einmal!",
"serviceName": "Livestreaming-Dienst",
"sessionAlreadyActive": "Diese Konferenz wird bereits als Livestream übertragen.",
"signIn": "Mit Google anmelden",
@@ -743,7 +742,7 @@
"connectedOneMember": "{{name}} nimmt an der Konferenz teil",
"connectedThreePlusMembers": "{{name}} und {{count}} andere Personen nehmen an der Konferenz teil",
"connectedTwoMembers": "{{first}} und {{second}} nehmen an der Konferenz teil",
"connectionFailed": "Verbindung fehlgeschlagen. Bitte versuchen Sie es später noch einmal!",
"connectionFailed": "Verbindung fehlgeschlagen. Bitte versuchen Sie es später noch einmal.",
"dataChannelClosed": "Schlechte Videoqualität",
"dataChannelClosedDescription": "Die Steuerungsverbindung (Bridge Channel) wurde unterbrochen, daher ist die Videoqulität auf die schlechteste Stufe limitiert.",
"dataChannelClosedDescriptionWithAudio": "Die Steuerungsverbindung (Bridge Channel) wurde unterbrochen, daher können Video- und Tonprobleme auftreten.",
@@ -758,9 +757,9 @@
"gifsMenu": "GIPHY",
"groupTitle": "Benachrichtigungen",
"hostAskedUnmute": "Die Moderation bittet Sie, das Mikrofon zu aktivieren",
"invalidTenant": "Ungültiger Mandant",
"invalidTenantHyphenDescription": "Der gewählte Mandantenname ist ungültig (beginnt oder endet mit '-').",
"invalidTenantLengthDescription": "Der gewählte Mandantenname ist zu lang.",
"invalidTenant": "Ungültiger Tenant",
"invalidTenantHyphenDescription": "Der von Ihnen genutzte Tenantname ist unfültig (beginnt oder endet mit '-').",
"invalidTenantLengthDescription": "Der von Ihnen genutzte Tenantname ist zu lang.",
"invitedOneMember": "{{name}} wurde eingeladen",
"invitedThreePlusMembers": "{{name}} und {{count}} andere wurden eingeladen",
"invitedTwoMembers": "{{first}} und {{second}} wurden eingeladen",
@@ -1060,7 +1059,7 @@
"onBy": "{{name}} startete die Aufnahme",
"onlyRecordSelf": "Nur eigenes Kamerabild und Ton aufzeichnen",
"pending": "Aufzeichnung der Konferenz wird vorbereitet…",
"policyError": "Sie haben die Aufzeichnung zu schnell gestartet. Bitte versuchen Sie es später noch einmal.",
"policyError": "Sie haben die Aufzeichnung zu früh gestartet. Bitte versuchen Sie es später noch einmal.",
"recordAudioAndVideo": "Kamera und Ton aufzeichnen",
"recordTranscription": "Transkription aufzeichnen",
"saveLocalRecording": "Aufzeichnung lokal abspeichern",
@@ -1083,10 +1082,10 @@
"pullToRefresh": "Ziehen, um zu aktualisieren"
},
"security": {
"about": "Sie können Ihre Konferenz mit einem Passwort sichern. Personen müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
"about": "Sie können Ihre Konferenz mit einem Passwort sichern. Teilnehmer müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
"aboutReadOnly": "Mit Moderationsrechten kann die Konferenz mit einem Passwort gesichert werden. Personen müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
"insecureRoomNameWarningNative": "Der Raumname ist unsicher. Unerwünschte Personen könnten Ihrer Konferenz beitreten. {{recommendAction}} Lernen Sie mehr über die Absicherung Ihrer Konferenz ",
"insecureRoomNameWarningWeb": "Der Raumname ist unsicher. Unerwünschte Personen könnten Ihrer Konferenz beitreten {{recommendAction}} Lernen Sie <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">hier</a> mehr über die Absicherung Ihrer Konferenz.",
"insecureRoomNameWarningNative": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten. {{recommendAction}} Lernen Sie mehr über die Absicherung Ihrer Konferenz ",
"insecureRoomNameWarningWeb": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten {{recommendAction}} Lernen Sie <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">hier</a> mehr über die Absicherung Ihrer Konferenz.",
"title": "Sicherheitsoptionen",
"unsafeRoomActions": {
"meeting": "Erwägen Sie die Absicherung Ihrer Konferenz über den Sicherheits-Button.",
@@ -1186,7 +1185,6 @@
"fearful": "Ängstlich",
"happy": "Fröhlich",
"hours": "{{count}} Std. ",
"labelTooltip": "Anzahl der Personen: {{count}}",
"minutes": "{{count}} Min. ",
"name": "Name",
"neutral": "Neutral",

File diff suppressed because it is too large Load Diff

View File

@@ -263,7 +263,6 @@
"Remove": "Remove",
"Share": "Share",
"Submit": "Submit",
"Understand": "I understand",
"WaitForHostMsg": "The conference has not yet started because no moderators have yet arrived. If you'd like to become a moderator please log-in. Otherwise, please wait.",
"WaitForHostNoAuthMsg": "The conference has not yet started because no moderators have yet arrived. Please wait.",
"WaitingForHostButton": "Wait for moderator",
@@ -359,7 +358,7 @@
"micTimeoutError": "Could not start audio source. Timeout occurred!",
"micUnknownError": "Cannot use microphone for an unknown reason.",
"moderationAudioLabel": "Allow attendees to unmute themselves",
"moderationVideoLabel": "Allow non-moderators to start their video",
"moderationVideoLabel": "Allow attendees to start their video",
"muteEveryoneDialog": "The participants can unmute themselves at any time.",
"muteEveryoneDialogModerationOn": "The participants can send a request to speak at any time.",
"muteEveryoneElseDialog": "Once muted, you won't be able to unmute them, but they can unmute themselves at any time.",
@@ -394,8 +393,6 @@
"recentlyUsedObjects": "Your recently used objects",
"recording": "Recording",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Not possible while a live stream is active",
"recordingInProgressDescription": "This meeting is being recorded. Your audio and video have been muted. If you choose to unmute, you consent to being recorded.",
"recordingInProgressTitle": "Recording in progress",
"rejoinNow": "Rejoin now",
"remoteControlAllowedMessage": "{{user}} accepted your remote control request!",
"remoteControlDeniedMessage": "{{user}} rejected your remote control request!",
@@ -848,7 +845,7 @@
"actions": {
"admit": "Admit",
"admitAll": "Admit all",
"allow": "Allow non-moderators to:",
"allow": "Allow attendees to:",
"allowVideo": "Allow video",
"askUnmute": "Ask to unmute",
"audioModeration": "Unmute themselves",

6
modules/API/API.js Executable file → Normal file
View File

@@ -1050,12 +1050,6 @@ function initCommands() {
callback(getRoomsInfo(APP.store.getState()));
break;
}
case 'get-shared-document-url': {
const { etherpad } = APP.store.getState()['features/etherpad'];
callback(etherpad?.documentUrl || '');
break;
}
case 'get-p2p-status': {
callback(isP2pActive(APP.store.getState()));
break;

View File

@@ -682,17 +682,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
});
}
/**
* Returns the Shared Document Url of the conference.
*
* @returns {Object} Rooms info.
*/
async getSharedDocumentUrl() {
return this._transport.sendRequest({
name: 'get-shared-document-url'
});
}
/**
* Returns whether the conference is P2P.
*

525
package-lock.json generated
View File

@@ -62,7 +62,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/v1928.0.0+763b2c8f/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1915.0.0+6e9b9c01/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",
@@ -8803,8 +8803,7 @@
"node_modules/@yarnpkg/lockfile": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
"dev": true
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
},
"node_modules/@zip.js/zip.js": {
"version": "2.7.54",
@@ -9618,6 +9617,14 @@
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==",
"license": "MIT"
},
"node_modules/at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"engines": {
"node": ">= 4.0.0"
}
},
"node_modules/available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -9962,7 +9969,6 @@
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true,
"engines": {
"node": ">=8"
}
@@ -10513,7 +10519,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -10537,7 +10542,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"dependencies": {
"is-glob": "^4.0.1"
},
@@ -11431,6 +11435,11 @@
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
"license": "MIT"
},
"node_modules/debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -13828,7 +13837,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
"integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
"dev": true,
"dependencies": {
"micromatch": "^4.0.2"
}
@@ -15183,7 +15191,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"dependencies": {
"binary-extensions": "^2.0.0"
},
@@ -15239,7 +15246,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
"integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
"dev": true,
"dependencies": {
"ci-info": "^2.0.0"
},
@@ -16782,6 +16788,21 @@
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
},
"node_modules/karma-rollup-preprocessor": {
"version": "7.0.8",
"resolved": "https://registry.npmjs.org/karma-rollup-preprocessor/-/karma-rollup-preprocessor-7.0.8.tgz",
"integrity": "sha512-WiuBCS9qsatJuR17dghiTARBZ7LF+ml+eb7qJXhw7IbsdY0lTWELDRQC/93J9i6636CsAXVBL3VJF4WtaFLZzA==",
"dependencies": {
"chokidar": "^3.3.1",
"debounce": "^1.2.0"
},
"engines": {
"node": ">= 8.0.0"
},
"peerDependencies": {
"rollup": ">= 1.0.0"
}
},
"node_modules/kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -16794,7 +16815,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
"integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
"dev": true,
"dependencies": {
"graceful-fs": "^4.1.11"
}
@@ -16889,8 +16909,9 @@
},
"node_modules/lib-jitsi-meet": {
"version": "0.0.0",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1928.0.0+763b2c8f/lib-jitsi-meet.tgz",
"integrity": "sha512-gjJfU1Ll4sYIpPM3vE5nFnPQgun2D/8RoYCsOmk+P1V/OZWx1E+v3iZiK6OyzgGnZlIPlF83rcUMUYy8WIFFCA==",
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1915.0.0+6e9b9c01/lib-jitsi-meet.tgz",
"integrity": "sha512-erPBz93xzWDIvW9EdvSfiraHFi0TMo1W68zxe7rKvIQWX1DCjmKxWKnxdq5WirSD7MXwoSIxgdX4PB7Wz3aTmg==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@jitsi/js-utils": "2.2.1",
@@ -16903,8 +16924,11 @@
"current-executing-script": "0.1.3",
"jquery": "3.6.1",
"lodash-es": "4.17.21",
"patch-package": "6.5.1",
"sdp-transform": "2.3.0",
"strophe.js": "https://github.com/jitsi/strophejs/releases/download/v1.5-jitsi-3/strophe.js-1.5.0.tgz",
"strophe.js": "1.5.0",
"strophejs-plugin-disco": "0.0.2",
"strophejs-plugin-stream-management": "git+https://github.com/jitsi/strophejs-plugin-stream-management#679be5902097ed612fb5062b5549f3f32b6f5f47",
"uuid": "8.1.0",
"webrtc-adapter": "8.1.1"
}
@@ -16928,11 +16952,197 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/lib-jitsi-meet/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/lib-jitsi-meet/node_modules/base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
"node_modules/lib-jitsi-meet/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/lib-jitsi-meet/node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/lib-jitsi-meet/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/lib-jitsi-meet/node_modules/cross-spawn": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
"integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"dependencies": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
},
"engines": {
"node": ">=4.8"
}
},
"node_modules/lib-jitsi-meet/node_modules/fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dependencies": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/lib-jitsi-meet/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"engines": {
"node": ">=8"
}
},
"node_modules/lib-jitsi-meet/node_modules/jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dependencies": {
"universalify": "^2.0.0"
},
"optionalDependencies": {
"graceful-fs": "^4.1.6"
}
},
"node_modules/lib-jitsi-meet/node_modules/patch-package": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz",
"integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==",
"dependencies": {
"@yarnpkg/lockfile": "^1.1.0",
"chalk": "^4.1.2",
"cross-spawn": "^6.0.5",
"find-yarn-workspace-root": "^2.0.0",
"fs-extra": "^9.0.0",
"is-ci": "^2.0.0",
"klaw-sync": "^6.0.0",
"minimist": "^1.2.6",
"open": "^7.4.2",
"rimraf": "^2.6.3",
"semver": "^5.6.0",
"slash": "^2.0.0",
"tmp": "^0.0.33",
"yaml": "^1.10.2"
},
"bin": {
"patch-package": "index.js"
},
"engines": {
"node": ">=10",
"npm": ">5"
}
},
"node_modules/lib-jitsi-meet/node_modules/path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
"integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
"engines": {
"node": ">=4"
}
},
"node_modules/lib-jitsi-meet/node_modules/rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"dependencies": {
"glob": "^7.1.3"
},
"bin": {
"rimraf": "bin.js"
}
},
"node_modules/lib-jitsi-meet/node_modules/semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
"bin": {
"semver": "bin/semver"
}
},
"node_modules/lib-jitsi-meet/node_modules/shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
"dependencies": {
"shebang-regex": "^1.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lib-jitsi-meet/node_modules/shebang-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/lib-jitsi-meet/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/lib-jitsi-meet/node_modules/universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==",
"engines": {
"node": ">= 10.0.0"
}
},
"node_modules/lib-jitsi-meet/node_modules/uuid": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz",
@@ -16941,6 +17151,17 @@
"uuid": "dist/bin/uuid"
}
},
"node_modules/lib-jitsi-meet/node_modules/which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"dependencies": {
"isexe": "^2.0.0"
},
"bin": {
"which": "bin/which"
}
},
"node_modules/lie": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
@@ -18577,8 +18798,7 @@
"node_modules/nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
},
"node_modules/no-case": {
"version": "3.0.4",
@@ -19105,7 +19325,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@@ -21640,7 +21859,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"dependencies": {
"picomatch": "^2.2.1"
},
@@ -22657,7 +22875,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
"integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
"dev": true,
"engines": {
"node": ">=6"
}
@@ -23241,9 +23458,54 @@
},
"node_modules/strophe.js": {
"version": "1.5.0",
"resolved": "https://github.com/jitsi/strophejs/releases/download/v1.5-jitsi-3/strophe.js-1.5.0.tgz",
"integrity": "sha512-LNtsu2qioXofCESHqEmLF12DuIK7itMMjxe9aSeQOENz8rCXBY/khV8OKO2xaWBy0QxpQs7nyb7RHefVu9ZlfA==",
"license": "MIT"
"resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.5.0.tgz",
"integrity": "sha512-H5tE/tZxPR5xP3jhXyQwsjnMSwQMf7vrn9r1OkufTApyGHYe8WjzhsfxtL3AFhVu7vFjXPPZBrmUOTm1ccYgOA==",
"dependencies": {
"abab": "^2.0.3",
"karma-rollup-preprocessor": "^7.0.8"
},
"optionalDependencies": {
"@xmldom/xmldom": "0.8.2",
"ws": "^8.5.0"
}
},
"node_modules/strophe.js/node_modules/ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"optional": true,
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/strophejs-plugin-disco": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/strophejs-plugin-disco/-/strophejs-plugin-disco-0.0.2.tgz",
"integrity": "sha512-T9pJFzn1ZUqZ/we9+OvI5pFdrjeb4IBMbEjK+ZWEZV036wEl8l8GOtF8AJ3sIqOMtdIiFLdFu99JiGWd7yapAQ==",
"peerDependencies": {
"strophe.js": "^1.2.12"
}
},
"node_modules/strophejs-plugin-stream-management": {
"version": "1.0.0",
"resolved": "git+ssh://git@github.com/jitsi/strophejs-plugin-stream-management.git#679be5902097ed612fb5062b5549f3f32b6f5f47",
"integrity": "sha512-pQUT174bznpLEVNAnJT2Q7lyoSaoIoo8LaVyglRx5rWwxpdHUcS+8NjfLYDlqM+rLcsO1uAKt/fMZ7j3clj9qg==",
"license": "MIT",
"peerDependencies": {
"strophe.js": ">=1.3.4"
}
},
"node_modules/style-loader": {
"version": "3.3.1",
@@ -23605,7 +23867,6 @@
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"dependencies": {
"os-tmpdir": "~1.0.2"
},
@@ -31599,8 +31860,7 @@
"@yarnpkg/lockfile": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
"dev": true
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ=="
},
"@zip.js/zip.js": {
"version": "2.7.54",
@@ -32165,6 +32425,11 @@
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg=="
},
"available-typed-arrays": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz",
@@ -32433,8 +32698,7 @@
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
"dev": true
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
},
"bl": {
"version": "4.1.0",
@@ -32819,7 +33083,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"dev": true,
"requires": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
@@ -32835,7 +33098,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"requires": {
"is-glob": "^4.0.1"
}
@@ -33488,6 +33750,11 @@
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
"integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg=="
},
"debounce": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz",
"integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug=="
},
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -35204,7 +35471,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
"integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
"dev": true,
"requires": {
"micromatch": "^4.0.2"
}
@@ -36162,7 +36428,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"dev": true,
"requires": {
"binary-extensions": "^2.0.0"
}
@@ -36200,7 +36465,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
"integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
"dev": true,
"requires": {
"ci-info": "^2.0.0"
}
@@ -37279,6 +37543,15 @@
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
},
"karma-rollup-preprocessor": {
"version": "7.0.8",
"resolved": "https://registry.npmjs.org/karma-rollup-preprocessor/-/karma-rollup-preprocessor-7.0.8.tgz",
"integrity": "sha512-WiuBCS9qsatJuR17dghiTARBZ7LF+ml+eb7qJXhw7IbsdY0lTWELDRQC/93J9i6636CsAXVBL3VJF4WtaFLZzA==",
"requires": {
"chokidar": "^3.3.1",
"debounce": "^1.2.0"
}
},
"kind-of": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@@ -37288,7 +37561,6 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
"integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.11"
}
@@ -37365,8 +37637,8 @@
}
},
"lib-jitsi-meet": {
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1928.0.0+763b2c8f/lib-jitsi-meet.tgz",
"integrity": "sha512-gjJfU1Ll4sYIpPM3vE5nFnPQgun2D/8RoYCsOmk+P1V/OZWx1E+v3iZiK6OyzgGnZlIPlF83rcUMUYy8WIFFCA==",
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1915.0.0+6e9b9c01/lib-jitsi-meet.tgz",
"integrity": "sha512-erPBz93xzWDIvW9EdvSfiraHFi0TMo1W68zxe7rKvIQWX1DCjmKxWKnxdq5WirSD7MXwoSIxgdX4PB7Wz3aTmg==",
"requires": {
"@jitsi/js-utils": "2.2.1",
"@jitsi/logger": "2.0.2",
@@ -37378,8 +37650,11 @@
"current-executing-script": "0.1.3",
"jquery": "3.6.1",
"lodash-es": "4.17.21",
"patch-package": "6.5.1",
"sdp-transform": "2.3.0",
"strophe.js": "https://github.com/jitsi/strophejs/releases/download/v1.5-jitsi-3/strophe.js-1.5.0.tgz",
"strophe.js": "1.5.0",
"strophejs-plugin-disco": "0.0.2",
"strophejs-plugin-stream-management": "git+https://github.com/jitsi/strophejs-plugin-stream-management#679be5902097ed612fb5062b5549f3f32b6f5f47",
"uuid": "8.1.0",
"webrtc-adapter": "8.1.1"
},
@@ -37402,15 +37677,155 @@
}
}
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"requires": {
"color-convert": "^2.0.1"
}
},
"base64-js": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"cross-spawn": {
"version": "6.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz",
"integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==",
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
}
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^2.0.0"
}
},
"patch-package": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/patch-package/-/patch-package-6.5.1.tgz",
"integrity": "sha512-I/4Zsalfhc6bphmJTlrLoOcAF87jcxko4q0qsv4bGcurbr8IskEOtdnt9iCmsQVGL1B+iUhSQqweyTLJfCF9rA==",
"requires": {
"@yarnpkg/lockfile": "^1.1.0",
"chalk": "^4.1.2",
"cross-spawn": "^6.0.5",
"find-yarn-workspace-root": "^2.0.0",
"fs-extra": "^9.0.0",
"is-ci": "^2.0.0",
"klaw-sync": "^6.0.0",
"minimist": "^1.2.6",
"open": "^7.4.2",
"rimraf": "^2.6.3",
"semver": "^5.6.0",
"slash": "^2.0.0",
"tmp": "^0.0.33",
"yaml": "^1.10.2"
}
},
"path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
"integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="
},
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"requires": {
"glob": "^7.1.3"
}
},
"semver": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
"integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
"requires": {
"shebang-regex": "^1.0.0"
}
},
"shebang-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"requires": {
"has-flag": "^4.0.0"
}
},
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
"integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
},
"uuid": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-8.1.0.tgz",
"integrity": "sha512-CI18flHDznR0lq54xBycOVmphdCYnQLKn8abKn7PXUiKUGdEd+/l9LWNJmugXel4hXq7S+RMNl34ecyC9TntWg=="
},
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
"integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
"requires": {
"isexe": "^2.0.0"
}
}
}
},
@@ -38632,8 +39047,7 @@
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
},
"no-case": {
"version": "3.0.4",
@@ -38974,8 +39388,7 @@
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
"dev": true
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"own-keys": {
"version": "1.0.1",
@@ -40655,7 +41068,6 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"dev": true,
"requires": {
"picomatch": "^2.2.1"
}
@@ -41424,8 +41836,7 @@
"slash": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
"integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
"dev": true
"integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A=="
},
"slashes": {
"version": "3.0.12",
@@ -41864,8 +42275,33 @@
"integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
},
"strophe.js": {
"version": "https://github.com/jitsi/strophejs/releases/download/v1.5-jitsi-3/strophe.js-1.5.0.tgz",
"integrity": "sha512-LNtsu2qioXofCESHqEmLF12DuIK7itMMjxe9aSeQOENz8rCXBY/khV8OKO2xaWBy0QxpQs7nyb7RHefVu9ZlfA=="
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/strophe.js/-/strophe.js-1.5.0.tgz",
"integrity": "sha512-H5tE/tZxPR5xP3jhXyQwsjnMSwQMf7vrn9r1OkufTApyGHYe8WjzhsfxtL3AFhVu7vFjXPPZBrmUOTm1ccYgOA==",
"requires": {
"@xmldom/xmldom": "0.8.7",
"abab": "^2.0.3",
"karma-rollup-preprocessor": "^7.0.8",
"ws": "^8.5.0"
},
"dependencies": {
"ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
"optional": true
}
}
},
"strophejs-plugin-disco": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/strophejs-plugin-disco/-/strophejs-plugin-disco-0.0.2.tgz",
"integrity": "sha512-T9pJFzn1ZUqZ/we9+OvI5pFdrjeb4IBMbEjK+ZWEZV036wEl8l8GOtF8AJ3sIqOMtdIiFLdFu99JiGWd7yapAQ=="
},
"strophejs-plugin-stream-management": {
"version": "git+ssh://git@github.com/jitsi/strophejs-plugin-stream-management.git#679be5902097ed612fb5062b5549f3f32b6f5f47",
"integrity": "sha512-pQUT174bznpLEVNAnJT2Q7lyoSaoIoo8LaVyglRx5rWwxpdHUcS+8NjfLYDlqM+rLcsO1uAKt/fMZ7j3clj9qg==",
"from": "strophejs-plugin-stream-management@git+https://github.com/jitsi/strophejs-plugin-stream-management#679be5902097ed612fb5062b5549f3f32b6f5f47"
},
"style-loader": {
"version": "3.3.1",
@@ -42123,7 +42559,6 @@
"version": "0.0.33",
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"requires": {
"os-tmpdir": "~1.0.2"
}

View File

@@ -68,7 +68,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/v1928.0.0+763b2c8f/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1915.0.0+6e9b9c01/lib-jitsi-meet.tgz",
"lodash-es": "4.17.21",
"moment": "2.29.4",
"moment-duration-format": "2.2.2",

View File

@@ -205,7 +205,7 @@ export default class AlwaysOnTop extends Component<any, IState> {
* @inheritdoc
* @returns {void}
*/
override componentDidMount() {
componentDidMount() {
api.on('avatarChanged', this._avatarChangedListener);
api.on('displayNameChange', this._displayNameChangedListener);
api.on('largeVideoChanged', this._videoChangedListener);
@@ -231,7 +231,7 @@ export default class AlwaysOnTop extends Component<any, IState> {
* @inheritdoc
* @returns {void}
*/
override componentDidUpdate(_prevProps: any, prevState: IState) {
componentDidUpdate(_prevProps: any, prevState: IState) {
if (!prevState.visible && this.state.visible) {
this._hideToolbarAfterTimeout();
}
@@ -243,7 +243,7 @@ export default class AlwaysOnTop extends Component<any, IState> {
* @inheritdoc
* @returns {void}
*/
override componentWillUnmount() {
componentWillUnmount() {
api.removeListener('avatarChanged', this._avatarChangedListener);
api.removeListener(
'displayNameChange',
@@ -267,7 +267,7 @@ export default class AlwaysOnTop extends Component<any, IState> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
return (
<div id = 'alwaysOnTop'>
<Toolbar

View File

@@ -63,7 +63,7 @@ export default class AudioMuteButton extends Component<Props, IState> {
* @inheritdoc
* @returns {void}
*/
override componentDidMount() {
componentDidMount() {
api.on('audioAvailabilityChanged', this._audioAvailabilityListener);
api.on('audioMuteStatusChanged', this._audioMutedListener);
@@ -86,7 +86,7 @@ export default class AudioMuteButton extends Component<Props, IState> {
* @inheritdoc
* @returns {void}
*/
override componentWillUnmount() {
componentWillUnmount() {
api.removeListener(
'audioAvailabilityChanged',
this._audioAvailabilityListener);
@@ -165,7 +165,7 @@ export default class AudioMuteButton extends Component<Props, IState> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const toggled = this._isAudioMuted();
return (

View File

@@ -48,7 +48,7 @@ export default class HangupButton extends Component<Props> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
return (
<ToolbarButton
accessibilityLabel = { this.accessibilityLabel }

View File

@@ -73,7 +73,7 @@ export default class Toolbar extends Component<Props, IState> {
* @inheritdoc
* @returns {void}
*/
override componentDidMount() {
componentDidMount() {
api.on('videoConferenceJoined', this._videoConferenceJoinedListener);
this._videoConferenceJoinedListener();
@@ -106,7 +106,7 @@ export default class Toolbar extends Component<Props, IState> {
* @inheritdoc
* @returns {void}
*/
override componentWillUnmount() {
componentWillUnmount() {
api.removeListener('videoConferenceJoined', this._videoConferenceJoinedListener);
}
@@ -116,7 +116,7 @@ export default class Toolbar extends Component<Props, IState> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const {
className = '',
onMouseOut,

View File

@@ -63,7 +63,7 @@ export default class VideoMuteButton extends Component<Props, State> {
* @inheritdoc
* @returns {void}
*/
override componentDidMount() {
componentDidMount() {
api.on('videoAvailabilityChanged', this._videoAvailabilityListener);
api.on('videoMuteStatusChanged', this._videoMutedListener);
@@ -85,7 +85,7 @@ export default class VideoMuteButton extends Component<Props, State> {
* @inheritdoc
* @returns {void}
*/
override componentWillUnmount() {
componentWillUnmount() {
api.removeListener(
'videoAvailabilityChanged',
this._videoAvailabilityListener);
@@ -165,7 +165,7 @@ export default class VideoMuteButton extends Component<Props, State> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const toggled = this._isVideoMuted();
return (

View File

@@ -31,7 +31,7 @@ export class AbstractApp<P extends IProps = IProps> extends BaseApp<P> {
*
* @inheritdoc
*/
override async componentDidMount() {
async componentDidMount() {
await super.componentDidMount();
// If a URL was explicitly specified to this React Component, then
@@ -44,7 +44,7 @@ export class AbstractApp<P extends IProps = IProps> extends BaseApp<P> {
*
* @inheritdoc
*/
override async componentDidUpdate(prevProps: IProps) {
async componentDidUpdate(prevProps: IProps) {
const previousUrl = toURLString(prevProps.url);
const currentUrl = toURLString(this.props.url);
const previousTimestamp = prevProps.timestamp;

View File

@@ -80,7 +80,7 @@ export class App extends AbstractApp<IProps> {
*
* @returns {void}
*/
override async componentDidMount() {
async componentDidMount() {
await super.componentDidMount();
SplashScreen.hide();
@@ -96,7 +96,7 @@ export class App extends AbstractApp<IProps> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
return (
<JitsiThemePaperProvider>
{ super.render() }

View File

@@ -28,7 +28,7 @@ export class App extends AbstractApp {
* @protected
* @returns {ReactElement}
*/
override _createExtraElement() {
_createExtraElement() {
return (
<JitsiThemeProvider>
<OverlayContainer />
@@ -42,7 +42,7 @@ export class App extends AbstractApp {
*
* @override
*/
override _createMainElement(component: React.ComponentType, props?: Object) {
_createMainElement(component: React.ComponentType, props?: Object) {
return (
<JitsiThemeProvider>
<GlobalStyles />
@@ -57,7 +57,7 @@ export class App extends AbstractApp {
*
* @returns {React$Element}
*/
override _renderDialogContainer() {
_renderDialogContainer() {
return (
<JitsiThemeProvider>
<DialogContainer />

View File

@@ -36,7 +36,7 @@ class AudioLevelIndicator extends Component<IProps> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const { audioLevel: passedAudioLevel } = this.props;
// First make sure we are sensitive enough.

View File

@@ -132,7 +132,7 @@ class LoginDialog extends Component<IProps, IState> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const {
_connecting: connecting,
t

View File

@@ -60,7 +60,7 @@ class WaitForOwnerDialog extends Component<IProps> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const { _isConfirmHidden } = this.props;
return (

View File

@@ -220,7 +220,7 @@ class LoginDialog extends Component<IProps, IState> {
*
* @inheritdoc
*/
override render() {
render() {
const {
_connecting: connecting,
t

View File

@@ -74,7 +74,7 @@ class WaitForOwnerDialog extends PureComponent<IProps> {
*
* @inheritdoc
*/
override render() {
render() {
const {
t
} = this.props;

View File

@@ -67,7 +67,7 @@ export default class BaseApp<P> extends Component<P, IState> {
*
* @inheritdoc
*/
override async componentDidMount() {
async componentDidMount() {
/**
* Make the mobile {@code BaseApp} wait until the {@code AsyncStorage}
* implementation of {@code Storage} initializes fully.
@@ -107,7 +107,7 @@ export default class BaseApp<P> extends Component<P, IState> {
*
* @inheritdoc
*/
override componentWillUnmount() {
componentWillUnmount() {
this.state.store?.dispatch(appWillUnmount(this));
}
@@ -119,7 +119,7 @@ export default class BaseApp<P> extends Component<P, IState> {
*
* @returns {void}
*/
override componentDidCatch(error: Error, info: Object) {
componentDidCatch(error: Error, info: Object) {
logger.error(error, info);
}
@@ -153,7 +153,7 @@ export default class BaseApp<P> extends Component<P, IState> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const { route: { component, props }, store } = this.state;
if (store) {

View File

@@ -148,7 +148,7 @@ class Avatar<P extends IProps> extends PureComponent<P, IState> {
*
* @inheritdoc
*/
override componentDidUpdate(prevProps: P) {
componentDidUpdate(prevProps: P) {
const { _corsAvatarURLs, url } = this.props;
if (prevProps.url !== url) {
@@ -170,7 +170,7 @@ class Avatar<P extends IProps> extends PureComponent<P, IState> {
*
* @inheritdoc
*/
override render() {
render() {
const {
_customAvatarBackgrounds,
_initialsBase,

View File

@@ -51,7 +51,7 @@ export default class StatelessAvatar extends Component<IProps> {
*
* @inheritdoc
*/
override render() {
render() {
const { initials, size, style, url } = this.props;
let avatar;

View File

@@ -4,7 +4,7 @@ import { JitsiConferenceErrors } from '../lib-jitsi-meet';
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
import { CONFERENCE_FAILED } from './actionTypes';
import { conferenceLeft } from './actions.native';
import { conferenceLeft } from './actions';
import { TRIGGER_READY_TO_CLOSE_REASONS } from './constants';
import './middleware.any';
@@ -15,20 +15,10 @@ MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
case CONFERENCE_FAILED: {
const { getState } = store;
const state = getState();
const { notifyOnConferenceDestruction = true } = state['features/base/config'];
if (error?.name !== JitsiConferenceErrors.CONFERENCE_DESTROYED) {
break;
}
if (!notifyOnConferenceDestruction) {
dispatch(conferenceLeft(action.conference));
dispatch(appNavigate(undefined));
break;
}
const [ reason ] = error.params;
const reasonKey = Object.keys(TRIGGER_READY_TO_CLOSE_REASONS)[

View File

@@ -122,14 +122,12 @@ MiddlewareRegistry.register(store => next => action => {
}
if (errorName === JitsiConferenceErrors.CONFERENCE_DESTROYED) {
const state = getState();
const { notifyOnConferenceDestruction = true } = state['features/base/config'];
const [ reason ] = action.error.params;
const titlekey = Object.keys(TRIGGER_READY_TO_CLOSE_REASONS)[
Object.values(TRIGGER_READY_TO_CLOSE_REASONS).indexOf(reason)
];
dispatch(hangup(true, i18next.t(titlekey) || reason, notifyOnConferenceDestruction));
dispatch(hangup(true, i18next.t(titlekey) || reason));
}
releaseScreenLock();

View File

@@ -486,7 +486,6 @@ export interface IConfig {
short?: number;
};
notifications?: Array<string>;
notifyOnConferenceDestruction?: boolean;
openSharedDocumentOnJoin?: boolean;
opusMaxAverageBitrate?: number;
p2p?: {
@@ -543,7 +542,6 @@ export interface IConfig {
recordingSharingUrl?: string;
recordings?: {
recordAudioAndVideo?: boolean;
requireConsent?: boolean;
showPrejoinWarning?: boolean;
showRecordingLink?: boolean;
suggestRecording?: boolean;
@@ -604,7 +602,6 @@ export interface IConfig {
tokenAuthUrl?: string;
tokenAuthUrlAutoRedirect?: string;
tokenLogoutUrl?: string;
tokenRespectTenant?: string;
toolbarButtons?: Array<ToolbarButton>;
toolbarConfig?: {
alwaysVisible?: boolean;

View File

@@ -182,7 +182,6 @@ export default [
'mouseMoveCallbackInterval',
'notifications',
'notificationTimeouts',
'notifyOnConferenceDestruction',
'openSharedDocumentOnJoin',
'opusMaxAverageBitrate',
'p2p.backToP2PDelay',
@@ -206,10 +205,7 @@ export default [
'remoteVideoMenu',
'roomPasswordNumberOfDigits',
'readOnlyName',
'recordings.recordAudioAndVideo',
'recordings.showPrejoinWarning',
'recordings.showRecordingLink',
'recordings.suggestRecording',
'recordings',
'replaceParticipant',
'resolution',
'screenshotCapture',

View File

@@ -572,12 +572,9 @@ function _translateLegacyConfig(oldValue: IConfig) {
};
}
// Profile button is not available on mobile
if (navigator.product !== 'ReactNative') {
if (oldValue.disableProfile) {
newValue.toolbarButtons = (newValue.toolbarButtons || TOOLBAR_BUTTONS)
.filter((button: ToolbarButton) => button !== 'profile');
}
if (oldValue.disableProfile) {
newValue.toolbarButtons = (newValue.toolbarButtons || TOOLBAR_BUTTONS)
.filter((button: ToolbarButton) => button !== 'profile');
}
_setDeeplinkingDefaults(newValue.deeplinking as IDeeplinkingConfig);

View File

@@ -62,11 +62,9 @@ export function connect(id?: string, password?: string) {
* @param {boolean} [requestFeedback] - Whether to attempt showing a
* request for call feedback.
* @param {string} [feedbackTitle] - The feedback title.
* @param {boolean} [notifyOnConferenceTermination] - Whether to notify
* the user on conference termination.
* @returns {Function}
*/
export function hangup(requestFeedback = false, feedbackTitle?: string, notifyOnConferenceTermination?: boolean) {
export function hangup(requestFeedback = false, feedbackTitle?: string) {
// XXX For web based version we use conference hanging up logic from the old app.
return async (dispatch: IStore['dispatch']) => {
if (LocalRecordingManager.isRecordingLocally()) {
@@ -82,6 +80,6 @@ export function hangup(requestFeedback = false, feedbackTitle?: string, notifyOn
});
}
return APP.conference.hangup(requestFeedback, feedbackTitle, notifyOnConferenceTermination);
return APP.conference.hangup(requestFeedback, feedbackTitle);
};
}

View File

@@ -52,7 +52,7 @@ export default class AbstractDialog<P extends IProps, S extends IState = IState>
*
* @inheritdoc
*/
override componentDidMount() {
componentDidMount() {
this._mounted = true;
}
@@ -62,7 +62,7 @@ export default class AbstractDialog<P extends IProps, S extends IState = IState>
*
* @inheritdoc
*/
override componentWillUnmount() {
componentWillUnmount() {
this._mounted = false;
}

View File

@@ -31,7 +31,7 @@ class AlertDialog extends AbstractDialog<IProps> {
*
* @inheritdoc
*/
override render() {
render() {
const { contentKey, t } = this.props;
const content
= typeof contentKey === 'string'

View File

@@ -100,7 +100,7 @@ class BottomSheet extends PureComponent<Props> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const {
addScrollViewPadding,
renderHeader,

View File

@@ -36,11 +36,6 @@ interface IProps extends AbstractProps, WithTranslation {
*/
descriptionKey?: string | { key: string; params: string; };
/**
* Whether the cancel button is hidden.
*/
isCancelHidden?: Boolean;
/**
* Whether or not the nature of the confirm button is destructive.
*/
@@ -100,12 +95,11 @@ class ConfirmDialog extends AbstractDialog<IProps> {
*
* @inheritdoc
*/
override render() {
render() {
const {
cancelLabel,
children,
confirmLabel,
isCancelHidden,
isConfirmDestructive,
isConfirmHidden,
t,
@@ -127,12 +121,10 @@ class ConfirmDialog extends AbstractDialog<IProps> {
}
{ this._renderDescription() }
{ children }
{
!isCancelHidden && <Dialog.Button
label = { t(cancelLabel || 'dialog.confirmNo') }
onPress = { this._onCancel }
style = { styles.dialogButton } />
}
<Dialog.Button
label = { t(cancelLabel || 'dialog.confirmNo') }
onPress = { this._onCancel }
style = { styles.dialogButton } />
{
!isConfirmHidden && <Dialog.Button
label = { t(confirmLabel || 'dialog.confirmYes') }

View File

@@ -38,7 +38,7 @@ class DialogContainer extends AbstractDialogContainer {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
return (
<Fragment>
{this._renderReactions()}

View File

@@ -91,7 +91,7 @@ class InputDialog extends AbstractDialog<IProps, IState> {
*
* @inheritdoc
*/
override render() {
render() {
const {
descriptionKey,
messageKey,

View File

@@ -71,7 +71,7 @@ class PageReloadDialog extends Component<IProps, IPageReloadDialogState> {
* @inheritdoc
* @returns {void}
*/
override componentDidMount() {
componentDidMount() {
const { timeLeft } = this.state;
logger.info(
@@ -88,7 +88,7 @@ class PageReloadDialog extends Component<IProps, IPageReloadDialogState> {
* @inheritdoc
* @returns {void}
*/
override componentWillUnmount() {
componentWillUnmount() {
if (this._interval) {
clearInterval(this._interval);
this._interval = undefined;
@@ -157,7 +157,7 @@ class PageReloadDialog extends Component<IProps, IPageReloadDialogState> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const { isNetworkFailure, t } = this.props;
const { timeLeft } = this.state;

View File

@@ -4,12 +4,6 @@
*/
export const ADD_PEOPLE_ENABLED = 'add-people.enabled';
/**
* Flag indicating if the audio device button should be displayed.
* Default: enabled (true).
*/
export const AUDIO_DEVICE_BUTTON_ENABLED = 'audio-device-button.enabled';
/**
* Flag indicating if the SDK should not require the audio focus.
* Used by apps that do not use Jitsi audio.
@@ -245,16 +239,10 @@ export const SETTINGS_ENABLED = 'settings.enabled';
/**
* Flag indicating if tile view feature should be enabled.
* Default: enabled(true).
* Default: enabled.
*/
export const TILE_VIEW_ENABLED = 'tile-view.enabled';
/**
* Flag indicating if the toggle camera button should be enabled
* Default: enabled(true).
*/
export const TOGGLE_CAMERA_BUTTON_ENABLED = 'toggle-camera-button.enabled';
/**
* Flag indicating if the toolbox should be always be visible
* Default: disabled (false).

View File

@@ -1,12 +1,9 @@
import { ParticipantFeaturesKey } from '../participants/types';
/**
* The list of supported meeting features to enable/disable through jwt.
*/
export const MEET_FEATURES: Record<string, ParticipantFeaturesKey> = {
export const MEET_FEATURES = {
BRANDING: 'branding',
CALENDAR: 'calendar',
CREATE_POLLS: 'create-polls',
FLIP: 'flip',
INBOUND_CALL: 'inbound-call',
LIVESTREAMING: 'livestreaming',
@@ -16,7 +13,6 @@ export const MEET_FEATURES: Record<string, ParticipantFeaturesKey> = {
RECORDING: 'recording',
ROOM: 'room',
SCREEN_SHARING: 'screen-sharing',
SEND_GROUPCHAT: 'send-groupchat',
SIP_INBOUND_CALL: 'sip-inbound-call',
SIP_OUTBOUND_CALL: 'sip-outbound-call',
TRANSCRIPTION: 'transcription'

View File

@@ -4,7 +4,7 @@ import jwtDecode from 'jwt-decode';
import { IReduxState } from '../../app/types';
import { isVpaasMeeting } from '../../jaas/functions';
import { getLocalParticipant } from '../participants/functions';
import { IParticipantFeatures, ParticipantFeaturesKey } from '../participants/types';
import { IParticipantFeatures } from '../participants/types';
import { parseURLParams } from '../util/parseURLParams';
import { JWT_VALIDATION_ERRORS, MEET_FEATURES } from './constants';
@@ -49,12 +49,7 @@ export function getJwtName(state: IReduxState) {
* @param {boolean} ifNotInFeatures - Default value if features prop exists but does not have the {@code feature}.
* @returns {boolean}
*/
export function isJwtFeatureEnabled(
state: IReduxState,
feature: ParticipantFeaturesKey,
ifNoToken: boolean,
ifNotInFeatures: boolean
) {
export function isJwtFeatureEnabled(state: IReduxState, feature: string, ifNoToken: boolean, ifNotInFeatures: boolean) {
const { jwt } = state['features/base/jwt'];
let { features } = getLocalParticipant(state) || {};
@@ -73,7 +68,7 @@ export function isJwtFeatureEnabled(
}
interface IIsJwtFeatureEnabledStatelessParams {
feature: ParticipantFeaturesKey;
feature: string;
ifNoToken: boolean;
ifNotInFeatures: boolean;
jwt?: string;
@@ -106,11 +101,11 @@ export function isJwtFeatureEnabledStateless({
return ifNoToken;
}
if (typeof features[feature] === 'undefined') {
if (typeof features[feature as keyof typeof features] === 'undefined') {
return ifNotInFeatures;
}
return String(features[feature]) === 'true';
return String(features[feature as keyof typeof features]) === 'true';
}
/**
@@ -207,7 +202,7 @@ export function validateJwt(jwt: string) {
const { features } = context;
const meetFeatures = Object.values(MEET_FEATURES);
(Object.keys(features) as ParticipantFeaturesKey[]).forEach(feature => {
Object.keys(features).forEach(feature => {
if (meetFeatures.includes(feature)) {
const featureValue = features[feature];

View File

@@ -3,14 +3,12 @@ import jwtDecode from 'jwt-decode';
import { AnyAction } from 'redux';
import { IStore } from '../../app/types';
import { isVpaasMeeting } from '../../jaas/functions';
import { SET_CONFIG } from '../config/actionTypes';
import { SET_LOCATION_URL } from '../connection/actionTypes';
import { participantUpdated } from '../participants/actions';
import { getLocalParticipant } from '../participants/functions';
import { IParticipant } from '../participants/types';
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
import { parseURIString } from '../util/uri';
import { SET_JWT } from './actionTypes';
import { setJWT } from './actions';
@@ -127,8 +125,6 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
const { jwt, type, ...actionPayload } = action;
if (!Object.keys(actionPayload).length) {
const state = store.getState();
if (jwt) {
let jwtPayload;
@@ -154,22 +150,9 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
const newUser = user ? { ...user } : {};
let features = context.features;
const { tokenRespectTenant } = state['features/base/config'];
// eslint-disable-next-line max-depth
if (!isVpaasMeeting(state) && tokenRespectTenant && context.tenant) {
// we skip checking vpaas meetings as there are other backend rules in place
// this way vpaas users can still use this field if needed
const { locationURL = { href: '' } as URL } = state['features/base/connection'];
const { tenant = '' } = parseURIString(locationURL.href) || {};
features = context.tenant === tenant ? features : {};
}
_overwriteLocalParticipant(
store, { ...newUser,
features });
features: context.features });
// eslint-disable-next-line max-depth
if (context.user && context.user.role === 'visitor') {
@@ -189,7 +172,7 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
// On Web it should eventually be restored from storage, but there's
// no such use case yet.
const { user } = state['features/base/jwt'];
const { user } = store.getState()['features/base/jwt'];
user && _undoOverwriteLocalParticipant(store, user);
}

View File

@@ -48,7 +48,7 @@ export default abstract class ExpandedLabel<P extends IProps> extends Component<
*
* @inheritdoc
*/
override componentDidMount() {
componentDidMount() {
Animated.decay(this.state.opacityAnimation, {
toValue: 1,
velocity: 1,
@@ -61,7 +61,7 @@ export default abstract class ExpandedLabel<P extends IProps> extends Component<
*
* @inheritdoc
*/
override render() {
render() {
return (
<Animated.View
style = { [ styles.expandedLabelContainer,

View File

@@ -89,7 +89,7 @@ export default class Label extends Component<IProps, State> {
*
* @inheritdoc
*/
override componentDidMount() {
componentDidMount() {
this._maybeToggleAnimation({}, this.props);
}
@@ -98,7 +98,7 @@ export default class Label extends Component<IProps, State> {
*
* @inheritdoc
*/
override componentDidUpdate(prevProps: IProps) {
componentDidUpdate(prevProps: IProps) {
this._maybeToggleAnimation(prevProps, this.props);
}
@@ -107,7 +107,7 @@ export default class Label extends Component<IProps, State> {
*
* @inheritdoc
*/
override render() {
render() {
const { icon, text, status, style, iconColor, textStyle } = this.props;
let extraStyle = null;

View File

@@ -165,6 +165,7 @@ function _initLogging({ dispatch, getState }: IStore,
}
Logger.addGlobalTransport(_logCollector);
JitsiMeetJS.addGlobalLogTransport(_logCollector);
dispatch(setLogCollector(_logCollector));
// The JitsiMeetInMemoryLogStorage can not be accessed on mobile through

View File

@@ -72,7 +72,7 @@ export default class AbstractVideoTrack<P extends IProps> extends Component<P> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const videoTrack = _falsy2null(this.props.videoTrack);
let render;

View File

@@ -36,7 +36,7 @@ export default class Audio extends AbstractAudio {
*
* @inheritdoc
*/
override async componentDidUpdate(prevProps: IProps): Promise<void> {
async componentDidUpdate(prevProps: IProps): Promise<void> {
// source is different !! call didunmount and call didmount
if (prevProps.src !== this.props.src) {
await this.componentWillUnmount();
@@ -49,7 +49,7 @@ export default class Audio extends AbstractAudio {
*
* @returns {void}
*/
override async componentDidMount() {
async componentDidMount() {
this._sound
= this.props.src
? new Sound(
@@ -63,7 +63,7 @@ export default class Audio extends AbstractAudio {
*
* @returns {void}
*/
override async componentWillUnmount() {
async componentWillUnmount() {
if (this._sound) {
this._sound.release();
this._sound = null;
@@ -94,7 +94,7 @@ export default class Audio extends AbstractAudio {
* @inheritdoc
* @returns {null}
*/
override render() {
render() {
// TODO react-native-webrtc's RTCView doesn't do anything with the audio
// MediaStream specified to it so it's easier at the time of this
// writing to not render anything.

View File

@@ -64,7 +64,7 @@ export default class Video extends Component<IProps> {
*
* @inheritdoc
*/
override componentDidMount() {
componentDidMount() {
// RTCView currently does not support media events, so just fire
// onPlaying callback when <RTCView> is rendered.
const { onPlaying } = this.props;
@@ -78,7 +78,7 @@ export default class Video extends Component<IProps> {
* @inheritdoc
* @returns {ReactElement|null}
*/
override render() {
render() {
const { onPress, stream, zoomEnabled } = this.props;
if (stream) {

View File

@@ -18,7 +18,7 @@ class VideoTrack extends AbstractVideoTrack<IProps> {
* @override
* @returns {ReactElement}
*/
override render() {
render() {
return (
<View style = { styles.video } >
{ super.render() }

View File

@@ -197,7 +197,7 @@ class VideoTransform extends Component<IProps, IState> {
*
* @inheritdoc
*/
override componentDidUpdate(prevProps: IProps, prevState: IState) {
componentDidUpdate(prevProps: IProps, prevState: IState) {
if (prevProps.streamId !== this.props.streamId) {
this._storeTransform(prevProps.streamId, prevState.transform);
this._restoreTransform(this.props.streamId);
@@ -209,7 +209,7 @@ class VideoTransform extends Component<IProps, IState> {
*
* @inheritdoc
*/
override componentWillUnmount() {
componentWillUnmount() {
this._storeTransform(this.props.streamId, this.state.transform);
}
@@ -218,7 +218,7 @@ class VideoTransform extends Component<IProps, IState> {
*
* @inheritdoc
*/
override render() {
render() {
const { _aspectRatio, children, style } = this.props;
const isAspectRatioWide = _aspectRatio === ASPECT_RATIO_WIDE;

View File

@@ -37,7 +37,7 @@ export default class Audio extends AbstractAudio {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
return (
<audio
loop = { Boolean(this.props.loop) }
@@ -53,7 +53,7 @@ export default class Audio extends AbstractAudio {
*
* @returns {void}
*/
override stop() {
stop() {
if (this._ref) {
this._ref.pause();
this._ref.currentTime = 0;

View File

@@ -91,7 +91,7 @@ class AudioTrack extends Component<IProps> {
* @inheritdoc
* @returns {void}
*/
override componentDidMount() {
componentDidMount() {
this._attachTrack(this.props.audioTrack);
if (this._ref?.current) {
@@ -120,7 +120,7 @@ class AudioTrack extends Component<IProps> {
* @inheritdoc
* @returns {void}
*/
override componentWillUnmount() {
componentWillUnmount() {
this._detachTrack(this.props.audioTrack);
// @ts-ignore
@@ -135,7 +135,7 @@ class AudioTrack extends Component<IProps> {
* @returns {boolean} - False is always returned to blackbox this component
* from React.
*/
override shouldComponentUpdate(nextProps: IProps) {
shouldComponentUpdate(nextProps: IProps) {
const currentJitsiTrack = this.props.audioTrack?.jitsiTrack;
const nextJitsiTrack = nextProps.audioTrack?.jitsiTrack;
@@ -175,7 +175,7 @@ class AudioTrack extends Component<IProps> {
* @inheritdoc
* @returns {ReactElement}
*/
override render() {
render() {
const { autoPlay, id } = this.props;
return (

View File

@@ -220,7 +220,7 @@ class Video extends Component<IProps> {
* @inheritdoc
* @returns {void}
*/
override componentDidMount() {
componentDidMount() {
this._mounted = true;
if (this._videoElement) {
@@ -254,7 +254,7 @@ class Video extends Component<IProps> {
* @inheritdoc
* @returns {void}
*/
override componentWillUnmount() {
componentWillUnmount() {
this._mounted = false;
this._detachTrack(this.props.videoTrack);
}
@@ -268,7 +268,7 @@ class Video extends Component<IProps> {
* @returns {boolean} - False is always returned to blackbox this component
* from React.
*/
override shouldComponentUpdate(nextProps: IProps) {
shouldComponentUpdate(nextProps: IProps) {
const currentJitsiTrack = this.props.videoTrack?.jitsiTrack;
const nextJitsiTrack = nextProps.videoTrack?.jitsiTrack;
@@ -295,7 +295,7 @@ class Video extends Component<IProps> {
* @override
* @returns {ReactElement}
*/
override render() {
render() {
const {
autoPlay,
className,

View File

@@ -150,7 +150,7 @@ class VideoTrack extends AbstractVideoTrack<IProps> {
* @override
* @returns {ReactElement}
*/
override render() {
render() {
const {
_noAutoPlayVideo,
className,

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