mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-09 00:00:19 +00:00
Compare commits
78 Commits
7280
...
android-sd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08e2b4a2dd | ||
|
|
7baa684e17 | ||
|
|
02ed9714f9 | ||
|
|
c5f91d31e4 | ||
|
|
febb50cd2c | ||
|
|
879e73c11a | ||
|
|
3ae18be21f | ||
|
|
9f5dbb21a7 | ||
|
|
2d14990b9e | ||
|
|
169c8ecb62 | ||
|
|
d608cf40f5 | ||
|
|
51a4e7daa3 | ||
|
|
7538bfc713 | ||
|
|
48e1f443ea | ||
|
|
2292ebe762 | ||
|
|
5425b52615 | ||
|
|
74f605e045 | ||
|
|
1918566581 | ||
|
|
ee8ba6696d | ||
|
|
15df3cb11e | ||
|
|
b77db024f5 | ||
|
|
c8a87e368a | ||
|
|
277ca23c52 | ||
|
|
55f66e236e | ||
|
|
70be08212d | ||
|
|
acb91990bf | ||
|
|
cd37cdd675 | ||
|
|
935a391525 | ||
|
|
d0f9231603 | ||
|
|
e461ec7027 | ||
|
|
5dc63f0632 | ||
|
|
f3dbf34842 | ||
|
|
66a9c4df25 | ||
|
|
e95a31c114 | ||
|
|
8565208d30 | ||
|
|
c1573057df | ||
|
|
904f820555 | ||
|
|
5172eda6b9 | ||
|
|
594a05a097 | ||
|
|
9ccdb62872 | ||
|
|
28d32cf740 | ||
|
|
ecc9b991ab | ||
|
|
5b83a91f9b | ||
|
|
bb7ae777b0 | ||
|
|
06e86a2f3e | ||
|
|
0a84dbb302 | ||
|
|
804f9041a6 | ||
|
|
7e8756a536 | ||
|
|
3b91e79675 | ||
|
|
dfc25e4519 | ||
|
|
d40aecb05d | ||
|
|
34e0b0392f | ||
|
|
8cc4a3c8b9 | ||
|
|
354a3c002a | ||
|
|
7d5eec779e | ||
|
|
90029003be | ||
|
|
c781884532 | ||
|
|
7272fd62a0 | ||
|
|
f21bd62ed0 | ||
|
|
842d0a9aef | ||
|
|
e06645a631 | ||
|
|
ebb65ea90c | ||
|
|
a7831ad809 | ||
|
|
80cfb80397 | ||
|
|
ae281e9935 | ||
|
|
b800ad8427 | ||
|
|
051cf67ce9 | ||
|
|
85e1333ad9 | ||
|
|
f02c7557af | ||
|
|
e82a5cf150 | ||
|
|
c92ce56110 | ||
|
|
4cae954eba | ||
|
|
b9d5838398 | ||
|
|
fcf723c679 | ||
|
|
06b67dcf44 | ||
|
|
61e9cacceb | ||
|
|
475c2f4606 | ||
|
|
20f2bfa449 |
16
.github/stale.yml
vendored
16
.github/stale.yml
vendored
@@ -1,16 +0,0 @@
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- confirmed
|
||||
staleLabel: wontfix
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
This issue has been automatically marked as stale because it has not had
|
||||
recent activity. It will be closed if no further activity occurs. Thank you
|
||||
for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: false
|
||||
|
||||
12
.github/workflows/ci.yml
vendored
12
.github/workflows/ci.yml
vendored
@@ -12,14 +12,24 @@ jobs:
|
||||
with:
|
||||
node-version: 16
|
||||
cache: 'npm'
|
||||
- name: Get changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v35
|
||||
- name: Get changed lang files
|
||||
id: lang-files
|
||||
run: echo "all=$(echo "${{ steps.changed-files.outputs.all_changed_files }}" | grep -oE 'lang\/\S+' | tr '\n' ' ')" >> "$GITHUB_OUTPUT"
|
||||
- run: npm install
|
||||
- name: Check git status
|
||||
run: git status
|
||||
- name: Normalize lang files to ensure sorted
|
||||
if: steps.lang-files.outputs.all
|
||||
run: npm run lang-sort
|
||||
- name: Check lang files are formatted correctly
|
||||
if: steps.lang-files.outputs.all
|
||||
run: npm run lint:lang
|
||||
- name: Check if the git repository is clean
|
||||
run: $(exit $(git status --porcelain --untracked-files=no | head -255 | wc -l)) || (echo "Dirty git tree"; git diff; exit 1)
|
||||
- run: npm run lint:ci
|
||||
- run: npm run lint:ci && npm run tsc:ci
|
||||
linux-build:
|
||||
name: Build Frontend (Linux)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
21
.github/workflows/stale.yml
vendored
Normal file
21
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/stale@v8
|
||||
with:
|
||||
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
|
||||
stale-pr-message: 'This PR has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
|
||||
stale-issue-label: 'stale'
|
||||
stale-pr-label: 'stale'
|
||||
exempt-issue-labels: 'confirmed,help-needed'
|
||||
exempt-pr-labels: 'confirmed'
|
||||
days-before-issue-stale: 60
|
||||
days-before-pr-stale: 90
|
||||
days-before-issue-close: 10
|
||||
days-before-pr-close: 10
|
||||
12
.gitignore
vendored
12
.gitignore
vendored
@@ -94,3 +94,15 @@ twa/*.aab
|
||||
twa/assetlinks.json
|
||||
|
||||
tsconfig.json
|
||||
|
||||
# React Native SDK
|
||||
#
|
||||
react-native-sdk/android/src
|
||||
react-native-sdk/images
|
||||
react-native-sdk/ios
|
||||
react-native-sdk/lang
|
||||
react-native-sdk/modules
|
||||
react-native-sdk/node_modules
|
||||
react-native-sdk/react
|
||||
react-native-sdk/service
|
||||
react-native-sdk/sounds
|
||||
|
||||
@@ -17,7 +17,7 @@ buildscript {
|
||||
}
|
||||
|
||||
ext {
|
||||
kotlinVersion = "1.5.32"
|
||||
kotlinVersion = "1.7.0"
|
||||
buildToolsVersion = "31.0.0"
|
||||
compileSdkVersion = 32
|
||||
minSdkVersion = 24
|
||||
|
||||
@@ -26,5 +26,5 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.bundle.enableUncompressedNativeLibs=false
|
||||
|
||||
appVersion=99.0.0
|
||||
sdkVersion=99.0.0
|
||||
appVersion=23.2.0
|
||||
sdkVersion=8.2.2
|
||||
|
||||
@@ -29,6 +29,10 @@ if [[ $MVN_HTTP == 1 ]]; then
|
||||
# Push React Native
|
||||
echo "Pushing React Native ${RN_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/react-native/android/com/facebook/react/react-native/${RN_VERSION}
|
||||
cat react-native-${RN_VERSION}.pom \
|
||||
| sed "s#<packaging>pom</packaging>#<packaging>aar</packaging>#" \
|
||||
| sed "/<optional>/d" \
|
||||
> react-native-${RN_VERSION}-fixed.pom
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
@@ -36,7 +40,7 @@ if [[ $MVN_HTTP == 1 ]]; then
|
||||
-Dfile=react-native-${RN_VERSION}-release.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom || true
|
||||
-DpomFile=react-native-${RN_VERSION}-fixed.pom || true
|
||||
popd
|
||||
# Push JSC
|
||||
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
|
||||
@@ -55,13 +59,17 @@ else
|
||||
if [[ ! -d ${MVN_REPO}/com/facebook/react/react-native/${RN_VERSION} ]]; then
|
||||
echo "Pushing React Native ${RN_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/react-native/android/com/facebook/react/react-native/${RN_VERSION}
|
||||
cat react-native-${RN_VERSION}.pom \
|
||||
| sed "s#<packaging>pom</packaging>#<packaging>aar</packaging>#" \
|
||||
| sed "/<optional>/d" \
|
||||
> react-native-${RN_VERSION}-fixed.pom
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-Dfile=react-native-${RN_VERSION}-release.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom
|
||||
-DpomFile=react-native-${RN_VERSION}-fixed.pom
|
||||
popd
|
||||
fi
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -32,7 +33,10 @@ import java.util.Map;
|
||||
class AppInfoModule
|
||||
extends ReactContextBaseJavaModule {
|
||||
|
||||
private static final String BUILD_CONFIG = "org.jitsi.meet.sdk.BuildConfig";
|
||||
public static final String NAME = "AppInfo";
|
||||
public static final boolean GOOGLE_SERVICES_ENABLED = getGoogleServicesEnabled();
|
||||
public static final boolean LIBRE_BUILD = getLibreBuild();
|
||||
|
||||
public AppInfoModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
@@ -75,8 +79,8 @@ class AppInfoModule
|
||||
constants.put(
|
||||
"version",
|
||||
packageInfo == null ? "" : packageInfo.versionName);
|
||||
constants.put("LIBRE_BUILD", BuildConfig.LIBRE_BUILD);
|
||||
constants.put("GOOGLE_SERVICES_ENABLED", BuildConfig.GOOGLE_SERVICES_ENABLED);
|
||||
constants.put("LIBRE_BUILD", LIBRE_BUILD);
|
||||
constants.put("GOOGLE_SERVICES_ENABLED", GOOGLE_SERVICES_ENABLED);
|
||||
|
||||
return constants;
|
||||
}
|
||||
@@ -85,4 +89,47 @@ class AppInfoModule
|
||||
public String getName() {
|
||||
return NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if libre google services object is null based on build configuration.
|
||||
*/
|
||||
private static boolean getGoogleServicesEnabled() {
|
||||
Object googleServicesEnabled = getBuildConfigValue("GOOGLE_SERVICES_ENABLED");
|
||||
|
||||
if (googleServicesEnabled !=null) {
|
||||
return (Boolean) googleServicesEnabled;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if libre build field is null based on build configuration.
|
||||
*/
|
||||
private static boolean getLibreBuild() {
|
||||
Object libreBuild = getBuildConfigValue("LIBRE_BUILD");
|
||||
|
||||
if (libreBuild !=null) {
|
||||
return (Boolean) libreBuild;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets build config value of a certain field.
|
||||
*
|
||||
* @param fieldName Field from build config.
|
||||
*/
|
||||
private static Object getBuildConfigValue(String fieldName) {
|
||||
try {
|
||||
Class<?> c = Class.forName(BUILD_CONFIG);
|
||||
Field f = c.getDeclaredField(fieldName);
|
||||
f.setAccessible(true);
|
||||
return f.get(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.telecom.PhoneAccount;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telecom.VideoProfile;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
@@ -357,7 +358,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
JitsiMeetLogger.i(TAG + " onDisconnect " + getCallUUID());
|
||||
WritableNativeMap data = new WritableNativeMap();
|
||||
data.putString("callUUID", getCallUUID());
|
||||
ReactInstanceManagerHolder.emitEvent(
|
||||
RNConnectionService.getInstance().emitEvent(
|
||||
"org.jitsi.meet:features/connection_service#disconnect",
|
||||
data);
|
||||
// The JavaScript side will not go back to the native with
|
||||
@@ -377,7 +378,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
JitsiMeetLogger.i(TAG + " onAbort " + getCallUUID());
|
||||
WritableNativeMap data = new WritableNativeMap();
|
||||
data.putString("callUUID", getCallUUID());
|
||||
ReactInstanceManagerHolder.emitEvent(
|
||||
RNConnectionService.getInstance().emitEvent(
|
||||
"org.jitsi.meet:features/connection_service#abort",
|
||||
data);
|
||||
// The JavaScript side will not go back to the native with
|
||||
@@ -406,7 +407,7 @@ public class ConnectionService extends android.telecom.ConnectionService {
|
||||
@Override
|
||||
public void onCallAudioStateChanged(CallAudioState state) {
|
||||
JitsiMeetLogger.d(TAG + " onCallAudioStateChanged: " + state);
|
||||
RNConnectionService module = ReactInstanceManagerHolder.getNativeModule(RNConnectionService.class);
|
||||
RNConnectionService module = RNConnectionService.getInstance();
|
||||
if (module != null) {
|
||||
module.onCallAudioStateChange(state);
|
||||
}
|
||||
|
||||
@@ -10,14 +10,19 @@ import android.telecom.PhoneAccount;
|
||||
import android.telecom.PhoneAccountHandle;
|
||||
import android.telecom.TelecomManager;
|
||||
import android.telecom.VideoProfile;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
@@ -35,6 +40,7 @@ class RNConnectionService extends ReactContextBaseJavaModule {
|
||||
|
||||
private static final String TAG = ConnectionService.TAG;
|
||||
|
||||
private static RNConnectionService sRNConnectionServiceInstance;
|
||||
/**
|
||||
* Handler for dealing with call state changes. We are acting as a proxy between ConnectionService
|
||||
* and other modules such as {@link AudioModeModule}.
|
||||
@@ -57,6 +63,11 @@ class RNConnectionService extends ReactContextBaseJavaModule {
|
||||
|
||||
RNConnectionService(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
sRNConnectionServiceInstance = this;
|
||||
}
|
||||
|
||||
static RNConnectionService getInstance() {
|
||||
return sRNConnectionServiceInstance;
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
@@ -226,4 +237,22 @@ class RNConnectionService extends ReactContextBaseJavaModule {
|
||||
interface CallAudioStateListener {
|
||||
void onCallAudioStateChange(android.telecom.CallAudioState callAudioState);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to send an event to JavaScript.
|
||||
*
|
||||
* @param eventName {@code String} containing the event name.
|
||||
* @param data {@code Object} optional ancillary data for the event.
|
||||
*/
|
||||
void emitEvent(
|
||||
String eventName,
|
||||
@Nullable Object data) {
|
||||
ReactContext reactContext = getReactApplicationContext();
|
||||
|
||||
if (reactContext != null) {
|
||||
reactContext
|
||||
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
|
||||
.emit(eventName, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
102
conference.js
102
conference.js
@@ -87,6 +87,7 @@ import {
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import {
|
||||
gumPending,
|
||||
setAudioAvailable,
|
||||
setAudioMuted,
|
||||
setAudioUnmutePermissions,
|
||||
@@ -100,6 +101,7 @@ import {
|
||||
getStartWithVideoMuted,
|
||||
isVideoMutedByUser
|
||||
} from './react/features/base/media/functions';
|
||||
import { IGUMPendingState } from './react/features/base/media/types';
|
||||
import {
|
||||
dominantSpeakerChanged,
|
||||
localParticipantAudioLevelChanged,
|
||||
@@ -361,11 +363,11 @@ class ConferenceConnector {
|
||||
const [ vnode ] = params;
|
||||
|
||||
APP.store.dispatch(overwriteConfig(newConfig))
|
||||
.then(this._conference.leaveRoom())
|
||||
.then(APP.store.dispatch(setIAmVisitor(Boolean(vnode))))
|
||||
.then(() => this._conference.leaveRoom())
|
||||
.then(() => APP.store.dispatch(setIAmVisitor(Boolean(vnode))))
|
||||
|
||||
// we do not clear local tracks on error, so we need to manually clear them
|
||||
.then(APP.store.dispatch(destroyLocalTracks()))
|
||||
.then(() => APP.store.dispatch(destroyLocalTracks()))
|
||||
.then(() => {
|
||||
// Reset VideoLayout. It's destroyed in features/video-layout/middleware.web.js so re-initialize it.
|
||||
VideoLayout.initLargeVideo();
|
||||
@@ -418,7 +420,7 @@ class ConferenceConnector {
|
||||
|
||||
if (newConfig) {
|
||||
APP.store.dispatch(overwriteConfig(newConfig))
|
||||
.then(this._conference.leaveRoom())
|
||||
.then(() => this._conference.leaveRoom())
|
||||
.then(() => {
|
||||
_connectionPromise = connect(this._conference.roomName);
|
||||
|
||||
@@ -493,6 +495,21 @@ function disconnect() {
|
||||
return connection.disconnect().then(onDisconnected, onDisconnected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the GUM pending state for the tracks that have failed.
|
||||
*
|
||||
* NOTE: Some of the track that we will be setting to GUM pending state NONE may not have failed but they may have
|
||||
* been requested. This won't be a problem because their current GUM pending state will be NONE anyway.
|
||||
* @param {JitsiLocalTrack} tracks - The tracks that have been created.
|
||||
* @returns {void}
|
||||
*/
|
||||
function setGUMPendingStateOnFailedTracks(tracks) {
|
||||
const tracksTypes = tracks.map(track => track.getType());
|
||||
const nonPendingTracks = [ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ].filter(type => !tracksTypes.includes(type));
|
||||
|
||||
APP.store.dispatch(gumPending(nonPendingTracks, IGUMPendingState.NONE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles CONNECTION_FAILED events from lib-jitsi-meet.
|
||||
*
|
||||
@@ -601,6 +618,7 @@ export default {
|
||||
return [];
|
||||
});
|
||||
} else if (requestedAudio || requestedVideo) {
|
||||
APP.store.dispatch(gumPending(initialDevices, IGUMPendingState.PENDING_UNMUTE));
|
||||
tryCreateLocalTracks = createLocalTracksF({
|
||||
devices: initialDevices,
|
||||
timeout,
|
||||
@@ -863,6 +881,8 @@ export default {
|
||||
this._initDeviceList(true);
|
||||
|
||||
if (isPrejoinPageVisible(state)) {
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
|
||||
|
||||
return APP.store.dispatch(initPrejoin(localTracks, errors));
|
||||
}
|
||||
|
||||
@@ -870,14 +890,22 @@ export default {
|
||||
|
||||
this._displayErrorsForCreateInitialLocalTracks(errors);
|
||||
|
||||
return this._setLocalAudioVideoStreams(handleInitialTracks(initialOptions, localTracks));
|
||||
const tracks = handleInitialTracks(initialOptions, localTracks);
|
||||
|
||||
setGUMPendingStateOnFailedTracks(tracks);
|
||||
|
||||
return this._setLocalAudioVideoStreams(tracks);
|
||||
}
|
||||
|
||||
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(roomName, initialOptions);
|
||||
|
||||
this._initDeviceList(true);
|
||||
|
||||
return this.startConference(con, handleInitialTracks(initialOptions, tracks));
|
||||
const filteredTracks = handleInitialTracks(initialOptions, tracks);
|
||||
|
||||
setGUMPendingStateOnFailedTracks(filteredTracks);
|
||||
|
||||
return this.startConference(con, filteredTracks);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1000,6 +1028,7 @@ export default {
|
||||
showUI && APP.store.dispatch(notifyMicError(error));
|
||||
};
|
||||
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.PENDING_UNMUTE));
|
||||
createLocalTracksF({ devices: [ 'audio' ] })
|
||||
.then(([ audioTrack ]) => audioTrack)
|
||||
.catch(error => {
|
||||
@@ -1011,7 +1040,10 @@ export default {
|
||||
.then(async audioTrack => {
|
||||
await this._maybeApplyAudioMixerEffect(audioTrack);
|
||||
|
||||
this.useAudioStream(audioTrack);
|
||||
return this.useAudioStream(audioTrack);
|
||||
})
|
||||
.finally(() => {
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO ], IGUMPendingState.NONE));
|
||||
});
|
||||
} else {
|
||||
muteLocalAudio(mute);
|
||||
@@ -1091,6 +1123,8 @@ export default {
|
||||
|
||||
this.isCreatingLocalTrack = true;
|
||||
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.PENDING_UNMUTE));
|
||||
|
||||
// Try to create local video if there wasn't any.
|
||||
// This handles the case when user joined with no video
|
||||
// (dismissed screen sharing screen or in audio only mode), but
|
||||
@@ -1115,6 +1149,7 @@ export default {
|
||||
})
|
||||
.finally(() => {
|
||||
this.isCreatingLocalTrack = false;
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
|
||||
});
|
||||
} else {
|
||||
// FIXME show error dialog if it fails (should be handled by react)
|
||||
@@ -1427,11 +1462,16 @@ export default {
|
||||
* @private
|
||||
*/
|
||||
_setLocalAudioVideoStreams(tracks = []) {
|
||||
const { dispatch } = APP.store;
|
||||
const pendingGUMDevicesToRemove = [];
|
||||
const promises = tracks.map(track => {
|
||||
if (track.isAudioTrack()) {
|
||||
pendingGUMDevicesToRemove.push(MEDIA_TYPE.AUDIO);
|
||||
|
||||
return this.useAudioStream(track);
|
||||
} else if (track.isVideoTrack()) {
|
||||
logger.debug(`_setLocalAudioVideoStreams is calling useVideoStream with track: ${track}`);
|
||||
pendingGUMDevicesToRemove.push(MEDIA_TYPE.VIDEO);
|
||||
|
||||
return this.useVideoStream(track);
|
||||
}
|
||||
@@ -1443,6 +1483,10 @@ export default {
|
||||
});
|
||||
|
||||
return Promise.allSettled(promises).then(() => {
|
||||
if (pendingGUMDevicesToRemove.length > 0) {
|
||||
dispatch(gumPending(pendingGUMDevicesToRemove, IGUMPendingState.NONE));
|
||||
}
|
||||
|
||||
this._localTracksInitialized = true;
|
||||
logger.log(`Initialized with ${tracks.length} local tracks`);
|
||||
});
|
||||
@@ -1985,7 +2029,10 @@ export default {
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.NON_PARTICIPANT_MESSAGE_RECEIVED,
|
||||
(...args) => APP.store.dispatch(nonParticipantMessageReceived(...args)));
|
||||
(...args) => {
|
||||
APP.store.dispatch(nonParticipantMessageReceived(...args));
|
||||
APP.API.notifyNonParticipantMessageReceived(...args);
|
||||
});
|
||||
|
||||
room.on(
|
||||
JitsiConferenceEvents.LOCK_STATE_CHANGED,
|
||||
@@ -2156,6 +2203,11 @@ export default {
|
||||
UIEvents.VIDEO_DEVICE_CHANGED,
|
||||
cameraDeviceId => {
|
||||
const videoWasMuted = this.isLocalVideoMuted();
|
||||
const localVideoTrack = getLocalJitsiVideoTrack(APP.store.getState());
|
||||
|
||||
if (localVideoTrack?.getDeviceId() === cameraDeviceId) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendAnalytics(createDeviceChangedEvent('video', 'input'));
|
||||
|
||||
@@ -2400,7 +2452,9 @@ export default {
|
||||
const { dispatch } = APP.store;
|
||||
const setAudioOutputPromise
|
||||
= setAudioOutputDeviceId(newDevices.audiooutput, dispatch)
|
||||
.catch(); // Just ignore any errors in catch block.
|
||||
.catch(err => {
|
||||
logger.error(`Failed to set the audio output device to ${newDevices.audiooutput} - ${err}`);
|
||||
});
|
||||
|
||||
promises.push(setAudioOutputPromise);
|
||||
}
|
||||
@@ -2438,7 +2492,7 @@ export default {
|
||||
}
|
||||
|
||||
// check for video
|
||||
if (!requestedInput.video) {
|
||||
if (requestedInput.video) {
|
||||
APP.store.dispatch(checkAndNotifyForNewDevice(newAvailDevices.videoInput, oldDevices.videoInput));
|
||||
}
|
||||
|
||||
@@ -2482,14 +2536,15 @@ export default {
|
||||
// Create the tracks and replace them only if the user is unmuted.
|
||||
if (requestedInput.audio || requestedInput.video) {
|
||||
let tracks = [];
|
||||
const realAudioDeviceId = hasDefaultMicChanged
|
||||
? getDefaultDeviceId(APP.store.getState(), 'audioInput') : newDevices.audioinput;
|
||||
|
||||
try {
|
||||
tracks = await mediaDeviceHelper.createLocalTracksAfterDeviceListChanged(
|
||||
createLocalTracksF,
|
||||
newDevices.videoinput,
|
||||
hasDefaultMicChanged
|
||||
? getDefaultDeviceId(APP.store.getState(), 'audioInput')
|
||||
: newDevices.audioinput);
|
||||
requestedInput.video ? newDevices.videoinput : null,
|
||||
requestedInput.audio ? realAudioDeviceId : null
|
||||
);
|
||||
} catch (error) {
|
||||
logger.error(`Track creation failed on device change, ${error}`);
|
||||
|
||||
@@ -2620,17 +2675,22 @@ export default {
|
||||
async leaveRoom(doDisconnect = true, reason = '') {
|
||||
APP.store.dispatch(conferenceWillLeave(room));
|
||||
|
||||
const maybeDisconnect = () => {
|
||||
if (doDisconnect) {
|
||||
return disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
if (room && room.isJoined()) {
|
||||
return room.leave(reason).finally(() => {
|
||||
if (doDisconnect) {
|
||||
return disconnect();
|
||||
}
|
||||
return room.leave(reason).then(() => maybeDisconnect())
|
||||
.catch(e => {
|
||||
logger.error(e);
|
||||
|
||||
return maybeDisconnect();
|
||||
});
|
||||
}
|
||||
|
||||
if (doDisconnect) {
|
||||
return disconnect();
|
||||
}
|
||||
return maybeDisconnect();
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
11
config.js
11
config.js
@@ -74,6 +74,9 @@ var config = {
|
||||
//
|
||||
|
||||
testing: {
|
||||
// Allows the setting of a custom bandwidth value from the UI.
|
||||
// assumeBandwidth: true,
|
||||
|
||||
// Disables the End to End Encryption feature. Useful for debugging
|
||||
// issues related to insertable streams.
|
||||
// disableE2EE: false,
|
||||
@@ -1065,7 +1068,12 @@ var config = {
|
||||
// },
|
||||
|
||||
// e2ee: {
|
||||
// labels,
|
||||
// labels: {
|
||||
// description: '',
|
||||
// label: '',
|
||||
// tooltip: '',
|
||||
// warning: '',
|
||||
// },
|
||||
// externallyManagedKey: false,
|
||||
// },
|
||||
|
||||
@@ -1375,7 +1383,6 @@ var config = {
|
||||
dialOutRegionUrl
|
||||
disableRemoteControl
|
||||
displayJids
|
||||
e2eeLabels
|
||||
firefox_fake_device
|
||||
googleApiApplicationClientID
|
||||
iAmRecorder
|
||||
|
||||
@@ -32,6 +32,14 @@
|
||||
pointer-events: none;
|
||||
z-index: $toolbarZ + 2;
|
||||
|
||||
&.shift-up {
|
||||
bottom: calc(((#{$newToolbarSize} + 30px) * 2) * -1);
|
||||
|
||||
.toolbox-content {
|
||||
margin-bottom: 46px;
|
||||
}
|
||||
}
|
||||
|
||||
&.visible {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@@ -41,3 +41,36 @@
|
||||
display: -webkit-flex !important;
|
||||
display: flex !important;
|
||||
}
|
||||
|
||||
/**
|
||||
* resets default button styles,
|
||||
* mostly intended to be used on interactive elements that
|
||||
* differ from their default styles (e.g. <a>) or have custom styles
|
||||
*/
|
||||
.invisible-button {
|
||||
background: none;
|
||||
border: none;
|
||||
color: inherit;
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* style an element the same as an <a>
|
||||
* useful on some cases where we visually have a link but it's actually a <button>
|
||||
*/
|
||||
.as-link {
|
||||
@extend .invisible-button;
|
||||
|
||||
display: inline;
|
||||
color: #44A5FF;
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
|
||||
&:focus,
|
||||
&:hover,
|
||||
&:active {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
&-actions {
|
||||
margin-top: 10px;
|
||||
a {
|
||||
button {
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
const jaasJwt = <!--#include virtual="/jaas-jwt" -->;
|
||||
const api = new JitsiMeetExternalAPI(
|
||||
window.location.host, {
|
||||
roomName: `${jaasJwt.tenant}/${getRoomName(window.location.pathname)}`,
|
||||
roomName: `${jaasJwt.tenant}/${jaasJwt.confId}`,
|
||||
parentNode: document.querySelector('#jaas-container'),
|
||||
jwt: jaasJwt.token,
|
||||
e2eeKey: jaasJwt.e2eeKey
|
||||
|
||||
@@ -8,7 +8,7 @@ location = /jaas-jwt {
|
||||
proxy_set_header Authorization "Bearer $jaas_asap_key";
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_body '{"sub":"jaas_magic_cookie","context":{"features":{"livestreaming":false,"outbound-call":false,"sip-outbound-call":false,"transcription":false,"recording":false},"user":{"moderator":true}},"room": "$roomname"}';
|
||||
proxy_pass http://127.0.0.1:8017/generate/client?e2eeKey=true;
|
||||
proxy_pass http://127.0.0.1:8017/generate/client?e2eeKey=true&confId=true;
|
||||
}
|
||||
|
||||
location @magic_root_path {
|
||||
|
||||
468
ios/Podfile.lock
468
ios/Podfile.lock
@@ -14,14 +14,14 @@ PODS:
|
||||
- CocoaLumberjack/Core (= 3.7.2)
|
||||
- CocoaLumberjack/Core (3.7.2)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.68.6)
|
||||
- FBReactNativeSpec (0.68.6):
|
||||
- FBLazyVector (0.69.11)
|
||||
- FBReactNativeSpec (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.6)
|
||||
- RCTTypeSafety (= 0.68.6)
|
||||
- React-Core (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- RCTRequired (= 0.69.11)
|
||||
- RCTTypeSafety (= 0.69.11)
|
||||
- React-Core (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- Firebase/Analytics (8.15.0):
|
||||
- Firebase/Core
|
||||
- Firebase/Core (8.15.0):
|
||||
@@ -77,10 +77,10 @@ PODS:
|
||||
- GoogleUtilities/UserDefaults (~> 7.7)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- fmt (6.2.1)
|
||||
- Giphy (2.1.20):
|
||||
- Giphy (2.2.4):
|
||||
- libwebp
|
||||
- giphy-react-native-sdk (1.7.0):
|
||||
- Giphy (= 2.1.20)
|
||||
- giphy-react-native-sdk (2.3.0):
|
||||
- Giphy (= 2.2.4)
|
||||
- React-Core
|
||||
- glog (0.3.5)
|
||||
- GoogleAppMeasurement (8.15.0):
|
||||
@@ -164,201 +164,203 @@ PODS:
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCTRequired (0.68.6)
|
||||
- RCTTypeSafety (0.68.6):
|
||||
- FBLazyVector (= 0.68.6)
|
||||
- RCTRequired (0.69.11)
|
||||
- RCTTypeSafety (0.69.11):
|
||||
- FBLazyVector (= 0.69.11)
|
||||
- RCTRequired (= 0.69.11)
|
||||
- React-Core (= 0.69.11)
|
||||
- React (0.69.11):
|
||||
- React-Core (= 0.69.11)
|
||||
- React-Core/DevSupport (= 0.69.11)
|
||||
- React-Core/RCTWebSocket (= 0.69.11)
|
||||
- React-RCTActionSheet (= 0.69.11)
|
||||
- React-RCTAnimation (= 0.69.11)
|
||||
- React-RCTBlob (= 0.69.11)
|
||||
- React-RCTImage (= 0.69.11)
|
||||
- React-RCTLinking (= 0.69.11)
|
||||
- React-RCTNetwork (= 0.69.11)
|
||||
- React-RCTSettings (= 0.69.11)
|
||||
- React-RCTText (= 0.69.11)
|
||||
- React-RCTVibration (= 0.69.11)
|
||||
- React-bridging (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.6)
|
||||
- React-Core (= 0.68.6)
|
||||
- React (0.68.6):
|
||||
- React-Core (= 0.68.6)
|
||||
- React-Core/DevSupport (= 0.68.6)
|
||||
- React-Core/RCTWebSocket (= 0.68.6)
|
||||
- React-RCTActionSheet (= 0.68.6)
|
||||
- React-RCTAnimation (= 0.68.6)
|
||||
- React-RCTBlob (= 0.68.6)
|
||||
- React-RCTImage (= 0.68.6)
|
||||
- React-RCTLinking (= 0.68.6)
|
||||
- React-RCTNetwork (= 0.68.6)
|
||||
- React-RCTSettings (= 0.68.6)
|
||||
- React-RCTText (= 0.68.6)
|
||||
- React-RCTVibration (= 0.68.6)
|
||||
- React-callinvoker (0.68.6)
|
||||
- React-Codegen (0.68.6):
|
||||
- FBReactNativeSpec (= 0.68.6)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-callinvoker (0.69.11)
|
||||
- React-Codegen (0.69.11):
|
||||
- FBReactNativeSpec (= 0.69.11)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.6)
|
||||
- RCTTypeSafety (= 0.68.6)
|
||||
- React-Core (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-Core (0.68.6):
|
||||
- RCTRequired (= 0.69.11)
|
||||
- RCTTypeSafety (= 0.69.11)
|
||||
- React-Core (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-Core (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.6)
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-Core/Default (= 0.69.11)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.68.6):
|
||||
- React-Core/CoreModulesHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/Default (0.68.6):
|
||||
- React-Core/Default (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.68.6):
|
||||
- React-Core/DevSupport (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.6)
|
||||
- React-Core/RCTWebSocket (= 0.68.6)
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-jsinspector (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-Core/Default (= 0.69.11)
|
||||
- React-Core/RCTWebSocket (= 0.69.11)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-jsinspector (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.68.6):
|
||||
- React-Core/RCTActionSheetHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.68.6):
|
||||
- React-Core/RCTAnimationHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.68.6):
|
||||
- React-Core/RCTBlobHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.68.6):
|
||||
- React-Core/RCTImageHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.68.6):
|
||||
- React-Core/RCTLinkingHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.68.6):
|
||||
- React-Core/RCTNetworkHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.68.6):
|
||||
- React-Core/RCTSettingsHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.68.6):
|
||||
- React-Core/RCTTextHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.68.6):
|
||||
- React-Core/RCTVibrationHeaders (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.68.6):
|
||||
- React-Core/RCTWebSocket (0.69.11):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.68.6)
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsiexecutor (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-Core/Default (= 0.69.11)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsiexecutor (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- Yoga
|
||||
- React-CoreModules (0.68.6):
|
||||
- React-CoreModules (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.6)
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/CoreModulesHeaders (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-RCTImage (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-cxxreact (0.68.6):
|
||||
- RCTTypeSafety (= 0.69.11)
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/CoreModulesHeaders (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-RCTImage (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-cxxreact (0.69.11):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-jsinspector (= 0.68.6)
|
||||
- React-logger (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-runtimeexecutor (= 0.68.6)
|
||||
- React-jsi (0.68.6):
|
||||
- React-callinvoker (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-jsinspector (= 0.69.11)
|
||||
- React-logger (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- React-runtimeexecutor (= 0.69.11)
|
||||
- React-jsi (0.69.11):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.68.6)
|
||||
- React-jsi/Default (0.68.6):
|
||||
- React-jsi/Default (= 0.69.11)
|
||||
- React-jsi/Default (0.69.11):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.68.6):
|
||||
- React-jsiexecutor (0.69.11):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-jsinspector (0.68.6)
|
||||
- React-logger (0.68.6):
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- React-jsinspector (0.69.11)
|
||||
- React-logger (0.69.11):
|
||||
- glog
|
||||
- react-native-background-timer (2.4.1):
|
||||
- React-Core
|
||||
@@ -372,8 +374,6 @@ PODS:
|
||||
- React-Core
|
||||
- react-native-pager-view (5.4.9):
|
||||
- React-Core
|
||||
- react-native-performance (2.1.0):
|
||||
- React-Core
|
||||
- react-native-safe-area-context (4.4.1):
|
||||
- RCT-Folly
|
||||
- RCTRequired
|
||||
@@ -390,76 +390,77 @@ PODS:
|
||||
- react-native-video/Video (6.0.0-alpha.1):
|
||||
- PromisesSwift
|
||||
- React-Core
|
||||
- react-native-webrtc (111.0.0):
|
||||
- react-native-webrtc (111.0.1):
|
||||
- JitsiWebRTC (~> 111.0.0)
|
||||
- React-Core
|
||||
- react-native-webview (11.15.1):
|
||||
- React-Core
|
||||
- React-perflogger (0.68.6)
|
||||
- React-RCTActionSheet (0.68.6):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.68.6)
|
||||
- React-RCTAnimation (0.68.6):
|
||||
- React-perflogger (0.69.11)
|
||||
- React-RCTActionSheet (0.69.11):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.69.11)
|
||||
- React-RCTAnimation (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.6)
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/RCTAnimationHeaders (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-RCTBlob (0.68.6):
|
||||
- RCTTypeSafety (= 0.69.11)
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/RCTAnimationHeaders (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-RCTBlob (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/RCTBlobHeaders (= 0.68.6)
|
||||
- React-Core/RCTWebSocket (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-RCTNetwork (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-RCTImage (0.68.6):
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/RCTBlobHeaders (= 0.69.11)
|
||||
- React-Core/RCTWebSocket (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-RCTNetwork (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-RCTImage (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.6)
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/RCTImageHeaders (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-RCTNetwork (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-RCTLinking (0.68.6):
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/RCTLinkingHeaders (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-RCTNetwork (0.68.6):
|
||||
- RCTTypeSafety (= 0.69.11)
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/RCTImageHeaders (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-RCTNetwork (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-RCTLinking (0.69.11):
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/RCTLinkingHeaders (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-RCTNetwork (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.6)
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/RCTNetworkHeaders (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-RCTSettings (0.68.6):
|
||||
- RCTTypeSafety (= 0.69.11)
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/RCTNetworkHeaders (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-RCTSettings (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.68.6)
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/RCTSettingsHeaders (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-RCTText (0.68.6):
|
||||
- React-Core/RCTTextHeaders (= 0.68.6)
|
||||
- React-RCTVibration (0.68.6):
|
||||
- RCTTypeSafety (= 0.69.11)
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/RCTSettingsHeaders (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-RCTText (0.69.11):
|
||||
- React-Core/RCTTextHeaders (= 0.69.11)
|
||||
- React-RCTVibration (0.69.11):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Codegen (= 0.68.6)
|
||||
- React-Core/RCTVibrationHeaders (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (= 0.68.6)
|
||||
- React-runtimeexecutor (0.68.6):
|
||||
- React-jsi (= 0.68.6)
|
||||
- ReactCommon/turbomodule/core (0.68.6):
|
||||
- React-Codegen (= 0.69.11)
|
||||
- React-Core/RCTVibrationHeaders (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (= 0.69.11)
|
||||
- React-runtimeexecutor (0.69.11):
|
||||
- React-jsi (= 0.69.11)
|
||||
- ReactCommon/turbomodule/core (0.69.11):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.68.6)
|
||||
- React-Core (= 0.68.6)
|
||||
- React-cxxreact (= 0.68.6)
|
||||
- React-jsi (= 0.68.6)
|
||||
- React-logger (= 0.68.6)
|
||||
- React-perflogger (= 0.68.6)
|
||||
- React-bridging (= 0.69.11)
|
||||
- React-callinvoker (= 0.69.11)
|
||||
- React-Core (= 0.69.11)
|
||||
- React-cxxreact (= 0.69.11)
|
||||
- React-jsi (= 0.69.11)
|
||||
- React-logger (= 0.69.11)
|
||||
- React-perflogger (= 0.69.11)
|
||||
- RNCalendarEvents (2.2.0):
|
||||
- React
|
||||
- RNCAsyncStorage (1.17.3):
|
||||
@@ -507,10 +508,10 @@ DEPENDENCIES:
|
||||
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- React-bridging (from `../node_modules/react-native/ReactCommon`)
|
||||
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
|
||||
- React-Codegen (from `build/generated/ios`)
|
||||
- React-Core (from `../node_modules/react-native/`)
|
||||
- React-Core/DevSupport (from `../node_modules/react-native/`)
|
||||
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
|
||||
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
|
||||
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
|
||||
@@ -524,7 +525,6 @@ DEPENDENCIES:
|
||||
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
|
||||
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
|
||||
- react-native-pager-view (from `../node_modules/react-native-pager-view`)
|
||||
- react-native-performance (from `../node_modules/react-native-performance/ios`)
|
||||
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
|
||||
- "react-native-slider (from `../node_modules/@react-native-community/slider`)"
|
||||
- react-native-splash-screen (from `../node_modules/react-native-splash-screen`)
|
||||
@@ -606,6 +606,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/Libraries/TypeSafety"
|
||||
React:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-bridging:
|
||||
:path: "../node_modules/react-native/ReactCommon"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Codegen:
|
||||
@@ -636,8 +638,6 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native-orientation-locker"
|
||||
react-native-pager-view:
|
||||
:path: "../node_modules/react-native-pager-view"
|
||||
react-native-performance:
|
||||
:path: "../node_modules/react-native-performance/ios"
|
||||
react-native-safe-area-context:
|
||||
:path: "../node_modules/react-native-safe-area-context"
|
||||
react-native-slider:
|
||||
@@ -705,9 +705,9 @@ SPEC CHECKSUMS:
|
||||
AppAuth: e48b432bb4ba88b10cb2bcc50d7f3af21e78b9c2
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: 74b042924fe14da854ac4e87cefc417f583b22b1
|
||||
FBReactNativeSpec: cc0037b9914b9b1d92a15f179bc3e2e2c7cc0c6f
|
||||
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
|
||||
FBLazyVector: 5c0975e66853436589eae7542f4b956c7e2ef465
|
||||
FBReactNativeSpec: bb062293e84c33200005312d1807d8cb94a0d66a
|
||||
Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
|
||||
FirebaseAnalytics: 7761cbadb00a717d8d0939363eb46041526474fa
|
||||
FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1
|
||||
@@ -716,9 +716,9 @@ SPEC CHECKSUMS:
|
||||
FirebaseDynamicLinks: 1dc816ef789c5adac6fede0b46d11478175c70e4
|
||||
FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
Giphy: b6d5087521d251bb8c99cdc0eb07bbdf86d142d5
|
||||
giphy-react-native-sdk: 7abccf2b52123a0f30ce99da895ab6288023680c
|
||||
glog: 476ee3e89abb49e07f822b48323c51c57124b572
|
||||
Giphy: 6b5f6986c8df4f71e01a8ef86595f426b3439fb5
|
||||
giphy-react-native-sdk: fcda9639f8ca2cc47e0517b6ef11c19359db5f5a
|
||||
glog: 3d02b25ca00c2d456734d0bcff864cbc62f6ae1a
|
||||
GoogleAppMeasurement: 4c19f031220c72464d460c9daa1fb5d1acce958e
|
||||
GoogleDataTransport: 8378d1fa8ac49753ea6ce70d65a7cb70ce5f66e6
|
||||
GoogleSignIn: 5651ce3a61e56ca864160e79b484cd9ed3f49b7a
|
||||
@@ -731,44 +731,44 @@ SPEC CHECKSUMS:
|
||||
ObjectiveDropboxOfficial: fe206ce8c0bc49976c249d472db7fdbc53ebbd53
|
||||
PromisesObjC: 09985d6d70fbe7878040aa746d78236e6946d2ef
|
||||
PromisesSwift: cf9eb58666a43bbe007302226e510b16c1e10959
|
||||
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
|
||||
RCTRequired: 92cbd71369a2de6add25fd2403ac39838f1b694f
|
||||
RCTTypeSafety: 494e8af41d7410ed0b877210859ee3984f37e6b4
|
||||
React: 59989499c0e8926a90d34a9ae0bdb2d1b5b53406
|
||||
React-callinvoker: 8187db1c71cf2c1c66e8f7328a0cf77a2b255d94
|
||||
React-Codegen: e806dc2f10ddae645d855cb58acf73ce41eb8ea5
|
||||
React-Core: fc7339b493e368ae079850a4721bdf716cf3dba2
|
||||
React-CoreModules: 2f54f6bbf2764044379332089fcbdaf79197021e
|
||||
React-cxxreact: ee119270006794976e1ab271f0111a5a88b16bcf
|
||||
React-jsi: ec691b2a475d13b1fd39f697145a526eeeb6661c
|
||||
React-jsiexecutor: b4ce4afc5dd9c8fdd2ac59049ccf420f288ecef7
|
||||
React-jsinspector: e396d5e56af08fce39f50571726b68a40f1e302d
|
||||
React-logger: cec52b3f8fb0be0d47b2cb75dec69de60f2de3b6
|
||||
RCT-Folly: b9d9fe1fc70114b751c076104e52f3b1b5e5a95a
|
||||
RCTRequired: 8e9a57dddc8f8e9e816c67c2d2537271a997137a
|
||||
RCTTypeSafety: 2b19e268e2036a2c2f6db6deb1ac03e28b1d607a
|
||||
React: f9478e6390f177ee6b67b87a3c6afea42b39523e
|
||||
React-bridging: d405ecd3ff80e1d0a4059a11063eaa9ed7a00c58
|
||||
React-callinvoker: c8ffa61f3f06f486ba6647769fc98f19e25d165a
|
||||
React-Codegen: 73acfdac1495b91ad5efdd3ab005568263c5def6
|
||||
React-Core: 7b7c75af4b73fe0ed4e5c3cdb7d79979e81148dc
|
||||
React-CoreModules: cd6e7efb38162884f08c7afa16fffaf15ff28ae4
|
||||
React-cxxreact: 51157cc600c9f436a7e623913a03b775305ef86c
|
||||
React-jsi: 3eeb345c4828d7b132fd38064a305f31b46d4ec3
|
||||
React-jsiexecutor: 5813455a4a908fb7284aa13307a9e0386e93b0bb
|
||||
React-jsinspector: 9ca5bf73ed0a195397e45fdbcd507cf7d503c428
|
||||
React-logger: 700340e325f21ba2a2d6413a61ef14268c7360aa
|
||||
react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe
|
||||
react-native-get-random-values: 30b3f74ca34e30e2e480de48e4add2706a40ac8f
|
||||
react-native-keep-awake: afad8a51dfef9fe9655a6344771be32c8596d774
|
||||
react-native-netinfo: 27f287f2d191693f3b9d01a4273137fcf91c3b5d
|
||||
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
|
||||
react-native-pager-view: 3ee7d4c7697fb3ef788346e834a60cca97ed8540
|
||||
react-native-performance: f4b6604a9d5a8a7407e34a82fab6c641d9a3ec12
|
||||
react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
|
||||
react-native-slider: 6e9b86e76cce4b9e35b3403193a6432ed07e0c81
|
||||
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
|
||||
react-native-video: bb6f12a7198db53b261fefb5d609dc77417acc8b
|
||||
react-native-webrtc: a9d4d8ef61adb634e006ffd956c494ad8318d95c
|
||||
react-native-webrtc: 2702afae1e59882b423e6077768ca0d1e6fc42ed
|
||||
react-native-webview: ea4899a1056c782afa96dd082179a66cbebf5504
|
||||
React-perflogger: 46620fc6d1c3157b60ed28434e08f7fd7f3f3353
|
||||
React-RCTActionSheet: b1f7e72a0ba760ec684df335c61f730b5179f5ff
|
||||
React-RCTAnimation: d73b62d42867ab608dfb10e100d8b91106275b18
|
||||
React-RCTBlob: b5f59693721d50967c35598158e6ca01b474c7de
|
||||
React-RCTImage: 37cf34d0c2fbef2e0278d42a7c5e8ea06a9fed6b
|
||||
React-RCTLinking: a11dced20019cf1c2ec7fd120f18b08f2851f79e
|
||||
React-RCTNetwork: ba097188e5eac42e070029e7cedd9b978940833a
|
||||
React-RCTSettings: 147073708a1c1bde521cf3af045a675682772726
|
||||
React-RCTText: 23f76ebfb2717d181476432e5ecf1c6c4a104c5e
|
||||
React-RCTVibration: be5f18ffc644f96f904e0e673ab639ca5d673ee8
|
||||
React-runtimeexecutor: d5498cfb7059bf8397b6416db4777843f3f4c1e7
|
||||
ReactCommon: 1974dab5108c79b40199f12a4833d2499b9f6303
|
||||
React-perflogger: fdee2a0c512167ae4c19c4e230ccf6aa66a6aff0
|
||||
React-RCTActionSheet: 1cf5fef4e372f1c877969710a51bea4bb25e78fe
|
||||
React-RCTAnimation: 73816e3acd1f5e3f00166fc7eedb34f6b112f734
|
||||
React-RCTBlob: 6976c838fb14a1daf75d7c8bb23bae9cbbf726bb
|
||||
React-RCTImage: ab8a7498f215117f32271698591e4bd932dcf812
|
||||
React-RCTLinking: e8e78aed2744ab9946cc8ba5716b4938c2efb1e0
|
||||
React-RCTNetwork: 796f5aed4d932655d292bdc6b40f9502dcdb9542
|
||||
React-RCTSettings: 7e1cd2a384b45c90caf67464572abe3833b9da3b
|
||||
React-RCTText: fd6162890828f0761e03c59058fa23c3a21b2e10
|
||||
React-RCTVibration: 302cfd5cc33669d7abdb7ec6790123baba66e62e
|
||||
React-runtimeexecutor: 59407514818b2afbb1d7507e4e1ac834d24b0fbd
|
||||
ReactCommon: b8487da74723562d7368dab27135fd182f00a91c
|
||||
RNCalendarEvents: 7e65eb4a94f53c1744d1e275f7fafcfaa619f7a3
|
||||
RNCAsyncStorage: 005c0e2f09575360f142d0d1f1f15e4ec575b1af
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
@@ -780,8 +780,8 @@ SPEC CHECKSUMS:
|
||||
RNSound: 27e8268bdb0a1f191f219a33267f7e0445e8d62f
|
||||
RNSVG: f3b60aeeaa81960e2e0536c3a9eef50b667ef3a9
|
||||
RNWatch: dae6c858a2051dbdcfb00b9a86cf4d90400263b4
|
||||
Yoga: 7929b92b1828675c1bebeb114dae8cb8fa7ef6a3
|
||||
Yoga: 7f5ad94937ba3fc58c151ad1b7bbada2c275b28e
|
||||
|
||||
PODFILE CHECKSUM: d9116cb59cd7e921956e45de7cbbd75bef3862c1
|
||||
PODFILE CHECKSUM: e3579df5272b8b697c9fdc0e55aa0845b189c4dd
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
COCOAPODS: 1.12.1
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>23.2.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>23.2.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>23.2.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>23.2.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CLKComplicationPrincipalClass</key>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>8.2.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>8.2.2</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -39,6 +39,18 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "Geringe Bandbreite"
|
||||
},
|
||||
"bandwidthSettings": {
|
||||
"assumedBandwidthBps": "z.B. 10000000 für 10 Mbps",
|
||||
"assumedBandwidthBpsWarning": "Höhere Werte können zu Netzwerk-Problemen führen.",
|
||||
"customValue": "spezifischer Wert",
|
||||
"customValueEffect": "setzt den Wert in bps",
|
||||
"leaveEmpty": "leer lassen",
|
||||
"leaveEmptyEffect": "aktiviert die automatische Abschätzung",
|
||||
"possibleValues": "Mögliche Werte",
|
||||
"setAssumedBandwidthBps": "Angenommene Bandbreite (bps)",
|
||||
"title": "Einstellungen Bandbreite",
|
||||
"zeroEffect": "schaltet Video aus"
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "Breakout-Raum hinzufügen",
|
||||
@@ -156,6 +168,7 @@
|
||||
"localport_plural": "Lokale Ports:",
|
||||
"maxEnabledResolution": "max. senden",
|
||||
"more": "Mehr anzeigen",
|
||||
"no": "Nein",
|
||||
"packetloss": "Paketverlust:",
|
||||
"participant_id": "Personen-ID:",
|
||||
"quality": {
|
||||
@@ -174,7 +187,8 @@
|
||||
"status": "Verbindung:",
|
||||
"transport": "Protokoll:",
|
||||
"transport_plural": "Protokolle:",
|
||||
"video_ssrc": "Video-SSRC:"
|
||||
"video_ssrc": "Video-SSRC:",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "Früher",
|
||||
@@ -673,6 +687,7 @@
|
||||
"connectedTwoMembers": "{{first}} und {{second}} nehmen am Meeting teil",
|
||||
"dataChannelClosed": "Schlechte Videoqualität",
|
||||
"dataChannelClosedDescription": "Die Steuerungsverbindung (Bridge Channel) wurde unterbrochen, daher ist die Videoqulität auf die schlechteste Stufe limitiert.",
|
||||
"disabledIframe": "Die Einbettung ist nur für Demo-Zwecke vorgesehen. Diese Konferenz wird in {{timeout}} Minuten beendet.",
|
||||
"disconnected": "getrennt",
|
||||
"displayNotifications": "Benachrichtigungen anzeigen für",
|
||||
"dontRemindMe": "Nicht erinnern",
|
||||
@@ -867,9 +882,11 @@
|
||||
"lookGood": "Ihr Mikrofon scheint zu funktionieren.",
|
||||
"or": "oder",
|
||||
"premeeting": "Vorschau",
|
||||
"proceedAnyway": "Trotzdem fortsetzen",
|
||||
"screenSharingError": "Fehler bei Bildschirmfreigabe:",
|
||||
"showScreen": "Konferenzvorschau aktivieren",
|
||||
"startWithPhone": "Mit Telefonaudio starten",
|
||||
"unsafeRoomConsent": "Ich verstehe das Risiko und möchte der Konferenz beitreten",
|
||||
"videoOnlyError": "Videofehler:",
|
||||
"videoTrackError": "Videotrack konnte nicht erstellt werden.",
|
||||
"viewAllNumbers": "alle Nummern anzeigen"
|
||||
@@ -971,8 +988,14 @@
|
||||
"security": {
|
||||
"about": "Sie können Ihre Konferenz mit einem Passwort sichern. Teilnehmer müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
|
||||
"aboutReadOnly": "Mit Moderationsrechten kann die Konferenz mit einem Passwort gesichert werden. Personen müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
|
||||
"insecureRoomNameWarning": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten",
|
||||
"title": "Sicherheitsoptionen"
|
||||
"insecureRoomNameWarningNative": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten. {{recommendAction}} Lernen Sie mehr über die Absicherung Ihrer Konferenz ",
|
||||
"insecureRoomNameWarningWeb": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten {{recommendAction}} Lernen Sie <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">hier</a> mehr über die Absicherung Ihrer Konferenz.",
|
||||
"title": "Sicherheitsoptionen",
|
||||
"unsafeRoomActions": {
|
||||
"meeting": "Erwägen Sie die Absicherung Ihrer Konferenz über den Sicherheits-Button.",
|
||||
"prejoin": "Erwägen Sie einen einzigartigeren Raumnamen zu wählen.",
|
||||
"welcome": "Erwägen Sie einen einzigartigeren Raumnamen zu wählen oder wählen Sie einen der Vorschläge."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"audio": "Audio",
|
||||
@@ -1140,6 +1163,7 @@
|
||||
"muteEveryoneElse": "Alle anderen stummschalten",
|
||||
"muteEveryoneElsesVideoStream": "Alle anderen Kameras ausschalten",
|
||||
"muteEveryonesVideoStream": "Alle Kameras ausschalten",
|
||||
"muteGUMPending": "Verbinde Ihr Mikrofon",
|
||||
"noiseSuppression": "Rauschunterdrückung",
|
||||
"openChat": "Chat öffnen",
|
||||
"participants": "Anwesende",
|
||||
@@ -1147,6 +1171,7 @@
|
||||
"privateMessage": "Private Nachricht senden",
|
||||
"profile": "Profil bearbeiten",
|
||||
"raiseHand": "Hand heben",
|
||||
"reactions": "Interaktionen",
|
||||
"reactionsMenu": "Interaktionsmenü öffnen / schließen",
|
||||
"recording": "Aufzeichnung ein-/ausschalten",
|
||||
"remoteMute": "Personen stummschalten",
|
||||
@@ -1172,6 +1197,7 @@
|
||||
"unmute": "Stummschaltung aufheben",
|
||||
"videoblur": "Unscharfer Hintergrund ein-/ausschalten",
|
||||
"videomute": "„Video stummschalten“ ein-/ausschalten",
|
||||
"videomuteGUMPending": "Verbinde Ihre Kamera",
|
||||
"videounmute": "Kamera einschalten"
|
||||
},
|
||||
"addPeople": "Personen zur Konferenz hinzufügen",
|
||||
@@ -1222,6 +1248,7 @@
|
||||
"mute": "Stummschalten",
|
||||
"muteEveryone": "Alle stummschalten",
|
||||
"muteEveryonesVideo": "Alle Kameras ausschalten",
|
||||
"muteGUMPending": "Verbinde Ihre Kamera",
|
||||
"noAudioSignalDesc": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stumm geschaltet haben, sollten Sie einen Wechsel des Geräts in Erwägung ziehen.",
|
||||
"noAudioSignalDescSuggestion": "Wenn Sie das Gerät nicht absichtlich über die Systemeinstellungen oder die Hardware stummgeschaltet haben, sollten Sie einen Wechsel auf das vorgeschlagene Gerät in Erwägung ziehen.",
|
||||
"noAudioSignalDialInDesc": "Sie können sich auch über die Einwahlnummer einwählen:",
|
||||
@@ -1244,6 +1271,7 @@
|
||||
"reactionLike": "Daumen hoch senden",
|
||||
"reactionSilence": "Stille senden",
|
||||
"reactionSurprised": "Überrascht senden",
|
||||
"reactions": "Interaktionen",
|
||||
"security": "Sicherheitsoptionen",
|
||||
"selectBackground": "Hintergrund auswählen",
|
||||
"shareRoom": "Person einladen",
|
||||
@@ -1266,6 +1294,7 @@
|
||||
"unmute": "Stummschaltung aufheben",
|
||||
"videoSettings": "Kameraeinstellungen",
|
||||
"videomute": "Kamera stoppen",
|
||||
"videomuteGUMPending": "Verbinde Ihre Kamera",
|
||||
"videounmute": "Kamera einschalten"
|
||||
},
|
||||
"transcribing": {
|
||||
@@ -1377,7 +1406,14 @@
|
||||
"webAssemblyWarning": "WebAssembly wird nicht unterstützt",
|
||||
"webAssemblyWarningDescription": "WebAssembly ist deaktiviert oder wird in diesem Browser nicht unterstützt"
|
||||
},
|
||||
"visitorsLabel": "Anzahl Gäste: {{count}}",
|
||||
"visitors": {
|
||||
"chatIndicator": "(Gast)",
|
||||
"labelTooltip": "Anzahl Gäste: {{count}}",
|
||||
"notification": {
|
||||
"description": "Bitte melden Sie sich um teilzunehmen",
|
||||
"title": "Sie sind Gast in der Konferenz"
|
||||
}
|
||||
},
|
||||
"volumeSlider": "Lautstärkeregler",
|
||||
"welcomepage": {
|
||||
"accessibilityLabel": {
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
"defaultEmail": "Dirección de correo por defecto",
|
||||
"disabled": "No puede invitar a otras personas.",
|
||||
"failedToAdd": "Error al agregar participantes",
|
||||
"footerText": "La marcación está desactivada.",
|
||||
"googleEmail": "Correo electrónico de Google",
|
||||
"inviteMoreHeader": "Usted se encuentra solo en la reunión",
|
||||
"inviteMoreMailSubject": "Unirse a la reunión {{appName}}",
|
||||
@@ -31,6 +30,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
"car": "Audio de automóvil",
|
||||
"headphones": "Auriculares",
|
||||
"none": "No hay dispositivos de audio disponibles",
|
||||
"phone": "Teléfono",
|
||||
@@ -39,6 +39,37 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "Solo sonido y pantalla compartida"
|
||||
},
|
||||
"bandwidthSettings": {
|
||||
"assumedBandwidthBps": "por ejemplo 10000000 para 10 Mbps",
|
||||
"assumedBandwidthBpsWarning": "Valores más altos podrían causar problemas de red.",
|
||||
"customValue": "valor personalizado",
|
||||
"customValueEffect": "para establecer el valor real de bps",
|
||||
"leaveEmpty": "dejar vacío",
|
||||
"leaveEmptyEffect": "para permitir que se realicen estimaciones",
|
||||
"possibleValues": "Valores posibles",
|
||||
"setAssumedBandwidthBps": "Ancho de banda asumido (bps)",
|
||||
"title": "Ajustes de ancho de banda",
|
||||
"zeroEffect": "para deshabilitar el video"
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "Agregar sala para grupos pequeños",
|
||||
"autoAssign": "Autoasignar a sala para grupos pequeños",
|
||||
"close": "Cerrar",
|
||||
"join": "Unirse",
|
||||
"leaveBreakoutRoom": "Abandonar sala para grupos pequeños",
|
||||
"more": "Más",
|
||||
"remove": "Quitar",
|
||||
"sendToBreakoutRoom": "Enviar participante a:"
|
||||
},
|
||||
"defaultName": "Sala para grupos pequeños #{{index}}",
|
||||
"mainRoom": "Sala principal",
|
||||
"notifications": {
|
||||
"joined": "Uniéndose a la sala para grupos pequeños \"{{name}}\"",
|
||||
"joinedMainRoom": "Uniéndose a la sala principal",
|
||||
"joinedTitle": "Salas para grupos pequeños"
|
||||
}
|
||||
},
|
||||
"calendarSync": {
|
||||
"addMeetingURL": "Agregar un vínculo a la reunión",
|
||||
"confirmAddLink": "¿Quiere añadir un enlace de Jitsi a este evento?",
|
||||
@@ -57,15 +88,27 @@
|
||||
"refresh": "Actualizar calendario",
|
||||
"today": "Hoy"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"selectSoundDevice": "Elija un dispositivo de sonido"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "Modo automóvil",
|
||||
"title": "Modo automóvil",
|
||||
"videoStopped": "Su video se ha detenido"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "Entrar en la sala",
|
||||
"error": "Error: su mensaje no se envío. Motivo: {{error}}",
|
||||
"fieldPlaceHolder": "Escriba su mensaje aquí",
|
||||
"lobbyChatMessageTo": "Mensaje de chat de lobby a {{recipient}}",
|
||||
"message": "Mensaje",
|
||||
"messageAccessibleTitle": "{{user}} dice:",
|
||||
"messageAccessibleTitleMe": "yo digo:",
|
||||
"messageTo": "Mensaje privado para {{recipient}}",
|
||||
"messagebox": "Escriba un mensaje",
|
||||
"newMessages": "Mensajes nuevos",
|
||||
"nickname": {
|
||||
"popover": "Selecciona un apodo",
|
||||
"title": "Introduce un apodo para usar el chat",
|
||||
@@ -85,6 +128,7 @@
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "Instalar extensión de Chrome",
|
||||
"buttonTextEdge": "Instalar extensión de Edge",
|
||||
"close": "Cerrar",
|
||||
"dontShowAgain": "No mostrar nuevamente",
|
||||
"installExtensionText": "Instalar la extensión para Google Calendar y la integración con Office 365"
|
||||
@@ -115,6 +159,7 @@
|
||||
"bridgeCount": "Contador del servidor: ",
|
||||
"codecs": "Codecs (A/V):",
|
||||
"connectedTo": "Conectado a:",
|
||||
"e2eeVerified": "",
|
||||
"framerate": "Fotogramas por segundo:",
|
||||
"less": "Mostrar menos",
|
||||
"localaddress": "Dirección local:",
|
||||
@@ -123,6 +168,7 @@
|
||||
"localport_plural": "Puertos locales:",
|
||||
"maxEnabledResolution": "enviar max",
|
||||
"more": "Mostrar más",
|
||||
"no": "no",
|
||||
"packetloss": "Pérdida de paquetes:",
|
||||
"participant_id": "ID participante:",
|
||||
"quality": {
|
||||
@@ -141,7 +187,8 @@
|
||||
"status": "Calidad:",
|
||||
"transport": "Transporte:",
|
||||
"transport_plural": "Transportes:",
|
||||
"video_ssrc": "Video SSRC:"
|
||||
"video_ssrc": "Video SSRC:",
|
||||
"yes": "sí"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "Anterior",
|
||||
@@ -150,15 +197,24 @@
|
||||
},
|
||||
"deepLinking": {
|
||||
"appNotInstalled": "Necesitas la aplicación {{app}} para unirte a esta reunión en el teléfono.",
|
||||
"description": "¿No pasó nada? Hemos intentado iniciar la reunión en la aplicación de escritorio {{app}}. Intenta de nuevo o inicia en la aplicación web {{app}}.",
|
||||
"description": "¿No pasó nada? Intentamos iniciar la reunión en la aplicación de escritorio {{app}}. Intenta de nuevo o inicia en la aplicación web {{app}}.",
|
||||
"descriptionNew": "¿No pasó nada? Intentamos iniciar la reunión en la aplicación de escritorio {{app}}. <br /><br /> Puedes volver a intentarlo o iniciar en la aplicación web.",
|
||||
"descriptionWithoutWeb": "¿No pasó nada? Intentamos iniciar su reunión en la aplicación de escritorio {{app}}.",
|
||||
"downloadApp": "Descargar la app",
|
||||
"downloadMobileApp": "",
|
||||
"ifDoNotHaveApp": "Si aún no tienes la app:",
|
||||
"ifHaveApp": "Si ya tienes la app:",
|
||||
"joinInApp": "Unirse a la reunion usando la app",
|
||||
"joinInAppNew": "Unirse en la app",
|
||||
"joinInBrowser": "Unirse en el navegador",
|
||||
"launchMeetingLabel": "¿Cómo quieres unirte a la reunión?",
|
||||
"launchWebButton": "Iniciar en el navegador",
|
||||
"noMobileApp": "¿No tienes la aplicación?",
|
||||
"termsAndConditions": "Al continuar aceptas nuestros <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>términos y condiciones.</a>",
|
||||
"title": "Iniciando la reunión en {{app}}…",
|
||||
"tryAgainButton": "Intentar de nuevo en el escritorio"
|
||||
"titleNew": "Iniciando la reunión.",
|
||||
"tryAgainButton": "Intentar de nuevo en el escritorio",
|
||||
"unsupportedBrowser": "Parece que estás usando un navegador para el que no tenemos soporte."
|
||||
},
|
||||
"defaultLink": "ej. {{url}}",
|
||||
"defaultNickname": "ej. Juan Pérez",
|
||||
@@ -169,11 +225,20 @@
|
||||
"microphonePermission": "Error al obtener permiso del micrófono"
|
||||
},
|
||||
"deviceSelection": {
|
||||
"hid": {
|
||||
"callControl": "Control de llamadas",
|
||||
"connectedDevices": "Dispositivos conectados:",
|
||||
"deleteDevice": "Eliminar dispositivo",
|
||||
"pairDevice": "Emparejar dispositivo"
|
||||
},
|
||||
"noPermission": "Permiso no concedido",
|
||||
"previewUnavailable": "Vista previa no disponible",
|
||||
"selectADevice": "Seleccionar un dispositivo",
|
||||
"testAudio": "Reproducir un sonido de prueba"
|
||||
},
|
||||
"dialIn": {
|
||||
"screenTitle": ""
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "está {{status}}"
|
||||
},
|
||||
@@ -189,9 +254,13 @@
|
||||
"WaitingForHostTitle": "Esperando al anfitrión...",
|
||||
"Yes": "Sí",
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Transmisión en vivo"
|
||||
"close": "Cerrar diálogo",
|
||||
"liveStreaming": "Transmisión en vivo",
|
||||
"sharingTabs": "Opciones para compartir"
|
||||
},
|
||||
"add": "Agregar",
|
||||
"addMeetingNote": "Agrega una nota acerca de esta reunión",
|
||||
"addOptionalNote": "Agrega una nota (opcional):",
|
||||
"allow": "Permitir",
|
||||
"alreadySharedVideoMsg": "Otro participante ya está compartiendo un vídeo. Esta conferencia sólo permite compartir un vídeo a la vez.",
|
||||
"alreadySharedVideoTitle": "Solo se permite un vídeo compartido a la vez",
|
||||
@@ -233,6 +302,7 @@
|
||||
"gracefulShutdown": "Nuestro servicio se encuentra en mantenimiento. Por favor, intente más tarde.",
|
||||
"grantModeratorDialog": "¿Estás seguro de que quieres convertir a este participante en moderador?",
|
||||
"grantModeratorTitle": "Convertir en moderador",
|
||||
"hide": "Esconder",
|
||||
"hideShareAudioHelper": "No volver a mostrar este diálogo",
|
||||
"incorrectPassword": "Nombre de usuario o contraseña incorrecta",
|
||||
"incorrectRoomLockPassword": "Contraseña incorrecta",
|
||||
@@ -243,9 +313,10 @@
|
||||
"kickParticipantDialog": "¿Seguro que quiere expulsar a este participante?",
|
||||
"kickParticipantTitle": "¿Expulsar a este participante?",
|
||||
"kickTitle": "¡Ay! {{participantDisplayName}} te expulsó de la reunión",
|
||||
"linkMeeting": "",
|
||||
"linkMeetingTitle": "",
|
||||
"liveStreaming": "Transmisión en vivo",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "No es posible mientras la grabación este activa",
|
||||
"liveStreamingDisabledTooltip": "Las trasmisiones están deshabilitadas.",
|
||||
"localUserControls": "Controles de usuario locales",
|
||||
"lockMessage": "No se pudo bloquear la conferencia.",
|
||||
"lockRoom": "Agregar $t(lockRoomPasswordUppercase) a la reunión",
|
||||
@@ -279,11 +350,11 @@
|
||||
"muteEveryonesVideoTitle": "¿Detener el vídeo de todos?",
|
||||
"muteParticipantBody": "No podrás quitarles el modo en silencio, pero ellos pueden quitárselo en cualquier momento.",
|
||||
"muteParticipantButton": "Silenciar",
|
||||
"muteParticipantDialog": "¿Seguro que quieres silenciar a este participante? No podrás revertir esta acción, pero el participante podrá hacerlo en cualquier momento",
|
||||
"muteParticipantTitle": "¿Silenciar a este participante?",
|
||||
"muteParticipantsVideoBody": "No podrás volver a encender la cámara, pero ellos pueden volver a encenderla en cualquier momento.",
|
||||
"muteParticipantsVideoBodyModerationOn": "",
|
||||
"muteParticipantsVideoButton": "Detener video",
|
||||
"muteParticipantsVideoDialog": "¿Estás seguro de que quieres apagar la cámara de este participante? No podrás volver a encender la cámara, pero ellos pueden volver a encenderla en cualquier momento.",
|
||||
"muteParticipantsVideoDialogModerationOn": "",
|
||||
"muteParticipantsVideoTitle": "¿Desactivar la cámara de este participante?",
|
||||
"noDropboxToken": "No hay un token válido de Dropbox",
|
||||
"password": "Contraseña",
|
||||
@@ -297,9 +368,9 @@
|
||||
"popupError": "Su navegador está bloqueando las ventanas emergentes de este sitio. Habilite las ventanas emergentes en la configuración de seguridad de su navegador y vuelva a intentarlo.",
|
||||
"popupErrorTitle": "Ventana emergente bloqueada",
|
||||
"readMore": "más",
|
||||
"recentlyUsedObjects": "Tus objetos usados recientemente",
|
||||
"recording": "Grabando",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "No es posible mientras la transmisión en vivo este activa",
|
||||
"recordingDisabledTooltip": "Inicio de grabación desactivado.",
|
||||
"rejoinNow": "Reunirse ahora",
|
||||
"remoteControlAllowedMessage": "¡{{user}} ha aceptado tu solicitud de control remoto!",
|
||||
"remoteControlDeniedMessage": "¡{{user}} ha rechazado tu solicitud de control remoto!",
|
||||
@@ -319,6 +390,12 @@
|
||||
"screenSharingFailed": "¡Ups! ¡Algo salió mal, no se pudo iniciar la compartición de su pantalla!",
|
||||
"screenSharingFailedTitle": "¡Fallo al compartir su pantalla!",
|
||||
"screenSharingPermissionDeniedError": "¡Uy! Algo salió mal con tus permisos de extensión para compartir pantalla. Vuelve a cargar la página e intenta de nuevo.",
|
||||
"searchInSalesforce": "Buscar en Salesforce",
|
||||
"searchResults": "Resultados de búsqueda({{count}}",
|
||||
"searchResultsDetailsError": "",
|
||||
"searchResultsError": "Hubo un error recuperando los datos.",
|
||||
"searchResultsNotFound": "No se encontraron resultados.",
|
||||
"searchResultsTryAgain": "Vuelve a intentar usando palabras clave alternativas",
|
||||
"sendPrivateMessage": "Acabas de recibir un mensaje privado. ¿Deseas responder en privado o a todos?",
|
||||
"sendPrivateMessageCancel": "Enviar al grupo",
|
||||
"sendPrivateMessageOk": "Enviar en privado",
|
||||
@@ -341,7 +418,10 @@
|
||||
"shareVideoTitle": "Compartir un vídeo",
|
||||
"shareYourScreen": "Compartir pantalla",
|
||||
"shareYourScreenDisabled": "Se desactivó la opción para compartir pantalla.",
|
||||
"sharedVideoDialogError": "Error: URL inválido",
|
||||
"sharedVideoLinkPlaceholder": "Enlace de YouTube o enlace de vídeo directo",
|
||||
"show": "Mostrar",
|
||||
"start": "Iniciar",
|
||||
"startLiveStreaming": "Iniciar transmisión en vivo",
|
||||
"startRecording": "Iniciar grabación",
|
||||
"startRemoteControlErrorMessage": "Se produjo un error al intentar iniciar la sesión de control remoto.",
|
||||
@@ -359,6 +439,10 @@
|
||||
"user": "Usuario",
|
||||
"userIdentifier": "Identificador de usuario",
|
||||
"userPassword": "contraseña del usuario",
|
||||
"verifyParticipantConfirm": "",
|
||||
"verifyParticipantDismiss": "",
|
||||
"verifyParticipantQuestion": "",
|
||||
"verifyParticipantTitle": "Verificación de usuario",
|
||||
"videoLink": "Enlace de vídeo",
|
||||
"viewUpgradeOptions": "Ver opciones de mejora",
|
||||
"viewUpgradeOptionsContent": "Para obtener acceso ilimitado a las funciones premium, como la grabación, las transcripciones, el streaming RTMP y otras, tendrás que actualizar tu plan.",
|
||||
@@ -384,8 +468,14 @@
|
||||
"veryBad": "Muy mala",
|
||||
"veryGood": "Muy buena"
|
||||
},
|
||||
"helpView": {
|
||||
"title": "Centro de ayuda"
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Miniaturas de video"
|
||||
}
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "No se encontraron resultados :(",
|
||||
"search": "Busca en GIPHY"
|
||||
},
|
||||
"incomingCall": {
|
||||
"answer": "Contestar",
|
||||
@@ -427,9 +517,11 @@
|
||||
"noRoom": "No se especificó la sala a marcar.",
|
||||
"numbers": "Números para entrar por llamada telefónica:",
|
||||
"password": "$t(lockRoomPasswordUppercase):",
|
||||
"reachedLimit": "Alcanzaste el límite de tu plan.",
|
||||
"sip": "Dirección SIP",
|
||||
"title": "Compartir",
|
||||
"tooltip": "Compartir el enlace y acceso telefónico para esta reunión"
|
||||
"tooltip": "Compartir el enlace y acceso telefónico para esta reunión",
|
||||
"upgradeOptions": "Por favor revisa las opciones de mejora en"
|
||||
},
|
||||
"inlineDialogFailure": {
|
||||
"msg": "Tuvimos un pequeño tropiezo.",
|
||||
@@ -450,6 +542,7 @@
|
||||
"focusLocal": "Ver tu cámara",
|
||||
"focusRemote": "Ver la cámara de otras personas",
|
||||
"fullScreen": "Entrar o salir de pantalla completa",
|
||||
"giphyMenu": "Alternar menú GIPHY",
|
||||
"keyboardShortcuts": "Atajos de teclado",
|
||||
"localRecording": "Mostrar u ocultar controles de grabación local",
|
||||
"mute": "Activar o silenciar el micrófono",
|
||||
@@ -463,6 +556,10 @@
|
||||
"toggleShortcuts": "Mostrar u ocultar atajos del teclado",
|
||||
"videoMute": "Encender o apagar la cámara"
|
||||
},
|
||||
"largeVideo": {
|
||||
"screenIsShared": "Estás compartiendo tu pantalla",
|
||||
"showMeWhatImSharing": "Muéstrame qué estoy compartiendo"
|
||||
},
|
||||
"liveStreaming": {
|
||||
"busy": "Nuestros servidores andan un poco ocupados. Vuelve a intentarlo en unos minutos.",
|
||||
"busyTitle": "Todos los transmisores están ocupados",
|
||||
@@ -479,6 +576,7 @@
|
||||
"failedToStart": "La transmisión en vivo no se pudo iniciar",
|
||||
"getStreamKeyManually": "No pudimos encontrar tu clave de transmisión. Por favor, obtenla de la página de YouTube y pégala.",
|
||||
"googlePrivacyPolicy": "Política de Privacidad de Google",
|
||||
"inProgress": "Grabación o transmisión en vivo en curso",
|
||||
"invalidStreamKey": "Es posible que la clave de transmisión sea incorrecta, o no es de YouTube.",
|
||||
"limitNotificationDescriptionNative": "Su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en {{app}}.",
|
||||
"limitNotificationDescriptionWeb": "Debido a la alta demanda su transmisión estará limitada a {{limit}} minutos. Puede obtener transmisiones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
@@ -488,6 +586,7 @@
|
||||
"onBy": "{{name}} inició la transmisión en vivo",
|
||||
"pending": "Iniciando transmisión en vivo…",
|
||||
"serviceName": "Servicio de transmisión en vivo",
|
||||
"sessionAlreadyActive": "Esta sesión ya está siendo grabada o transmitida en vivo.",
|
||||
"signIn": "Iniciar sesión con Google",
|
||||
"signInCTA": "Para transmitir a YouTube, inicia sesión o introduce la clave de transmisión. Para transmitir a otro lugar, introduce el URL (que empieza en rtmp), seguido de la clave de transmisión. Debe haber una diagonal (/) entre ambos.",
|
||||
"signOut": "Cerrar sesión",
|
||||
@@ -501,8 +600,8 @@
|
||||
"lobby": {
|
||||
"admit": "Admitir",
|
||||
"admitAll": "Admitir todo",
|
||||
"allow": "permitir",
|
||||
"backToKnockModeButton": "No hay contraseña, pide permiso para entrar.",
|
||||
"chat": "Chat",
|
||||
"dialogTitle": "Sala de espera",
|
||||
"disableDialogContent": "Sala de espera activada. Así no entrarán intrusos. ¿Quieres desactivarla?",
|
||||
"disableDialogSubmit": "Desactivar",
|
||||
@@ -515,6 +614,7 @@
|
||||
"errorMissingPassword": "Por favor, introduzca la contraseña de la reunión",
|
||||
"invalidPassword": "Contraseña inválida",
|
||||
"joinRejectedMessage": "Tu solicitud para entrar ha sido rechazada por un moderador.",
|
||||
"joinRejectedTitle": "Solicitud para entrar rechazada.",
|
||||
"joinTitle": "Entrar a la reunión",
|
||||
"joinWithPasswordMessage": "Tratando de entrar con contraseña, por favor espera...",
|
||||
"joiningMessage": "Podrás entrar tan pronto te acepten tu solicitud.",
|
||||
@@ -523,6 +623,8 @@
|
||||
"knockButton": "Pedir entrar",
|
||||
"knockTitle": "Alguien quiere entrar a la reunión",
|
||||
"knockingParticipantList": "Participantes que quieren entrar",
|
||||
"lobbyChatStartedNotification": "{{moderator}} inició un chat de lobby con {{attendee}}",
|
||||
"lobbyChatStartedTitle": "{{moderator}} inició un chat de lobby contigo.",
|
||||
"nameField": "Introduce tu nombre",
|
||||
"notificationLobbyAccessDenied": "{{originParticipantName}} no dejó entrar a {{targetParticipantName}}",
|
||||
"notificationLobbyAccessGranted": "{{originParticipantName}} permitió entrar a {{targetParticipantName}}",
|
||||
@@ -560,6 +662,7 @@
|
||||
"no": "No",
|
||||
"participant": "Participante",
|
||||
"participantStats": "Estadística de participantes",
|
||||
"selectTabTitle": "🎥 Por favor seleccione esta pestaña para grabar",
|
||||
"sessionToken": "Token de sesión",
|
||||
"start": "Iniciar grabación",
|
||||
"stop": "Detener grabación",
|
||||
@@ -576,18 +679,39 @@
|
||||
"OldElectronAPPTitle": "¡Aplicación obsoleta e insegura!",
|
||||
"allowAction": "Permitir",
|
||||
"allowedUnmute": "Puedes anular el silencio del micrófono, iniciar la cámara o compartir la pantalla.",
|
||||
"audioUnmuteBlockedDescription": "La operación de activación del micrófono ha sido bloqueada temporalmente debido a límites del sistema.",
|
||||
"audioUnmuteBlockedTitle": "¡Activación del micrófono bloqueado!",
|
||||
"chatMessages": "Mensajes del chat",
|
||||
"connectedOneMember": "{{name}} se unió a la reunión",
|
||||
"connectedThreePlusMembers": "{{name}} y {{count}} más se unieron a la reunión",
|
||||
"connectedTwoMembers": "{{first}} y {{second}} se unieron a la reunión",
|
||||
"dataChannelClosed": "",
|
||||
"dataChannelClosedDescription": "",
|
||||
"disabledIframe": "",
|
||||
"disconnected": "desconectado",
|
||||
"displayNotifications": "Mostrar notificaciones para",
|
||||
"dontRemindMe": "No me lo recuerdes",
|
||||
"focus": "Enfocar conferencia",
|
||||
"focusFail": "{{component}} no disponible. Vuelve a intentar en {{ms}} segundos",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Notificaciones",
|
||||
"hostAskedUnmute": "El moderador quiere que hables",
|
||||
"invitedOneMember": "{{name}} ha sido invitado",
|
||||
"invitedThreePlusMembers": "{{name}} y {{count}} más han sido invitados",
|
||||
"invitedTwoMembers": "{{first}} y {{second}} han sido invitados",
|
||||
"joinMeeting": "Unirse",
|
||||
"kickParticipant": "{{kicker}} sacó a {{kicked}}",
|
||||
"leftOneMember": "{{name}} abandonó la reunión",
|
||||
"leftThreePlusMembers": "{{name}} y muchos otros abandonaron la reunión",
|
||||
"leftTwoMembers": "{{first}} y {{second}} abandonaron la reunión",
|
||||
"linkToSalesforce": "Enlace a Salesforce",
|
||||
"linkToSalesforceDescription": "Puedes vincular el resumen de la reunión a un objeto Salesforce",
|
||||
"linkToSalesforceError": "Error al vincular la reunión a Salesforce",
|
||||
"linkToSalesforceKey": "",
|
||||
"linkToSalesforceProgress": "Vinculando reunión a Salesorce...",
|
||||
"linkToSalesforceSuccess": "La reunión fue vinculada a Salesforce",
|
||||
"localRecordingStarted": "{{name}} ha iniciado una grabación local.",
|
||||
"localRecordingStopped": "{{name}} ha detenido una grabación local.",
|
||||
"me": "Yo",
|
||||
"moderationInEffectCSDescription": "Por favor, levante la mano si quiere compartir su pantalla.",
|
||||
"moderationInEffectCSTitle": "La pantalla compartida está bloqueada por el moderador",
|
||||
@@ -608,16 +732,27 @@
|
||||
"newDeviceAction": "Usar",
|
||||
"newDeviceAudioTitle": "Se detectó un dispositivo de audio nuevo",
|
||||
"newDeviceCameraTitle": "Se detectó una cámara nueva",
|
||||
"noiseSuppressionDesktopAudioDescription": "La supresión de ruido no puede ser habilitada mientras comparte audio del escritorio, por favor deshabilítelo y vuelva a intentar.",
|
||||
"noiseSuppressionFailedTitle": "Error al activar la supresión de ruido",
|
||||
"noiseSuppressionNoTrackDescription": "Por favor active su micrófono primero.",
|
||||
"noiseSuppressionStereoDescription": "La supresión de ruido en audio estéreo no tiene soporte actualmente",
|
||||
"oldElectronClientDescription1": "Estás usando una versión vieja de la aplicación de Jitsi Meet que tiene problemas de seguridad. ¡Por favor, actualiza a la ",
|
||||
"oldElectronClientDescription2": "versión más reciente",
|
||||
"oldElectronClientDescription3": " YA!",
|
||||
"participantWantsToJoin": "Quiere unirse a la reunión",
|
||||
"participantsWantToJoin": "Quieren unirse a la reunión",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) eliminada por otro participante",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) agregada por otro participante",
|
||||
"raiseHandAction": "Levantar la mano",
|
||||
"raisedHand": "{{name}} quisiera hablar.",
|
||||
"raisedHands": "",
|
||||
"reactionSounds": "Desactivar sonidos",
|
||||
"reactionSoundsForAll": "Desactivar sonidos para todos",
|
||||
"screenShareNoAudio": "La casilla Compartir audio no estaba marcada en la pantalla de selección de ventanas.",
|
||||
"screenShareNoAudioTitle": "No se pudo compartir el audio del sistema.",
|
||||
"screenSharingAudioOnlyDescription": "Por favor tenga en cuenta que al compartir si pantalla está afectando el modo \"Mejor rendimiento\" y usará más ancho de banda",
|
||||
"screenSharingAudioOnlyTitle": "Modo \"Mejor rendimiento\"",
|
||||
"selfViewTitle": "Siempre puedes reactivar la vista propia en los ajustes",
|
||||
"somebody": "Alguien",
|
||||
"startSilentDescription": "Vuelve a ingresar para activar el audio",
|
||||
"startSilentTitle": "¡Te uniste sin audio!",
|
||||
@@ -625,7 +760,11 @@
|
||||
"suboptimalExperienceTitle": "¡Tu navegador no es compatible!",
|
||||
"unmute": "Reactivar micrófono",
|
||||
"videoMutedRemotelyDescription": "Siempre puedes volver a encenderlo.",
|
||||
"videoMutedRemotelyTitle": "Su vídeo ha sido desactivado por {{moderator}}"
|
||||
"videoMutedRemotelyTitle": "Su vídeo ha sido desactivado por {{moderator}}",
|
||||
"videoUnmuteBlockedDescription": "Las operaciones de desactivar la cámara y compartir pantalla hansido bloqueadas temporalmente debido a límites del sistema.",
|
||||
"videoUnmuteBlockedTitle": "¡Desactivar cámara y compartir pantalla bloqueados!",
|
||||
"viewLobby": "Ver lobby",
|
||||
"waitingParticipants": "{{waitingParticipants}} personas"
|
||||
},
|
||||
"participantsPane": {
|
||||
"actions": {
|
||||
@@ -635,6 +774,9 @@
|
||||
"audioModeration": "Desmutearse a sí mismos",
|
||||
"blockEveryoneMicCamera": "Bloquear el micrófono y la cámara de todos.",
|
||||
"invite": "Invitar a alguien",
|
||||
"moreModerationActions": "Más opciones de moderación",
|
||||
"moreModerationControls": "Más controles de moderación",
|
||||
"moreParticipantOptions": "Más opciones de participantes",
|
||||
"mute": "Silenciar",
|
||||
"muteAll": "Silenciar a todos los demás",
|
||||
"muteEveryoneElse": "Silenciar al resto",
|
||||
@@ -647,17 +789,22 @@
|
||||
"headings": {
|
||||
"lobby": "Vestíbulo ({{count}})",
|
||||
"participantsList": "Participantes en la reunión ({{count}})",
|
||||
"visitors": "Visitantes ({{count}})",
|
||||
"waitingLobby": "Esperando en el vestíbulo ({{count}})"
|
||||
},
|
||||
"search": "Buscar participantes",
|
||||
"title": "Participantes"
|
||||
},
|
||||
"passwordDigitsOnly": "Hasta {{number}} cifras",
|
||||
"passwordSetRemotely": "Definida por otro participante",
|
||||
"pinParticipant": "",
|
||||
"pinnedParticipant": "",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"skip": "Saltar",
|
||||
"submit": "Enviar"
|
||||
},
|
||||
"by": "Por {{ name }}",
|
||||
"create": {
|
||||
"addOption": "Añadir opción",
|
||||
"answerPlaceholder": "Opción {{index}}",
|
||||
@@ -728,15 +875,18 @@
|
||||
"initiated": "Llamada iniciada",
|
||||
"joinAudioByPhone": "Entrar con audio de llamada telefónica",
|
||||
"joinMeeting": "Entrar a la reunión",
|
||||
"joinMeetingInLowBandwidthMode": "Entrar en modo de ancho de banda bajo",
|
||||
"joinWithoutAudio": "Entrar sin sonido",
|
||||
"keyboardShortcuts": "Activar los atajos de teclado",
|
||||
"linkCopied": "Se copió el link",
|
||||
"lookGood": "Tu micrófono funciona bien.",
|
||||
"or": "o",
|
||||
"premeeting": "Pre-reunión",
|
||||
"proceedAnyway": "Continuar de todos modos",
|
||||
"screenSharingError": "Error al compartir pantalla:",
|
||||
"showScreen": "Habilitar pantalla pre-reunión",
|
||||
"startWithPhone": "Iniciar con audio de llamada telefónica",
|
||||
"unsafeRoomConsent": "Comprendo los riesgos, quiero unirme a la reunión",
|
||||
"videoOnlyError": "Error con el vídeo:",
|
||||
"videoTrackError": "No se pudo crear la pista de vídeo.",
|
||||
"viewAllNumbers": "ver todos los números"
|
||||
@@ -763,6 +913,19 @@
|
||||
"title": "Perfil"
|
||||
},
|
||||
"raisedHand": "Desea hablar",
|
||||
"raisedHandsLabel": "Cantidad de manos levantadas",
|
||||
"record": {
|
||||
"already": {
|
||||
"linked": "La reunión ya está vinculada a este objeto Salesforce"
|
||||
},
|
||||
"type": {
|
||||
"account": "Cuenta",
|
||||
"contact": "Contacto",
|
||||
"lead": "",
|
||||
"opportunity": "Oportunidad",
|
||||
"owner": "Dueño"
|
||||
}
|
||||
},
|
||||
"recording": {
|
||||
"authDropboxText": "Subir a Dropbox",
|
||||
"availableSpace": "Espacio disponible: {{spaceLeft}} MB (aproximadamente {{duration}} minutos de grabación)",
|
||||
@@ -777,37 +940,66 @@
|
||||
"expandedPending": "La grabación se está iniciando…",
|
||||
"failedToStart": "No se pudo iniciar la grabación",
|
||||
"fileSharingdescription": "Compartir la grabación con los participantes de la reunión",
|
||||
"highlight": "Destacar",
|
||||
"highlightMoment": "Destacar momento",
|
||||
"highlightMomentDisabled": "Puede destacar momentos cuando inicie la grabación",
|
||||
"highlightMomentSuccess": "Momento destacado",
|
||||
"highlightMomentSucessDescription": "Su momento destacado será agregado al resumen de la reunión.",
|
||||
"inProgress": "Grabación o transmisión en vivo en curso",
|
||||
"limitNotificationDescriptionNative": "Su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <3>{{app}}</3>.",
|
||||
"limitNotificationDescriptionWeb": "Debido a la alta demanda su grabación estará limitada a {{limit}} minutos. Puede obtener grabaciones ilimitadas en <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "Hemos generado un enlace a su grabación.",
|
||||
"live": "EN VIVO",
|
||||
"localRecordingNoNotificationWarning": "La grabación no será anunciada al resto de participantes. Necesitarás hacerles saber que la reunión está siendo grabada.",
|
||||
"localRecordingNoVideo": "El video no está siendo grabado",
|
||||
"localRecordingStartWarning": "Por favor asegúrese de detener la grabación antes de abandonar la reunión para guardarla.",
|
||||
"localRecordingStartWarningTitle": "Detenga la grabación para guardarla",
|
||||
"localRecordingVideoStop": "Detener su video también detendrá la grabación local. ¿Está seguro de querer continuar?",
|
||||
"localRecordingVideoWarning": "Para grabar su video debe tenerlo encendido al iniciar la grabación",
|
||||
"localRecordingWarning": "Asegúrese de seleccionar la pestaña actual para usar el video y audio correctos. La grabación está actualmente limitada a 1GB, que son aproximadamente 100 minutos.",
|
||||
"loggedIn": "Sesión iniciada como {{userName}}",
|
||||
"noMicPermission": "No se pudo crear la pista de micrófono. Por favor otorgue permiso para usar el micrófono.",
|
||||
"noStreams": "",
|
||||
"off": "Grabación detenida",
|
||||
"offBy": "{{name}} detuvo la grabación",
|
||||
"on": "Grabando",
|
||||
"onBy": "{{name}} comenzó la grabación",
|
||||
"onlyRecordSelf": "",
|
||||
"pending": "Preparando para grabar la reunión…",
|
||||
"rec": "GRA",
|
||||
"saveLocalRecording": "Guardar archivo de grabación localmente (Beta)",
|
||||
"serviceDescription": "El servicio de grabación guardará la grabación",
|
||||
"serviceDescriptionCloud": "Grabación en la nube",
|
||||
"serviceDescriptionCloudInfo": "Las reuniones grabadas son limpiadas 24h luego de su horario de grabación.",
|
||||
"serviceName": "Servicio de grabación",
|
||||
"sessionAlreadyActive": "Esta sesión ya está siendo grabada o transmitida en vivo.",
|
||||
"signIn": "Iniciar sesión",
|
||||
"signOut": "Cerrar sesión",
|
||||
"surfaceError": "Por favor seleccione la pestaña actual.",
|
||||
"title": "Grabando",
|
||||
"unavailable": "¡Uy! {{serviceName}} actualmente no está disponible. Estamos trabajando para resolver el problema. Vuelve a intentarlo más tarde.",
|
||||
"unavailableTitle": "Grabación no disponible",
|
||||
"uploadToCloud": "Subir a la nube"
|
||||
},
|
||||
"screenshareDisplayName": "Pantalla de {{name}}",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Mueve el dedo para abajo para actualizar."
|
||||
},
|
||||
"security": {
|
||||
"about": "Puedes agregar una contraseña a la reunión. Los participantes necesitarán la contraseña para unirse a la reunión.",
|
||||
"aboutReadOnly": "Los participantes moderadores pueden agregar una $t(lockRoomPassword) a la reunión. Los participantes deberán proporcionar la $t(lockRoomPassword) antes de que se les permita unirse a la reunión.",
|
||||
"insecureRoomNameWarning": "El nombre de la sala es inseguro. Participantes no deseados pueden llegar a unirse a la reunión.",
|
||||
"securityOptions": "Opciones de seguridad"
|
||||
"insecureRoomNameWarningNative": "El nombre de esta sala es inseguro. Participantes indeseados podrían ingresar a su reunión. {{recommendAction}} Aprenda más sobre asegurar su reunión ",
|
||||
"insecureRoomNameWarningWeb": "El nombre de esta sala es inseguro. Participantes indeseados podrían ingresar a su reunión. {{recommendAction}} Aprenda más sobre asegurar su reunión <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">aquí</a>.",
|
||||
"title": "Opciones de seguridad",
|
||||
"unsafeRoomActions": {
|
||||
"meeting": "Considere hacer más segura su reunión utilizando el botón de seguridad.",
|
||||
"prejoin": "Considere utilizar un nombre de reunión más único.",
|
||||
"welcome": "Considere utilizar un nombre de reunión más único, o elija una de las sugerencias"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"audio": "Audio",
|
||||
"buttonLabel": "Ajustes",
|
||||
"calendar": {
|
||||
"about": "La integración del calendario de {{appName}} se usa para acceder al calendario de manera segura para que puedas estar al tanto de los próximos eventos.",
|
||||
"disconnect": "Desconectar",
|
||||
@@ -824,12 +1016,16 @@
|
||||
"incomingMessage": "Mensaje entrante",
|
||||
"language": "Idioma",
|
||||
"loggedIn": "Sesión iniciada como {{name}}",
|
||||
"maxStageParticipants": "",
|
||||
"microphones": "Micrófono",
|
||||
"moderator": "Moderador",
|
||||
"moderatorOptions": "Opciones de moderador",
|
||||
"more": "Más",
|
||||
"name": "Nombre",
|
||||
"noDevice": "Ninguno",
|
||||
"participantJoined": "Un articipante incorporado",
|
||||
"notifications": "Notificaciones",
|
||||
"participantJoined": "Un participante se ha unido",
|
||||
"participantKnocking": "Un participante ha ingresado al lobby",
|
||||
"participantLeft": "Un participante se ha ido",
|
||||
"playSounds": "Reproducir sonido",
|
||||
"reactions": "Reacciones de la reunión",
|
||||
@@ -837,12 +1033,15 @@
|
||||
"selectAudioOutput": "Salida de audio",
|
||||
"selectCamera": "Cámara",
|
||||
"selectMic": "Micrófono",
|
||||
"sounds": "Sonidos",
|
||||
"selfView": "Vista propia",
|
||||
"shortcuts": "Atajos",
|
||||
"speakers": "Altavoces",
|
||||
"startAudioMuted": "Todos inician silenciados",
|
||||
"startReactionsMuted": "Silenciar sonidos de reacción para todos",
|
||||
"startVideoMuted": "Todos inician con cámara desactivada",
|
||||
"talkWhileMuted": "Hablar en silencio",
|
||||
"title": "Ajustes"
|
||||
"title": "Ajustes",
|
||||
"video": "Video"
|
||||
},
|
||||
"settingsView": {
|
||||
"advanced": "Avanzado",
|
||||
@@ -857,13 +1056,21 @@
|
||||
"disableCrashReportingWarning": "¿Estás seguro que no deseas reportarnos los crasheos? La opción se activará al reiniciar la app.",
|
||||
"disableP2P": "Desactivar la comunicación directa (\"Peer-To-Peer\")",
|
||||
"displayName": "Nombre a mostrar",
|
||||
"displayNamePlaceholderText": "Por ejemplo: Juan Pérez",
|
||||
"email": "Correo electrónico",
|
||||
"emailPlaceholderText": "",
|
||||
"goTo": "Ir a",
|
||||
"header": "Configuración",
|
||||
"help": "Ayuda",
|
||||
"links": "Enlaces",
|
||||
"privacy": "Privacidad",
|
||||
"profileSection": "Perfil",
|
||||
"serverURL": "URL del servidor",
|
||||
"showAdvanced": "Mostrar configuración avanzada",
|
||||
"startCarModeInLowBandwidthMode": "Iniciar módo automóvil en modo ancho de banda bajo",
|
||||
"startWithAudioMuted": "Iniciar con el micrófono apagado",
|
||||
"startWithVideoMuted": "Iniciar con la cámara apagada",
|
||||
"terms": "Términos",
|
||||
"version": "Versión"
|
||||
},
|
||||
"share": {
|
||||
@@ -872,13 +1079,21 @@
|
||||
},
|
||||
"speaker": "Participante",
|
||||
"speakerStats": {
|
||||
"angry": "Enojado",
|
||||
"disgusted": "Disgustado",
|
||||
"displayEmotions": "Mostrar emociones",
|
||||
"fearful": "Temeroso",
|
||||
"happy": "Feliz",
|
||||
"hours": "{{count}} h",
|
||||
"minutes": "{{count}} min",
|
||||
"name": "Nombre",
|
||||
"neutral": "Neutral",
|
||||
"sad": "Triste",
|
||||
"search": "Buscar",
|
||||
"seconds": "{{count}} s",
|
||||
"speakerStats": "Estadísticas de participantes",
|
||||
"speakerTime": "Tiempo hablado"
|
||||
"speakerTime": "Tiempo hablado",
|
||||
"surprised": "Sorprendido"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"genericTitle": "La reunión debe utilizar su micrófono y su cámara.",
|
||||
@@ -890,6 +1105,10 @@
|
||||
"text": "Presiona el botón <i>Reconectar</i> para volver a conectarte.",
|
||||
"title": "La vídeollamada se interrumpió porque la computadora estaba suspendida."
|
||||
},
|
||||
"termsView": {
|
||||
"title": "Términos"
|
||||
},
|
||||
"toggleTopPanelLabel": "Alternar panel superior",
|
||||
"toolbar": {
|
||||
"Settings": "Configuración",
|
||||
"accessibilityLabel": {
|
||||
@@ -897,60 +1116,89 @@
|
||||
"audioOnly": "Alternar cámaras de los demás",
|
||||
"audioRoute": "Seleccionar el dispositivo de sonido",
|
||||
"boo": "Boo",
|
||||
"breakoutRoom": "Unirse/abandonar sala para grupos pequeños",
|
||||
"callQuality": "Administrar la calidad de vídeo",
|
||||
"carmode": "Modo automóvil",
|
||||
"cc": "Alternar subtítulos",
|
||||
"chat": "Alternar ventana de chat",
|
||||
"clap": "Aplauso",
|
||||
"closeChat": "Cerrar chat",
|
||||
"closeMoreActions": "Cerrar el menú de más acciones",
|
||||
"closeParticipantsPane": "Cerrar panel de participantes",
|
||||
"collapse": "Colapsar",
|
||||
"document": "Alternar documento compartido",
|
||||
"documentClose": "Cerrar documento compartido",
|
||||
"documentOpen": "Abrir documento compartido",
|
||||
"download": "Descargar nuestras aplicaciones",
|
||||
"embedMeeting": "Insertar reunión",
|
||||
"endConference": "Terminar reunión para todos",
|
||||
"enterFullScreen": "Ver en pantalla completa",
|
||||
"enterTileView": "Ingresar en vista de mosaico",
|
||||
"exitFullScreen": "Salir de pantalla completa",
|
||||
"exitTileView": "Salir de vista de mosaico",
|
||||
"expand": "Ampliar",
|
||||
"feedback": "Dejar comentarios",
|
||||
"fullScreen": "Alternar pantalla completa",
|
||||
"giphy": "Alternar menú GIPHY",
|
||||
"grantModerator": "Convertir en moderador",
|
||||
"hangup": "Colgar",
|
||||
"heading": "Barra de herramientas",
|
||||
"help": "Ayuda",
|
||||
"hideWhiteboard": "Esconder pizarra",
|
||||
"invite": "Invitar personas",
|
||||
"kick": "Expulsar participante",
|
||||
"laugh": "Ríete",
|
||||
"leaveConference": "Abandonar reunión",
|
||||
"like": "Pulgares arriba",
|
||||
"linkToSalesforce": "Enlace a Salesforce",
|
||||
"lobbyButton": "Activar / desactivar el modo lobby",
|
||||
"localRecording": "Alternar controles de grabación local",
|
||||
"lockRoom": "Alternar contraseña de la reunión",
|
||||
"lowerHand": "Bajar mano",
|
||||
"moreActions": "Alternar más acciones",
|
||||
"moreActionsMenu": "Menú de más acciones",
|
||||
"moreOptions": "Mostrar más opciones",
|
||||
"mute": "Silenciar micrófono",
|
||||
"muteEveryone": "Silenciar a todos",
|
||||
"muteEveryoneElse": "Silenciar a todos los demás",
|
||||
"muteEveryoneElsesVideo": "Desactivar el vídeo de los demás",
|
||||
"muteEveryonesVideo": "Desactivar el vídeo de todos",
|
||||
"muteEveryoneElsesVideoStream": "Detener el video del resto",
|
||||
"muteEveryonesVideoStream": "Detener el video de todos",
|
||||
"muteGUMPending": "Conectando su micrófono",
|
||||
"noiseSuppression": "Supresión de ruido",
|
||||
"openChat": "Abrir chat",
|
||||
"participants": "Participantes",
|
||||
"pip": "Alternar modo ventana en miniatura",
|
||||
"privateMessage": "Enviar mensaje privado",
|
||||
"profile": "Editar perfil",
|
||||
"raiseHand": "Levantar o bajar la mano",
|
||||
"reactions": "Reacciones",
|
||||
"reactionsMenu": "Abrir / Cerrar el menú de reacciones",
|
||||
"recording": "Alternar grabación",
|
||||
"remoteMute": "Silenciar participante",
|
||||
"remoteVideoMute": "Desactivar la cámara del participante",
|
||||
"security": "Opciones de seguridad",
|
||||
"selectBackground": "Seleccione el fondo",
|
||||
"selfView": "Alternar vista propia",
|
||||
"shareRoom": "Invitar a alguien",
|
||||
"shareYourScreen": "Comenzar / detener compartir pantalla",
|
||||
"shareaudio": "Compartir audio",
|
||||
"sharedvideo": "Alternar vídeo compartido",
|
||||
"shortcuts": "Alternar accesos directos",
|
||||
"show": "Mostrar en primer",
|
||||
"showWhiteboard": "Mostrar vista propia",
|
||||
"silence": "Silencio",
|
||||
"speakerStats": "Alternar estadísticas del orador",
|
||||
"stopScreenSharing": "Dejar de compartir pantalla",
|
||||
"stopSharedVideo": "Detener video",
|
||||
"surprised": "Sorprendido",
|
||||
"tileView": "Alternar vista de mosaico",
|
||||
"toggleCamera": "Alternar cámara",
|
||||
"toggleFilmstrip": "Alternar mosaicos",
|
||||
"unmute": "Activar micrófono",
|
||||
"videoblur": "Alternar desenfoque de vídeo",
|
||||
"videomute": "Alternar vídeo"
|
||||
"videomute": "Alternar vídeo",
|
||||
"videomuteGUMPending": "Conectando tu cámara",
|
||||
"videounmute": "Encender cámara"
|
||||
},
|
||||
"addPeople": "Agregar personas a la llamada",
|
||||
"audioOnlyOff": "Mostrar cámaras de los demás",
|
||||
@@ -963,23 +1211,33 @@
|
||||
"chat": "Abrir o cerrar chat",
|
||||
"clap": "Aplauso",
|
||||
"closeChat": "Cerrar chat",
|
||||
"closeParticipantsPane": "Cerrar panel de participantes",
|
||||
"closeReactionsMenu": "Cerrar el menú de reacciones",
|
||||
"disableNoiseSuppression": "Desactivar supresión de ruido",
|
||||
"disableReactionSounds": "Puede desactivar los sonidos de reacción para esta reunión",
|
||||
"documentClose": "Cerrar documento compartido",
|
||||
"documentOpen": "Abrir documento compartido",
|
||||
"download": "Descarga nuestras aplicaciones",
|
||||
"e2ee": "Cifrado de extremo a extremo",
|
||||
"embedMeeting": "Insertar reunión",
|
||||
"enableNoiseSuppression": "Activar supresión de ruido",
|
||||
"endConference": "Terminar reunión para todos",
|
||||
"enterFullScreen": "Pantalla completa",
|
||||
"enterTileView": "Ver en cuadrícula",
|
||||
"exitFullScreen": "Salir de pantalla completa",
|
||||
"exitTileView": "Salir de vista de mosaico",
|
||||
"feedback": "Dejar sugerencias",
|
||||
"giphy": "Alternar menú GIPHY",
|
||||
"hangup": "Colgar",
|
||||
"help": "Ayuda",
|
||||
"hideWhiteboard": "Esconder pizarra",
|
||||
"invite": "Invitar personas",
|
||||
"joinBreakoutRoom": "Unirse a sala para grupos pequeños",
|
||||
"laugh": "Ríete",
|
||||
"leaveBreakoutRoom": "Abandonar sala para grupos pequeños",
|
||||
"leaveConference": "Abandonar reunión",
|
||||
"like": "Pulgares arriba",
|
||||
"linkToSalesforce": "",
|
||||
"lobbyButtonDisable": "Desactivar el modo lobby",
|
||||
"lobbyButtonEnable": "Activar el modo lobby",
|
||||
"login": "Inicio de sesión",
|
||||
@@ -990,11 +1248,13 @@
|
||||
"mute": "Activar o silenciar el micrófono",
|
||||
"muteEveryone": "Silenciar a todos",
|
||||
"muteEveryonesVideo": "Desactivar la cámara de todos",
|
||||
"muteGUMPending": "Conectando tu micrónono",
|
||||
"noAudioSignalDesc": "Checa si no está silenciado en tu configuración del sistema o dispositivo, o cambia de micrófono.",
|
||||
"noAudioSignalDescSuggestion": "Si no lo silenciaste a propósito desde la configuración del sistema o el dispositivo, intenta usar este otro micrófono:",
|
||||
"noAudioSignalDialInDesc": "Además, puedes llamar usando:",
|
||||
"noAudioSignalDialInLinkDesc": "Números de llamada",
|
||||
"noAudioSignalTitle": "¡No se registra audio de tu micrófono!",
|
||||
"noiseSuppression": "Supresión de ruido",
|
||||
"noisyAudioInputDesc": "Tu micrófono está haciendo ruido, siléncialo, ajusta su volumen en configuración del sistema, o cambia de micrófono.",
|
||||
"noisyAudioInputTitle": "Tu micrófono parece estar ruidoso",
|
||||
"openChat": "Abrir chat",
|
||||
@@ -1011,12 +1271,14 @@
|
||||
"reactionLike": "Enviar la reacción de los pulgares hacia arriba",
|
||||
"reactionSilence": "Enviar reacción de silencio",
|
||||
"reactionSurprised": "Enviar reacción de sorpresa",
|
||||
"reactions": "Reacciones",
|
||||
"security": "Opciones de seguridad",
|
||||
"selectBackground": "Seleccionar fondo",
|
||||
"shareRoom": "Invitar a alguien",
|
||||
"shareaudio": "Compartir audio",
|
||||
"sharedvideo": "Compartir un vídeo",
|
||||
"shortcuts": "Ver atajos del teclado",
|
||||
"showWhiteboard": "Mostrar pizarra",
|
||||
"silence": "Silencio",
|
||||
"speakerStats": "Estadísticas de los participantes",
|
||||
"startScreenSharing": "Comenzar a compartir pantalla",
|
||||
@@ -1029,8 +1291,11 @@
|
||||
"talkWhileMutedPopup": "¿Intentas hablar? Estás silenciado.",
|
||||
"tileViewToggle": "Activar o desactivar vista en cuadrícula",
|
||||
"toggleCamera": "Alternar cámara",
|
||||
"unmute": "Activar",
|
||||
"videoSettings": "Ajustes de vídeo",
|
||||
"videomute": "Iniciar o detener cámara"
|
||||
"videomute": "Detener cámara",
|
||||
"videomuteGUMPending": "Conectando tu cámara",
|
||||
"videounmute": "Iniciar cámara"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Iniciar o detener subtítulos",
|
||||
@@ -1040,10 +1305,15 @@
|
||||
"labelToolTip": "La reunión se está transcribiendo",
|
||||
"off": "Transcripción detenida",
|
||||
"pending": "Preparando para transcribir la reunión…",
|
||||
"sourceLanguageDesc": "El lenguaje actual de la reunión es <b>{{sourceLanguage}}</b>. <br/> Puedes cambiarlo desde ",
|
||||
"sourceLanguageHere": "aquí",
|
||||
"start": "Mostrar subtítulos",
|
||||
"stop": "Dejar de mostrar subtítulos",
|
||||
"subtitles": "Subtítulos",
|
||||
"subtitlesOff": "",
|
||||
"tr": "TR"
|
||||
},
|
||||
"unpinParticipant": "",
|
||||
"userMedia": {
|
||||
"androidGrantPermissions": "Selecciona <b><i>Permitir</i></b> cuando el navegador solicite permisos.",
|
||||
"chromeGrantPermissions": "Selecciona <b><i>Permitir</i></b> cuando el navegador solicite permisos.",
|
||||
@@ -1067,20 +1337,26 @@
|
||||
"pending": "{{displayName}} ha sido invitado"
|
||||
},
|
||||
"videoStatus": {
|
||||
"adjustFor": "Ajustar para:",
|
||||
"audioOnly": "AUD",
|
||||
"audioOnlyExpanded": "Estás en modo de ancho de banda bajo. En este modo, sólo recibirás audio y pantalla compartida.",
|
||||
"bestPerformance": "Mejor rendimiento",
|
||||
"callQuality": "Calidad de vídeo",
|
||||
"hd": "HD",
|
||||
"hdTooltip": "Viendo vídeo en alta definición",
|
||||
"highDefinition": "Alta definición",
|
||||
"highestQuality": "Calidad máxima",
|
||||
"labelTooiltipNoVideo": "Sin vídeo",
|
||||
"labelTooltipAudioOnly": "Modo de ancho de banda bajo habilitado",
|
||||
"ld": "LD",
|
||||
"ldTooltip": "Viendo vídeo en baja definición",
|
||||
"lowDefinition": "Baja definición",
|
||||
"performanceSettings": "Ajustes de rendimiento",
|
||||
"recording": "Grabación en curso",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Viendo vídeo en definición estándar",
|
||||
"standardDefinition": "Definición estándar"
|
||||
"standardDefinition": "Definición estándar",
|
||||
"streaming": "Transmisión en curso"
|
||||
},
|
||||
"videothumbnail": {
|
||||
"connectionInfo": "Información de conexión",
|
||||
@@ -1090,12 +1366,19 @@
|
||||
"domuteVideoOfOthers": "Desactivar la cámara de todos los demás",
|
||||
"flip": "Voltear",
|
||||
"grantModerator": "Convertir en moderador",
|
||||
"hideSelfView": "Esconder vista propia",
|
||||
"kick": "Expulsar",
|
||||
"mirrorVideo": "Espejar mi video",
|
||||
"moderator": "Moderador",
|
||||
"mute": "Se silenció el participante",
|
||||
"muted": "Silenciado",
|
||||
"pinToStage": "",
|
||||
"remoteControl": "Control remoto",
|
||||
"screenSharing": "El participante está compartiendo su pantalla",
|
||||
"show": "Mostrar en primer plano",
|
||||
"showSelfView": "Mostrar vista propia",
|
||||
"unpinFromStage": "",
|
||||
"verify": "Verificar participante",
|
||||
"videoMuted": "Cámara desactivada",
|
||||
"videomute": "El participante paró su cámara"
|
||||
},
|
||||
@@ -1120,7 +1403,16 @@
|
||||
"slightBlur": "Desenfoque Ligero",
|
||||
"title": "Fondos virtuales",
|
||||
"uploadedImage": "Imagen subida {{index}}",
|
||||
"webAssemblyWarning": "No se admite WebAssembly"
|
||||
"webAssemblyWarning": "No se admite WebAssembly",
|
||||
"webAssemblyWarningDescription": "WebAssembly está desactivado o no cuenta con soporte en este navegador"
|
||||
},
|
||||
"visitors": {
|
||||
"chatIndicator": "(visitante)",
|
||||
"labelTooltip": "Cantidad de visitantes: {{count}}",
|
||||
"notification": {
|
||||
"description": "Levanta la mano para participar",
|
||||
"title": "Eres un visitante en la reunión"
|
||||
}
|
||||
},
|
||||
"volumeSlider": "Deslizador de volumen",
|
||||
"welcomepage": {
|
||||
@@ -1154,6 +1446,7 @@
|
||||
"microsoftLogo": "Logotipo de Microsoft",
|
||||
"policyLogo": "Logotipo de la política"
|
||||
},
|
||||
"meetingsAccessibilityLabel": "Reuniones",
|
||||
"mobileDownLoadLinkAndroid": "Descargar la aplicación móvil para Android",
|
||||
"mobileDownLoadLinkFDroid": "Descargar la aplicación móvil para F-Droid",
|
||||
"mobileDownLoadLinkIos": "Descargar la aplicación móvil para iOS",
|
||||
@@ -1162,13 +1455,21 @@
|
||||
"recentList": "Reciente",
|
||||
"recentListDelete": "Eliminar",
|
||||
"recentListEmpty": "Tu historial de reuniones está vacío. Reúnete y aparecerán aquí.",
|
||||
"recentMeetings": "Tus reuniones recientes",
|
||||
"reducedUIText": "¡Bienvenido a {{app}}!",
|
||||
"roomNameAllowedChars": "El nombre de la reunión no debe contener ninguno de estos caracteres: ?, &, :, ', \", %, #.",
|
||||
"roomname": "Introduce el nombre de la sala",
|
||||
"roomnameHint": "Introduce el nombre o URL de la sala a la que deseas unirte. Puedes inventar un nombre, simplemente infórmaselo a las personas con las que te reunirás para que introduzcan el mismo nombre.",
|
||||
"sendFeedback": "Enviar sugerencias",
|
||||
"settings": "Ajustes",
|
||||
"startMeeting": "Iniciar la reunión",
|
||||
"terms": "Términos",
|
||||
"title": "Videoconferencias seguras, con gran variedad de funcionalidades y completamente gratuitas"
|
||||
"title": "Videoconferencias seguras, con gran variedad de funcionalidades y completamente gratuitas",
|
||||
"upcomingMeetings": "Tus próximas reuniones"
|
||||
},
|
||||
"whiteboard": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Pizarra"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -68,9 +68,9 @@
|
||||
},
|
||||
"join": "Gå med",
|
||||
"joinTooltip": "Gå med i mötet",
|
||||
"nextMeeting": "nästa möte",
|
||||
"nextMeeting": "Nästa möte",
|
||||
"noEvents": "Det finns inga inbokade kommande aktiviteter.",
|
||||
"ongoingMeeting": "pågående möte",
|
||||
"ongoingMeeting": "Pågående möte",
|
||||
"permissionButton": "Öppna inställningar",
|
||||
"permissionMessage": "Tillåtelse från kalendern krävs för att se dina möten i appen.",
|
||||
"refresh": "Uppdatera kalender",
|
||||
@@ -147,6 +147,7 @@
|
||||
"bridgeCount": "Serverantal: ",
|
||||
"codecs": "Codecs (A/V):",
|
||||
"connectedTo": "Ansluten till:",
|
||||
"e2eeVerified": "E2EE verifierad",
|
||||
"framerate": "Bildfrekvens:",
|
||||
"less": "Visa mindre",
|
||||
"localaddress": "Lokal adress:",
|
||||
@@ -155,6 +156,7 @@
|
||||
"localport_plural": "Lokala portar:",
|
||||
"maxEnabledResolution": "Sänd maxiamlt",
|
||||
"more": "Visa mer",
|
||||
"no": "Nej",
|
||||
"packetloss": "Paketförluster:",
|
||||
"participant_id": "Deltagar id:",
|
||||
"quality": {
|
||||
@@ -173,7 +175,8 @@
|
||||
"status": "Anslutning:",
|
||||
"transport": "Transport:",
|
||||
"transport_plural": "Transporter:",
|
||||
"video_ssrc": "Video SSRC:"
|
||||
"video_ssrc": "Video SSRC:",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "Tidigare",
|
||||
@@ -183,17 +186,25 @@
|
||||
"deepLinking": {
|
||||
"appNotInstalled": "Du behöver mobilappen {{app}} för att gå med i det här mötet från din telefon.",
|
||||
"description": "Hände inget? Vi försökte starta mötet i programmet {{app}} i din skrivbordsapp. Försök igen eller starta det i webbappen {{app}}.",
|
||||
"descriptionNew": "Hände inget? Vi försökte starta mötet i programmet {{app}} i din skrivbordsapp. <br /><br /> Försök igen eller starta det på webben.",
|
||||
"descriptionWithoutWeb": "Händer inget? Vi försökte starta mötet i {{app}}-skrivbordsappen.",
|
||||
"downloadApp": "Hämta appen",
|
||||
"downloadMobileApp": "Ladda ner mobilappen",
|
||||
"ifDoNotHaveApp": "Om du inte har appen än:",
|
||||
"ifHaveApp": "Om du redan har appen:",
|
||||
"joinInApp": "Delta i detta möte med din app",
|
||||
"joinInAppNew": "Delta i appen",
|
||||
"joinInBrowser": "Delta på webben",
|
||||
"launchMeetingLabel": "Hur vill du delta i detta möte?",
|
||||
"launchWebButton": "Starta på webben",
|
||||
"noMobileApp": "Har du inte appen?",
|
||||
"termsAndConditions": "Genom att fortsätta godkänner du våra <a href='{{termsAndConditionsLink}}' rel='noopener noreferrer' target='_blank'>villkor.</a>",
|
||||
"title": "Startar ditt möte i {{app}} ...",
|
||||
"titleNew": "Startar ditt möte...",
|
||||
"tryAgainButton": "Försök igen på skrivbordet",
|
||||
"unsupportedBrowser": "Det verkar som att du använder en webbläsare som vi inte stöder."
|
||||
},
|
||||
"defaultLink": "t ex. {{url}}",
|
||||
"defaultLink": "t.ex. {{url}}",
|
||||
"defaultNickname": "till exempel Julia Eriksson",
|
||||
"deviceError": {
|
||||
"cameraError": "Det gick inte att komma åt kameran",
|
||||
@@ -202,6 +213,12 @@
|
||||
"microphonePermission": "Fel vid begäran om åtkomst till mikrofon"
|
||||
},
|
||||
"deviceSelection": {
|
||||
"hid": {
|
||||
"callControl": "Samtalskontroll",
|
||||
"connectedDevices": "Anslutna enheter",
|
||||
"deleteDevice": "Radera enhet",
|
||||
"pairDevice": "Para enhet"
|
||||
},
|
||||
"noPermission": "Behörighet nekad",
|
||||
"previewUnavailable": "Förhandsgranskning inte tillgänglig",
|
||||
"selectADevice": "Välj en enhet",
|
||||
@@ -225,7 +242,9 @@
|
||||
"WaitingForHostTitle": "Väntar på värden ...",
|
||||
"Yes": "Ja",
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Livesändning"
|
||||
"close": "Stäng",
|
||||
"liveStreaming": "Livesändning",
|
||||
"sharingTabs": "Delningsalternativ"
|
||||
},
|
||||
"add": "Lägg till",
|
||||
"addMeetingNote": "Mötesinformation",
|
||||
@@ -408,6 +427,10 @@
|
||||
"user": "Användare",
|
||||
"userIdentifier": "Användar-ID",
|
||||
"userPassword": "Lösenord",
|
||||
"verifyParticipantConfirm": "Dem matchar",
|
||||
"verifyParticipantDismiss": "Dem matchar inte",
|
||||
"verifyParticipantQuestion": "EXPERIMENTELLT: Fråga deltagaren; {{participantName}} om han/hon kan se samma innehåll, i samma ordning.",
|
||||
"verifyParticipantTitle": "Användarverifikation",
|
||||
"videoLink": "Videolänk",
|
||||
"viewUpgradeOptions": "Se uppgraderings alternativ",
|
||||
"viewUpgradeOptionsContent": "För att få obegränsad tillgång till premiumfunktioner som inspelning, transkriptioner, RTMP -streaming och mer måste du uppgradera din plan.",
|
||||
@@ -433,13 +456,15 @@
|
||||
"veryBad": "Mycket dåligt",
|
||||
"veryGood": "Mycket bra"
|
||||
},
|
||||
"filmstrip": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Videomineatyrer"
|
||||
}
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "Inga resultat funna :(",
|
||||
"search": "Sök efter GIPHY"
|
||||
},
|
||||
"helpView": {
|
||||
"title": "Hjälpcenter"
|
||||
},
|
||||
"incomingCall": {
|
||||
"answer": "Svara",
|
||||
"audioCallTitle": "Inkommande samtal",
|
||||
@@ -517,7 +542,8 @@
|
||||
"toggleParticipantsPane": "Visa eller dölj deltagarfönstret",
|
||||
"toggleScreensharing": "Växla mellan kamera och skärmdelning",
|
||||
"toggleShortcuts": "Visa eller dölj kortkommandon",
|
||||
"videoMute": "Aktivera / avaktivera din kamera"
|
||||
"videoMute": "Aktivera / inaktivera din kamera",
|
||||
"whiteboard": "Visa / dölj whiteboardtavlan"
|
||||
},
|
||||
"largeVideo": {
|
||||
"screenIsShared": "Du delar din skärm",
|
||||
@@ -563,7 +589,6 @@
|
||||
"lobby": {
|
||||
"admit": "Godkänn",
|
||||
"admitAll": "Godkänn alla",
|
||||
"allow": "Tillåt",
|
||||
"backToKnockModeButton": "Tillbaka till väntrum",
|
||||
"chat": "Chatt",
|
||||
"dialogTitle": "Väntrum",
|
||||
@@ -649,8 +674,12 @@
|
||||
"connectedOneMember": "{{name}} har gått med i mötet",
|
||||
"connectedThreePlusMembers": "{{name}} och {{count}} andra har gått med i mötet",
|
||||
"connectedTwoMembers": "{{first}} och {{second}} har gått med i mötet",
|
||||
"dataChannelClosed": "Försämrad videokvalitet",
|
||||
"dataChannelClosedDescription": "Bryggkanalen har kopplats bort och därmed är videokvaliteten begränsad till sin lägsta inställning",
|
||||
"disabledIframe": "Inbäddning är endast avsedd för demonstrationsändamål, så det här samtalet kommer att kopplas ner om {{timeout}} minuter.",
|
||||
"disconnected": "frånkopplad",
|
||||
"displayNotifications": "Visa aviseringar för",
|
||||
"dontRemindMe": "Påminn mig inte",
|
||||
"focus": "Konferensfokus",
|
||||
"focusFail": "{{component}} inte tillgänglig – försöker igen om {{ms}} sek",
|
||||
"gifsMenu": "GIPHY",
|
||||
@@ -659,6 +688,7 @@
|
||||
"invitedOneMember": "{{name}} har bjudits in",
|
||||
"invitedThreePlusMembers": "{{name}} och {{count}} andra har bjudits in",
|
||||
"invitedTwoMembers": "{{first}} och {{second}} har bjudits in",
|
||||
"joinMeeting": "Delta",
|
||||
"kickParticipant": "{{kicked}} sparkades ut av {{kicker}}",
|
||||
"leftOneMember": "{{name}} lämnade mötet",
|
||||
"leftThreePlusMembers": "{{name}} och många andra lämnade mötet",
|
||||
@@ -709,6 +739,8 @@
|
||||
"reactionSoundsForAll": "Inaktivera ljud för alla",
|
||||
"screenShareNoAudio": "\"Dela ljudrutan\" aktiverades inte i fönstret för val av fönster.",
|
||||
"screenShareNoAudioTitle": "Det gick inte att dela systemljud!",
|
||||
"screenSharingAudioOnlyDescription": "Observera att genom att dela din skärm påverkar du läget \"Bästa prestanda\" och du kommer att använda mer bandbredd.",
|
||||
"screenSharingAudioOnlyTitle": "Läget \"Bästa prestanda\"",
|
||||
"selfViewTitle": "Du kan alltid ta bort döljandet av självvyn från inställningarna",
|
||||
"somebody": "Någon",
|
||||
"startSilentDescription": "Anslut till mötet igen för att aktivera ljud",
|
||||
@@ -746,6 +778,7 @@
|
||||
"headings": {
|
||||
"lobby": "Väntrum ({{count}})",
|
||||
"participantsList": "Mötesdeltagare ({{count}})",
|
||||
"visitors": "Gäster ({{count}})",
|
||||
"waitingLobby": "Väntar i väntrum ({{count}})"
|
||||
},
|
||||
"search": "Sök efter deltagare",
|
||||
@@ -753,6 +786,7 @@
|
||||
},
|
||||
"passwordDigitsOnly": "Ange max {{number}} siffror",
|
||||
"passwordSetRemotely": "satt av en annan deltagare",
|
||||
"pinParticipant": "{{participantName}} - Fäst",
|
||||
"pinnedParticipant": "Deltagaren är fäst",
|
||||
"polls": {
|
||||
"answer": {
|
||||
@@ -837,9 +871,11 @@
|
||||
"lookGood": "Din mikrofon fungerar som den ska",
|
||||
"or": "eller",
|
||||
"premeeting": "Förmöte",
|
||||
"proceedAnyway": "Fortsätt ändå",
|
||||
"screenSharingError": "Skärmdelningsfel:",
|
||||
"showScreen": "Aktivera skärmen före mötet",
|
||||
"startWithPhone": "Börja med telefonljud",
|
||||
"unsafeRoomConsent": "Jag förstår riskerna, jag vill vara med på mötet",
|
||||
"videoOnlyError": "Videofel:",
|
||||
"videoTrackError": "Det gick inte att skapa videospår.",
|
||||
"viewAllNumbers": "visa alla nummer"
|
||||
@@ -858,9 +894,6 @@
|
||||
"rejected": "Avvisad",
|
||||
"ringing": "Ringer..."
|
||||
},
|
||||
"privacyView": {
|
||||
"title": "Privat"
|
||||
},
|
||||
"profile": {
|
||||
"avatar": "avatar",
|
||||
"setDisplayNameLabel": "Ange ditt visningsnamn",
|
||||
@@ -869,7 +902,7 @@
|
||||
"title": "Profil"
|
||||
},
|
||||
"raisedHand": "Räck upp handen",
|
||||
"raisedHandsLabel": "Antal upphöjda händer",
|
||||
"raisedHandsLabel": "Antal uppräckta händer",
|
||||
"record": {
|
||||
"already": {
|
||||
"linked": "Mötet är redan länkat till detta Salesforce-objekt."
|
||||
@@ -914,6 +947,7 @@
|
||||
"localRecordingVideoWarning": "För att spela in din video måste du ha den på när du startar inspelningen",
|
||||
"localRecordingWarning": "Se till att du väljer den aktuella fliken för att kunna använda rätt video och ljud. Inspelningen är för närvarande begränsad till 1 GB, vilket är cirka 100 minuter.",
|
||||
"loggedIn": "Inloggad som {{userName}}",
|
||||
"noMicPermission": "Mikrofonspåret kunde inte skapas. Vänligen ge tillstånd att använda mikrofonen.",
|
||||
"noStreams": "Ingen ljud- eller videoström upptäcktes.",
|
||||
"off": "Inspelningen avslutades",
|
||||
"offBy": "{{name}} avslutade inspelningen",
|
||||
@@ -943,10 +977,17 @@
|
||||
"security": {
|
||||
"about": "Du kan lägga till ett $t(lockRoomPassword) till ditt möte. Deltagarna måste ange $t(lockRoomPassword) innan de får gå med i mötet.",
|
||||
"aboutReadOnly": "Moderatorn kan lägga till ett $t(lockRoomPassword) till mötet. Deltagarna måste ange $t(lockRoomPassword) innan de får gå med i mötet.",
|
||||
"insecureRoomNameWarning": "Rummets namn är osäkert. Oönskade deltagare kan gå med i din konferens. Överväg att säkra ditt möte med hjälp av säkerhetsknappen.",
|
||||
"title": "Säkerhetsalternativ"
|
||||
"insecureRoomNameWarningNative": "Rumsnamnet är osäkert. Oönskade deltagare kan gå med i ditt möte. {{recommendAction}} Läs mer om att säkra ditt möte",
|
||||
"insecureRoomNameWarningWeb": "Rumsnamnet är osäkert. Oönskade deltagare kan gå med i ditt möte. {{recommendAction}} Läs mer om hur du säkerställer att du möter <a href=\"{{securityUrl}}\" rel=\"security\"-målet =\"_blank\">här</a>.",
|
||||
"title": "Säkerhetsalternativ",
|
||||
"unsafeRoomActions": {
|
||||
"meeting": "Överväg att göra ditt möte säkrare med hjälp av säkerhetsknappen.",
|
||||
"prejoin": "Överväg att använda ett mer unikt mötesnamn.",
|
||||
"welcome": "Överväg att använda ett mer unikt mötesnamn, eller välj ett av förslagen."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"audio": "Ljud",
|
||||
"buttonLabel": "Inställningar",
|
||||
"calendar": {
|
||||
"about": "Kalenderintegrationen med {{appName}} används för att hämta din kalender på ett säkert sätt så att den kan läsa framtida händelser.",
|
||||
@@ -967,9 +1008,11 @@
|
||||
"maxStageParticipants": "Maximalt antal deltagare som kan fästas på huvudscenen",
|
||||
"microphones": "Mikrofoner",
|
||||
"moderator": "Moderator",
|
||||
"moderatorOptions": "Moderatoralternativ",
|
||||
"more": "Mer",
|
||||
"name": "Namn",
|
||||
"noDevice": "Inga enheter",
|
||||
"notifications": "Notifikationer",
|
||||
"participantJoined": "Deltagare ansluten",
|
||||
"participantKnocking": "Deltagare har anslutit till lobbyn",
|
||||
"participantLeft": "Deltagare lämnat mötet",
|
||||
@@ -980,13 +1023,14 @@
|
||||
"selectCamera": "Kamera",
|
||||
"selectMic": "Mikrofon",
|
||||
"selfView": "Självvy",
|
||||
"sounds": "Ljud",
|
||||
"shortcuts": "Genvägar",
|
||||
"speakers": "Högtalare",
|
||||
"startAudioMuted": "Alla börjar tystade",
|
||||
"startReactionsMuted": "Stäng av reaktionsljud för alla",
|
||||
"startVideoMuted": "Alla börjar osynliga",
|
||||
"talkWhileMuted": "Prata medan din ljud är inaktiverad",
|
||||
"title": "Inställningar"
|
||||
"title": "Inställningar",
|
||||
"video": "Video"
|
||||
},
|
||||
"settingsView": {
|
||||
"advanced": "Avancerat",
|
||||
@@ -1003,6 +1047,7 @@
|
||||
"displayName": "Skärmnamn",
|
||||
"displayNamePlaceholderText": "Exempel: John Doe",
|
||||
"email": "E-post",
|
||||
"emailPlaceholderText": "mejl@exempel.se",
|
||||
"goTo": "Gå till",
|
||||
"header": "Inställningar",
|
||||
"help": "Hjälp",
|
||||
@@ -1060,69 +1105,87 @@
|
||||
"audioOnly": "Slå av eller på ljudet",
|
||||
"audioRoute": "Välj ljudenhet",
|
||||
"boo": "Bua",
|
||||
"breakoutRoom": "Gå med i/lämna grupprum",
|
||||
"breakoutRoom": "Anslut eller lämna grupprum",
|
||||
"callQuality": "Hantera videokvalitet",
|
||||
"carmode": "Billäge",
|
||||
"cc": "Slå av eller på undertexter",
|
||||
"chat": "Öppna eller stäng chattfönster",
|
||||
"clap": "Klappa",
|
||||
"collapse": "Kollaps",
|
||||
"document": "Öppna eller stäng delat dokument",
|
||||
"download": "Ladda ner app",
|
||||
"clap": "Applådera",
|
||||
"closeChat": "Stäng chatten",
|
||||
"closeMoreActions": "Stäng menyn för fler åtgärder",
|
||||
"closeParticipantsPane": "Stäng deltagarfönstret",
|
||||
"collapse": "Minimera",
|
||||
"document": "Växla delat dokument",
|
||||
"documentClose": "Stäng delat dokument",
|
||||
"documentOpen": "Öppna delat dokument",
|
||||
"download": "Ladda ner våra appar",
|
||||
"embedMeeting": "Bädda in möte",
|
||||
"endConference": "Avsluta mötet för alla",
|
||||
"expand": "Expandera",
|
||||
"feedback": "Lämna återkoppling",
|
||||
"fullScreen": "Öppna eller stäng fullskärm",
|
||||
"giphy": "Växla GIPHY meny",
|
||||
"grantModerator": "Godkänn moderator",
|
||||
"hangup": "Lämna samtalet",
|
||||
"endConference": "Avsluta möte för alla",
|
||||
"enterFullScreen": "Visa helskärm",
|
||||
"enterTileView": "Öppna sida vid sida",
|
||||
"exitFullScreen": "Avsluta helskärm",
|
||||
"exitTileView": "Avsluta sida vid sida",
|
||||
"expand": "Utöka",
|
||||
"feedback": "Ge feedback",
|
||||
"fullScreen": "Växla helskärm",
|
||||
"giphy": "Växla GIPHY-menyn",
|
||||
"grantModerator": "Tilldela moderatorrättigheter",
|
||||
"hangup": "Lämna mötet",
|
||||
"heading": "Verktygsfält",
|
||||
"help": "Hjälp",
|
||||
"invite": "Bjud in andra",
|
||||
"hideWhiteboard": "Dölj whiteboard",
|
||||
"invite": "Bjud in personer",
|
||||
"kick": "Sparka ut deltagare",
|
||||
"laugh": "Skratta",
|
||||
"leaveConference": "Lämna möte",
|
||||
"leaveConference": "Lämna mötet",
|
||||
"like": "Tummen upp",
|
||||
"linkToSalesforce": "Länk till Salesforce",
|
||||
"lobbyButton": "Aktivera/inaktivera väntrumsläge",
|
||||
"localRecording": "Öppna eller stäng lokala inspelningsverktyg",
|
||||
"lockRoom": "Slå av eller på möteslösenord",
|
||||
"moreActions": "Öppna eller stäng menyn för fler åtgärder",
|
||||
"moreActionsMenu": "Meny för fler åtgärder",
|
||||
"lobbyButton": "Aktivera / inaktivera lobbyläge",
|
||||
"localRecording": "Växla lokala inspelningskontroller",
|
||||
"lockRoom": "Växla möteslösenord",
|
||||
"lowerHand": "Sänk din hand",
|
||||
"moreActions": "Fler åtgärder",
|
||||
"moreActionsMenu": "Menyn Fler åtgärder",
|
||||
"moreOptions": "Visa fler alternativ",
|
||||
"mute": "Slå av eller på ljud",
|
||||
"muteEveryone": "Tysta alla",
|
||||
"muteEveryoneElse": "Inkativerad ljud för alla andra",
|
||||
"mute": "Mute",
|
||||
"muteEveryone": "Stäng av ljudet för alla",
|
||||
"muteEveryoneElse": "Stäng av ljudet för alla andra",
|
||||
"muteEveryoneElsesVideoStream": "Stoppa alla andras video",
|
||||
"muteEveryonesVideoStream": "Stoppa allas video",
|
||||
"noiseSuppression": "Brusreducering",
|
||||
"participants": "Deltagare",
|
||||
"pip": "Öppna eller stäng bild-i-bild-läge",
|
||||
"noiseSuppression": "Brusdämpning",
|
||||
"openChat": "Öppna chatt",
|
||||
"participants": "Öppna deltagarfönstret",
|
||||
"pip": "Växla bild-i-bild-läge",
|
||||
"privateMessage": "Skicka privat meddelande",
|
||||
"profile": "Redigera din profil",
|
||||
"raiseHand": "Räck upp eller ta ner handen",
|
||||
"reactionsMenu": "Öppna7ständ meny för reaktioner",
|
||||
"recording": "Slå av eller på inspelning",
|
||||
"remoteMute": "Tysta deltagare",
|
||||
"remoteVideoMute": "Inaktivera kamera för deltagare",
|
||||
"raiseHand": "Räck upp handen",
|
||||
"reactions": "Reaktioner",
|
||||
"reactionsMenu": "Reaktionsmeny",
|
||||
"recording": "Växla inspelning",
|
||||
"remoteMute": "Ljud av deltagare",
|
||||
"remoteVideoMute": "Inaktivera kameran för deltagaren",
|
||||
"security": "Säkerhetsalternativ",
|
||||
"selectBackground": "Välj bakgrund",
|
||||
"selfView": "Växla självvy",
|
||||
"shareRoom": "Bjud in någon",
|
||||
"shareYourScreen": "Slå av eller på skärmdelning",
|
||||
"shareYourScreen": "Börja dela din skärm",
|
||||
"shareaudio": "Dela ljud",
|
||||
"sharedvideo": "Slå av eller på videodelning",
|
||||
"shortcuts": "Stäng eller öppna genvägar",
|
||||
"sharedvideo": "Dela video",
|
||||
"shortcuts": "Växla genvägar",
|
||||
"show": "Visa på scenen",
|
||||
"silence": "Tyst läge",
|
||||
"speakerStats": "Stäng eller öppna talarstatistik",
|
||||
"surprised": "Överaskning",
|
||||
"tileView": "Öppna eller stäng panelvyn",
|
||||
"showWhiteboard": "Visa whiteboard",
|
||||
"silence": "Tystnad",
|
||||
"speakerStats": "Växla deltagarstatistik",
|
||||
"stopScreenSharing": "Sluta dela din skärm",
|
||||
"stopSharedVideo": "Stoppa video",
|
||||
"surprised": "Förvånad",
|
||||
"tileView": "Växla sida vid sida",
|
||||
"toggleCamera": "Växla kamera",
|
||||
"toggleFilmstrip": "Växla filmremsa",
|
||||
"unmute": "Slå på ljudet",
|
||||
"videoblur": "Växla videooskärpa",
|
||||
"videomute": "Sätt på eller stäng av mikrofonen",
|
||||
"whiteboard": "Visa/dölj whiteboardtavlan"
|
||||
"videomute": "Stoppa kamera",
|
||||
"videounmute": "Starta kameran"
|
||||
},
|
||||
"addPeople": "Lägg till personer i samtal",
|
||||
"audioOnlyOff": "Avsluta ljudläget",
|
||||
@@ -1135,6 +1198,7 @@
|
||||
"chat": "Öppna / stäng chatten",
|
||||
"clap": "Klappa",
|
||||
"closeChat": "Stäng chatt",
|
||||
"closeParticipantsPane": "Stäng deltagarrutan",
|
||||
"closeReactionsMenu": "Stäng meny för reaktioner",
|
||||
"disableNoiseSuppression": "Inaktivera brusreducering",
|
||||
"disableReactionSounds": "Du kan inaktivera reaktionsljud för det här mötet",
|
||||
@@ -1143,6 +1207,7 @@
|
||||
"download": "Ladda ner vår app",
|
||||
"e2ee": "End-to-End kryptering",
|
||||
"embedMeeting": "Bädda in möte",
|
||||
"enableNoiseSuppression": "Aktivera brusreducering",
|
||||
"endConference": "Avsluta mötet för alla",
|
||||
"enterFullScreen": "Visa fullskärm",
|
||||
"enterTileView": "Öppna panelvy",
|
||||
@@ -1192,6 +1257,7 @@
|
||||
"reactionLike": "Skicka tummen upp",
|
||||
"reactionSilence": "Skicka tyst reaktion",
|
||||
"reactionSurprised": "Skicka reaktionen överaskad",
|
||||
"reactions": "Reaktioner",
|
||||
"security": "Säkerhetsalternativ",
|
||||
"selectBackground": "Välj bakgrund",
|
||||
"shareRoom": "Bjud in någon",
|
||||
@@ -1211,11 +1277,13 @@
|
||||
"talkWhileMutedPopup": "Försöker du tala? Din mikrofon är tystad.",
|
||||
"tileViewToggle": "Öppna eller stäng panelvyn",
|
||||
"toggleCamera": "Byta kamera",
|
||||
"unmute": "Slå på ljud",
|
||||
"videoSettings": "Video inställningar",
|
||||
"videomute": "Aktivera / avaktivera kameran"
|
||||
"videomute": "Inaktivera kameran",
|
||||
"videounmute": "Aktivera kameran"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Starta / Avsluta undertexter",
|
||||
"ccButtonTooltip": "Aktivera / Inaktivera undertexter",
|
||||
"error": "Transkriberingen misslyckades. Försök igen.",
|
||||
"expandedLabel": "Transkribering är aktiverad",
|
||||
"failedToStart": "Det gick inte att starta transkribering",
|
||||
@@ -1230,6 +1298,7 @@
|
||||
"subtitlesOff": "Av",
|
||||
"tr": "TR"
|
||||
},
|
||||
"unpinParticipant": "Lossa deltagare",
|
||||
"userMedia": {
|
||||
"androidGrantPermissions": "Välj <b><i>Tillåt</i></b> när din webbläsare begär åtkomst.",
|
||||
"chromeGrantPermissions": "Välj <b><i>Tillåt</i></b> när din webbläsare begär åtkomst.",
|
||||
@@ -1268,9 +1337,11 @@
|
||||
"ldTooltip": "Titta på lågupplöst video",
|
||||
"lowDefinition": "Låg upplösning",
|
||||
"performanceSettings": "Prestandainställningar",
|
||||
"recording": "Inspelning pågår",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Titta på video med standardupplösning",
|
||||
"standardDefinition": "Normal upplösning"
|
||||
"standardDefinition": "Normal upplösning",
|
||||
"streaming": "Streaming pågår"
|
||||
},
|
||||
"videothumbnail": {
|
||||
"connectionInfo": "Anslutningsinformation",
|
||||
@@ -1282,6 +1353,7 @@
|
||||
"grantModerator": "Godkänn moderator",
|
||||
"hideSelfView": "Dölj självvyn",
|
||||
"kick": "Sparka ut",
|
||||
"mirrorVideo": "Spegelvänd video",
|
||||
"moderator": "Moderator",
|
||||
"mute": "Deltagaren har avstängd mikrofon",
|
||||
"muted": "Tystad",
|
||||
@@ -1291,8 +1363,9 @@
|
||||
"show": "Visa på scenen",
|
||||
"showSelfView": "Visa självvy",
|
||||
"unpinFromStage": "Ta loss",
|
||||
"videoMuted": "kamera inaktiverad",
|
||||
"videomute": "Deltagaren har stäng av kameran"
|
||||
"verify": "Verifiera",
|
||||
"videoMuted": "Kamera inaktiverad",
|
||||
"videomute": "Deltagaren har stängt av kameran"
|
||||
},
|
||||
"virtualBackground": {
|
||||
"addBackground": "Lägg till bakgrund",
|
||||
@@ -1318,6 +1391,14 @@
|
||||
"webAssemblyWarning": "WebAssembly stöds inte",
|
||||
"webAssemblyWarningDescription": "WebAssembly inaktiverad eller stöds inte av den här webbläsaren"
|
||||
},
|
||||
"visitors": {
|
||||
"chatIndicator": "(besökare)",
|
||||
"labelTooltip": "Antal besökare: {{count}}",
|
||||
"notification": {
|
||||
"description": "Räck upp handen för att delta",
|
||||
"title": "Du är en besökare i mötet"
|
||||
}
|
||||
},
|
||||
"volumeSlider": "Volymreglage",
|
||||
"welcomepage": {
|
||||
"accessibilityLabel": {
|
||||
@@ -1338,6 +1419,7 @@
|
||||
"go": "KÖR",
|
||||
"goSmall": "BÖRJA",
|
||||
"headerSubtitle": "Säkra möten med hög kvalitet",
|
||||
"headerTitle": "Jitsi Meet",
|
||||
"info": "Info",
|
||||
"jitsiOnMobile": "Jitsi på mobilen - ladda ner våra appar och starta ett möte var som helst",
|
||||
"join": "Gå med",
|
||||
@@ -1349,6 +1431,7 @@
|
||||
"microsoftLogo": "Microsoft logotyp",
|
||||
"policyLogo": "Policy-logotyp"
|
||||
},
|
||||
"meetingsAccessibilityLabel": "Möten",
|
||||
"mobileDownLoadLinkAndroid": "Ladda ner mobilappen för Android",
|
||||
"mobileDownLoadLinkFDroid": "Ladda ner mobilappen för F-droid",
|
||||
"mobileDownLoadLinkIos": "Ladda ner mobilappen för iOS",
|
||||
@@ -1357,6 +1440,7 @@
|
||||
"recentList": "Tidigare",
|
||||
"recentListDelete": "Radera",
|
||||
"recentListEmpty": "Inga tidigare möten. Chatta med ditt team och hitta alla tidigare möten där.",
|
||||
"recentMeetings": "Dina senaste möten",
|
||||
"reducedUIText": "Välkommen till {{app}}!",
|
||||
"roomNameAllowedChars": "Mötesnamn kan inte innehålla dessa tecken: ?, &,:, ', \",%, #.",
|
||||
"roomname": "Skriv in rumsnamn",
|
||||
@@ -1365,6 +1449,12 @@
|
||||
"settings": "Inställningar",
|
||||
"startMeeting": "Starta möte",
|
||||
"terms": "Villkor",
|
||||
"title": "Säkra, välutrustade och helt kostnadsfria videokonferenser"
|
||||
"title": "Säkra, välutrustade och helt kostnadsfria videokonferenser",
|
||||
"upcomingMeetings": "Dina kommande möten"
|
||||
},
|
||||
"whiteboard": {
|
||||
"accessibilityLabel": {
|
||||
"heading": "Whiteboard"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
{
|
||||
"addPeople": {
|
||||
"accessibilityLabel": {
|
||||
"meetingLink": "Meeting link: {{url}}"
|
||||
},
|
||||
"add": "Invite",
|
||||
"addContacts": "Invite your contacts",
|
||||
"contacts": "contacts",
|
||||
@@ -39,6 +42,18 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "Low bandwidth"
|
||||
},
|
||||
"bandwidthSettings": {
|
||||
"assumedBandwidthBps": "e.g. 10000000 for 10 Mbps",
|
||||
"assumedBandwidthBpsWarning": "Higher values might cause network issues.",
|
||||
"customValue": "custom value",
|
||||
"customValueEffect": "to set the actual bps value",
|
||||
"leaveEmpty": "leave empty",
|
||||
"leaveEmptyEffect": "to allow estimations to take place",
|
||||
"possibleValues": "Possible values",
|
||||
"setAssumedBandwidthBps": "Assumed bandwidth (bps)",
|
||||
"title": "Bandwidth settings",
|
||||
"zeroEffect": "to disable video"
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "Add breakout room",
|
||||
@@ -242,6 +257,8 @@
|
||||
"WaitingForHostTitle": "Waiting for the host ...",
|
||||
"Yes": "Yes",
|
||||
"accessibilityLabel": {
|
||||
"Cancel": "Cancel (leave dialog)",
|
||||
"Ok": "OK (save and leave dialog)",
|
||||
"close": "Close dialog",
|
||||
"liveStreaming": "Live Stream",
|
||||
"sharingTabs": "Sharing options"
|
||||
@@ -447,6 +464,9 @@
|
||||
"title": "Embed this meeting"
|
||||
},
|
||||
"feedback": {
|
||||
"accessibilityLabel": {
|
||||
"yourChoice": "Your choice: {{rating}}"
|
||||
},
|
||||
"average": "Average",
|
||||
"bad": "Bad",
|
||||
"detailsLabel": "Tell us more about it.",
|
||||
@@ -1151,6 +1171,7 @@
|
||||
"muteEveryoneElse": "Mute everyone else",
|
||||
"muteEveryoneElsesVideoStream": "Stop everyone else's video",
|
||||
"muteEveryonesVideoStream": "Stop everyone's video",
|
||||
"muteGUMPending": "Connecting your microphone",
|
||||
"noiseSuppression": "Noise suppression",
|
||||
"openChat": "Open chat",
|
||||
"participants": "Open participants pane",
|
||||
@@ -1184,6 +1205,7 @@
|
||||
"unmute": "Unmute",
|
||||
"videoblur": "Toggle video blur",
|
||||
"videomute": "Stop camera",
|
||||
"videomuteGUMPending": "Connecting your camera",
|
||||
"videounmute": "Start camera"
|
||||
},
|
||||
"addPeople": "Add people to your call",
|
||||
@@ -1234,6 +1256,7 @@
|
||||
"mute": "Mute",
|
||||
"muteEveryone": "Mute everyone",
|
||||
"muteEveryonesVideo": "Disable everyone's camera",
|
||||
"muteGUMPending": "Connecting your microphone",
|
||||
"noAudioSignalDesc": "If you did not purposely mute it from system settings or hardware, consider switching the device.",
|
||||
"noAudioSignalDescSuggestion": "If you did not purposely mute it from system settings or hardware, consider switching to the suggested device.",
|
||||
"noAudioSignalDialInDesc": "You can also dial-in using:",
|
||||
@@ -1279,6 +1302,7 @@
|
||||
"unmute": "Unmute",
|
||||
"videoSettings": "Video settings",
|
||||
"videomute": "Stop camera",
|
||||
"videomuteGUMPending": "Connecting your camera",
|
||||
"videounmute": "Start camera"
|
||||
},
|
||||
"transcribing": {
|
||||
@@ -1325,7 +1349,7 @@
|
||||
"audioOnly": "AUD",
|
||||
"audioOnlyExpanded": "You are in low bandwidth mode. In this mode you will receive only audio and screen sharing.",
|
||||
"bestPerformance": "Best performance",
|
||||
"callQuality": "Video Quality",
|
||||
"callQuality": "Video Quality (0 for best performance, 3 for highest quality)",
|
||||
"hd": "HD",
|
||||
"hdTooltip": "Viewing high definition video",
|
||||
"highDefinition": "High definition",
|
||||
@@ -1367,6 +1391,10 @@
|
||||
"videomute": "Participant has stopped the camera"
|
||||
},
|
||||
"virtualBackground": {
|
||||
"accessibilityLabel": {
|
||||
"currentBackground": "Current background: {{background}}",
|
||||
"selectBackground": "Select a background"
|
||||
},
|
||||
"addBackground": "Add background",
|
||||
"apply": "Apply",
|
||||
"backgroundEffectError": "Failed to apply background effect.",
|
||||
|
||||
@@ -17,12 +17,13 @@ import { isEnabledFromState } from '../../react/features/av-moderation/functions
|
||||
import {
|
||||
endConference,
|
||||
sendTones,
|
||||
setAssumedBandwidthBps,
|
||||
setFollowMe,
|
||||
setLocalSubject,
|
||||
setPassword,
|
||||
setSubject
|
||||
} from '../../react/features/base/conference/actions';
|
||||
import { getCurrentConference } from '../../react/features/base/conference/functions';
|
||||
import { getCurrentConference, isP2pActive } from '../../react/features/base/conference/functions';
|
||||
import { overwriteConfig } from '../../react/features/base/config/actions';
|
||||
import { getWhitelistedJSON } from '../../react/features/base/config/functions.any';
|
||||
import { toggleDialog } from '../../react/features/base/dialog/actions';
|
||||
@@ -117,7 +118,6 @@ import { getJitsiMeetTransport } from '../transport';
|
||||
|
||||
import {
|
||||
API_ID,
|
||||
ASSUMED_BANDWIDTH_BPS,
|
||||
ENDPOINT_TEXT_MESSAGE_NAME
|
||||
} from './constants';
|
||||
|
||||
@@ -321,13 +321,7 @@ function initCommands() {
|
||||
return;
|
||||
}
|
||||
|
||||
const { conference } = APP.store.getState()['features/base/conference'];
|
||||
|
||||
if (conference) {
|
||||
conference.setAssumedBandwidthBps(value < ASSUMED_BANDWIDTH_BPS
|
||||
? ASSUMED_BANDWIDTH_BPS
|
||||
: value);
|
||||
}
|
||||
APP.store.dispatch(setAssumedBandwidthBps(value));
|
||||
},
|
||||
'set-follow-me': value => {
|
||||
logger.debug('Set follow me command received');
|
||||
@@ -342,15 +336,16 @@ function initCommands() {
|
||||
},
|
||||
'set-large-video-participant': (participantId, videoType) => {
|
||||
logger.debug('Set large video participant command received');
|
||||
const { getState, dispatch } = APP.store;
|
||||
|
||||
if (!participantId) {
|
||||
sendAnalytics(createApiEvent('largevideo.participant.set'));
|
||||
APP.store.dispatch(selectParticipantInLargeVideo());
|
||||
dispatch(selectParticipantInLargeVideo());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const state = APP.store.getState();
|
||||
const state = getState();
|
||||
const participant = videoType === VIDEO_TYPE.DESKTOP
|
||||
? getVirtualScreenshareParticipantByOwnerId(state, participantId)
|
||||
: getParticipantById(state, participantId);
|
||||
@@ -361,8 +356,9 @@ function initCommands() {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch(setTileView(false));
|
||||
sendAnalytics(createApiEvent('largevideo.participant.set'));
|
||||
APP.store.dispatch(selectParticipantInLargeVideo(participant.id));
|
||||
dispatch(selectParticipantInLargeVideo(participant.id));
|
||||
},
|
||||
'set-participant-volume': (participantId, volume) => {
|
||||
APP.store.dispatch(setVolume(participantId, volume));
|
||||
@@ -985,6 +981,10 @@ function initCommands() {
|
||||
callback(getRoomsInfo(APP.store.getState()));
|
||||
break;
|
||||
}
|
||||
case 'get-p2p-status': {
|
||||
callback(isP2pActive(APP.store.getState()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -2027,6 +2027,36 @@ class API {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) if non participant message
|
||||
* is received.
|
||||
*
|
||||
* @param {string} id - The resource id of the sender.
|
||||
* @param {Object} json - The json carried by the message.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyNonParticipantMessageReceived(id, json) {
|
||||
this._sendEvent({
|
||||
name: 'non-participant-message-received',
|
||||
id,
|
||||
message: json
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify the external application (if API is enabled) if the connection type changed.
|
||||
*
|
||||
* @param {boolean} isP2p - Whether the new connection is P2P.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyP2pStatusChanged(isP2p) {
|
||||
this._sendEvent({
|
||||
name: 'p2p-status-changed',
|
||||
isP2p
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the allocated resources.
|
||||
*
|
||||
|
||||
@@ -21,4 +21,4 @@ export const ENDPOINT_TEXT_MESSAGE_NAME = 'endpoint-text-message';
|
||||
* Setting it to this value means not assuming any bandwidth,
|
||||
* but rather allowing the estimations to take place.
|
||||
*/
|
||||
export const ASSUMED_BANDWIDTH_BPS = -1;
|
||||
export const MIN_ASSUMED_BANDWIDTH_BPS = -1;
|
||||
|
||||
14
modules/API/external/external_api.js
vendored
14
modules/API/external/external_api.js
vendored
@@ -128,8 +128,10 @@ const events = {
|
||||
'mouse-enter': 'mouseEnter',
|
||||
'mouse-leave': 'mouseLeave',
|
||||
'mouse-move': 'mouseMove',
|
||||
'non-participant-message-received': 'nonParticipantMessageReceived',
|
||||
'notification-triggered': 'notificationTriggered',
|
||||
'outgoing-message': 'outgoingMessage',
|
||||
'p2p-status-changed': 'p2pStatusChanged',
|
||||
'participant-joined': 'participantJoined',
|
||||
'participant-kicked-out': 'participantKickedOut',
|
||||
'participant-left': 'participantLeft',
|
||||
@@ -693,7 +695,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
this._numberOfParticipants = allParticipants;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the rooms info in the conference.
|
||||
*
|
||||
@@ -705,6 +706,17 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the conference is P2P.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
isP2pActive() {
|
||||
return this._transport.sendRequest({
|
||||
name: 'get-p2p-status'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds event listener to Meet Jitsi.
|
||||
*
|
||||
|
||||
@@ -15,7 +15,7 @@ const Filmstrip = {
|
||||
// horizontal film strip mode for calculating how tall large video
|
||||
// display should be.
|
||||
if (isFilmstripVisible(APP.store) && !interfaceConfig.VERTICAL_FILMSTRIP) {
|
||||
return document.querySelector('.filmstrip').offsetHeight;
|
||||
return document.querySelector('.filmstrip')?.offsetHeight ?? 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
270
package-lock.json
generated
270
package-lock.json
generated
@@ -15,9 +15,9 @@
|
||||
"@emotion/styled": "11.10.6",
|
||||
"@giphy/js-fetch-api": "4.7.1",
|
||||
"@giphy/react-components": "6.8.1",
|
||||
"@giphy/react-native-sdk": "1.7.0",
|
||||
"@giphy/react-native-sdk": "2.3.0",
|
||||
"@hapi/bourne": "2.0.0",
|
||||
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
|
||||
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
|
||||
"@jitsi/js-utils": "2.0.5",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/rnnoise-wasm": "0.1.0",
|
||||
@@ -60,7 +60,7 @@
|
||||
"js-md5": "0.6.1",
|
||||
"js-sha512": "0.8.0",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1635.0.0+152fdb21/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
@@ -71,10 +71,10 @@
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-emoji-render": "1.2.4",
|
||||
"react-focus-lock": "2.9.4",
|
||||
"react-focus-on": "3.8.1",
|
||||
"react-i18next": "10.11.4",
|
||||
"react-linkify": "1.0.0-alpha",
|
||||
"react-native": "0.69.10",
|
||||
"react-native": "0.69.11",
|
||||
"react-native-background-timer": "2.4.1",
|
||||
"react-native-calendar-events": "2.2.0",
|
||||
"react-native-callstats": "3.73.7",
|
||||
@@ -99,7 +99,7 @@
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
|
||||
"react-native-watch-connectivity": "1.0.11",
|
||||
"react-native-webrtc": "111.0.0",
|
||||
"react-native-webrtc": "111.0.1",
|
||||
"react-native-webview": "11.15.1",
|
||||
"react-native-youtube-iframe": "2.2.1",
|
||||
"react-redux": "7.1.0",
|
||||
@@ -127,6 +127,7 @@
|
||||
"@jitsi/eslint-config": "4.1.5",
|
||||
"@types/amplitude-js": "8.16.2",
|
||||
"@types/audioworklet": "0.0.29",
|
||||
"@types/dom-screen-wake-lock": "1.0.1",
|
||||
"@types/js-md5": "0.4.3",
|
||||
"@types/lodash": "4.14.182",
|
||||
"@types/punycode": "2.1.0",
|
||||
@@ -2924,12 +2925,12 @@
|
||||
"integrity": "sha512-GP6WDNWf+o403jrEp9c5jibKavrtLW+/qYGhFxFrG8maXhwTBI7gLLhiBb0o7uFccWN+EOS9aMO6cGHWAO07OA=="
|
||||
},
|
||||
"node_modules/@giphy/react-native-sdk": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@giphy/react-native-sdk/-/react-native-sdk-1.7.0.tgz",
|
||||
"integrity": "sha512-mCIqtPkDAstL+BDTbC1EQ4SiRkND3zd9uLKUeR4RkK2AhjRTUIheGzfxOZrdR014LVwcwKw5s9qpogoXr66mgw==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@giphy/react-native-sdk/-/react-native-sdk-2.3.0.tgz",
|
||||
"integrity": "sha512-hSCbgdi4Fptd1QwiZrhDhOuvy51HjWNOJE2Pa7/XkQ9NFSeu14N02m1Be2bXOhbN4kf/SptTzRzkMzn5U+IgmA==",
|
||||
"dependencies": {
|
||||
"@giphy/js-types": "^4.0.3",
|
||||
"type-fest": "^2.10.0"
|
||||
"@giphy/js-types": "^4.2.1",
|
||||
"type-fest": "^2.18.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "*",
|
||||
@@ -2937,9 +2938,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@giphy/react-native-sdk/node_modules/type-fest": {
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.12.1.tgz",
|
||||
"integrity": "sha512-AiknQSEqKVGDDjtZqeKrUoTlcj7FKhupmnVUgz6KoOKtvMwRGE6hUNJ/nVear+h7fnUPO1q/htSkYKb1pyntkQ==",
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
},
|
||||
@@ -3099,9 +3100,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@jitsi/excalidraw": {
|
||||
"version": "0.0.13",
|
||||
"resolved": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
|
||||
"integrity": "sha512-GcH+KwBTuE+3bdf73lS2X+TpVp/QFyXBHps8jntSWjz5UOfmXhF4SAoUe+550eVCHiZex78AaLaVflR34Lv0VA==",
|
||||
"version": "0.0.14",
|
||||
"resolved": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
|
||||
"integrity": "sha512-iK7p7i6qJFOkjTVZhWDvurDW1u+eMoOhAVgpab9CZEqCTX+W4Ih4AOPrUpf+mjaAHK5XqmQZSc5nVEpMg+xIGQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^17.0.2 || ^18.2.0",
|
||||
@@ -5583,6 +5584,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/dom-screen-wake-lock": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/dom-screen-wake-lock/-/dom-screen-wake-lock-1.0.1.tgz",
|
||||
"integrity": "sha512-WJQas3OFGcC8AeMzaa7FwzzbNNfanuV2R12kQYNp4BkUMghsRz5JxJ5RgVhJifhw7t0s6LvRSWZArmKbMDZ+5g==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/emscripten": {
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-0.0.34.tgz",
|
||||
@@ -6919,6 +6926,17 @@
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/aria-hidden": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
|
||||
"integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/arr-diff": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||
@@ -10633,6 +10651,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-nonce": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
|
||||
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
@@ -12742,8 +12768,8 @@
|
||||
},
|
||||
"node_modules/lib-jitsi-meet": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1635.0.0+152fdb21/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-zihPwmE0lO/dFKVQBO12w2ojJST6h/tpxT3ShyvKZUFUUAWa0MfFQx7HvuyEUAOjKmzeivFLSCsvGOyBMSbMqA==",
|
||||
"resolved": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-HtLhGkrSHEztTcMZ1iJmG7a5Bj8KvsT8bGL/h3G+4kro5JRp/E40XJPPWiaGT0e9av4RQZa4u1giSgF/50ssoQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
@@ -15574,6 +15600,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-focus-on": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.8.1.tgz",
|
||||
"integrity": "sha512-fQcBx+SZMgXoRL+69r5+ic4bdVgqaCeKeoFPra8yhcSuL/3unWavfdirEFBGgH71K+RiocMTS6DETHcX0SlOZg==",
|
||||
"dependencies": {
|
||||
"aria-hidden": "^1.2.2",
|
||||
"react-focus-lock": "^2.9.2",
|
||||
"react-remove-scroll": "^2.5.6",
|
||||
"react-style-singleton": "^2.2.0",
|
||||
"tslib": "^2.3.1",
|
||||
"use-callback-ref": "^1.3.0",
|
||||
"use-sidecar": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.5.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-freeze": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.0.tgz",
|
||||
@@ -15613,9 +15665,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native": {
|
||||
"version": "0.69.10",
|
||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.10.tgz",
|
||||
"integrity": "sha512-zBsJmFsjyx9zC0JDRH6F6hib3BWbIu65EYPsJBQMDHMSGJ9fL7C6ZV49O7Abockn/dbCHhIWpiSyCuda/bhV8g==",
|
||||
"version": "0.69.11",
|
||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.11.tgz",
|
||||
"integrity": "sha512-lYSzyDicrE5FLag+Vaq1XmPscQFKFqiUCsDMNkgd+wW9139u3hDEnbEWnXfM/kgF3vrKQUfyLMwfkuLV8EQfug==",
|
||||
"deprecated": "Issues and pull requests filed against this version are not supported. See the React Native release support policy to learn more: https://github.com/reactwg/react-native-releases#releases-support-policy",
|
||||
"dependencies": {
|
||||
"@jest/create-cache-key-function": "^27.0.1",
|
||||
"@react-native-community/cli": "^8.0.4",
|
||||
@@ -15975,9 +16028,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/react-native-webrtc": {
|
||||
"version": "111.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.0.tgz",
|
||||
"integrity": "sha512-eCvjPiU28cT85K8TBV7geAA92+uCldhmJ6F+3CMtAAG7U4AOQzxYOI5HC3h9Lt2zfTwsUzg3tyamqWf00PWndA==",
|
||||
"version": "111.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.1.tgz",
|
||||
"integrity": "sha512-yMRmLFtKRDXaK5b/s92+ArsMElEEjZnGW2cE+GqTHxLka0Kj0qq/sgNS2sMTuJuZRhW4oT6ryMLwTYzIrGM1lQ==",
|
||||
"dependencies": {
|
||||
"adm-zip": "0.5.9",
|
||||
"base64-js": "1.5.1",
|
||||
@@ -16100,6 +16153,51 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll": {
|
||||
"version": "2.5.6",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.6.tgz",
|
||||
"integrity": "sha512-bO856ad1uDYLefgArk559IzUNeQ6SWH4QnrevIUjH+GczV56giDfl3h0Idptf2oIKxQmd1p9BN25jleKodTALg==",
|
||||
"dependencies": {
|
||||
"react-remove-scroll-bar": "^2.3.4",
|
||||
"react-style-singleton": "^2.2.1",
|
||||
"tslib": "^2.1.0",
|
||||
"use-callback-ref": "^1.3.0",
|
||||
"use-sidecar": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-remove-scroll-bar": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz",
|
||||
"integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==",
|
||||
"dependencies": {
|
||||
"react-style-singleton": "^2.2.1",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-shallow-renderer": {
|
||||
"version": "16.15.0",
|
||||
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
|
||||
@@ -16112,6 +16210,28 @@
|
||||
"react": "^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-style-singleton": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
|
||||
"integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
|
||||
"dependencies": {
|
||||
"get-nonce": "^1.0.0",
|
||||
"invariant": "^2.2.4",
|
||||
"tslib": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/react-textarea-autosize": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz",
|
||||
@@ -21762,18 +21882,18 @@
|
||||
}
|
||||
},
|
||||
"@giphy/react-native-sdk": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/@giphy/react-native-sdk/-/react-native-sdk-1.7.0.tgz",
|
||||
"integrity": "sha512-mCIqtPkDAstL+BDTbC1EQ4SiRkND3zd9uLKUeR4RkK2AhjRTUIheGzfxOZrdR014LVwcwKw5s9qpogoXr66mgw==",
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@giphy/react-native-sdk/-/react-native-sdk-2.3.0.tgz",
|
||||
"integrity": "sha512-hSCbgdi4Fptd1QwiZrhDhOuvy51HjWNOJE2Pa7/XkQ9NFSeu14N02m1Be2bXOhbN4kf/SptTzRzkMzn5U+IgmA==",
|
||||
"requires": {
|
||||
"@giphy/js-types": "^4.0.3",
|
||||
"type-fest": "^2.10.0"
|
||||
"@giphy/js-types": "^4.2.1",
|
||||
"type-fest": "^2.18.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"type-fest": {
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.12.1.tgz",
|
||||
"integrity": "sha512-AiknQSEqKVGDDjtZqeKrUoTlcj7FKhupmnVUgz6KoOKtvMwRGE6hUNJ/nVear+h7fnUPO1q/htSkYKb1pyntkQ=="
|
||||
"version": "2.19.0",
|
||||
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
|
||||
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -21890,8 +22010,8 @@
|
||||
"dev": true
|
||||
},
|
||||
"@jitsi/excalidraw": {
|
||||
"version": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
|
||||
"integrity": "sha512-GcH+KwBTuE+3bdf73lS2X+TpVp/QFyXBHps8jntSWjz5UOfmXhF4SAoUe+550eVCHiZex78AaLaVflR34Lv0VA=="
|
||||
"version": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
|
||||
"integrity": "sha512-iK7p7i6qJFOkjTVZhWDvurDW1u+eMoOhAVgpab9CZEqCTX+W4Ih4AOPrUpf+mjaAHK5XqmQZSc5nVEpMg+xIGQ=="
|
||||
},
|
||||
"@jitsi/js-utils": {
|
||||
"version": "2.0.5",
|
||||
@@ -23649,6 +23769,12 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/dom-screen-wake-lock": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/dom-screen-wake-lock/-/dom-screen-wake-lock-1.0.1.tgz",
|
||||
"integrity": "sha512-WJQas3OFGcC8AeMzaa7FwzzbNNfanuV2R12kQYNp4BkUMghsRz5JxJ5RgVhJifhw7t0s6LvRSWZArmKbMDZ+5g==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/emscripten": {
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/emscripten/-/emscripten-0.0.34.tgz",
|
||||
@@ -24725,6 +24851,14 @@
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"aria-hidden": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.3.tgz",
|
||||
"integrity": "sha512-xcLxITLe2HYa1cnYnwCjkOO1PqUHQpozB8x9AR0OgWN2woOBi5kSDVxKfd0b7sb1hw5qFeJhXm9H1nu3xSfLeQ==",
|
||||
"requires": {
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"arr-diff": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
|
||||
@@ -27558,6 +27692,11 @@
|
||||
"has-symbols": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"get-nonce": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz",
|
||||
"integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="
|
||||
},
|
||||
"get-stream": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
|
||||
@@ -29128,8 +29267,8 @@
|
||||
}
|
||||
},
|
||||
"lib-jitsi-meet": {
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1635.0.0+152fdb21/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-zihPwmE0lO/dFKVQBO12w2ojJST6h/tpxT3ShyvKZUFUUAWa0MfFQx7HvuyEUAOjKmzeivFLSCsvGOyBMSbMqA==",
|
||||
"version": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
|
||||
"integrity": "sha512-HtLhGkrSHEztTcMZ1iJmG7a5Bj8KvsT8bGL/h3G+4kro5JRp/E40XJPPWiaGT0e9av4RQZa4u1giSgF/50ssoQ==",
|
||||
"requires": {
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
@@ -31274,6 +31413,20 @@
|
||||
"use-sidecar": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"react-focus-on": {
|
||||
"version": "3.8.1",
|
||||
"resolved": "https://registry.npmjs.org/react-focus-on/-/react-focus-on-3.8.1.tgz",
|
||||
"integrity": "sha512-fQcBx+SZMgXoRL+69r5+ic4bdVgqaCeKeoFPra8yhcSuL/3unWavfdirEFBGgH71K+RiocMTS6DETHcX0SlOZg==",
|
||||
"requires": {
|
||||
"aria-hidden": "^1.2.2",
|
||||
"react-focus-lock": "^2.9.2",
|
||||
"react-remove-scroll": "^2.5.6",
|
||||
"react-style-singleton": "^2.2.0",
|
||||
"tslib": "^2.3.1",
|
||||
"use-callback-ref": "^1.3.0",
|
||||
"use-sidecar": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"react-freeze": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.0.tgz",
|
||||
@@ -31303,9 +31456,9 @@
|
||||
}
|
||||
},
|
||||
"react-native": {
|
||||
"version": "0.69.10",
|
||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.10.tgz",
|
||||
"integrity": "sha512-zBsJmFsjyx9zC0JDRH6F6hib3BWbIu65EYPsJBQMDHMSGJ9fL7C6ZV49O7Abockn/dbCHhIWpiSyCuda/bhV8g==",
|
||||
"version": "0.69.11",
|
||||
"resolved": "https://registry.npmjs.org/react-native/-/react-native-0.69.11.tgz",
|
||||
"integrity": "sha512-lYSzyDicrE5FLag+Vaq1XmPscQFKFqiUCsDMNkgd+wW9139u3hDEnbEWnXfM/kgF3vrKQUfyLMwfkuLV8EQfug==",
|
||||
"requires": {
|
||||
"@jest/create-cache-key-function": "^27.0.1",
|
||||
"@react-native-community/cli": "^8.0.4",
|
||||
@@ -31573,9 +31726,9 @@
|
||||
}
|
||||
},
|
||||
"react-native-webrtc": {
|
||||
"version": "111.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.0.tgz",
|
||||
"integrity": "sha512-eCvjPiU28cT85K8TBV7geAA92+uCldhmJ6F+3CMtAAG7U4AOQzxYOI5HC3h9Lt2zfTwsUzg3tyamqWf00PWndA==",
|
||||
"version": "111.0.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-webrtc/-/react-native-webrtc-111.0.1.tgz",
|
||||
"integrity": "sha512-yMRmLFtKRDXaK5b/s92+ArsMElEEjZnGW2cE+GqTHxLka0Kj0qq/sgNS2sMTuJuZRhW4oT6ryMLwTYzIrGM1lQ==",
|
||||
"requires": {
|
||||
"adm-zip": "0.5.9",
|
||||
"base64-js": "1.5.1",
|
||||
@@ -31645,6 +31798,27 @@
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.4.3.tgz",
|
||||
"integrity": "sha512-Hwln1VNuGl/6bVwnd0Xdn1e84gT/8T9aYNL+HAKDArLCS7LWjwr7StE30IEYbIkx0Vi3vs+coQxe+SQDbGbbpA=="
|
||||
},
|
||||
"react-remove-scroll": {
|
||||
"version": "2.5.6",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.6.tgz",
|
||||
"integrity": "sha512-bO856ad1uDYLefgArk559IzUNeQ6SWH4QnrevIUjH+GczV56giDfl3h0Idptf2oIKxQmd1p9BN25jleKodTALg==",
|
||||
"requires": {
|
||||
"react-remove-scroll-bar": "^2.3.4",
|
||||
"react-style-singleton": "^2.2.1",
|
||||
"tslib": "^2.1.0",
|
||||
"use-callback-ref": "^1.3.0",
|
||||
"use-sidecar": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"react-remove-scroll-bar": {
|
||||
"version": "2.3.4",
|
||||
"resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz",
|
||||
"integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==",
|
||||
"requires": {
|
||||
"react-style-singleton": "^2.2.1",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"react-shallow-renderer": {
|
||||
"version": "16.15.0",
|
||||
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz",
|
||||
@@ -31654,6 +31828,16 @@
|
||||
"react-is": "^16.12.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"react-style-singleton": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
|
||||
"integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==",
|
||||
"requires": {
|
||||
"get-nonce": "^1.0.0",
|
||||
"invariant": "^2.2.4",
|
||||
"tslib": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"react-textarea-autosize": {
|
||||
"version": "8.3.0",
|
||||
"resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.0.tgz",
|
||||
|
||||
15
package.json
15
package.json
@@ -20,9 +20,9 @@
|
||||
"@emotion/styled": "11.10.6",
|
||||
"@giphy/js-fetch-api": "4.7.1",
|
||||
"@giphy/react-components": "6.8.1",
|
||||
"@giphy/react-native-sdk": "1.7.0",
|
||||
"@giphy/react-native-sdk": "2.3.0",
|
||||
"@hapi/bourne": "2.0.0",
|
||||
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.13/jitsi-excalidraw-0.0.13.tgz",
|
||||
"@jitsi/excalidraw": "https://github.com/jitsi/excalidraw/releases/download/v0.0.14/jitsi-excalidraw-0.0.14.tgz",
|
||||
"@jitsi/js-utils": "2.0.5",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/rnnoise-wasm": "0.1.0",
|
||||
@@ -65,7 +65,7 @@
|
||||
"js-md5": "0.6.1",
|
||||
"js-sha512": "0.8.0",
|
||||
"jwt-decode": "2.2.0",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1635.0.0+152fdb21/lib-jitsi-meet.tgz",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
@@ -76,10 +76,10 @@
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-emoji-render": "1.2.4",
|
||||
"react-focus-lock": "2.9.4",
|
||||
"react-focus-on": "3.8.1",
|
||||
"react-i18next": "10.11.4",
|
||||
"react-linkify": "1.0.0-alpha",
|
||||
"react-native": "0.69.10",
|
||||
"react-native": "0.69.11",
|
||||
"react-native-background-timer": "2.4.1",
|
||||
"react-native-calendar-events": "2.2.0",
|
||||
"react-native-callstats": "3.73.7",
|
||||
@@ -104,7 +104,7 @@
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
|
||||
"react-native-watch-connectivity": "1.0.11",
|
||||
"react-native-webrtc": "111.0.0",
|
||||
"react-native-webrtc": "111.0.1",
|
||||
"react-native-webview": "11.15.1",
|
||||
"react-native-youtube-iframe": "2.2.1",
|
||||
"react-redux": "7.1.0",
|
||||
@@ -132,6 +132,7 @@
|
||||
"@jitsi/eslint-config": "4.1.5",
|
||||
"@types/amplitude-js": "8.16.2",
|
||||
"@types/audioworklet": "0.0.29",
|
||||
"@types/dom-screen-wake-lock": "1.0.1",
|
||||
"@types/js-md5": "0.4.3",
|
||||
"@types/lodash": "4.14.182",
|
||||
"@types/punycode": "2.1.0",
|
||||
@@ -192,7 +193,7 @@
|
||||
"tsc:web": "tsc --noEmit --project tsconfig.web.json",
|
||||
"tsc:native": "tsc --noEmit --project tsconfig.native.json",
|
||||
"tsc:ci": "npm run tsc:web && npm run tsc:native",
|
||||
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 . && npm run tsc:ci && npm run lint:lang",
|
||||
"lint:ci": "eslint --ext .js,.ts,.tsx --max-warnings 0 .",
|
||||
"lint:lang": "for file in lang/*.json; do npx --yes jsonlint -q $file || exit 1; done",
|
||||
"lang-sort": "./resources/lang-sort.sh",
|
||||
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",
|
||||
|
||||
3
react-native-sdk/.npmrc
Normal file
3
react-native-sdk/.npmrc
Normal file
@@ -0,0 +1,3 @@
|
||||
package-lock=true
|
||||
; FIXME Set legacy-peer-deps=false when we upgrade RN.
|
||||
legacy-peer-deps=true
|
||||
48
react-native-sdk/README.md
Normal file
48
react-native-sdk/README.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# <p align="center">Jitsi Meet React Native SDK</p>
|
||||
|
||||
|
||||
## Installation
|
||||
Inside your project, run `npm i @jitsi/react-native-sdk`.<br/><br/>Additionally if not already installed, the following dependencies need to be added:
|
||||
<br/>`npm i @react-native-async-storage/async-storage react-native-webrtc`
|
||||
|
||||
[comment]: # (These deps definitely need to be added manually, more could be neccesary)
|
||||
|
||||
### iOS
|
||||
|
||||
#### Project Info.plist
|
||||
- Add a *Privacy - Camera Usage Description*
|
||||
- Add a *Privacy - Microphone Usage Description*
|
||||
|
||||
#### General
|
||||
- Signing & capabilites:
|
||||
- Add Background modes
|
||||
- Audio
|
||||
- Voice over IP
|
||||
- Background fetch
|
||||
- Add Copy Sounds step:
|
||||
|
||||
```
|
||||
SOUNDS_DIR="${PROJECT_DIR}/../node_modules/rnsdk/sounds"
|
||||
cp $SOUNDS_DIR/* ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/
|
||||
```
|
||||
#### Podfile
|
||||
- At the beginning of your target step add `pod 'ObjectiveDropboxOfficial', :modular_headers => true`
|
||||
|
||||
Run `cd ios && pod install && cd ..`
|
||||
|
||||
### Android
|
||||
|
||||
- In your build.gradle have at least `minSdkVersion = 24`
|
||||
- TODO: HOW TO ADD COPY SOUNDS STEP
|
||||
- Under the `</application>` tag of your AndroidManifest.xml make sure that it includes
|
||||
```
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
```
|
||||
|
||||
### TODOS
|
||||
- Ref ConnectionService to not rely on ReactInstanceHolder anymore
|
||||
- Add Copy Sounds step to build.gradle
|
||||
- Include copy sounds step in podspec (if possible)
|
||||
- Add ranges for dependencies
|
||||
- Add Build_Config for react native to AppInfoModule
|
||||
140
react-native-sdk/android/build.gradle
Normal file
140
react-native-sdk/android/build.gradle
Normal file
@@ -0,0 +1,140 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
}
|
||||
}
|
||||
|
||||
def isNewArchitectureEnabled() {
|
||||
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
apply plugin: 'com.facebook.react'
|
||||
}
|
||||
|
||||
def getExtOrDefault(name) {
|
||||
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['JitsiMeetReactNative_' + name]
|
||||
}
|
||||
|
||||
def getExtOrIntegerDefault(name) {
|
||||
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['JitsiMeetReactNative_' + name]).toInteger()
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
|
||||
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
|
||||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
}
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
disable 'GradleCompatible'
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
google()
|
||||
|
||||
def found = false
|
||||
def defaultDir = null
|
||||
def androidSourcesName = 'React Native sources'
|
||||
|
||||
if (rootProject.ext.has('reactNativeAndroidRoot')) {
|
||||
defaultDir = rootProject.ext.get('reactNativeAndroidRoot')
|
||||
} else {
|
||||
defaultDir = new File(
|
||||
projectDir,
|
||||
'/../../../node_modules/react-native/android'
|
||||
)
|
||||
}
|
||||
|
||||
if (defaultDir.exists()) {
|
||||
maven {
|
||||
url defaultDir.toString()
|
||||
name androidSourcesName
|
||||
}
|
||||
|
||||
logger.info(":${project.name}:reactNativeAndroidRoot ${defaultDir.canonicalPath}")
|
||||
found = true
|
||||
} else {
|
||||
def parentDir = rootProject.projectDir
|
||||
|
||||
1.upto(5, {
|
||||
if (found) return true
|
||||
parentDir = parentDir.parentFile
|
||||
|
||||
def androidSourcesDir = new File(
|
||||
parentDir,
|
||||
'node_modules/react-native'
|
||||
)
|
||||
|
||||
def androidPrebuiltBinaryDir = new File(
|
||||
parentDir,
|
||||
'node_modules/react-native/android'
|
||||
)
|
||||
|
||||
if (androidPrebuiltBinaryDir.exists()) {
|
||||
maven {
|
||||
url androidPrebuiltBinaryDir.toString()
|
||||
name androidSourcesName
|
||||
}
|
||||
|
||||
logger.info(":${project.name}:reactNativeAndroidRoot ${androidPrebuiltBinaryDir.canonicalPath}")
|
||||
found = true
|
||||
} else if (androidSourcesDir.exists()) {
|
||||
maven {
|
||||
url androidSourcesDir.toString()
|
||||
name androidSourcesName
|
||||
}
|
||||
|
||||
logger.info(":${project.name}:reactNativeAndroidRoot ${androidSourcesDir.canonicalPath}")
|
||||
found = true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
throw new GradleException(
|
||||
"${project.name}: unable to locate React Native android sources. " +
|
||||
"Ensure you have you installed React Native as a dependency in your project and try again."
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation "com.facebook.react:react-native:+"
|
||||
implementation 'com.squareup.duktape:duktape-android:1.3.0'
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
// From node_modules
|
||||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
react {
|
||||
jsRootDir = file("../src/")
|
||||
libraryName = "JitsiMeetReactNative"
|
||||
codegenJavaPackageName = "org.jitsi.meet.sdk"
|
||||
}
|
||||
}
|
||||
5
react-native-sdk/android/gradle.properties
Normal file
5
react-native-sdk/android/gradle.properties
Normal file
@@ -0,0 +1,5 @@
|
||||
JitsiMeetReactNative_kotlinVersion=1.7.0
|
||||
JitsiMeetReactNative_minSdkVersion=21
|
||||
JitsiMeetReactNative_targetSdkVersion=31
|
||||
JitsiMeetReactNative_compileSdkVersion=31
|
||||
JitsiMeetReactNative_ndkversion=21.4.7075529
|
||||
4
react-native-sdk/android/src/main/AndroidManifest.xml
Normal file
4
react-native-sdk/android/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.jitsi.meet.sdk">
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,39 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class JitsiMeetReactNativePackage implements ReactPackage {
|
||||
@NonNull
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules
|
||||
= new ArrayList<>(Arrays.<NativeModule>asList(
|
||||
new AndroidSettingsModule(reactContext),
|
||||
new AppInfoModule(reactContext),
|
||||
new AudioModeModule(reactContext),
|
||||
new JavaScriptSandboxModule(reactContext),
|
||||
new LocaleDetector(reactContext),
|
||||
new LogBridgeModule(reactContext),
|
||||
new PictureInPictureModule(reactContext),
|
||||
new ProximityModule(reactContext),
|
||||
new org.jitsi.meet.sdk.net.NAT64AddrInfoModule(reactContext)
|
||||
));
|
||||
return modules;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
99
react-native-sdk/components/JitsiMeet.tsx
Normal file
99
react-native-sdk/components/JitsiMeet.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
/* eslint-disable lines-around-comment, no-undef, no-unused-vars */
|
||||
|
||||
import 'react-native-gesture-handler';
|
||||
// Apply all necessary polyfills as early as possible
|
||||
// to make sure anything imported henceforth sees them.
|
||||
import 'react-native-get-random-values';
|
||||
import '../react/features/mobile/polyfills';
|
||||
|
||||
// @ts-ignore
|
||||
import React, { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
|
||||
import { View } from 'react-native';
|
||||
|
||||
import { convertPropsToURL } from '../functions';
|
||||
import { appNavigate } from '../react/features/app/actions.native';
|
||||
import { App } from '../react/features/app/components/App.native';
|
||||
import { setAudioMuted, setVideoMuted } from '../react/features/base/media/actions';
|
||||
// @ts-ignore
|
||||
import JitsiThemePaperProvider from '../react/features/base/ui/components/JitsiThemeProvider';
|
||||
|
||||
|
||||
interface IAppProps {
|
||||
flags: [];
|
||||
meetingOptions: {
|
||||
domain: string;
|
||||
roomName: string;
|
||||
onReadyToClose?: Function;
|
||||
onConferenceJoined?: Function;
|
||||
onConferenceWillJoin?: Function;
|
||||
onConferenceLeft?: Function;
|
||||
onParticipantJoined?: Function;
|
||||
settings?: {
|
||||
startWithAudioMuted?: boolean;
|
||||
startAudioOnly?: boolean;
|
||||
startWithVideoMuted?: boolean;
|
||||
}
|
||||
};
|
||||
style?: Object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main React Native SDK component that displays a Jitsi Meet conference and gets all required params as props
|
||||
*/
|
||||
const JitsiMeet = forwardRef(({ flags, meetingOptions, style }: IAppProps, ref) => {
|
||||
const [ appProps, setAppProps ] = useState({});
|
||||
const app = useRef(null);
|
||||
|
||||
// eslint-disable-next-line arrow-body-style
|
||||
useImperativeHandle(ref, () => ({
|
||||
close: () => {
|
||||
const dispatch = app.current.state.store.dispatch;
|
||||
|
||||
dispatch(appNavigate(undefined));
|
||||
},
|
||||
setAudioMuted: muted => {
|
||||
const dispatch = app.current.state.store.dispatch;
|
||||
|
||||
dispatch(setAudioMuted(muted));
|
||||
},
|
||||
setVideoMuted: muted => {
|
||||
const dispatch = app.current.state.store.dispatch;
|
||||
|
||||
dispatch(setVideoMuted(muted));
|
||||
}
|
||||
}));
|
||||
|
||||
useEffect(
|
||||
() => {
|
||||
const url = convertPropsToURL(meetingOptions.domain, meetingOptions.roomName);
|
||||
|
||||
setAppProps({
|
||||
'url': {
|
||||
url,
|
||||
config: meetingOptions.settings
|
||||
},
|
||||
'rnSdkHandlers': {
|
||||
onReadyToClose: meetingOptions.onReadyToClose,
|
||||
onConferenceJoined: meetingOptions.onConferenceJoined,
|
||||
onConferenceWillJoin: meetingOptions.onConferenceWillJoin,
|
||||
onConferenceLeft: meetingOptions.onConferenceLeft,
|
||||
onParticipantJoined: meetingOptions.onParticipantJoined
|
||||
},
|
||||
'flags': { ...flags }
|
||||
});
|
||||
}, []
|
||||
);
|
||||
|
||||
return (
|
||||
<View style = { style }>
|
||||
<JitsiThemePaperProvider>
|
||||
{/* @ts-ignore */}
|
||||
<App
|
||||
{ ...appProps }
|
||||
ref = { app } />
|
||||
</JitsiThemePaperProvider>
|
||||
</View>
|
||||
);
|
||||
});
|
||||
|
||||
export default JitsiMeet;
|
||||
7
react-native-sdk/constants.ts
Normal file
7
react-native-sdk/constants.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
module.exports = {
|
||||
androidSourcePath: '../android/sdk/src/main/java/org/jitsi/meet/sdk',
|
||||
androidTargetPath: './android/src/main/java/org/jitsi/meet/sdk',
|
||||
iosSrcPath: '../ios/sdk/src',
|
||||
iosDestPath: './ios/src'
|
||||
};
|
||||
8
react-native-sdk/functions.ts
Normal file
8
react-native-sdk/functions.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
/**
|
||||
* Converts the meetingOptions domain and roomName to a URL that can be passed to the App component.
|
||||
* @param {*} domain domain address from props.
|
||||
* @param {*} roomName room name from props.
|
||||
*/
|
||||
export function convertPropsToURL(domain, roomName) {
|
||||
return `${domain}/${roomName}`;
|
||||
}
|
||||
26
react-native-sdk/jitsi-meet-react-native.podspec
Normal file
26
react-native-sdk/jitsi-meet-react-native.podspec
Normal file
@@ -0,0 +1,26 @@
|
||||
require 'json'
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = package['name']
|
||||
s.version = package['version']
|
||||
s.summary = package['description']
|
||||
s.description = package['description']
|
||||
s.license = package['license']
|
||||
s.author = package['author']
|
||||
s.homepage = package['homepage']
|
||||
s.source = { :git => package['repository']['url'], :tag => s.version }
|
||||
|
||||
s.requires_arc = true
|
||||
s.platform = :ios, '12.4'
|
||||
|
||||
s.preserve_paths = 'ios/**/*'
|
||||
s.source_files = 'ios/**/*.{h,m,swift}'
|
||||
|
||||
|
||||
s.dependency 'React-Core'
|
||||
s.dependency 'ObjectiveDropboxOfficial', '6.2.3'
|
||||
s.dependency 'JitsiWebRTC', '~> 111.0.0'
|
||||
|
||||
end
|
||||
6075
react-native-sdk/package-lock.json
generated
Normal file
6075
react-native-sdk/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
107
react-native-sdk/package.json
Normal file
107
react-native-sdk/package.json
Normal file
@@ -0,0 +1,107 @@
|
||||
{
|
||||
"name": "@jitsi/react-native-sdk",
|
||||
"version": "0.1.0",
|
||||
"description": "React Native SDK for Jitsi Meet.",
|
||||
"main": "index.js",
|
||||
"license": "Apache-2.0",
|
||||
"author": "",
|
||||
"homepage": "https://jitsi.org",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jitsi/jitsi-meet.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amplitude/react-native": "2.7.0",
|
||||
"@giphy/react-components": "6.8.1",
|
||||
"@giphy/react-native-sdk": "2.3.0",
|
||||
"@hapi/bourne": "2.0.0",
|
||||
"@jitsi/js-utils": "2.0.5",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/rtcstats": "9.5.1",
|
||||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
|
||||
"@react-navigation/bottom-tabs": "6.5.3",
|
||||
"@react-navigation/elements": "1.3.13",
|
||||
"@react-navigation/material-top-tabs": "6.5.2",
|
||||
"@react-navigation/native": "6.1.2",
|
||||
"@react-navigation/stack": "6.3.11",
|
||||
"@xmldom/xmldom": "0.8.7",
|
||||
"base64-js": "1.3.1",
|
||||
"grapheme-splitter": "1.0.4",
|
||||
"i18n-iso-countries": "6.8.0",
|
||||
"i18next": "17.0.6",
|
||||
"i18next-browser-languagedetector": "3.0.1",
|
||||
"i18next-xhr-backend": "3.0.0",
|
||||
"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/v1643.0.0+0748d89a/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
"optional-require": "1.0.3",
|
||||
"promise.allsettled": "1.0.4",
|
||||
"punycode": "2.1.1",
|
||||
"react-emoji-render": "1.2.4",
|
||||
"react-i18next": "10.11.4",
|
||||
"react-linkify": "1.0.0-alpha",
|
||||
"react-redux": "7.1.0",
|
||||
"react-window": "1.8.6",
|
||||
"react-youtube": "10.1.0",
|
||||
"redux": "4.0.4",
|
||||
"redux-thunk": "2.4.1",
|
||||
"unorm": "1.6.0",
|
||||
"util": "0.12.1",
|
||||
"uuid": "8.3.2",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@react-native-async-storage/async-storage": "1.17.3",
|
||||
"@react-native-community/clipboard": "1.5.1",
|
||||
"@react-native-community/netinfo": "7.1.7",
|
||||
"@react-native-community/slider": "4.1.12",
|
||||
"@react-native-google-signin/google-signin": "7.0.4",
|
||||
"@react-native-masked-view/masked-view": "0.2.6",
|
||||
"react-native": "*",
|
||||
"react": "*",
|
||||
"react-dom": "*",
|
||||
"react-native-background-timer": "2.4.1",
|
||||
"react-native-calendar-events": "2.2.0",
|
||||
"react-native-callstats": "3.73.7",
|
||||
"react-native-collapsible": "1.6.0",
|
||||
"react-native-default-preference": "1.4.4",
|
||||
"react-native-device-info": "8.4.8",
|
||||
"react-native-dialog": "https://github.com/jitsi/react-native-dialog/releases/download/v9.2.2-jitsi.1/react-native-dialog-9.2.2.tgz",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
"react-native-keep-awake": "4.0.0",
|
||||
"react-native-pager-view": "5.4.9",
|
||||
"react-native-paper": "4.11.1",
|
||||
"react-native-performance": "2.1.0",
|
||||
"react-native-orientation-locker": "1.5.0",
|
||||
"react-native-sound": "0.11.1",
|
||||
"react-native-splash-screen": "3.3.0",
|
||||
"react-native-svg": "12.4.3",
|
||||
"react-native-svg-transformer": "1.0.0",
|
||||
"react-native-tab-view": "3.1.1",
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-video": "https://git@github.com/react-native-video/react-native-video#7c48ae7c8544b2b537fb60194e9620b9fcceae52",
|
||||
"react-native-watch-connectivity": "1.0.11",
|
||||
"react-native-webrtc": "111.0.0",
|
||||
"react-native-webview": "11.15.1",
|
||||
"react-native-youtube-iframe": "2.2.1"
|
||||
},
|
||||
"overrides": {
|
||||
"strophe.js@1.5.0": {
|
||||
"@xmldom/xmldom": "0.8.7"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"prepare": "node prepare_sdk.js"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jitsi/jitsi-meet/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"react-native"
|
||||
]
|
||||
}
|
||||
214
react-native-sdk/prepare_sdk.js
vendored
Normal file
214
react-native-sdk/prepare_sdk.js
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const packageJSON = require('../package.json');
|
||||
|
||||
const {
|
||||
androidSourcePath,
|
||||
androidTargetPath,
|
||||
iosDestPath,
|
||||
iosSrcPath
|
||||
} = require('./constants.ts');
|
||||
const SDKPackageJSON = require('./package.json');
|
||||
|
||||
|
||||
/**
|
||||
* Copies a specified file in a way that recursive copy is possible.
|
||||
*/
|
||||
function copyFileSync(source, target) {
|
||||
|
||||
let targetFile = target;
|
||||
|
||||
// If target is a directory, a new file with the same name will be created
|
||||
if (fs.existsSync(target)) {
|
||||
if (fs.lstatSync(target).isDirectory()) {
|
||||
targetFile = path.join(target, path.basename(source));
|
||||
}
|
||||
}
|
||||
|
||||
fs.copyFileSync(source, targetFile);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copies a specified directory recursively.
|
||||
*/
|
||||
function copyFolderRecursiveSync(source, target) {
|
||||
let files = [];
|
||||
const targetFolder = path.join(target, path.basename(source));
|
||||
|
||||
if (!fs.existsSync(targetFolder)) {
|
||||
fs.mkdirSync(targetFolder, { recursive: true });
|
||||
}
|
||||
|
||||
if (fs.lstatSync(source).isDirectory()) {
|
||||
files = fs.readdirSync(source);
|
||||
files.forEach(file => {
|
||||
const curSource = path.join(source, file);
|
||||
|
||||
if (fs.lstatSync(curSource).isDirectory()) {
|
||||
copyFolderRecursiveSync(curSource, targetFolder);
|
||||
} else {
|
||||
copyFileSync(curSource, targetFolder);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges the dependency versions from the root package.json with the dependencies of the SDK package.json.
|
||||
*/
|
||||
function mergeDependencyVersions() {
|
||||
for (const key in SDKPackageJSON.dependencies) {
|
||||
if (SDKPackageJSON.dependencies.hasOwnProperty(key)) {
|
||||
SDKPackageJSON.dependencies[key] = packageJSON.dependencies[key] || packageJSON.devDependencies[key];
|
||||
}
|
||||
}
|
||||
const data = JSON.stringify(SDKPackageJSON, null, 4);
|
||||
|
||||
fs.writeFileSync('package.json', data);
|
||||
}
|
||||
|
||||
// TODO: put this in a seperate step
|
||||
mergeDependencyVersions();
|
||||
|
||||
copyFolderRecursiveSync(
|
||||
'../images',
|
||||
'.'
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../sounds',
|
||||
'.'
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../lang',
|
||||
'.'
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../modules',
|
||||
'.'
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../react',
|
||||
'.'
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../service',
|
||||
'.'
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../ios/sdk/sdk.xcodeproj',
|
||||
'./ios'
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
`${iosSrcPath}/callkit`,
|
||||
iosDestPath
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
`${iosSrcPath}/dropbox`,
|
||||
iosDestPath
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
'../ios/sdk/src/picture-in-picture',
|
||||
iosDestPath
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/AppInfo.m`,
|
||||
`${iosDestPath}/AppInfo.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/AudioMode.m`,
|
||||
`${iosDestPath}/AudioMode.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/InfoPlistUtil.m`,
|
||||
`${iosDestPath}/InfoPlistUtil.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/InfoPlistUtil.h`,
|
||||
`${iosDestPath}/InfoPlistUtil.h`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/JavaScriptSandbox.m`,
|
||||
`${iosDestPath}/JavaScriptSandbox.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/JitsiAudioSession.m`,
|
||||
`${iosDestPath}/JitsiAudioSession.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/JitsiAudioSession.h`,
|
||||
`${iosDestPath}/JitsiAudioSession.h`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/JitsiAudioSession+Private.h`,
|
||||
`${iosDestPath}/JitsiAudioSession+Private.h`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/LocaleDetector.m`,
|
||||
`${iosDestPath}/LocaleDetector.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/POSIX.m`,
|
||||
`${iosDestPath}/POSIX.m`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${iosSrcPath}/Proximity.m`,
|
||||
`${iosDestPath}/Proximity.m`
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
`${androidSourcePath}/log`,
|
||||
`${androidTargetPath}/log`
|
||||
);
|
||||
copyFolderRecursiveSync(
|
||||
`${androidSourcePath}/net`,
|
||||
`${androidTargetPath}/log`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/AndroidSettingsModule.java`,
|
||||
`${androidTargetPath}/AndroidSettingsModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/AppInfoModule.java`,
|
||||
`${androidTargetPath}/AppInfoModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/AudioDeviceHandlerConnectionService.java`,
|
||||
`${androidTargetPath}/AudioDeviceHandlerConnectionService.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/AudioDeviceHandlerGeneric.java`,
|
||||
`${androidTargetPath}/AudioDeviceHandlerGeneric.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/AudioModeModule.java`,
|
||||
`${androidTargetPath}/AudioModeModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/ConnectionService.java`,
|
||||
`${androidTargetPath}/ConnectionService.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/JavaScriptSandboxModule.java`,
|
||||
`${androidTargetPath}/JavaScriptSandboxModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/LocaleDetector.java`,
|
||||
`${androidTargetPath}/LocaleDetector.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/LogBridgeModule.java`,
|
||||
`${androidTargetPath}/LogBridgeModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/PictureInPictureModule.java`,
|
||||
`${androidTargetPath}/PictureInPictureModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/ProximityModule.java`,
|
||||
`${androidTargetPath}/ProximityModule.java`
|
||||
);
|
||||
fs.copyFileSync(
|
||||
`${androidSourcePath}/RNConnectionService.java`,
|
||||
`${androidTargetPath}/RNConnectionService.java`
|
||||
);
|
||||
@@ -173,7 +173,15 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
|
||||
const { group, server } = state['features/base/jwt'];
|
||||
const { locationURL = { href: '' } } = state['features/base/connection'];
|
||||
const { tenant } = parseURIString(locationURL.href) || {};
|
||||
const permanentProperties: any = {};
|
||||
const permanentProperties: {
|
||||
appName?: string;
|
||||
externalApi?: boolean;
|
||||
group?: string;
|
||||
inIframe?: boolean;
|
||||
server?: string;
|
||||
tenant?: string;
|
||||
websocket?: boolean;
|
||||
} & typeof deploymentInfo = {};
|
||||
|
||||
if (server) {
|
||||
permanentProperties.server = server;
|
||||
@@ -202,7 +210,8 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
|
||||
if (deploymentInfo) {
|
||||
for (const key in deploymentInfo) {
|
||||
if (deploymentInfo.hasOwnProperty(key)) {
|
||||
permanentProperties[key] = deploymentInfo[key as keyof typeof deploymentInfo];
|
||||
permanentProperties[key as keyof typeof deploymentInfo] = deploymentInfo[
|
||||
key as keyof typeof deploymentInfo];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +244,7 @@ export function initAnalytics(store: IStore, handlers: Array<Object>) {
|
||||
* @returns {Promise} Resolves with the handlers that have been successfully loaded and rejects if there are no handlers
|
||||
* loaded or the analytics is disabled.
|
||||
*/
|
||||
function _loadHandlers(scriptURLs: any[] = [], handlerConstructorOptions: Object) {
|
||||
function _loadHandlers(scriptURLs: string[] = [], handlerConstructorOptions: Object) {
|
||||
const promises: Promise<{ error?: Error; type: string; url?: string; }>[] = [];
|
||||
|
||||
for (const url of scriptURLs) {
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Amplitude } from '@amplitude/react-native';
|
||||
import DefaultPreference from 'react-native-default-preference';
|
||||
import DeviceInfo from 'react-native-device-info';
|
||||
|
||||
@@ -7,7 +8,7 @@ import DeviceInfo from 'react-native-device-info';
|
||||
* @param {AmplitudeClient} amplitude - The amplitude instance.
|
||||
* @returns {void}
|
||||
*/
|
||||
export async function fixDeviceID(amplitude: any) {
|
||||
export async function fixDeviceID(amplitude: Amplitude) {
|
||||
await DefaultPreference.setName('jitsi-preferences');
|
||||
|
||||
const current = await DefaultPreference.get('amplitudeDeviceId');
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { AmplitudeClient } from 'amplitude-js';
|
||||
|
||||
/**
|
||||
* Custom logic for setting the correct device id.
|
||||
*
|
||||
* @param {AmplitudeClient} _amplitude - The amplitude instance.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function fixDeviceID(_amplitude: any): Promise<any> {
|
||||
export function fixDeviceID(_amplitude: AmplitudeClient): Promise<any> {
|
||||
return new Promise(resolve => resolve(true));
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ import {
|
||||
import {
|
||||
createFakeConfig,
|
||||
restoreConfig
|
||||
} from '../base/config/functions';
|
||||
import { connect, disconnect, setLocationURL } from '../base/connection/actions';
|
||||
} from '../base/config/functions.native';
|
||||
import { connect, disconnect, setLocationURL } from '../base/connection/actions.native';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet/functions.native';
|
||||
import { createDesiredLocalTracks } from '../base/tracks/actions';
|
||||
import { createDesiredLocalTracks } from '../base/tracks/actions.native';
|
||||
import isInsecureRoomName from '../base/util/isInsecureRoomName';
|
||||
import { parseURLParams } from '../base/util/parseURLParams';
|
||||
import {
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
} from '../mobile/navigation/rootNavigationContainerRef';
|
||||
import { screen } from '../mobile/navigation/routes';
|
||||
import { clearNotifications } from '../notifications/actions';
|
||||
import { isUnsafeRoomWarningEnabled } from '../prejoin/functions';
|
||||
|
||||
import { addTrackStateToURL, getDefaultURL } from './functions.native';
|
||||
import logger from './logger';
|
||||
@@ -137,7 +138,7 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
|
||||
dispatch(setRoom(room));
|
||||
|
||||
if (room) {
|
||||
if (isInsecureRoomName(room)) {
|
||||
if (isUnsafeRoomWarningEnabled(getState()) && isInsecureRoomName(room)) {
|
||||
navigateRoot(screen.unsafeRoomWarning);
|
||||
|
||||
return;
|
||||
|
||||
@@ -12,7 +12,7 @@ export interface IProps {
|
||||
* XXX Refer to the implementation of loadURLObject: in
|
||||
* ios/sdk/src/JitsiMeetView.m for further information.
|
||||
*/
|
||||
timestamp: any;
|
||||
timestamp: number;
|
||||
|
||||
/**
|
||||
* The URL, if any, with which the app was launched.
|
||||
|
||||
@@ -42,7 +42,7 @@ export class App extends AbstractApp {
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
_createMainElement(component: React.ComponentType, props: any) {
|
||||
_createMainElement(component: React.ComponentType, props?: Object) {
|
||||
return (
|
||||
<JitsiThemeProvider>
|
||||
<GlobalStyles />
|
||||
|
||||
@@ -10,6 +10,7 @@ import '../mobile/navigation/middleware';
|
||||
import '../mobile/permissions/middleware';
|
||||
import '../mobile/proximity/middleware';
|
||||
import '../mobile/wake-lock/middleware';
|
||||
import '../mobile/react-native-sdk/middleware';
|
||||
import '../mobile/watchos/middleware';
|
||||
import '../share-room/middleware';
|
||||
import '../shared-video/middleware';
|
||||
|
||||
@@ -203,7 +203,7 @@ class LoginDialog extends Component<IProps, IState> {
|
||||
t
|
||||
} = this.props;
|
||||
const { username, password } = this.state;
|
||||
const messageOptions: any = {};
|
||||
const messageOptions: { msg?: string; } = {};
|
||||
let messageKey;
|
||||
|
||||
if (progress && progress < 1) {
|
||||
@@ -268,6 +268,7 @@ class LoginDialog extends Component<IProps, IState> {
|
||||
titleKey = { t('dialog.authenticationRequired') }>
|
||||
<Input
|
||||
autoFocus = { true }
|
||||
id = 'login-dialog-username'
|
||||
label = { t('dialog.user') }
|
||||
name = 'username'
|
||||
onChange = { this._onUsernameChange }
|
||||
@@ -277,6 +278,7 @@ class LoginDialog extends Component<IProps, IState> {
|
||||
<br />
|
||||
<Input
|
||||
className = 'dialog-bottom-margin'
|
||||
id = 'login-dialog-password'
|
||||
label = { t('dialog.userPassword') }
|
||||
name = 'password'
|
||||
onChange = { this._onPasswordChange }
|
||||
|
||||
@@ -48,6 +48,7 @@ import {
|
||||
ASKED_TO_UNMUTE_NOTIFICATION_ID,
|
||||
ASKED_TO_UNMUTE_SOUND_ID,
|
||||
AUDIO_MODERATION_NOTIFICATION_ID,
|
||||
CS_MODERATION_NOTIFICATION_ID,
|
||||
VIDEO_MODERATION_NOTIFICATION_ID
|
||||
} from './constants';
|
||||
import {
|
||||
@@ -88,6 +89,11 @@ MiddlewareRegistry.register(({ dispatch, getState }) => next => action => {
|
||||
uid = VIDEO_MODERATION_NOTIFICATION_ID;
|
||||
break;
|
||||
}
|
||||
case MEDIA_TYPE.SCREENSHARE: {
|
||||
titleKey = 'notify.moderationInEffectCSTitle';
|
||||
uid = CS_MODERATION_NOTIFICATION_ID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch(showNotification({
|
||||
|
||||
@@ -239,7 +239,7 @@ class Avatar<P extends IProps> extends PureComponent<P, IState> {
|
||||
* @param {boolean} params.dontRetry - If false we will retry to load the Avatar with different CORS mode.
|
||||
* @returns {void}
|
||||
*/
|
||||
_onAvatarLoadError(params: any = {}) {
|
||||
_onAvatarLoadError(params: { dontRetry?: boolean; } = {}) {
|
||||
const { dontRetry = false } = params;
|
||||
|
||||
if (Boolean(this.props.useCORS) === this.state.isUsingCORS && !dontRetry) {
|
||||
|
||||
@@ -57,6 +57,14 @@ let mounted: boolean;
|
||||
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* The invisible text for screen readers.
|
||||
*
|
||||
* Intended to give the same info as `displayedText`, but can be customized to give more necessary context.
|
||||
* If not given, `displayedText` will be used.
|
||||
*/
|
||||
accessibilityText?: string;
|
||||
|
||||
/**
|
||||
* Css class to apply on container.
|
||||
*/
|
||||
@@ -93,7 +101,15 @@ interface IProps {
|
||||
*
|
||||
* @returns {React$Element<any>}
|
||||
*/
|
||||
function CopyButton({ className = '', displayedText, textToCopy, textOnHover, textOnCopySuccess, id }: IProps) {
|
||||
function CopyButton({
|
||||
accessibilityText,
|
||||
className = '',
|
||||
displayedText,
|
||||
textToCopy,
|
||||
textOnHover,
|
||||
textOnCopySuccess,
|
||||
id
|
||||
}: IProps) {
|
||||
const { classes, cx } = useStyles();
|
||||
const [ isClicked, setIsClicked ] = useState(false);
|
||||
const [ isHovered, setIsHovered ] = useState(false);
|
||||
@@ -196,20 +212,33 @@ function CopyButton({ className = '', displayedText, textToCopy, textOnHover, te
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-label = { textOnHover }
|
||||
className = { cx(className, classes.copyButton, isClicked ? ' clicked' : '') }
|
||||
id = { id }
|
||||
onBlur = { onHoverOut }
|
||||
onClick = { onClick }
|
||||
onFocus = { onHoverIn }
|
||||
onKeyPress = { onKeyPress }
|
||||
onMouseOut = { onHoverOut }
|
||||
onMouseOver = { onHoverIn }
|
||||
role = 'button'
|
||||
tabIndex = { 0 }>
|
||||
{ renderContent() }
|
||||
</div>
|
||||
<>
|
||||
<div
|
||||
aria-describedby = { displayedText === textOnHover
|
||||
? undefined
|
||||
: `${id}-sr-text` }
|
||||
aria-label = { displayedText === textOnHover ? accessibilityText : textOnHover }
|
||||
className = { cx(className, classes.copyButton, isClicked ? ' clicked' : '') }
|
||||
id = { id }
|
||||
onBlur = { onHoverOut }
|
||||
onClick = { onClick }
|
||||
onFocus = { onHoverIn }
|
||||
onKeyPress = { onKeyPress }
|
||||
onMouseOut = { onHoverOut }
|
||||
onMouseOver = { onHoverIn }
|
||||
role = 'button'
|
||||
tabIndex = { 0 }>
|
||||
{ renderContent() }
|
||||
</div>
|
||||
|
||||
{ displayedText !== textOnHover && (
|
||||
<span
|
||||
className = 'sr-only'
|
||||
id = { `${id}-sr-text` }>
|
||||
{ accessibilityText }
|
||||
</span>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -295,3 +295,13 @@ export const SET_ROOM = 'SET_ROOM';
|
||||
* }
|
||||
*/
|
||||
export const SET_START_MUTED_POLICY = 'SET_START_MUTED_POLICY';
|
||||
|
||||
/**
|
||||
* The type of (redux) action which updates the assumed bandwidth bps.
|
||||
*
|
||||
* {
|
||||
* type: SET_ASSUMED_BANDWIDTH_BPS,
|
||||
* assumedBandwidthBps: number
|
||||
* }
|
||||
*/
|
||||
export const SET_ASSUMED_BANDWIDTH_BPS = 'SET_ASSUMED_BANDWIDTH_BPS';
|
||||
|
||||
@@ -51,6 +51,7 @@ import {
|
||||
NON_PARTICIPANT_MESSAGE_RECEIVED,
|
||||
P2P_STATUS_CHANGED,
|
||||
SEND_TONES,
|
||||
SET_ASSUMED_BANDWIDTH_BPS,
|
||||
SET_FOLLOW_ME,
|
||||
SET_OBFUSCATED_ROOM,
|
||||
SET_PASSWORD,
|
||||
@@ -956,3 +957,20 @@ export function setLocalSubject(localSubject: string) {
|
||||
localSubject
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the assumed bandwidth bps.
|
||||
*
|
||||
* @param {number} assumedBandwidthBps - The new assumed bandwidth.
|
||||
* @returns {{
|
||||
* type: SET_ASSUMED_BANDWIDTH_BPS,
|
||||
* assumedBandwidthBps: number
|
||||
* }}
|
||||
*/
|
||||
export function setAssumedBandwidthBps(assumedBandwidthBps: number) {
|
||||
return {
|
||||
type: SET_ASSUMED_BANDWIDTH_BPS,
|
||||
assumedBandwidthBps
|
||||
};
|
||||
}
|
||||
|
||||
@@ -388,6 +388,24 @@ export function getCurrentConference(stateful: IStateful): IJitsiConference | un
|
||||
return joining || passwordRequired || membersOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current conference is a P2P connection.
|
||||
* Will return `false` if it's a JVB one, and `null` if there is no conference.
|
||||
*
|
||||
* @param {IStateful} stateful - The redux store, state, or
|
||||
* {@code getState} function.
|
||||
* @returns {boolean|null}
|
||||
*/
|
||||
export function isP2pActive(stateful: IStateful): boolean | null {
|
||||
const conference = getCurrentConference(toState(stateful));
|
||||
|
||||
if (!conference) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return conference.isP2PActive();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stored room name.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
// @ts-ignore
|
||||
import { MIN_ASSUMED_BANDWIDTH_BPS } from '../../../../modules/API/constants';
|
||||
import {
|
||||
ACTION_PINNED,
|
||||
ACTION_UNPINNED,
|
||||
@@ -37,7 +39,9 @@ import {
|
||||
CONFERENCE_JOINED,
|
||||
CONFERENCE_SUBJECT_CHANGED,
|
||||
CONFERENCE_WILL_LEAVE,
|
||||
P2P_STATUS_CHANGED,
|
||||
SEND_TONES,
|
||||
SET_ASSUMED_BANDWIDTH_BPS,
|
||||
SET_PENDING_SUBJECT_CHANGE,
|
||||
SET_ROOM
|
||||
} from './actionTypes';
|
||||
@@ -96,6 +100,9 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
_conferenceWillLeave(store);
|
||||
break;
|
||||
|
||||
case P2P_STATUS_CHANGED:
|
||||
return _p2pStatusChanged(next, action);
|
||||
|
||||
case PARTICIPANT_UPDATED:
|
||||
return _updateLocalParticipantInConference(store, next, action);
|
||||
|
||||
@@ -111,6 +118,9 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
case TRACK_ADDED:
|
||||
case TRACK_REMOVED:
|
||||
return _trackAddedOrRemoved(store, next, action);
|
||||
|
||||
case SET_ASSUMED_BANDWIDTH_BPS:
|
||||
return _setAssumedBandwidthBps(store, next, action);
|
||||
}
|
||||
|
||||
return next(action);
|
||||
@@ -665,3 +675,54 @@ function _updateLocalParticipantInConference({ dispatch, getState }: IStore, nex
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the external API that the action {@code P2P_STATUS_CHANGED}
|
||||
* is being dispatched within a specific redux store.
|
||||
*
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
|
||||
* specified {@code action} to the specified {@code store}.
|
||||
* @param {Action} action - The redux action {@code P2P_STATUS_CHANGED}
|
||||
* which is being dispatched in the specified {@code store}.
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _p2pStatusChanged(next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
|
||||
if (typeof APP !== 'undefined') {
|
||||
APP.API.notifyP2pStatusChanged(action.p2p);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies the feature base/conference that the action
|
||||
* {@code SET_ASSUMED_BANDWIDTH_BPS} is being dispatched within a specific
|
||||
* redux store.
|
||||
*
|
||||
* @param {Store} store - The redux store in which the specified {@code action}
|
||||
* is being dispatched.
|
||||
* @param {Dispatch} next - The redux {@code dispatch} function to dispatch the
|
||||
* specified {@code action} to the specified {@code store}.
|
||||
* @param {Action} action - The redux action {@code SET_ASSUMED_BANDWIDTH_BPS}
|
||||
* which is being dispatched in the specified {@code store}.
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _setAssumedBandwidthBps({ getState }: IStore, next: Function, action: AnyAction) {
|
||||
const state = getState();
|
||||
const conference = getCurrentConference(state);
|
||||
const payload = Number(action.assumedBandwidthBps);
|
||||
|
||||
const assumedBandwidthBps = isNaN(payload) || payload < MIN_ASSUMED_BANDWIDTH_BPS
|
||||
? MIN_ASSUMED_BANDWIDTH_BPS
|
||||
: payload;
|
||||
|
||||
if (conference) {
|
||||
conference.setAssumedBandwidthBps(assumedBandwidthBps);
|
||||
}
|
||||
|
||||
return next(action);
|
||||
}
|
||||
|
||||
@@ -5,9 +5,82 @@ import {
|
||||
import { JitsiConferenceErrors } from '../lib-jitsi-meet';
|
||||
import MiddlewareRegistry from '../redux/MiddlewareRegistry';
|
||||
|
||||
import { CONFERENCE_FAILED, CONFERENCE_JOINED, CONFERENCE_JOIN_IN_PROGRESS } from './actionTypes';
|
||||
import {
|
||||
CONFERENCE_FAILED,
|
||||
CONFERENCE_JOINED,
|
||||
CONFERENCE_JOIN_IN_PROGRESS,
|
||||
CONFERENCE_LEFT, KICKED_OUT
|
||||
} from './actionTypes';
|
||||
import logger from './logger';
|
||||
import './middleware.any';
|
||||
|
||||
let screenLock: WakeLockSentinel | undefined;
|
||||
|
||||
/**
|
||||
* Releases the screen lock.
|
||||
*
|
||||
* @returns {Promise}
|
||||
*/
|
||||
async function releaseScreenLock() {
|
||||
if (screenLock) {
|
||||
if (!screenLock.released) {
|
||||
logger.debug('Releasing wake lock.');
|
||||
|
||||
try {
|
||||
await screenLock.release();
|
||||
} catch (e) {
|
||||
logger.error(`Error while releasing the screen wake lock: ${e}.`);
|
||||
}
|
||||
}
|
||||
screenLock.removeEventListener('release', onWakeLockReleased);
|
||||
screenLock = undefined;
|
||||
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests a new screen wake lock.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function requestWakeLock() {
|
||||
if (navigator.wakeLock?.request) {
|
||||
navigator.wakeLock.request('screen')
|
||||
.then(lock => {
|
||||
screenLock = lock;
|
||||
screenLock.addEventListener('release', onWakeLockReleased);
|
||||
document.addEventListener('visibilitychange', handleVisibilityChange);
|
||||
logger.debug('Wake lock created.');
|
||||
})
|
||||
.catch(e => {
|
||||
logger.error(`Error while requesting wake lock for screen: ${e}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Page visibility change handler that re-requests the wake lock if it has been released by the OS.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
async function handleVisibilityChange() {
|
||||
if (screenLock?.released && document.visibilityState === 'visible') {
|
||||
// The screen lock have been released by the OS because of document visibility change. Lets try to request the
|
||||
// wake lock again.
|
||||
await releaseScreenLock();
|
||||
requestWakeLock();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wake lock released handler.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
function onWakeLockReleased() {
|
||||
logger.debug('Wake lock released');
|
||||
}
|
||||
|
||||
MiddlewareRegistry.register(store => next => action => {
|
||||
const { dispatch, getState } = store;
|
||||
const { enableForcedReload } = getState()['features/base/config'];
|
||||
@@ -23,6 +96,8 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
dispatch(setSkipPrejoinOnReload(false));
|
||||
}
|
||||
|
||||
requestWakeLock();
|
||||
|
||||
break;
|
||||
}
|
||||
case CONFERENCE_FAILED: {
|
||||
@@ -32,8 +107,15 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
dispatch(setSkipPrejoinOnReload(true));
|
||||
}
|
||||
|
||||
releaseScreenLock();
|
||||
|
||||
break;
|
||||
}
|
||||
case CONFERENCE_LEFT:
|
||||
case KICKED_OUT:
|
||||
releaseScreenLock();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return next(action);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { FaceLandmarks } from '../../face-landmarks/types';
|
||||
import { LOCKED_LOCALLY, LOCKED_REMOTELY } from '../../room-lock/constants';
|
||||
import { ISpeakerStats } from '../../speaker-stats/reducer';
|
||||
@@ -18,6 +20,7 @@ import {
|
||||
CONFERENCE_WILL_LEAVE,
|
||||
LOCK_STATE_CHANGED,
|
||||
P2P_STATUS_CHANGED,
|
||||
SET_ASSUMED_BANDWIDTH_BPS,
|
||||
SET_FOLLOW_ME,
|
||||
SET_OBFUSCATED_ROOM,
|
||||
SET_PASSWORD,
|
||||
@@ -29,6 +32,7 @@ import {
|
||||
import { isRoomValid } from './functions';
|
||||
|
||||
const DEFAULT_STATE = {
|
||||
assumedBandwidthBps: undefined,
|
||||
conference: undefined,
|
||||
e2eeSupported: undefined,
|
||||
joining: undefined,
|
||||
@@ -73,6 +77,7 @@ export interface IJitsiConference {
|
||||
isE2EESupported: Function;
|
||||
isEndConferenceSupported: Function;
|
||||
isLobbySupported: Function;
|
||||
isP2PActive: Function;
|
||||
isSIPCallingSupported: Function;
|
||||
isStartAudioMuted: Function;
|
||||
isStartVideoMuted: Function;
|
||||
@@ -121,6 +126,7 @@ export interface IJitsiConference {
|
||||
}
|
||||
|
||||
export interface IConferenceState {
|
||||
assumedBandwidthBps?: number;
|
||||
authEnabled?: boolean;
|
||||
authLogin?: string;
|
||||
authRequired?: IJitsiConference;
|
||||
@@ -148,6 +154,7 @@ export interface IConferenceState {
|
||||
}
|
||||
|
||||
export interface IJitsiConferenceRoom {
|
||||
locked: boolean;
|
||||
myroomjid: string;
|
||||
roomjid: string;
|
||||
}
|
||||
@@ -193,6 +200,13 @@ ReducerRegistry.register<IConferenceState>('features/base/conference',
|
||||
case P2P_STATUS_CHANGED:
|
||||
return _p2pStatusChanged(state, action);
|
||||
|
||||
case SET_ASSUMED_BANDWIDTH_BPS: {
|
||||
const assumedBandwidthBps = action.assumedBandwidthBps >= 0
|
||||
? Number(action.assumedBandwidthBps)
|
||||
: undefined;
|
||||
|
||||
return set(state, 'assumedBandwidthBps', assumedBandwidthBps);
|
||||
}
|
||||
case SET_FOLLOW_ME:
|
||||
return set(state, 'followMeEnabled', action.enabled);
|
||||
|
||||
@@ -266,7 +280,7 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: {
|
||||
return state;
|
||||
}
|
||||
|
||||
let authRequired: any;
|
||||
let authRequired;
|
||||
let membersOnly;
|
||||
let passwordRequired;
|
||||
|
||||
@@ -323,7 +337,7 @@ function _conferenceFailed(state: IConferenceState, { conference, error }: {
|
||||
* @returns {Object} The new state of the feature base/conference after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _conferenceJoined(state: IConferenceState, { conference }: { conference: any; }) {
|
||||
function _conferenceJoined(state: IConferenceState, { conference }: { conference: IJitsiConference; }) {
|
||||
// FIXME The indicator which determines whether a JitsiConference is locked
|
||||
// i.e. password-protected is private to lib-jitsi-meet. However, the
|
||||
// library does not fire LOCK_STATE_CHANGED upon joining a JitsiConference
|
||||
@@ -462,7 +476,7 @@ function _lockStateChanged(state: IConferenceState, { conference, locked }: { co
|
||||
* @returns {Object} The new state of the feature base/conference after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _p2pStatusChanged(state: IConferenceState, action: any) {
|
||||
function _p2pStatusChanged(state: IConferenceState, action: AnyAction) {
|
||||
return set(state, 'p2p', action.p2p);
|
||||
}
|
||||
|
||||
@@ -476,7 +490,7 @@ function _p2pStatusChanged(state: IConferenceState, action: any) {
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _setPassword(state: IConferenceState, { conference, method, password }: {
|
||||
conference: any; method: Object; password: string; }) {
|
||||
conference: IJitsiConference; method: Object; password: string; }) {
|
||||
switch (method) {
|
||||
case conference.join:
|
||||
return assign(state, {
|
||||
@@ -523,7 +537,7 @@ function _setPassword(state: IConferenceState, { conference, method, password }:
|
||||
* @returns {Object} The new state of the feature base/conference after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _setRoom(state: IConferenceState, action: any) {
|
||||
function _setRoom(state: IConferenceState, action: AnyAction) {
|
||||
let { room } = action;
|
||||
|
||||
if (!isRoomValid(room)) {
|
||||
|
||||
@@ -142,6 +142,7 @@ export interface IConfig {
|
||||
rtcstatsEndpoint?: string;
|
||||
rtcstatsPollInterval?: number;
|
||||
rtcstatsSendSdp?: boolean;
|
||||
rtcstatsStoreLogs?: boolean;
|
||||
rtcstatsUseLegacy?: boolean;
|
||||
scriptURLs?: Array<string>;
|
||||
whiteListedEvents?: string[];
|
||||
@@ -292,12 +293,6 @@ export interface IConfig {
|
||||
};
|
||||
dynamicBrandingUrl?: string;
|
||||
e2ee?: {
|
||||
e2eeLabels?: {
|
||||
description?: string;
|
||||
label?: string;
|
||||
tooltip?: string;
|
||||
warning?: string;
|
||||
};
|
||||
externallyManagedKey?: boolean;
|
||||
labels?: {
|
||||
description?: string;
|
||||
@@ -517,6 +512,7 @@ export interface IConfig {
|
||||
stereo?: boolean;
|
||||
subject?: string;
|
||||
testing?: {
|
||||
assumeBandwidth?: boolean;
|
||||
callStatsThreshold?: number;
|
||||
disableE2EE?: boolean;
|
||||
mobileXmppWsThreshold?: number;
|
||||
|
||||
@@ -43,20 +43,17 @@ const INITIAL_NON_RN_STATE: IConfig = {
|
||||
* @type {Object}
|
||||
*/
|
||||
const INITIAL_RN_STATE: IConfig = {
|
||||
analytics: {},
|
||||
|
||||
// FIXME: Mobile codecs should probably be configurable separately, rather
|
||||
// FIXME: than requiring this override here...
|
||||
|
||||
// TODO: Remove comments later, after next release, so that the fix is applied
|
||||
p2p: {
|
||||
// disabledCodec: 'vp9',
|
||||
// preferredCodec: 'vp8'
|
||||
disabledCodec: 'vp9',
|
||||
preferredCodec: 'h264'
|
||||
},
|
||||
|
||||
videoQuality: {
|
||||
// disabledCodec: 'vp9',
|
||||
// preferredCodec: 'vp8'
|
||||
disabledCodec: 'vp9',
|
||||
preferredCodec: 'vp8'
|
||||
}
|
||||
};
|
||||
|
||||
@@ -64,7 +61,7 @@ const INITIAL_RN_STATE: IConfig = {
|
||||
* Mapping between old configs controlling the conference info headers visibility and the
|
||||
* new configs. Needed in order to keep backwards compatibility.
|
||||
*/
|
||||
const CONFERENCE_HEADER_MAPPING: any = {
|
||||
const CONFERENCE_HEADER_MAPPING = {
|
||||
hideConferenceTimer: [ 'conference-timer' ],
|
||||
hideConferenceSubject: [ 'subject' ],
|
||||
hideParticipantsStats: [ 'participants-count' ],
|
||||
@@ -388,9 +385,10 @@ function _translateLegacyConfig(oldValue: IConfig) {
|
||||
} else {
|
||||
newValue.conferenceInfo.alwaysVisible
|
||||
= (newValue.conferenceInfo.alwaysVisible ?? [])
|
||||
.filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c));
|
||||
.filter(c => !CONFERENCE_HEADER_MAPPING[key as keyof typeof CONFERENCE_HEADER_MAPPING].includes(c));
|
||||
newValue.conferenceInfo.autoHide
|
||||
= (newValue.conferenceInfo.autoHide ?? []).filter(c => !CONFERENCE_HEADER_MAPPING[key].includes(c));
|
||||
= (newValue.conferenceInfo.autoHide ?? []).filter(c =>
|
||||
!CONFERENCE_HEADER_MAPPING[key as keyof typeof CONFERENCE_HEADER_MAPPING].includes(c));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -438,7 +436,7 @@ function _translateLegacyConfig(oldValue: IConfig) {
|
||||
newValue.e2ee = newValue.e2ee || {};
|
||||
|
||||
if (oldValue.e2eeLabels) {
|
||||
newValue.e2ee.e2eeLabels = oldValue.e2eeLabels;
|
||||
newValue.e2ee.labels = oldValue.e2eeLabels;
|
||||
}
|
||||
|
||||
newValue.defaultLocalDisplayName
|
||||
|
||||
@@ -21,6 +21,7 @@ export interface IConnectionState {
|
||||
getJid: () => string;
|
||||
getLogs: () => Object;
|
||||
initJitsiConference: Function;
|
||||
removeFeature: Function;
|
||||
};
|
||||
error?: ConnectionFailedError;
|
||||
locationURL?: URL;
|
||||
|
||||
@@ -142,7 +142,7 @@ export function getAvailableDevices() {
|
||||
|
||||
if (mediaDevices.isDeviceListAvailable()
|
||||
&& mediaDevices.isDeviceChangeAvailable()) {
|
||||
mediaDevices.enumerateDevices((devices: any) => {
|
||||
mediaDevices.enumerateDevices((devices: MediaDeviceInfo[]) => {
|
||||
dispatch(updateDeviceList(devices));
|
||||
|
||||
resolve(devices);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { IReduxState } from '../../app/types';
|
||||
import { IReduxState, IStore } from '../../app/types';
|
||||
import JitsiMeetJS from '../lib-jitsi-meet';
|
||||
import { updateSettings } from '../settings/actions';
|
||||
import { ISettingsState } from '../settings/reducer';
|
||||
import { setNewAudioOutputDevice } from '../sounds/functions.web';
|
||||
import { parseURLParams } from '../util/parseURLParams';
|
||||
|
||||
import logger from './logger';
|
||||
@@ -251,7 +252,7 @@ export function getVideoDeviceIds(state: IReduxState) {
|
||||
*/
|
||||
export function setAudioOutputDeviceId(
|
||||
newId = 'default',
|
||||
dispatch: Function,
|
||||
dispatch: IStore['dispatch'],
|
||||
userSelection = false,
|
||||
newLabel?: string): Promise<any> {
|
||||
|
||||
@@ -265,6 +266,7 @@ export function setAudioOutputDeviceId(
|
||||
|
||||
return JitsiMeetJS.mediaDevices.setAudioOutputDevice(newId)
|
||||
.then(() => {
|
||||
dispatch(setNewAudioOutputDevice(newId));
|
||||
const newSettings: Partial<ISettingsState> = {
|
||||
audioOutputDeviceId: newId,
|
||||
userSelectedAudioOutputDeviceId: undefined,
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { PureComponent, ReactNode } from 'react';
|
||||
import { SafeAreaView, ScrollView, View, ViewStyle } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IStore } from '../../../../app/types';
|
||||
import SlidingView from '../../../react/components/native/SlidingView';
|
||||
import { hideSheet } from '../../actions';
|
||||
|
||||
@@ -25,7 +26,7 @@ type Props = {
|
||||
/**
|
||||
* Redux Dispatch function.
|
||||
*/
|
||||
dispatch: Function;
|
||||
dispatch: IStore['dispatch'];
|
||||
|
||||
/**
|
||||
* Handler for the cancel event, which happens when the user dismisses
|
||||
|
||||
@@ -243,6 +243,12 @@ export const TOOLBOX_ALWAYS_VISIBLE = 'toolbox.alwaysVisible';
|
||||
*/
|
||||
export const TOOLBOX_ENABLED = 'toolbox.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if the unsafe room warning should be enabled.
|
||||
* Default: disabled (false).
|
||||
*/
|
||||
export const UNSAFE_ROOM_WARNING = 'unsaferoomwarning.enabled';
|
||||
|
||||
/**
|
||||
* Flag indicating if the video mute button should be displayed.
|
||||
* Default: enabled (true).
|
||||
|
||||
@@ -13,7 +13,7 @@ import { toState } from '../redux/functions';
|
||||
* @returns {*} The value of the specified React {@code Component} prop of the
|
||||
* currently mounted {@code App}.
|
||||
*/
|
||||
export function getFeatureFlag(stateful: IStateful, flag: string, defaultValue?: any) {
|
||||
export function getFeatureFlag(stateful: IStateful, flag: string, defaultValue?: boolean | string) {
|
||||
const state = toState(stateful)['features/base/flags'];
|
||||
|
||||
if (state) {
|
||||
|
||||
@@ -7,6 +7,16 @@ import { IIconProps } from './types';
|
||||
|
||||
interface IProps extends IIconProps {
|
||||
|
||||
/**
|
||||
* Optional label for screen reader users.
|
||||
*
|
||||
* If set, this is will add a `aria-label` attribute on the svg element,
|
||||
* contrary to the aria* props which set attributes on the container element.
|
||||
*
|
||||
* Use this if the icon conveys meaning and is not clickable.
|
||||
*/
|
||||
alt?: string;
|
||||
|
||||
/**
|
||||
* The id of the element this button icon controls.
|
||||
*/
|
||||
@@ -114,6 +124,7 @@ export const DEFAULT_SIZE = navigator.product === 'ReactNative' ? 36 : 22;
|
||||
*/
|
||||
export default function Icon(props: IProps) {
|
||||
const {
|
||||
alt,
|
||||
className,
|
||||
color,
|
||||
id,
|
||||
@@ -156,6 +167,13 @@ export default function Icon(props: IProps) {
|
||||
|
||||
const jitsiIconClassName = calculatedColor ? 'jitsi-icon' : 'jitsi-icon jitsi-icon-default';
|
||||
|
||||
const iconProps = alt ? {
|
||||
'aria-label': alt,
|
||||
role: 'img'
|
||||
} : {
|
||||
'aria-hidden': true
|
||||
};
|
||||
|
||||
return (
|
||||
<Container
|
||||
{ ...rest }
|
||||
@@ -176,6 +194,7 @@ export default function Icon(props: IProps) {
|
||||
style = { restStyle }
|
||||
tabIndex = { tabIndex }>
|
||||
<IconComponent
|
||||
{ ...iconProps }
|
||||
fill = { calculatedColor }
|
||||
height = { calculatedSize }
|
||||
id = { id }
|
||||
|
||||
@@ -226,9 +226,15 @@ function _undoOverwriteLocalParticipant(
|
||||
* }}
|
||||
*/
|
||||
function _user2participant({ avatar, avatarUrl, email, id, name, 'hidden-from-recorder': hiddenFromRecorder }:
|
||||
{ avatar: any; avatarUrl: string; email: string; 'hidden-from-recorder': string | boolean;
|
||||
{ avatar?: string; avatarUrl?: string; email: string; 'hidden-from-recorder': string | boolean;
|
||||
id: string; name: string; }) {
|
||||
const participant: any = {};
|
||||
const participant: {
|
||||
avatarURL?: string;
|
||||
email?: string;
|
||||
hiddenFromRecorder?: boolean;
|
||||
id?: string;
|
||||
name?: string;
|
||||
} = {};
|
||||
|
||||
if (typeof avatarUrl === 'string') {
|
||||
participant.avatarURL = avatarUrl.trim();
|
||||
|
||||
@@ -7,6 +7,14 @@ import { COLORS } from '../../constants';
|
||||
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* Optional label for screen reader users, invisible in the UI.
|
||||
*
|
||||
* Note: if the text prop is set, a screen reader will first announce
|
||||
* the accessibilityText, then the text.
|
||||
*/
|
||||
accessibilityText?: string;
|
||||
|
||||
/**
|
||||
* Own CSS class name.
|
||||
*/
|
||||
@@ -82,6 +90,7 @@ const useStyles = makeStyles()(theme => {
|
||||
});
|
||||
|
||||
const Label = ({
|
||||
accessibilityText,
|
||||
className,
|
||||
color,
|
||||
icon,
|
||||
@@ -117,6 +126,7 @@ const Label = ({
|
||||
color = { iconColor }
|
||||
size = '16'
|
||||
src = { icon } />}
|
||||
{accessibilityText && <span className = 'sr-only'>{accessibilityText}</span>}
|
||||
{text && <span className = { icon && classes.withIcon }>{text}</span>}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,10 @@ import debounce from 'lodash/debounce';
|
||||
import { IStore } from '../../app/types';
|
||||
import { SET_FILMSTRIP_ENABLED } from '../../filmstrip/actionTypes';
|
||||
import { APP_STATE_CHANGED } from '../../mobile/background/actionTypes';
|
||||
import { SET_CAR_MODE } from '../../video-layout/actionTypes';
|
||||
import {
|
||||
SET_CAR_MODE,
|
||||
VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED
|
||||
} from '../../video-layout/actionTypes';
|
||||
import { SET_AUDIO_ONLY } from '../audio-only/actionTypes';
|
||||
import { CONFERENCE_JOINED } from '../conference/actionTypes';
|
||||
import { getParticipantById } from '../participants/functions';
|
||||
@@ -81,6 +84,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
case SET_AUDIO_ONLY:
|
||||
case SET_CAR_MODE:
|
||||
case SET_FILMSTRIP_ENABLED:
|
||||
case VIRTUAL_SCREENSHARE_REMOTE_PARTICIPANTS_UPDATED:
|
||||
_updateLastN(store);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { IStore } from '../../app/types';
|
||||
import RTCStats from '../../rtcstats/RTCStats';
|
||||
import { canSendRtcstatsData } from '../../rtcstats/functions';
|
||||
import { getCurrentConference } from '../conference/functions';
|
||||
@@ -8,14 +9,14 @@ import { getCurrentConference } from '../conference/functions';
|
||||
*/
|
||||
export default class JitsiMeetLogStorage {
|
||||
counter: number;
|
||||
getState: Function;
|
||||
getState: IStore['getState'];
|
||||
|
||||
/**
|
||||
* Creates new <tt>JitsiMeetLogStorage</tt>.
|
||||
*
|
||||
* @param {Function} getState - The Redux store's {@code getState} method.
|
||||
*/
|
||||
constructor(getState: Function) {
|
||||
constructor(getState: IStore['getState']) {
|
||||
/**
|
||||
* Counts each log entry, increases on every batch log entry stored.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// @ts-expect-error
|
||||
import Logger from '@jitsi/logger';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { APP_WILL_MOUNT } from '../app/actionTypes';
|
||||
@@ -61,7 +62,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _appWillMount({ getState }: IStore, next: Function, action: any) {
|
||||
function _appWillMount({ getState }: IStore, next: Function, action: AnyAction) {
|
||||
const { config } = getState()['features/base/logging'];
|
||||
|
||||
_setLogLevels(Logger, config);
|
||||
@@ -87,7 +88,7 @@ function _appWillMount({ getState }: IStore, next: Function, action: any) {
|
||||
* @private
|
||||
* @returns {*}
|
||||
*/
|
||||
function _conferenceJoined({ getState }: IStore, next: Function, action: any) {
|
||||
function _conferenceJoined({ getState }: IStore, next: Function, action: AnyAction) {
|
||||
|
||||
// Wait until the joined event is processed, so that the JitsiMeetLogStorage
|
||||
// will be ready.
|
||||
@@ -191,7 +192,7 @@ function _initLogging({ dispatch, getState }: IStore,
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _libWillInit({ getState }: IStore, next: Function, action: any) {
|
||||
function _libWillInit({ getState }: IStore, next: Function, action: AnyAction) {
|
||||
// Adding the if in order to preserve the logic for web after enabling
|
||||
// LIB_WILL_INIT action for web in initLib action.
|
||||
if (typeof APP === 'undefined') {
|
||||
@@ -215,7 +216,7 @@ function _libWillInit({ getState }: IStore, next: Function, action: any) {
|
||||
* @returns {Object} The new state that is the result of the reduction of the
|
||||
* specified action.
|
||||
*/
|
||||
function _setConfig({ dispatch }: IStore, next: Function, action: any) {
|
||||
function _setConfig({ dispatch }: IStore, next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
|
||||
dispatch(setLoggingConfig(action.config?.logging));
|
||||
@@ -238,7 +239,7 @@ function _setConfig({ dispatch }: IStore, next: Function, action: any) {
|
||||
* specified {@code action}.
|
||||
*/
|
||||
function _setLoggingConfig({ dispatch, getState }: IStore,
|
||||
next: Function, action: any) {
|
||||
next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
const newValue = getState()['features/base/logging'].config;
|
||||
const isTestingEnabled = isTestModeEnabled(getState());
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import ReducerRegistry from '../redux/ReducerRegistry';
|
||||
import { equals, set } from '../redux/functions';
|
||||
@@ -94,7 +95,7 @@ ReducerRegistry.register<ILoggingState>(
|
||||
* @returns {Object} The new state of the feature base/logging after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _setLoggingConfig(state: ILoggingState, action: any) {
|
||||
function _setLoggingConfig(state: ILoggingState, action: AnyAction) {
|
||||
const newConfig = _.merge({}, DEFAULT_STATE.config, action.config);
|
||||
|
||||
if (equals(state.config, newConfig)) {
|
||||
@@ -117,6 +118,6 @@ function _setLoggingConfig(state: ILoggingState, action: any) {
|
||||
* @returns {Object} The new state of the feature base/logging after the
|
||||
* reduction of the specified action.
|
||||
*/
|
||||
function _setLogCollector(state: ILoggingState, action: any) {
|
||||
function _setLogCollector(state: ILoggingState, action: AnyAction) {
|
||||
return set(state, 'logCollector', action.logCollector);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,15 @@
|
||||
|
||||
/**
|
||||
* The type of (redux) action to store the gum pending state for unmute and initial track creation.
|
||||
*
|
||||
* {
|
||||
* type: GUM_PENDING,
|
||||
* mediaTypes: Array<MediaType>,
|
||||
* status: IGUMPendingState
|
||||
* }
|
||||
*/
|
||||
export const GUM_PENDING = 'GUM_PENDING';
|
||||
|
||||
/**
|
||||
* The type of (redux) action to adjust the availability of the local audio.
|
||||
*
|
||||
|
||||
@@ -4,6 +4,7 @@ import { shouldShowModeratedNotification } from '../../av-moderation/functions';
|
||||
import { isModerationNotificationDisplayed } from '../../notifications/functions';
|
||||
|
||||
import {
|
||||
GUM_PENDING,
|
||||
SET_AUDIO_AVAILABLE,
|
||||
SET_AUDIO_MUTED,
|
||||
SET_AUDIO_UNMUTE_PERMISSIONS,
|
||||
@@ -17,9 +18,11 @@ import {
|
||||
} from './actionTypes';
|
||||
import {
|
||||
MEDIA_TYPE,
|
||||
MediaType,
|
||||
SCREENSHARE_MUTISM_AUTHORITY,
|
||||
VIDEO_MUTISM_AUTHORITY
|
||||
} from './constants';
|
||||
import { IGUMPendingState } from './types';
|
||||
|
||||
/**
|
||||
* Action to adjust the availability of the local audio.
|
||||
@@ -237,3 +240,22 @@ export function toggleCameraFacingMode() {
|
||||
type: TOGGLE_CAMERA_FACING_MODE
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the GUM pending status from unmute and initial track creation operation.
|
||||
*
|
||||
* @param {Array<MediaType>} mediaTypes - An array with the media types that GUM is called with.
|
||||
* @param {IGUMPendingState} status - The GUM status.
|
||||
* @returns {{
|
||||
* type: TOGGLE_CAMERA_FACING_MODE,
|
||||
* mediaTypes: Array<MediaType>,
|
||||
* status: IGUMPendingState
|
||||
* }}
|
||||
*/
|
||||
export function gumPending(mediaTypes: Array<MediaType>, status: IGUMPendingState) {
|
||||
return {
|
||||
type: GUM_PENDING,
|
||||
mediaTypes,
|
||||
status
|
||||
};
|
||||
}
|
||||
|
||||
@@ -597,7 +597,8 @@ class VideoTransform extends Component<IProps, IState> {
|
||||
this._onGesture('scale', scale);
|
||||
}
|
||||
} else if (gestureState.numberActiveTouches === 1
|
||||
&& isNaN(this.initialDistance ?? 0)
|
||||
&& (this.initialDistance === undefined
|
||||
|| isNaN(this.initialDistance))
|
||||
&& this._didMove(gestureState)) {
|
||||
// this is a move event
|
||||
const position = this._getTouchPosition(evt);
|
||||
|
||||
@@ -152,7 +152,7 @@ class AudioTrack extends Component<IProps> {
|
||||
const currentMuted = this._ref.muted;
|
||||
const nextMuted = nextProps._muted;
|
||||
|
||||
if (typeof nextMuted === 'boolean' && currentMuted !== nextVolume) {
|
||||
if (typeof nextMuted === 'boolean' && currentMuted !== nextMuted) {
|
||||
this._ref.muted = nextMuted;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ function _setRoom({ dispatch, getState }: IStore, next: Function, action: AnyAct
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _syncTrackMutedState({ getState }: IStore, track: ITrack) {
|
||||
function _syncTrackMutedState({ getState, dispatch }: IStore, track: ITrack) {
|
||||
const state = getState()['features/base/media'];
|
||||
const mediaType = track.mediaType;
|
||||
const muted = Boolean(state[mediaType].muted);
|
||||
@@ -312,6 +312,6 @@ function _syncTrackMutedState({ getState }: IStore, track: ITrack) {
|
||||
logger.log(`Sync ${mediaType} track muted state to ${muted ? 'muted' : 'unmuted'}`);
|
||||
|
||||
track.muted = muted;
|
||||
setTrackMuted(track.jitsiTrack, muted, state);
|
||||
setTrackMuted(track.jitsiTrack, muted, state, dispatch);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import './middleware.any';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { IStore } from '../../app/types';
|
||||
import { showNotification } from '../../notifications/actions';
|
||||
@@ -18,7 +19,7 @@ import './subscriber';
|
||||
* @param {IStore} store - The redux store.
|
||||
* @returns {Function}
|
||||
*/
|
||||
MiddlewareRegistry.register((store: IStore) => (next: Function) => (action: any) => {
|
||||
MiddlewareRegistry.register((store: IStore) => (next: Function) => (action: AnyAction) => {
|
||||
const { dispatch } = store;
|
||||
|
||||
switch (action.type) {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { combineReducers } from 'redux';
|
||||
import { AnyAction, combineReducers } from 'redux';
|
||||
|
||||
import { CONFERENCE_FAILED, CONFERENCE_LEFT } from '../conference/actionTypes';
|
||||
import ReducerRegistry from '../redux/ReducerRegistry';
|
||||
import { TRACK_REMOVED } from '../tracks/actionTypes';
|
||||
|
||||
import {
|
||||
GUM_PENDING,
|
||||
SET_AUDIO_AVAILABLE,
|
||||
SET_AUDIO_MUTED,
|
||||
SET_AUDIO_UNMUTE_PERMISSIONS,
|
||||
@@ -16,7 +17,8 @@ import {
|
||||
STORE_VIDEO_TRANSFORM,
|
||||
TOGGLE_CAMERA_FACING_MODE
|
||||
} from './actionTypes';
|
||||
import { CAMERA_FACING_MODE, SCREENSHARE_MUTISM_AUTHORITY } from './constants';
|
||||
import { CAMERA_FACING_MODE, MEDIA_TYPE, SCREENSHARE_MUTISM_AUTHORITY } from './constants';
|
||||
import { IGUMPendingState } from './types';
|
||||
|
||||
/**
|
||||
* Media state object for local audio.
|
||||
@@ -36,6 +38,7 @@ import { CAMERA_FACING_MODE, SCREENSHARE_MUTISM_AUTHORITY } from './constants';
|
||||
*/
|
||||
export const _AUDIO_INITIAL_MEDIA_STATE = {
|
||||
available: true,
|
||||
gumPending: IGUMPendingState.NONE,
|
||||
unmuteBlocked: false,
|
||||
muted: false
|
||||
};
|
||||
@@ -49,7 +52,7 @@ export const _AUDIO_INITIAL_MEDIA_STATE = {
|
||||
* @private
|
||||
* @returns {AudioMediaState}
|
||||
*/
|
||||
function _audio(state: IAudioState = _AUDIO_INITIAL_MEDIA_STATE, action: any) {
|
||||
function _audio(state: IAudioState = _AUDIO_INITIAL_MEDIA_STATE, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case SET_AUDIO_AVAILABLE:
|
||||
return {
|
||||
@@ -57,6 +60,16 @@ function _audio(state: IAudioState = _AUDIO_INITIAL_MEDIA_STATE, action: any) {
|
||||
available: action.available
|
||||
};
|
||||
|
||||
case GUM_PENDING:
|
||||
if (action.mediaTypes.includes(MEDIA_TYPE.AUDIO)) {
|
||||
return {
|
||||
...state,
|
||||
gumPending: action.status
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
|
||||
case SET_AUDIO_MUTED:
|
||||
return {
|
||||
...state,
|
||||
@@ -103,7 +116,7 @@ export const _SCREENSHARE_INITIAL_MEDIA_STATE = {
|
||||
* @private
|
||||
* @returns {ScreenshareMediaState}
|
||||
*/
|
||||
function _screenshare(state: IScreenshareState = _SCREENSHARE_INITIAL_MEDIA_STATE, action: any) {
|
||||
function _screenshare(state: IScreenshareState = _SCREENSHARE_INITIAL_MEDIA_STATE, action: AnyAction) {
|
||||
switch (action.type) {
|
||||
case SET_SCREENSHARE_MUTED:
|
||||
return {
|
||||
@@ -141,6 +154,7 @@ function _screenshare(state: IScreenshareState = _SCREENSHARE_INITIAL_MEDIA_STAT
|
||||
*/
|
||||
export const _VIDEO_INITIAL_MEDIA_STATE = {
|
||||
available: true,
|
||||
gumPending: IGUMPendingState.NONE,
|
||||
unmuteBlocked: false,
|
||||
facingMode: CAMERA_FACING_MODE.USER,
|
||||
muted: 0,
|
||||
@@ -167,6 +181,16 @@ function _video(state: IVideoState = _VIDEO_INITIAL_MEDIA_STATE, action: any) {
|
||||
case CONFERENCE_LEFT:
|
||||
return _clearAllVideoTransforms(state);
|
||||
|
||||
case GUM_PENDING:
|
||||
if (action.mediaTypes.includes(MEDIA_TYPE.VIDEO)) {
|
||||
return {
|
||||
...state,
|
||||
gumPending: action.status
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
|
||||
case SET_CAMERA_FACING_MODE:
|
||||
return {
|
||||
...state,
|
||||
@@ -218,6 +242,7 @@ function _video(state: IVideoState = _VIDEO_INITIAL_MEDIA_STATE, action: any) {
|
||||
|
||||
interface IAudioState {
|
||||
available: boolean;
|
||||
gumPending: IGUMPendingState;
|
||||
muted: boolean;
|
||||
unmuteBlocked: boolean;
|
||||
}
|
||||
@@ -231,6 +256,7 @@ interface IScreenshareState {
|
||||
interface IVideoState {
|
||||
available: boolean;
|
||||
facingMode: string;
|
||||
gumPending: IGUMPendingState;
|
||||
muted: number;
|
||||
transforms: Object;
|
||||
unmuteBlocked: boolean;
|
||||
|
||||
4
react/features/base/media/types.ts
Normal file
4
react/features/base/media/types.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export enum IGUMPendingState {
|
||||
PENDING_UNMUTE = 1,
|
||||
NONE = 2
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { IStore } from '../../app/types';
|
||||
import { showNotification } from '../../notifications/actions';
|
||||
import { NOTIFICATION_TIMEOUT_TYPE } from '../../notifications/constants';
|
||||
import { IJitsiConference } from '../conference/reducer';
|
||||
import { set } from '../redux/functions';
|
||||
|
||||
import {
|
||||
@@ -60,7 +61,7 @@ import { FakeParticipant, IJitsiParticipant, IParticipant } from './types';
|
||||
* }}
|
||||
*/
|
||||
export function dominantSpeakerChanged(
|
||||
dominantSpeaker: string, previousSpeakers: string[], silence: boolean, conference: any) {
|
||||
dominantSpeaker: string, previousSpeakers: string[], silence: boolean, conference: IJitsiConference) {
|
||||
return {
|
||||
type: DOMINANT_SPEAKER_CHANGED,
|
||||
participant: {
|
||||
@@ -386,7 +387,9 @@ export function hiddenParticipantLeft(id: string) {
|
||||
* }
|
||||
* }}
|
||||
*/
|
||||
export function participantLeft(id: string, conference: any, participantLeftProps: any = {}) {
|
||||
export function participantLeft(id: string, conference?: IJitsiConference, participantLeftProps: {
|
||||
fakeParticipant?: string; isReplaced?: boolean;
|
||||
} = {}) {
|
||||
return {
|
||||
type: PARTICIPANT_LEFT,
|
||||
participant: {
|
||||
@@ -516,7 +519,7 @@ export function participantMutedUs(participant: any, track: any) {
|
||||
* @param {JitsiConference} conference - The conference instance for which the participant is to be created.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function createVirtualScreenshareParticipant(sourceName: string, local: boolean, conference: any) {
|
||||
export function createVirtualScreenshareParticipant(sourceName: string, local: boolean, conference?: IJitsiConference) {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const state = getState();
|
||||
const ownerId = getVirtualScreenshareParticipantOwnerId(sourceName);
|
||||
|
||||
@@ -733,7 +733,7 @@ export const addPeopleFeatureControl = (stateful: IStateful) => {
|
||||
* @param {Function} dispatch - The Redux dispatch function.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export const setShareDialogVisiblity = (addPeopleFeatureEnabled: boolean, dispatch: Function) => {
|
||||
export const setShareDialogVisiblity = (addPeopleFeatureEnabled: boolean, dispatch: IStore['dispatch']) => {
|
||||
if (addPeopleFeatureEnabled) {
|
||||
dispatch(toggleShareDialog(false));
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import i18n from 'i18next';
|
||||
import { batch } from 'react-redux';
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
// @ts-expect-error
|
||||
import UIEvents from '../../../../service/UI/UIEvents';
|
||||
@@ -543,7 +544,7 @@ function _e2eeUpdated({ getState, dispatch }: IStore, conference: IJitsiConferen
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _localParticipantJoined({ getState, dispatch }: IStore, next: Function, action: any) {
|
||||
function _localParticipantJoined({ getState, dispatch }: IStore, next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
|
||||
const settings = getState()['features/base/settings'];
|
||||
@@ -569,7 +570,7 @@ function _localParticipantJoined({ getState, dispatch }: IStore, next: Function,
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _localParticipantLeft({ dispatch }: IStore, next: Function, action: any) {
|
||||
function _localParticipantLeft({ dispatch }: IStore, next: Function, action: AnyAction) {
|
||||
const result = next(action);
|
||||
|
||||
dispatch(localParticipantLeft());
|
||||
@@ -586,7 +587,7 @@ function _localParticipantLeft({ dispatch }: IStore, next: Function, action: any
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
function _maybePlaySounds({ getState, dispatch }: IStore, action: any) {
|
||||
function _maybePlaySounds({ getState, dispatch }: IStore, action: AnyAction) {
|
||||
const state = getState();
|
||||
const { startAudioMuted } = state['features/base/config'];
|
||||
const { soundsParticipantJoined: joinSound, soundsParticipantLeft: leftSound } = state['features/base/settings'];
|
||||
@@ -631,7 +632,7 @@ function _maybePlaySounds({ getState, dispatch }: IStore, action: any) {
|
||||
* @private
|
||||
* @returns {Object} The value returned by {@code next(action)}.
|
||||
*/
|
||||
function _participantJoinedOrUpdated(store: IStore, next: Function, action: any) {
|
||||
function _participantJoinedOrUpdated(store: IStore, next: Function, action: AnyAction) {
|
||||
const { dispatch, getState } = store;
|
||||
const { overwrittenNameList } = store.getState()['features/base/participants'];
|
||||
const { participant: {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { AnyAction } from 'redux';
|
||||
|
||||
import { MEDIA_TYPE } from '../media/constants';
|
||||
import ReducerRegistry from '../redux/ReducerRegistry';
|
||||
import { set } from '../redux/functions';
|
||||
@@ -512,7 +514,7 @@ function _getDisplayName(state: Object, name?: string): string {
|
||||
* @returns {IParticipant}
|
||||
*/
|
||||
function _participant(state: IParticipant | ILocalParticipant = { id: '' },
|
||||
action: any): IParticipant | ILocalParticipant {
|
||||
action: AnyAction): IParticipant | ILocalParticipant {
|
||||
switch (action.type) {
|
||||
case SET_LOADABLE_AVATAR_URL:
|
||||
case PARTICIPANT_UPDATED: {
|
||||
|
||||
@@ -78,6 +78,10 @@ function _updateScreenshareParticipants(store: IStore): void {
|
||||
if (track.videoType === VIDEO_TYPE.DESKTOP && !track.jitsiTrack.isMuted()) {
|
||||
const sourceName: string = track.jitsiTrack.getSourceName();
|
||||
|
||||
// Ignore orphan tracks in ssrc-rewriting mode.
|
||||
if (!sourceName && getSsrcRewritingFeatureFlag(state)) {
|
||||
return acc;
|
||||
}
|
||||
if (track.local) {
|
||||
newLocalSceenshareSourceName = sourceName;
|
||||
} else if (getParticipantById(state, getVirtualScreenshareParticipantOwnerId(sourceName))) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { IJitsiConference } from '../conference/reducer';
|
||||
|
||||
export enum FakeParticipant {
|
||||
LocalScreenShare = 'LocalScreenShare',
|
||||
RemoteScreenShare = 'RemoteScreenShare',
|
||||
@@ -8,7 +10,7 @@ export enum FakeParticipant {
|
||||
export interface IParticipant {
|
||||
avatarURL?: string;
|
||||
botType?: string;
|
||||
conference?: Object;
|
||||
conference?: IJitsiConference;
|
||||
displayName?: string;
|
||||
dominantSpeaker?: boolean;
|
||||
e2eeEnabled?: boolean;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { Component, ReactNode } from 'react';
|
||||
import ReactFocusLock from 'react-focus-lock';
|
||||
import { FocusOn } from 'react-focus-on';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { IReduxState } from '../../../app/types';
|
||||
@@ -40,6 +40,16 @@ interface IProps {
|
||||
*/
|
||||
disablePopover?: boolean;
|
||||
|
||||
/**
|
||||
* Whether we can reach the popover element via keyboard or not when trigger is 'hover' (true by default).
|
||||
*
|
||||
* Only works when trigger is set to 'hover'.
|
||||
*
|
||||
* There are some rare cases where we want to set this to false,
|
||||
* when the popover content is not necessary for screen reader users, because accessible elsewhere.
|
||||
*/
|
||||
focusable?: boolean;
|
||||
|
||||
/**
|
||||
* The id of the dom element acting as the Popover label (matches aria-labelledby).
|
||||
*/
|
||||
@@ -103,6 +113,14 @@ interface IState {
|
||||
position: string;
|
||||
top?: string;
|
||||
} | null;
|
||||
|
||||
/**
|
||||
* Whether the popover should be focus locked or not.
|
||||
*
|
||||
* This is enabled if we notice the popover is interactive
|
||||
* (trigger is click or focusable is true).
|
||||
*/
|
||||
enableFocusLock: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -119,6 +137,7 @@ class Popover extends Component<IProps, IState> {
|
||||
*/
|
||||
static defaultProps = {
|
||||
className: '',
|
||||
focusable: true,
|
||||
id: '',
|
||||
trigger: 'hover'
|
||||
};
|
||||
@@ -140,10 +159,12 @@ class Popover extends Component<IProps, IState> {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
contextMenuStyle: null
|
||||
contextMenuStyle: null,
|
||||
enableFocusLock: false
|
||||
};
|
||||
|
||||
// Bind event handlers so they are only bound once for every instance.
|
||||
this._enableFocusLock = this._enableFocusLock.bind(this);
|
||||
this._onHideDialog = this._onHideDialog.bind(this);
|
||||
this._onShowDialog = this._onShowDialog.bind(this);
|
||||
this._onKeyPress = this._onKeyPress.bind(this);
|
||||
@@ -207,8 +228,8 @@ class Popover extends Component<IProps, IState> {
|
||||
const { children,
|
||||
className,
|
||||
content,
|
||||
focusable,
|
||||
headingId,
|
||||
headingLabel,
|
||||
id,
|
||||
overflowDrawer,
|
||||
visible,
|
||||
@@ -242,35 +263,40 @@ class Popover extends Component<IProps, IState> {
|
||||
onKeyPress = { this._onKeyPress }
|
||||
{ ...(trigger === 'hover' ? {
|
||||
onMouseEnter: this._onShowDialog,
|
||||
onMouseLeave: this._onHideDialog,
|
||||
tabIndex: 0
|
||||
onMouseLeave: this._onHideDialog
|
||||
} : {}) }
|
||||
{ ...(trigger === 'hover' && focusable && {
|
||||
role: 'button',
|
||||
tabIndex: 0
|
||||
}) }
|
||||
ref = { this._containerRef }>
|
||||
{ visible && (
|
||||
<DialogPortal
|
||||
getRef = { this._setContextMenuRef }
|
||||
onVisible = { this._isInteractive() ? this._enableFocusLock : undefined }
|
||||
setSize = { this._setContextMenuStyle }
|
||||
style = { this.state.contextMenuStyle }
|
||||
targetSelector = '.popover-content'>
|
||||
<ReactFocusLock
|
||||
lockProps = {{
|
||||
role: 'dialog',
|
||||
'aria-modal': true,
|
||||
'aria-labelledby': headingId,
|
||||
'aria-label': !headingId && headingLabel ? headingLabel : undefined
|
||||
}}
|
||||
<FocusOn
|
||||
|
||||
// Use the `enabled` prop instead of conditionally rendering ReactFocusOn
|
||||
// to prevent UI stutter on dialog appearance. It seems the focus guards generated annoy
|
||||
// our DialogPortal positioning calculations.
|
||||
enabled = { this.state.enableFocusLock }
|
||||
returnFocus = {
|
||||
|
||||
// If we return the focus to an element outside the viewport the page will scroll to
|
||||
// this element which in our case is undesirable and the element is outside of the
|
||||
// viewport on purpose (to be hidden). For example if we return the focus to the toolbox
|
||||
// when it is hidden the whole page will move up in order to show the toolbox. This is
|
||||
// usually followed up with displaying the toolbox (because now it is on focus) but
|
||||
// because of the animation the whole scenario looks like jumping large video.
|
||||
// viewport on purpose (to be hidden). For example if we return the focus to the
|
||||
// toolbox when it is hidden the whole page will move up in order to show the
|
||||
// toolbox. This is usually followed up with displaying the toolbox (because now it
|
||||
// is on focus) but because of the animation the whole scenario looks like jumping
|
||||
// large video.
|
||||
isElementInTheViewport
|
||||
}>
|
||||
}
|
||||
shards = { [ this._contextMenuRef ] }>
|
||||
{this._renderContent()}
|
||||
</ReactFocusLock>
|
||||
</FocusOn>
|
||||
</DialogPortal>
|
||||
)}
|
||||
{ children }
|
||||
@@ -361,12 +387,12 @@ class Popover extends Component<IProps, IState> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_onClick(event: React.MouseEvent) {
|
||||
const { allowClick, trigger, visible } = this.props;
|
||||
const { allowClick, trigger, focusable, visible } = this.props;
|
||||
|
||||
if (!allowClick) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
if (trigger === 'click') {
|
||||
if (trigger === 'click' || focusable) {
|
||||
if (visible) {
|
||||
this._onHideDialog();
|
||||
} else {
|
||||
@@ -383,7 +409,9 @@ class Popover extends Component<IProps, IState> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_onKeyPress(e: React.KeyboardEvent) {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
// first check that the element we pressed is the actual popover toggle or any of its descendant,
|
||||
// otherwise pressing space or enter in any child element of the popover _dialog_ will trigger this.
|
||||
if (e.currentTarget.contains(e.target as Node) && (e.key === ' ' || e.key === 'Enter')) {
|
||||
e.preventDefault();
|
||||
if (this.props.visible) {
|
||||
this._onHideDialog();
|
||||
@@ -435,18 +463,49 @@ class Popover extends Component<IProps, IState> {
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
_renderContent() {
|
||||
const { content, position, trigger } = this.props;
|
||||
const { content, position, trigger, headingId, headingLabel } = this.props;
|
||||
|
||||
return (
|
||||
<div
|
||||
className = { `popover ${trigger}` }
|
||||
onKeyDown = { this._onEscKey }>
|
||||
<div className = { `popover-content ${position.split('-')[0]}` }>
|
||||
<div className = { `popover ${trigger}` }>
|
||||
<div
|
||||
className = { `popover-content ${position.split('-')[0]}` }
|
||||
data-autofocus = { this.state.enableFocusLock }
|
||||
onKeyDown = { this._onEscKey }
|
||||
{ ...(this.state.enableFocusLock && {
|
||||
'aria-modal': true,
|
||||
'aria-label': !headingId && headingLabel ? headingLabel : undefined,
|
||||
'aria-labelledby': headingId,
|
||||
role: 'dialog',
|
||||
tabIndex: -1
|
||||
}) }>
|
||||
{ content }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the popover is considered interactive or not.
|
||||
*
|
||||
* Interactive means the popover content is certainly composed of buttons, links…
|
||||
* Non-interactive popovers are mostly tooltips.
|
||||
*
|
||||
* @private
|
||||
* @returns {boolean}
|
||||
*/
|
||||
_isInteractive() {
|
||||
return this.props.trigger === 'click' || Boolean(this.props.focusable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the focus lock in the popover dialog.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_enableFocusLock() {
|
||||
this.setState({ enableFocusLock: true });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -88,7 +88,7 @@ const BaseIndicator = ({
|
||||
tooltipPosition = 'top'
|
||||
}: IProps) => {
|
||||
const { classes: styles } = useStyles();
|
||||
const style: any = {};
|
||||
const style: { fontSize?: string | number; } = {};
|
||||
|
||||
if (iconSize) {
|
||||
style.fontSize = iconSize;
|
||||
@@ -103,6 +103,7 @@ const BaseIndicator = ({
|
||||
className = { className }
|
||||
id = { id }>
|
||||
<Icon
|
||||
alt = { t(tooltipKey) }
|
||||
className = { iconClassName }
|
||||
color = { iconColor }
|
||||
id = { iconId }
|
||||
|
||||
@@ -24,6 +24,11 @@ interface IProps {
|
||||
*/
|
||||
footer?: any;
|
||||
|
||||
/**
|
||||
* Id for the included input, necessary for screen readers.
|
||||
*/
|
||||
id: string;
|
||||
|
||||
/**
|
||||
* Indicates if the component is disabled.
|
||||
*/
|
||||
@@ -174,6 +179,7 @@ class MultiSelectAutocomplete extends Component<IProps, IState> {
|
||||
error = { this.state.error }
|
||||
errorDialog = { errorDialog }
|
||||
filterValue = { this.state.filterValue }
|
||||
id = { this.props.id }
|
||||
isOpen = { this.state.isOpen }
|
||||
items = { this.state.items }
|
||||
noMatchesText = { noMatchesFound }
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { IStore } from '../../app/types';
|
||||
import { Sounds } from '../config/configType';
|
||||
import { AudioElement } from '../media/components/AbstractAudio';
|
||||
|
||||
@@ -66,7 +67,7 @@ export function _removeAudioElement(soundId: string) {
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function playSound(soundId: string) {
|
||||
return (dispatch: Function, getState: Function) => {
|
||||
return (dispatch: IStore['dispatch'], getState: IStore['getState']) => {
|
||||
const disabledSounds = getDisabledSounds(getState());
|
||||
|
||||
if (!disabledSounds.includes(soundId as Sounds) && !disabledSounds.find(id => soundId.startsWith(id))) {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { IStore } from '../../app/types';
|
||||
|
||||
/**
|
||||
* Returns the location of the sounds. On Web it's the relative path to
|
||||
* the sounds folder placed in the source root.
|
||||
@@ -7,3 +9,19 @@
|
||||
export function getSoundsPath() {
|
||||
return 'sounds';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set new audio output device on the global sound elements.
|
||||
*
|
||||
* @param {string } deviceId - The new output deviceId.
|
||||
* @returns {Function}
|
||||
*/
|
||||
export function setNewAudioOutputDevice(deviceId: string) {
|
||||
return function(_dispatch: IStore['dispatch'], getState: IStore['getState']) {
|
||||
const sounds = getState()['features/base/sounds'];
|
||||
|
||||
for (const [ , sound ] of sounds) {
|
||||
sound.audioElement?.setSinkId?.(deviceId);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user