Compare commits

..

1 Commits

Author SHA1 Message Date
titus.moldovan
d5916cdb3a e2ee stuff 2022-06-23 15:18:13 +03:00
576 changed files with 10498 additions and 15834 deletions

View File

@@ -20,6 +20,4 @@ jobs:
run: $(exit $(git status --porcelain --untracked-files=no | head -255 | wc -l)) || (echo "Dirty git tree"; git diff; exit 1)
- run: npm run lint
- run: for file in lang/*.json; do npx --yes jsonlint -q $file || exit 1; done
- env:
NODE_OPTIONS: '--max-old-space-size=4096'
run: make
- run: make

View File

@@ -4,7 +4,7 @@ DEPLOY_DIR = libs
LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet
OLM_DIR = node_modules/@matrix-org/olm
TF_WASM_DIR = node_modules/@tensorflow/tfjs-backend-wasm/dist/
RNNOISE_WASM_DIR = node_modules/@jitsi/rnnoise-wasm/dist
RNNOISE_WASM_DIR = node_modules/rnnoise-wasm/dist
TFLITE_WASM = react/features/stream-effects/virtual-background/vendor/tflite
MEET_MODELS_DIR = react/features/stream-effects/virtual-background/vendor/models
FACE_MODELS_DIR = node_modules/@vladmandic/human-models/models
@@ -49,8 +49,6 @@ deploy-appbundle:
$(BUILD_DIR)/analytics-ga.min.js.map \
$(BUILD_DIR)/face-landmarks-worker.min.js \
$(BUILD_DIR)/face-landmarks-worker.min.js.map \
$(BUILD_DIR)/noise-suppressor-worklet.min.js \
$(BUILD_DIR)/noise-suppressor-worklet.min.js.map \
$(DEPLOY_DIR)
cp \
$(BUILD_DIR)/close3.min.js \

View File

@@ -26,5 +26,5 @@ android.useAndroidX=true
android.enableJetifier=true
android.bundle.enableUncompressedNativeLibs=false
appVersion=99.0.0
sdkVersion=99.0.0
appVersion=22.3.0
sdkVersion=5.2.0

View File

@@ -51,10 +51,15 @@ dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
implementation "androidx.startup:startup-runtime:1.1.0"
// Only add these packages if we are NOT doing a LIBRE_BUILD
if (!rootProject.ext.libreBuild) {
if (rootProject.ext.libreBuild) {
implementation(project(':react-native-device-info')) {
exclude group: 'com.google.firebase'
exclude group: 'com.google.android.gms'
exclude group: 'com.android.installreferrer'
}
} else {
implementation project(':react-native-amplitude')
implementation project(':react-native-giphy')
implementation project(':react-native-device-info')
implementation(project(":react-native-google-signin")) {
exclude group: 'com.google.android.gms'
exclude group: 'androidx'
@@ -67,18 +72,15 @@ dependencies {
implementation project(':react-native-community_clipboard')
implementation project(':react-native-community_netinfo')
implementation project(':react-native-default-preference')
implementation(project(':react-native-device-info')) {
exclude group: 'com.google.firebase'
exclude group: 'com.google.android.gms'
exclude group: 'com.android.installreferrer'
}
implementation project(':react-native-gesture-handler')
implementation project(':react-native-get-random-values')
implementation project(':react-native-giphy')
implementation project(':react-native-immersive')
implementation project(':react-native-keep-awake')
implementation project(':react-native-masked-view_masked-view')
implementation project(':react-native-pager-view')
implementation project(':react-native-performance')
implementation project(':react-native-reanimated')
implementation project(':react-native-safe-area-context')
implementation project(':react-native-screens')
implementation project(':react-native-slider')

View File

@@ -32,7 +32,6 @@
android:name=".JitsiMeetActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
android:launchMode="singleTask"
android:theme="@style/JitsiMeetActivityStyle"
android:resizeableActivity="true"
android:supportsPictureInPicture="true"
android:windowSoftInputMode="adjustResize"/>

View File

@@ -0,0 +1,240 @@
/*
* Copyright @ 2018-present 8x8, Inc.
* Copyright @ 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.
*/
package org.jitsi.meet.sdk;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.ReadableMap;
import com.rnimmersive.RNImmersiveModule;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.WeakHashMap;
/**
* Base class for all views which are backed by a React Native view.
*/
public abstract class BaseReactView<ListenerT>
extends FrameLayout {
/**
* Background color used by {@code BaseReactView} and the React Native root
* view.
*/
protected static int BACKGROUND_COLOR = 0xFF111111;
/**
* The collection of all existing {@code BaseReactView}s. Used to find the
* {@code BaseReactView} when delivering events coming from
* {@link ExternalAPIModule}.
*/
static final Set<BaseReactView> views
= Collections.newSetFromMap(new WeakHashMap<BaseReactView, Boolean>());
/**
* Finds a {@code BaseReactView} which matches a specific external API
* scope.
*
* @param externalAPIScope - The external API scope associated with the
* {@code BaseReactView} to find.
* @return The {@code BaseReactView}, if any, associated with the specified
* {@code externalAPIScope}; otherwise, {@code null}.
*/
public static BaseReactView findViewByExternalAPIScope(
String externalAPIScope) {
synchronized (views) {
for (BaseReactView view : views) {
if (view.externalAPIScope.equals(externalAPIScope)) {
return view;
}
}
}
return null;
}
/**
* Gets all registered React views.
*
* @return An {@link ArrayList} containing all views currently held by React.
*/
static ArrayList<BaseReactView> getViews() {
return new ArrayList<>(views);
}
/**
* The unique identifier of this {@code BaseReactView} within the process
* for the purposes of {@link ExternalAPIModule}. The name scope was
* inspired by postis which we use on Web for the similar purposes of the
* iframe-based external API.
*/
protected String externalAPIScope;
/**
* The listener (e.g. {@link JitsiMeetViewListener}) instance for reporting
* events occurring in Jitsi Meet.
*/
@Deprecated
private ListenerT listener;
/**
* React Native root view.
*/
private ReactRootView reactRootView;
public BaseReactView(@NonNull Context context) {
super(context);
initialize((Activity)context);
}
public BaseReactView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize((Activity)context);
}
public BaseReactView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize((Activity)context);
}
/**
* Creates the {@code ReactRootView} for the given app name with the given
* props. Once created it's set as the view of this {@code FrameLayout}.
*
* @param appName - The name of the "app" (in React Native terms) to load.
* @param props - The React Component props to pass to the app.
*/
public void createReactRootView(String appName, @Nullable Bundle props) {
if (props == null) {
props = new Bundle();
}
props.putString("externalAPIScope", externalAPIScope);
if (reactRootView == null) {
reactRootView = new ReactRootView(getContext());
reactRootView.startReactApplication(
ReactInstanceManagerHolder.getReactInstanceManager(),
appName,
props);
reactRootView.setBackgroundColor(BACKGROUND_COLOR);
addView(reactRootView);
} else {
reactRootView.setAppProperties(props);
}
}
/**
* Releases the React resources (specifically the {@link ReactRootView})
* associated with this view.
*
* MUST be called when the {@link Activity} holding this view is destroyed,
* typically in the {@code onDestroy} method.
*/
public void dispose() {
if (reactRootView != null) {
removeView(reactRootView);
reactRootView.unmountReactApplication();
reactRootView = null;
}
}
/**
* Gets the listener set on this {@code BaseReactView}.
*
* @return The listener set on this {@code BaseReactView}.
*/
@Deprecated
public ListenerT getListener() {
return listener;
}
/**
* Abstract method called by {@link ExternalAPIModule} when an event is
* received for this view.
*
* @param name - The name of the event.
* @param data - The details of the event associated with/specific to the
* specified {@code name}.
*/
@Deprecated
protected abstract void onExternalAPIEvent(String name, ReadableMap data);
@Deprecated
protected void onExternalAPIEvent(
Map<String, Method> listenerMethods,
String name, ReadableMap data) {
ListenerT listener = getListener();
if (listener != null) {
ListenerUtils.runListenerMethod(
listener, listenerMethods, name, data);
}
}
/**
* Called when the window containing this view gains or loses focus.
*
* @param hasFocus If the window of this view now has focus, {@code true};
* otherwise, {@code false}.
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
if (hasFocus && immersive != null) {
immersive.emitImmersiveStateChangeEvent();
}
}
/**
* Sets a specific listener on this {@code BaseReactView}.
*
* @param listener The listener to set on this {@code BaseReactView}.
*/
@Deprecated
public void setListener(ListenerT listener) {
this.listener = listener;
}
private void initialize(Activity activity) {
setBackgroundColor(BACKGROUND_COLOR);
ReactInstanceManagerHolder.initReactInstanceManager(activity);
// Hook this BaseReactView into ExternalAPI.
externalAPIScope = UUID.randomUUID().toString();
synchronized (views) {
views.add(this);
}
}
}

View File

@@ -102,18 +102,31 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
/**
* Dispatches an event that occurred on the JavaScript side of the SDK to
* the native side.
* the specified {@link BaseReactView}'s listener.
*
* @param name The name of the event.
* @param data The details/specifics of the event to send determined
* by/associated with the specified {@code name}.
* @param scope
*/
@ReactMethod
public void sendEvent(String name, ReadableMap data) {
public void sendEvent(String name, ReadableMap data, String scope) {
// Keep track of the current ongoing conference.
OngoingConferenceTracker.getInstance().onExternalAPIEvent(name, data);
JitsiMeetLogger.d(TAG + " Sending event: " + name + " with data: " + data);
broadcastEmitter.sendBroadcast(name, data);
// The JavaScript App needs to provide uniquely identifying information
// to the native ExternalAPI module so that the latter may match the
// former to the native BaseReactView which hosts it.
BaseReactView view = BaseReactView.findViewByExternalAPIScope(scope);
if (view != null) {
JitsiMeetLogger.d(TAG + " Sending event: " + name + " with data: " + data);
try {
view.onExternalAPIEvent(name, data);
broadcastEmitter.sendBroadcast(name, data);
} catch (Exception e) {
JitsiMeetLogger.e(e, TAG + " onExternalAPIEvent: error sending event");
}
}
}
}

View File

@@ -167,9 +167,12 @@ public class JitsiMeetActivity extends AppCompatActivity
}
}
protected void leave() {
Intent hangupBroadcastIntent = BroadcastIntentHelper.buildHangUpIntent();
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(hangupBroadcastIntent);
public void leave() {
if (this.jitsiView != null) {
this.jitsiView .leave();
} else {
JitsiMeetLogger.w("Cannot leave, view is null");
}
}
private @Nullable

View File

@@ -0,0 +1,82 @@
/*
* Copyright @ 2019-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.
*/
package org.jitsi.meet.sdk;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Base {@link Fragment} for applications integrating Jitsi Meet at a higher level. It
* contains all the required wiring between the {@code JitsiMeetView} and
* the Fragment lifecycle methods already implemented.
*
* In this fragment we use a single {@code JitsiMeetView} instance. This
* instance gives us access to a view which displays the welcome page and the
* conference itself. All lifecycle methods associated with this Fragment are
* hooked to the React Native subsystem via proxy calls through the
* {@code JitsiMeetActivityDelegate} static methods.
*
* @deprecated use {@link JitsiMeetActivity} or directly {@link JitsiMeetView}
*/
@Deprecated
public class JitsiMeetFragment extends Fragment {
/**
* Instance of the {@link JitsiMeetView} which this activity will display.
*/
private JitsiMeetView view;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return this.view = new JitsiMeetView(getActivity());
}
public JitsiMeetView getJitsiView() {
return view;
}
@Override
public void onDestroy() {
super.onDestroy();
JitsiMeetActivityDelegate.onHostDestroy(getActivity());
}
@Override
public void onResume() {
super.onResume();
JitsiMeetActivityDelegate.onHostResume(getActivity());
}
@Override
public void onStop() {
super.onStop();
JitsiMeetActivityDelegate.onHostPause(getActivity());
}
}

View File

