mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-09-10 00:48:41 +00:00
Compare commits
2 Commits
6608
...
ios-callki
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
95ccc2cbe1 | ||
|
|
468d77c3d6 |
@@ -1,6 +1,5 @@
|
||||
module.exports = {
|
||||
'extends': [
|
||||
'@jitsi/eslint-config'
|
||||
],
|
||||
'ignorePatterns': [ '*.d.ts' ]
|
||||
]
|
||||
};
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
PKG_NAME=${1:-org.jitsi.meet}
|
||||
APP_PID=$(adb shell ps | grep $PKG_NAME | awk '{print $2}')
|
||||
|
||||
if [[ -z "$APP_PID" ]]; then
|
||||
echo "App is not running"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exec adb logcat --pid=$APP_PID
|
||||
@@ -77,7 +77,6 @@ dependencies {
|
||||
implementation project(':react-native-immersive')
|
||||
implementation project(':react-native-keep-awake')
|
||||
implementation project(':react-native-masked-view_masked-view')
|
||||
implementation project(':react-native-orientation-locker')
|
||||
implementation project(':react-native-pager-view')
|
||||
implementation project(':react-native-performance')
|
||||
implementation project(':react-native-safe-area-context')
|
||||
|
||||
@@ -21,7 +21,6 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
|
||||
@@ -31,7 +30,6 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
|
||||
import org.wonday.orientation.OrientationActivityLifecycle;
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.HashMap;
|
||||
@@ -88,14 +86,6 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
// Overrides
|
||||
//
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
Intent intent = new Intent("onConfigurationChanged");
|
||||
intent.putExtra("newConfig", newConfig);
|
||||
this.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
@@ -104,7 +94,6 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
this.jitsiView = findViewById(R.id.jitsiView);
|
||||
|
||||
registerForBroadcastMessages();
|
||||
registerActivityLifecycleCallbacks(OrientationActivityLifecycle.getInstance());
|
||||
|
||||
if (!extraInitialize()) {
|
||||
initialize();
|
||||
|
||||
@@ -85,7 +85,6 @@ class ReactInstanceManagerHolder {
|
||||
WebRTCModule.Options options = new WebRTCModule.Options();
|
||||
|
||||
AudioDeviceModule adm = JavaAudioDeviceModule.builder(reactContext)
|
||||
.setEnableVolumeLogger(false)
|
||||
.createAudioDeviceModule();
|
||||
options.setAudioDeviceModule(adm);
|
||||
|
||||
@@ -129,7 +128,6 @@ class ReactInstanceManagerHolder {
|
||||
new com.zmxv.RNSound.RNSoundPackage(),
|
||||
new com.th3rdwave.safeareacontext.SafeAreaContextPackage(),
|
||||
new com.horcrux.svg.SvgPackage(),
|
||||
new org.wonday.orientation.OrientationPackage(),
|
||||
new ReactPackageAdapter() {
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
|
||||
@@ -33,8 +33,6 @@ include ':react-native-keep-awake'
|
||||
project(':react-native-keep-awake').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-keep-awake/android')
|
||||
include ':react-native-masked-view_masked-view'
|
||||
project(':react-native-masked-view_masked-view').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-masked-view/masked-view/android')
|
||||
include ':react-native-orientation-locker'
|
||||
project(':react-native-orientation-locker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-orientation-locker/android')
|
||||
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'
|
||||
|
||||
@@ -15,8 +15,8 @@ import Recorder from './modules/recorder/Recorder';
|
||||
import { createTaskQueue } from './modules/util/helpers';
|
||||
import {
|
||||
createDeviceChangedEvent,
|
||||
createScreenSharingEvent,
|
||||
createStartSilentEvent,
|
||||
createScreenSharingEvent,
|
||||
createTrackMutedEvent,
|
||||
sendAnalytics
|
||||
} from './react/features/analytics';
|
||||
@@ -30,15 +30,14 @@ import { shouldShowModeratedNotification } from './react/features/av-moderation/
|
||||
import { setAudioOnly } from './react/features/base/audio-only';
|
||||
import {
|
||||
AVATAR_URL_COMMAND,
|
||||
CONFERENCE_LEAVE_REASONS,
|
||||
EMAIL_COMMAND,
|
||||
_conferenceWillJoin,
|
||||
authStatusChanged,
|
||||
commonUserJoinedHandling,
|
||||
commonUserLeftHandling,
|
||||
conferenceFailed,
|
||||
conferenceJoinInProgress,
|
||||
conferenceJoined,
|
||||
conferenceJoinInProgress,
|
||||
conferenceLeft,
|
||||
conferenceSubjectChanged,
|
||||
conferenceTimestampChanged,
|
||||
@@ -50,14 +49,15 @@ import {
|
||||
getConferenceOptions,
|
||||
kickedOut,
|
||||
lockStateChanged,
|
||||
nonParticipantMessageReceived,
|
||||
onStartMutedPolicyChanged,
|
||||
p2pStatusChanged,
|
||||
sendLocalParticipant
|
||||
sendLocalParticipant,
|
||||
nonParticipantMessageReceived,
|
||||
CONFERENCE_LEAVE_REASONS
|
||||
} from './react/features/base/conference';
|
||||
import {
|
||||
getMultipleVideoSendingSupportFeatureFlag,
|
||||
getReplaceParticipant
|
||||
getReplaceParticipant,
|
||||
getMultipleVideoSendingSupportFeatureFlag
|
||||
} from './react/features/base/config/functions';
|
||||
import {
|
||||
checkAndNotifyForNewDevice,
|
||||
@@ -69,6 +69,7 @@ import {
|
||||
updateDeviceList
|
||||
} from './react/features/base/devices';
|
||||
import {
|
||||
browser,
|
||||
JitsiConferenceErrors,
|
||||
JitsiConferenceEvents,
|
||||
JitsiConnectionErrors,
|
||||
@@ -77,15 +78,14 @@ import {
|
||||
JitsiMediaDevicesEvents,
|
||||
JitsiParticipantConnectionStatus,
|
||||
JitsiTrackErrors,
|
||||
JitsiTrackEvents,
|
||||
browser
|
||||
JitsiTrackEvents
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import {
|
||||
MEDIA_TYPE,
|
||||
getStartWithAudioMuted,
|
||||
getStartWithVideoMuted,
|
||||
isVideoMutedByUser,
|
||||
MEDIA_TYPE,
|
||||
setAudioAvailable,
|
||||
setAudioMuted,
|
||||
setAudioUnmutePermissions,
|
||||
@@ -140,9 +140,9 @@ import {
|
||||
import { maybeSetLobbyChatMessageListener } from './react/features/lobby/actions.any';
|
||||
import { setNoiseSuppressionEnabled } from './react/features/noise-suppression/actions';
|
||||
import {
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
isModerationNotificationDisplayed,
|
||||
showNotification
|
||||
showNotification,
|
||||
NOTIFICATION_TIMEOUT_TYPE
|
||||
} from './react/features/notifications';
|
||||
import { mediaPermissionPromptVisibilityChanged, toggleSlowGUMOverlay } from './react/features/overlay';
|
||||
import { suspendDetected } from './react/features/power-monitor';
|
||||
@@ -153,7 +153,7 @@ import {
|
||||
setJoiningInProgress
|
||||
} from './react/features/prejoin';
|
||||
import { disableReceiver, stopReceiver } from './react/features/remote-control';
|
||||
import { isScreenAudioShared, setScreenAudioShareState } from './react/features/screen-share/';
|
||||
import { setScreenAudioShareState, isScreenAudioShared } from './react/features/screen-share/';
|
||||
import { toggleScreenshotCaptureSummary } from './react/features/screenshot-capture';
|
||||
import { isScreenshotCaptureEnabled } from './react/features/screenshot-capture/functions';
|
||||
import { AudioMixerEffect } from './react/features/stream-effects/audio-mixer/AudioMixerEffect';
|
||||
@@ -2291,9 +2291,7 @@ export default {
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
|
||||
(dominant, previous, silence) => {
|
||||
APP.store.dispatch(dominantSpeakerChanged(dominant, previous, Boolean(silence), room));
|
||||
});
|
||||
(dominant, previous) => APP.store.dispatch(dominantSpeakerChanged(dominant, previous, room)));
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.CONFERENCE_CREATED_TIMESTAMP,
|
||||
@@ -2985,6 +2983,7 @@ export default {
|
||||
const available = audioDeviceCount > 0 || Boolean(localAudio);
|
||||
|
||||
APP.store.dispatch(setAudioAvailable(available));
|
||||
APP.API.notifyAudioAvailabilityChanged(available);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -3248,6 +3247,7 @@ export default {
|
||||
*/
|
||||
setAudioMuteStatus(muted) {
|
||||
APP.UI.setAudioMuted(this.getMyUserId(), muted);
|
||||
APP.API.notifyAudioMutedStatusChanged(muted);
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
@@ -114,7 +114,7 @@ var config = {
|
||||
|
||||
// Signal that this client supports receiving multiple video streams. Without this flag jicofo will enable
|
||||
// multi-stream backward compatibility.
|
||||
// receiveMultipleVideoStreams: true,
|
||||
receiveMultipleVideoStreams: true,
|
||||
},
|
||||
|
||||
// Disables moderator indicators.
|
||||
@@ -824,7 +824,7 @@ var config = {
|
||||
// Application ID and Secret.
|
||||
// callStatsID: '',
|
||||
// callStatsSecret: '',
|
||||
// callStatsApplicationLogsDisabled: false,
|
||||
// callstatsStoreLogs: true,
|
||||
|
||||
// The callstats initialize config params as described in the API:
|
||||
// https://docs.callstats.io/docs/javascript#callstatsinitialize-with-app-secret
|
||||
@@ -1441,10 +1441,6 @@ var config = {
|
||||
// // (displaying multiple participants on stage besides the vertical filmstrip)
|
||||
// disableStageFilmstrip: false,
|
||||
|
||||
// // Default number of participants that can be displayed on stage.
|
||||
// // The user can change this in settings. Number must be between 1 and 6.
|
||||
// stageFilmstripParticipants: 1,
|
||||
|
||||
// // Disables the top panel (only shown when a user is sharing their screen).
|
||||
// disableTopPanel: false,
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import { getCustomerDetails } from './react/features/jaas/actions.any';
|
||||
import { getJaasJWT, isVpaasMeeting } from './react/features/jaas/functions';
|
||||
import { isVpaasMeeting, getJaasJWT } from './react/features/jaas/functions';
|
||||
import {
|
||||
setPrejoinDisplayNameRequired
|
||||
} from './react/features/prejoin/actions';
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
// extract header + tabs height
|
||||
height: calc(100% - 119px);
|
||||
height: calc(100% - 102px);
|
||||
}
|
||||
|
||||
.chat-panel-no-tabs {
|
||||
@@ -531,3 +531,41 @@
|
||||
background: #36383C;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.chat-tabs-container {
|
||||
width: 100%;
|
||||
border-bottom: thin solid #292929;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.chat-tab {
|
||||
font-size: 1.2em;
|
||||
padding-bottom: 0.5em;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
color: #8B8B8B;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.chat-tab-focus {
|
||||
border-bottom-style: solid;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.chat-tab-title {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.chat-tab-badge {
|
||||
background-color: #165ecc;
|
||||
border-radius: 50%;
|
||||
box-sizing: border-box;
|
||||
font-weight: 700;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: middle;
|
||||
padding: 0 4px;
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ ol.poll-result-list {
|
||||
}
|
||||
|
||||
#polls-panel {
|
||||
height: calc(100% - 119px);
|
||||
height: calc(100% - 102px);
|
||||
}
|
||||
|
||||
.poll-container {
|
||||
|
||||
22
debian/jitsi-meet-prosody.postinst
vendored
22
debian/jitsi-meet-prosody.postinst
vendored
@@ -83,28 +83,16 @@ case "$1" in
|
||||
TURN_SECRET="$RET"
|
||||
fi
|
||||
|
||||
db_get jitsi-meet/jaas-choice
|
||||
JAAS_INPUT="$RET"
|
||||
# In the case of updating from an older version the configure of -prosody package may happen before the -config
|
||||
# one, so if JAAS_INPUT is empty (the question is not asked), let's ask it now.
|
||||
db_get jitsi-meet/cert-choice
|
||||
CERT_CHOICE="$RET"
|
||||
if [ -z "$CERT_CHOICE" ] ; then
|
||||
db_input critical jitsi-meet/cert-choice || true
|
||||
if [ -z "$JAAS_INPUT" ] ; then
|
||||
db_subst jitsi-meet/jaas-choice domain "${JVB_HOSTNAME}"
|
||||
db_input critical jitsi-meet/jaas-choice || true
|
||||
db_go
|
||||
db_get jitsi-meet/cert-choice
|
||||
CERT_CHOICE="$RET"
|
||||
fi
|
||||
SELF_SIGNED_CHOICE="Generate a new self-signed certificate"
|
||||
if [ "$CERT_CHOICE" != "$SELF_SIGNED_CHOICE" ]; then
|
||||
db_get jitsi-meet/jaas-choice
|
||||
JAAS_INPUT="$RET"
|
||||
if [ -z "$JAAS_INPUT" ] ; then
|
||||
db_subst jitsi-meet/jaas-choice domain "${JVB_HOSTNAME}"
|
||||
db_set jitsi-meet/jaas-choice false
|
||||
db_input critical jitsi-meet/jaas-choice || true
|
||||
db_go
|
||||
db_get jitsi-meet/jaas-choice
|
||||
JAAS_INPUT="$RET"
|
||||
fi
|
||||
fi
|
||||
|
||||
# and we're done with debconf
|
||||
|
||||
39
debian/jitsi-meet-web-config.postinst
vendored
39
debian/jitsi-meet-web-config.postinst
vendored
@@ -68,6 +68,12 @@ case "$1" in
|
||||
FORCE_NGINX="false"
|
||||
fi
|
||||
|
||||
db_subst jitsi-meet/jaas-choice domain "${JVB_HOSTNAME}"
|
||||
db_input critical jitsi-meet/jaas-choice || true
|
||||
db_go
|
||||
db_get jitsi-meet/jaas-choice
|
||||
JAAS_INPUT="$RET"
|
||||
|
||||
UPLOADED_CERT_CHOICE="I want to use my own certificate"
|
||||
LE_CERT_CHOICE="Let's Encrypt certificates"
|
||||
# if first time config ask for certs, or if we are reconfiguring
|
||||
@@ -136,20 +142,6 @@ case "$1" in
|
||||
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $JITSI_MEET_CONFIG
|
||||
fi
|
||||
|
||||
if [ "$CERT_CHOICE" = "$LE_CERT_CHOICE" ] || [ "$CERT_CHOICE" = "$UPLOADED_CERT_CHOICE" ]; then
|
||||
# Make sure jaas-choice is not answered already
|
||||
db_get jitsi-meet/jaas-choice
|
||||
JAAS_INPUT="$RET"
|
||||
if [ -z "$JAAS_INPUT" ] ; then
|
||||
db_subst jitsi-meet/jaas-choice domain "${JVB_HOSTNAME}"
|
||||
db_set jitsi-meet/jaas-choice false
|
||||
db_input critical jitsi-meet/jaas-choice || true
|
||||
db_go
|
||||
db_get jitsi-meet/jaas-choice
|
||||
JAAS_INPUT="$RET"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "${JAAS_INPUT}" = "true" ] && ! grep -q "^var enableJaaS = true;$" $JITSI_MEET_CONFIG; then
|
||||
if grep -q "^var enableJaaS = false;$" $JITSI_MEET_CONFIG; then
|
||||
sed -i "s/^var enableJaaS = false;$/var enableJaaS = true;/g" $JITSI_MEET_CONFIG
|
||||
@@ -228,15 +220,8 @@ case "$1" in
|
||||
invoke-rc.d apache2 reload || true
|
||||
fi
|
||||
|
||||
# If scripts fail they will print suggestions for next steps, do not fail install
|
||||
# those can be re-run later
|
||||
# run the scripts only on new install or when re-configuring
|
||||
if [[ "$ISSUE_LE_CERT" = "true" && ( -z "$JVB_HOSTNAME_OLD" || "$RECONFIGURING" = "true" ) ]] ; then
|
||||
/usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh $EMAIL $JVB_HOSTNAME || true
|
||||
fi
|
||||
JAAS_REG_ERROR=0
|
||||
if [[ "${JAAS_INPUT}" = "true" && ( -z "$JVB_HOSTNAME_OLD" || "$RECONFIGURING" = "true" ) ]] ; then
|
||||
/usr/share/jitsi-meet/scripts/register-jaas-account.sh $EMAIL $JVB_HOSTNAME || JAAS_REG_ERROR=$?
|
||||
if [ "$ISSUE_LE_CERT" = "true" ] ; then
|
||||
/usr/share/jitsi-meet/scripts/install-letsencrypt-cert.sh $EMAIL $JVB_HOSTNAME
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -247,16 +232,16 @@ case "$1" in
|
||||
echo " .xMMMMNxkNc"
|
||||
echo " dMMMMMkxXc"
|
||||
echo " cNMMMNl.."
|
||||
if [ "${JAAS_INPUT}" != "true" ] || [ ${JAAS_REG_ERROR} -ne 0 ]; then
|
||||
if [ "${JAAS_INPUT}" != "true" ]; then
|
||||
echo " .kMMMX; Interested in adding telephony to your Jitsi meetings?"
|
||||
echo " ;XMMMO'"
|
||||
echo " lNMMWO' Sign up on https://jaas.8x8.vc/components?host=${JVB_HOSTNAME}"
|
||||
echo " lNMMM0, and follow the guide in the dev console."
|
||||
else
|
||||
echo " .kMMMX;"
|
||||
echo " ;XMMMO' Congratulations! Now you can use telephony in your Jitsi meetings!"
|
||||
echo " lNMMWO' We have created a free JaaS (Jitsi as a Service) account for you. "
|
||||
echo " lNMMM0, You can login to https://jaas.8x8.vc/components to check our developer console and your account details."
|
||||
echo " ;XMMMO' Don't forget to sign up on"
|
||||
echo " lNMMWO' https://jaas.8x8.vc/components?host=${JVB_HOSTNAME}"
|
||||
echo " lNMMM0, in order to add telephony to your Jitsi meetings!"
|
||||
fi
|
||||
echo " lXMMMK:."
|
||||
echo " ;KMMMNKd. 'oo,"
|
||||
|
||||
22
debian/jitsi-meet-web-config.templates
vendored
22
debian/jitsi-meet-web-config.templates
vendored
@@ -1,13 +1,16 @@
|
||||
Template: jitsi-meet/cert-choice
|
||||
Type: select
|
||||
__Choices: Let's Encrypt certificates, I want to use my own certificate, Generate a new self-signed certificate
|
||||
_Description: SSL certificate
|
||||
__Choices: Generate a new self-signed certificate, Let's Encrypt certificates, I want to use my own certificate
|
||||
_Description: SSL certificate for the Jitsi Meet instance
|
||||
.
|
||||
Jitsi Meet requires an SSL certificate. This installer can generate one automatically for your using "Let’s Encrypt". This is the recommended and simplest option for most installations.
|
||||
Jitsi Meet is best to be set up with an SSL certificate.
|
||||
.
|
||||
In the event you need to use a certificate of your own, you can configure its location which defaults to /etc/ssl/--domain.name--.key for the key and /etc/ssl/--domain.name--.crt for the certificate.
|
||||
Having no certificate, a self-signed one will be generated.
|
||||
In the case of using a self-signed certificate, only the web app will be available with some warnings, the mobile app will not connect.
|
||||
Self-signed certificates are not supported by JaaS (Jitsi as a Service).
|
||||
.
|
||||
If you are a developer and are only looking for a quick way to test basic Jitsi Meet functionality then this installer can also generate a self-signed certificate.
|
||||
Having a certificate signed by a recognised CA, it can be uploaded on the server and point its location.
|
||||
The default filenames will be /etc/ssl/--domain.name--.key for the key and /etc/ssl/--domain.name--.crt for the certificate.
|
||||
|
||||
Template: jitsi-meet/cert-path-key
|
||||
Type: string
|
||||
@@ -34,7 +37,10 @@ _Description: Hostname:
|
||||
Template: jitsi-meet/jaas-choice
|
||||
Type: boolean
|
||||
_Description: Interested in adding telephony to your Jitsi meetings?
|
||||
You can easily add dialing in support to your meetings. You need to give us the permission to create a free JaaS (Jitsi as a Service) account for you.
|
||||
You can easily add dialing in support to your meetings using JaaS (Jitsi as a Service).
|
||||
You need to:
|
||||
- have a certificate signed by a recognised CA or Let’s Encrypt on your deployment
|
||||
- sign in for JaaS at https://jaas.8x8.vc/components?host=${domain}
|
||||
|
||||
Template: jitsi-meet/email
|
||||
Type: string
|
||||
@@ -44,6 +50,4 @@ _Description: Enter your email:
|
||||
You need a working DNS record pointing to this machine(for hostname ${domain})"
|
||||
.
|
||||
You need to agree to the ACME server's Subscriber Agreement (https://letsencrypt.org/documents/LE-SA-v1.1.1-August-1-2016.pdf)
|
||||
by providing an email address for important account notifications.
|
||||
.
|
||||
We will use the email for creating your JaaS (Jitsi as a Service) account if that option was selected.
|
||||
by providing an email address for important account notifications
|
||||
|
||||
18
globals.d.ts
vendored
18
globals.d.ts
vendored
@@ -1,18 +0,0 @@
|
||||
import { IStore } from "./react/features/app/types";
|
||||
import { IConfig } from "./react/features/base/config/configType";
|
||||
|
||||
export {};
|
||||
|
||||
declare global {
|
||||
const APP: {
|
||||
store: IStore;
|
||||
UI: any;
|
||||
API: any;
|
||||
conference: any;
|
||||
};
|
||||
const interfaceConfig: any;
|
||||
|
||||
interface Window {
|
||||
config?: IConfig;
|
||||
}
|
||||
}
|
||||
@@ -72,13 +72,8 @@ post_install do |installer|
|
||||
react_native_post_install(installer)
|
||||
__apply_Xcode_12_5_M1_post_install_workaround(installer)
|
||||
installer.pods_project.targets.each do |target|
|
||||
# https://github.com/CocoaPods/CocoaPods/issues/11402
|
||||
if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
|
||||
end
|
||||
end
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'YES'
|
||||
config.build_settings['SUPPORTS_MACCATALYST'] = 'NO'
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
|
||||
end
|
||||
|
||||
@@ -366,8 +366,6 @@ PODS:
|
||||
- React
|
||||
- react-native-netinfo (7.1.7):
|
||||
- React-Core
|
||||
- react-native-orientation-locker (1.5.0):
|
||||
- React-Core
|
||||
- react-native-pager-view (5.4.9):
|
||||
- React-Core
|
||||
- react-native-performance (2.1.0):
|
||||
@@ -384,7 +382,7 @@ PODS:
|
||||
- react-native-video/Video (6.0.0-alpha.1):
|
||||
- PromisesSwift
|
||||
- React-Core
|
||||
- react-native-webrtc (1.106.0):
|
||||
- react-native-webrtc (1.100.1):
|
||||
- React-Core
|
||||
- react-native-webview (11.15.1):
|
||||
- React-Core
|
||||
@@ -516,7 +514,6 @@ DEPENDENCIES:
|
||||
- react-native-get-random-values (from `../node_modules/react-native-get-random-values`)
|
||||
- react-native-keep-awake (from `../node_modules/react-native-keep-awake`)
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
|
||||
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
|
||||
- react-native-performance (from `../node_modules/react-native-performance/ios`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
@@ -626,8 +623,6 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-keep-awake"
|
||||
react-native-netinfo:
|
||||
:path: "../node_modules/@react-native-community/netinfo"
|
||||
react-native-orientation-locker:
|
||||
:path: "../node_modules/react-native-orientation-locker"
|
||||
react-native-pager-view:
|
||||
:path: "../node_modules/react-native-pager-view"
|
||||
react-native-performance:
|
||||
@@ -743,14 +738,13 @@ SPEC CHECKSUMS:
|
||||
react-native-get-random-values: 30b3f74ca34e30e2e480de48e4add2706a40ac8f
|
||||
react-native-keep-awake: afad8a51dfef9fe9655a6344771be32c8596d774
|
||||
react-native-netinfo: 27f287f2d191693f3b9d01a4273137fcf91c3b5d
|
||||
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
|
||||
react-native-pager-view: 3ee7d4c7697fb3ef788346e834a60cca97ed8540
|
||||
react-native-performance: f4b6604a9d5a8a7407e34a82fab6c641d9a3ec12
|
||||
react-native-safe-area-context: 584dc04881deb49474363f3be89e4ca0e854c057
|
||||
react-native-slider: 6e9b86e76cce4b9e35b3403193a6432ed07e0c81
|
||||
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
|
||||
react-native-video: bb6f12a7198db53b261fefb5d609dc77417acc8b
|
||||
react-native-webrtc: ae0a19dd7de9889f7596989f33db67c58632323c
|
||||
react-native-webrtc: 206a0ac12a5633d2ec4605174d7c9f12f0d674b2
|
||||
react-native-webview: ea4899a1056c782afa96dd082179a66cbebf5504
|
||||
React-perflogger: 30ab8d6db10e175626069e742eead3ebe8f24fd5
|
||||
React-RCTActionSheet: 4b45da334a175b24dabe75f856b98fed3dfd6201
|
||||
@@ -778,6 +772,6 @@ SPEC CHECKSUMS:
|
||||
RNWatch: dae6c858a2051dbdcfb00b9a86cf4d90400263b4
|
||||
Yoga: 17cd9a50243093b547c1e539c749928dd68152da
|
||||
|
||||
PODFILE CHECKSUM: 55f1a79792dd5f74b7510fc84068abcb79ddd518
|
||||
PODFILE CHECKSUM: a437875b597d999a137c671b1da54153fe31d23f
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
@@ -854,6 +854,7 @@
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEAD_CODE_STRIPPING = NO;
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -884,6 +885,7 @@
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEVELOPMENT_TEAM = FC967L3QRG;
|
||||
ENABLE_BITCODE = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
@@ -1001,6 +1003,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
@@ -1061,6 +1064,7 @@
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
|
||||
@@ -124,10 +124,4 @@
|
||||
options:options];
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application
|
||||
supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
return [[JitsiMeet sharedInstance] application:application
|
||||
supportedInterfaceOrientationsForWindow:window];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -78,6 +78,7 @@ platform :ios do
|
||||
# Actually build the app
|
||||
build_app(
|
||||
scheme: "JitsiMeet",
|
||||
include_bitcode: true,
|
||||
include_symbols: true,
|
||||
export_xcargs: "-allowProvisioningUpdates"
|
||||
)
|
||||
|
||||
@@ -35,6 +35,7 @@ xcodebuild archive \
|
||||
-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 \
|
||||
@@ -44,6 +45,7 @@ xcodebuild archive \
|
||||
-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 \
|
||||
|
||||
@@ -12,6 +12,8 @@ DO_GIT_TAG=${GIT_TAG:-0}
|
||||
|
||||
echo "Releasing Jitsi Meet SDK ${SDK_VERSION}"
|
||||
|
||||
${THIS_DIR}/../../node_modules/react-native-webrtc/tools/downloadBitcode.sh
|
||||
|
||||
pushd ${RELEASE_REPO}
|
||||
|
||||
# Generate podspec file
|
||||
@@ -35,6 +37,7 @@ xcodebuild archive \
|
||||
-sdk iphonesimulator \
|
||||
-destination='generic/platform=iOS Simulator' \
|
||||
-archivePath ios/sdk/out/ios-simulator \
|
||||
ENABLE_BITCODE=YES \
|
||||
SKIP_INSTALL=NO \
|
||||
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
|
||||
xcodebuild archive \
|
||||
@@ -44,6 +47,7 @@ xcodebuild archive \
|
||||
-sdk iphoneos \
|
||||
-destination='generic/platform=iOS' \
|
||||
-archivePath ios/sdk/out/ios-device \
|
||||
ENABLE_BITCODE=YES \
|
||||
SKIP_INSTALL=NO \
|
||||
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
|
||||
xcodebuild -create-xcframework \
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
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; };
|
||||
6F08DF7D4458EE3CF3F36F6D /* (null) in Frameworks */ = {isa = PBXBuildFile; };
|
||||
9A8EE79C77C17743BB66E8BD /* libPods-JitsiMeetSDKLite.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B46497DE9A95BDF5E312AF48 /* libPods-JitsiMeetSDKLite.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 */; };
|
||||
@@ -206,7 +206,7 @@
|
||||
files = (
|
||||
0BB9AD791F5EC6D7001C08DB /* Intents.framework in Frameworks */,
|
||||
0BB9AD771F5EC6CE001C08DB /* CallKit.framework in Frameworks */,
|
||||
6F08DF7D4458EE3CF3F36F6D /* BuildFile in Frameworks */,
|
||||
6F08DF7D4458EE3CF3F36F6D /* (null) in Frameworks */,
|
||||
3453F4A32680898C4A40E821 /* libPods-JitsiMeetSDK.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -788,6 +788,7 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
@@ -850,6 +851,7 @@
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
ENABLE_BITCODE = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
@@ -886,6 +888,7 @@
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
@@ -915,6 +918,7 @@
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_BITCODE = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
INFOPLIST_FILE = src/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
@@ -943,6 +947,7 @@
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_BITCODE = NO;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
@@ -977,6 +982,7 @@
|
||||
DYLIB_COMPATIBILITY_VERSION = 1;
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
ENABLE_BITCODE = YES;
|
||||
"EXCLUDED_ARCHS[sdk=iphonesimulator*]" = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(inherited)",
|
||||
|
||||
@@ -57,9 +57,6 @@
|
||||
openURL:(NSURL *_Nonnull)url
|
||||
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *_Nonnull)options;
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application
|
||||
supportedInterfaceOrientationsForWindow:(UIWindow *)window;
|
||||
|
||||
#pragma mark - Utility methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#import <Intents/Intents.h>
|
||||
#import <WebRTC/RTCLogging.h>
|
||||
#import "Orientation.h"
|
||||
|
||||
#import "JitsiMeet+Private.h"
|
||||
#import "JitsiMeetConferenceOptions+Private.h"
|
||||
@@ -128,10 +127,6 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
|
||||
return [Orientation getOrientation];
|
||||
}
|
||||
|
||||
#pragma mark - Utility methods
|
||||
|
||||
- (void)instantiateReactNativeBridge {
|
||||
|
||||
34
lang/languages-fy.json
Normal file
34
lang/languages-fy.json
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"af": "",
|
||||
"bg": "",
|
||||
"ca": "",
|
||||
"cs": "",
|
||||
"da": "",
|
||||
"de": "",
|
||||
"el": "",
|
||||
"en": "",
|
||||
"enGB": "",
|
||||
"eo": "",
|
||||
"es": "",
|
||||
"esUS": "",
|
||||
"et": "",
|
||||
"fi": "",
|
||||
"fr": "",
|
||||
"frCA": "",
|
||||
"hr": "",
|
||||
"hu": "",
|
||||
"hy": "",
|
||||
"it": "",
|
||||
"ja": "",
|
||||
"ko": "",
|
||||
"nl": "",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sv": "",
|
||||
"tr": "",
|
||||
"vi": "",
|
||||
"zhCN": "",
|
||||
"zhTW": ""
|
||||
}
|
||||
36
lang/languages-ka.json
Normal file
36
lang/languages-ka.json
Normal file
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"af": "აფრიკული",
|
||||
"bg": "ბულგარული",
|
||||
"ca": "კატალონიური",
|
||||
"cs": "ჩეხური",
|
||||
"da": "დანიური",
|
||||
"de": "გერმანული",
|
||||
"el": "ბერძნული",
|
||||
"en": "ინგლისური",
|
||||
"enGB": "ინგლისური (დიდი ბრიტანეთი)",
|
||||
"eo": "ესტონური",
|
||||
"es": "ესპანური",
|
||||
"esUS": "ესპანური (ლათინური ამერიკა)",
|
||||
"et": "ესტონური",
|
||||
"fi": "ფინური",
|
||||
"fr": "ფრანგული",
|
||||
"frCA": "ფრანგული (კანადური)",
|
||||
"hr": "ხორვატიული",
|
||||
"hu": "უნგრული",
|
||||
"hy": "სომხური",
|
||||
"it": "იტალიური",
|
||||
"ja": "იაპონური",
|
||||
"ka": "ქართული",
|
||||
"ko": "კორეული",
|
||||
"nl": "ჰოლანდიური",
|
||||
"oc": "ოქსიტანური",
|
||||
"pl": "პოლონური",
|
||||
"ptBR": "პორტუგალიური (ბრაზილია)",
|
||||
"ru": "რუსული",
|
||||
"sr": "სერბული",
|
||||
"sv": "შვედური",
|
||||
"tr": "თურქული",
|
||||
"vi": "ვიეტნამური",
|
||||
"zhCN": "ჩინური (ჩინეთი)",
|
||||
"zhTW": "ჩინური (ტაივანი)"
|
||||
}
|
||||
27
lang/languages-km.json
Normal file
27
lang/languages-km.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"af": "អាហ្វ្រិច",
|
||||
"az": "Azerbaijani",
|
||||
"bg": "ប៊ុលហ្គារី",
|
||||
"cs": "ឆេក",
|
||||
"de": "អាល្លឺម៉ង់",
|
||||
"el": "ក្រិក",
|
||||
"en": "អង់គ្លេស",
|
||||
"eo": "Esperanto",
|
||||
"es": "អេស្ប៉ាញ",
|
||||
"fr": "បារាំង",
|
||||
"hy": "ភាសាអាមេនី",
|
||||
"it": "អ៊ីតាលី",
|
||||
"ja": "ជប៉ុន",
|
||||
"ko": "កូរ៉េ",
|
||||
"nb": "ន័រវេបាំម៉ាល",
|
||||
"oc": "អុកស៊ីត",
|
||||
"pl": "ប៉ូឡូញ",
|
||||
"ptBR": "ព័រទុយហ្គាល់",
|
||||
"ru": "រុស្ស៊ី",
|
||||
"sk": "ស្លូវ៉ាគី",
|
||||
"sl": "ស្លូវ៉ានី",
|
||||
"sv": "ស៊ុយអែត",
|
||||
"tr": "ទួរគី",
|
||||
"vi": "វៀតណាម",
|
||||
"zhCN": "ចិន (ចិន)"
|
||||
}
|
||||
@@ -239,7 +239,7 @@
|
||||
"cameraNotSendingData": "Não podemos aceder à sua câmara. Verifique se outra aplicação está a utilizar este dispositivo, seleccione outro dispositivo do menu de definições ou tente recarregar a aplicação.",
|
||||
"cameraNotSendingDataTitle": "Não é possível aceder à câmara",
|
||||
"cameraPermissionDeniedError": "Não concedeu autorização para utilizar a sua câmara. Ainda pode participar na conferência, mas outros não o verão. Use o botão da câmara na barra de endereço para corrigir isto.",
|
||||
"cameraTimeoutError": "Não foi possível iniciar a fonte de vídeo. Tempo limite expirado!",
|
||||
"cameraTimeoutError": "Não foi possível iniciar a fonte de vídeo. Tempo limite esgotado!",
|
||||
"cameraUnknownError": "Não é possível utilizar a câmara por uma razão desconhecida.",
|
||||
"cameraUnsupportedResolutionError": "A sua câmara não suporta a resolução de vídeo necessária.",
|
||||
"close": "Fechar",
|
||||
@@ -298,7 +298,7 @@
|
||||
"micNotSendingData": "Vá às definições do seu computador para desligar o seu microfone e ajustar o seu nível",
|
||||
"micNotSendingDataTitle": "O seu microfone está silenciado pelas definições do seu sistema",
|
||||
"micPermissionDeniedError": "Não concedeu autorização para utilizar o seu microfone. Ainda pode participar na conferência, mas outros não o ouvirão. Use o botão da câmara na barra de endereço para corrigir isto.",
|
||||
"micTimeoutError": "Não foi possível iniciar a fonte de áudio. Tempo limite expirado!",
|
||||
"micTimeoutError": "Não foi possível iniciar a fonte de áudio. Tempo limite esgotado!",
|
||||
"micUnknownError": "Não pode usar microfone por uma razão desconhecida.",
|
||||
"moderationAudioLabel": "Permitir aos participantes reativar o som",
|
||||
"moderationVideoLabel": "Permitir aos participantes reativar o vídeo",
|
||||
@@ -965,7 +965,7 @@
|
||||
"participantKnocking": "Entrar um participante na sala de espera",
|
||||
"participantLeft": "Sair um participante",
|
||||
"playSounds": "Reproduzir som quando",
|
||||
"reactions": "Há uma reação na reunião",
|
||||
"reactions": "Expressarem uma reação",
|
||||
"sameAsSystem": "O mesmo que o sistema ({{label}})",
|
||||
"screenTitle": "Definições",
|
||||
"selectAudioOutput": "Saída de áudio",
|
||||
@@ -1193,7 +1193,7 @@
|
||||
"silence": "Silêncio",
|
||||
"speakerStats": "Estatísticas dos participantes",
|
||||
"startScreenSharing": "Iniciar partilha de ecrã",
|
||||
"startSubtitles": "Legendas • {{language}}",
|
||||
"startSubtitles": "Iniciar legendas",
|
||||
"stopAudioSharing": "Parar partilha de áudio",
|
||||
"stopScreenSharing": "Parar partilha de ecrã",
|
||||
"stopSharedVideo": "Parar vídeo",
|
||||
@@ -1216,8 +1216,6 @@
|
||||
"pending": "Preparando a transcrição da reunião...",
|
||||
"start": "Exibir legendas",
|
||||
"stop": "Não exibir legendas",
|
||||
"subtitles": "Legendas",
|
||||
"subtitlesOff": "Desligado",
|
||||
"tr": "TR"
|
||||
},
|
||||
"userMedia": {
|
||||
|
||||
@@ -25,24 +25,24 @@ import {
|
||||
setPassword,
|
||||
setSubject
|
||||
} from '../../react/features/base/conference';
|
||||
import { getWhitelistedJSON, overwriteConfig } from '../../react/features/base/config';
|
||||
import { overwriteConfig, getWhitelistedJSON } from '../../react/features/base/config';
|
||||
import { toggleDialog } from '../../react/features/base/dialog/actions';
|
||||
import { isSupportedBrowser } from '../../react/features/base/environment';
|
||||
import { parseJWTFromURLParams } from '../../react/features/base/jwt';
|
||||
import JitsiMeetJS, { JitsiRecordingConstants } from '../../react/features/base/lib-jitsi-meet';
|
||||
import { MEDIA_TYPE } from '../../react/features/base/media';
|
||||
import {
|
||||
LOCAL_PARTICIPANT_DEFAULT_ID,
|
||||
getLocalParticipant,
|
||||
getParticipantById,
|
||||
grantModerator,
|
||||
hasRaisedHand,
|
||||
isLocalParticipantModerator,
|
||||
isParticipantModerator,
|
||||
kickParticipant,
|
||||
overwriteParticipantsNames,
|
||||
pinParticipant,
|
||||
raiseHand
|
||||
kickParticipant,
|
||||
raiseHand,
|
||||
isParticipantModerator,
|
||||
isLocalParticipantModerator,
|
||||
hasRaisedHand,
|
||||
grantModerator,
|
||||
overwriteParticipantsNames,
|
||||
LOCAL_PARTICIPANT_DEFAULT_ID
|
||||
} from '../../react/features/base/participants';
|
||||
import { updateSettings } from '../../react/features/base/settings';
|
||||
import { getDisplayName } from '../../react/features/base/settings/functions.web';
|
||||
@@ -68,8 +68,7 @@ import {
|
||||
import { appendSuffix } from '../../react/features/display-name';
|
||||
import { isEnabled as isDropboxEnabled } from '../../react/features/dropbox';
|
||||
import { setMediaEncryptionKey, toggleE2EE } from '../../react/features/e2ee/actions';
|
||||
import { addStageParticipant, resizeFilmStrip, setVolume } from '../../react/features/filmstrip/actions.web';
|
||||
import { isStageFilmstripAvailable } from '../../react/features/filmstrip/functions.web';
|
||||
import { resizeFilmStrip, setVolume } from '../../react/features/filmstrip/actions.web';
|
||||
import { invite } from '../../react/features/invite';
|
||||
import {
|
||||
selectParticipantInLargeVideo
|
||||
@@ -78,12 +77,12 @@ import {
|
||||
captureLargeVideoScreenshot,
|
||||
resizeLargeVideo
|
||||
} from '../../react/features/large-video/actions.web';
|
||||
import { answerKnockingParticipant, toggleLobbyMode } from '../../react/features/lobby/actions';
|
||||
import { toggleLobbyMode, answerKnockingParticipant } from '../../react/features/lobby/actions';
|
||||
import { setNoiseSuppressionEnabled } from '../../react/features/noise-suppression/actions';
|
||||
import {
|
||||
hideNotification,
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
NOTIFICATION_TYPE,
|
||||
hideNotification,
|
||||
showNotification
|
||||
} from '../../react/features/notifications';
|
||||
import {
|
||||
@@ -91,18 +90,17 @@ import {
|
||||
open as openParticipantsPane
|
||||
} from '../../react/features/participants-pane/actions';
|
||||
import { getParticipantsPaneOpen, isForceMuted } from '../../react/features/participants-pane/functions';
|
||||
import { startLocalVideoRecording, stopLocalVideoRecording } from '../../react/features/recording';
|
||||
import { RECORDING_TYPES } from '../../react/features/recording/constants';
|
||||
import { getActiveSession, supportsLocalRecording } from '../../react/features/recording/functions';
|
||||
import { getActiveSession } from '../../react/features/recording/functions';
|
||||
import { isScreenAudioSupported } from '../../react/features/screen-share';
|
||||
import { startAudioScreenShareFlow, startScreenShareFlow } from '../../react/features/screen-share/actions';
|
||||
import { startScreenShareFlow, startAudioScreenShareFlow } from '../../react/features/screen-share/actions';
|
||||
import { toggleScreenshotCaptureSummary } from '../../react/features/screenshot-capture';
|
||||
import { isScreenshotCaptureEnabled } from '../../react/features/screenshot-capture/functions';
|
||||
import { playSharedVideo, stopSharedVideo } from '../../react/features/shared-video/actions.any';
|
||||
import { extractYoutubeIdOrURL } from '../../react/features/shared-video/functions';
|
||||
import { setRequestingSubtitles, toggleRequestingSubtitles } from '../../react/features/subtitles/actions';
|
||||
import { toggleRequestingSubtitles, setRequestingSubtitles } from '../../react/features/subtitles/actions';
|
||||
import { isAudioMuteButtonDisabled } from '../../react/features/toolbox/functions';
|
||||
import { setTileView, toggleTileView } from '../../react/features/video-layout';
|
||||
import { toggleTileView, setTileView } from '../../react/features/video-layout';
|
||||
import { muteAllParticipants } from '../../react/features/video-menu/actions';
|
||||
import { setVideoQuality } from '../../react/features/video-quality';
|
||||
import VirtualBackgroundDialog from '../../react/features/virtual-background/components/VirtualBackgroundDialog';
|
||||
@@ -237,11 +235,7 @@ function initCommands() {
|
||||
'pin-participant': id => {
|
||||
logger.debug('Pin participant command received');
|
||||
sendAnalytics(createApiEvent('participant.pinned'));
|
||||
if (isStageFilmstripAvailable(APP.store.getState())) {
|
||||
APP.store.dispatch(addStageParticipant(id, true));
|
||||
} else {
|
||||
APP.store.dispatch(pinParticipant(id));
|
||||
}
|
||||
APP.store.dispatch(pinParticipant(id));
|
||||
},
|
||||
'proxy-connection-event': event => {
|
||||
APP.conference.onProxyConnectionEvent(event);
|
||||
@@ -550,12 +544,10 @@ function initCommands() {
|
||||
* For youtube streams, `youtubeStreamKey` must be passed on. `youtubeBroadcastID` is optional.
|
||||
* For dropbox recording, recording `mode` should be `file` and a dropbox oauth2 token must be provided.
|
||||
* For file recording, recording `mode` should be `file` and optionally `shouldShare` could be passed on.
|
||||
* For local recording, recording `mode` should be `local` and optionally `onlySelf` could be passed on.
|
||||
* No other params should be passed.
|
||||
*
|
||||
* @param { string } arg.mode - Recording mode, either `local`, `file` or `stream`.
|
||||
* @param { string } arg.mode - Recording mode, either `file` or `stream`.
|
||||
* @param { string } arg.dropboxToken - Dropbox oauth2 token.
|
||||
* @param { boolean } arg.onlySelf - Whether to only record the local streams.
|
||||
* @param { string } arg.rtmpStreamKey - The RTMP stream key.
|
||||
* @param { string } arg.rtmpBroadcastID - The RTMP broadcast ID.
|
||||
* @param { boolean } arg.shouldShare - Whether the recording should be shared with the participants or not.
|
||||
@@ -567,7 +559,6 @@ function initCommands() {
|
||||
'start-recording': ({
|
||||
mode,
|
||||
dropboxToken,
|
||||
onlySelf,
|
||||
shouldShare,
|
||||
rtmpStreamKey,
|
||||
rtmpBroadcastID,
|
||||
@@ -595,26 +586,7 @@ function initCommands() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === 'local') {
|
||||
const { localRecording } = state['features/base/config'];
|
||||
|
||||
if (!localRecording?.disable && supportsLocalRecording()) {
|
||||
APP.store.dispatch(startLocalVideoRecording(onlySelf));
|
||||
} else {
|
||||
logger.error('Failed starting recording: local recording is either disabled or not supported');
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let recordingConfig;
|
||||
const { recordingService } = state['features/base/config'];
|
||||
|
||||
if (!recordingService.enabled && !dropboxToken) {
|
||||
logger.error('Failed starting recording: the recording service is not enabled');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === JitsiRecordingConstants.mode.FILE) {
|
||||
if (dropboxToken) {
|
||||
@@ -660,7 +632,7 @@ function initCommands() {
|
||||
/**
|
||||
* Stops a recording or streaming in progress.
|
||||
*
|
||||
* @param {string} mode - `local`, `file` or `stream`.
|
||||
* @param {string} mode - `file` or `stream`.
|
||||
* @returns {void}
|
||||
*/
|
||||
'stop-recording': mode => {
|
||||
@@ -673,12 +645,6 @@ function initCommands() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === 'local') {
|
||||
APP.store.dispatch(stopLocalVideoRecording());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (![ JitsiRecordingConstants.mode.FILE, JitsiRecordingConstants.mode.STREAM ].includes(mode)) {
|
||||
logger.error('Invalid recording mode provided!');
|
||||
|
||||
|
||||
1
modules/API/external/external_api.js
vendored
1
modules/API/external/external_api.js
vendored
@@ -553,7 +553,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
|
||||
this._myUserID = userID;
|
||||
this._participants[userID] = {
|
||||
email: data.email,
|
||||
avatarURL: data.avatarURL
|
||||
};
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ import { setColorAlpha } from '../../react/features/base/util';
|
||||
import { setDocumentUrl } from '../../react/features/etherpad';
|
||||
import { setFilmstripVisible } from '../../react/features/filmstrip';
|
||||
import {
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
joinLeaveNotificationsDisabled,
|
||||
setNotificationsEnabled,
|
||||
showNotification
|
||||
showNotification,
|
||||
NOTIFICATION_TIMEOUT_TYPE
|
||||
} from '../../react/features/notifications';
|
||||
import {
|
||||
dockToolbox,
|
||||
|
||||
@@ -11,8 +11,8 @@ import {
|
||||
WaitForOwnerDialog
|
||||
} from '../../../react/features/authentication/components';
|
||||
import {
|
||||
getTokenAuthUrl,
|
||||
isTokenAuthEnabled
|
||||
isTokenAuthEnabled,
|
||||
getTokenAuthUrl
|
||||
} from '../../../react/features/authentication/functions';
|
||||
import { getReplaceParticipant } from '../../../react/features/base/config/functions';
|
||||
import { isDialogOpen } from '../../../react/features/base/dialog';
|
||||
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
isTrackStreamingStatusInactive,
|
||||
isTrackStreamingStatusInterrupted
|
||||
} from '../../../react/features/connection-indicator/functions';
|
||||
import { FILMSTRIP_BREAKPOINT, getVerticalViewMaxWidth, isFilmstripResizable } from '../../../react/features/filmstrip';
|
||||
import { FILMSTRIP_BREAKPOINT, isFilmstripResizable, getVerticalViewMaxWidth } from '../../../react/features/filmstrip';
|
||||
import {
|
||||
updateKnownLargeVideoResolution
|
||||
} from '../../../react/features/large-video/actions';
|
||||
@@ -45,7 +45,7 @@ import { shouldDisplayTileView } from '../../../react/features/video-layout';
|
||||
import { createDeferred } from '../../util/helpers';
|
||||
import AudioLevels from '../audio_levels/AudioLevels';
|
||||
|
||||
import { VIDEO_CONTAINER_TYPE, VideoContainer } from './VideoContainer';
|
||||
import { VideoContainer, VIDEO_CONTAINER_TYPE } from './VideoContainer';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import ReactDOM from 'react-dom';
|
||||
import { browser } from '../../../react/features/base/lib-jitsi-meet';
|
||||
import { isTestModeEnabled } from '../../../react/features/base/testing';
|
||||
import { FILMSTRIP_BREAKPOINT } from '../../../react/features/filmstrip';
|
||||
import { LargeVideoBackground, ORIENTATION, updateLastLargeVideoMediaEvent } from '../../../react/features/large-video';
|
||||
import { ORIENTATION, LargeVideoBackground, updateLastLargeVideoMediaEvent } from '../../../react/features/large-video';
|
||||
import { setLargeVideoDimensions } from '../../../react/features/large-video/actions.any';
|
||||
import { LAYOUTS, getCurrentLayout } from '../../../react/features/video-layout';
|
||||
/* eslint-enable no-unused-vars */
|
||||
|
||||
@@ -5,8 +5,8 @@ import Logger from '@jitsi/logger';
|
||||
import { getMultipleVideoSupportFeatureFlag } from '../../../react/features/base/config';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE } from '../../../react/features/base/media';
|
||||
import {
|
||||
getParticipantById,
|
||||
getPinnedParticipant
|
||||
getPinnedParticipant,
|
||||
getParticipantById
|
||||
} from '../../../react/features/base/participants';
|
||||
import {
|
||||
getTrackByMediaTypeAndParticipant,
|
||||
|
||||
120
package-lock.json
generated
120
package-lock.json
generated
@@ -11,6 +11,7 @@
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@amplitude/react-native": "2.7.0",
|
||||
"@atlaskit/dropdown-menu": "10.1.2",
|
||||
"@atlaskit/field-text-area": "8.0.4",
|
||||
"@atlaskit/flag": "14.1.0",
|
||||
"@atlaskit/icon": "21.2.0",
|
||||
@@ -73,7 +74,7 @@
|
||||
"js-md5": "0.6.1",
|
||||
"js-sha512": "0.8.0",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1506.0.0+3fc03265/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1498.0.0+bc3aae02/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
@@ -99,7 +100,6 @@
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "^1.5.0",
|
||||
"react-native-pager-view": "5.4.9",
|
||||
"react-native-paper": "4.11.1",
|
||||
"react-native-performance": "2.1.0",
|
||||
@@ -113,7 +113,7 @@
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
|
||||
"react-native-watch-connectivity": "1.0.11",
|
||||
"react-native-webrtc": "https://git@github.com/react-native-webrtc/react-native-webrtc#ed07969a85c159953d3004cfd04d44792b95e8db",
|
||||
"react-native-webrtc": "1.100.1",
|
||||
"react-native-webview": "11.15.1",
|
||||
"react-native-youtube-iframe": "2.2.1",
|
||||
"react-redux": "7.1.0",
|
||||
@@ -142,7 +142,7 @@
|
||||
"@babel/preset-flow": "7.16.0",
|
||||
"@babel/preset-react": "7.16.0",
|
||||
"@babel/runtime": "7.16.0",
|
||||
"@jitsi/eslint-config": "4.1.3",
|
||||
"@jitsi/eslint-config": "4.1.2",
|
||||
"@types/js-md5": "0.4.3",
|
||||
"@types/lodash": "4.14.182",
|
||||
"@types/react": "17.0.14",
|
||||
@@ -372,6 +372,28 @@
|
||||
"@babel/runtime": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@atlaskit/dropdown-menu": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@atlaskit/dropdown-menu/-/dropdown-menu-10.1.2.tgz",
|
||||
"integrity": "sha512-1E03eM0aoXxwzTzRamnRrBsC9OX1mU2YATfDb45RZRmz+kOx0bw1q5xGXLQsHpUPZFgfK8rdFy8h94qvrucKsQ==",
|
||||
"dependencies": {
|
||||
"@atlaskit/analytics-next": "^8.0.0",
|
||||
"@atlaskit/button": "^15.1.0",
|
||||
"@atlaskit/droplist": "^11.0.0",
|
||||
"@atlaskit/icon": "^21.1.0",
|
||||
"@atlaskit/item": "^12.0.0",
|
||||
"@atlaskit/theme": "^11.0.0",
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"array-find": "^1.0.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react-uid": "^2.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0",
|
||||
"react-dom": "^16.8.0",
|
||||
"styled-components": "^3.2.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@atlaskit/droplist": {
|
||||
"version": "11.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@atlaskit/droplist/-/droplist-11.0.9.tgz",
|
||||
@@ -3723,9 +3745,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jitsi/eslint-config": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@jitsi/eslint-config/-/eslint-config-4.1.3.tgz",
|
||||
"integrity": "sha512-Fl3bvasAOREemcCdKXpBJDayuNl2CFIHkvNjUCqCs8uorHAMdagjbqBvg4ow7GnMamQdCrcdpIpZfeOmf+FTJQ==",
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jitsi/eslint-config/-/eslint-config-4.1.2.tgz",
|
||||
"integrity": "sha512-kAkCLEKSWdwqj8L026T/5+FttvPLmNkPPETfgzG4SxWdkIVsW8wqFN/RypUZp2H7NmL5AgVL+QkXQXoEoQgW8A==",
|
||||
"dev": true,
|
||||
"peerDependencies": {
|
||||
"@babel/eslint-parser": ">= 7",
|
||||
@@ -7023,14 +7045,6 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/adm-zip": {
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
|
||||
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==",
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@@ -7301,6 +7315,11 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/array-find": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz",
|
||||
"integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg="
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
|
||||
@@ -13050,8 +13069,8 @@
|
||||
},
|
||||
"node_modules/lib-jitsi-meet": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1506.0.0+3fc03265/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-Dga5fB3eJwCnKlpxr4jQYoyfcL0si78tI+NOYGCn3Mc97FFmzxdjux0WLv6+/XFUqRnxTN/P57ECDXMCdyxysw==",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1498.0.0+bc3aae02/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-x796ul9mZXK+AaxxKL0FLmhUR23YibExkoBCsQr9LoSeN5mJskbRTQB8phTcnDbxFh4+0Xp+xzi7zOpuHsisWA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
@@ -15916,16 +15935,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-keep-awake/-/react-native-keep-awake-4.0.0.tgz",
|
||||
"integrity": "sha512-0Fotox+eLXQooeibVs3P60yASYUWjtRw9MZNmbuHt5UZQrgUrAKsE4jm7gTr4tPU1m1RkwGzcgUFpcOkh/ec7g=="
|
||||
},
|
||||
"node_modules/react-native-orientation-locker": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-orientation-locker/-/react-native-orientation-locker-1.5.0.tgz",
|
||||
"integrity": "sha512-4XOCGmNN4BXg5JUFjUuXpsfhPJmbA3LkQilJO1ed+6vL97teTdG2w5IEevKiqL9/hPjeWE8YYtX/YW+yp53hkg==",
|
||||
"peerDependencies": {
|
||||
"react": ">=16.13.1",
|
||||
"react-native": ">=0.63.2",
|
||||
"react-native-windows": ">=0.63.3"
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-pager-view": {
|
||||
"version": "5.4.9",
|
||||
"resolved": "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-5.4.9.tgz",
|
||||
@@ -16578,13 +16587,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-webrtc": {
|
||||
"version": "1.106.0",
|
||||
"resolved": "git+https://git@github.com/react-native-webrtc/react-native-webrtc.git#ed07969a85c159953d3004cfd04d44792b95e8db",
|
||||
"integrity": "sha512-hpYt1DuN0QCBuZOXoqR51AxIU2n0lKcGS2YGsww1wYXBCwVzKi6mhVyDVPNH7bU93UBXXnMCzLI4VJzv70GoYg==",
|
||||
"version": "1.100.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-1.100.1.tgz",
|
||||
"integrity": "sha512-2dF8HrZWdfrbm1NLso424xgNeGFf4WK5Jlqs7ecVDvCMWHTYVHVwyNt52zx1yiOMEqQWk4edOd4xhWJfUiOvMg==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"adm-zip": "0.5.9",
|
||||
"base64-js": "1.5.1",
|
||||
"event-target-shim": "6.0.2",
|
||||
"tar": "6.1.11"
|
||||
@@ -20759,6 +20766,23 @@
|
||||
"@babel/runtime": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@atlaskit/dropdown-menu": {
|
||||
"version": "10.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@atlaskit/dropdown-menu/-/dropdown-menu-10.1.2.tgz",
|
||||
"integrity": "sha512-1E03eM0aoXxwzTzRamnRrBsC9OX1mU2YATfDb45RZRmz+kOx0bw1q5xGXLQsHpUPZFgfK8rdFy8h94qvrucKsQ==",
|
||||
"requires": {
|
||||
"@atlaskit/analytics-next": "^8.0.0",
|
||||
"@atlaskit/button": "^15.1.0",
|
||||
"@atlaskit/droplist": "^11.0.0",
|
||||
"@atlaskit/icon": "^21.1.0",
|
||||
"@atlaskit/item": "^12.0.0",
|
||||
"@atlaskit/theme": "^11.0.0",
|
||||
"@babel/runtime": "^7.0.0",
|
||||
"array-find": "^1.0.0",
|
||||
"prop-types": "^15.5.10",
|
||||
"react-uid": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"@atlaskit/droplist": {
|
||||
"version": "11.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@atlaskit/droplist/-/droplist-11.0.9.tgz",
|
||||
@@ -23210,9 +23234,9 @@
|
||||
}
|
||||
},
|
||||
"@jitsi/eslint-config": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@jitsi/eslint-config/-/eslint-config-4.1.3.tgz",
|
||||
"integrity": "sha512-Fl3bvasAOREemcCdKXpBJDayuNl2CFIHkvNjUCqCs8uorHAMdagjbqBvg4ow7GnMamQdCrcdpIpZfeOmf+FTJQ==",
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jitsi/eslint-config/-/eslint-config-4.1.2.tgz",
|
||||
"integrity": "sha512-kAkCLEKSWdwqj8L026T/5+FttvPLmNkPPETfgzG4SxWdkIVsW8wqFN/RypUZp2H7NmL5AgVL+QkXQXoEoQgW8A==",
|
||||
"dev": true
|
||||
},
|
||||
"@jitsi/js-utils": {
|
||||
@@ -25656,11 +25680,6 @@
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||
"dev": true
|
||||
},
|
||||
"adm-zip": {
|
||||
"version": "0.5.9",
|
||||
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
|
||||
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg=="
|
||||
},
|
||||
"agent-base": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
|
||||
@@ -25869,6 +25888,11 @@
|
||||
"resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
|
||||
"integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ="
|
||||
},
|
||||
"array-find": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz",
|
||||
"integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg="
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz",
|
||||
@@ -30309,8 +30333,8 @@
|
||||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1506.0.0+3fc03265/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-Dga5fB3eJwCnKlpxr4jQYoyfcL0si78tI+NOYGCn3Mc97FFmzxdjux0WLv6+/XFUqRnxTN/P57ECDXMCdyxysw==",
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1498.0.0+bc3aae02/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-x796ul9mZXK+AaxxKL0FLmhUR23YibExkoBCsQr9LoSeN5mJskbRTQB8phTcnDbxFh4+0Xp+xzi7zOpuHsisWA==",
|
||||
"requires": {
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
@@ -32514,11 +32538,6 @@
|
||||
"resolved": "https://registry.npmjs.org/react-native-keep-awake/-/react-native-keep-awake-4.0.0.tgz",
|
||||
"integrity": "sha512-0Fotox+eLXQooeibVs3P60yASYUWjtRw9MZNmbuHt5UZQrgUrAKsE4jm7gTr4tPU1m1RkwGzcgUFpcOkh/ec7g=="
|
||||
},
|
||||
"react-native-orientation-locker": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-orientation-locker/-/react-native-orientation-locker-1.5.0.tgz",
|
||||
"integrity": "sha512-4XOCGmNN4BXg5JUFjUuXpsfhPJmbA3LkQilJO1ed+6vL97teTdG2w5IEevKiqL9/hPjeWE8YYtX/YW+yp53hkg=="
|
||||
},
|
||||
"react-native-pager-view": {
|
||||
"version": "5.4.9",
|
||||
"resolved": "https://registry.npmjs.org/react-native-pager-view/-/react-native-pager-view-5.4.9.tgz",
|
||||
@@ -32904,11 +32923,10 @@
|
||||
}
|
||||
},
|
||||
"react-native-webrtc": {
|
||||
"version": "git+https://git@github.com/react-native-webrtc/react-native-webrtc.git#ed07969a85c159953d3004cfd04d44792b95e8db",
|
||||
"integrity": "sha512-hpYt1DuN0QCBuZOXoqR51AxIU2n0lKcGS2YGsww1wYXBCwVzKi6mhVyDVPNH7bU93UBXXnMCzLI4VJzv70GoYg==",
|
||||
"from": "react-native-webrtc@https://git@github.com/react-native-webrtc/react-native-webrtc#ed07969a85c159953d3004cfd04d44792b95e8db",
|
||||
"version": "1.100.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-1.100.1.tgz",
|
||||
"integrity": "sha512-2dF8HrZWdfrbm1NLso424xgNeGFf4WK5Jlqs7ecVDvCMWHTYVHVwyNt52zx1yiOMEqQWk4edOd4xhWJfUiOvMg==",
|
||||
"requires": {
|
||||
"adm-zip": "0.5.9",
|
||||
"base64-js": "1.5.1",
|
||||
"event-target-shim": "6.0.2",
|
||||
"tar": "6.1.11"
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"readmeFilename": "README.md",
|
||||
"dependencies": {
|
||||
"@amplitude/react-native": "2.7.0",
|
||||
"@atlaskit/dropdown-menu": "10.1.2",
|
||||
"@atlaskit/field-text-area": "8.0.4",
|
||||
"@atlaskit/flag": "14.1.0",
|
||||
"@atlaskit/icon": "21.2.0",
|
||||
@@ -78,7 +79,7 @@
|
||||
"js-md5": "0.6.1",
|
||||
"js-sha512": "0.8.0",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1506.0.0+3fc03265/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1498.0.0+bc3aae02/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
@@ -104,7 +105,6 @@
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-orientation-locker": "^1.5.0",
|
||||
"react-native-pager-view": "5.4.9",
|
||||
"react-native-paper": "4.11.1",
|
||||
"react-native-performance": "2.1.0",
|
||||
@@ -118,7 +118,7 @@
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
|
||||
"react-native-watch-connectivity": "1.0.11",
|
||||
"react-native-webrtc": "https://git@github.com/react-native-webrtc/react-native-webrtc#ed07969a85c159953d3004cfd04d44792b95e8db",
|
||||
"react-native-webrtc": "1.100.1",
|
||||
"react-native-webview": "11.15.1",
|
||||
"react-native-youtube-iframe": "2.2.1",
|
||||
"react-redux": "7.1.0",
|
||||
@@ -147,7 +147,7 @@
|
||||
"@babel/preset-flow": "7.16.0",
|
||||
"@babel/preset-react": "7.16.0",
|
||||
"@babel/runtime": "7.16.0",
|
||||
"@jitsi/eslint-config": "4.1.3",
|
||||
"@jitsi/eslint-config": "4.1.2",
|
||||
"@types/js-md5": "0.4.3",
|
||||
"@types/lodash": "4.14.182",
|
||||
"@types/react": "17.0.14",
|
||||
|
||||
@@ -22,8 +22,8 @@ import {
|
||||
} from '../base/util';
|
||||
import { isVpaasMeeting } from '../jaas/functions';
|
||||
import {
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
clearNotifications,
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
showNotification
|
||||
} from '../notifications';
|
||||
import { setFatalError } from '../overlay';
|
||||
|
||||
@@ -6,7 +6,7 @@ import { hideDialog, openDialog } from '../base/dialog/actions';
|
||||
import {
|
||||
CANCEL_LOGIN
|
||||
} from './actionTypes';
|
||||
import { LoginDialog, WaitForOwnerDialog } from './components';
|
||||
import { WaitForOwnerDialog, LoginDialog } from './components';
|
||||
|
||||
export * from './actions.any';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { Dispatch } from 'redux';
|
||||
import { ConfirmDialog } from '../../../base/dialog';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { cancelWaitForOwner, openLoginDialog } from '../../actions.native';
|
||||
import { openLoginDialog, cancelWaitForOwner } from '../../actions.native';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
|
||||
|
||||
@@ -8,19 +8,19 @@ import { Participant } from '../base/participants/types';
|
||||
import { isForceMuted } from '../participants-pane/functions';
|
||||
|
||||
import {
|
||||
DISABLE_MODERATION,
|
||||
DISMISS_PENDING_PARTICIPANT,
|
||||
DISABLE_MODERATION,
|
||||
ENABLE_MODERATION,
|
||||
LOCAL_PARTICIPANT_APPROVED,
|
||||
LOCAL_PARTICIPANT_MODERATION_NOTIFICATION,
|
||||
LOCAL_PARTICIPANT_REJECTED,
|
||||
PARTICIPANT_APPROVED,
|
||||
PARTICIPANT_PENDING_AUDIO,
|
||||
PARTICIPANT_REJECTED,
|
||||
REQUEST_DISABLE_AUDIO_MODERATION,
|
||||
REQUEST_DISABLE_VIDEO_MODERATION,
|
||||
REQUEST_ENABLE_AUDIO_MODERATION,
|
||||
REQUEST_ENABLE_VIDEO_MODERATION
|
||||
REQUEST_DISABLE_VIDEO_MODERATION,
|
||||
REQUEST_ENABLE_VIDEO_MODERATION,
|
||||
LOCAL_PARTICIPANT_REJECTED,
|
||||
PARTICIPANT_REJECTED
|
||||
} from './actionTypes';
|
||||
import { isEnabledFromState } from './functions';
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { isLocalParticipantModerator } from '../base/participants/functions';
|
||||
import { Participant } from '../base/participants/types';
|
||||
import { isInBreakoutRoom } from '../breakout-rooms/functions';
|
||||
|
||||
import { MEDIA_TYPE_TO_PENDING_STORE_KEY, MEDIA_TYPE_TO_WHITELIST_STORE_KEY } from './constants';
|
||||
import { MEDIA_TYPE_TO_WHITELIST_STORE_KEY, MEDIA_TYPE_TO_PENDING_STORE_KEY } from './constants';
|
||||
|
||||
/**
|
||||
* Returns this feature's root state.
|
||||
|
||||
@@ -5,7 +5,7 @@ import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../base/app/actionTypes';
|
||||
// @ts-ignore
|
||||
import { getConferenceState } from '../base/conference';
|
||||
import { JitsiConferenceEvents } from '../base/lib-jitsi-meet';
|
||||
import { MEDIA_TYPE, MediaType } from '../base/media/constants';
|
||||
import { MediaType, MEDIA_TYPE } from '../base/media/constants';
|
||||
import { PARTICIPANT_UPDATED } from '../base/participants/actionTypes';
|
||||
import { raiseHand } from '../base/participants/actions';
|
||||
import {
|
||||
@@ -40,13 +40,13 @@ import {
|
||||
} from './actionTypes';
|
||||
import {
|
||||
disableModeration,
|
||||
dismissPendingAudioParticipant,
|
||||
dismissPendingParticipant,
|
||||
dismissPendingAudioParticipant,
|
||||
enableModeration,
|
||||
localParticipantApproved,
|
||||
localParticipantRejected,
|
||||
participantApproved,
|
||||
participantPendingAudio,
|
||||
localParticipantRejected,
|
||||
participantRejected
|
||||
} from './actions';
|
||||
import {
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { IStore } from '../../app/types';
|
||||
// @flow
|
||||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||
|
||||
declare var APP;
|
||||
|
||||
/**
|
||||
* Signals that a specific App will mount (in the terms of React).
|
||||
*
|
||||
@@ -12,7 +16,7 @@ import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||
* }}
|
||||
*/
|
||||
export function appWillMount(app: Object) {
|
||||
return (dispatch: IStore['dispatch']) => {
|
||||
return (dispatch: Dispatch<any>) => {
|
||||
// TODO There was a redux action creator appInit which I did not like
|
||||
// because we already had the redux action creator appWillMount and,
|
||||
// respectively, the redux action APP_WILL_MOUNT. So I set out to remove
|
||||
@@ -1,19 +1,19 @@
|
||||
import { toState } from '../redux/functions';
|
||||
// @flow
|
||||
|
||||
import { IStateful } from './types';
|
||||
import { toState } from '../redux';
|
||||
|
||||
/**
|
||||
* Gets the value of a specific React {@code Component} prop of the currently
|
||||
* mounted {@link App}.
|
||||
*
|
||||
* @param {IStateful} stateful - The redux store or {@code getState}
|
||||
* @param {Function|Object} stateful - The redux store or {@code getState}
|
||||
* function.
|
||||
* @param {string} propName - The name of the React {@code Component} prop of
|
||||
* the currently mounted {@code App} to get.
|
||||
* @returns {*} The value of the specified React {@code Component} prop of the
|
||||
* currently mounted {@code App}.
|
||||
*/
|
||||
export function getAppProp(stateful: IStateful, propName: string) {
|
||||
export function getAppProp(stateful: Function | Object, propName: string) {
|
||||
const state = toState(stateful)['features/base/app'];
|
||||
|
||||
if (state) {
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/app');
|
||||
@@ -3,7 +3,7 @@ import ReducerRegistry from '../redux/ReducerRegistry';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
|
||||
|
||||
export interface IAppState {
|
||||
app?: any;
|
||||
app?: Object | undefined;
|
||||
}
|
||||
|
||||
ReducerRegistry.register<IAppState>('features/base/app', (state = {}, action): IAppState => {
|
||||
|
||||
@@ -7,7 +7,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import Icon from '../icons/components/Icon';
|
||||
import { IconCheck, IconCopy } from '../icons/svg';
|
||||
import { withPixelLineHeight } from '../styles/functions.web';
|
||||
import { copyText } from '../util/copyText';
|
||||
import { copyText } from '../util/helpers';
|
||||
|
||||
const styles = (theme: Theme) => {
|
||||
return {
|
||||
|
||||
@@ -41,8 +41,8 @@ import { getBackendSafeRoomName } from '../util';
|
||||
import {
|
||||
AUTH_STATUS_CHANGED,
|
||||
CONFERENCE_FAILED,
|
||||
CONFERENCE_JOINED,
|
||||
CONFERENCE_JOIN_IN_PROGRESS,
|
||||
CONFERENCE_JOINED,
|
||||
CONFERENCE_LEFT,
|
||||
CONFERENCE_LOCAL_SUBJECT_CHANGED,
|
||||
CONFERENCE_SUBJECT_CHANGED,
|
||||
@@ -61,8 +61,8 @@ import {
|
||||
SET_OBFUSCATED_ROOM,
|
||||
SET_PASSWORD,
|
||||
SET_PASSWORD_FAILED,
|
||||
SET_PENDING_SUBJECT_CHANGE,
|
||||
SET_ROOM,
|
||||
SET_PENDING_SUBJECT_CHANGE,
|
||||
SET_START_MUTED_POLICY,
|
||||
SET_START_REACTIONS_MUTED
|
||||
} from './actionTypes';
|
||||
@@ -76,8 +76,8 @@ import {
|
||||
commonUserJoinedHandling,
|
||||
commonUserLeftHandling,
|
||||
getConferenceOptions,
|
||||
getConferenceState,
|
||||
getCurrentConference,
|
||||
getConferenceState,
|
||||
sendLocalParticipant
|
||||
} from './functions';
|
||||
import logger from './logger';
|
||||
@@ -216,9 +216,7 @@ function _addConferenceListeners(conference, dispatch, state) {
|
||||
|
||||
conference.on(
|
||||
JitsiConferenceEvents.DOMINANT_SPEAKER_CHANGED,
|
||||
(dominant, previous, silence) => {
|
||||
dispatch(dominantSpeakerChanged(dominant, previous, Boolean(silence), conference));
|
||||
});
|
||||
(dominant, previous) => dispatch(dominantSpeakerChanged(dominant, previous, conference)));
|
||||
|
||||
conference.on(
|
||||
JitsiConferenceEvents.ENDPOINT_MESSAGE_RECEIVED,
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
// @flow
|
||||
|
||||
import { sha512_256 as sha512 } from 'js-sha512';
|
||||
import _ from 'lodash';
|
||||
|
||||
// @ts-ignore
|
||||
import { getName } from '../../app/functions';
|
||||
import { IState, IStore } from '../../app/types';
|
||||
import { determineTranscriptionLanguage } from '../../transcribing/functions';
|
||||
import { IStateful } from '../app/types';
|
||||
import { JitsiTrackErrors } from '../lib-jitsi-meet';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
hiddenParticipantJoined,
|
||||
hiddenParticipantLeft,
|
||||
participantJoined,
|
||||
participantLeft
|
||||
} from '../participants/actions';
|
||||
import { getLocalParticipant } from '../participants/functions';
|
||||
import { toState } from '../redux/functions';
|
||||
import { getJitsiMeetGlobalNS } from '../util/helpers';
|
||||
import { getBackendSafePath, safeDecodeURIComponent } from '../util/uri';
|
||||
} from '../participants';
|
||||
import { toState } from '../redux';
|
||||
import {
|
||||
getBackendSafePath,
|
||||
getJitsiMeetGlobalNS,
|
||||
safeDecodeURIComponent
|
||||
} from '../util';
|
||||
|
||||
// @ts-ignore
|
||||
import { setObfuscatedRoom } from './actions';
|
||||
import {
|
||||
AVATAR_URL_COMMAND,
|
||||
@@ -26,23 +27,22 @@ import {
|
||||
JITSI_CONFERENCE_URL_KEY
|
||||
} from './constants';
|
||||
import logger from './logger';
|
||||
import { IJitsiConference } from './reducer';
|
||||
|
||||
/**
|
||||
* Returns root conference state.
|
||||
*
|
||||
* @param {IState} state - Global state.
|
||||
* @param {Object} state - Global state.
|
||||
* @returns {Object} Conference state.
|
||||
*/
|
||||
export const getConferenceState = (state: IState) => state['features/base/conference'];
|
||||
export const getConferenceState = (state: Object) => state['features/base/conference'];
|
||||
|
||||
/**
|
||||
* Is the conference joined or not.
|
||||
*
|
||||
* @param {IState} state - Global state.
|
||||
* @param {Object} state - Global state.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const getIsConferenceJoined = (state: IState) => Boolean(getConferenceState(state).conference);
|
||||
export const getIsConferenceJoined = (state: Object) => Boolean(getConferenceState(state).conference);
|
||||
|
||||
/**
|
||||
* Attach a set of local tracks to a conference.
|
||||
@@ -53,7 +53,7 @@ export const getIsConferenceJoined = (state: IState) => Boolean(getConferenceSta
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function _addLocalTracksToConference(
|
||||
conference: IJitsiConference,
|
||||
conference: { addTrack: Function, getLocalTracks: Function },
|
||||
localTracks: Array<Object>) {
|
||||
const conferenceLocalTracks = conference.getLocalTracks();
|
||||
const promises = [];
|
||||
@@ -63,7 +63,7 @@ export function _addLocalTracksToConference(
|
||||
// adding one and the same video track multiple times.
|
||||
if (conferenceLocalTracks.indexOf(track) === -1) {
|
||||
promises.push(
|
||||
conference.addTrack(track).catch((err: Error) => {
|
||||
conference.addTrack(track).catch(err => {
|
||||
_reportError(
|
||||
'Failed to add local track to conference',
|
||||
err);
|
||||
@@ -86,16 +86,16 @@ export function _addLocalTracksToConference(
|
||||
* @returns {void}
|
||||
*/
|
||||
export function commonUserJoinedHandling(
|
||||
{ dispatch }: IStore,
|
||||
conference: IJitsiConference,
|
||||
user: any) {
|
||||
{ dispatch }: Object,
|
||||
conference: Object,
|
||||
user: Object) {
|
||||
const id = user.getId();
|
||||
const displayName = user.getDisplayName();
|
||||
|
||||
if (user.isHidden()) {
|
||||
dispatch(hiddenParticipantJoined(id, displayName));
|
||||
} else {
|
||||
const isReplacing = user?.isReplacing();
|
||||
const isReplacing = user.isReplacing && user.isReplacing();
|
||||
|
||||
dispatch(participantJoined({
|
||||
botType: user.getBotType(),
|
||||
@@ -122,15 +122,15 @@ export function commonUserJoinedHandling(
|
||||
* @returns {void}
|
||||
*/
|
||||
export function commonUserLeftHandling(
|
||||
{ dispatch }: IStore,
|
||||
conference: IJitsiConference,
|
||||
user: any) {
|
||||
{ dispatch }: Object,
|
||||
conference: Object,
|
||||
user: Object) {
|
||||
const id = user.getId();
|
||||
|
||||
if (user.isHidden()) {
|
||||
dispatch(hiddenParticipantLeft(id));
|
||||
} else {
|
||||
const isReplaced = user.isReplaced?.();
|
||||
const isReplaced = user.isReplaced && user.isReplaced();
|
||||
|
||||
dispatch(participantLeft(id, conference, { isReplaced }));
|
||||
}
|
||||
@@ -140,7 +140,7 @@ export function commonUserLeftHandling(
|
||||
* Evaluates a specific predicate for each {@link JitsiConference} known to the
|
||||
* redux state features/base/conference while it returns {@code true}.
|
||||
*
|
||||
* @param {IStateful} stateful - The redux store, state, or
|
||||
* @param {Function | Object} stateful - The redux store, state, or
|
||||
* {@code getState} function.
|
||||
* @param {Function} predicate - The predicate to evaluate for each
|
||||
* {@code JitsiConference} know to the redux state features/base/conference
|
||||
@@ -150,8 +150,8 @@ export function commonUserLeftHandling(
|
||||
* features/base/conference.
|
||||
*/
|
||||
export function forEachConference(
|
||||
stateful: IStateful,
|
||||
predicate: (a: any, b: URL) => boolean) {
|
||||
stateful: Function | Object,
|
||||
predicate: (Object, URL) => boolean) {
|
||||
const state = getConferenceState(toState(stateful));
|
||||
|
||||
for (const v of Object.values(state)) {
|
||||
@@ -178,48 +178,48 @@ export function forEachConference(
|
||||
/**
|
||||
* Returns the display name of the conference.
|
||||
*
|
||||
* @param {IStateful} stateful - Reference that can be resolved to Redux
|
||||
* @param {Function | Object} stateful - Reference that can be resolved to Redux
|
||||
* state with the {@code toState} function.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getConferenceName(stateful: IStateful): string {
|
||||
export function getConferenceName(stateful: Function | Object): string {
|
||||
const state = toState(stateful);
|
||||
const { callee } = state['features/base/jwt'];
|
||||
const { callDisplayName } = state['features/base/config'];
|
||||
const { localSubject, room, subject } = getConferenceState(state);
|
||||
|
||||
return (localSubject
|
||||
return localSubject
|
||||
|| subject
|
||||
|| callDisplayName
|
||||
|| callee?.name
|
||||
|| (room && safeStartCase(safeDecodeURIComponent(room)))) ?? '';
|
||||
|| (callee && callee.name)
|
||||
|| (room && safeStartCase(safeDecodeURIComponent(room)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the conference formatted for the title.
|
||||
*
|
||||
* @param {IStateful} stateful - Reference that can be resolved to Redux state with the {@code toState}
|
||||
* @param {Function | Object} stateful - Reference that can be resolved to Redux state with the {@code toState}
|
||||
* function.
|
||||
* @returns {string} - The name of the conference formatted for the title.
|
||||
*/
|
||||
export function getConferenceNameForTitle(stateful: IStateful) {
|
||||
return safeStartCase(safeDecodeURIComponent(getConferenceState(toState(stateful)).room ?? ''));
|
||||
export function getConferenceNameForTitle(stateful: Function | Object) {
|
||||
return safeStartCase(safeDecodeURIComponent(getConferenceState(toState(stateful)).room));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object aggregating the conference options.
|
||||
*
|
||||
* @param {IStateful} stateful - The redux store state.
|
||||
* @param {Object|Function} stateful - The redux store state.
|
||||
* @returns {Object} - Options object.
|
||||
*/
|
||||
export function getConferenceOptions(stateful: IStateful) {
|
||||
export function getConferenceOptions(stateful: Function | Object) {
|
||||
const state = toState(stateful);
|
||||
|
||||
const config = state['features/base/config'];
|
||||
const { locationURL } = state['features/base/connection'];
|
||||
const { tenant } = state['features/base/jwt'];
|
||||
const { email, name: nick } = getLocalParticipant(state) ?? {};
|
||||
const options: any = { ...config };
|
||||
const { email, name: nick } = getLocalParticipant(state);
|
||||
const options = { ...config };
|
||||
|
||||
if (tenant) {
|
||||
options.siteID = tenant;
|
||||
@@ -257,11 +257,11 @@ export function getConferenceOptions(stateful: IStateful) {
|
||||
/**
|
||||
* Returns the UTC timestamp when the first participant joined the conference.
|
||||
*
|
||||
* @param {IStateful} stateful - Reference that can be resolved to Redux
|
||||
* @param {Function | Object} stateful - Reference that can be resolved to Redux
|
||||
* state with the {@code toState} function.
|
||||
* @returns {number}
|
||||
*/
|
||||
export function getConferenceTimestamp(stateful: IStateful) {
|
||||
export function getConferenceTimestamp(stateful: Function | Object): number {
|
||||
const state = toState(stateful);
|
||||
const { conferenceTimestamp } = getConferenceState(state);
|
||||
|
||||
@@ -274,11 +274,11 @@ export function getConferenceTimestamp(stateful: IStateful) {
|
||||
* {@code conference} state of the feature base/conference which is not joining
|
||||
* but may be leaving already.
|
||||
*
|
||||
* @param {IStateful} stateful - The redux store, state, or
|
||||
* @param {Function|Object} stateful - The redux store, state, or
|
||||
* {@code getState} function.
|
||||
* @returns {JitsiConference|undefined}
|
||||
*/
|
||||
export function getCurrentConference(stateful: IStateful): any {
|
||||
export function getCurrentConference(stateful: Function | Object) {
|
||||
const { conference, joining, leaving, membersOnly, passwordRequired }
|
||||
= getConferenceState(toState(stateful));
|
||||
|
||||
@@ -293,29 +293,25 @@ export function getCurrentConference(stateful: IStateful): any {
|
||||
/**
|
||||
* Returns the stored room name.
|
||||
*
|
||||
* @param {IState} state - The current state of the app.
|
||||
* @param {Object} state - The current state of the app.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getRoomName(state: IState) {
|
||||
export function getRoomName(state: Object): string {
|
||||
return getConferenceState(state).room;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an obfuscated room name or create and persist it if it doesn't exists.
|
||||
*
|
||||
* @param {IState} state - The current state of the app.
|
||||
* @param {Object} state - The current state of the app.
|
||||
* @param {Function} dispatch - The Redux dispatch function.
|
||||
* @returns {string} - Obfuscated room name.
|
||||
*/
|
||||
export function getOrCreateObfuscatedRoomName(state: IState, dispatch: IStore['dispatch']) {
|
||||
export function getOrCreateObfuscatedRoomName(state: Object, dispatch: Function) {
|
||||
let { obfuscatedRoom } = getConferenceState(state);
|
||||
const { obfuscatedRoomSource } = getConferenceState(state);
|
||||
const room = getRoomName(state);
|
||||
|
||||
if (!room) {
|
||||
return;
|
||||
}
|
||||
|
||||
// On native mobile the store doesn't clear when joining a new conference so we might have the obfuscatedRoom
|
||||
// stored even though a different room was joined.
|
||||
// Check if the obfuscatedRoom was already computed for the current room.
|
||||
@@ -331,11 +327,11 @@ export function getOrCreateObfuscatedRoomName(state: IState, dispatch: IStore['d
|
||||
* Analytics may require an obfuscated room name, this functions decides based on a config if the normal or
|
||||
* obfuscated room name should be returned.
|
||||
*
|
||||
* @param {IState} state - The current state of the app.
|
||||
* @param {Object} state - The current state of the app.
|
||||
* @param {Function} dispatch - The Redux dispatch function.
|
||||
* @returns {string} - Analytics room name.
|
||||
*/
|
||||
export function getAnalyticsRoomName(state: IState, dispatch: IStore['dispatch']) {
|
||||
export function getAnalyticsRoomName(state: Object, dispatch: Function) {
|
||||
const { analysis: { obfuscateRoomName = false } = {} } = state['features/base/config'];
|
||||
|
||||
if (obfuscateRoomName) {
|
||||
@@ -369,7 +365,7 @@ function getWiFiStatsMethod() {
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
export function _handleParticipantError(err: Error) {
|
||||
export function _handleParticipantError(err: { message: ?string }) {
|
||||
// XXX DataChannels are initialized at some later point when the conference
|
||||
// has multiple participants, but code that pins or selects a participant
|
||||
// might be executed before. So here we're swallowing a particular error.
|
||||
@@ -388,7 +384,7 @@ export function _handleParticipantError(err: Error) {
|
||||
* @returns {boolean} If the specified room name is valid, then true; otherwise,
|
||||
* false.
|
||||
*/
|
||||
export function isRoomValid(room?: string) {
|
||||
export function isRoomValid(room: ?string) {
|
||||
return typeof room === 'string' && room !== '';
|
||||
}
|
||||
|
||||
@@ -401,11 +397,11 @@ export function isRoomValid(room?: string) {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function _removeLocalTracksFromConference(
|
||||
conference: IJitsiConference,
|
||||
conference: { removeTrack: Function },
|
||||
localTracks: Array<Object>) {
|
||||
return Promise.all(localTracks.map(track =>
|
||||
conference.removeTrack(track)
|
||||
.catch((err: Error) => {
|
||||
.catch(err => {
|
||||
// Local track might be already disposed by direct
|
||||
// JitsiTrack#dispose() call. So we should ignore this error
|
||||
// here.
|
||||
@@ -429,7 +425,7 @@ export function _removeLocalTracksFromConference(
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _reportError(msg: string, err: Error) {
|
||||
function _reportError(msg, err) {
|
||||
// TODO This is a good point to call some global error handler when we have
|
||||
// one.
|
||||
logger.error(msg, err);
|
||||
@@ -447,14 +443,17 @@ function _reportError(msg: string, err: Error) {
|
||||
* @returns {void}
|
||||
*/
|
||||
export function sendLocalParticipant(
|
||||
stateful: IStateful,
|
||||
conference: IJitsiConference) {
|
||||
stateful: Function | Object,
|
||||
conference: {
|
||||
sendCommand: Function,
|
||||
setDisplayName: Function,
|
||||
setLocalParticipantProperty: Function }) {
|
||||
const {
|
||||
avatarURL,
|
||||
email,
|
||||
features,
|
||||
name
|
||||
} = getLocalParticipant(stateful) ?? {};
|
||||
} = getLocalParticipant(stateful);
|
||||
|
||||
avatarURL && conference.sendCommand(AVATAR_URL_COMMAND, {
|
||||
value: avatarURL
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/conference');
|
||||
@@ -17,12 +17,12 @@ import { validateJwt } from '../jwt';
|
||||
import { JitsiConferenceErrors } from '../lib-jitsi-meet';
|
||||
import { MEDIA_TYPE } from '../media';
|
||||
import {
|
||||
PARTICIPANT_ROLE,
|
||||
PARTICIPANT_UPDATED,
|
||||
PIN_PARTICIPANT,
|
||||
getLocalParticipant,
|
||||
getParticipantById,
|
||||
getPinnedParticipant
|
||||
getPinnedParticipant,
|
||||
PARTICIPANT_ROLE,
|
||||
PARTICIPANT_UPDATED,
|
||||
PIN_PARTICIPANT
|
||||
} from '../participants';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
import { TRACK_ADDED, TRACK_REMOVED } from '../tracks';
|
||||
|
||||
@@ -6,9 +6,9 @@ import { showModeratedNotification } from '../../av-moderation/actions';
|
||||
import { shouldShowModeratedNotification } from '../../av-moderation/functions';
|
||||
import { setNoiseSuppressionEnabled } from '../../noise-suppression/actions';
|
||||
import {
|
||||
showNotification,
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
isModerationNotificationDisplayed,
|
||||
showNotification
|
||||
isModerationNotificationDisplayed
|
||||
} from '../../notifications';
|
||||
import {
|
||||
setPrejoinPageVisibility,
|
||||
@@ -25,19 +25,19 @@ import { AudioMixerEffect } from '../../stream-effects/audio-mixer/AudioMixerEff
|
||||
import { setAudioOnly } from '../audio-only';
|
||||
import { getMultipleVideoSendingSupportFeatureFlag } from '../config/functions.any';
|
||||
import { JitsiConferenceErrors, JitsiTrackErrors, JitsiTrackEvents } from '../lib-jitsi-meet';
|
||||
import { MEDIA_TYPE, VIDEO_TYPE, setScreenshareMuted } from '../media';
|
||||
import { MEDIA_TYPE, setScreenshareMuted, VIDEO_TYPE } from '../media';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
import {
|
||||
TOGGLE_SCREENSHARING,
|
||||
addLocalTrack,
|
||||
createLocalTracksF,
|
||||
getLocalDesktopTrack,
|
||||
getLocalJitsiAudioTrack,
|
||||
replaceLocalTrack,
|
||||
toggleScreensharing
|
||||
toggleScreensharing,
|
||||
TOGGLE_SCREENSHARING
|
||||
} from '../tracks';
|
||||
|
||||
import { CONFERENCE_FAILED, CONFERENCE_JOINED, CONFERENCE_JOIN_IN_PROGRESS } from './actionTypes';
|
||||
import { CONFERENCE_FAILED, CONFERENCE_JOIN_IN_PROGRESS, CONFERENCE_JOINED } from './actionTypes';
|
||||
import { getCurrentConference } from './functions';
|
||||
import './middleware.any';
|
||||
|
||||
|
||||
@@ -40,34 +40,11 @@ const DEFAULT_STATE = {
|
||||
passwordRequired: undefined
|
||||
};
|
||||
|
||||
export interface IJitsiConference {
|
||||
addTrack: Function;
|
||||
getBreakoutRooms: Function;
|
||||
getLocalTracks: Function;
|
||||
grantOwner: Function;
|
||||
isAVModerationSupported: Function;
|
||||
isEndConferenceSupported: Function;
|
||||
isLobbySupported: Function;
|
||||
kickParticipant: Function;
|
||||
muteParticipant: Function;
|
||||
myLobbyUserId: Function;
|
||||
myUserId: Function;
|
||||
on: Function;
|
||||
removeTrack: Function;
|
||||
replaceTrack: Function;
|
||||
sendCommand: Function;
|
||||
sendEndpointMessage: Function;
|
||||
sendLobbyMessage: Function;
|
||||
sessionId: string;
|
||||
setDisplayName: Function;
|
||||
setLocalParticipantProperty: Function;
|
||||
}
|
||||
|
||||
export interface IConferenceState {
|
||||
authEnabled?: boolean;
|
||||
authLogin?: string;
|
||||
authRequired?: Object;
|
||||
conference?: IJitsiConference;
|
||||
conference?: any;
|
||||
conferenceTimestamp?: number;
|
||||
e2eeSupported?: boolean;
|
||||
error?: Error;
|
||||
|
||||
@@ -8,9 +8,9 @@ import { parseURIString } from '../util/uri';
|
||||
import {
|
||||
CONFIG_WILL_LOAD,
|
||||
LOAD_CONFIG_ERROR,
|
||||
OVERWRITE_CONFIG,
|
||||
SET_CONFIG,
|
||||
UPDATE_CONFIG
|
||||
UPDATE_CONFIG,
|
||||
OVERWRITE_CONFIG
|
||||
} from './actionTypes';
|
||||
import { IConfig } from './configType';
|
||||
import { _CONFIG_STORE_PREFIX } from './constants';
|
||||
|
||||
@@ -67,7 +67,7 @@ type ButtonsWithNotifyClick = 'camera' |
|
||||
'add-passcode' |
|
||||
'__end';
|
||||
|
||||
export type Sounds = 'ASKED_TO_UNMUTE_SOUND' |
|
||||
type Sounds = 'ASKED_TO_UNMUTE_SOUND' |
|
||||
'E2EE_OFF_SOUND' |
|
||||
'E2EE_ON_SOUND' |
|
||||
'INCOMING_MSG_SOUND' |
|
||||
@@ -125,7 +125,6 @@ export interface IConfig {
|
||||
key: ButtonsWithNotifyClick;
|
||||
preventExecution: boolean;
|
||||
}>;
|
||||
callDisplayName?: string;
|
||||
callStatsConfigParams?: {
|
||||
additionalIDs?: {
|
||||
customerID?: string;
|
||||
@@ -301,7 +300,6 @@ export interface IConfig {
|
||||
disableTopPanel?: boolean;
|
||||
minParticipantCountForTopPanel?: number;
|
||||
};
|
||||
firefox_fake_device?: string;
|
||||
flags?: {
|
||||
sendMultipleVideoStreams?: boolean;
|
||||
sourceNameSignaling?: boolean;
|
||||
@@ -426,7 +424,7 @@ export interface IConfig {
|
||||
};
|
||||
serviceUrl?: string;
|
||||
speakerStatsOrder?: Array<'role' | 'name' | 'hasLeft'>;
|
||||
startAudioMuted?: number;
|
||||
startAudioMuted?: boolean;
|
||||
startAudioOnly?: boolean;
|
||||
startLastN?: number;
|
||||
startScreenSharing?: boolean;
|
||||
|
||||
@@ -11,7 +11,7 @@ import { parseURLParams } from '../util/parseURLParams';
|
||||
|
||||
import { IConfig } from './configType';
|
||||
import CONFIG_WHITELIST from './configWhitelist';
|
||||
import { FEATURE_FLAGS, _CONFIG_STORE_PREFIX } from './constants';
|
||||
import { _CONFIG_STORE_PREFIX, FEATURE_FLAGS } from './constants';
|
||||
import INTERFACE_CONFIG_WHITELIST from './interfaceConfigWhitelist';
|
||||
import logger from './logger';
|
||||
|
||||
@@ -60,8 +60,8 @@ export function getMeetingRegion(state: IState) {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function getMultipleVideoSupportFeatureFlag(state: IState) {
|
||||
return (getFeatureFlag(state, FEATURE_FLAGS.MULTIPLE_VIDEO_STREAMS_SUPPORT)
|
||||
&& getSourceNameSignalingFeatureFlag(state)) ?? true;
|
||||
return getFeatureFlag(state, FEATURE_FLAGS.MULTIPLE_VIDEO_STREAMS_SUPPORT)
|
||||
&& getSourceNameSignalingFeatureFlag(state);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,7 +72,7 @@ export function getMultipleVideoSupportFeatureFlag(state: IState) {
|
||||
*/
|
||||
export function getMultipleVideoSendingSupportFeatureFlag(state: IState) {
|
||||
return navigator.product !== 'ReactNative'
|
||||
&& ((getMultipleVideoSupportFeatureFlag(state) ?? true) && isUnifiedPlanEnabled(state));
|
||||
&& getMultipleVideoSupportFeatureFlag(state) && isUnifiedPlanEnabled(state);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ export function getMultipleVideoSendingSupportFeatureFlag(state: IState) {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function getSourceNameSignalingFeatureFlag(state: IState) {
|
||||
return getFeatureFlag(state, FEATURE_FLAGS.SOURCE_NAME_SIGNALING) ?? true;
|
||||
return getFeatureFlag(state, FEATURE_FLAGS.SOURCE_NAME_SIGNALING);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -95,7 +95,7 @@ export function getSourceNameSignalingFeatureFlag(state: IState) {
|
||||
export function getFeatureFlag(state: IState, featureFlag: string) {
|
||||
const featureFlags = state['features/base/config']?.flags || {};
|
||||
|
||||
return featureFlags[featureFlag as keyof typeof featureFlags];
|
||||
return Boolean(featureFlags[featureFlag as keyof typeof featureFlags]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,7 +5,7 @@ import { getFeatureFlag } from '../flags/functions';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
import { updateSettings } from '../settings/actions';
|
||||
|
||||
import { OVERWRITE_CONFIG, SET_CONFIG } from './actionTypes';
|
||||
import { SET_CONFIG, OVERWRITE_CONFIG } from './actionTypes';
|
||||
import { updateConfig } from './actions';
|
||||
import { IConfig } from './configType';
|
||||
|
||||
@@ -74,12 +74,6 @@ function _setConfig({ dispatch, getState }: IStore, next: Function, action: AnyA
|
||||
}));
|
||||
}
|
||||
|
||||
if (action.config.filmstrip?.stageFilmstripParticipants !== undefined) {
|
||||
dispatch(updateSettings({
|
||||
maxStageParticipants: action.config.filmstrip.stageFilmstripParticipants
|
||||
}));
|
||||
}
|
||||
|
||||
dispatch(updateConfig(config));
|
||||
|
||||
// FIXME On Web we rely on the global 'config' variable which gets altered
|
||||
|
||||
@@ -5,11 +5,11 @@ import ReducerRegistry from '../redux/ReducerRegistry';
|
||||
import { equals } from '../redux/functions';
|
||||
|
||||
import {
|
||||
UPDATE_CONFIG,
|
||||
CONFIG_WILL_LOAD,
|
||||
LOAD_CONFIG_ERROR,
|
||||
OVERWRITE_CONFIG,
|
||||
SET_CONFIG,
|
||||
UPDATE_CONFIG
|
||||
OVERWRITE_CONFIG
|
||||
} from './actionTypes';
|
||||
import { IConfig } from './configType';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
@@ -71,9 +71,6 @@ const CONFERENCE_HEADER_MAPPING: any = {
|
||||
};
|
||||
|
||||
export interface IConfigState extends IConfig {
|
||||
analysis?: {
|
||||
obfuscateRoomName?: boolean;
|
||||
};
|
||||
error?: Error;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ export interface IConnectionState {
|
||||
connecting?: Object;
|
||||
connection?: {
|
||||
getJid: () => string;
|
||||
getLogs: () => Object;
|
||||
};
|
||||
error?: ConnectionFailedError;
|
||||
locationURL?: URL;
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
import { AnyAction } from 'redux';
|
||||
/* global APP */
|
||||
|
||||
/* eslint-disable lines-around-comment */
|
||||
// @ts-ignore
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
import { IStore } from '../../app/types';
|
||||
import { processExternalDeviceRequest } from '../../device-selection/functions';
|
||||
import { showNotification, showWarningNotification } from '../../notifications/actions';
|
||||
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
|
||||
// @ts-ignore
|
||||
import { processExternalDeviceRequest } from '../../device-selection';
|
||||
import {
|
||||
NOTIFICATION_TIMEOUT_TYPE,
|
||||
showNotification,
|
||||
showWarningNotification
|
||||
} from '../../notifications';
|
||||
import { replaceAudioTrackById, replaceVideoTrackById, setDeviceStatusWarning } from '../../prejoin/actions';
|
||||
// @ts-ignore
|
||||
import { isPrejoinPageVisible } from '../../prejoin/functions';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes';
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
|
||||
import JitsiMeetJS, { JitsiMediaDevicesEvents, JitsiTrackErrors } from '../lib-jitsi-meet';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
import { updateSettings } from '../settings/actions';
|
||||
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
import { updateSettings } from '../settings';
|
||||
|
||||
import {
|
||||
CHECK_AND_NOTIFY_FOR_NEW_DEVICE,
|
||||
@@ -38,7 +35,6 @@ import {
|
||||
setAudioOutputDeviceId
|
||||
} from './functions';
|
||||
import logger from './logger';
|
||||
import { IDevicesState } from './reducer';
|
||||
|
||||
const JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP = {
|
||||
microphone: {
|
||||
@@ -61,7 +57,7 @@ const JITSI_TRACK_ERROR_TO_MESSAGE_KEY_MAP = {
|
||||
/**
|
||||
* A listener for device permissions changed reported from lib-jitsi-meet.
|
||||
*/
|
||||
let permissionsListener: Function | undefined;
|
||||
let permissionsListener;
|
||||
|
||||
/**
|
||||
* Logs the current device list.
|
||||
@@ -69,9 +65,8 @@ let permissionsListener: Function | undefined;
|
||||
* @param {Object} deviceList - Whatever is returned by {@link groupDevicesByKind}.
|
||||
* @returns {string}
|
||||
*/
|
||||
function logDeviceList(deviceList: IDevicesState['availableDevices']) {
|
||||
const devicesToStr = (list?: MediaDeviceInfo[]) =>
|
||||
list?.map(device => `\t\t${device.label}[${device.deviceId}]`).join('\n');
|
||||
function logDeviceList(deviceList) {
|
||||
const devicesToStr = list => list.map(device => `\t\t${device.label}[${device.deviceId}]`).join('\n');
|
||||
const audioInputs = devicesToStr(deviceList.audioInput);
|
||||
const audioOutputs = devicesToStr(deviceList.audioOutput);
|
||||
const videoInputs = devicesToStr(deviceList.videoInput);
|
||||
@@ -92,7 +87,7 @@ function logDeviceList(deviceList: IDevicesState['availableDevices']) {
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
switch (action.type) {
|
||||
case APP_WILL_MOUNT: {
|
||||
const _permissionsListener = (permissions: Object) => {
|
||||
const _permissionsListener = permissions => {
|
||||
store.dispatch(devicePermissionsChanged(permissions));
|
||||
};
|
||||
const { mediaDevices } = JitsiMeetJS;
|
||||
@@ -219,7 +214,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _processPendingRequests({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
function _processPendingRequests({ dispatch, getState }, next, action) {
|
||||
const result = next(action);
|
||||
const state = getState();
|
||||
const { pendingRequests } = state['features/base/devices'];
|
||||
@@ -228,7 +223,7 @@ function _processPendingRequests({ dispatch, getState }: IStore, next: Function,
|
||||
return result;
|
||||
}
|
||||
|
||||
pendingRequests.forEach((request: any) => {
|
||||
pendingRequests.forEach(request => {
|
||||
processExternalDeviceRequest(
|
||||
dispatch,
|
||||
getState,
|
||||
@@ -253,7 +248,7 @@ function _processPendingRequests({ dispatch, getState }: IStore, next: Function,
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _checkAndNotifyForNewDevice(store: IStore, newDevices: MediaDeviceInfo[], oldDevices: MediaDeviceInfo[]) {
|
||||
function _checkAndNotifyForNewDevice(store, newDevices, oldDevices) {
|
||||
const { dispatch } = store;
|
||||
|
||||
// let's intersect both newDevices and oldDevices and handle thew newly
|
||||
@@ -265,9 +260,7 @@ function _checkAndNotifyForNewDevice(store: IStore, newDevices: MediaDeviceInfo[
|
||||
// we group devices by groupID which normally is the grouping by physical device
|
||||
// plugging in headset we provide normally two device, one input and one output
|
||||
// and we want to show only one notification for this physical audio device
|
||||
const devicesGroupBy: {
|
||||
[key: string]: MediaDeviceInfo[];
|
||||
} = onlyNewDevices.reduce((accumulated: any, value) => {
|
||||
const devicesGroupBy = onlyNewDevices.reduce((accumulated, value) => {
|
||||
accumulated[value.groupId] = accumulated[value.groupId] || [];
|
||||
accumulated[value.groupId].push(value);
|
||||
|
||||
@@ -321,7 +314,7 @@ function _checkAndNotifyForNewDevice(store: IStore, newDevices: MediaDeviceInfo[
|
||||
* @returns {boolean} - Returns true in order notifications to be dismissed.
|
||||
* @private
|
||||
*/
|
||||
function _useDevice({ dispatch }: IStore, devices: MediaDeviceInfo[]) {
|
||||
function _useDevice({ dispatch }, devices) {
|
||||
devices.forEach(device => {
|
||||
switch (device.kind) {
|
||||
case 'videoinput': {
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { type Node, PureComponent } from 'react';
|
||||
import React, { PureComponent, type Node } from 'react';
|
||||
import { SafeAreaView, ScrollView, View } from 'react-native';
|
||||
|
||||
import { SlidingView } from '../../../react';
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { Component } from 'react';
|
||||
|
||||
/**
|
||||
@@ -8,17 +10,17 @@ export type Props = {
|
||||
/**
|
||||
* Function that closes the dialog.
|
||||
*/
|
||||
closeDialog: Function;
|
||||
closeDialog: Function,
|
||||
|
||||
/**
|
||||
* Callback to invoke on change.
|
||||
*/
|
||||
onTabStateChange: Function;
|
||||
onTabStateChange: Function,
|
||||
|
||||
/**
|
||||
* The id of the tab.
|
||||
*/
|
||||
tabId: number;
|
||||
tabId: number
|
||||
};
|
||||
|
||||
|
||||
@@ -27,7 +29,7 @@ export type Props = {
|
||||
*
|
||||
* @augments Component
|
||||
*/
|
||||
class AbstractDialogTab<P extends Props, S> extends Component<P, S> {
|
||||
class AbstractDialogTab<P: Props, S: *> extends Component<P, S> {
|
||||
/**
|
||||
* Initializes a new {@code AbstractDialogTab} instance.
|
||||
*
|
||||
@@ -41,6 +43,8 @@ class AbstractDialogTab<P extends Props, S> extends Component<P, S> {
|
||||
this._onChange = this._onChange.bind(this);
|
||||
}
|
||||
|
||||
_onChange: (Object) => void;
|
||||
|
||||
/**
|
||||
* Uses the onTabStateChange function to pass the changed state of the
|
||||
* controlled tab component to the controlling DialogWithTabs component.
|
||||
@@ -49,7 +53,7 @@ class AbstractDialogTab<P extends Props, S> extends Component<P, S> {
|
||||
* value.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onChange(change: Object) {
|
||||
_onChange(change) {
|
||||
const { onTabStateChange, tabId } = this.props;
|
||||
|
||||
onTabStateChange(tabId, {
|
||||
@@ -5,8 +5,8 @@ import WarningIcon from '@atlaskit/icon/glyph/warning';
|
||||
import {
|
||||
Header,
|
||||
Title,
|
||||
TitleText,
|
||||
titleIconWrapperStyles
|
||||
titleIconWrapperStyles,
|
||||
TitleText
|
||||
// @ts-ignore
|
||||
} from '@atlaskit/modal-dialog/dist/es2019/styled/Content';
|
||||
import { Theme } from '@mui/material';
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
import {
|
||||
Dialog,
|
||||
FillScreen,
|
||||
PositionerAbsolute,
|
||||
PositionerRelative,
|
||||
dialogWidth,
|
||||
dialogHeight,
|
||||
dialogWidth
|
||||
PositionerAbsolute,
|
||||
PositionerRelative
|
||||
} from '@atlaskit/modal-dialog/dist/es2019/styled/Modal.js';
|
||||
import { DN50, N0 } from '@atlaskit/theme/colors';
|
||||
import { N0, DN50 } from '@atlaskit/theme/colors';
|
||||
import { themed } from '@atlaskit/theme/components';
|
||||
import React from 'react';
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="10" height="6" viewBox="0 0 10 6" xmlns="http://www.w3.org/2000/svg">
|
||||
<svg width="10" height="6" viewBox="0 0 10 6" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.07001 0.248238C8.3471 -0.0596449 8.82132 -0.0846038 9.1292 0.192491C9.43709 0.469585 9.46205 0.943802 9.18495 1.25168L5.65622 5.19348C5.35829 5.52451 4.83922 5.52451 4.54128 5.19348L1.06752 1.25168C0.79043 0.943802 0.81539 0.469585 1.12327 0.192491C1.43115 -0.0846038 1.90537 -0.0596449 2.18247 0.248238L5.09875 3.57062L8.07001 0.248238Z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 482 B After Width: | Height: | Size: 494 B |
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { SET_JWT } from './actionTypes';
|
||||
|
||||
/**
|
||||
@@ -9,7 +11,7 @@ import { SET_JWT } from './actionTypes';
|
||||
* jwt: (string|undefined)
|
||||
* }}
|
||||
*/
|
||||
export function setJWT(jwt?: string) {
|
||||
export function setJWT(jwt: ?string) {
|
||||
return {
|
||||
type: SET_JWT,
|
||||
jwt
|
||||
@@ -1,9 +1,9 @@
|
||||
// @ts-ignore
|
||||
/* @flow */
|
||||
|
||||
import jwtDecode from 'jwt-decode';
|
||||
|
||||
import { IState } from '../../app/types';
|
||||
import { getLocalParticipant } from '../participants/functions';
|
||||
import { parseURLParams } from '../util/parseURLParams';
|
||||
import { parseURLParams } from '../util';
|
||||
|
||||
import { MEET_FEATURES } from './constants';
|
||||
|
||||
@@ -16,18 +16,17 @@ import { MEET_FEATURES } from './constants';
|
||||
* @returns {string} The JSON Web Token (JWT), if any, defined by the specified
|
||||
* {@code url}; otherwise, {@code undefined}.
|
||||
*/
|
||||
export function parseJWTFromURLParams(url: URL | Location = window.location) {
|
||||
// @ts-ignore
|
||||
export function parseJWTFromURLParams(url: URL = window.location) {
|
||||
return parseURLParams(url, true, 'search').jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user name after decoding the jwt.
|
||||
*
|
||||
* @param {IState} state - The app state.
|
||||
* @param {Object} state - The app state.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function getJwtName(state: IState) {
|
||||
export function getJwtName(state: Object) {
|
||||
const { user } = state['features/base/jwt'];
|
||||
|
||||
return user?.name;
|
||||
@@ -36,12 +35,12 @@ export function getJwtName(state: IState) {
|
||||
/**
|
||||
* Check if the given JWT feature is enabled.
|
||||
*
|
||||
* @param {IState} state - The app state.
|
||||
* @param {Object} state - The app state.
|
||||
* @param {string} feature - The feature we want to check.
|
||||
* @param {boolean} ifNoToken - Default value if there is no token.
|
||||
* @returns {string}
|
||||
*/
|
||||
export function isJwtFeatureEnabled(state: IState, feature: string, ifNoToken = false) {
|
||||
export function isJwtFeatureEnabled(state: Object, feature: string, ifNoToken: boolean = false) {
|
||||
const { jwt } = state['features/base/jwt'];
|
||||
|
||||
if (!jwt) {
|
||||
@@ -55,7 +54,7 @@ export function isJwtFeatureEnabled(state: IState, feature: string, ifNoToken =
|
||||
return true;
|
||||
}
|
||||
|
||||
return String(features[feature as keyof typeof features]) === 'true';
|
||||
return String(features[feature]) === 'true';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +64,7 @@ export function isJwtFeatureEnabled(state: IState, feature: string, ifNoToken =
|
||||
* @param {any} timestamp - A UNIX timestamp in seconds as stored in the jwt.
|
||||
* @returns {boolean} - Whether the timestamp is indeed a valid UNIX timestamp or not.
|
||||
*/
|
||||
function isValidUnixTimestamp(timestamp: number | string) {
|
||||
function isValidUnixTimestamp(timestamp: any) {
|
||||
return typeof timestamp === 'number' && timestamp * 1000 === new Date(timestamp * 1000).getTime();
|
||||
}
|
||||
|
||||
@@ -76,7 +75,7 @@ function isValidUnixTimestamp(timestamp: number | string) {
|
||||
* @returns {Array<string>} - An array containing all jwt validation errors.
|
||||
*/
|
||||
export function validateJwt(jwt: string) {
|
||||
const errors: string[] = [];
|
||||
const errors = [];
|
||||
|
||||
if (!jwt) {
|
||||
return errors;
|
||||
@@ -104,7 +103,7 @@ export function validateJwt(jwt: string) {
|
||||
} = payload;
|
||||
|
||||
// JaaS only
|
||||
if (sub?.startsWith('vpaas-magic-cookie')) {
|
||||
if (sub && sub.startsWith('vpaas-magic-cookie')) {
|
||||
const { kid } = header;
|
||||
|
||||
// if Key ID is missing, we return the error immediately without further validations.
|
||||
@@ -166,7 +165,7 @@ export function validateJwt(jwt: string) {
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (e: any) {
|
||||
} catch (e) {
|
||||
errors.push(e ? e.message : '- unspecified jwt error');
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/jwt');
|
||||
@@ -1,20 +1,22 @@
|
||||
// @ts-ignore
|
||||
import jwtDecode from 'jwt-decode';
|
||||
import { AnyAction } from 'redux';
|
||||
// @flow
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { SET_CONFIG } from '../config/actionTypes';
|
||||
import { SET_LOCATION_URL } from '../connection/actionTypes';
|
||||
import { participantUpdated } from '../participants/actions';
|
||||
import { getLocalParticipant } from '../participants/functions';
|
||||
import { Participant } from '../participants/types';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
import jwtDecode from 'jwt-decode';
|
||||
|
||||
import { SET_CONFIG } from '../config';
|
||||
import { SET_LOCATION_URL } from '../connection';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
participantUpdated
|
||||
} from '../participants';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
|
||||
import { SET_JWT } from './actionTypes';
|
||||
import { setJWT } from './actions';
|
||||
import { parseJWTFromURLParams } from './functions';
|
||||
import logger from './logger';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Middleware to parse token data upon setting a new room URL.
|
||||
*
|
||||
@@ -49,14 +51,13 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
* @returns {void}
|
||||
*/
|
||||
function _overwriteLocalParticipant(
|
||||
{ dispatch, getState }: IStore,
|
||||
{ avatarURL, email, id: jwtId, name, features }:
|
||||
{ avatarURL?: string; email?: string; features?: any; id?: string; name?: string; }) {
|
||||
{ dispatch, getState },
|
||||
{ avatarURL, email, id: jwtId, name, features }) {
|
||||
let localParticipant;
|
||||
|
||||
if ((avatarURL || email || name)
|
||||
&& (localParticipant = getLocalParticipant(getState))) {
|
||||
const newProperties: Participant = {
|
||||
const newProperties: Object = {
|
||||
id: localParticipant.id,
|
||||
local: true
|
||||
};
|
||||
@@ -96,7 +97,7 @@ function _overwriteLocalParticipant(
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _setConfigOrLocationURL({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
function _setConfigOrLocationURL({ dispatch, getState }, next, action) {
|
||||
const result = next(action);
|
||||
|
||||
const { locationURL } = getState()['features/base/connection'];
|
||||
@@ -121,8 +122,8 @@ function _setConfigOrLocationURL({ dispatch, getState }: IStore, next: Function,
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _setJWT(store: IStore, next: Function, action: AnyAction) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function _setJWT(store, next, action) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const { jwt, type, ...actionPayload } = action;
|
||||
|
||||
if (!Object.keys(actionPayload).length) {
|
||||
@@ -185,13 +186,13 @@ function _setJWT(store: IStore, next: Function, action: AnyAction) {
|
||||
* @returns {void}
|
||||
*/
|
||||
function _undoOverwriteLocalParticipant(
|
||||
{ dispatch, getState }: IStore,
|
||||
{ avatarURL, name, email }: { avatarURL?: string; email?: string; name?: string; }) {
|
||||
{ dispatch, getState },
|
||||
{ avatarURL, name, email }) {
|
||||
let localParticipant;
|
||||
|
||||
if ((avatarURL || name || email)
|
||||
&& (localParticipant = getLocalParticipant(getState))) {
|
||||
const newProperties: Participant = {
|
||||
const newProperties: Object = {
|
||||
id: localParticipant.id,
|
||||
local: true
|
||||
};
|
||||
@@ -225,10 +226,8 @@ function _undoOverwriteLocalParticipant(
|
||||
* hidden-from-recorder: ?boolean
|
||||
* }}
|
||||
*/
|
||||
function _user2participant({ avatar, avatarUrl, email, id, name, 'hidden-from-recorder': hiddenFromRecorder }:
|
||||
{ avatar: any; avatarUrl: string; email: string; 'hidden-from-recorder': string | boolean;
|
||||
id: string; name: string; }) {
|
||||
const participant: any = {};
|
||||
function _user2participant({ avatar, avatarUrl, email, id, name, 'hidden-from-recorder': hiddenFromRecorder }) {
|
||||
const participant = {};
|
||||
|
||||
if (typeof avatarUrl === 'string') {
|
||||
participant.avatarURL = avatarUrl.trim();
|
||||
@@ -4,16 +4,9 @@ import { equals } from '../redux/functions';
|
||||
import { SET_JWT } from './actionTypes';
|
||||
|
||||
export interface IJwtState {
|
||||
callee?: {
|
||||
name: string;
|
||||
};
|
||||
group?: string;
|
||||
jwt?: string;
|
||||
server?: string;
|
||||
tenant?: string;
|
||||
user?: {
|
||||
name: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,7 @@ import React from 'react';
|
||||
import { Animated, Text } from 'react-native';
|
||||
|
||||
import Icon from '../../../icons/components/Icon';
|
||||
import { type StyleType, combineStyles } from '../../../styles';
|
||||
import { combineStyles, type StyleType } from '../../../styles';
|
||||
import AbstractLabel, {
|
||||
type Props as AbstractProps
|
||||
} from '../AbstractLabel';
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { SET_LAST_N } from './actionTypes';
|
||||
|
||||
/**
|
||||
@@ -7,7 +7,7 @@ import { VIDEO_QUALITY_LEVELS } from '../../video-quality/constants';
|
||||
* @param {number} channelLastN - LastN value set for the whole conference.
|
||||
* @returns {number} LastN value applicable to the quality level specified.
|
||||
*/
|
||||
export function getLastNForQualityLevel(qualityLevel: number, channelLastN: number) {
|
||||
export function getLastNForQualityLevel(qualityLevel, channelLastN) {
|
||||
let lastN = channelLastN;
|
||||
|
||||
const videoQualityLevels = Object.values(VIDEO_QUALITY_LEVELS);
|
||||
@@ -15,8 +15,8 @@ export function getLastNForQualityLevel(qualityLevel: number, channelLastN: numb
|
||||
for (const lvl in videoQualityLevels) {
|
||||
if (videoQualityLevels.hasOwnProperty(lvl)
|
||||
&& qualityLevel === videoQualityLevels[lvl]
|
||||
&& Number(lvl) > 1) {
|
||||
lastN = Math.floor(channelLastN / Math.pow(2, Number(lvl) - 1));
|
||||
&& lvl > 1) {
|
||||
lastN = Math.floor(channelLastN / Math.pow(2, lvl - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export function getLastNForQualityLevel(qualityLevel: number, channelLastN: numb
|
||||
* @param {Object} lastNLimits - The Object to be verified.
|
||||
* @returns {undefined|Map<number, number>}
|
||||
*/
|
||||
export function validateLastNLimits(lastNLimits: any) {
|
||||
export function validateLastNLimits(lastNLimits) {
|
||||
// Checks if only numbers are used
|
||||
if (typeof lastNLimits !== 'object'
|
||||
|| !Object.keys(lastNLimits).length
|
||||
@@ -64,7 +64,7 @@ export function validateLastNLimits(lastNLimits: any) {
|
||||
* @returns {number|undefined} - A "last N" number if there was a corresponding "last N" value matched with the number
|
||||
* of participants or {@code undefined} otherwise.
|
||||
*/
|
||||
export function limitLastN(participantsCount: number, lastNLimits: Map<number, number>) {
|
||||
export function limitLastN(participantsCount, lastNLimits) {
|
||||
if (!lastNLimits || !lastNLimits.keys) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/lastn');
|
||||
@@ -1,6 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import debounce from 'lodash/debounce';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
|
||||
import { SELECT_LARGE_VIDEO_PARTICIPANT } from '../../large-video/actionTypes';
|
||||
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
|
||||
@@ -21,9 +22,7 @@ import {
|
||||
getParticipantById,
|
||||
getParticipantCount
|
||||
} from '../participants/functions';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
import { isLocalVideoTrackDesktop } from '../tracks/functions';
|
||||
|
||||
import { setLastN } from './actions';
|
||||
@@ -37,7 +36,7 @@ import logger from './logger';
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
const _updateLastN = debounce(({ dispatch, getState }: IStore) => {
|
||||
const _updateLastN = debounce(({ dispatch, getState }) => {
|
||||
const state = getState();
|
||||
const { conference } = state['features/base/conference'];
|
||||
|
||||
@@ -62,7 +61,6 @@ const _updateLastN = debounce(({ dispatch, getState }: IStore) => {
|
||||
let lastNSelected = config.startLastN ?? (config.channelLastN ?? -1);
|
||||
|
||||
// Apply last N limit based on the # of participants and config settings.
|
||||
// @ts-ignore
|
||||
const limitedLastN = limitLastN(participantCount, lastNLimits);
|
||||
|
||||
if (limitedLastN !== undefined) {
|
||||
@@ -83,7 +81,7 @@ const _updateLastN = debounce(({ dispatch, getState }: IStore) => {
|
||||
// view since we make an exception only for screenshare when in audio-only mode. If the user unpins
|
||||
// the screenshare, lastN will be set to 0 here. It will be set to 1 if screenshare has been auto pinned.
|
||||
if (!tileViewEnabled && largeVideoParticipant && !largeVideoParticipant.local) {
|
||||
lastNSelected = (remoteScreenShares || []).includes(largeVideoParticipantId ?? '') ? 1 : 0;
|
||||
lastNSelected = (remoteScreenShares || []).includes(largeVideoParticipantId) ? 1 : 0;
|
||||
} else {
|
||||
lastNSelected = 0;
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
/* eslint-disable lines-around-comment */
|
||||
// @ts-ignore
|
||||
import { jitsiLocalStorage } from '@jitsi/js-utils';
|
||||
/* @flow */
|
||||
|
||||
import { jitsiLocalStorage } from '@jitsi/js-utils';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { isOnline } from '../net-info/selectors';
|
||||
|
||||
// @ts-ignore
|
||||
import JitsiMeetJS from './_';
|
||||
import {
|
||||
LIB_DID_DISPOSE,
|
||||
@@ -14,16 +13,17 @@ import {
|
||||
LIB_WILL_DISPOSE,
|
||||
LIB_WILL_INIT
|
||||
} from './actionTypes';
|
||||
// @ts-ignore
|
||||
import { isAnalyticsEnabled } from './functions';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Disposes (of) lib-jitsi-meet.
|
||||
*
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function disposeLib() {
|
||||
return (dispatch: IStore['dispatch']) => {
|
||||
return (dispatch: Dispatch<any>) => {
|
||||
dispatch({ type: LIB_WILL_DISPOSE });
|
||||
|
||||
// TODO Currently, lib-jitsi-meet doesn't have the functionality to
|
||||
@@ -39,7 +39,7 @@ export function disposeLib() {
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function initLib() {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch<any>, getState: Function): void => {
|
||||
const state = getState();
|
||||
const config = state['features/base/config'];
|
||||
|
||||
@@ -59,7 +59,7 @@ export function initLib() {
|
||||
isOnline: isOnline(state)
|
||||
});
|
||||
dispatch({ type: LIB_DID_INIT });
|
||||
} catch (error: any) {
|
||||
} catch (error) {
|
||||
dispatch(libInitError(error));
|
||||
}
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
import { IStateful } from '../app/types';
|
||||
import { toState } from '../redux/functions';
|
||||
// @flow
|
||||
|
||||
import { toState } from '../redux';
|
||||
|
||||
// @ts-ignore
|
||||
import JitsiMeetJS from './_';
|
||||
|
||||
const JitsiConferenceErrors = JitsiMeetJS.errors.conference;
|
||||
@@ -18,7 +18,7 @@ const JitsiConnectionErrors = JitsiMeetJS.errors.connection;
|
||||
*
|
||||
* @returns {Promise<JitsiLocalTrack>}
|
||||
*/
|
||||
export function createLocalTrack(type: string, deviceId: string, timeout?: number, additionalOptions?: Object) {
|
||||
export function createLocalTrack(type: string, deviceId: string, timeout: ?number, additionalOptions: ?Object) {
|
||||
return (
|
||||
JitsiMeetJS.createLocalTracks({
|
||||
cameraDeviceId: deviceId,
|
||||
@@ -26,23 +26,23 @@ export function createLocalTrack(type: string, deviceId: string, timeout?: numbe
|
||||
|
||||
// eslint-disable-next-line camelcase
|
||||
firefox_fake_device:
|
||||
window.config?.firefox_fake_device,
|
||||
window.config && window.config.firefox_fake_device,
|
||||
micDeviceId: deviceId,
|
||||
timeout,
|
||||
...additionalOptions
|
||||
})
|
||||
.then(([ jitsiLocalTrack ]: any[]) => jitsiLocalTrack));
|
||||
.then(([ jitsiLocalTrack ]) => jitsiLocalTrack));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether analytics is enabled in a specific redux {@code store}.
|
||||
*
|
||||
* @param {IStateful} stateful - The redux store, state, or
|
||||
* @param {Function|Object} stateful - The redux store, state, or
|
||||
* {@code getState} function.
|
||||
* @returns {boolean} If analytics is enabled, {@code true}; {@code false},
|
||||
* otherwise.
|
||||
*/
|
||||
export function isAnalyticsEnabled(stateful: IStateful) {
|
||||
export function isAnalyticsEnabled(stateful: Function | Object) {
|
||||
const { disableThirdPartyRequests, analytics = {} } = toState(stateful)['features/base/config'];
|
||||
|
||||
return !(disableThirdPartyRequests || analytics.disabled);
|
||||
@@ -56,13 +56,13 @@ export function isAnalyticsEnabled(stateful: IStateful) {
|
||||
* that category. I've currently named the category fatal because it appears to
|
||||
* be used in the cases of unrecoverable errors that necessitate a reload.
|
||||
*
|
||||
* @param {Error|string} error - The {@code JitsiConferenceErrors} instance to
|
||||
* @param {Object|string} error - The {@code JitsiConferenceErrors} instance to
|
||||
* categorize/classify or an {@link Error}-like object.
|
||||
* @returns {boolean} If the specified {@code JitsiConferenceErrors} instance
|
||||
* indicates a fatal {@code JitsiConference} error, {@code true}; otherwise,
|
||||
* {@code false}.
|
||||
*/
|
||||
export function isFatalJitsiConferenceError(error: Error | string) {
|
||||
export function isFatalJitsiConferenceError(error: Object | string) {
|
||||
if (typeof error !== 'string') {
|
||||
error = error.name; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
@@ -83,13 +83,13 @@ export function isFatalJitsiConferenceError(error: Error | string) {
|
||||
* that category. I've currently named the category fatal because it appears to
|
||||
* be used in the cases of unrecoverable errors that necessitate a reload.
|
||||
*
|
||||
* @param {Error|string} error - The {@code JitsiConnectionErrors} instance to
|
||||
* @param {Object|string} error - The {@code JitsiConnectionErrors} instance to
|
||||
* categorize/classify or an {@link Error}-like object.
|
||||
* @returns {boolean} If the specified {@code JitsiConnectionErrors} instance
|
||||
* indicates a fatal {@code JitsiConnection} error, {@code true}; otherwise,
|
||||
* {@code false}.
|
||||
*/
|
||||
export function isFatalJitsiConnectionError(error: Error | string) {
|
||||
export function isFatalJitsiConnectionError(error: Object | string) {
|
||||
if (typeof error !== 'string') {
|
||||
error = error.name; // eslint-disable-line no-param-reassign
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
export * from './functions.any';
|
||||
|
||||
/**
|
||||
@@ -6,7 +8,7 @@ export * from './functions.any';
|
||||
* @param {string} url - The URL to load.
|
||||
* @returns {Promise<Object>}
|
||||
*/
|
||||
export async function loadConfig(url: string) { // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||
export async function loadConfig(url: string): Promise<Object> { // eslint-disable-line no-unused-vars
|
||||
// Return "the config.js file" from the global scope - that is how the
|
||||
// Web app on both the client and the server was implemented before the
|
||||
// React Native app was even conceived.
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/lib-jitsi-meet');
|
||||
@@ -1,16 +1,14 @@
|
||||
import { AnyAction } from 'redux';
|
||||
import { SET_CONFIG } from '../config';
|
||||
import { SET_NETWORK_INFO } from '../net-info';
|
||||
import { PARTICIPANT_LEFT } from '../participants';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { SET_CONFIG } from '../config/actionTypes';
|
||||
import { SET_NETWORK_INFO } from '../net-info/actionTypes';
|
||||
import { PARTICIPANT_LEFT } from '../participants/actionTypes';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
|
||||
// @ts-ignore
|
||||
import JitsiMeetJS from './_';
|
||||
import { LIB_WILL_INIT } from './actionTypes';
|
||||
import { disposeLib, initLib } from './actions';
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* Middleware that captures PARTICIPANT_LEFT action for a local participant
|
||||
* (which signalizes that we finally left the app) and disposes lib-jitsi-meet.
|
||||
@@ -62,7 +60,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
function _setConfig({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
|
||||
function _setConfig({ dispatch, getState }, next, action) {
|
||||
const { initialized } = getState()['features/base/lib-jitsi-meet'];
|
||||
|
||||
// XXX Since the config is changing, the library lib-jitsi-meet must be
|
||||
@@ -93,10 +91,10 @@ function _setErrorHandlers() {
|
||||
if (JitsiMeetJS.getGlobalOnErrorHandler) {
|
||||
const oldOnErrorHandler = window.onerror;
|
||||
|
||||
// @ts-ignore
|
||||
window.onerror = (message, source, lineno, colno, error) => { // eslint-disable-line max-params
|
||||
const errMsg = message || error?.message;
|
||||
const stack = error?.stack;
|
||||
// eslint-disable-next-line max-params
|
||||
window.onerror = (message, source, lineno, colno, error) => {
|
||||
const errMsg = message || (error && error.message);
|
||||
const stack = error && error.stack;
|
||||
|
||||
JitsiMeetJS.getGlobalOnErrorHandler(errMsg, source, lineno, colno, stack);
|
||||
|
||||
@@ -109,7 +107,7 @@ function _setErrorHandlers() {
|
||||
|
||||
window.onunhandledrejection = function(event) {
|
||||
let message = event.reason;
|
||||
let stack: string | undefined = 'n/a';
|
||||
let stack = 'n/a';
|
||||
|
||||
if (event.reason instanceof Error) {
|
||||
({ message, stack } = event.reason);
|
||||
@@ -118,7 +116,6 @@ function _setErrorHandlers() {
|
||||
JitsiMeetJS.getGlobalOnErrorHandler(message, null, null, null, stack);
|
||||
|
||||
if (oldOnUnhandledRejection) {
|
||||
// @ts-ignore
|
||||
oldOnUnhandledRejection(event);
|
||||
}
|
||||
};
|
||||
@@ -50,6 +50,22 @@ export default class JitsiMeetLogStorage {
|
||||
return Boolean(conference);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether callstats logs storage is enabled.
|
||||
*
|
||||
* @returns {boolean} <tt>true</tt> when this storage can store logs to
|
||||
* callstats, <tt>false</tt> otherwise.
|
||||
*/
|
||||
canStoreLogsCallstats() {
|
||||
const { callstatsStoreLogs } = this.getState()['features/base/config'];
|
||||
|
||||
// The behavior prior to adding this configuration parameter, is to send logs to callstats (if callstats is
|
||||
// enabled). So, in order to maintain backwards compatibility I set the default of this option to be true, i.e.
|
||||
// if the config.callstatsStoreLogs is not set, the JS console logs will be sent to callstats (if callstats is
|
||||
// enabled)
|
||||
return callstatsStoreLogs || callstatsStoreLogs === undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether rtcstats logs storage is enabled.
|
||||
*
|
||||
@@ -76,9 +92,9 @@ export default class JitsiMeetLogStorage {
|
||||
*/
|
||||
storeLogs(logEntries: Array<string | any>) {
|
||||
|
||||
// XXX the config.callStatsApplicationLogsDisabled controls whether or not the logs will be sent to callstats.
|
||||
// this is done in LJM
|
||||
this.storeLogsCallstats(logEntries);
|
||||
if (this.canStoreLogsCallstats()) {
|
||||
this.storeLogsCallstats(logEntries);
|
||||
}
|
||||
|
||||
if (this.canStoreLogsRtcstats()) {
|
||||
RTCStats.sendLogs(logEntries);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SET_LOGGING_CONFIG, SET_LOG_COLLECTOR } from './actionTypes';
|
||||
import { SET_LOG_COLLECTOR, SET_LOGGING_CONFIG } from './actionTypes';
|
||||
|
||||
/**
|
||||
* Stores a {@code Logger.LogCollector} instance which will be uploading logs
|
||||
|
||||
@@ -3,7 +3,7 @@ import _ from 'lodash';
|
||||
import ReducerRegistry from '../redux/ReducerRegistry';
|
||||
import { equals, set } from '../redux/functions';
|
||||
|
||||
import { SET_LOGGING_CONFIG, SET_LOG_COLLECTOR } from './actionTypes';
|
||||
import { SET_LOG_COLLECTOR, SET_LOGGING_CONFIG } from './actionTypes';
|
||||
|
||||
const DEFAULT_LOGGING_CONFIG = {
|
||||
// default log level for the app and lib-jitsi-meet
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { Dispatch } from 'redux';
|
||||
/* @flow */
|
||||
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { showModeratedNotification } from '../../av-moderation/actions';
|
||||
import { shouldShowModeratedNotification } from '../../av-moderation/functions';
|
||||
import { isModerationNotificationDisplayed } from '../../notifications/functions';
|
||||
import { isModerationNotificationDisplayed } from '../../notifications';
|
||||
|
||||
import {
|
||||
SET_AUDIO_AVAILABLE,
|
||||
SET_AUDIO_MUTED,
|
||||
SET_AUDIO_AVAILABLE,
|
||||
SET_AUDIO_UNMUTE_PERMISSIONS,
|
||||
SET_CAMERA_FACING_MODE,
|
||||
SET_SCREENSHARE_MUTED,
|
||||
@@ -53,7 +55,7 @@ export function setAudioAvailable(available: boolean) {
|
||||
* muted: boolean
|
||||
* }}
|
||||
*/
|
||||
export function setAudioMuted(muted: boolean, ensureTrack = false) {
|
||||
export function setAudioMuted(muted: boolean, ensureTrack: boolean = false) {
|
||||
return {
|
||||
type: SET_AUDIO_MUTED,
|
||||
ensureTrack,
|
||||
@@ -68,7 +70,7 @@ export function setAudioMuted(muted: boolean, ensureTrack = false) {
|
||||
* @param {boolean|undefined} skipNotification - True if we want to skip showing the notification.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function setAudioUnmutePermissions(blocked: boolean, skipNotification = false) {
|
||||
export function setAudioUnmutePermissions(blocked: boolean, skipNotification: boolean = false) {
|
||||
return {
|
||||
type: SET_AUDIO_UNMUTE_PERMISSIONS,
|
||||
blocked,
|
||||
@@ -105,7 +107,7 @@ export function setScreenshareMuted(
|
||||
muted: boolean,
|
||||
mediaType: MediaType = MEDIA_TYPE.SCREENSHARE,
|
||||
authority: number = SCREENSHARE_MUTISM_AUTHORITY.USER,
|
||||
ensureTrack = false) {
|
||||
ensureTrack: boolean = false) {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
const state = getState();
|
||||
|
||||
@@ -166,7 +168,7 @@ export function setVideoMuted(
|
||||
muted: boolean,
|
||||
mediaType: string = MEDIA_TYPE.VIDEO,
|
||||
authority: number = VIDEO_MUTISM_AUTHORITY.USER,
|
||||
ensureTrack = false) {
|
||||
ensureTrack: boolean = false) {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
const state = getState();
|
||||
|
||||
@@ -201,7 +203,7 @@ export function setVideoMuted(
|
||||
* @param {boolean|undefined} skipNotification - True if we want to skip showing the notification.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function setVideoUnmutePermissions(blocked: boolean, skipNotification = false) {
|
||||
export function setVideoUnmutePermissions(blocked: boolean, skipNotification: boolean = false) {
|
||||
return {
|
||||
type: SET_VIDEO_UNMUTE_PERMISSIONS,
|
||||
blocked,
|
||||
@@ -54,9 +54,7 @@ export const VIDEO_MUTISM_AUTHORITY = {
|
||||
*
|
||||
* @enum {string}
|
||||
*/
|
||||
export const VIDEO_TYPE: { [key: string]: VideoType; } = {
|
||||
export const VIDEO_TYPE = {
|
||||
CAMERA: 'camera',
|
||||
DESKTOP: 'desktop'
|
||||
};
|
||||
|
||||
export type VideoType = 'camera' | 'desktop';
|
||||
|
||||
@@ -15,17 +15,17 @@ import {
|
||||
import { isForceMuted } from '../../participants-pane/functions';
|
||||
import { isScreenMediaShared } from '../../screen-share/functions';
|
||||
import { SET_AUDIO_ONLY, setAudioOnly } from '../audio-only';
|
||||
import { SET_ROOM, isRoomValid } from '../conference';
|
||||
import { isRoomValid, SET_ROOM } from '../conference';
|
||||
import { getMultipleVideoSendingSupportFeatureFlag } from '../config';
|
||||
import { getLocalParticipant } from '../participants';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
import { getPropertyValue } from '../settings';
|
||||
import {
|
||||
TRACK_ADDED,
|
||||
destroyLocalTracks,
|
||||
isLocalTrackMuted,
|
||||
isLocalVideoTrackDesktop,
|
||||
setTrackMuted
|
||||
setTrackMuted,
|
||||
TRACK_ADDED
|
||||
} from '../tracks';
|
||||
|
||||
import {
|
||||
|
||||
@@ -14,8 +14,6 @@ import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
|
||||
import { SET_VIDEO_MUTED } from './actionTypes';
|
||||
|
||||
import './subscriber';
|
||||
|
||||
/**
|
||||
* Implements the entry point of the middleware of the feature base/media.
|
||||
*
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import { IState, IStore } from '../../app/types';
|
||||
import StateListenerRegistry from '../redux/StateListenerRegistry';
|
||||
|
||||
|
||||
declare let APP: any;
|
||||
|
||||
/**
|
||||
* Notifies when the local audio mute state changes.
|
||||
*/
|
||||
StateListenerRegistry.register(
|
||||
/* selector */ (state: IState) => state['features/base/media'].audio.muted,
|
||||
/* listener */ (muted: boolean, store: IStore, previousMuted: boolean) => {
|
||||
if (typeof APP !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (muted !== previousMuted) {
|
||||
APP.API.notifyAudioMutedStatusChanged(muted);
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -1,5 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import { SET_NETWORK_INFO, _STORE_NETWORK_INFO_CLEANUP } from './actionTypes';
|
||||
import { NetworkInfo } from './types';
|
||||
import type { NetworkInfo } from './types';
|
||||
|
||||
/**
|
||||
* Up[dates the network info state.
|
||||
@@ -12,7 +14,7 @@ import { NetworkInfo } from './types';
|
||||
* details: Object
|
||||
* }}
|
||||
*/
|
||||
export function setNetworkInfo({ isOnline, networkType, details }: NetworkInfo) {
|
||||
export function setNetworkInfo({ isOnline, networkType, details }: NetworkInfo): Object {
|
||||
return {
|
||||
type: SET_NETWORK_INFO,
|
||||
isOnline,
|
||||
@@ -31,7 +33,7 @@ export function setNetworkInfo({ isOnline, networkType, details }: NetworkInfo)
|
||||
* }}
|
||||
* @private
|
||||
*/
|
||||
export function _storeNetworkInfoCleanup(cleanup?: Function) {
|
||||
export function _storeNetworkInfoCleanup(cleanup: Function): Object {
|
||||
return {
|
||||
type: _STORE_NETWORK_INFO_CLEANUP,
|
||||
cleanup
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { getLogger } from '../logging/functions';
|
||||
|
||||
export default getLogger('features/base/net-info');
|
||||
@@ -1,7 +1,8 @@
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app/actionTypes';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
// @flow
|
||||
|
||||
import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from '../app';
|
||||
import { MiddlewareRegistry } from '../redux';
|
||||
|
||||
// @ts-ignore
|
||||
import NetworkInfoService from './NetworkInfoService';
|
||||
import { _storeNetworkInfoCleanup, setNetworkInfo } from './actions';
|
||||
import { STORE_NAME } from './constants';
|
||||
@@ -1,13 +1,11 @@
|
||||
import { IState } from '../../app/types';
|
||||
|
||||
import { STORE_NAME } from './constants';
|
||||
|
||||
/**
|
||||
* A selector for the internet online status.
|
||||
*
|
||||
* @param {IState} state - The redux state.
|
||||
* @param {Object} state - The redux state.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function isOnline(state: IState) {
|
||||
export function isOnline(state) {
|
||||
return state[STORE_NAME].isOnline;
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
// @flow
|
||||
|
||||
import { NetInfoCellularGeneration, NetInfoStateType } from '@react-native-community/netinfo';
|
||||
|
||||
/**
|
||||
@@ -6,32 +8,32 @@ import { NetInfoCellularGeneration, NetInfoStateType } from '@react-native-commu
|
||||
*/
|
||||
export type NetworkInfo = {
|
||||
|
||||
/**
|
||||
* Any extra info provided by the OS. Should be JSON and is OS specific. Reported only by iOS and Android and
|
||||
* the format is whatever comes out of the 'react-native-netinfo' library which is network type dependent.
|
||||
*/
|
||||
details?: {
|
||||
|
||||
/**
|
||||
* If {@link networkType} is {@link NetInfoStateType.cellular} then it may provide the info about the type of
|
||||
* cellular network.
|
||||
*/
|
||||
cellularGeneration?: NetInfoCellularGeneration;
|
||||
|
||||
/**
|
||||
* Indicates whether or not the connection is expensive.
|
||||
*/
|
||||
isConnectionExpensive?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Tells whether or not the internet is reachable.
|
||||
*/
|
||||
isOnline: boolean;
|
||||
isOnline: boolean,
|
||||
|
||||
/**
|
||||
* The network type. Currently reported only on Android/iOS. Can be one of the constants defined by
|
||||
* the 'react-native-netinfo' library.
|
||||
*/
|
||||
networkType?: NetInfoStateType;
|
||||
};
|
||||
networkType: ?NetInfoStateType,
|
||||
|
||||
/**
|
||||
* Any extra info provided by the OS. Should be JSON and is OS specific. Reported only by iOS and Android and
|
||||
* the format is whatever comes out of the 'react-native-netinfo' library which is network type dependent.
|
||||
*/
|
||||
details: ?{
|
||||
|
||||
/**
|
||||
* If {@link networkType} is {@link NetInfoStateType.cellular} then it may provide the info about the type of
|
||||
* cellular network.
|
||||
*/
|
||||
cellularGeneration: ?NetInfoCellularGeneration;
|
||||
|
||||
/**
|
||||
* Indicates whether or not the connection is expensive.
|
||||
*/
|
||||
isConnectionExpensive: ?boolean;
|
||||
}
|
||||
}
|
||||
@@ -8,8 +8,7 @@
|
||||
* participant: {
|
||||
* conference: JitsiConference,
|
||||
* id: string,
|
||||
* previousSpeakers: Array<string>,
|
||||
* silence: boolean
|
||||
* previousSpeakers: Array<string>
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { IStore } from '../../app/types';
|
||||
import { Dispatch } from 'redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { showNotification } from '../../notifications/actions';
|
||||
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
|
||||
import { set } from '../redux/functions';
|
||||
|
||||
import {
|
||||
DOMINANT_SPEAKER_CHANGED,
|
||||
GRANT_MODERATOR,
|
||||
HIDDEN_PARTICIPANT_JOINED,
|
||||
HIDDEN_PARTICIPANT_LEFT,
|
||||
GRANT_MODERATOR,
|
||||
KICK_PARTICIPANT,
|
||||
LOCAL_PARTICIPANT_AUDIO_LEVEL_CHANGED,
|
||||
LOCAL_PARTICIPANT_RAISE_HAND,
|
||||
MUTE_REMOTE_PARTICIPANT,
|
||||
OVERWRITE_PARTICIPANTS_NAMES,
|
||||
OVERWRITE_PARTICIPANT_NAME,
|
||||
OVERWRITE_PARTICIPANTS_NAMES,
|
||||
PARTICIPANT_ID_CHANGED,
|
||||
PARTICIPANT_JOINED,
|
||||
PARTICIPANT_KICKED,
|
||||
@@ -30,10 +32,10 @@ import {
|
||||
} from './constants';
|
||||
import {
|
||||
getLocalParticipant,
|
||||
getVirtualScreenshareParticipantOwnerId,
|
||||
getNormalizedDisplayName,
|
||||
getParticipantById,
|
||||
getParticipantDisplayName,
|
||||
getVirtualScreenshareParticipantOwnerId
|
||||
getParticipantById
|
||||
} from './functions';
|
||||
import logger from './logger';
|
||||
import { Participant } from './types';
|
||||
@@ -43,7 +45,6 @@ import { Participant } from './types';
|
||||
*
|
||||
* @param {string} dominantSpeaker - Participant ID of the dominant speaker.
|
||||
* @param {Array<string>} previousSpeakers - Participant IDs of the previous speakers.
|
||||
* @param {boolean} silence - Whether the dominant speaker is silent or not.
|
||||
* @param {JitsiConference} conference - The {@code JitsiConference} associated
|
||||
* with the participant identified by the specified {@code id}. Only the local
|
||||
* participant is allowed to not specify an associated {@code JitsiConference}
|
||||
@@ -53,20 +54,17 @@ import { Participant } from './types';
|
||||
* participant: {
|
||||
* conference: JitsiConference,
|
||||
* id: string,
|
||||
* previousSpeakers: Array<string>,
|
||||
* silence: boolean
|
||||
* previousSpeakers: Array<string>
|
||||
* }
|
||||
* }}
|
||||
*/
|
||||
export function dominantSpeakerChanged(
|
||||
dominantSpeaker: string, previousSpeakers: string[], silence: boolean, conference: any) {
|
||||
export function dominantSpeakerChanged(dominantSpeaker: string, previousSpeakers: string[], conference: any) {
|
||||
return {
|
||||
type: DOMINANT_SPEAKER_CHANGED,
|
||||
participant: {
|
||||
conference,
|
||||
id: dominantSpeaker,
|
||||
previousSpeakers,
|
||||
silence
|
||||
previousSpeakers
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -113,7 +111,7 @@ export function kickParticipant(id: string) {
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function localParticipantConnectionStatusChanged(connectionStatus: string) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
const participant = getLocalParticipant(getState);
|
||||
|
||||
if (participant) {
|
||||
@@ -133,7 +131,7 @@ export function localParticipantConnectionStatusChanged(connectionStatus: string
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function localParticipantIdChanged(id: string) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
const participant = getLocalParticipant(getState);
|
||||
|
||||
if (participant) {
|
||||
@@ -169,7 +167,7 @@ export function localParticipantJoined(participant: Participant = { id: '' }) {
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function localParticipantLeft() {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
const participant = getLocalParticipant(getState);
|
||||
|
||||
if (participant) {
|
||||
@@ -199,7 +197,7 @@ export function localParticipantLeft() {
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function localParticipantRoleChanged(role: string) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
const participant = getLocalParticipant(getState);
|
||||
|
||||
if (participant) {
|
||||
@@ -278,7 +276,7 @@ export function participantJoined(participant: Participant) {
|
||||
'A remote participant must be associated with a JitsiConference!');
|
||||
}
|
||||
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
// A remote participant is only expected to join in a joined or joining
|
||||
// conference. The following check is really necessary because a
|
||||
// JitsiConference may have moved into leaving but may still manage to
|
||||
@@ -308,7 +306,7 @@ export function participantJoined(participant: Participant) {
|
||||
* }}
|
||||
*/
|
||||
export function updateRemoteParticipantFeatures(jitsiParticipant: any) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
if (!jitsiParticipant) {
|
||||
return;
|
||||
}
|
||||
@@ -506,7 +504,7 @@ export function participantUpdated(participant: Participant = { id: '' }) {
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function participantMutedUs(participant: any, track: any) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch, getState: Function) => {
|
||||
if (!participant) {
|
||||
return;
|
||||
}
|
||||
@@ -530,7 +528,7 @@ export function participantMutedUs(participant: any, track: any) {
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function createVirtualScreenshareParticipant(sourceName: string, local: boolean) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
const state = getState();
|
||||
const ownerId = getVirtualScreenshareParticipantOwnerId(sourceName);
|
||||
const ownerName = getParticipantDisplayName(state, ownerId);
|
||||
@@ -553,7 +551,7 @@ export function createVirtualScreenshareParticipant(sourceName: string, local: b
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function participantKicked(kicker: any, kicked: any) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
|
||||
dispatch({
|
||||
type: PARTICIPANT_KICKED,
|
||||
|
||||
@@ -12,7 +12,7 @@ import { Container, TintedView } from '../../react';
|
||||
import { connect } from '../../redux';
|
||||
import { TestHint } from '../../testing/components';
|
||||
import { getVideoTrackByParticipant } from '../../tracks';
|
||||
import { getParticipantById, shouldRenderParticipantVideo } from '../functions';
|
||||
import { shouldRenderParticipantVideo, getParticipantById } from '../functions';
|
||||
|
||||
import styles from './styles';
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user