@@ -51,7 +51,7 @@ public class JitsiMeetOngoingConferenceService extends Service
private boolean isAudioMuted;
public static void launch(Context context, HashMap<String, Object> extraData) {
static void launch(Context context, HashMap<String, Object> extraData) {
OngoingNotification.createOngoingConferenceNotificationChannel();
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
@@ -80,7 +80,7 @@ public class JitsiMeetOngoingConferenceService extends Service
}
}
public static void abort(Context context) {
static void abort(Context context) {
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
context.stopService(intent);
}

View File

@@ -16,33 +16,37 @@
package org.jitsi.meet.sdk;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.facebook.react.ReactRootView;
import com.rnimmersive.RNImmersiveModule;
import com.facebook.react.bridge.ReadableMap;
import com.oney.WebRTCModule.WebRTCModule;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
import java.lang.reflect.Method;
import java.util.Map;
public class JitsiMeetView extends FrameLayout {
public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
implements OngoingConferenceTracker.OngoingConferenceListener {
/**
* Background color used by {@code BaseReactView} and the React Native root
* view.
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
* redux action types.
*/
private static final int BACKGROUND_COLOR = 0xFF111111;
private static final Map<String, Method> LISTENER_METHODS
= ListenerUtils.mapListenerMethods(JitsiMeetViewListener.class);
/**
* React Native root view.
* The URL of the current conference.
*/
private ReactRootView reactRootView;
// XXX Currently, one thread writes and one thread reads, so it should be
// fine to have this field volatile without additional synchronization.
private volatile String url;
/**
* Helper method to recursively merge 2 {@link Bundle} objects representing React Native props.
@@ -106,19 +110,10 @@ public class JitsiMeetView extends FrameLayout {
initialize(context);
}
/**
* Releases the React resources (specifically the {@link ReactRootView})
* associated with this view.
*
* MUST be called when the {@link Activity} holding this view is destroyed,
* typically in the {@code onDestroy} method.
*/
@Override
public void dispose() {
if (reactRootView != null) {
removeView(reactRootView);
reactRootView.unmountReactApplication();
reactRootView = null;
}
OngoingConferenceTracker.getInstance().removeListener(this);
super.dispose();
}
/**
@@ -131,17 +126,14 @@ public class JitsiMeetView extends FrameLayout {
* page.
*/
public void enterPictureInPicture() {
PictureInPictureModule pipModule
= ReactInstanceManagerHolder.getNativeModule(
PictureInPictureModule.class);
if (pipModule != null
&& pipModule.isPictureInPictureSupported()
&& !JitsiMeetActivityDelegate.arePermissionsBeingRequested()) {
try {
pipModule.enterPictureInPicture();
} catch (RuntimeException re) {
JitsiMeetLogger.e(re, "Failed to enter PiP mode");
}
try {
WebRTCModule pipModule
= ReactInstanceManagerHolder.getNativeModule(
WebRTCModule.class);
pipModule.addDecryptors();
}
catch (Exception e) {
int a = 1;
}
}
@@ -156,40 +148,10 @@ public class JitsiMeetView extends FrameLayout {
}
/**
* Creates the {@code ReactRootView} for the given app name with the given
* props. Once created it's set as the view of this {@code FrameLayout}.
*
* @param appName - The name of the "app" (in React Native terms) to load.
* @param props - The React Component props to pass to the app.
* Leaves the currently active conference.
*/
private void createReactRootView(String appName, @Nullable Bundle props) {
if (props == null) {
props = new Bundle();
}
if (reactRootView == null) {
reactRootView = new ReactRootView(getContext());
reactRootView.startReactApplication(
ReactInstanceManagerHolder.getReactInstanceManager(),
appName,
props);
reactRootView.setBackgroundColor(BACKGROUND_COLOR);
addView(reactRootView);
} else {
reactRootView.setAppProperties(props);
}
}
private void initialize(@NonNull Context context) {
// Check if the parent Activity implements JitsiMeetActivityInterface,
// otherwise things may go wrong.
if (!(context instanceof JitsiMeetActivityInterface)) {
throw new RuntimeException("Enclosing Activity must implement JitsiMeetActivityInterface");
}
setBackgroundColor(BACKGROUND_COLOR);
ReactInstanceManagerHolder.initReactInstanceManager((Activity) context);
public void leave() {
setProps(new Bundle());
}
/**
@@ -214,27 +176,46 @@ public class JitsiMeetView extends FrameLayout {
createReactRootView("App", props);
}
/**
* Handler for {@link OngoingConferenceTracker} events.
* @param conferenceUrl
*/
@Override
public void onCurrentConferenceChanged(String conferenceUrl) {
// This property was introduced in order to address
// an exception in the Picture-in-Picture functionality which arose
// because of delays related to bridging between JavaScript and Java. To
// reduce these delays do not wait for the call to be transferred to the
// UI thread.
this.url = conferenceUrl;
}
/**
* Handler for {@link ExternalAPIModule} events.
*
* @param name The name of the event.
* @param data The details/specifics of the event to send determined
* by/associated with the specified {@code name}.
*/
@Override
@Deprecated
protected void onExternalAPIEvent(String name, ReadableMap data) {
onExternalAPIEvent(LISTENER_METHODS, name, data);
}
@Override
protected void onDetachedFromWindow() {
dispose();
super.onDetachedFromWindow();
}
/**
* Called when the window containing this view gains or loses focus.
*
* @param hasFocus If the window of this view now has focus, {@code true};
* otherwise, {@code false}.
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
if (hasFocus && immersive != null) {
immersive.emitImmersiveStateChangeEvent();
private void initialize(@NonNull Context context) {
// Check if the parent Activity implements JitsiMeetActivityInterface,
// otherwise things may go wrong.
if (!(context instanceof JitsiMeetActivityInterface)) {
throw new RuntimeException("Enclosing Activity must implement JitsiMeetActivityInterface");
}
OngoingConferenceTracker.getInstance().addListener(this);
}
}

View File

@@ -0,0 +1,51 @@
/*
* 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.
*/
package org.jitsi.meet.sdk;
import java.util.Map;
/**
* Interface for listening to events coming from Jitsi Meet.
*/
@Deprecated
public interface JitsiMeetViewListener {
/**
* Called when a conference was joined.
*
* @param data Map with a "url" key with the conference URL.
*/
void onConferenceJoined(Map<String, Object> data);
/**
* Called when the active conference ends, be it because of user choice or
* because of a failure.
*
* @param data Map with an "error" key with the error and a "url" key with
* the conference URL. If the conference finished gracefully no `error`
* key will be present. The possible values for "error" are described here:
* https://github.com/jitsi/lib-jitsi-meet/blob/master/JitsiConnectionErrors.js
* https://github.com/jitsi/lib-jitsi-meet/blob/master/JitsiConferenceErrors.js
*/
void onConferenceTerminated(Map<String, Object> data);
/**
* Called before the conference is joined.
*
* @param data Map with a "url" key with the conference URL.
*/
void onConferenceWillJoin(Map<String, Object> data);
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright @ 2018-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.
*/
package org.jitsi.meet.sdk;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableMapKeySetIterator;
import com.facebook.react.bridge.UiThreadUtil;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Utility methods for helping with transforming {@link ExternalAPIModule}
* events into listener methods. Used with descendants of {@link BaseReactView}.
*/
@Deprecated
public final class ListenerUtils {
/**
* Extracts the methods defined in a listener and creates a mapping of this
* form: event name -> method.
*
* @param listener - The listener whose methods we want to slurp.
* @return A mapping with event names - methods.
*/
public static Map<String, Method> mapListenerMethods(Class listener) {
Map<String, Method> methods = new HashMap<>();
// Figure out the mapping between the listener methods
// and the events i.e. redux action types.
Pattern onPattern = Pattern.compile("^on[A-Z]+");
Pattern camelcasePattern = Pattern.compile("([a-z0-9]+)([A-Z0-9]+)");
for (Method method : listener.getDeclaredMethods()) {
// * The method must be public (because it is declared by an
// interface).
// * The method must be/return void.
if (!Modifier.isPublic(method.getModifiers())
|| !Void.TYPE.equals(method.getReturnType())) {
continue;
}
// * The method name must start with "on" followed by a
// capital/uppercase letter (in agreement with the camelcase
// coding style customary to Java in general and the projects of
// the Jitsi community in particular).
String name = method.getName();
if (!onPattern.matcher(name).find()) {
continue;
}
// * The method must accept/have exactly 1 parameter of a type
// assignable from HashMap.
Class<?>[] parameterTypes = method.getParameterTypes();
if (parameterTypes.length != 1
|| !parameterTypes[0].isAssignableFrom(HashMap.class)) {
continue;
}
// Convert the method name to an event name.
name
= camelcasePattern.matcher(name.substring(2))
.replaceAll("$1_$2")
.toUpperCase(Locale.ROOT);
methods.put(name, method);
}
return methods;
}
/**
* Executes the right listener method for the given event.
* NOTE: This function will run asynchronously on the UI thread.
*
* @param listener - The listener on which the method will be called.
* @param listenerMethods - Mapping with event names and the matching
* methods.
* @param eventName - Name of the event.
* @param eventData - Data associated with the event.
*/
public static void runListenerMethod(
final Object listener,
final Map<String, Method> listenerMethods,
final String eventName,
final ReadableMap eventData) {
// Make sure listener methods are invoked on the UI thread. It
// was requested by SDK consumers.
if (UiThreadUtil.isOnUiThread()) {
runListenerMethodOnUiThread(
listener, listenerMethods, eventName, eventData);
} else {
UiThreadUtil.runOnUiThread(new Runnable() {
@Override
public void run() {
runListenerMethodOnUiThread(
listener, listenerMethods, eventName, eventData);
}
});
}
}
/**
* Helper companion for {@link ListenerUtils#runListenerMethod} which runs
* in the UI thread.
*/
private static void runListenerMethodOnUiThread(
Object listener,
Map<String, Method> listenerMethods,
String eventName,
ReadableMap eventData) {
UiThreadUtil.assertOnUiThread();
Method method = listenerMethods.get(eventName);
if (method != null) {
try {
method.invoke(listener, toHashMap(eventData));
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}
/**
* Initializes a new {@code HashMap} instance with the key-value
* associations of a specific {@code ReadableMap}.
*
* @param readableMap the {@code ReadableMap} specifying the key-value
* associations with which the new {@code HashMap} instance is to be
* initialized.
* @return a new {@code HashMap} instance initialized with the key-value
* associations of the specified {@code readableMap}.
*/
private static HashMap<String, Object> toHashMap(ReadableMap readableMap) {
HashMap<String, Object> hashMap = new HashMap<>();
for (ReadableMapKeySetIterator i = readableMap.keySetIterator();
i.hasNextKey();) {
String key = i.nextKey();
hashMap.put(key, readableMap.getString(key));
}
return hashMap;
}
}

View File

@@ -28,6 +28,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import com.oney.WebRTCModule.WebRTCModule;
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
@@ -84,34 +85,10 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
*/
@TargetApi(Build.VERSION_CODES.O)
public void enterPictureInPicture() {
if (!isEnabled) {
return;
}
if (!isSupported) {
throw new IllegalStateException("Picture-in-Picture not supported");
}
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
throw new IllegalStateException("No current Activity!");
}
JitsiMeetLogger.i(TAG + " Entering Picture-in-Picture");
PictureInPictureParams.Builder builder
= new PictureInPictureParams.Builder()
.setAspectRatio(new Rational(1, 1));
// https://developer.android.com/reference/android/app/Activity.html#enterPictureInPictureMode(android.app.PictureInPictureParams)
//
// The system may disallow entering picture-in-picture in various cases,
// including when the activity is not visible, if the screen is locked
// or if the user has an activity pinned.
if (!currentActivity.enterPictureInPictureMode(builder.build())) {
throw new RuntimeException("Failed to enter Picture-in-Picture");
}
WebRTCModule pipModule
= ReactInstanceManagerHolder.getNativeModule(
WebRTCModule.class);
pipModule.addDecryptors();
}
/**
@@ -123,12 +100,10 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
*/
@ReactMethod
public void enterPictureInPicture(Promise promise) {
try {
enterPictureInPicture();
promise.resolve(null);
} catch (RuntimeException re) {
promise.reject(re);
}
WebRTCModule pipModule
= ReactInstanceManagerHolder.getNativeModule(
WebRTCModule.class);
pipModule.addDecryptors();
}
@ReactMethod

View File

@@ -35,6 +35,8 @@ import com.oney.WebRTCModule.RTCVideoViewManager;
import com.oney.WebRTCModule.WebRTCModule;
import org.devio.rn.splashscreen.SplashScreenModule;
import org.webrtc.Loggable;
import org.webrtc.Logging;
import org.webrtc.SoftwareVideoDecoderFactory;
import org.webrtc.SoftwareVideoEncoderFactory;
import org.webrtc.audio.AudioDeviceModule;
@@ -46,8 +48,6 @@ import java.util.Arrays;
import java.util.List;
class ReactInstanceManagerHolder {
private static final String TAG = ReactInstanceManagerHolder.class.getSimpleName();
/**
* FIXME (from linter): Do not place Android context classes in static
* fields (static reference to ReactInstanceManager which has field
@@ -59,6 +59,13 @@ class ReactInstanceManagerHolder {
*/
private static ReactInstanceManager reactInstanceManager;
private static Loggable webrtcLogger = new Loggable() {
@Override
public void onLogMessage(String message, Logging.Severity severity, String tag) {
Log.d(tag,message);
}
};
private static List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> nativeModules
= new ArrayList<>(Arrays.<NativeModule>asList(
@@ -90,6 +97,8 @@ class ReactInstanceManagerHolder {
options.setVideoDecoderFactory(new SoftwareVideoDecoderFactory());
options.setVideoEncoderFactory(new SoftwareVideoEncoderFactory());
options.setInjectableLogger(webrtcLogger);
options.setLoggingSeverity(Logging.Severity.LS_VERBOSE);
nativeModules.add(new WebRTCModule(reactContext, options));
@@ -112,11 +121,13 @@ class ReactInstanceManagerHolder {
new com.corbt.keepawake.KCKeepAwakePackage(),
new com.facebook.react.shell.MainReactPackage(),
new com.reactnativecommunity.clipboard.ClipboardPackage(),
new com.giphyreactnativesdk.GiphyReactNativeSdkPackage(),
new com.reactnativecommunity.netinfo.NetInfoPackage(),
new com.reactnativepagerview.PagerViewPackage(),
new com.oblador.performance.PerformancePackage(),
new com.reactnativecommunity.slider.ReactSliderPackage(),
new com.brentvatne.react.ReactVideoPackage(),
new com.swmansion.reanimated.ReanimatedPackage(),
new org.reactnative.maskedview.RNCMaskedViewPackage(),
new com.reactnativecommunity.webview.RNCWebViewPackage(),
new com.kevinresol.react_native_default_preference.RNDefaultPreferencePackage(),
@@ -146,17 +157,6 @@ class ReactInstanceManagerHolder {
packages.add((ReactPackage)constructor.newInstance());
} catch (Exception e) {
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
Log.d(TAG, "Not loading AmplitudeReactNativePackage");
}
// GiphyReactNativeSdkPackage
try {
Class<?> giphyPackageClass = Class.forName("com.giphyreactnativesdk.GiphyReactNativeSdkPackage");
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.
Log.d(TAG, "Not loading GiphyReactNativeSdkPackage");
}
// RNGoogleSignInPackage
@@ -166,7 +166,6 @@ class ReactInstanceManagerHolder {
packages.add((ReactPackage)constructor.newInstance());
} catch (Exception e) {
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
Log.d(TAG, "Not loading RNGoogleSignInPackage");
}
return packages;
@@ -252,7 +251,7 @@ class ReactInstanceManagerHolder {
return;
}
Log.d(TAG, "initializing RN with Application");
Log.d(ReactInstanceManagerHolder.class.getCanonicalName(), "initializing RN with Application");
reactInstanceManager
= ReactInstanceManager.builder()

View File

@@ -1,3 +0,0 @@
<resources>
<style name="JitsiMeetActivityStyle" parent="Theme.AppCompat.Light.NoActionBar"/>
</resources>

View File

@@ -37,6 +37,8 @@ include ':react-native-pager-view'
project(':react-native-pager-view').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-pager-view/android')
include ':react-native-performance'
project(':react-native-performance').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-performance/android')
include ':react-native-reanimated'
project(':react-native-reanimated').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-reanimated/android')
include ':react-native-safe-area-context'
project(':react-native-safe-area-context').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-safe-area-context/android')
include ':react-native-screens'

View File

@@ -137,7 +137,6 @@ import {
submitFeedback
} from './react/features/feedback';
import { maybeSetLobbyChatMessageListener } from './react/features/lobby/actions.any';
import { setNoiseSuppressionEnabled } from './react/features/noise-suppression/actions';
import {
isModerationNotificationDisplayed,
showNotification,
@@ -2018,11 +2017,6 @@ export default {
}
if (this._desktopAudioStream) {
// Noise suppression doesn't work with desktop audio because we can't chain
// track effects yet, disable it first.
// We need to to wait for the effect to clear first or it might interfere with the audio mixer.
await APP.store.dispatch(setNoiseSuppressionEnabled(false));
const localAudio = getLocalJitsiAudioTrack(APP.store.getState());
// If there is a localAudio stream, mix in the desktop audio stream captured by the screen sharing
@@ -2596,12 +2590,9 @@ export default {
APP.UI.addListener(
UIEvents.AUDIO_DEVICE_CHANGED,
async micDeviceId => {
micDeviceId => {
const audioWasMuted = this.isLocalAudioMuted();
// Disable noise suppression if it was enabled on the previous track.
await APP.store.dispatch(setNoiseSuppressionEnabled(false));
// When the 'default' mic needs to be selected, we need to
// pass the real device id to gUM instead of 'default' in order
// to get the correct MediaStreamTrack from chrome because of the
@@ -3079,7 +3070,7 @@ export default {
/**
* Leaves the room.
*
* @param {boolean} doDisconnect - Whether leaving the room should also terminate the connection.
* @param {boolean} doDisconnect - Wether leaving the room should also terminate the connection.
* @returns {Promise}
*/
async leaveRoom(doDisconnect = true) {
@@ -3103,12 +3094,34 @@ export default {
* @param email {string} the new email
*/
changeLocalEmail(email = '') {
const localParticipant = getLocalParticipant(APP.store.getState());
const formattedEmail = String(email).trim();
if (formattedEmail === localParticipant.email) {
return;
}
const localId = localParticipant.id;
APP.store.dispatch(participantUpdated({
// XXX Only the local participant is allowed to update without
// stating the JitsiConference instance (i.e. participant property
// `conference` for a remote participant) because the local
// participant is uniquely identified by the very fact that there is
// only one local participant.
id: localId,
local: true,
email: formattedEmail
}));
APP.store.dispatch(updateSettings({
email: formattedEmail
}));
APP.API.notifyEmailChanged(localId, {
email: formattedEmail
});
sendData(commands.EMAIL, formattedEmail);
},
@@ -3117,12 +3130,29 @@ export default {
* @param url {string} the new url
*/
changeLocalAvatarUrl(url = '') {
const { avatarURL, id } = getLocalParticipant(APP.store.getState());
const formattedUrl = String(url).trim();
if (formattedUrl === avatarURL) {
return;
}
APP.store.dispatch(participantUpdated({
// XXX Only the local participant is allowed to update without
// stating the JitsiConference instance (i.e. participant property
// `conference` for a remote participant) because the local
// participant is uniquely identified by the very fact that there is
// only one local participant.
id,
local: true,
avatarURL: formattedUrl
}));
APP.store.dispatch(updateSettings({
avatarURL: formattedUrl
}));
sendData(commands.AVATAR_URL, url);
},
@@ -3163,6 +3193,23 @@ export default {
*/
changeLocalDisplayName(nickname = '') {
const formattedNickname = getNormalizedDisplayName(nickname);
const { id, name } = getLocalParticipant(APP.store.getState());
if (formattedNickname === name) {
return;
}
APP.store.dispatch(participantUpdated({
// XXX Only the local participant is allowed to update without
// stating the JitsiConference instance (i.e. participant property
// `conference` for a remote participant) because the local
// participant is uniquely identified by the very fact that there is
// only one local participant.
id,
local: true,
name: formattedNickname
}));
APP.store.dispatch(updateSettings({
displayName: formattedNickname

304
config.js
View File

@@ -1,27 +1,11 @@
/* eslint-disable comma-dangle, no-unused-vars, no-var, prefer-template, vars-on-top */
/* eslint-disable no-unused-vars, no-var */
/*
* NOTE: If you add a new option please remember to document it here:
* https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-configuration
*/
var subdir = '<!--# echo var="subdir" default="" -->';
var subdomain = '<!--# echo var="subdomain" default="" -->';
if (subdomain) {
subdomain = subdomain.substr(0, subdomain.length - 1).split('.')
.join('_')
.toLowerCase() + '.';
}
// In case of no ssi provided by the webserver, use empty strings
if (subdir.startsWith('<!--')) {
subdir = '';
}
if (subdomain.startsWith('<!--')) {
subdomain = '';
}
var config = {
// Connection
//
@@ -40,14 +24,14 @@ var config = {
// focus: 'focus.jitsi-meet.example.com',
// XMPP MUC domain. FIXME: use XEP-0030 to discover it.
muc: 'conference.' + subdomain + 'jitsi-meet.example.com',
muc: 'conference.jitsi-meet.example.com'
},
// BOSH URL. FIXME: use XEP-0156 to discover it.
bosh: '//jitsi-meet.example.com/' + subdir + 'http-bind',
bosh: '//jitsi-meet.example.com/http-bind',
// Websocket URL
// websocket: 'wss://jitsi-meet.example.com/' + subdir + 'xmpp-websocket',
// websocket: 'wss://jitsi-meet.example.com/xmpp-websocket',
// The real JID of focus participant - can be overridden here
// Do not change username - FIXME: Make focus username configurable
@@ -68,18 +52,18 @@ var config = {
// enableThumbnailReordering: true,
// Enables XMPP WebSocket (as opposed to BOSH) for the given amount of users.
// mobileXmppWsThreshold: 10, // enable XMPP WebSockets on mobile for 10% of the users
// mobileXmppWsThreshold: 10 // enable XMPP WebSockets on mobile for 10% of the users
// P2P test mode disables automatic switching to P2P when there are 2
// participants in the conference.
// p2pTestMode: false,
// Enables the test specific features consumed by jitsi-meet-torture
// testMode: false,
// testMode: false
// Disables the auto-play behavior of *all* newly created video element.
// This is useful when the client runs on a host with limited resources.
// noAutoPlayVideo: false,
// noAutoPlayVideo: false
// Enable / disable 500 Kbps bitrate cap on desktop tracks. When enabled,
// simulcast is turned off for the desktop share. If presenter is turned
@@ -88,17 +72,17 @@ var config = {
// the probability for this to be enabled. This setting has been deprecated.
// desktopSharingFrameRate.max now determines whether simulcast will be enabled
// or disabled for the screenshare.
// capScreenshareBitrate: 1, // 0 to disable - deprecated.
// capScreenshareBitrate: 1 // 0 to disable - deprecated.
// Whether to use fake constraints (height: 99999, width: 99999) when calling getDisplayMedia on
// Chromium based browsers. This is intended as a workaround for
// https://bugs.chromium.org/p/chromium/issues/detail?id=1056311
// setScreenSharingResolutionConstraints: true,
// setScreenSharingResolutionConstraints: true
// Enable callstats only for a percentage of users.
// This takes a value between 0 and 100 which determines the probability for
// the callstats to be enabled.
// callStatsThreshold: 5, // enable callstats for 5% of the users.
// callStatsThreshold: 5 // enable callstats for 5% of the users.
},
// Feature Flags.
@@ -108,11 +92,7 @@ var config = {
// Enables sending multiple video streams, i.e., camera and desktop tracks can be shared in the conference
// separately as two different streams instead of one composite stream.
// sendMultipleVideoStreams: false,
// Signal that this client supports receiving multiple video streams. Without this flag jicofo will enable
// multi-stream backward compatibility.
receiveMultipleVideoStreams: true,
// sendMultipleVideoStreams: false
},
// Disables moderator indicators.
@@ -141,7 +121,7 @@ var config = {
// Can be either 'recording' - screensharing screenshots are taken
// only when the recording is also on,
// or 'always' - screensharing screenshots are always taken.
// mode: 'recording',
// mode: 'recording'
// }
// Disables ICE/UDP by filtering out local and remote UDP candidates in
@@ -163,7 +143,6 @@ var config = {
// Disable measuring of audio levels.
// disableAudioLevels: false,
// audioLevelsInterval: 200,
// Enabling this will run the lib-jitsi-meet no audio detection module which
@@ -199,7 +178,7 @@ var config = {
// Enabling it (with #params) will disable local audio output of remote
// participants and to enable it back a reload is needed.
// startSilent: false,
// startSilent: false
// Enables support for opus-red (redundancy for Opus).
// enableOpusRed: false,
@@ -208,7 +187,7 @@ var config = {
// Beware, by doing so, you are disabling echo cancellation, noise suppression and AGC.
// audioQuality: {
// stereo: false,
// opusMaxAverageBitrate: null, // Value to fit the 6000 to 510000 range.
// opusMaxAverageBitrate: null // Value to fit the 6000 to 510000 range.
// },
// Video
@@ -227,7 +206,7 @@ var config = {
// 'role', <- Moderators on top
// 'name', <- Alphabetically by name
// 'hasLeft', <- The ones that have left in the bottom
// ], <- the order of the array elements determines priority
// ] <- the order of the array elements determines priority
// How many participants while in the tile view mode, before the receiving video quality is reduced from HD to SD.
// Use -1 to disable.
@@ -243,9 +222,9 @@ var config = {
// height: {
// ideal: 720,
// max: 720,
// min: 240,
// },
// },
// min: 240
// }
// }
// },
// Enable / disable simulcast support.
@@ -280,7 +259,7 @@ var config = {
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
// desktopSharingFrameRate: {
// min: 5,
// max: 5,
// max: 5
// },
// This option has been deprecated since it is no longer supported as per the w3c spec.
@@ -292,107 +271,57 @@ var config = {
// Recording
// DEPRECATED. Use recordingService.enabled instead.
// Whether to enable file recording or not.
// fileRecordingsEnabled: false,
// Enable the dropbox integration.
// dropbox: {
// appKey: '<APP_KEY>', // Specify your app key here.
// appKey: '<APP_KEY>' // Specify your app key here.
// // A URL to redirect the user to, after authenticating
// // by default uses:
// // 'https://jitsi-meet.example.com/static/oauth.html'
// redirectURI:
// 'https://jitsi-meet.example.com/subfolder/static/oauth.html',
// 'https://jitsi-meet.example.com/subfolder/static/oauth.html'
// },
// recordingService: {
// // When integrations like dropbox are enabled only that will be shown,
// // by enabling fileRecordingsServiceEnabled, we show both the integrations
// // and the generic recording service (its configuration and storage type
// // depends on jibri configuration)
// enabled: false,
// // Whether to show the possibility to share file recording with other people
// // (e.g. meeting participants), based on the actual implementation
// // on the backend.
// sharingEnabled: false,
// // Hide the warning that says we only store the recording for 24 hours.
// hideStorageWarning: false,
// },
// DEPRECATED. Use recordingService.enabled instead.
// When integrations like dropbox are enabled only that will be shown,
// by enabling fileRecordingsServiceEnabled, we show both the integrations
// and the generic recording service (its configuration and storage type
// depends on jibri configuration)
// fileRecordingsServiceEnabled: false,
// DEPRECATED. Use recordingService.sharingEnabled instead.
// Whether to show the possibility to share file recording with other people
// (e.g. meeting participants), based on the actual implementation
// on the backend.
// fileRecordingsServiceSharingEnabled: false,
// Whether to enable live streaming or not.
// liveStreamingEnabled: false,
// Local recording configuration.
// localRecording: {
// // Whether to disable local recording or not.
// disable: false,
// // Whether to notify all participants when a participant is recording locally.
// notifyAllParticipants: false,
// // Whether to disable the self recording feature (only local participant streams).
// disableSelfRecording: false,
// notifyAllParticipants: false
// },
// Customize the Live Streaming dialog. Can be modified for a non-YouTube provider.
// liveStreaming: {
// // Whether to enable live streaming or not.
// enabled: false,
// // Terms link
// termsLink: 'https://www.youtube.com/t/terms',
// // Data privacy link
// dataPrivacyLink: 'https://policies.google.com/privacy',
// // RegExp string that validates the stream key input field
// validatorRegExpString: '^(?:[a-zA-Z0-9]{4}(?:-(?!$)|$)){4}',
// // Documentation reference for the live streaming feature.
// helpLink: 'https://jitsi.org/live'
// },
// DEPRECATED. Use liveStreaming.enabled instead.
// liveStreamingEnabled: false,
// DEPRECATED. Use transcription.enabled instead.
// Transcription (in interface_config,
// subtitles and buttons can be configured)
// transcribingEnabled: false,
// DEPRECATED. Use transcription.useAppLanguage instead.
// If true transcriber will use the application language.
// The application language is either explicitly set by participants in their settings or automatically
// detected based on the environment, e.g. if the app is opened in a chrome instance which is using french as its
// default language then transcriptions for that participant will be in french.
// Defaults to true.
// transcribeWithAppLanguage: true,
// DEPRECATED. Use transcription.preferredLanguage instead.
// Transcriber language. This settings will only work if "transcribeWithAppLanguage" is explicitly set to false.
// Available languages can be found in
// ./src/react/features/transcribing/transcriber-langs.json.
// preferredTranscribeLanguage: 'en-US',
// DEPRECATED. Use transcription.autoCaptionOnRecord instead.
// Enables automatic turning on captions when recording is started
// autoCaptionOnRecord: false,
// Transcription options.
// transcription: {
// // Whether the feature should be enabled or not.
// enabled: false,
// // If true transcriber will use the application language.
// // The application language is either explicitly set by participants in their settings or automatically
// // detected based on the environment, e.g. if the app is opened in a chrome instance which
// // is using french as its default language then transcriptions for that participant will be in french.
// // Defaults to true.
// useAppLanguage: true,
// // Transcriber language. This settings will only work if "useAppLanguage"
// // is explicitly set to false.
// // Available languages can be found in
// // ./src/react/features/transcribing/transcriber-langs.json.
// preferredLanguage: 'en-US',
// // Disable start transcription for all participants.
// disableStartForAll: false,
// // Enables automatic turning on captions when recording is started
// autoCaptionOnRecord: false,
// },
// Misc
// Default value for the channel "last N" attribute. -1 for unlimited.
@@ -425,7 +354,7 @@ var config = {
// 30: 15,
// 50: 10,
// 70: 5,
// 90: 2,
// 90: 2
// },
// Provides a way to translate the legacy bridge signaling messages, 'LastNChangedEvent',
@@ -454,7 +383,7 @@ var config = {
// // This will result in Safari not being able to decode video from endpoints sending VP9 video.
// // When set to false, the conference falls back to VP8 whenever there is an endpoint that doesn't support the
// // preferred codec and goes back to the preferred codec when that endpoint leaves.
// enforcePreferredCodec: false,
// // enforcePreferredCodec: false,
//
// // Provides a way to configure the maximum bitrates that will be enforced on the simulcast streams for
// // video tracks. The keys in the object represent the type of the stream (LD, SD or HD) and the values
@@ -465,18 +394,18 @@ var config = {
// H264: {
// low: 200000,
// standard: 500000,
// high: 1500000,
// high: 1500000
// },
// VP8 : {
// low: 200000,
// standard: 500000,
// high: 1500000,
// high: 1500000
// },
// VP9: {
// low: 100000,
// standard: 300000,
// high: 1200000,
// },
// high: 1200000
// }
// },
//
// // The options can be used to override default thresholds of video thumbnail heights corresponding to
@@ -491,19 +420,19 @@ var config = {
// // the high quality.
// minHeightForQualityLvl: {
// 360: 'standard',
// 720: 'high',
// 720: 'high'
// },
//
// // Provides a way to resize the desktop track to 720p (if it is greater than 720p) before creating a canvas
// // for the presenter mode (camera picture-in-picture mode with screenshare).
// resizeDesktopForPresenter: false,
// resizeDesktopForPresenter: false
// },
// Notification timeouts
// notificationTimeouts: {
// short: 2500,
// medium: 5000,
// long: 10000,
// long: 10000
// },
// // Options for the recording limit notification.
@@ -518,7 +447,7 @@ var config = {
// appName: 'Unlimited recordings APP',
//
// // The URL of the app with unlimited recordings.
// appURL: 'https://unlimited.recordings.app.com/',
// appURL: 'https://unlimited.recordings.app.com/'
// },
// Disables or enables RTX (RFC 4588) (defaults to false).
@@ -618,9 +547,12 @@ var config = {
// Hides the email section under profile settings.
// hideEmailInSettings: false,
// Whether or not some features are checked based on token.
// enableFeaturesBasedOnToken: false,
// When enabled the password used for locking a room is restricted to up to the number of digits specified
// default: roomPasswordNumberOfDigits: false,
// roomPasswordNumberOfDigits: 10,
// default: roomPasswordNumberOfDigits: false,
// Message to show the users. Example: 'The service will be down for
// maintenance at 01:00 AM GMT,
@@ -640,11 +572,11 @@ var config = {
// // either the jwt or the userInfo from the iframe api init object in order for this to have an effect.
// hideDisplayName: false,
// // List of buttons to hide from the extra join options dropdown.
// hideExtraJoinButtons: ['no-audio', 'by-phone'],
// hideExtraJoinButtons: ['no-audio', 'by-phone']
// },
// When 'true', the user cannot edit the display name.
// (Mainly useful when used in conjunction with the JWT so the JWT name becomes read only.)
// (Mainly useful when used in conjuction with the JWT so the JWT name becomes read only.)
// readOnlyName: false,
// If etherpad integration is enabled, setting this to true will
@@ -675,7 +607,7 @@ var config = {
// // Defaults to Gravatar.
// baseUrl: 'https://www.gravatar.com/avatar/',
// // True if Gravatar should be disabled.
// disabled: false,
// disabled: false
// },
// App name to be displayed in the invitation email subject, as an alternative to
@@ -698,7 +630,7 @@ var config = {
// 'chat',
// 'closedcaptions',
// 'desktop',
// 'dock-iframe',
// 'dock-iframe'
// 'download',
// 'embedmeeting',
// 'etherpad',
@@ -712,7 +644,6 @@ var config = {
// 'linktosalesforce',
// 'livestreaming',
// 'microphone',
// 'noisesuppression',
// 'participants-pane',
// 'profile',
// 'raisehand',
@@ -728,6 +659,7 @@ var config = {
// 'toggle-camera',
// 'undock-iframe',
// 'videoquality',
// '__end'
// ],
// Holds values related to toolbar visibility control.
@@ -742,7 +674,7 @@ var config = {
// // Whether toolbar should be always visible or should hide after x miliseconds.
// alwaysVisible: false,
// // Indicates whether the toolbar should still autohide when chat is open
// autoHideWhileChatIsOpen: false,
// autoHideWhileChatIsOpen: false
// },
// Toolbar buttons which have their click/tap event exposed through the API on
@@ -777,7 +709,6 @@ var config = {
// 'microphone',
// 'mute-everyone',
// 'mute-video-everyone',
// 'noisesuppression',
// 'participants-pane',
// 'profile',
// {
@@ -799,7 +730,8 @@ var config = {
// {
// key: 'add-passcode',
// preventExecution: false
// },
// }
// '__end'
// ],
// List of pre meeting screens buttons to hide. The values must be one or more of the 5 allowed buttons:
@@ -839,10 +771,10 @@ var config = {
// pbxID: "PBX Identifier. Example, walmart.",
// pbxExtensionID: "PBX Extension Identifier. Example, 5625.",
// fqExtensionID: "Fully qualified Extension Identifier. Example, +71 (US) +5625.",
// sessionID: "Session Identifier. Example, session-12-34",
// sessionID: "Session Identifier. Example, session-12-34"
// },
// collectLegacyStats: true, //enables the collection of legacy stats in chrome browser
// collectIP: true, //enables the collection localIP address
// collectIP: true //enables the collection localIP address
// },
// Enables sending participants' display names to callstats
@@ -868,7 +800,7 @@ var config = {
// faceCenteringThreshold: 10,
// // Milliseconds for processing a new image capture in order to detect face coordinates if they exist.
// captureInterval: 1000,
// captureInterval: 1000
// },
// Controls the percentage of automatic feedback shown to participants when callstats is enabled.
@@ -930,8 +862,8 @@ var config = {
stunServers: [
// { urls: 'stun:jitsi-meet.example.com:3478' },
{ urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' },
],
{ urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' }
]
},
analytics: {
@@ -939,14 +871,14 @@ var config = {
// disabled: false,
// The Google Analytics Tracking ID:
// googleAnalyticsTrackingId: 'your-tracking-id-UA-123456-1',
// googleAnalyticsTrackingId: 'your-tracking-id-UA-123456-1'
// Matomo configuration:
// matomoEndpoint: 'https://your-matomo-endpoint/',
// matomoSiteID: '42',
// The Amplitude APP Key:
// amplitudeAPPKey: '<APP_KEY>',
// amplitudeAPPKey: '<APP_KEY>'
// Obfuscates room name sent to analytics (amplitude, rtcstats)
// Default value is false.
@@ -962,15 +894,15 @@ var config = {
// In order to enable rtcstats one needs to provide a endpoint url.
// rtcstatsEndpoint: wss://rtcstats-server-pilot.jitsi.net/,
// The interval at which rtcstats will poll getStats, defaults to 10000ms.
// The interval at which rtcstats will poll getStats, defaults to 1000ms.
// If the value is set to 0 getStats won't be polled and the rtcstats client
// will only send data related to RTCPeerConnection events.
// rtcstatsPollInterval: 10000,
// rtcstatsPolIInterval: 1000,
// Array of script URLs to load as lib-jitsi-meet "analytics handlers".
// scriptURLs: [
// "libs/analytics-ga.min.js", // google-analytics
// "https://example.com/my-custom-analytics.js",
// "https://example.com/my-custom-analytics.js"
// ],
},
@@ -979,11 +911,11 @@ var config = {
// Information about the jitsi-meet instance we are connecting to, including
// the user region as seen by the server.
// deploymentInfo: {
// shard: "shard1",
// region: "europe",
// userRegion: "asia",
// },
deploymentInfo: {
// shard: "shard1",
// region: "europe",
// userRegion: "asia"
},
// Array<string> of disabled sounds.
// Possible values:
@@ -1032,19 +964,19 @@ var config = {
// chromeExtensionsInfo: [
// {
// id: 'kglhbbefdnlheedjiejgomgmfplipfeb',
// path: 'jitsi-logo-48x48.png',
// path: 'jitsi-logo-48x48.png'
// },
// // Edge extension info
// {
// id: 'eeecajlpbgjppibfledfihobcabccihn',
// path: 'jitsi-logo-48x48.png',
// },
// path: 'jitsi-logo-48x48.png'
// }
// ]
// },
// e2ee: {
// labels,
// externallyManagedKey: false,
// externallyManagedKey: false
// },
// Options related to end-to-end (participant to participant) ping.
@@ -1060,8 +992,8 @@ var config = {
//
// // The maximum number of e2e ping messages per second for the whole conference to aim for.
// // This is used to contol the pacing of messages in order to reduce the load on the backend.
// maxMessagesPerSecond: 250,
// },
// maxMessagesPerSecond: 250
// },
// If set, will attempt to use the provided video input device label when
// triggering a screenshare, instead of proceeding through the normal flow
@@ -1098,7 +1030,7 @@ var config = {
// userDocumentationURL: 'https://docs.example.com/video-meetings.html',
// // If specified a 'Download our apps' button will be displayed in the overflow menu with a link
// // to the specified URL for an app download page.
// downloadAppsUrl: 'https://docs.example.com/our-apps.html',
// downloadAppsUrl: 'https://docs.example.com/our-apps.html'
// },
// Options related to the remote participant menu.
@@ -1110,7 +1042,7 @@ var config = {
// // If set to true the 'Grant moderator' button will be disabled.
// disableGrantModerator: true,
// // If set to true the 'Send private message' button will be disabled.
// disablePrivateChat: true,
// disablePrivateChat: true
// },
// Endpoint that enables support for salesforce integration with in-meeting resource linking
@@ -1126,7 +1058,7 @@ var config = {
// disableRemoteMute: true,
// Enables support for lip-sync for this client (if the browser supports it).
// enableLipSync: false,
// enableLipSync: false
/**
External API url used to receive branding specific information.
@@ -1169,15 +1101,15 @@ var config = {
field02Hover: 'red',
action01: 'green',
action01Hover: 'lightgreen',
disabled01: 'beige',
action02Disabled: 'beige',
success02: 'cadetblue',
action02Hover: 'aliceblue',
action02Hover: 'aliceblue'
},
typography: {
labelRegular: {
fontSize: 25,
lineHeight: 30,
fontWeight: 500,
fontWeight: 500
}
}
}
@@ -1192,7 +1124,7 @@ var config = {
// // Hides the more actions button.
// hideMoreActionsButton: false,
// // Hides the mute all button.
// hideMuteAllButton: false,
// hideMuteAllButton: false
// },
// Options related to the breakout rooms feature.
@@ -1202,7 +1134,7 @@ var config = {
// // Hides the auto assign participants button.
// hideAutoAssignButton: false,
// // Hides the join breakout room button.
// hideJoinRoomButton: false,
// hideJoinRoomButton: false
// },
// When true the user cannot add more images to be used as virtual background.
@@ -1241,8 +1173,7 @@ var config = {
// 'transcribing',
// 'video-quality',
// 'insecure-room',
// 'highlight-moment',
// 'top-panel-toggle',
// 'highlight-moment'
// ]
// },
@@ -1269,8 +1200,9 @@ var config = {
// is not persisting the local storage inside the iframe.
// useHostPageLocalStorage: true,
// Etherpad ("shared document") integration.
// etherpad ("shared document") integration.
//
// If set, add a "Open shared document" link to the bottom right menu that
// will open an etherpad document.
// etherpad_base: 'https://your-etherpad-installati.on/p/',
@@ -1386,7 +1318,6 @@ var config = {
// 'notify.leftTwoMembers', // show when two participants left simultaneously
// 'notify.leftThreePlusMembers', // show when more than 2 participants left simultaneously
// 'notify.grantedTo', // shown when moderator rights were granted to a participant
// 'notify.hostAskedUnmute', // shown to participant when host asks them to unmute
// 'notify.invitedOneMember', // shown when 1 participant has been invited
// 'notify.invitedThreePlusMembers', // shown when 3+ participants have been invited
// 'notify.invitedTwoMembers', // shown when 2 participants have been invited
@@ -1407,7 +1338,7 @@ var config = {
// 'notify.raisedHand', // shown when a partcipant used raise hand,
// 'notify.startSilentTitle', // shown when user joined with no audio
// 'notify.unmute', // shown to moderator when user raises hand during AV moderation
// 'notify.videoMutedRemotelyTitle', // shown when user's video is muted by a remote party,
// 'notify.hostAskedUnmute', // shown to participant when host asks them to unmute
// 'prejoin.errorDialOut',
// 'prejoin.errorDialOutDisconnected',
// 'prejoin.errorDialOutFailed',
@@ -1420,7 +1351,7 @@ var config = {
// 'toolbar.noAudioSignalTitle', // shown when a broken mic is detected
// 'toolbar.noisyAudioInputTitle', // shown when noise is detected for the current microphone
// 'toolbar.talkWhileMutedPopup', // shown when user tries to speak while muted
// 'transcribing.failedToStart', // shown when transcribing fails to start
// 'transcribing.failedToStart' // shown when transcribing fails to start
// ],
// List of notifications to be disabled. Works in tandem with the above setting.
@@ -1436,21 +1367,14 @@ var config = {
// // Disables the stage filmstrip
// // (displaying multiple participants on stage besides the vertical filmstrip)
// disableStageFilmstrip: false,
// // Disables the top panel (only shown when a user is sharing their screen).
// disableTopPanel: false,
// // The minimum number of participants that must be in the call for
// // the top panel layout to be used.
// minParticipantCountForTopPanel: 50,
// disableStageFilmstrip: false
// },
// Tile view related config options.
// tileView: {
// // The optimal number of tiles that are going to be shown in tile view. Depending on the screen size it may
// // not be possible to show the exact number of participants specified here.
// numberOfVisibleTiles: 25,
// numberOfVisibleTiles: 25
// },
// Specifies whether the chat emoticons are disabled or not
@@ -1468,20 +1392,14 @@ var config = {
// // - all: all of the above. This is the default option
// displayMode: 'all',
// // How long the GIF should be displayed on the tile (in miliseconds).
// tileTime: 5000,
// tileTime: 5000
// },
// Logging
// logging: {
// // Default log level for the app and lib-jitsi-meet.
// defaultLogLevel: 'trace',
// // Option to disable LogCollector (which stores the logs on CallStats).
// //disableLogCollector: true,
// // Indivual loggers are customizable.
// loggers: {
// // The following are too verbose in their logging with the default level.
// 'modules/RTC/TraceablePeerConnection.js': 'info',
// 'modules/statistics/CallStats.js': 'info',
// 'modules/xmpp/strophe.util.js': 'log',
// },
// Allow all above example options to include a trailing comma and
// prevent fear when commenting out the last value.
makeJsonParserHappy: 'even if last key had a trailing comma'
// no configuration value should follow this line.
};
/* eslint-enable no-unused-vars, no-var */

View File

@@ -21,7 +21,8 @@ import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-mee
import { getCustomerDetails } from './react/features/jaas/actions.any';
import { isVpaasMeeting, getJaasJWT } from './react/features/jaas/functions';
import {
setPrejoinDisplayNameRequired
setPrejoinDisplayNameRequired,
setPrejoinPageVisibility
} from './react/features/prejoin/actions';
const logger = Logger.getLogger(__filename);
@@ -246,6 +247,7 @@ function requestAuth(roomName) {
resolve(connection);
};
APP.store.dispatch(setPrejoinPageVisibility(false));
APP.store.dispatch(
openDialog(LoginDialog, { onSuccess,
roomName })

View File

@@ -119,18 +119,63 @@
.chat-input-container {
padding: 0 16px 16px;
&.populated {
#chat-input {
.send-button {
background: #1B67EC;
cursor: pointer;
margin-left: 0.3rem;
@media (hover: hover) and (pointer: fine) {
&:hover {
background: #3D82FB;
}
}
&:active {
background: #0852D4;
}
path {
fill: #fff;
}
}
}
}
}
#chat-input {
border: 1px solid $chatInputSeparatorColor;
display: flex;
align-items: flex-end;
padding: 4px;
position: relative;
border-radius: 3px;
&:focus-within {
border: 1px solid #619CF4;
}
* {
background-color: transparent;
}
}
.chat-input {
flex: 1;
margin-right: 8px;
.send-button-container {
display: flex;
align-items: center;
}
.send-button {
display: flex;
align-items: center;
justify-content: center;
height: 40px;
width: 40px;
border-radius: 3px;
path {
fill: $chatInputSeparatorColor;
}
}
.smiley-button {
@@ -350,9 +395,7 @@
.smiley-input {
display: flex;
position: absolute;
top: 0;
left: 0;
position: relative;
}
.smileys-panel {
@@ -360,7 +403,7 @@
box-sizing: border-box;
background-color: rgba(0, 0, 0, .6) !important;
height: auto;
display: flex;
display: none;
overflow: hidden;
position: absolute;
width: calc(#{$sidebarWidth} - 32px);
@@ -375,6 +418,11 @@
*/
transition: max-height 0.3s;
&.show-smileys {
display: flex;
max-height: 500%;
}
#smileysContainer {
background-color: $chatBackgroundColor;
border-top: 1px solid $chatInputSeparatorColor;

View File

@@ -28,23 +28,32 @@
}
.poll-answer-container {
display: flex;
padding: 4px;
background: #3D3D3D;
border-radius: 3px;
margin-bottom: 8px;
@media (max-width: 580px) {
&> span {
padding: 8px 0;
}
&> span {
padding: 8px 0;
}
svg {
margin-top: 6px;
}
svg {
margin-top: 6px;
}
}
}
.poll-answer-option {
font-weight: 400;
display: block;
margin: 4px;
@media (max-width: 580px) {
font-size: 16px;
margin: 11px 8px
}
}
.poll-answer-field-list, .poll-answer-list, .poll-result-list {
list-style-type: none;
padding: 0;
@@ -75,11 +84,11 @@ ol.poll-result-list {
}
.poll-create-option-row {
display: flex;
display: 'flex';
margin-bottom: 4;
}
// Needed to override atlaskit default blue color
// Needeed to override atlaskit default blue color
.poll-create-container .jsYMHu {
background: #292929;
border-color: #808090;
@@ -282,10 +291,6 @@ ol.poll-result-list {
h1, strong ,span {
color: #fff;
}
button > span {
color: inherit;
}
}
.poll-create-label {
@@ -358,3 +363,82 @@ ol.poll-result-list {
.poll-answer-footer {
padding: 8px 0 0 0;
}
.poll-button {
align-items: center;
border: 0;
border-radius: 6px;
font-size: 14px;
font-weight: 600;
display: flex;
justify-content: center;
min-height: 40px;
width: 100%;
&:disabled {
cursor: initial;
}
@media (max-width: 580px) {
min-height: 48px;
}
}
.poll-button-primary {
background-color: #0056E0;
&:hover {
background-color: #246FE5;
}
&:active {
background-color: #0045B3;
}
&:focus {
background-color: #0045B3;
border: 3px solid #99BBF3;
}
&:disabled {
background-color: #00225A;
color: #858585;
}
}
.poll-button-secondary {
background-color: #3D3D3D;
&:hover {
background-color: #525252;
}
&:active {
background-color: #292929;
}
&:focus {
background-color: #292929;
border: 3px solid #858585;
}
&:disabled {
background-color: #141414;
color: #858585;
}
}
.poll-button-short {
max-width: 132px;
}
.poll-button-shortest {
max-width: 117px;
}
.poll-button-short,
.poll-button-shortest {
@media (max-width: 580px) {
min-width: 49%;
}
}

View File

@@ -19,10 +19,6 @@
font-size: 14px;
margin-left: 16px;
}
&.space-top {
margin-top: 10px;
}
}
.recording-header-line {

View File

@@ -12,7 +12,6 @@
&#autoHide.with-always-on {
overflow: hidden;
animation: hideSubject forwards .6s ease-out;
margin-left: 4px;
& > .subject-info-container {
justify-content: flex-start;

View File

@@ -68,12 +68,6 @@
}
.buttons {
margin-top: 16px;
display: flex;
align-items: center;
&>button:first-child {
margin-right: 8px;
}
}
}
}

View File

@@ -112,7 +112,7 @@
}
/**
* Remove unnecessary padding that is normally used to prevent horizontal
* Remove unnecssary padding that is normally used to prevent horizontal
* filmstrip from overlapping the left edge of the screen.
*/
#filmstripLocalVideo,

View File

@@ -38,6 +38,19 @@
color: #fff;
}
.info-password-input {
width: 100%;
background-color: #0E1624;
border-radius: 3px;
border: 2px solid #202B3D;
color: inherit;
padding-left: 0;
}
.info-password-input:focus ,
.info-password-input:active {
border: 2px solid #B8C7E0;
}
.info-password-local {
user-select: text;
}

View File

@@ -3,7 +3,9 @@
width: 100%;
height: 90%;
object-fit: contain;
margin-bottom: 10px;
}
input[type="checkbox"] + svg + span {
color: #9FB0CC;
}
.separator-line {

View File

@@ -13,14 +13,12 @@
}
.password {
align-items: flex-start;
align-items: center;
display: flex;
justify-content: flex-start;
justify-content: space-between;
margin-top: 15px;
flex-direction: column;
&-actions {
margin-top: 10px;
a {
cursor: pointer;
text-decoration: none;
@@ -28,8 +26,8 @@
color: #6FB1EA;
}
& > :first-child:not(:last-child) {
margin-right: 24px;
& > :first-child:not(:last-child) {
margin-right: 24px;
}
}
}

4
custom.d.ts vendored
View File

@@ -1,4 +0,0 @@
declare module '*.svg' {
const content: any;
export default content;
}

View File

@@ -50,15 +50,27 @@ case "$1" in
if [ -f "$PROSODY_HOST_CONFIG" ] ; then
# search for the token auth, if this is not enabled this is the
# first time we install tokens package and needs a config change
if ! egrep -q '^\s*authentication\s*=\s*"token" -- do not delete me' "$PROSODY_HOST_CONFIG"; then
if ! egrep -q '^\s*authentication\s*=\s*"token"' "$PROSODY_HOST_CONFIG"; then
# enable tokens in prosody host config
sed -i 's/--plugin_paths/plugin_paths/g' $PROSODY_HOST_CONFIG
sed -i 's/authentication = "jitsi-anonymous" -- do not delete me/authentication = "token" -- do not delete me/g' $PROSODY_HOST_CONFIG
sed -i 's/authentication = "anonymous"/authentication = "token"/g' $PROSODY_HOST_CONFIG
sed -i 's/ --allow_unencrypted_plain_auth/ allow_unencrypted_plain_auth/g' $PROSODY_HOST_CONFIG
sed -i "s/ --app_id=\"example_app_id\"/ app_id=\"$APP_ID\"/g" $PROSODY_HOST_CONFIG
sed -i "s/ --app_secret=\"example_app_secret\"/ app_secret=\"$APP_SECRET\"/g" $PROSODY_HOST_CONFIG
sed -i 's/ --modules_enabled = { "token_verification" }/ modules_enabled = { "token_verification" }/g' $PROSODY_HOST_CONFIG
sed -i '/^\s*--\s*"token_verification"/ s/--\s*//' $PROSODY_HOST_CONFIG
PR10_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-0.10' 2>/dev/null | awk '{print $3}' || true)"
PRTRUNK_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-trunk' 2>/dev/null | awk '{print $3}' || true)"
PR_VER_INSTALLED=$(dpkg-query -f='${Version}\n' --show prosody 2>/dev/null || true)
if [ "$PR10_INSTALL_CHECK" = "installed" ] \
|| [ "$PR10_INSTALL_CHECK" = "unpacked" ] \
|| [ "$PRTRUNK_INSTALL_CHECK" = "installed" ] \
|| [ "$PRTRUNK_INSTALL_CHECK" = "unpacked" ] \
|| dpkg --compare-versions "$PR_VER_INSTALLED" lt "0.11" ; then
sed -i 's/module:hook_global(/module:hook(/g' /usr/share/jitsi-meet/prosody-plugins/mod_auth_token.lua
fi
if [ -x "/etc/init.d/prosody" ]; then
invoke-rc.d prosody restart || true
fi

View File

@@ -37,7 +37,7 @@ case "$1" in
APP_SECRET=$RET
# Revert prosody config
sed -i 's/authentication = "token" -- do not delete me/authentication = "jitsi-anonymous" -- do not delete me/g' $PROSODY_HOST_CONFIG
sed -i 's/authentication = "token"/authentication = "anonymous"/g' $PROSODY_HOST_CONFIG
sed -i "s/ app_id=\"$APP_ID\"/ --app_id=\"example_app_id\"/g" $PROSODY_HOST_CONFIG
sed -i "s/ app_secret=\"$APP_SECRET\"/ --app_secret=\"example_app_secret\"/g" $PROSODY_HOST_CONFIG
sed -i '/^\s*"token_verification"/ s/"token_verification"/-- "token_verification"/' $PROSODY_HOST_CONFIG

View File

@@ -246,28 +246,6 @@ case "$1" in
echo ""
echo "----------------"
echo ""
echo ""
echo " ;dOocd;"
echo " .dNMM0dKO."
echo " lNMMMKd0K,"
echo " .xMMMMNxkNc"
echo " dMMMMMkxXc"
echo " cNMMMNl.."
echo " .kMMMX; Interested in adding telephony to your Jitsi meetings?"
echo " ;XMMMO'"
echo " lNMMWO' Sign up on https://jaas.8x8.vc/#/components"
echo " lNMMM0, and follow the guide in the dev console."
echo " lXMMMK:."
echo " ;KMMMNKd. 'oo,"
echo " 'xNMMMMXkkkkOKOl'"
echo " :0WMMMMMMNOkk0Kk,"
echo " .cdOWMMMMMWXOkOl"
echo " .;dKWMMMMMXc."
echo " .,:cll:'"
echo ""
echo ""
# and we're done with debconf
db_stop
;;

View File

@@ -1,4 +1,5 @@
interface_config.js /usr/share/jitsi-meet/
logging_config.js /usr/share/jitsi-meet/
*.html /usr/share/jitsi-meet/
*.ico /usr/share/jitsi-meet/
libs /usr/share/jitsi-meet/

View File

@@ -36,7 +36,8 @@ unlimited_jids = {
}
VirtualHost "jitmeet.example.com"
authentication = "jitsi-anonymous" -- do not delete me
-- enabled = false -- Remove this line to enable this host
authentication = "anonymous"
-- Properties below are modified by jitsi-meet-tokens package config
-- and authentication above is switched to "token"
--app_id="example_app_id"
@@ -90,6 +91,7 @@ Component "breakout.jitmeet.example.com" "muc"
modules_enabled = {
"muc_meeting_id";
"muc_domain_mapper";
--"token_verification";
"muc_rate_limit";
"polls";
}
@@ -144,7 +146,6 @@ VirtualHost "jigasi.meet.jitsi"
modules_enabled = {
"ping";
"bosh";
"muc_password_check";
}
authentication = "token"
app_id = "jitsi";

View File

@@ -1,9 +1,8 @@
server_names_hash_bucket_size 64;
types {
# nginx's default mime.types doesn't include a mapping for wasm or wav.
# nginx's default mime.types doesn't include a mapping for wasm
application/wasm wasm;
audio/wav wav;
}
upstream prosody {
zone upstreams 64K;
@@ -74,13 +73,6 @@ server {
alias /usr/share/jitsi-meet/libs/external_api.min.js;
}
location = /_api/room-info {
proxy_pass http://prosody/room-info?prefix=$prefix&$args;
proxy_http_version 1.1;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
}
# ensure all static content can always be found first
location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
{
@@ -164,14 +156,6 @@ server {
rewrite ^/(.*)$ /xmpp-websocket;
}
location ~ ^/([^/?&:'"]+)/_api/room-info {
set $subdomain "$1.";
set $subdir "$1/";
set $prefix "$1";
rewrite ^/(.*)$ /_api/room-info;
}
# Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
location ~ ^/([^/?&:'"]+)/(.*)$ {
set $subdomain "$1.";

View File

@@ -67,6 +67,7 @@
"utils.js",
"do_external_connect.js",
"interface_config.js",
"logging_config.js",
"lib-jitsi-meet.min.js",
"app.bundle.min.js",
"all.css"
@@ -184,6 +185,7 @@
<!--#include virtual="connection_optimization/connection_optimization.html" -->
<script src="libs/do_external_connect.min.js?v=1"></script>
<script><!--#include virtual="/interface_config.js" --></script>
<script><!--#include virtual="/logging_config.js" --></script>
<script src="libs/lib-jitsi-meet.min.js?v=139"></script>
<script src="libs/app.bundle.min.js?v=139"></script>
<!--#include virtual="title.html" -->

View File

@@ -90,6 +90,7 @@ var interfaceConfig = {
JITSI_WATERMARK_LINK: 'https://jitsi.org',
LANG_DETECTION: true, // Allow i18n to detect the system language
LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live', // Documentation reference for the live streaming feature.
LOCAL_THUMBNAIL_RATIO: 16 / 9, // 16:9
/**
@@ -143,7 +144,7 @@ var interfaceConfig = {
RECENT_LIST_ENABLED: true,
REMOTE_THUMBNAIL_RATIO: 1, // 1:1
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar', 'sounds', 'more' ],
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar', 'sounds' ],
/**
* Specify which sharing features should be displayed. If the value is not set
@@ -247,10 +248,6 @@ var interfaceConfig = {
// Moved to config.js as `toolbarConfig.initialTimeout`.
// INITIAL_TOOLBAR_TIMEOUT: 20000,
// Please use `liveStreaming.helpLink` from config.js
// Documentation reference for the live streaming feature.
// LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live',
// Moved to config.js as `toolbarConfig.alwaysVisible`.
// TOOLBAR_ALWAYS_VISIBLE: false,

View File

@@ -9,9 +9,9 @@ install! 'cocoapods', :deterministic_uuids => false
target 'JitsiMeet' do
project 'app/app.xcodeproj'
pod 'Firebase/Analytics', '~> 8.0'
pod 'Firebase/Crashlytics', '~> 8.0'
pod 'Firebase/DynamicLinks', '~> 8.0'
pod 'Firebase/Analytics', '~> 6.33.0'
pod 'Firebase/Crashlytics', '~> 6.33.0'
pod 'Firebase/DynamicLinks', '~> 6.33.0'
end
target 'JitsiMeetSDK' do
@@ -29,14 +29,6 @@ target 'JitsiMeetSDK' do
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
# We use auto linking, but some dependencies are excluded from the lite build
# (see react-native.config.js) so we add them here.
pod 'giphy-react-native-sdk', :path => '../node_modules/@giphy/react-native-sdk'
pod 'RNCalendarEvents', :path => '../node_modules/react-native-calendar-events'
pod 'RNGoogleSignin', :path => '../node_modules/@react-native-google-signin/google-signin'
pod 'RNWatch', :path => '../node_modules/react-native-watch-connectivity'
# Native pod dependencies
#
@@ -44,30 +36,6 @@ target 'JitsiMeetSDK' do
pod 'ObjectiveDropboxOfficial', '6.2.3'
end
target 'JitsiMeetSDKLite' do
project 'sdk/sdk.xcodeproj'
# This is a more lightweight target, which removes some functionality.
# Check the react-native.config.js for the list of excluded packages.
# React Native and its dependencies
#
config = use_native_modules!
use_react_native!(
:path => config["reactNativePath"],
:hermes_enabled => false,
:fabric_enabled => false,
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
# Native pod dependencies
#
pod 'CocoaLumberjack', '3.7.2'
end
post_install do |installer|
react_native_post_install(installer)
__apply_Xcode_12_5_M1_post_install_workaround(installer)

View File

@@ -21,60 +21,50 @@ PODS:
- React-Core (= 0.68.1)
- React-jsi (= 0.68.1)
- ReactCommon/turbomodule/core (= 0.68.1)
- Firebase/Analytics (8.15.0):
- Firebase/Analytics (6.33.0):
- Firebase/Core
- Firebase/Core (8.15.0):
- Firebase/Core (6.33.0):
- Firebase/CoreOnly
- FirebaseAnalytics (~> 8.15.0)
- Firebase/CoreOnly (8.15.0):
- FirebaseCore (= 8.15.0)
- Firebase/Crashlytics (8.15.0):
- FirebaseAnalytics (= 6.8.3)
- Firebase/CoreOnly (6.33.0):
- FirebaseCore (= 6.10.3)
- Firebase/Crashlytics (6.33.0):
- Firebase/CoreOnly
- FirebaseCrashlytics (~> 8.15.0)
- Firebase/DynamicLinks (8.15.0):
- FirebaseCrashlytics (~> 4.6.1)
- Firebase/DynamicLinks (6.33.0):
- Firebase/CoreOnly
- FirebaseDynamicLinks (~> 8.15.0)
- FirebaseAnalytics (8.15.0):
- FirebaseAnalytics/AdIdSupport (= 8.15.0)
- FirebaseCore (~> 8.0)
- FirebaseInstallations (~> 8.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (~> 2.30908.0)
- FirebaseAnalytics/AdIdSupport (8.15.0):
- FirebaseCore (~> 8.0)
- FirebaseInstallations (~> 8.0)
- GoogleAppMeasurement (= 8.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (~> 2.30908.0)
- FirebaseCore (8.15.0):
- FirebaseCoreDiagnostics (~> 8.0)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/Logger (~> 7.7)
- FirebaseCoreDiagnostics (8.15.0):
- GoogleDataTransport (~> 9.1)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/Logger (~> 7.7)
- nanopb (~> 2.30908.0)
- FirebaseCrashlytics (8.15.0):
- FirebaseCore (~> 8.0)
- FirebaseInstallations (~> 8.0)
- GoogleDataTransport (~> 9.1)
- GoogleUtilities/Environment (~> 7.7)
- nanopb (~> 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- FirebaseDynamicLinks (8.15.0):
- FirebaseCore (~> 8.0)
- FirebaseInstallations (8.15.0):
- FirebaseCore (~> 8.0)
- GoogleUtilities/Environment (~> 7.7)
- GoogleUtilities/UserDefaults (~> 7.7)
- PromisesObjC (< 3.0, >= 1.2)
- FirebaseDynamicLinks (~> 4.3.1)
- FirebaseAnalytics (6.8.3):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (~> 1.6)
- GoogleAppMeasurement (= 6.8.3)
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/MethodSwizzler (~> 6.7)
- GoogleUtilities/Network (~> 6.7)
- "GoogleUtilities/NSData+zlib (~> 6.7)"
- nanopb (~> 1.30906.0)
- FirebaseCore (6.10.3):
- FirebaseCoreDiagnostics (~> 1.6)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- FirebaseCoreDiagnostics (1.7.0):
- GoogleDataTransport (~> 7.4)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/Logger (~> 6.7)
- nanopb (~> 1.30906.0)
- FirebaseCrashlytics (4.6.2):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (~> 1.6)
- GoogleDataTransport (~> 7.2)
- nanopb (~> 1.30906.0)
- PromisesObjC (~> 1.2)
- FirebaseDynamicLinks (4.3.1):
- FirebaseCore (~> 6.10)
- FirebaseInstallations (1.7.0):
- FirebaseCore (~> 6.10)
- GoogleUtilities/Environment (~> 6.7)
- GoogleUtilities/UserDefaults (~> 6.7)
- PromisesObjC (~> 1.2)
- fmt (6.2.1)
- Giphy (2.1.20):
- libwebp
@@ -82,52 +72,36 @@ PODS:
- Giphy (= 2.1.20)
- React-Core
- glog (0.3.5)
- GoogleAppMeasurement (8.15.0):
- GoogleAppMeasurement/AdIdSupport (= 8.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (~> 2.30908.0)
- GoogleAppMeasurement/AdIdSupport (8.15.0):
- GoogleAppMeasurement/WithoutAdIdSupport (= 8.15.0)
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (~> 2.30908.0)
- GoogleAppMeasurement/WithoutAdIdSupport (8.15.0):
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
- GoogleUtilities/MethodSwizzler (~> 7.7)
- GoogleUtilities/Network (~> 7.7)
- "GoogleUtilities/NSData+zlib (~> 7.7)"
- nanopb (~> 2.30908.0)
- GoogleDataTransport (9.1.4):
- GoogleUtilities/Environment (~> 7.7)
- nanopb (< 2.30910.0, >= 2.30908.0)
- PromisesObjC (< 3.0, >= 1.2)
- GoogleAppMeasurement (6.8.3):
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
- GoogleUtilities/MethodSwizzler (~> 6.7)
- GoogleUtilities/Network (~> 6.7)
- "GoogleUtilities/NSData+zlib (~> 6.7)"
- nanopb (~> 1.30906.0)
- GoogleDataTransport (7.5.1):
- nanopb (~> 1.30906.0)
- GoogleSignIn (6.0.2):
- AppAuth (~> 1.4)
- GTMAppAuth (~> 1.0)
- GTMSessionFetcher/Core (~> 1.1)
- GoogleUtilities/AppDelegateSwizzler (7.7.0):
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/Logger
- GoogleUtilities/Network
- GoogleUtilities/Environment (7.7.0):
- PromisesObjC (< 3.0, >= 1.2)
- GoogleUtilities/Logger (7.7.0):
- GoogleUtilities/Environment (6.7.2):
- PromisesObjC (~> 1.2)
- GoogleUtilities/Logger (6.7.2):
- GoogleUtilities/Environment
- GoogleUtilities/MethodSwizzler (7.7.0):
- GoogleUtilities/MethodSwizzler (6.7.2):
- GoogleUtilities/Logger
- GoogleUtilities/Network (7.7.0):
- GoogleUtilities/Network (6.7.2):
- GoogleUtilities/Logger
- "GoogleUtilities/NSData+zlib"
- GoogleUtilities/Reachability
- "GoogleUtilities/NSData+zlib (7.7.0)"
- GoogleUtilities/Reachability (7.7.0):
- "GoogleUtilities/NSData+zlib (6.7.2)"
- GoogleUtilities/Reachability (6.7.2):
- GoogleUtilities/Logger
- GoogleUtilities/UserDefaults (7.7.0):
- GoogleUtilities/UserDefaults (6.7.2):
- GoogleUtilities/Logger
- GTMAppAuth (1.2.2):
- AppAuth/Core (~> 1.4)
@@ -142,13 +116,13 @@ PODS:
- libwebp/mux (1.2.1):
- libwebp/demux
- libwebp/webp (1.2.1)
- nanopb (2.30908.0):
- nanopb/decode (= 2.30908.0)
- nanopb/encode (= 2.30908.0)
- nanopb/decode (2.30908.0)
- nanopb/encode (2.30908.0)
- nanopb (1.30906.0):
- nanopb/decode (= 1.30906.0)
- nanopb/encode (= 1.30906.0)
- nanopb/decode (1.30906.0)
- nanopb/encode (1.30906.0)
- ObjectiveDropboxOfficial (6.2.3)
- PromisesObjC (2.1.1)
- PromisesObjC (1.2.12)
- RCT-Folly (2021.06.28.00-v2):
- boost
- DoubleConversion
@@ -465,7 +439,9 @@ PODS:
- RNGoogleSignin (7.0.4):
- GoogleSignIn (~> 6.0.0)
- React-Core
- RNScreens (3.13.1):
- RNReanimated (1.13.4):
- React-Core
- RNScreens (3.10.1):
- React-Core
- React-RCTImage
- RNSound (0.11.1):
@@ -473,9 +449,9 @@ PODS:
- RNSound/Core (= 0.11.1)
- RNSound/Core (0.11.1):
- React-Core
- RNSVG (12.4.3):
- React-Core
- RNWatch (1.0.11):
- RNSVG (12.1.0):
- React
- RNWatch (1.0.4):
- React
- Yoga (1.14.0)
@@ -486,9 +462,9 @@ DEPENDENCIES:
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
- Firebase/Analytics (~> 8.0)
- Firebase/Crashlytics (~> 8.0)
- Firebase/DynamicLinks (~> 8.0)
- Firebase/Analytics (~> 6.33.0)
- Firebase/Crashlytics (~> 6.33.0)
- Firebase/DynamicLinks (~> 6.33.0)
- "giphy-react-native-sdk (from `../node_modules/@giphy/react-native-sdk`)"
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- ObjectiveDropboxOfficial (= 6.2.3)
@@ -539,6 +515,7 @@ DEPENDENCIES:
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- "RNGoogleSignin (from `../node_modules/@react-native-google-signin/google-signin`)"
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNSound (from `../node_modules/react-native-sound`)
- RNSVG (from `../node_modules/react-native-svg`)
@@ -675,6 +652,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-gesture-handler"
RNGoogleSignin:
:path: "../node_modules/@react-native-google-signin/google-signin"
RNReanimated:
:path: "../node_modules/react-native-reanimated"
RNScreens:
:path: "../node_modules/react-native-screens"
RNSound:
@@ -695,27 +674,27 @@ SPEC CHECKSUMS:
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
FBLazyVector: 2c76493a346ef8cacf1f442926a39f805fffec1f
FBReactNativeSpec: 371350f24afa87b6aba606972ec959dcd4a95c9a
Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
FirebaseAnalytics: 7761cbadb00a717d8d0939363eb46041526474fa
FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1
FirebaseCoreDiagnostics: 92e07a649aeb66352b319d43bdd2ee3942af84cb
FirebaseCrashlytics: feb07e4e9187be3c23c6a846cce4824e5ce2dd0b
FirebaseDynamicLinks: 1dc816ef789c5adac6fede0b46d11478175c70e4
FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
FirebaseCrashlytics: 1a747c9cc084a24dc6d9511c991db1cd078154eb
FirebaseDynamicLinks: 6eac37d86910382eafb6315d952cc44c9e176094
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
Giphy: b6d5087521d251bb8c99cdc0eb07bbdf86d142d5
giphy-react-native-sdk: 7abccf2b52123a0f30ce99da895ab6288023680c
glog: 476ee3e89abb49e07f822b48323c51c57124b572
GoogleAppMeasurement: 4c19f031220c72464d460c9daa1fb5d1acce958e
GoogleDataTransport: 5fffe35792f8b96ec8d6775f5eccd83c998d5a3b
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
GoogleSignIn: fd381840dbe7c1137aa6dc30849a5c3e070c034a
GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89
GTMSessionFetcher: 43748f93435c2aa068b1cbe39655aaf600652e91
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
ObjectiveDropboxOfficial: fe206ce8c0bc49976c249d472db7fdbc53ebbd53
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
RCTRequired: 00581111c53531e39e3c6346ef0d2c0cf52a5a37
RCTTypeSafety: 07e03ee7800e7dd65cba8e52ad0c2edb06c96604
@@ -761,12 +740,13 @@ SPEC CHECKSUMS:
RNDeviceInfo: 0400a6d0c94186d1120c3cbd97b23abc022187a9
RNGestureHandler: e5c7cab5f214503dcefd6b2b0cefb050e1f51c4a
RNGoogleSignin: c4381751eefd73c552b923ba347a9bfc6f18771c
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
RNReanimated: c1b56d030d1616239861534d9adb531f8cffab68
RNScreens: 522705f2e5c9d27efb17f24aceb2bf8335bc7b8e
RNSound: 27e8268bdb0a1f191f219a33267f7e0445e8d62f
RNSVG: f3b60aeeaa81960e2e0536c3a9eef50b667ef3a9
RNWatch: dae6c858a2051dbdcfb00b9a86cf4d90400263b4
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
RNWatch: 99637948ec9b5c9ec5a41920642594ad5ba07e80
Yoga: 17cd9a50243093b547c1e539c749928dd68152da
PODFILE CHECKSUM: a437875b597d999a137c671b1da54153fe31d23f
PODFILE CHECKSUM: bef1335067eaa4e8c558b1248f8ab3948de855bc
COCOAPODS: 1.11.3

View File

@@ -8,11 +8,11 @@
<string>applinks:beta.meet.jit.si</string>
<string>applinks:meet.jit.si</string>
</array>
<key>com.apple.developer.siri</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>group.org.jitsi.meet.appgroup</string>
</array>
<key>com.apple.developer.siri</key>
<true/>
</dict>
</plist>

View File

@@ -369,7 +369,6 @@
DEF4813D224925A2002AD03A /* Copy Google Plist file */,
DE11877A21EE09640078D059 /* Setup Google reverse URL handler */,
DE4F6D6E22005C0400DE699E /* Setup Dropbox */,
4E81688528A408E600F8FA9E /* Update App Entitlements */,
0BEA5C491F7B8F73000D0AB4 /* Embed Watch Content */,
4EC49B9025BED71300E76218 /* Embed App Extensions */,
);
@@ -523,24 +522,6 @@
shellPath = /bin/sh;
shellScript = "../scripts/run-packager.sh\n";
};
4E81688528A408E600F8FA9E /* Update App Entitlements */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Update App Entitlements";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if test \"$PRODUCT_BUNDLE_IDENTIFIER\" = \"com.atlassian.JitsiMeet.ios\"; then\n ENTITLEMENTS_PLIST=\"$PROJECT_DIR/app.entitlements\"\n \n /usr/libexec/PlistBuddy -c \"Add :com.apple.developer.avfoundation.multitasking-camera-access bool 1\" $ENTITLEMENTS_PLIST\nfi\n";
};
69BC5020DBE393B56BD76636 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<string>22.3.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSExtension</key>

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<string>22.3.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleURLTypes</key>

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<string>22.3.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>UISupportedInterfaceOrientations</key>

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>XPC!</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<string>22.3.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>CLKComplicationPrincipalClass</key>

View File

@@ -1,75 +0,0 @@
#!/bin/bash
set -e -u
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
PROJECT_REPO=$(realpath ${THIS_DIR}/../..)
RELEASE_REPO=$(realpath ${THIS_DIR}/../../../jitsi-meet-ios-sdk-releases)
DEFAULT_SDK_VERSION=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" ${THIS_DIR}/../sdk/src/Lite-Info.plist)
SDK_VERSION=${OVERRIDE_SDK_VERSION:-${DEFAULT_SDK_VERSION}}
DO_GIT_TAG=${GIT_TAG:-0}
echo "Releasing Jitsi Meet SDK Lite ${SDK_VERSION}"
pushd ${RELEASE_REPO}
# Generate podspec file
cat JitsiMeetSDKLite.podspec.tpl | sed -e s/VERSION/${SDK_VERSION}/g > JitsiMeetSDKLite.podspec
# Cleanup
rm -rf lite/Frameworks/*
popd
# Build the SDK
pushd ${PROJECT_REPO}
rm -rf ios/sdk/out
xcodebuild clean \
-workspace ios/jitsi-meet.xcworkspace \
-scheme JitsiMeetSDKLite
xcodebuild archive \
-workspace ios/jitsi-meet.xcworkspace \
-scheme JitsiMeetSDKLite \
-configuration Release \
-sdk iphonesimulator \
-destination='generic/platform=iOS Simulator' \
-archivePath ios/sdk/out/ios-simulator \
ENABLE_BITCODE=NO \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild archive \
-workspace ios/jitsi-meet.xcworkspace \
-scheme JitsiMeetSDKLite \
-configuration Release \
-sdk iphoneos \
-destination='generic/platform=iOS' \
-archivePath ios/sdk/out/ios-device \
ENABLE_BITCODE=NO \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild -create-xcframework \
-framework ios/sdk/out/ios-device.xcarchive/Products/Library/Frameworks/JitsiMeetSDK.framework \
-framework ios/sdk/out/ios-simulator.xcarchive/Products/Library/Frameworks/JitsiMeetSDK.framework \
-output ios/sdk/out/JitsiMeetSDK.xcframework
if [[ $DO_GIT_TAG == 1 ]]; then
git tag ios-sdk-lite-${SDK_VERSION}
fi
popd
pushd ${RELEASE_REPO}
# Put the new files in the repo
cp -a ${PROJECT_REPO}/ios/sdk/out/JitsiMeetSDK.xcframework lite/Frameworks/
# Add all files to git
if [[ $DO_GIT_TAG == 1 ]]; then
git add -A .
git commit -m "${SDK_VERSION} lite"
git tag "lite-${SDK_VERSION}"
fi
popd
echo "Finished! Don't forget to push the tags and releases repo artifacts."
echo "The new pod can be pushed to CocoaPods by doing: pod trunk push JitsiMeetSDKLite.podspec"

View File

@@ -22,19 +22,11 @@
0BCA49601EC4B6C600B793EE /* POSIX.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BCA495D1EC4B6C600B793EE /* POSIX.m */; };
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BCA495E1EC4B6C600B793EE /* Proximity.m */; };
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; };
3453F4A32680898C4A40E821 /* libPods-JitsiMeetSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 927ED7DF018DE5E12C4C3404 /* libPods-JitsiMeetSDK.a */; };
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */; };
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */; };
4EBA6E61286072E300B31882 /* JitsiMeetViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */; };
4EBA6E62286072E300B31882 /* JitsiMeetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */; };
4EBA6E652860B1E800B31882 /* JitsiMeetRenderingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */; };
4EBA6E662860B1E800B31882 /* JitsiMeetRenderingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */; };
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */; };
4EEC9630286C73A2008705FA /* JitsiMeetView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */; };
4EEC9631286C73A2008705FA /* JitsiMeetView+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */; };
6F08DF7D4458EE3CF3F36F6D /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
9A8EE79C77C17743BB66E8BD /* libPods-JitsiMeetSDKLite.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B46497DE9A95BDF5E312AF48 /* libPods-JitsiMeetSDKLite.a */; };
6F08DF7D4458EE3CF3F36F6D /* libPods-JitsiMeetSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4376CA6886DE68FD7A4294B /* libPods-JitsiMeetSDK.a */; };
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */ = {isa = PBXBuildFile; fileRef = A4A934E8212F3ADB001E9388 /* Dropbox.m */; };
C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; };
C6245F5E2053091D0040BE68 /* image-resize@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5C2053091D0040BE68 /* image-resize@3x.png */; };
@@ -56,58 +48,6 @@
DE81A2D92316AC7600AE1940 /* LogBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = DE81A2D72316AC7600AE1940 /* LogBridge.m */; };
DE81A2DE2317ED5400AE1940 /* JitsiMeetBaseLogHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = DE81A2DC2317ED5400AE1940 /* JitsiMeetBaseLogHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE81A2DF2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = DE81A2DD2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m */; };
DE9A0130289A9A9A00E41CBB /* JitsiMeetUserInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = DE762DB322AFDE76000DEBD6 /* JitsiMeetUserInfo.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A0131289A9A9A00E41CBB /* JitsiMeetView.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A0132289A9A9A00E41CBB /* RCTBridgeWrapper.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B93EF7C1EC9DDCD0030D24D /* RCTBridgeWrapper.h */; };
DE9A0133289A9A9A00E41CBB /* JitsiMeetBaseLogHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = DE81A2DC2317ED5400AE1940 /* JitsiMeetBaseLogHandler.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A0134289A9A9A00E41CBB /* JitsiMeetSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = DEA9F283258A5D9900D4CD74 /* JitsiMeetSDK.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A0135289A9A9A00E41CBB /* ScheenshareEventEmiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */; };
DE9A0136289A9A9A00E41CBB /* JitsiMeetBaseLogHandler+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */; };
DE9A0137289A9A9A00E41CBB /* JitsiMeetRenderingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */; };
DE9A0138289A9A9A00E41CBB /* JitsiMeetViewDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 0B412F1B1EDEC80100B1A0A6 /* JitsiMeetViewDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A0139289A9A9A00E41CBB /* JitsiAudioSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A013A289A9A9A00E41CBB /* JitsiMeetView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */; };
DE9A013B289A9A9A00E41CBB /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A013C289A9A9A00E41CBB /* JitsiMeetLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = DE81A2D22316AC4D00AE1940 /* JitsiMeetLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A013D289A9A9A00E41CBB /* LogUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = DE65AAC92317FFCD00290BEC /* LogUtils.h */; };
DE9A013E289A9A9A00E41CBB /* JitsiMeetViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */; };
DE9A013F289A9A9A00E41CBB /* JitsiMeetConferenceOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = DEAD3224220C497000E93636 /* JitsiMeetConferenceOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A0140289A9A9A00E41CBB /* ExternalAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */; };
DE9A0141289A9A9A00E41CBB /* InfoPlistUtil.h in Headers */ = {isa = PBXBuildFile; fileRef = C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */; settings = {ATTRIBUTES = (Public, ); }; };
DE9A0143289A9A9A00E41CBB /* CallKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BB9AD7A1F5EC8F4001C08DB /* CallKit.m */; };
DE9A0144289A9A9A00E41CBB /* JitsiMeetBaseLogHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = DE81A2DD2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m */; };
DE9A0145289A9A9A00E41CBB /* JitsiMeetRenderingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */; };
DE9A0146289A9A9A00E41CBB /* JitsiAudioSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */; };
DE9A0147289A9A9A00E41CBB /* AppInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BB9AD7C1F60356D001C08DB /* AppInfo.m */; };
DE9A0148289A9A9A00E41CBB /* LogBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = DE81A2D72316AC7600AE1940 /* LogBridge.m */; };
DE9A0149289A9A9A00E41CBB /* RNRootView.m in Sources */ = {isa = PBXBuildFile; fileRef = DEAFA778229EAD520033A7FA /* RNRootView.m */; };
DE9A014A289A9A9A00E41CBB /* JitsiMeetUserInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = DE762DB522AFDE8D000DEBD6 /* JitsiMeetUserInfo.m */; };
DE9A014B289A9A9A00E41CBB /* JitsiMeetConferenceOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = DEAD3225220C497000E93636 /* JitsiMeetConferenceOptions.m */; };
DE9A014C289A9A9A00E41CBB /* RCTBridgeWrapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B93EF7D1EC9DDCD0030D24D /* RCTBridgeWrapper.m */; };
DE9A014D289A9A9A00E41CBB /* ExternalAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */; };
DE9A014E289A9A9A00E41CBB /* POSIX.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BCA495D1EC4B6C600B793EE /* POSIX.m */; };
DE9A014F289A9A9A00E41CBB /* InfoPlistUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */; };
DE9A0150289A9A9A00E41CBB /* PiPViewCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */; };
DE9A0151289A9A9A00E41CBB /* LocaleDetector.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */; };
DE9A0152289A9A9A00E41CBB /* AudioMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BCA495C1EC4B6C600B793EE /* AudioMode.m */; };
DE9A0153289A9A9A00E41CBB /* Proximity.m in Sources */ = {isa = PBXBuildFile; fileRef = 0BCA495E1EC4B6C600B793EE /* Proximity.m */; };
DE9A0154289A9A9A00E41CBB /* JMCallKitEmitter.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69EFA09209A0F650027712B /* JMCallKitEmitter.swift */; };
DE9A0155289A9A9A00E41CBB /* ReactUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFE535521FB2E8300011A3A /* ReactUtils.m */; };
DE9A0156289A9A9A00E41CBB /* JitsiMeetView+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */; };
DE9A0157289A9A9A00E41CBB /* DragGestureController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6A3425E204EF76800E062DD /* DragGestureController.swift */; };
DE9A0158289A9A9A00E41CBB /* ScheenshareEventEmiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */; };
DE9A015A289A9A9A00E41CBB /* JitsiMeetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */; };
DE9A015B289A9A9A00E41CBB /* JMCallKitProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69EFA0A209A0F660027712B /* JMCallKitProxy.swift */; };
DE9A015C289A9A9A00E41CBB /* JitsiMeetLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = DE81A2D32316AC4D00AE1940 /* JitsiMeetLogger.m */; };
DE9A015D289A9A9A00E41CBB /* JMCallKitListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = C69EFA0B209A0F660027712B /* JMCallKitListener.swift */; };
DE9A015E289A9A9A00E41CBB /* JitsiMeetView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */; };
DE9A015F289A9A9A00E41CBB /* JitsiMeet.m in Sources */ = {isa = PBXBuildFile; fileRef = DEFE535321FB1BF800011A3A /* JitsiMeet.m */; };
DE9A0160289A9A9A00E41CBB /* JavaScriptSandbox.m in Sources */ = {isa = PBXBuildFile; fileRef = DE438CD82350934700DD541D /* JavaScriptSandbox.m */; };
DE9A0162289A9A9A00E41CBB /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB9AD781F5EC6D7001C08DB /* Intents.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
DE9A0163289A9A9A00E41CBB /* CallKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0BB9AD761F5EC6CE001C08DB /* CallKit.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
DE9A0166289A9A9A00E41CBB /* CallKitIcon.png in Resources */ = {isa = PBXBuildFile; fileRef = 0BC4B8681F8C01E100CE8B21 /* CallKitIcon.png */; };
DE9A0167289A9A9A00E41CBB /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; };
DE9A0168289A9A9A00E41CBB /* image-resize@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5C2053091D0040BE68 /* image-resize@3x.png */; };
DEA9F284258A5D9900D4CD74 /* JitsiMeetSDK.h in Headers */ = {isa = PBXBuildFile; fileRef = DEA9F283258A5D9900D4CD74 /* JitsiMeetSDK.h */; settings = {ATTRIBUTES = (Public, ); }; };
DEAD3226220C497000E93636 /* JitsiMeetConferenceOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = DEAD3224220C497000E93636 /* JitsiMeetConferenceOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
DEAD3227220C497000E93636 /* JitsiMeetConferenceOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = DEAD3225220C497000E93636 /* JitsiMeetConferenceOptions.m */; };
@@ -139,24 +79,14 @@
0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScheenshareEventEmiter.h; sourceTree = "<group>"; };
4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScheenshareEventEmiter.m; sourceTree = "<group>"; };
4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetViewController.h; sourceTree = "<group>"; };
4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetViewController.m; sourceTree = "<group>"; };
4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetRenderingView.h; sourceTree = "<group>"; };
4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetRenderingView.m; sourceTree = "<group>"; };
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>"; };
4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "JitsiMeetView+Private.m"; 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>"; };
927ED7DF018DE5E12C4C3404 /* libPods-JitsiMeetSDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeetSDK.a"; sourceTree = BUILT_PRODUCTS_DIR; };
98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
A4A934E8212F3ADB001E9388 /* Dropbox.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Dropbox.m; sourceTree = "<group>"; };
A4A934EB21349A06001E9388 /* Dropbox.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Dropbox.h; sourceTree = "<group>"; };
B46497DE9A95BDF5E312AF48 /* libPods-JitsiMeetSDKLite.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeetSDKLite.a"; sourceTree = BUILT_PRODUCTS_DIR; };
C6245F5B2053091D0040BE68 /* image-resize@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "image-resize@2x.png"; path = "src/picture-in-picture/image-resize@2x.png"; sourceTree = "<group>"; };
C6245F5C2053091D0040BE68 /* image-resize@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "image-resize@3x.png"; path = "src/picture-in-picture/image-resize@3x.png"; sourceTree = "<group>"; };
C69EFA09209A0F650027712B /* JMCallKitEmitter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JMCallKitEmitter.swift; sourceTree = "<group>"; };
@@ -164,6 +94,7 @@
C69EFA0B209A0F660027712B /* JMCallKitListener.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JMCallKitListener.swift; sourceTree = "<group>"; };
C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPViewCoordinator.swift; sourceTree = "<group>"; };
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExternalAPI.h; sourceTree = "<group>"; };
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
@@ -178,8 +109,6 @@
DE81A2D72316AC7600AE1940 /* LogBridge.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LogBridge.m; sourceTree = "<group>"; };
DE81A2DC2317ED5400AE1940 /* JitsiMeetBaseLogHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetBaseLogHandler.h; sourceTree = "<group>"; };
DE81A2DD2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetBaseLogHandler.m; sourceTree = "<group>"; };
DE9A016F289A9A9A00E41CBB /* JitsiMeetSDK.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JitsiMeetSDK.framework; sourceTree = BUILT_PRODUCTS_DIR; };
DE9A0170289A9A9A00E41CBB /* Lite-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Lite-Info.plist"; path = "/Users/saghul/work/jitsi/jitsi-meet-prs/ios/sdk/src/Lite-Info.plist"; sourceTree = "<absolute>"; };
DEA9F283258A5D9900D4CD74 /* JitsiMeetSDK.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetSDK.h; sourceTree = "<group>"; };
DEAD3224220C497000E93636 /* JitsiMeetConferenceOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetConferenceOptions.h; sourceTree = "<group>"; };
DEAD3225220C497000E93636 /* JitsiMeetConferenceOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetConferenceOptions.m; sourceTree = "<group>"; };
@@ -191,6 +120,7 @@
DEFE535521FB2E8300011A3A /* ReactUtils.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ReactUtils.m; sourceTree = "<group>"; };
DEFE535721FB2E9E00011A3A /* ReactUtils.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ReactUtils.h; sourceTree = "<group>"; };
DEFE535821FB311F00011A3A /* JitsiMeet+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeet+Private.h"; sourceTree = "<group>"; };
E4376CA6886DE68FD7A4294B /* libPods-JitsiMeetSDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-JitsiMeetSDK.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -200,18 +130,7 @@
files = (
0BB9AD791F5EC6D7001C08DB /* Intents.framework in Frameworks */,
0BB9AD771F5EC6CE001C08DB /* CallKit.framework in Frameworks */,
6F08DF7D4458EE3CF3F36F6D /* BuildFile in Frameworks */,
3453F4A32680898C4A40E821 /* libPods-JitsiMeetSDK.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DE9A0161289A9A9A00E41CBB /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DE9A0162289A9A9A00E41CBB /* Intents.framework in Frameworks */,
DE9A0163289A9A9A00E41CBB /* CallKit.framework in Frameworks */,
9A8EE79C77C17743BB66E8BD /* libPods-JitsiMeetSDKLite.a in Frameworks */,
6F08DF7D4458EE3CF3F36F6D /* libPods-JitsiMeetSDK.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -243,7 +162,6 @@
isa = PBXGroup;
children = (
0BD906E51EC0C00300C8C18E /* JitsiMeetSDK.framework */,
DE9A016F289A9A9A00E41CBB /* JitsiMeetSDK.framework */,
);
name = Products;
sourceTree = "<group>";
@@ -276,17 +194,12 @@
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */,
DE81A2DD2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m */,
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */,
4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */,
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */,
4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */,
4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */,
4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */,
DE81A2D72316AC7600AE1940 /* LogBridge.m */,
DE65AAC92317FFCD00290BEC /* LogUtils.h */,
DEAFA777229EAD3B0033A7FA /* RNRootView.h */,
DEAFA778229EAD520033A7FA /* RNRootView.m */,
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */,
0B412F1B1EDEC80100B1A0A6 /* JitsiMeetViewDelegate.h */,
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */,
C6A3426B204F127900E062DD /* picture-in-picture */,
@@ -302,7 +215,6 @@
0BA13D301EE83FF8007BEF7F /* ExternalAPI.m */,
4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */,
4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */,
DE9A0170289A9A9A00E41CBB /* Lite-Info.plist */,
);
path = src;
sourceTree = "<group>";
@@ -313,8 +225,7 @@
0BB9AD761F5EC6CE001C08DB /* CallKit.framework */,
0B93EF7A1EC608550030D24D /* CoreText.framework */,
0BB9AD781F5EC6D7001C08DB /* Intents.framework */,
B46497DE9A95BDF5E312AF48 /* libPods-JitsiMeetSDKLite.a */,
927ED7DF018DE5E12C4C3404 /* libPods-JitsiMeetSDK.a */,
E4376CA6886DE68FD7A4294B /* libPods-JitsiMeetSDK.a */,
);
name = Frameworks;
sourceTree = "<group>";
@@ -335,8 +246,6 @@
9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */,
09A78016288AF50ACD28A10D /* Pods-JitsiMeetSDK.debug.xcconfig */,
891FE43DAD30BC8976683100 /* Pods-JitsiMeetSDK.release.xcconfig */,
8F48C340DE0D91D1012976C5 /* Pods-JitsiMeetSDKLite.debug.xcconfig */,
86389F55993FAAF6AEB3FA3E /* Pods-JitsiMeetSDKLite.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
@@ -375,45 +284,17 @@
DEA9F284258A5D9900D4CD74 /* JitsiMeetSDK.h in Headers */,
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */,
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */,
4EBA6E652860B1E800B31882 /* JitsiMeetRenderingView.h in Headers */,
0B412F221EDEF6EA00B1A0A6 /* JitsiMeetViewDelegate.h in Headers */,
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */,
4EEC9630286C73A2008705FA /* JitsiMeetView+Private.h in Headers */,
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */,
DE81A2D42316AC4D00AE1940 /* JitsiMeetLogger.h in Headers */,
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */,
4EBA6E61286072E300B31882 /* JitsiMeetViewController.h in Headers */,
DEAD3226220C497000E93636 /* JitsiMeetConferenceOptions.h in Headers */,
C81E9AB925AC5AD800B134D9 /* ExternalAPI.h in Headers */,
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DE9A012F289A9A9A00E41CBB /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
DE9A0130289A9A9A00E41CBB /* JitsiMeetUserInfo.h in Headers */,
DE9A0131289A9A9A00E41CBB /* JitsiMeetView.h in Headers */,
DE9A0132289A9A9A00E41CBB /* RCTBridgeWrapper.h in Headers */,
DE9A0133289A9A9A00E41CBB /* JitsiMeetBaseLogHandler.h in Headers */,
DE9A0134289A9A9A00E41CBB /* JitsiMeetSDK.h in Headers */,
DE9A0135289A9A9A00E41CBB /* ScheenshareEventEmiter.h in Headers */,
DE9A0136289A9A9A00E41CBB /* JitsiMeetBaseLogHandler+Private.h in Headers */,
DE9A0137289A9A9A00E41CBB /* JitsiMeetRenderingView.h in Headers */,
DE9A0138289A9A9A00E41CBB /* JitsiMeetViewDelegate.h in Headers */,
DE9A0139289A9A9A00E41CBB /* JitsiAudioSession.h in Headers */,
DE9A013A289A9A9A00E41CBB /* JitsiMeetView+Private.h in Headers */,
DE9A013B289A9A9A00E41CBB /* JitsiMeet.h in Headers */,
DE9A013C289A9A9A00E41CBB /* JitsiMeetLogger.h in Headers */,
DE9A013D289A9A9A00E41CBB /* LogUtils.h in Headers */,
DE9A013E289A9A9A00E41CBB /* JitsiMeetViewController.h in Headers */,
DE9A013F289A9A9A00E41CBB /* JitsiMeetConferenceOptions.h in Headers */,
DE9A0140289A9A9A00E41CBB /* ExternalAPI.h in Headers */,
DE9A0141289A9A9A00E41CBB /* InfoPlistUtil.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
@@ -439,28 +320,6 @@
productReference = 0BD906E51EC0C00300C8C18E /* JitsiMeetSDK.framework */;
productType = "com.apple.product-type.framework";
};
DE9A012D289A9A9A00E41CBB /* JitsiMeetSDKLite */ = {
isa = PBXNativeTarget;
buildConfigurationList = DE9A016C289A9A9A00E41CBB /* Build configuration list for PBXNativeTarget "JitsiMeetSDKLite" */;
buildPhases = (
DE9A012E289A9A9A00E41CBB /* [CP] Check Pods Manifest.lock */,
DE9A012F289A9A9A00E41CBB /* Headers */,
DE9A0142289A9A9A00E41CBB /* Sources */,
DE9A0161289A9A9A00E41CBB /* Frameworks */,
DE9A0165289A9A9A00E41CBB /* Resources */,
DE9A0169289A9A9A00E41CBB /* Copy sounds */,
DE9A016A289A9A9A00E41CBB /* Package React bundle */,
DE9A016B289A9A9A00E41CBB /* [CP] Copy Pods Resources */,
);
buildRules = (
);
dependencies = (
);
name = JitsiMeetSDKLite;
productName = "Jitsi Meet SDK";
productReference = DE9A016F289A9A9A00E41CBB /* JitsiMeetSDK.framework */;
productType = "com.apple.product-type.framework";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
@@ -491,7 +350,6 @@
projectRoot = "";
targets = (
0BD906E41EC0C00300C8C18E /* JitsiMeetSDK */,
DE9A012D289A9A9A00E41CBB /* JitsiMeetSDKLite */,
);
};
/* End PBXProject section */
@@ -507,16 +365,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DE9A0165289A9A9A00E41CBB /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DE9A0166289A9A9A00E41CBB /* CallKitIcon.png in Resources */,
DE9A0167289A9A9A00E41CBB /* image-resize@2x.png in Resources */,
DE9A0168289A9A9A00E41CBB /* image-resize@3x.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
@@ -592,76 +440,6 @@
shellPath = /bin/sh;
shellScript = "SOUNDS_DIR=\"${PROJECT_DIR}/../../sounds\"\n\ncp $SOUNDS_DIR/* ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\n";
};
DE9A012E289A9A9A00E41CBB /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-JitsiMeetSDKLite-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
DE9A0169289A9A9A00E41CBB /* Copy sounds */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "Copy sounds";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "SOUNDS_DIR=\"${PROJECT_DIR}/../../sounds\"\n\ncp $SOUNDS_DIR/* ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/\n";
};
DE9A016A289A9A9A00E41CBB /* Package React bundle */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Package React bundle";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export NODE_BINARY=node\nexport NODE_ARGS=\"--max_old_space_size=4096\"\n../../node_modules/react-native/scripts/react-native-xcode.sh\n";
};
DE9A016B289A9A9A00E41CBB /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources.sh",
"${PODS_ROOT}/Amplitude/Sources/Resources/ComodoRsaDomainValidationCA.der",
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
);
name = "[CP] Copy Pods Resources";
outputPaths = (
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoRsaDomainValidationCA.der",
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
@@ -671,7 +449,6 @@
files = (
0BB9AD7B1F5EC8F4001C08DB /* CallKit.m in Sources */,
DE81A2DF2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m in Sources */,
4EBA6E662860B1E800B31882 /* JitsiMeetRenderingView.m in Sources */,
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */,
0BB9AD7D1F60356D001C08DB /* AppInfo.m in Sources */,
DE81A2D92316AC7600AE1940 /* LogBridge.m in Sources */,
@@ -688,11 +465,9 @@
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
DEFE535621FB2E8300011A3A /* ReactUtils.m in Sources */,
4EEC9631286C73A2008705FA /* JitsiMeetView+Private.m in Sources */,
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */,
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
4EBA6E62286072E300B31882 /* JitsiMeetViewController.m in Sources */,
C69EFA0D209A0F660027712B /* JMCallKitProxy.swift in Sources */,
DE81A2D52316AC4D00AE1940 /* JitsiMeetLogger.m in Sources */,
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */,
@@ -702,42 +477,6 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DE9A0142289A9A9A00E41CBB /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DE9A0143289A9A9A00E41CBB /* CallKit.m in Sources */,
DE9A0144289A9A9A00E41CBB /* JitsiMeetBaseLogHandler.m in Sources */,
DE9A0145289A9A9A00E41CBB /* JitsiMeetRenderingView.m in Sources */,
DE9A0146289A9A9A00E41CBB /* JitsiAudioSession.m in Sources */,
DE9A0147289A9A9A00E41CBB /* AppInfo.m in Sources */,
DE9A0148289A9A9A00E41CBB /* LogBridge.m in Sources */,
DE9A0149289A9A9A00E41CBB /* RNRootView.m in Sources */,
DE9A014A289A9A9A00E41CBB /* JitsiMeetUserInfo.m in Sources */,
DE9A014B289A9A9A00E41CBB /* JitsiMeetConferenceOptions.m in Sources */,
DE9A014C289A9A9A00E41CBB /* RCTBridgeWrapper.m in Sources */,
DE9A014D289A9A9A00E41CBB /* ExternalAPI.m in Sources */,
DE9A014E289A9A9A00E41CBB /* POSIX.m in Sources */,
DE9A014F289A9A9A00E41CBB /* InfoPlistUtil.m in Sources */,
DE9A0150289A9A9A00E41CBB /* PiPViewCoordinator.swift in Sources */,
DE9A0151289A9A9A00E41CBB /* LocaleDetector.m in Sources */,
DE9A0152289A9A9A00E41CBB /* AudioMode.m in Sources */,
DE9A0153289A9A9A00E41CBB /* Proximity.m in Sources */,
DE9A0154289A9A9A00E41CBB /* JMCallKitEmitter.swift in Sources */,
DE9A0155289A9A9A00E41CBB /* ReactUtils.m in Sources */,
DE9A0156289A9A9A00E41CBB /* JitsiMeetView+Private.m in Sources */,
DE9A0157289A9A9A00E41CBB /* DragGestureController.swift in Sources */,
DE9A0158289A9A9A00E41CBB /* ScheenshareEventEmiter.m in Sources */,
DE9A015A289A9A9A00E41CBB /* JitsiMeetViewController.m in Sources */,
DE9A015B289A9A9A00E41CBB /* JMCallKitProxy.swift in Sources */,
DE9A015C289A9A9A00E41CBB /* JitsiMeetLogger.m in Sources */,
DE9A015D289A9A9A00E41CBB /* JMCallKitListener.swift in Sources */,
DE9A015E289A9A9A00E41CBB /* JitsiMeetView.m in Sources */,
DE9A015F289A9A9A00E41CBB /* JitsiMeet.m in Sources */,
DE9A0160289A9A9A00E41CBB /* JavaScriptSandbox.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
@@ -919,73 +658,6 @@
};
name = Release;
};
DE9A016D289A9A9A00E41CBB /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8F48C340DE0D91D1012976C5 /* Pods-JitsiMeetSDKLite.debug.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = NO;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"COCOAPODS=1",
"JITSI_MEET_SDK_LITE=1",
);
INFOPLIST_FILE = "src/Lite-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeetSDK.ios;
PRODUCT_NAME = JitsiMeetSDK;
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
DE9A016E289A9A9A00E41CBB /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 86389F55993FAAF6AEB3FA3E /* Pods-JitsiMeetSDKLite.release.xcconfig */;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;
ARCHS = "$(ARCHS_STANDARD_64_BIT)";
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = "";
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_BITCODE = YES;
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)",
"COCOAPODS=1",
JITSI_MEET_SDK_LITE,
);
INFOPLIST_FILE = "src/Lite-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = org.jitsi.JitsiMeetSDK.ios;
PRODUCT_NAME = JitsiMeetSDK;
PROVISIONING_PROFILE_SPECIFIER = "";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = NO;
SWIFT_OBJC_BRIDGING_HEADER = "";
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
@@ -1007,15 +679,6 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DE9A016C289A9A9A00E41CBB /* Build configuration list for PBXNativeTarget "JitsiMeetSDKLite" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DE9A016D289A9A9A00E41CBB /* Debug */,
DE9A016E289A9A9A00E41CBB /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 0BD906DC1EC0C00300C8C18E /* Project object */;

View File

@@ -1,67 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1340"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DE9A012D289A9A9A00E41CBB"
BuildableName = "JitsiMeetSDK.framework"
BlueprintName = "JitsiMeetSDKLite"
ReferencedContainer = "container:sdk.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DE9A012D289A9A9A00E41CBB"
BuildableName = "JitsiMeetSDK.framework"
BlueprintName = "JitsiMeetSDKLite"
ReferencedContainer = "container:sdk.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -37,10 +37,8 @@ RCT_EXPORT_MODULE();
= [[NSBundle mainBundle] infoDictionary];
// calendarEnabled
BOOL calendarEnabled = NO;
#if !defined(JITSI_MEET_SDK_LITE)
calendarEnabled = infoDictionary[@"NSCalendarsUsageDescription"] != nil;
#endif
BOOL calendarEnabled
= infoDictionary[@"NSCalendarsUsageDescription"] != nil;
// name
NSString *name = infoDictionary[@"CFBundleDisplayName"];
@@ -65,39 +63,19 @@ RCT_EXPORT_MODULE();
}
}
// SDK version
NSDictionary<NSString *, id> *sdkInfoDictionary
= [[NSBundle bundleForClass:self.class] infoDictionary];
NSString *sdkVersion = sdkInfoDictionary[@"CFBundleShortVersionString"];
if (sdkVersion == nil) {
sdkVersion = sdkInfoDictionary[@"CFBundleVersion"];
if (sdkVersion == nil) {
sdkVersion = @"";
}
}
// build number
NSString *buildNumber = infoDictionary[@"CFBundleVersion"];
if (buildNumber == nil) {
buildNumber = @"";
}
// google services (sign in)
BOOL isGoogleServiceEnabled = [InfoPlistUtil containsRealServiceInfoPlistInBundle:[NSBundle mainBundle]];
// lite SDK
BOOL isLiteSDK = NO;
#if defined(JITSI_MEET_SDK_LITE)
isLiteSDK = YES;
#endif
return @{
@"calendarEnabled": [NSNumber numberWithBool:calendarEnabled],
@"buildNumber": buildNumber,
@"isLiteSDK": [NSNumber numberWithBool:isLiteSDK],
@"name": name,
@"sdkBundlePath": sdkBundlePath,
@"sdkVersion": sdkVersion,
@"version": version,
@"GOOGLE_SERVICES_ENABLED": [NSNumber numberWithBool:isGoogleServiceEnabled]
};

View File

@@ -21,6 +21,7 @@
#import <WebRTC/WebRTC.h>
#import "JitsiAudioSession+Private.h"
#import "LogUtils.h"
// Audio mode
@@ -177,7 +178,7 @@ RCT_EXPORT_METHOD(setMode:(int)mode
RCT_EXPORT_METHOD(setAudioDevice:(NSString *)device
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
RCTLogInfo(@"[AudioMode] Selected device: %@", device);
DDLogInfo(@"[AudioMode] Selected device: %@", device);
RTCAudioSession *session = JitsiAudioSession.rtcAudioSession;
[session lockForConfiguration];
@@ -247,7 +248,7 @@ RCT_EXPORT_METHOD(updateDeviceList) {
- (void)audioSessionDidChangeRoute:(RTCAudioSession *)session
reason:(AVAudioSessionRouteChangeReason)reason
previousRoute:(AVAudioSessionRouteDescription *)previousRoute {
RCTLogInfo(@"[AudioMode] Route changed, reason: %lu", (unsigned long)reason);
DDLogInfo(@"[AudioMode] Route changed, reason: %lu", (unsigned long)reason);
// Update JS about the changes.
[self notifyDevicesChanged];
@@ -274,7 +275,7 @@ RCT_EXPORT_METHOD(updateDeviceList) {
// This is to play well with other components which could be integrated
// into the final application.
if (self->activeMode != kAudioModeDefault) {
RCTLogInfo(@"[AudioMode] Route changed, reapplying RTCAudioSession config");
DDLogInfo(@"[AudioMode] Route changed, reapplying RTCAudioSession config");
RTCAudioSessionConfiguration *config = [self configForMode:self->activeMode];
[self setConfig:config error:nil];
if (self->forceSpeaker && !self->isSpeakerOn) {
@@ -287,7 +288,7 @@ RCT_EXPORT_METHOD(updateDeviceList) {
}
- (void)audioSession:(RTCAudioSession *)audioSession didSetActive:(BOOL)active {
RCTLogInfo(@"[AudioMode] Audio session didSetActive:%d", active);
DDLogInfo(@"[AudioMode] Audio session didSetActive:%d", active);
}
#pragma mark - Helper methods

View File

@@ -16,8 +16,6 @@
#import <React/RCTBridgeModule.h>
#import <React/RCTEventEmitter.h>
static NSString * const sendEventNotificationName = @"org.jitsi.meet.SendEvent";
@interface ExternalAPI : RCTEventEmitter<RCTBridgeModule>
- (void)sendHangUp;

View File

@@ -15,6 +15,7 @@
*/
#import "ExternalAPI.h"
#import "JitsiMeetView+Private.h"
// Events
static NSString * const hangUpAction = @"org.jitsi.meet.HANG_UP";
@@ -88,15 +89,33 @@ RCT_EXPORT_MODULE();
* @param scope
*/
RCT_EXPORT_METHOD(sendEvent:(NSString *)name
data:(NSDictionary *)data) {
data:(NSDictionary *)data
scope:(NSString *)scope) {
// The JavaScript App needs to provide uniquely identifying information to
// the native ExternalAPI module so that the latter may match the former
// to the native JitsiMeetView which hosts it.
JitsiMeetView *view = [JitsiMeetView viewForExternalAPIScope:scope];
if (!view) {
return;
}
id delegate = view.delegate;
if (!delegate) {
return;
}
if ([name isEqual: @"PARTICIPANTS_INFO_RETRIEVED"]) {
[self onParticipantsInfoRetrieved: data];
return;
}
[[NSNotificationCenter defaultCenter] postNotificationName:sendEventNotificationName
object:nil
userInfo:@{@"name": name, @"data": data}];
SEL sel = NSSelectorFromString([self methodNameFromEventName:name]);
if (sel && [delegate respondsToSelector:sel]) {
[delegate performSelector:sel withObject:data];
}
}
- (void) onParticipantsInfoRetrieved:(NSDictionary *)data {
@@ -108,6 +127,28 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
[participantInfoCompletionHandlers removeObjectForKey:completionHandlerId];
}
/**
* Converts a specific event name i.e. redux action type description to a
* method name.
*
* @param eventName The event name to convert to a method name.
* @return A method name constructed from the specified `eventName`.
*/
- (NSString *)methodNameFromEventName:(NSString *)eventName {
NSMutableString *methodName
= [NSMutableString stringWithCapacity:eventName.length];
for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
if (c.length) {
[methodName appendString:
methodName.length ? c.capitalizedString : c.lowercaseString];
}
}
[methodName appendString:@":"];
return methodName;
}
- (void)sendHangUp {
[self sendEventWithName:hangUpAction body:nil];
}

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<string>5.2.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>

View File

@@ -15,8 +15,8 @@
*/
#import <Intents/Intents.h>
#import <WebRTC/RTCLogging.h>
#import "Dropbox.h"
#import "JitsiMeet+Private.h"
#import "JitsiMeetConferenceOptions+Private.h"
#import "JitsiMeetView+Private.h"
@@ -25,10 +25,8 @@
#import "RNSplashScreen.h"
#import "ScheenshareEventEmiter.h"
#if !defined(JITSI_MEET_SDK_LITE)
#import <RNGoogleSignin/RNGoogleSignin.h>
#import "Dropbox.h"
#endif
#import <WebRTC/RTCLogging.h>
@implementation JitsiMeet {
RCTBridgeWrapper *_bridgeWrapper;
@@ -79,9 +77,7 @@
_launchOptions = [launchOptions copy];
#if !defined(JITSI_MEET_SDK_LITE)
[Dropbox setAppKey];
#endif
return YES;
}
@@ -91,19 +87,14 @@
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *))restorationHandler {
JitsiMeetConferenceOptions *options = [self optionsFromUserActivity:userActivity];
if (options) {
[JitsiMeetView updateProps:[options asProps]];
return true;
}
return false;
return options && [JitsiMeetView setPropsInViews:[options asProps]];
}
- (BOOL)application:(UIApplication *)app
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
#if !defined(JITSI_MEET_SDK_LITE)
if ([Dropbox application:app openURL:url options:options]) {
return YES;
}
@@ -113,7 +104,6 @@
options:options]) {
return YES;
}
#endif
if (_customUrlScheme == nil || ![_customUrlScheme isEqualToString:url.scheme]) {
return NO;
@@ -122,9 +112,8 @@
JitsiMeetConferenceOptions *conferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
builder.room = [url absoluteString];
}];
[JitsiMeetView updateProps:[conferenceOptions asProps]];
return true;
return [JitsiMeetView setPropsInViews:[conferenceOptions asProps]];
}
#pragma mark - Utility methods

View File

@@ -1,30 +0,0 @@
/*
* Copyright @ 2022-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <UIKit/UIKit.h>
#import "JitsiMeetViewDelegate.h"
NS_ASSUME_NONNULL_BEGIN
@interface JitsiMeetRenderingView : UIView
@property (nonatomic, assign) BOOL isPiPEnabled;
- (void)setProps:(NSDictionary *_Nonnull)newProps;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,83 +0,0 @@
/*
* Copyright @ 2022-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <mach/mach_time.h>
#import "JitsiMeetRenderingView.h"
#import "ReactUtils.h"
#import "RNRootView.h"
#import "JitsiMeet+Private.h"
/**
* Backwards compatibility: turn the boolean prop into a feature flag.
*/
static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
@interface JitsiMeetRenderingView ()
@end
@implementation JitsiMeetRenderingView {
/**
* React Native view where the entire content will be rendered.
*/
RNRootView *rootView;
}
/**
* Passes the given props to the React Native application. The props which we pass
* are a combination of 3 different sources:
*
* - JitsiMeet.defaultConferenceOptions
* - This function's parameters
* - Some extras which are added by this function
*/
- (void)setProps:(NSDictionary *_Nonnull)newProps {
NSMutableDictionary *props = mergeProps([[JitsiMeet sharedInstance] getDefaultProps], newProps);
// Set the PiP flag if it wasn't manually set.
NSMutableDictionary *featureFlags = props[@"flags"];
// TODO: temporary implementation
if (featureFlags[PiPEnabledFeatureFlag] == nil) {
featureFlags[PiPEnabledFeatureFlag] = @(self.isPiPEnabled);
}
// This method is supposed to be imperative i.e. a second
// invocation with one and the same URL is expected to join the respective
// conference again if the first invocation was followed by leaving the
// conference. However, React and, respectively,
// appProperties/initialProperties are declarative expressions i.e. one and
// the same URL will not trigger an automatic re-render in the JavaScript
// source code. The workaround implemented below introduces imperativeness
// in React Component props by defining a unique value per invocation.
props[@"timestamp"] = @(mach_absolute_time());
if (rootView) {
// Update props with the new URL.
rootView.appProperties = props;
} else {
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
rootView = [[RNRootView alloc] initWithBridge:bridge
moduleName:@"App"
initialProperties:props];
rootView.backgroundColor = self.backgroundColor;
// Add rootView as a subview which completely covers this one.
[rootView setFrame:[self bounds]];
rootView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:rootView];
}
}
@end

View File

@@ -1,5 +1,6 @@
/*
* Copyright @ 2022-present 8x8, Inc.
* 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.
@@ -14,16 +15,11 @@
* limitations under the License.
*/
#import <JitsiMeetSDK/JitsiMeetSDK.h>
#import "JitsiMeetView.h"
NS_ASSUME_NONNULL_BEGIN
@interface JitsiMeetView ()
static NSString * const updateViewPropsNotificationName = @"org.jitsi.meet.UpdateViewProps";
@interface JitsiMeetView (Private)
+ (void)updateProps:(NSDictionary *_Nonnull)newProps;
+ (instancetype _Nullable)viewForExternalAPIScope:(NSString *_Nonnull)externalAPIScope;
+ (BOOL)setPropsInViews:(NSDictionary *_Nonnull)newProps;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,25 +0,0 @@
/*
* Copyright @ 2022-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "JitsiMeetView+Private.h"
@implementation JitsiMeetView (Private)
+ (void)updateProps:(NSDictionary *_Nonnull)newProps {
[[NSNotificationCenter defaultCenter] postNotificationName:updateViewPropsNotificationName object:nil userInfo:@{@"props": newProps}];
}
@end

View File

@@ -20,22 +20,43 @@
#import "ExternalAPI.h"
#import "JitsiMeet+Private.h"
#import "JitsiMeetConferenceOptions+Private.h"
#import "JitsiMeetView.h"
#import "JitsiMeetViewController.h"
#import "JitsiMeetView+Private.h"
#import "ReactUtils.h"
#import "RNRootView.h"
@interface JitsiMeetView ()
@property (nonatomic, strong) JitsiMeetViewController *jitsiMeetViewController;
@property (nonatomic, strong) UINavigationController *navController;
@property (nonatomic, readonly) BOOL isPiPEnabled;
/**
* Backwards compatibility: turn the boolean prop into a feature flag.
*/
static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
@end
@implementation JitsiMeetView
@implementation JitsiMeetView {
/**
* The unique identifier of this `JitsiMeetView` within the process for the
* purposes of `ExternalAPI`. The name scope was inspired by postis which we
* use on Web for the similar purposes of the iframe-based external API.
*/
NSString *externalAPIScope;
@dynamic isPiPEnabled;
/**
* React Native view where the entire content will be rendered.
*/
RNRootView *rootView;
}
/**
* The `JitsiMeetView`s associated with their `ExternalAPI` scopes (i.e. unique
* identifiers within the process).
*/
static NSMapTable<NSString *, JitsiMeetView *> *views;
/**
* This gets called automagically when the program starts.
*/
__attribute__((constructor))
static void initializeViewsMap() {
views = [NSMapTable strongToWeakObjectsMapTable];
}
#pragma mark Initializers
@@ -66,10 +87,6 @@
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
/**
* Internal initialization:
*
@@ -77,57 +94,70 @@
* - initializes the external API scope
*/
- (void)initWithXXX {
self.jitsiMeetViewController = [[JitsiMeetViewController alloc] init];
self.jitsiMeetViewController.view.frame = [self bounds];
[self addSubview:self.jitsiMeetViewController.view];
[self registerObservers];
// Hook this JitsiMeetView into ExternalAPI.
externalAPIScope = [NSUUID UUID].UUIDString;
[views setObject:self forKey:externalAPIScope];
// 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];
}
#pragma mark API
- (void)join:(JitsiMeetConferenceOptions *)options {
[self.jitsiMeetViewController join:options withPiP:self.isPiPEnabled];
[self setProps:options == nil ? @{} : [options asProps]];
}
- (void)leave {
[self.jitsiMeetViewController leave];
[self setProps:@{}];
}
- (void)hangUp {
[self.jitsiMeetViewController hangUp];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendHangUp];
}
- (void)setAudioMuted:(BOOL)muted {
[self.jitsiMeetViewController setAudioMuted:muted];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendSetAudioMuted:muted];
}
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
[self.jitsiMeetViewController sendEndpointTextMessage:message :to];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendEndpointTextMessage:message :to];
}
- (void)toggleScreenShare:(BOOL)enabled {
[self.jitsiMeetViewController toggleScreenShare:enabled];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI toggleScreenShare:enabled];
}
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler {
[self.jitsiMeetViewController retrieveParticipantsInfo:completionHandler];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI retrieveParticipantsInfo:completionHandler];
}
- (void)openChat:(NSString*)to {
[self.jitsiMeetViewController openChat:to];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI openChat:to];
}
- (void)closeChat {
[self.jitsiMeetViewController closeChat];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI closeChat];
}
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
[self.jitsiMeetViewController sendChatMessage:message :to];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendChatMessage:message :to];
}
- (void)setVideoMuted:(BOOL)muted {
[self.jitsiMeetViewController setVideoMuted:muted];
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendSetVideoMuted:muted];
}
- (void)setClosedCaptionsEnabled:(BOOL)enabled {
@@ -135,47 +165,79 @@
[externalAPI sendSetClosedCaptionsEnabled:enabled];
}
#pragma mark Private
#pragma mark Private methods
- (BOOL)isPiPEnabled {
return self.delegate && [self.delegate respondsToSelector:@selector(enterPictureInPicture:)];
}
/**
* Passes the given props to the React Native application. The props which we pass
* are a combination of 3 different sources:
*
* - JitsiMeet.defaultConferenceOptions
* - This function's parameters
* - Some extras which are added by this function
*/
- (void)setProps:(NSDictionary *_Nonnull)newProps {
NSMutableDictionary *props = mergeProps([[JitsiMeet sharedInstance] getDefaultProps], newProps);
- (void)registerObservers {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSendEventNotification:) name:sendEventNotificationName object:nil];
}
// Set the PiP flag if it wasn't manually set.
NSMutableDictionary *featureFlags = props[@"flags"];
if (featureFlags[PiPEnabledFeatureFlag] == nil) {
featureFlags[PiPEnabledFeatureFlag]
= [NSNumber numberWithBool:
self.delegate && [self.delegate respondsToSelector:@selector(enterPictureInPicture:)]];
}
- (void)handleSendEventNotification:(NSNotification *)notification {
NSString *eventName = notification.userInfo[@"name"];
NSString *eventData = notification.userInfo[@"data"];
SEL sel = NSSelectorFromString([self methodNameFromEventName:eventName]);
props[@"externalAPIScope"] = externalAPIScope;
if (sel && [self.delegate respondsToSelector:sel]) {
[self.delegate performSelector:sel withObject:eventData];
// This method is supposed to be imperative i.e. a second
// invocation with one and the same URL is expected to join the respective
// conference again if the first invocation was followed by leaving the
// conference. However, React and, respectively,
// appProperties/initialProperties are declarative expressions i.e. one and
// the same URL will not trigger an automatic re-render in the JavaScript
// source code. The workaround implemented below introduces imperativeness
// in React Component props by defining a unique value per invocation.
props[@"timestamp"] = @(mach_absolute_time());
if (rootView) {
// Update props with the new URL.
rootView.appProperties = props;
} else {
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
rootView
= [[RNRootView alloc] initWithBridge:bridge
moduleName:@"App"
initialProperties:props];
rootView.backgroundColor = self.backgroundColor;
// Add rootView as a subview which completely covers this one.
[rootView setFrame:[self bounds]];
rootView.autoresizingMask
= UIViewAutoresizingFlexibleWidth
| UIViewAutoresizingFlexibleHeight;
[self addSubview:rootView];
}
}
/**
* Converts a specific event name i.e. redux action type description to a
* method name.
*
* @param eventName The event name to convert to a method name.
* @return A method name constructed from the specified `eventName`.
*/
- (NSString *)methodNameFromEventName:(NSString *)eventName {
NSMutableString *methodName
= [NSMutableString stringWithCapacity:eventName.length];
+ (BOOL)setPropsInViews:(NSDictionary *_Nonnull)newProps {
BOOL handled = NO;
for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
if (c.length) {
[methodName appendString:
methodName.length ? c.capitalizedString : c.lowercaseString];
}
}
[methodName appendString:@":"];
if (views) {
for (NSString *externalAPIScope in views) {
JitsiMeetView *view
= [self viewForExternalAPIScope:externalAPIScope];
return methodName;
if (view) {
[view setProps:newProps];
handled = YES;
}
}
}
return handled;
}
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope {
return [views objectForKey:externalAPIScope];
}
@end

View File

@@ -1,38 +0,0 @@
/*
* Copyright @ 2022-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import <UIKit/UIKit.h>
#import "JitsiMeetConferenceOptions.h"
NS_ASSUME_NONNULL_BEGIN
@interface JitsiMeetViewController : UIViewController
- (void)join:(JitsiMeetConferenceOptions *)options withPiP:(BOOL)enablePiP;
- (void)leave;
- (void)hangUp;
- (void)setAudioMuted:(BOOL)muted;
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
- (void)toggleScreenShare:(BOOL)enabled;
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler;
- (void)openChat:(NSString*)to;
- (void)closeChat;
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
- (void)setVideoMuted:(BOOL)muted;
@end
NS_ASSUME_NONNULL_END

View File

@@ -1,127 +0,0 @@
/*
* Copyright @ 2022-present 8x8, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#import "JitsiMeetViewController.h"
#import "JitsiMeet+Private.h"
#import "JitsiMeetConferenceOptions+Private.h"
#import "JitsiMeetRenderingView.h"
#import "JitsiMeetView+Private.h"
@interface JitsiMeetViewController ()
@property (strong, nonatomic) JitsiMeetRenderingView *view;
@end
@implementation JitsiMeetViewController
@dynamic view;
- (instancetype)init {
self = [super init];
if (self) {
[self registerObservers];
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)loadView {
[super loadView];
self.view = [[JitsiMeetRenderingView alloc] init];
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
}
- (void)viewDidLoad {
[super viewDidLoad];
// 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.view.backgroundColor = [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
}
- (void)join:(JitsiMeetConferenceOptions *)options withPiP:(BOOL)enablePiP {
self.view.isPiPEnabled = enablePiP;
[self.view setProps:options == nil ? @{} : [options asProps]];
}
- (void)leave {
[self.view setProps:@{}];
}
- (void)hangUp {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendHangUp];
}
- (void)setAudioMuted:(BOOL)muted {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendSetAudioMuted:muted];
}
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendEndpointTextMessage:message :to];
}
- (void)toggleScreenShare:(BOOL)enabled {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI toggleScreenShare:enabled];
}
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI retrieveParticipantsInfo:completionHandler];
}
- (void)openChat:(NSString*)to {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI openChat:to];
}
- (void)closeChat {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI closeChat];
}
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendChatMessage:message :to];
}
- (void)setVideoMuted:(BOOL)muted {
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
[externalAPI sendSetVideoMuted:muted];
}
#pragma mark Private
- (void)registerObservers {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUpdateViewPropsNotification:) name:updateViewPropsNotificationName object:nil];
}
- (void)handleUpdateViewPropsNotification:(NSNotification *)notification {
NSDictionary *props = [notification.userInfo objectForKey:@"props"];
[self.view setProps:props];
}
@end

View File

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>99.0.0</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View File

@@ -26,10 +26,11 @@
#import <React/RCTBridge.h>
#import <React/RCTEventEmitter.h>
#import <React/RCTUtils.h>
#import <React/RCTLog.h>
#import <WebRTC/WebRTC.h>
#import <JitsiMeetSDK/JitsiMeetSDK-Swift.h>
#import "../LogUtils.h"
#import "JitsiAudioSession.h"
@@ -72,7 +73,7 @@ RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(endCall:(NSString *)callUUID
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
RCTLogInfo(@"[RNCallKit][endCall] callUUID = %@", callUUID);
DDLogInfo(@"[RNCallKit][endCall] callUUID = %@", callUUID);
NSUUID *callUUID_ = [[NSUUID alloc] initWithUUIDString:callUUID];
@@ -93,7 +94,7 @@ RCT_EXPORT_METHOD(setMuted:(NSString *)callUUID
muted:(BOOL)muted
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
RCTLogInfo(@"[RNCallKit][setMuted] callUUID = %@", callUUID);
DDLogInfo(@"[RNCallKit][setMuted] callUUID = %@", callUUID);
NSUUID *callUUID_ = [[NSUUID alloc] initWithUUIDString:callUUID];
@@ -110,7 +111,7 @@ RCT_EXPORT_METHOD(setMuted:(NSString *)callUUID
}
RCT_EXPORT_METHOD(setProviderConfiguration:(NSDictionary *)dictionary) {
RCTLogInfo(@"[RNCallKit][setProviderConfiguration:] dictionary = %@", dictionary);
DDLogInfo(@"[RNCallKit][setProviderConfiguration:] dictionary = %@", dictionary);
if (![JMCallKitProxy isProviderConfigured]) {
JMCallKitProxy.enabled = true;
@@ -127,7 +128,7 @@ RCT_EXPORT_METHOD(startCall:(NSString *)callUUID
video:(BOOL)video
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
RCTLogInfo(@"[RNCallKit][startCall] callUUID = %@", callUUID);
DDLogInfo(@"[RNCallKit][startCall] callUUID = %@", callUUID);
NSUUID *callUUID_ = [[NSUUID alloc] initWithUUIDString:callUUID];
@@ -191,7 +192,7 @@ RCT_EXPORT_METHOD(updateCall:(NSString *)callUUID
options:(NSDictionary *)options
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject) {
RCTLogInfo(@"[RNCallKit][updateCall] callUUID = %@ options = %@", callUUID, options);
DDLogInfo(@"[RNCallKit][updateCall] callUUID = %@ options = %@", callUUID, options);
NSUUID *callUUID_ = [[NSUUID alloc] initWithUUIDString:callUUID];
@@ -214,7 +215,7 @@ RCT_EXPORT_METHOD(updateCall:(NSString *)callUUID
#pragma mark - Helper methods
- (void)configureProviderFromDictionary:(NSDictionary* )dictionary {
RCTLogInfo(@"[RNCallKit][providerConfigurationFromDictionary: %@]", dictionary);
DDLogInfo(@"[RNCallKit][providerConfigurationFromDictionary: %@]", dictionary);
if (!dictionary) {
dictionary = @{};
@@ -258,12 +259,12 @@ RCT_EXPORT_METHOD(updateCall:(NSString *)callUUID
- (void)requestTransaction:(CXTransaction *)transaction
resolve:(RCTPromiseResolveBlock)resolve
reject:(RCTPromiseRejectBlock)reject {
RCTLogInfo(@"[RNCallKit][requestTransaction] transaction = %@", transaction);
DDLogInfo(@"[RNCallKit][requestTransaction] transaction = %@", transaction);
[JMCallKitProxy request:transaction
completion:^(NSError * _Nullable error) {
if (error) {
RCTLogError(@"[RNCallKit][requestTransaction] Error requesting transaction (%@): (%@)", transaction.actions, error);
DDLogError(@"[RNCallKit][requestTransaction] Error requesting transaction (%@): (%@)", transaction.actions, error);
reject(nil, @"Error processing CallKit transaction", error);
} else {
resolve(nil);
@@ -275,14 +276,14 @@ RCT_EXPORT_METHOD(updateCall:(NSString *)callUUID
// Called when the provider has been reset. We should terminate all calls.
- (void)providerDidReset {
RCTLogInfo(@"[RNCallKit][CXProviderDelegate][providerDidReset:]");
DDLogInfo(@"[RNCallKit][CXProviderDelegate][providerDidReset:]");
[self sendEventWithName:RNCallKitProviderDidReset body:nil];
}
// Answering incoming call
- (void) performAnswerCallWithUUID:(NSUUID *)UUID {
RCTLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performAnswerCallAction:]");
DDLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performAnswerCallAction:]");
[self sendEventWithName:RNCallKitPerformAnswerCallAction
body:@{ @"callUUID": UUID.UUIDString }];
@@ -290,7 +291,7 @@ RCT_EXPORT_METHOD(updateCall:(NSString *)callUUID
// Call ended, user request
- (void) performEndCallWithUUID:(NSUUID *)UUID {
RCTLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performEndCallAction:]");
DDLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performEndCallAction:]");
[self sendEventWithName:RNCallKitPerformEndCallAction
body:@{ @"callUUID": UUID.UUIDString }];
@@ -299,7 +300,7 @@ RCT_EXPORT_METHOD(updateCall:(NSString *)callUUID
// Handle audio mute from CallKit view
- (void) performSetMutedCallWithUUID:(NSUUID *)UUID
isMuted:(BOOL)isMuted {
RCTLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performSetMutedCallAction:]");
DDLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performSetMutedCallAction:]");
[self sendEventWithName:RNCallKitPerformSetMutedCallAction
body:@{
@@ -311,26 +312,26 @@ RCT_EXPORT_METHOD(updateCall:(NSString *)callUUID
// Starting outgoing call
- (void) performStartCallWithUUID:(NSUUID *)UUID
isVideo:(BOOL)isVideo {
RCTLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performStartCallAction:]");
DDLogInfo(@"[RNCallKit][CXProviderDelegate][provider:performStartCallAction:]");
[JMCallKitProxy reportOutgoingCallWith:UUID
startedConnectingAt:nil];
}
- (void) providerDidActivateAudioSessionWithSession:(AVAudioSession *)session {
RCTLogInfo(@"[RNCallKit][CXProviderDelegate][provider:didActivateAudioSession:]");
DDLogInfo(@"[RNCallKit][CXProviderDelegate][provider:didActivateAudioSession:]");
[JitsiAudioSession activateWithAudioSession:session];
}
- (void) providerDidDeactivateAudioSessionWithSession:(AVAudioSession *)session {
RCTLogInfo(@"[RNCallKit][CXProviderDelegate][provider:didDeactivateAudioSession:]");
DDLogInfo(@"[RNCallKit][CXProviderDelegate][provider:didDeactivateAudioSession:]");
[JitsiAudioSession deactivateWithAudioSession:session];
}
- (void) providerTimedOutPerformingActionWithAction:(CXAction *)action {
RCTLogWarn(@"[RNCallKit][CXProviderDelegate][provider:timedOutPerformingAction:]");
DDLogWarn(@"[RNCallKit][CXProviderDelegate][provider:timedOutPerformingAction:]");
}

View File

@@ -17,7 +17,6 @@
"fr": "Französisch",
"frCA": "Französisch (Kanada)",
"hr": "Kroatisch",
"hsb": "Obersorbisch",
"hu": "Ungarisch",
"hy": "Armenisch",
"it": "Italienisch",

View File

@@ -17,7 +17,6 @@
"fr": "French",
"frCA": "French (Canadian)",
"hr": "Croatian",
"hsb": "Upper Sorbian",
"hu": "Hungarian",
"hy": "Armenian",
"it": "Italian",

View File

@@ -1,56 +1,28 @@
{
"af": "Afrikanski",
"ar": "Arapski",
"az": "Ažerbejdžanski",
"bg": "Bugarski",
"ca": "Katalanski",
"cs": "Češki",
"da": "Danski",
"de": "Njemački",
"el": "Grčki",
"en": "Engleski",
"enGB": "Engleski (Ujedinjeno Kraljevstvo)",
"eo": "Esperanto",
"es": "Španjolski",
"esUS": "Španjolski (Latinska Amerika)",
"et": "Estonski",
"eu": "Baskijski",
"fa": "Perzijski",
"fi": "Finski",
"fr": "Francuski",
"frCA": "Francuski (Canada)",
"he": "Hebrejski",
"hi": "Hindski",
"hr": "Hrvatski",
"hsb": "Gornjolužičkosrpski",
"hu": "Mađarski",
"hy": "Armenski",
"id": "Indonezijski",
"it": "Talijanski",
"ja": "Japanski",
"ko": "Korejski",
"lt": "Litvanski",
"lv": "Latvijski",
"ml": "Malayalam",
"mr": "Marathi",
"nb": "Norveški Bokmal",
"nl": "Nizozemski",
"oc": "Okcitanski",
"pl": "Poljski",
"pt": "Portugalski",
"ptBR": "Portugalski (Brazil)",
"ro": "Rumunjski",
"ru": "Ruski",
"sc": "Sardijski",
"sk": "Slovački",
"sl": "Slovenski",
"sq": "Albanski",
"sr": "Srpski",
"sv": "Švedski",
"te": "Teluški",
"th": "Tajski",
"tr": "Turski",
"uk": "Ukrajinski",
"vi": "Vijetnamski",
"zhCN": "Kineski (Kina)",
"zhTW": "Kineski (Taiwan)"
"zhCN": "Kineski (Kina)"
}

View File

@@ -1,47 +0,0 @@
{
"ar": "arabšćina",
"bg": "bołharšćina",
"cs": "čěšćina",
"da": "danšćina",
"de": "němčina",
"el": "grjekšćina",
"en": "jendźelšćina",
"enGB": "jendźelšćina (Wulka Britaniska)",
"eo": "esperanto",
"es": "španišćina",
"esUS": "španišćina (Łaćonska)",
"et": "estišćina",
"eu": "baskišćina",
"fa": "persišćina",
"fi": "finšćina",
"fr": "francošćina",
"frCA": "francošćina (Kanada)",
"he": "hebrejšćina",
"hi": "hindišćina",
"hr": "chorwatšćina",
"hsb": "hornjoserbšćina",
"hu": "madźaršćina",
"hy": "armenšćina",
"id": "indonešćina",
"it": "italšćina",
"ja": "japanšćina",
"ko": "korejšćina",
"lt": "litawšćina",
"lv": "letišćina",
"nl": "nižozemšćina",
"pl": "pólšćina",
"pt": "portugalšćina",
"ptBR": "portugalšćina (Brazilska)",
"ro": "rumunšćina",
"ru": "rušćina",
"sk": "słowakšćina",
"sl": "słowjenšćina",
"sq": "albanšćina",
"sr": "serbišćina",
"sv": "šwedšćina",
"tr": "turkowšćina",
"uk": "ukrainšćina",
"vi": "vietnamšćina",
"zhCN": "chinšćina (China)",
"zhTW": "chinšćina (Taiwan)"
}

View File

@@ -21,7 +21,6 @@
"he": "Hebrew",
"hi": "Hindi",
"hr": "Croatian",
"hsb": "Upper Sorbian",
"hu": "Hungarian",
"hy": "Armenian",
"id": "Indonesian",

View File

@@ -683,10 +683,6 @@
"newDeviceAction": "استعمل",
"newDeviceAudioTitle": "اكتُشفَ جهاز صوت جديد",
"newDeviceCameraTitle": "اكتُشفَت كاميرا جديدة",
"noiseSuppressionDesktopAudioDescription": "لا يمكن تمكين منع الضوضاء أثناء مشاركة صوت سطح المكتب ، يرجى تعطيله والمحاولة مرة أخرى.",
"noiseSuppressionFailedTitle": "فشل في بدء قمع الضوضاء",
"noiseSuppressionNoTrackDescription": "يرجى إعادة صوت الميكروفون أولاً.",
"noiseSuppressionStereoDescription": "قمع ضوضاء صوت الاستريو غير مدعوم حاليًا.",
"oldElectronClientDescription1": "يبدو أنَّك تستعمل إصدارًا قديمًا من جيتسي يحوي ثغرة أمنية. تأكد رجاءً من أنَّك حدَّثته إلى ",
"oldElectronClientDescription2": "أحدث إصدار",
"oldElectronClientDescription3": " الآن!",
@@ -898,20 +894,12 @@
"limitNotificationDescriptionWeb": "نظرًا للضغط الكبير، سيقيَّد التسجيل إلى {{limit}} د، ولكن إن أردت التسجيل لمدة مفتوحة، جرِّب <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "لقد أنشأنا رابطًا لتسجيلك.",
"live": "مباشر",
"localRecordingNoNotificationWarning": "لن يتم الإعلان عن التسجيل للمشاركين الآخرين. ستحتاج إلى إخبارهم بأنه تم تسجيل الاجتماع.",
"localRecordingNoVideo": "لا يتم تسجيل الفيديو",
"localRecordingStartWarning": "يرجى التأكد من إيقاف التسجيل قبل الخروج من الاجتماع من أجل حفظه.",
"localRecordingStartWarningTitle": "أوقف التسجيل لحفظه",
"localRecordingVideoStop": "سيؤدي إيقاف الفيديو أيضًا إلى إيقاف التسجيل المحلي. هل أنت متأكد أنك تريد الاستمرار؟",
"localRecordingVideoWarning": "لتسجيل الفيديو الخاص بك ، يجب أن يكون لديك عند بدء التسجيل",
"localRecordingWarning": "تأكد من تحديد علامة التبويب الحالية لاستخدام الفيديو والصوت الصحيحين. التسجيل محدود حاليًا بـ 1 كيغابايت ، أي حوالي 100 دقيقة.",
"loggedIn": "مُسجَّل باسم {{userName}}",
"noStreams": "لم يتم الكشف عن دفق الصوت أو الفيديو.",
"off": "أوقِف التسجيل",
"offBy": "أوقَف {{name}} التسجيل",
"on": "تسجيل",
"onBy": "بدأ {{name}} التسجيل",
"onlyRecordSelf": "تسجيل فقط دفق الصوت والفيديو الخاصة بي",
"pending": "التحضير لتسجيل المُلتقى...",
"rec": "تسجيل",
"saveLocalRecording": "حفظ ملف التسجيل محليا",
@@ -938,7 +926,6 @@
"insecureRoomNameWarning": "اسم الغرفة غير آمن، فقد ينضم عبره مشاركون غرباء إلى المُلتقى. ننصحك بتأمين المُلتقى عبر وسائل الحماية التي يوفرها زر الحماية."
},
"settings": {
"buttonLabel": "إعدادات",
"calendar": {
"about": "تُستعمَل الرزنامة {{appName}} المدمجة للوصل بأمان إلى رزنامتك، لذا بالإمكان معرفة الأحداث القادمة.",
"disconnect": "قطع الاتصال",
@@ -962,7 +949,6 @@
"name": "الاسم",
"noDevice": "لا يوجد",
"participantJoined": "انضم مشارك",
"participantKnocking": "دخل المشارك في الردهة",
"participantLeft": "غادر المشارك",
"playSounds": "تشغيل الصوت عند:",
"reactions": "ردود فعل المُلتقى",
@@ -995,17 +981,12 @@
"displayName": "عرض الاسم",
"displayNamePlaceholderText": "على سبيل المثال: علي الحيدري",
"email": "البريد الإلكتروني",
"goTo": "اذهب إلى",
"header": "الإعدادات",
"help": "مساعدة",
"links": "روابط",
"privacy": "خصوصية",
"profileSection": "الملف الشخصي",
"serverURL": "رابط المُخدِّم",
"showAdvanced": "أظهِر الإعدادات المتقدمة",
"startWithAudioMuted": "بدء الجميع مكتومي الصوت",
"startWithVideoMuted": "بدء الجميع دون فيديو",
"terms": "شروط",
"version": "الإصدار"
},
"share": {
@@ -1043,7 +1024,6 @@
"termsView": {
"header": "مصطلحات"
},
"toggleTopPanelLabel": "تبديل اللوحة العلوية",
"toolbar": {
"Settings": "الإعدادات",
"accessibilityLabel": {
@@ -1085,7 +1065,6 @@
"muteEveryoneElse": "كتم صوت الآخرين",
"muteEveryoneElsesVideoStream": "وقّف فيديو أي شخص آخر",
"muteEveryonesVideoStream": "وقّف فيديو الجميع",
"noiseSuppression": "قمع الضوضاء",
"participants": "مشاركون",
"pip": "استعمل/اخرج من وضع صورة-في-صورة",
"privateMessage": "أرسل رسالة خاصة",
@@ -1126,7 +1105,6 @@
"clap": "تصفيق",
"closeChat": "أغلق الدردشة",
"closeReactionsMenu": "إغلاق قائمة ردود الفعل",
"disableNoiseSuppression": "قم بتعطيل خاصية منع الضوضاء",
"disableReactionSounds": "يمكنك تعطيل أصوات ردود الفعل لهذا المُلتقى",
"dock": "إرساء في النافذة الرئيسية",
"documentClose": "أغلق الملف المشارك",
@@ -1163,7 +1141,6 @@
"noAudioSignalDialInDesc": "يمكن أيضًا الاتصال باستعمال:",
"noAudioSignalDialInLinkDesc": "أرقام الاتصال",
"noAudioSignalTitle": "لا يصلنا شيئًا من المجهار (المايكروفون) الخاص بك",
"noiseSuppression": "قمع الضوضاء",
"noisyAudioInputDesc": "يبدو أنَّ المجهار (المايكروفون) لديك يصدر الكثير من الضجة، اكتمه رجاءً أو استعمل مجهارًا آخر.",
"noisyAudioInputTitle": "يبدو أنَّ المجهار (المايكروفون) لديك يصدر الكثير من الضجة!",
"openChat": "فتح الدرشة",

View File

@@ -40,6 +40,9 @@
"audioOnly": {
"audioOnly": "Geringe Bandbreite"
},
"blankPage": {
"meetingEnded": "Konferenz beendet."
},
"breakoutRooms": {
"actions": {
"add": "Breakout-Raum hinzufügen",
@@ -77,17 +80,6 @@
"refresh": "Kalender aktualisieren",
"today": "Heute"
},
"carmode": {
"actions": {
"leaveMeeting": "Konferenz verlassen",
"selectSoundDevice": "Audiogerät auswählen"
},
"labels": {
"buttonLabel": "Automodus",
"title": "Automodus",
"videoStopped": "Ihre Kamera ist deaktiviert"
}
},
"chat": {
"enter": "Chat-Raum betreten",
"error": "Fehler: Ihre Nachricht wurde nicht versendet. Grund: {{error}}",
@@ -116,7 +108,6 @@
},
"chromeExtensionBanner": {
"buttonText": "Chrome-Erweiterung installieren",
"buttonTextEdge": "Edge-Erweiterung installieren",
"close": "Schließen",
"dontShowAgain": "Hinweis nicht mehr anzeigen",
"installExtensionText": "Installieren Sie die Erweiterung für die Integration von Google Calendar und Office 365"
@@ -208,9 +199,6 @@
"selectADevice": "Ein Gerät wählen",
"testAudio": "Prüfton wiedergeben"
},
"dialIn": {
"screenTitle": "Einwahldaten"
},
"dialOut": {
"statusMessage": "ist jetzt {{status}}"
},
@@ -661,8 +649,6 @@
"linkToSalesforceKey": "Konferenz verlinken",
"linkToSalesforceProgress": "Konferenz wird mit Salesforce verlinkt...",
"linkToSalesforceSuccess": "Die Konferenz wurde mit Salesforce verlinkt",
"localRecordingStarted": "{{name}} hat eine lokale Aufzeichnung gestartet.",
"localRecordingStopped": "{{name}} hat eine lokale Aufzeichnung gestoppt.",
"me": "Ich",
"moderationInEffectCSDescription": "Bitte melden um ein Video zu teilen",
"moderationInEffectCSTitle": "Die Videofreigabe ist von der Moderation gesperrt",
@@ -683,10 +669,6 @@
"newDeviceAction": "Verwenden",
"newDeviceAudioTitle": "Neues Audiogerät erkannt",
"newDeviceCameraTitle": "Neue Kamera erkannt",
"noiseSuppressionDesktopAudioDescription": "Die Rauschunterdrückung kann nicht genutzt werden, wenn der Computersound geteilt wird, bitte zuerst deaktivieren und dann nochmals versuchen.",
"noiseSuppressionFailedTitle": "Rauschunterdrückung konnte nicht gestartet werden",
"noiseSuppressionNoTrackDescription": "Bitte eigenes Mikrofon zuerst aktivieren.",
"noiseSuppressionStereoDescription": "Rauschunterdrückung unterstützt aktuell keinen Stereoton.",
"oldElectronClientDescription1": "Sie scheinen eine alte Version des Jitsi-Meet-Clients zu nutzen. Diese hat bekannte Schwachstellen. Bitte aktualisieren Sie auf unsere ",
"oldElectronClientDescription2": "aktuelle Version",
"oldElectronClientDescription3": "!",
@@ -822,7 +804,6 @@
"initiated": "Anruf gestartet",
"joinAudioByPhone": "Per Telefon teilnehmen",
"joinMeeting": "Konferenz beitreten",
"joinMeetingInLowBandwidthMode": "Konferenz im Datensparmodus beitreten",
"joinWithoutAudio": "Ohne Ton beitreten",
"keyboardShortcuts": "Tastaturkurzbefehle aktivieren",
"linkCopied": "Link in die Zwischenablage kopiert",
@@ -898,23 +879,13 @@
"limitNotificationDescriptionWeb": "Wegen hoher Nachfrage ist Ihre Aufnahme auf {{limit}} Min. begrenzt. Für unlimitierte Aufnahmen nutzen Sie bitte <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Link zur Aufzeichnung wurde generiert.",
"live": "LIVE",
"localRecordingNoNotificationWarning": "Die Aufzeichnung wird anderen Anwesenden nicht mitgeteilt. Sie müssen diese selbst darauf hinweisen, dass die Konferenz aufgezeichnet wird.",
"localRecordingNoVideo": "Videos werden nicht aufgenommen",
"localRecordingStartWarning": "Bitte beenden Sie die Aufzeichnung vor dem Verlassen der Konferenz, um die Aufzeichnung zu speichern.",
"localRecordingStartWarningTitle": "Aufzeichnung zum Speichern beenden",
"localRecordingVideoStop": "Wenn Sie ihre Kamera abschalten wird auch die Aufnahme beendet. Sind Sie sicher, dass Sie fortfahren möchten?",
"localRecordingVideoWarning": "Um Ihr eigenes Kamerabild aufzuzeichnen, müssen Sie Ihre Kamera beim Start der Aufnahme einschalten",
"localRecordingWarning": "Bitte prüfen Sie, dass das aktuelle Tab auswählen, um Bild und Ton aufzuzeichnen. Die Länge der Aufzeichnung ist aktuell auf 1GB beschränkt, was ungefähr 100 Minuten entspricht.",
"loggedIn": "Als {{userName}} angemeldet",
"noStreams": "Kein Ton oder Video erkannt.",
"off": "Aufnahme gestoppt",
"offBy": "{{name}} stoppte die Aufnahme",
"on": "Aufnahme",
"onBy": "{{name}} startete die Aufnahme",
"onlyRecordSelf": "Nur eigenes Kamerabild und Ton aufzeichnen",
"pending": "Aufzeichnung des Meetings wird vorbereitet…",
"rec": "AUFZ",
"saveLocalRecording": "Aufzeichnung lokal abspeichern",
"serviceDescription": "Ihre Aufzeichnung wird vom Aufzeichnungsdienst gespeichert",
"serviceDescriptionCloud": "Cloud-Aufzeichnung",
"serviceDescriptionCloudInfo": "Aufzeichnungen werden 24 Stunden nach Aufzeichnungsende automatisch gelöscht.",
@@ -922,12 +893,10 @@
"sessionAlreadyActive": "Diese Konferenz wird bereits aufgezeichnet.",
"signIn": "Anmelden",
"signOut": "Abmelden",
"surfaceError": "Bitte das aktuelle Tab auswählen.",
"unavailable": "Oh! Der {{serviceName}} ist aktuell nicht verfügbar. Wir arbeiten an der Behebung des Problems. Bitte versuchen Sie es später noch einmal.",
"unavailableTitle": "Aufnahme nicht verfügbar",
"uploadToCloud": "In die Cloud hochladen"
},
"screenshareDisplayName": "{{name}}s Bildschirmfreigabe",
"sectionList": {
"pullToRefresh": "Ziehen, um zu aktualisieren"
},
@@ -961,12 +930,10 @@
"name": "Name",
"noDevice": "Kein",
"participantJoined": "Neue Person nimmt teil",
"participantKnocking": "Person hat Lobby betreten",
"participantLeft": "Person verlässt die Konferenz",
"playSounds": "Hinweistöne aktiviert",
"reactions": "Interaktionen",
"sameAsSystem": "Wie System ({{label}})",
"screenTitle": "Einstellungen",
"selectAudioOutput": "Audioausgabe",
"selectCamera": "Kamera",
"selectMic": "Mikrofon",
@@ -992,7 +959,6 @@
"disableCrashReportingWarning": "Möchten Sie die Absturzberichte wirklich deaktivieren? Diese Einstellung wird nach einem Neustart der App wirksam.",
"disableP2P": "Ende-zu-Ende-Modus deaktivieren",
"displayName": "Anzeigename",
"displayNamePlaceholderText": "z.B. Erika Musterfrau",
"email": "E-Mail",
"header": "Einstellungen",
"profileSection": "Profil",
@@ -1037,7 +1003,6 @@
"termsView": {
"header": "Nutzungsbedingungen"
},
"toggleTopPanelLabel": "Obere Leiste ein-/ausschalten",
"toolbar": {
"Settings": "Einstellungen",
"accessibilityLabel": {
@@ -1047,12 +1012,10 @@
"boo": "Buhen",
"breakoutRoom": "Breakout-Räume betreten/verlassen",
"callQuality": "Qualitätseinstellungen",
"carmode": "Automodus",
"cc": "Untertitel ein-/ausschalten",
"chat": "Chatfenster öffnen / schließen",
"clap": "Klatschen",
"collapse": "Einklappen",
"dock": "In Hauptfenster einbinden",
"document": "Geteiltes Dokument schließen",
"download": "Unsere Apps herunterladen",
"embedMeeting": "Konferenz einbetten",
@@ -1079,7 +1042,6 @@
"muteEveryoneElse": "Alle anderen stummschalten",
"muteEveryoneElsesVideoStream": "Alle anderen Kameras ausschalten",
"muteEveryonesVideoStream": "Alle Kameras ausschalten",
"noiseSuppression": "Rauschunterdrückung",
"participants": "Anwesende",
"pip": "Bild-in-Bild-Modus ein-/ausschalten",
"privateMessage": "Private Nachricht senden",
@@ -1104,7 +1066,6 @@
"tileView": "Kachelansicht ein-/ausschalten",
"toggleCamera": "Kamera wechseln",
"toggleFilmstrip": "Miniaturansichten ein-/ausschalten",
"undock": "In eigenem Fenster anzeigen",
"videoblur": "Unscharfer Hintergrund ein-/ausschalten",
"videomute": "„Video stummschalten“ ein-/ausschalten"
},
@@ -1120,9 +1081,7 @@
"clap": "Klatschen",
"closeChat": "Chat schließen",
"closeReactionsMenu": "Interaktionsmenü schließen",
"disableNoiseSuppression": "Rauschunterdrückung deaktivieren",
"disableReactionSounds": "Sie können die Interaktionstöne für diese Konferenz deaktivieren",
"dock": "In Hauptfenster einbinden",
"documentClose": "Geteiltes Dokument schließen",
"documentOpen": "Geteiltes Dokument öffnen",
"download": "Unsere Apps herunterladen",
@@ -1157,7 +1116,6 @@
"noAudioSignalDialInDesc": "Sie können sich auch über die Einwahlnummer einwählen:",
"noAudioSignalDialInLinkDesc": "Einwahlnummern",
"noAudioSignalTitle": "Es kommt kein Input von Ihrem Mikrofon!",
"noiseSuppression": "Rauschunterdrückung",
"noisyAudioInputDesc": "Es klingt, als ob Ihr Mikrofon Störgeräusche verursacht. Bitte überlegen Sie, ob Sie das Gerät stummschalten oder austauschen wollen.",
"noisyAudioInputTitle": "Ihr Mikrofon scheint lärmintensiv zu sein!",
"openChat": "Chat öffnen",
@@ -1192,7 +1150,6 @@
"talkWhileMutedPopup": "Versuchen Sie zu sprechen? Ihr Mikrofon ist stummgeschaltet.",
"tileViewToggle": "Kachelansicht ein-/ausschalten",
"toggleCamera": "Kamera wechseln",
"undock": "In eigenem Fenster anzeigen",
"videoSettings": "Kameraeinstellungen",
"videomute": "Kamera starten / stoppen"
},

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -518,10 +518,6 @@
"toggleShortcuts": "Mostrar ou ocultar atalhos de teclado",
"videoMute": "Iniciar ou parar a sua câmara"
},
"largeVideo": {
"screenIsShared": "Está a partilhar o seu ecrã",
"showMeWhatImSharing": "Mostre-me o que estou a partilhar"
},
"liveStreaming": {
"busy": "Estamos trabalhando para liberar os recursos de transmissão. Tente novamente em alguns minutos.",
"busyTitle": "Todas as transmissões estão atualmente ocupadas",
@@ -687,10 +683,6 @@
"newDeviceAction": "Usar",
"newDeviceAudioTitle": "Novo dispositivo de áudio detetado",
"newDeviceCameraTitle": "Nova câmara detetada",
"noiseSuppressionDesktopAudioDescription": "A supressão de ruído não pode ser ativada enquanto se partilha o áudio do ambiente de trabalho, por favor desative-o e tente novamente.",
"noiseSuppressionFailedTitle": "Falha ao iniciar a supressão de ruído",
"noiseSuppressionNoTrackDescription": "Por favor, ligue primeiro o seu microfone.",
"noiseSuppressionStereoDescription": "A supressão do ruído de áudio estéreo não é atualmente suportada.",
"oldElectronClientDescription1": "Parece estar a utilizar uma versão antiga do cliente Jitsi Meet que tem vulnerabilidades de segurança conhecidas. Por favor, certifique-se de que actualiza a nossa ",
"oldElectronClientDescription2": "compilação mais recente",
"oldElectronClientDescription3": " agora!",
@@ -708,7 +700,7 @@
"selfViewTitle": "Pode sempre reexibir a autovisualização a partir das definições",
"somebody": "Alguém",
"startSilentDescription": "Volte à reunião para habilitar o áudio",
"startSilentTitle": "Entrou sem áudio!",
"startSilentTitle": "Entrou sem saída de áudio!",
"suboptimalBrowserWarning": "Tememos que sua experiência de reunião não seja tão boa aqui. Estamos procurando maneiras de melhorar isso, mas até então, tente usar um dos <a href='{{recommendedBrowserPageLink}}' target='_blank'>navegadores completamente suportados</a>.",
"suboptimalExperienceTitle": "Alerta do navegador",
"unmute": "Ativar som",
@@ -902,23 +894,15 @@
"limitNotificationDescriptionWeb": "Devido à grande procura, a sua gravação será limitada a {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
"linkGenerated": "Gerámos um link para a sua gravação.",
"live": "DIRETO",
"localRecordingNoNotificationWarning": "A gravação não será anunciada aos outros participantes. Será necessário avisá-los de que a reunião está gravada.",
"localRecordingNoVideo": "O vídeo não está a ser gravado",
"localRecordingStartWarning": "Por favor, certifique-se de que pára a gravação antes de sair da reunião a fim de a guardar.",
"localRecordingStartWarningTitle": "Parar a gravação para a salvar",
"localRecordingVideoStop": "A paragem do seu vídeo também irá parar a gravação local. Tem a certeza de que quer continuar?",
"localRecordingVideoWarning": "Para gravar o seu vídeo deve tê-lo ligado quando iniciar a gravação",
"localRecordingWarning": "Certifique-se de selecionar o separador actual a fim de utilizar o vídeo e áudio corretos. A gravação está actualmente limitada a 1 GB, o que é cerca de 100 minutos.",
"localRecordingWarning": "Certifique-se de seleccionar o separador actual a fim de utilizar o vídeo e áudio correctos. A gravação está actualmente limitada a 1 GB, o que é cerca de 100 minutos.",
"loggedIn": "Conectado como {{userName}}",
"noStreams": "Não foi detetado nenhum sinal áudio ou vídeo.",
"off": "Gravação parada",
"offBy": "{{name}} parou a gravação",
"on": "Gravando",
"onBy": "{{name}} iniciou a gravação",
"onlyRecordSelf": "Gravar apenas as minhas transmissões áudio e vídeo",
"pending": "Preparando para gravar a reunião...",
"rec": "REC",
"saveLocalRecording": "Guardar ficheiro de gravação localmente (Beta)",
"saveLocalRecording": "Guardar ficheiro de gravação localmente",
"serviceDescription": "Sua gravação será salva pelo serviço de gravação",
"serviceDescriptionCloud": "Gravação na nuvem",
"serviceDescriptionCloudInfo": "As reuniões gravadas são automaticamente apagadas 24h após a hora de gravação.",
@@ -931,7 +915,7 @@
"unavailableTitle": "Gravação indisponível",
"uploadToCloud": "Enviar para a nuvem"
},
"screenshareDisplayName": "Ecrã do/a {{name}}",
"screenshareDisplayName": "Ecrã de {{name}}",
"sectionList": {
"pullToRefresh": "Puxe para atualizar"
},
@@ -942,7 +926,6 @@
"insecureRoomNameWarning": "O nome da sala é inseguro. Participantes indesejados podem juntar-se à sua conferência. Considere proteger a sua reunião utilizando o botão de segurança."
},
"settings": {
"buttonLabel": "Definições",
"calendar": {
"about": "A integração do calendário {{appName}} é utilizada para aceder com segurança ao seu calendário para que este possa ler os próximos eventos.",
"disconnect": "Desligar",
@@ -966,7 +949,6 @@
"name": "Nome",
"noDevice": "Nenhum",
"participantJoined": "Entrar um participante",
"participantKnocking": "Entrar um participante na sala de espera",
"participantLeft": "Sair um participante",
"playSounds": "Reproduzir som quando",
"reactions": "Expressarem uma reação",
@@ -999,17 +981,12 @@
"displayName": "Nome de exibição",
"displayNamePlaceholderText": "Ex: João Dias",
"email": "Email",
"goTo": "Ir para",
"header": "Configurações",
"help": "Ajuda",
"links": "Links",
"privacy": "Privacidade",
"profileSection": "Perfil",
"serverURL": "URL do servidor",
"showAdvanced": "",
"startWithAudioMuted": "Iniciar sem áudio",
"startWithVideoMuted": "Iniciar sem vídeo",
"terms": "Termos",
"version": "Versão"
},
"share": {
@@ -1047,7 +1024,6 @@
"termsView": {
"header": "Termos"
},
"toggleTopPanelLabel": "Mostrar ou ocultar o painel superior",
"toolbar": {
"Settings": "Definições",
"accessibilityLabel": {
@@ -1062,7 +1038,7 @@
"chat": "Abrir / Fechar chat",
"clap": "Aplausos",
"collapse": "Colapsar",
"dock": "Ancorar na janela principal",
"dock": "Encaixar na janela principal",
"document": "Mudar para documento partilhado",
"download": "Descarregar as nossas aplicações",
"embedMeeting": "Reunião incorporada",
@@ -1089,7 +1065,6 @@
"muteEveryoneElse": "Silenciar todos os outros",
"muteEveryoneElsesVideo": "Parar o vídeo de todos os outros",
"muteEveryonesVideo": "Parar o vídeo de todos",
"noiseSuppression": "Supressão de ruído",
"participants": "Participantes",
"pip": "Mudar para o modo Picture-in-Picture",
"privateMessage": "Enviar mensagem privada",
@@ -1114,7 +1089,7 @@
"tileView": "Mudar a vista em quadrícula",
"toggleCamera": "Mudar a câmara",
"toggleFilmstrip": "Mudar a película de filme",
"undock": "Desancorar numa janela separada",
"undock": "Soltar numa janela separada",
"videoblur": "Mudar o desfoque de vídeo",
"videomute": "Iniciar / Parar câmara"
},
@@ -1130,9 +1105,8 @@
"clap": "Aplausos",
"closeChat": "Fechar chat",
"closeReactionsMenu": "Fechar menu de reações",
"disableNoiseSuppression": "Desativar a supressão de ruído",
"disableReactionSounds": "Pode desactivar os sons de reacção para esta reunião",
"dock": "Ancorar na janela principal",
"dock": "Encaixar na janela principal",
"documentClose": "Fechar documento partilhado",
"documentOpen": "Abrir documento partilhado",
"download": "Descarregar as nossas aplicações",
@@ -1167,7 +1141,6 @@
"noAudioSignalDialInDesc": "Também pode marcar usando:",
"noAudioSignalDialInLinkDesc": "Números de marcação",
"noAudioSignalTitle": "Não há nenhuma entrada vinda do seu microfone!",
"noiseSuppression": "Supressão de ruído",
"noisyAudioInputDesc": "Parece que o seu microfone está a fazer barulho, por favor considere silenciar ou mudar de dispositivo.",
"noisyAudioInputTitle": "Seu microfone parece estar barulhento!",
"openChat": "Abrir chat",
@@ -1202,7 +1175,7 @@
"talkWhileMutedPopup": "Está a tentar falar? Está com o microfone desativado.",
"tileViewToggle": "Mudar para vista em quadrícula",
"toggleCamera": "Mudar a câmara",
"undock": "Desancorar numa janela separada",
"undock": "Soltar numa janela separada",
"videoSettings": "Definições de vídeo",
"videomute": "Iniciar / Parar câmara"
},

View File

@@ -652,7 +652,7 @@
"moderationInEffectTitle": "Ваш микрофон отключен модератором",
"moderationInEffectVideoDescription": "Пожалуйста, поднимите руку, если хотите включить камеру.",
"moderationInEffectVideoTitle": "Ваша камера заблокирована модератором",
"moderationRequestFromModerator": "Модератор хочет, чтобы вы включили звук",
"moderationRequestFromModerator": "Хозяин хочет, чтобы вы включили звук",
"moderationRequestFromParticipant": "Хочет говорить",
"moderationStartedTitle": "Началась модерация",
"moderationStoppedTitle": "Модерация остановлена",

View File

@@ -11,6 +11,7 @@
"defaultEmail": "Your Default Email",
"disabled": "You can't invite people.",
"failedToAdd": "Failed to add participants",
"footerText": "Dialing out is disabled.",
"googleEmail": "Google Email",
"inviteMoreHeader": "You are the only one in the meeting",
"inviteMoreMailSubject": "Join {{appName}} meeting",
@@ -285,6 +286,7 @@
"linkMeetingTitle": "Link meeting to Salesforce",
"liveStreaming": "Live Streaming",
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Not possible while recording is active",
"liveStreamingDisabledTooltip": "Start live stream disabled.",
"localUserControls": "Local user controls",
"lockMessage": "Failed to lock the conference.",
"lockRoom": "Add meeting $t(lockRoomPassword)",
@@ -339,6 +341,7 @@
"recentlyUsedObjects": "Your recently used objects",
"recording": "Recording",
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Not possible while a live stream is active",
"recordingDisabledTooltip": "Start recording disabled.",
"rejoinNow": "Rejoin now",
"remoteControlAllowedMessage": "{{user}} accepted your remote control request!",
"remoteControlDeniedMessage": "{{user}} rejected your remote control request!",
@@ -515,10 +518,6 @@
"toggleShortcuts": "Show or hide keyboard shortcuts",
"videoMute": "Start or stop your camera"
},
"largeVideo": {
"screenIsShared": "You are sharing your screen",
"showMeWhatImSharing": "Show me what I'm sharing"
},
"liveStreaming": {
"busy": "We're working on freeing streaming resources. Please try again in a few minutes.",
"busyTitle": "All streamers are currently busy",
@@ -684,10 +683,6 @@
"newDeviceAction": "Use",
"newDeviceAudioTitle": "New audio device detected",
"newDeviceCameraTitle": "New camera detected",
"noiseSuppressionDesktopAudioDescription": "Noise suppression can't be enabled while sharing desktop audio, please disable it and try again.",
"noiseSuppressionFailedTitle": "Failed to start noise suppression",
"noiseSuppressionNoTrackDescription": "Please unmute your microphone first.",
"noiseSuppressionStereoDescription": "Stereo audio noise suppression is not currently supported.",
"oldElectronClientDescription1": "You appear to be using an old version of the Jitsi Meet client which has known security vulnerabilities. Please make sure you update to our ",
"oldElectronClientDescription2": "latest build",
"oldElectronClientDescription3": " now!",
@@ -900,22 +895,15 @@
"linkGenerated": "We have generated a link to your recording.",
"live": "LIVE",
"localRecordingNoNotificationWarning": "The recording will not be announced to other participants. You will need to let them know that the meeting is recorded.",
"localRecordingNoVideo": "Video is not being recorded",
"localRecordingStartWarning": "Please make sure you stop the recording before exiting the meeting in order to save it.",
"localRecordingStartWarningTitle": "Stop the recording to save it",
"localRecordingVideoStop": "Stopping your video will also stop the local recording. Are you sure you want to continue?",
"localRecordingVideoWarning": "To record your video you must have it on when starting the recording",
"localRecordingWarning": "Make sure you select the current tab in order to use the right video and audio. The recording is currently limited to 1GB, which is around 100 minutes.",
"loggedIn": "Logged in as {{userName}}",
"noStreams": "No audio or video stream detected.",
"off": "Recording stopped",
"offBy": "{{name}} stopped the recording",
"on": "Recording started",
"onBy": "{{name}} started the recording",
"onlyRecordSelf": "Record only my audio and video streams",
"pending": "Preparing to record the meeting...",
"rec": "REC",
"saveLocalRecording": "Save recording file locally (Beta)",
"saveLocalRecording": "Save recording file locally",
"serviceDescription": "Your recording will be saved by the recording service",
"serviceDescriptionCloud": "Cloud recording",
"serviceDescriptionCloudInfo": "Recorded meetings are automatically cleared 24h after their recording time.",
@@ -939,7 +927,6 @@
"insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button."
},
"settings": {
"buttonLabel": "Settings",
"calendar": {
"about": "The {{appName}} calendar integration is used to securely access your calendar so it can read upcoming events.",
"disconnect": "Disconnect",
@@ -963,7 +950,6 @@
"name": "Name",
"noDevice": "None",
"participantJoined": "Participant Joined",
"participantKnocking": "Participant entered lobby",
"participantLeft": "Participant Left",
"playSounds": "Play sound on",
"reactions": "Meeting reactions",
@@ -996,17 +982,12 @@
"displayName": "Display name",
"displayNamePlaceholderText": "Eg: John Doe",
"email": "Email",
"goTo": "Go to",
"header": "Settings",
"help": "Help",
"links": "Links",
"privacy": "Privacy",
"profileSection": "Profile",
"serverURL": "Server URL",
"showAdvanced": "Show advanced settings",
"startWithAudioMuted": "Start with audio muted",
"startWithVideoMuted": "Start with video muted",
"terms": "Terms",
"version": "Version"
},
"share": {
@@ -1044,7 +1025,6 @@
"termsView": {
"header": "Terms"
},
"toggleTopPanelLabel": "Toggle top panel",
"toolbar": {
"Settings": "Settings",
"accessibilityLabel": {
@@ -1086,7 +1066,6 @@
"muteEveryoneElse": "Mute everyone else",
"muteEveryoneElsesVideoStream": "Stop everyone else's video",
"muteEveryonesVideoStream": "Stop everyone's video",
"noiseSuppression": "Noise suppression",
"participants": "Participants",
"pip": "Toggle Picture-in-Picture mode",
"privateMessage": "Send private message",
@@ -1127,7 +1106,6 @@
"clap": "Clap",
"closeChat": "Close chat",
"closeReactionsMenu": "Close reactions menu",
"disableNoiseSuppression": "Disable noise suppression",
"disableReactionSounds": "You can disable reaction sounds for this meeting",
"dock": "Dock in main window",
"documentClose": "Close shared document",
@@ -1164,7 +1142,6 @@
"noAudioSignalDialInDesc": "You can also dial-in using:",
"noAudioSignalDialInLinkDesc": "Dial-in numbers",
"noAudioSignalTitle": "There is no input coming from your mic!",
"noiseSuppression": "Noise suppression",
"noisyAudioInputDesc": "It sounds like your microphone is making noise, please consider muting or changing the device.",
"noisyAudioInputTitle": "Your microphone appears to be noisy!",
"openChat": "Open chat",

26
logging_config.js Normal file
View File

@@ -0,0 +1,26 @@
/* eslint-disable no-unused-vars, no-var */
// Logging configuration
var loggingConfig = {
// default log level for the app and lib-jitsi-meet
defaultLogLevel: 'trace',
// Option to disable LogCollector (which stores the logs on CallStats)
// disableLogCollector: true,
// The following are too verbose in their logging with the
// {@link #defaultLogLevel}:
'modules/RTC/TraceablePeerConnection.js': 'info',
'modules/statistics/CallStats.js': 'info',
'modules/xmpp/strophe.util.js': 'log'
};
/* eslint-enable no-unused-vars, no-var */
// XXX Web/React server-includes logging_config.js into index.html.
// Mobile/react-native requires it in react/features/base/logging. For the
// purposes of the latter, (try to) export loggingConfig. The following
// detection of a module system is inspired by webpack.
typeof module === 'object'
&& typeof exports === 'object'
&& (module.exports = loggingConfig);

View File

@@ -75,13 +75,6 @@ import {
resizeLargeVideo
} from '../../react/features/large-video/actions.web';
import { toggleLobbyMode, answerKnockingParticipant } from '../../react/features/lobby/actions';
import { setNoiseSuppressionEnabled } from '../../react/features/noise-suppression/actions';
import {
hideNotification,
NOTIFICATION_TIMEOUT_TYPE,
NOTIFICATION_TYPE,
showNotification
} from '../../react/features/notifications';
import {
close as closeParticipantsPane,
open as openParticipantsPane
@@ -381,9 +374,6 @@ function initCommands() {
sendAnalytics(createApiEvent('screen.sharing.toggled'));
toggleScreenSharing(options.enable);
},
'set-noise-suppression-enabled': (options = {}) => {
APP.store.dispatch(setNoiseSuppressionEnabled(options.enabled));
},
'toggle-subtitles': () => {
APP.store.dispatch(toggleRequestingSubtitles());
},
@@ -473,58 +463,6 @@ function initCommands() {
APP.store.dispatch(stopSharedVideo());
},
/**
* Shows a custom in-meeting notification.
*
* @param { string } arg.title - Notification title.
* @param { string } arg.description - Notification description.
* @param { string } arg.uid - Optional unique identifier for the notification.
* @param { string } arg.type - Notification type, either `error`, `info`, `normal`, `success` or `warning`.
* Defaults to "normal" if not provided.
* @param { string } arg.timeout - Timeout type, either `short`, `medium`, `long` or `sticky`.
* Defaults to "short" if not provided.
* @returns {void}
*/
'show-notification': ({
title,
description,
uid,
type = NOTIFICATION_TYPE.NORMAL,
timeout = NOTIFICATION_TIMEOUT_TYPE.SHORT
}) => {
const validTypes = Object.values(NOTIFICATION_TYPE);
const validTimeouts = Object.values(NOTIFICATION_TIMEOUT_TYPE);
if (!validTypes.includes(type)) {
logger.error(`Invalid notification type "${type}". Expecting one of ${validTypes}`);
return;
}
if (!validTimeouts.includes(timeout)) {
logger.error(`Invalid notification timeout "${timeout}". Expecting one of ${validTimeouts}`);
return;
}
APP.store.dispatch(showNotification({
uid,
title,
description,
appearance: type
}, timeout));
},
/**
* Removes a notification given a unique identifier.
*
* @param { string } uid - Unique identifier for the notification to be removed.
* @returns {void}
*/
'hide-notification': uid => {
APP.store.dispatch(hideNotification(uid));
},
/**
* Starts a file recording or streaming session depending on the passed on params.
* For RTMP streams, `rtmpStreamKey` must be passed on. `rtmpBroadcastID` is optional.
@@ -536,11 +474,11 @@ function initCommands() {
* @param { string } arg.mode - Recording mode, either `file` or `stream`.
* @param { string } arg.dropboxToken - Dropbox oauth2 token.
* @param { string } arg.rtmpStreamKey - The RTMP stream key.
* @param { string } arg.rtmpBroadcastID - The RTMP broadcast ID.
* @param { string } arg.rtmpBroadcastID - The RTMP braodcast ID.
* @param { boolean } arg.shouldShare - Whether the recording should be shared with the participants or not.
* Only applies to certain jitsi meet deploys.
* @param { string } arg.youtubeStreamKey - The youtube stream key.
* @param { string } arg.youtubeBroadcastID - The youtube broadcast ID.
* @param { string } arg.youtubeBroadcastID - The youtube broacast ID.
* @returns {void}
*/
'start-recording': ({
@@ -1661,7 +1599,7 @@ class API {
* Notify external application (if API is enabled) that recording has started or stopped.
*
* @param {boolean} on - True if recording is on, false otherwise.
* @param {string} mode - Stream or file or local.
* @param {string} mode - Stream or file.
* @param {string} error - Error type or null if success.
* @returns {void}
*/
@@ -1704,7 +1642,7 @@ class API {
}
/**
* Notify external application (if API is enabled) that an error occurred.
* Notify external application (if API is enabled) that an error occured.
*
* @param {Object} error - The error.
* @returns {void}
@@ -1732,7 +1670,7 @@ class API {
}
/**
* Notify external application (if API is enabled) whether the used browser is supported or not.
* Notify external application (if API is enabled) wether the used browser is supported or not.
*
* @param {boolean} supported - If browser is supported or not.
* @returns {void}
@@ -1760,7 +1698,7 @@ class API {
/**
* Notify the external application that the state of the participants pane changed.
*
* @param {boolean} open - Whether the panel is open or not.
* @param {boolean} open - Wether the panel is open or not.
* @returns {void}
*/
notifyParticipantsPaneToggled(open) {

View File

@@ -40,7 +40,6 @@ const commands = {
email: 'email',
grantModerator: 'grant-moderator',
hangup: 'video-hangup',
hideNotification: 'hide-notification',
initiatePrivateChat: 'initiate-private-chat',
joinBreakoutRoom: 'join-breakout-room',
localSubject: 'local-subject',
@@ -60,12 +59,10 @@ const commands = {
setFollowMe: 'set-follow-me',
setLargeVideoParticipant: 'set-large-video-participant',
setMediaEncryptionKey: 'set-media-encryption-key',
setNoiseSuppressionEnabled: 'set-noise-suppression-enabled',
setParticipantVolume: 'set-participant-volume',
setSubtitles: 'set-subtitles',
setTileView: 'set-tile-view',
setVideoQuality: 'set-video-quality',
showNotification: 'show-notification',
startRecording: 'start-recording',
startShareVideo: 'start-share-video',
stopRecording: 'stop-recording',
@@ -80,9 +77,9 @@ const commands = {
toggleFilmStrip: 'toggle-film-strip',
toggleLobby: 'toggle-lobby',
toggleModeration: 'toggle-moderation',
toggleNoiseSuppression: 'toggle-noise-suppression',
toggleParticipantsPane: 'toggle-participants-pane',
toggleRaiseHand: 'toggle-raise-hand',
toggleShareAudio: 'toggle-share-audio',
toggleShareScreen: 'toggle-share-screen',
toggleSubtitles: 'toggle-subtitles',
toggleTileView: 'toggle-tile-view',
@@ -1003,7 +1000,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
}
/**
* Returns whether meeting is started silent.
* Returns wether meeting is started silent.
*
* @returns {Promise} - Resolves with start silent status.
*/
@@ -1245,9 +1242,9 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
* @param { boolean } options.shouldShare - Whether the recording should be shared with the participants or not.
* Only applies to certain jitsi meet deploys.
* @param { string } options.rtmpStreamKey - The RTMP stream key.
* @param { string } options.rtmpBroadcastID - The RTMP broadcast ID.
* @param { string } options.rtmpBroadcastID - The RTMP broacast ID.
* @param { string } options.youtubeStreamKey - The youtube stream key.
* @param { string } options.youtubeBroadcastID - The youtube broadcast ID.
* @param { string } options.youtubeBroadcastID - The youtube broacast ID.
* @returns {void}
*/
startRecording(options) {

View File

@@ -17,6 +17,7 @@ import {
import { getReplaceParticipant } from '../../../react/features/base/config/functions';
import { isDialogOpen } from '../../../react/features/base/dialog';
import { setJWT } from '../../../react/features/base/jwt';
import { setPrejoinPageVisibility } from '../../../react/features/prejoin';
import UIUtil from '../util/UIUtil';
import ExternalLoginDialog from './LoginDialog';
@@ -180,6 +181,7 @@ function authenticate(room: Object, lockPassword: string) {
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
doExternalAuth(room, lockPassword);
} else {
APP.store.dispatch(setPrejoinPageVisibility(false));
APP.store.dispatch(openLoginDialog());
}
}

View File

@@ -246,7 +246,7 @@ export default class LargeVideoManager {
this.newStreamData = null;
logger.debug(`Scheduled large video update for ${id}`);
logger.info(`hover in ${id}`);
this.state = videoType;
// eslint-disable-next-line no-shadow
const container = this.getCurrentContainer();
@@ -288,13 +288,12 @@ export default class LargeVideoManager {
this.videoTrack.jitsiTrack.getTrackStreamingStatus()));
}
}
const streamingStatusActive = isTrackStreamingStatusActive(videoTrack);
isVideoRenderable = !isVideoMuted
&& (APP.conference.isLocalId(id) || participant?.isLocalScreenShare || streamingStatusActive);
this.videoTrack?.jitsiTrack?.getVideoType() === VIDEO_TYPE.DESKTOP
&& logger.debug(`Remote track ${videoTrack?.jitsiTrack}, isVideoMuted=${isVideoMuted},`
+ ` streamingStatusActive=${streamingStatusActive}, isVideoRenderable=${isVideoRenderable}`);
isVideoRenderable = !isVideoMuted && (
APP.conference.isLocalId(id)
|| participant?.isLocalScreenShare
|| isTrackStreamingStatusActive(videoTrack)
);
} else {
isVideoRenderable = !isVideoMuted
&& (APP.conference.isLocalId(id) || isParticipantConnectionStatusActive(participant));

View File

@@ -480,7 +480,7 @@ export class VideoContainer extends LargeContainer {
*/
setStream(userID, stream, videoType) {
this.userId = userID;
if (this.stream === stream && !stream?.forceStreamToReattach) {
if (this.stream === stream) {
// Handles the use case for the remote participants when the
// videoType is received with delay after turning on/off the
// desktop sharing.
@@ -492,12 +492,8 @@ export class VideoContainer extends LargeContainer {
return;
}
if (stream?.forceStreamToReattach) {
delete stream.forceStreamToReattach;
}
// detach old stream
if (this.stream && this.$video[0]) {
if (this.stream) {
this.stream.detach(this.$video[0]);
}
@@ -508,20 +504,19 @@ export class VideoContainer extends LargeContainer {
return;
}
if (this.$video[0]) {
stream.attach(this.$video[0]);
stream.attach(this.$video[0]);
// Ensure large video gets play() called on it when a new stream is attached to it. This is necessary in the
// case of Safari as autoplay doesn't kick-in automatically on Safari 15 and newer versions.
browser.isWebKitBased() && this.$video[0].play();
// Ensure large video gets play() called on it when a new stream is attached to it. This is necessary in the
// case of Safari as autoplay doesn't kick-in automatically on Safari 15 and newer versions.
browser.isWebKitBased() && this.$video[0].play();
const flipX = stream.isLocal() && this.localFlipX && !this.isScreenSharing();
const flipX = stream.isLocal() && this.localFlipX && !this.isScreenSharing();
this.$video.css({
transform: flipX ? 'scaleX(-1)' : 'none'
});
this._updateBackground();
}
this.$video.css({
transform: flipX ? 'scaleX(-1)' : 'none'
});
this._updateBackground();
}
/**

View File

@@ -177,7 +177,7 @@ const VideoLayout = {
return largeVideo && largeVideo.id === id;
},
updateLargeVideo(id, forceUpdate, forceStreamToReattach = false) {
updateLargeVideo(id, forceUpdate) {
if (!largeVideo) {
return;
}
@@ -198,10 +198,6 @@ const VideoLayout = {
const videoStream = videoTrack?.jitsiTrack;
if (videoStream && forceStreamToReattach) {
videoStream.forceStreamToReattach = forceStreamToReattach;
}
if (isOnLarge && !forceUpdate
&& LargeVideoManager.isVideoContainer(currentContainerType)
&& videoStream) {
@@ -334,7 +330,7 @@ const VideoLayout = {
*/
_updateLargeVideoIfDisplayed(participantId, force = false) {
if (this.isCurrentlyOnLarge(participantId)) {
this.updateLargeVideo(participantId, force, false);
this.updateLargeVideo(participantId, force);
}
},

3969
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -16,25 +16,29 @@
"readmeFilename": "README.md",
"dependencies": {
"@amplitude/react-native": "2.7.0",
"@atlaskit/button": "15.1.4",
"@atlaskit/checkbox": "12.0.0",
"@atlaskit/dropdown-menu": "10.1.2",
"@atlaskit/field-text": "11.0.4",
"@atlaskit/field-text-area": "8.0.4",
"@atlaskit/flag": "14.1.0",
"@atlaskit/icon": "21.2.0",
"@atlaskit/inline-dialog": "13.0.9",
"@atlaskit/inline-message": "11.0.8",
"@atlaskit/lozenge": "10.1.1",
"@atlaskit/modal-dialog": "11.2.4",
"@atlaskit/multi-select": "15.0.5",
"@atlaskit/spinner": "15.0.6",
"@atlaskit/tabs": "12.1.2",
"@atlaskit/theme": "11.0.2",
"@atlaskit/toggle": "12.0.3",
"@atlaskit/tooltip": "17.1.2",
"@giphy/js-fetch-api": "4.1.2",
"@giphy/react-components": "5.6.0",
"@giphy/react-native-sdk": "1.7.0",
"@hapi/bourne": "2.0.0",
"@jitsi/js-utils": "2.0.3",
"@jitsi/js-utils": "2.0.0",
"@jitsi/logger": "2.0.0",
"@jitsi/rnnoise-wasm": "0.1.0",
"@jitsi/rtcstats": "9.2.0",
"@material-ui/core": "4.11.3",
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
@@ -46,14 +50,14 @@
"@react-native-google-signin/google-signin": "7.0.4",
"@react-native-masked-view/masked-view": "0.2.6",
"@react-navigation/bottom-tabs": "6.0.9",
"@react-navigation/drawer": "6.1.8",
"@react-navigation/elements": "1.2.1",
"@react-navigation/material-top-tabs": "6.0.6",
"@react-navigation/native": "6.0.6",
"@react-navigation/stack": "6.2.2",
"@react-navigation/native-stack": "6.6.2",
"@svgr/webpack": "4.3.2",
"@tensorflow/tfjs-backend-wasm": "3.13.0",
"@tensorflow/tfjs-core": "3.13.0",
"@types/audioworklet": "0.0.29",
"@vladmandic/human": "2.6.5",
"@vladmandic/human-models": "2.5.9",
"@xmldom/xmldom": "0.7.5",
@@ -75,11 +79,10 @@
"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/v1487.0.0+f3f922a8/lib-jitsi-meet.tgz",
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1457.0.0+ad75454f/lib-jitsi-meet.tgz",
"lodash": "4.17.21",
"moment": "2.29.4",
"moment": "2.29.2",
"moment-duration-format": "2.2.2",
"null-loader": "4.0.1",
"optional-require": "1.0.3",
"promise.allsettled": "1.0.4",
"punycode": "2.1.1",
@@ -104,16 +107,17 @@
"react-native-pager-view": "5.4.9",
"react-native-paper": "4.11.1",
"react-native-performance": "2.1.0",
"react-native-reanimated": "https://git@github.com/software-mansion/react-native-reanimated#c4a6b6f687ede090f6081064abe83a2ef9a05784",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "3.13.1",
"react-native-screens": "3.10.1",
"react-native-sound": "0.11.1",
"react-native-splash-screen": "3.3.0",
"react-native-svg": "12.4.3",
"react-native-svg": "12.1.0",
"react-native-svg-transformer": "1.0.0",
"react-native-tab-view": "3.1.1",
"react-native-url-polyfill": "1.3.0",
"react-native-video": "https://git@github.com/jitsi/react-native-video#4f6dad990d17ce42894df993780b5386a9c11b85",
"react-native-watch-connectivity": "1.0.11",
"react-native-watch-connectivity": "1.0.4",
"react-native-webrtc": "1.100.1",
"react-native-webview": "11.15.1",
"react-native-youtube-iframe": "2.2.1",
@@ -125,7 +129,7 @@
"redux": "4.0.4",
"redux-thunk": "2.2.0",
"resemblejs": "4.0.0",
"seamless-scroll-polyfill": "2.1.8",
"rnnoise-wasm": "https://git@github.com/jitsi/rnnoise-wasm#566a16885897704d6e6d67a1d5ac5d39781db2af",
"styled-components": "3.4.9",
"util": "0.12.1",
"uuid": "8.3.2",
@@ -143,16 +147,10 @@
"@babel/preset-react": "7.16.0",
"@babel/runtime": "7.16.0",
"@jitsi/eslint-config": "4.0.0",
"@types/js-md5": "0.4.3",
"@types/lodash": "4.14.182",
"@types/react": "17.0.14",
"@types/react-native": "0.68.1",
"@types/react-native": "0.67.6",
"@types/react-redux": "7.1.24",
"@types/unorm": "1.3.28",
"@types/uuid": "8.3.4",
"@types/zxcvbn": "4.4.1",
"@typescript-eslint/eslint-plugin": "5.30.5",
"@typescript-eslint/parser": "5.30.4",
"babel-loader": "8.2.3",
"babel-plugin-optional-require": "0.3.1",
"circular-dependency-plugin": "5.2.0",
@@ -164,7 +162,6 @@
"eslint-plugin-jsdoc": "37.0.3",
"eslint-plugin-react": "7.26.1",
"eslint-plugin-react-native": "3.11.0",
"eslint-plugin-typescript-sort-keys": "2.1.0",
"expose-loader": "3.0.0",
"imports-loader": "0.7.1",
"jetifier": "1.6.4",
@@ -173,7 +170,7 @@
"process": "0.11.10",
"sass": "1.26.8",
"string-replace-loader": "3.0.3",
"style-loader": "3.3.1",
"style-loader": "0.19.0",
"traverse": "0.6.6",
"ts-loader": "9.2.6",
"typescript": "4.6.4",
@@ -189,9 +186,9 @@
},
"license": "Apache-2.0",
"scripts": {
"lint": "eslint --ext .js,.ts,.tsx --max-warnings 0 . && tsc --noEmit --skipLibCheck",
"lint": "eslint --max-warnings 0 .",
"lang-sort": "./resources/lang-sort.sh",
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",
"lint-fix": "eslint --max-warnings 0 --fix .",
"postinstall": "patch-package --error-on-fail && jetify",
"validate": "npm ls",
"start": "make dev"

View File

@@ -4,29 +4,6 @@
* Podfile are wrong.
*/
module.exports = {
// Exclude some dependencies from auto-linking for the lite SDK.
dependencies: {
'@giphy/react-native-sdk': {
platforms: {
ios: null
}
},
'@react-native-google-signin/google-signin': {
platforms: {
ios: null
}
},
'react-native-calendar-events': {
platforms: {
ios: null
}
},
'react-native-watch-connectivity': {
platforms: {
ios: null
}
}
},
project: {
ios: {
project: '.ios/jitsi-meet.xcworkspace'

View File

@@ -6,30 +6,6 @@ module.exports = {
'@jitsi/eslint-config/react',
'.eslintrc-react-native.js'
],
'overrides': [
{
'files': [ '*.ts', '*.tsx' ],
parser: '@typescript-eslint/parser',
rules: {
'no-undef': 'off',
'no-use-before-define': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/ban-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'no-prototype-builtins': 'off',
'no-shadow': 'off',
'@typescript-eslint/no-shadow': [ 'error' ],
'typescript-sort-keys/interface': 'error',
'typescript-sort-keys/string-enum': 'error'
},
'plugins': [ '@typescript-eslint', 'typescript-sort-keys' ],
'extends': [
'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended'
]
}
],
'rules': {
'flowtype/no-types-missing-file-annotation': 0,

View File

@@ -690,7 +690,7 @@ export function createStartSilentEvent() {
/**
* Creates an event which indicates that HTMLAudioElement.play has failed.
*
* @param {string} elementID - The ID of the HTMLAudioElement.
* @param {sting} elementID - The ID of the HTMLAudioElement.
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
*/
export function createAudioPlayErrorEvent(elementID) {
@@ -703,9 +703,9 @@ export function createAudioPlayErrorEvent(elementID) {
}
/**
* Creates an event which indicates that HTMLAudioElement.play has succeeded after a prior failure.
* Creates an event which indicates that HTMLAudioElement.play has succeded after a prior failure.
*
* @param {string} elementID - The ID of the HTMLAudioElement.
* @param {sting} elementID - The ID of the HTMLAudioElement.
* @returns {Object} The event in a format suitable for sending via sendAnalytics.
*/
export function createAudioPlaySuccessEvent(elementID) {

View File

@@ -61,6 +61,7 @@ export function resetAnalytics() {
*/
export async function createHandlers({ getState }: { getState: Function }) {
getJitsiMeetGlobalNS().analyticsHandlers = [];
window.analyticsHandlers = []; // Legacy support.
if (!isAnalyticsEnabled(getState)) {
// Avoid all analytics processing if there are no handlers, since no event would be sent.
@@ -257,9 +258,16 @@ function _loadHandlers(scriptURLs = [], handlerConstructorOptions) {
}
}
// analyticsHandlers is the handlers we want to use
// we search for them in the JitsiMeetGlobalNS, but also
// check the old location to provide legacy support
const analyticsHandlers = [
...getJitsiMeetGlobalNS().analyticsHandlers,
...window.analyticsHandlers
];
const handlers = [];
for (const Handler of getJitsiMeetGlobalNS().analyticsHandlers) {
for (const Handler of analyticsHandlers) {
// Catch any error while loading to avoid skipping analytics in case
// of multiple scripts.
try {

View File

@@ -1,4 +1,6 @@
import ReducerRegistry from '../base/redux/ReducerRegistry';
// @flow
import { ReducerRegistry } from '../base/redux';
import { UPDATE_LOCAL_TRACKS_DURATION } from './actionTypes';
@@ -28,22 +30,6 @@ const DEFAULT_STATE = {
}
};
interface Value {
startedTime: number,
value: number
}
export interface IAnalyticsState {
localTracksDuration: {
audio: Value,
conference: Value,
video: {
camera: Value,
desktop: Value
}
}
}
/**
* Listen for actions which changes the state of the analytics feature.
*
@@ -52,7 +38,7 @@ export interface IAnalyticsState {
* @param {string} action.type - Type of action.
* @returns {Object}
*/
ReducerRegistry.register('features/analytics', (state: IAnalyticsState = DEFAULT_STATE, action: any) => {
ReducerRegistry.register('features/analytics', (state = DEFAULT_STATE, action) => {
switch (action.type) {
case UPDATE_LOCAL_TRACKS_DURATION:
return {

View File

@@ -44,7 +44,7 @@ export * from './actions.any';
* scheme, or a mere room name.
* @returns {Function}
*/
export function appNavigate(uri?: string) {
export function appNavigate(uri: ?string) {
logger.info(`appNavigate to ${uri}`);
return async (dispatch: Dispatch<any>, getState: Function) => {

View File

@@ -164,7 +164,7 @@ export function maybeRedirectToWelcomePage(options: Object = {}) {
// if close page is enabled redirect to it, without further action
if (enableClosePage) {
if (isVpaasMeeting(getState())) {
dispatch(redirectToStaticPage('/'));
redirectToStaticPage('/');
return;
}

View File

@@ -1,6 +1,7 @@
import React from 'react';
import { NativeModules, Platform, StyleSheet, View } from 'react-native';
import { Platform, StyleSheet, View } from 'react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { FullWindowOverlay } from 'react-native-screens';
import SplashScreen from 'react-native-splash-screen';
import { DialogContainer } from '../../base/dialog';
@@ -22,9 +23,8 @@ import '../reducers';
declare var __DEV__;
const { AppInfo } = NativeModules;
const DialogContainerWrapper = Platform.select({
ios: FullWindowOverlay,
default: View
});
@@ -33,6 +33,11 @@ const DialogContainerWrapper = Platform.select({
*/
type Props = AbstractAppProps & {
/**
* Identifier for this app on the native side.
*/
externalAPIScope: string,
/**
* An object with the feature flags.
*/
@@ -86,10 +91,6 @@ export class App extends AbstractApp {
await super.componentDidMount();
SplashScreen.hide();
const liteTxt = AppInfo.isLiteSDK ? ' (lite)' : '';
logger.info(`Loaded SDK ${AppInfo.sdkVersion}${liteTxt}`);
}
/**

View File

@@ -5,7 +5,7 @@ import React from 'react';
import { DialogContainer } from '../../base/dialog';
import GlobalStyles from '../../base/ui/components/GlobalStyles';
import JitsiThemeProvider from '../../base/ui/components/JitsiThemeProvider.web';
import JitsiThemeProvider from '../../base/ui/components/JitsiThemeProvider';
import { ChromeExtensionBanner } from '../../chrome-extension-banner';
import { AbstractApp } from './AbstractApp';

View File

@@ -3,7 +3,6 @@
import '../authentication/middleware';
import '../base/i18n/middleware';
import '../base/devices/middleware';
import '../base/media/middleware';
import '../dynamic-branding/middleware';
import '../e2ee/middleware';
import '../external-api/middleware';

View File

@@ -11,7 +11,6 @@ import '../power-monitor/reducer';
import '../prejoin/reducer';
import '../remote-control/reducer';
import '../screen-share/reducer';
import '../noise-suppression/reducer';
import '../screenshot-capture/reducer';
import '../shared-video/reducer';
import '../talk-while-muted/reducer';

View File

@@ -1,96 +1,4 @@
import { IAnalyticsState } from '../analytics/reducer';
import { IAuthenticationState } from '../authentication/reducer';
import { IAVModerationState } from '../av-moderation/reducer';
import { IAppState } from '../base/app/reducer';
import { IAudioOnlyState } from '../base/audio-only/reducer';
import { IConferenceState } from '../base/conference/reducer';
import { IConfig } from '../base/config/configType';
import { IConnectionState } from '../base/connection/reducer';
import { IDevicesState } from '../base/devices/reducer';
import { IDialogState } from '../base/dialog/reducer';
import { IFlagsState } from '../base/flags/reducer';
import { IJwtState } from '../base/jwt/reducer';
import { ILastNState } from '../base/lastn/reducer';
import { ILibJitsiMeetState } from '../base/lib-jitsi-meet/reducer';
import { ILoggingState } from '../base/logging/reducer';
import { IMediaState } from '../base/media/reducer';
import { INetInfoState } from '../base/net-info/reducer';
import { IParticipantsState } from '../base/participants/reducer';
import { IResponsiveUIState } from '../base/responsive-ui/reducer';
import { ISettingsState } from '../base/settings/reducer';
import { ISoundsState } from '../base/sounds/reducer';
import { ITestingState } from '../base/testing/reducer';
import { INoSrcDataState, ITracksState } from '../base/tracks/reducer';
import { IUserInteractionState } from '../base/user-interaction/reducer';
import { IBreakoutRoomsState } from '../breakout-rooms/reducer';
import { ICalendarSyncState } from '../calendar-sync/reducer';
import { IChatState } from '../chat/reducer';
import { IDeepLinkingState } from '../deep-linking/reducer';
import { IDropboxState } from '../dropbox/reducer';
import { IDynamicBrandingState } from '../dynamic-branding/reducer';
import { IE2EEState } from '../e2ee/reducer';
import { IEtherpadState } from '../etherpad/reducer';
import { IFaceLandmarksState } from '../face-landmarks/reducer';
import { IFeedbackState } from '../feedback/reducer';
import { IFilmstripState } from '../filmstrip/reducer';
import { IFollowMeState } from '../follow-me/reducer';
import { IGifsState } from '../gifs/reducer';
import { IGoogleApiState } from '../google-api/reducer';
import { IInviteState } from '../invite/reducer';
import { IJaaSState } from '../jaas/reducer';
import { ILargeVideoState } from '../large-video/reducer';
import { ILobbyState } from '../lobby/reducer';
import { INoiseSuppressionState } from '../noise-suppression/reducer';
export interface IStore {
dispatch: Function,
getState: Function
}
export interface IState {
'features/analytics': IAnalyticsState,
'features/authentication': IAuthenticationState,
'features/av-moderation': IAVModerationState,
'features/base/app': IAppState,
'features/base/audio-only': IAudioOnlyState,
'features/base/conference': IConferenceState,
'features/base/config': IConfig,
'features/base/connection': IConnectionState,
'features/base/devices': IDevicesState,
'features/base/dialog': IDialogState,
'features/base/flags': IFlagsState,
'features/base/jwt': IJwtState,
'features/base/known-domains': Array<string>,
'features/base/lastn': ILastNState,
'features/base/lib-jitsi-meet': ILibJitsiMeetState,
'features/base/logging': ILoggingState,
'features/base/media': IMediaState,
'features/base/net-info': INetInfoState,
'features/base/no-src-data': INoSrcDataState,
'features/base/participants': IParticipantsState,
'features/base/responsive-ui': IResponsiveUIState,
'features/base/settings': ISettingsState,
'features/base/sounds': ISoundsState,
'features/base/tracks': ITracksState,
'features/base/user-interaction': IUserInteractionState,
'features/breakout-rooms': IBreakoutRoomsState,
'features/calendar-sync': ICalendarSyncState,
'features/chat': IChatState,
'features/deep-linking': IDeepLinkingState,
'features/dropbox': IDropboxState,
'features/dynamic-branding': IDynamicBrandingState,
'features/e2ee': IE2EEState,
'features/etherpad': IEtherpadState,
'features/face-landmarks': IFaceLandmarksState,
'features/feedback': IFeedbackState,
'features/filmstrip': IFilmstripState,
'features/follow-me': IFollowMeState,
'features/gifs': IGifsState,
'features/google-api': IGoogleApiState,
'features/invite': IInviteState,
'features/jaas': IJaaSState,
'features/large-video': ILargeVideoState,
'features/lobby': ILobbyState,
'features/noise-suppression': INoiseSuppressionState,
'features/testing': ITestingState
getState: Function,
dispatch: Function
}

View File

@@ -1,29 +1,24 @@
/* eslint-disable lines-around-comment */
// @flow
import { FieldTextStateless as TextField } from '@atlaskit/field-text';
import React, { Component } from 'react';
import { WithTranslation } from 'react-i18next';
import type { Dispatch } from 'redux';
// @ts-ignore
import { connect } from '../../../../../connection';
// @ts-ignore
import { toJid } from '../../../base/connection/functions';
// @ts-ignore
import { Dialog } from '../../../base/dialog';
import { translate, translateToHTML } from '../../../base/i18n/functions';
// @ts-ignore
import { translate, translateToHTML } from '../../../base/i18n';
import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet';
import { connect as reduxConnect } from '../../../base/redux/functions';
import Input from '../../../base/ui/components/web/Input';
import { connect as reduxConnect } from '../../../base/redux';
import {
authenticateAndUpgradeRole,
cancelLogin
// @ts-ignore
} from '../../actions.web';
/**
* The type of the React {@code Component} props of {@link LoginDialog}.
*/
interface Props extends WithTranslation {
type Props = {
/**
* {@link JitsiConference} That needs authentication - will hold a valid
@@ -44,7 +39,7 @@ interface Props extends WithTranslation {
/**
* The error which occurred during login/authentication.
*/
_error: any,
_error: Object,
/**
* The progress in the floating range between 0 and 1 of the authenticating
@@ -65,7 +60,12 @@ interface Props extends WithTranslation {
/**
* Conference room name.
*/
roomName: string
roomName: string,
/**
* Invoked to obtain translated strings.
*/
t: Function
}
/**
@@ -73,11 +73,6 @@ interface Props extends WithTranslation {
*/
type State = {
/**
* Authentication process starts before joining the conference room.
*/
loginStarted: boolean,
/**
* The user entered password for the conference.
*/
@@ -86,7 +81,12 @@ type State = {
/**
* The user entered local participant name.
*/
username: string
username: string,
/**
* Authentication process starts before joining the conference room.
*/
loginStarted: boolean
}
/**
@@ -111,10 +111,11 @@ class LoginDialog extends Component<Props, State> {
this._onCancelLogin = this._onCancelLogin.bind(this);
this._onLogin = this._onLogin.bind(this);
this._onUsernameChange = this._onUsernameChange.bind(this);
this._onPasswordChange = this._onPasswordChange.bind(this);
this._onChange = this._onChange.bind(this);
}
_onCancelLogin: () => void;
/**
* Called when the cancel button is clicked.
*
@@ -127,6 +128,8 @@ class LoginDialog extends Component<Props, State> {
dispatch(cancelLogin());
}
_onLogin: () => void;
/**
* Notifies this LoginDialog that the login button (OK) has been pressed by
* the user.
@@ -153,7 +156,7 @@ class LoginDialog extends Component<Props, State> {
});
connect(jid, password, roomName)
.then((connection: any) => {
.then(connection => {
onSuccess && onSuccess(connection);
})
.catch(() => {
@@ -164,27 +167,17 @@ class LoginDialog extends Component<Props, State> {
}
}
_onChange: Object => void;
/**
* Callback for the onChange event of the field.
*
* @param {string} value - The static event.
* @param {Object} evt - The static event.
* @returns {void}
*/
_onPasswordChange(value: string) {
_onChange(evt: Object) {
this.setState({
password: value
});
}
/**
* Callback for the onChange event of the username input.
*
* @param {string} value - The new value.
* @returns {void}
*/
_onUsernameChange(value: string) {
this.setState({
username: value
[evt.target.name]: evt.target.value
});
}
@@ -203,7 +196,7 @@ class LoginDialog extends Component<Props, State> {
t
} = this.props;
const { username, password } = this.state;
const messageOptions: any = {};
const messageOptions = {};
let messageKey;
if (progress && progress < 1) {
@@ -265,20 +258,25 @@ class LoginDialog extends Component<Props, State> {
onSubmit = { this._onLogin }
titleKey = { t('dialog.authenticationRequired') }
width = { 'small' }>
<Input
<TextField
autoFocus = { true }
className = 'input-control'
compact = { false }
label = { t('dialog.user') }
name = 'username'
onChange = { this._onUsernameChange }
onChange = { this._onChange }
placeholder = { t('dialog.userIdentifier') }
shouldFitContainer = { true }
type = 'text'
value = { username } />
<br />
<Input
<TextField
className = 'input-control'
compact = { false }
label = { t('dialog.userPassword') }
name = 'password'
onChange = { this._onPasswordChange }
onChange = { this._onChange }
placeholder = { t('dialog.password') }
shouldFitContainer = { true }
type = 'password'
value = { password } />
{ this.renderMessage() }
@@ -295,7 +293,7 @@ class LoginDialog extends Component<Props, State> {
* @private
* @returns {Props}
*/
function mapStateToProps(state: any) {
function mapStateToProps(state) {
const {
error: authenticateAndUpgradeRoleError,
progress,

View File

@@ -15,6 +15,7 @@ import {
JitsiConnectionErrors
} from '../base/lib-jitsi-meet';
import { MiddlewareRegistry } from '../base/redux';
import { setPrejoinPageVisibility } from '../prejoin';
import {
CANCEL_LOGIN,
@@ -120,6 +121,7 @@ MiddlewareRegistry.register(store => next => action => {
&& error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
&& typeof error.recoverable === 'undefined') {
error.recoverable = true;
store.dispatch(setPrejoinPageVisibility(false));
store.dispatch(openLoginDialog());
}
break;

View File

@@ -1,5 +1,6 @@
import ReducerRegistry from '../base/redux/ReducerRegistry';
import { assign } from '../base/redux/functions';
// @flow
import { assign, ReducerRegistry } from '../base/redux';
import {
CANCEL_LOGIN,
@@ -9,13 +10,6 @@ import {
WAIT_FOR_OWNER
} from './actionTypes';
export interface IAuthenticationState {
error?: Object|undefined;
progress?: number|undefined;
thenableWithCancel?: Object|undefined;
waitForOwnerTimeoutID?: number;
}
/**
* Listens for actions which change the state of the authentication feature.
*
@@ -24,7 +18,7 @@ export interface IAuthenticationState {
* @param {string} action.type - Type of action.
* @returns {Object}
*/
ReducerRegistry.register('features/authentication', (state: IAuthenticationState = {}, action: any) => {
ReducerRegistry.register('features/authentication', (state = {}, action) => {
switch (action.type) {
case CANCEL_LOGIN:
return assign(state, {

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