mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-02 04:42:28 +00:00
Compare commits
129 Commits
android-ap
...
android-sd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 | ||
|
|
4c0c36d233 | ||
|
|
59f1ee1e1e | ||
|
|
1af90a208e | ||
|
|
22c6b72a75 | ||
|
|
d8c7f8de81 | ||
|
|
f76122f0b0 | ||
|
|
63927db9e4 | ||
|
|
6b28af8329 | ||
|
|
ccebccf8e6 | ||
|
|
279a4efb83 | ||
|
|
ceac1ab25f | ||
|
|
2ba6bcf172 | ||
|
|
ae0669fa07 | ||
|
|
71627f97f7 | ||
|
|
e35338b73d | ||
|
|
a112d38943 | ||
|
|
b705c63a65 | ||
|
|
b4c8f7d097 | ||
|
|
74bac9806f | ||
|
|
65248d7d29 | ||
|
|
dc037bc8dd | ||
|
|
a22db037c7 | ||
|
|
44cc0f7e9a | ||
|
|
eafb337cd1 | ||
|
|
9b3be66287 | ||
|
|
1a10a00f74 | ||
|
|
a196bc27b8 | ||
|
|
ac8e4d9828 | ||
|
|
a6ade336b7 | ||
|
|
350443ad34 | ||
|
|
4c37ef7a2c | ||
|
|
3eedc2a49d | ||
|
|
aaeb1a90e5 | ||
|
|
ed89f9af20 | ||
|
|
863ad0b0e6 | ||
|
|
e2d701a8cc | ||
|
|
2710273069 | ||
|
|
07af18e284 | ||
|
|
519e37f567 | ||
|
|
7cf61eb776 | ||
|
|
f81446909c | ||
|
|
b4115593c0 | ||
|
|
f8bd8b616e | ||
|
|
be55ccd6f4 | ||
|
|
e7db18bd80 | ||
|
|
dff41e0fcb | ||
|
|
43be4324af | ||
|
|
c33baf4c96 | ||
|
|
f95a356025 | ||
|
|
1ba7765898 | ||
|
|
0346fca434 | ||
|
|
d267b2499d | ||
|
|
e3e5f1fbfa | ||
|
|
4697192b43 |
@@ -1,6 +1,8 @@
|
||||
# The build artifacts of the jitsi-meet project.
|
||||
build/*
|
||||
|
||||
doc/*
|
||||
|
||||
# Third-party source code which we (1) do not want to modify or (2) try to
|
||||
# modify as little as possible.
|
||||
libs/*
|
||||
|
||||
16
.github/stale.yml
vendored
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
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -61,8 +61,9 @@ buck-out/
|
||||
|
||||
# fastlane
|
||||
#
|
||||
*/fastlane/report.xml
|
||||
*/fastlane/Preview.html
|
||||
**/fastlane/report.xml
|
||||
**/fastlane/Preview.html
|
||||
**/fastlane/test_output
|
||||
|
||||
# Build artifacts
|
||||
*.jsbundle
|
||||
@@ -93,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
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
android:launchMode="singleInstance"
|
||||
android:taskAffinity=""
|
||||
android:name=".MainActivity"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsPictureInPicture="true"
|
||||
|
||||
@@ -10,16 +10,17 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.0.4'
|
||||
classpath 'com.android.tools.build:gradle:7.1.1'
|
||||
classpath 'com.google.gms:google-services:4.3.14'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.2'
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
kotlinVersion = "1.7.0"
|
||||
buildToolsVersion = "31.0.0"
|
||||
compileSdkVersion = 32
|
||||
minSdkVersion = 23
|
||||
minSdkVersion = 24
|
||||
targetSdkVersion = 32
|
||||
supportLibVersion = "28.0.0"
|
||||
|
||||
|
||||
@@ -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.1
|
||||
|
||||
@@ -33,7 +33,7 @@ if [[ $MVN_HTTP == 1 ]]; then
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-DrepositoryId=${MVN_REPO_ID} \
|
||||
-Dfile=react-native-${RN_VERSION}.aar \
|
||||
-Dfile=react-native-${RN_VERSION}-release.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom || true
|
||||
@@ -58,7 +58,7 @@ else
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-Dfile=react-native-${RN_VERSION}.aar \
|
||||
-Dfile=react-native-${RN_VERSION}-release.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,12 @@ class AudioDeviceHandlerGeneric implements
|
||||
*/
|
||||
private AudioModeModule module;
|
||||
|
||||
/**
|
||||
* Constant defining a Hearing Aid. Only available on API level >= 28.
|
||||
* The value of: AudioDeviceInfo.TYPE_HEARING_AID
|
||||
*/
|
||||
private static final int TYPE_HEARING_AID = 23;
|
||||
|
||||
/**
|
||||
* Constant defining a USB headset. Only available on API level >= 26.
|
||||
* The value of: AudioDeviceInfo.TYPE_USB_HEADSET
|
||||
@@ -85,6 +91,7 @@ class AudioDeviceHandlerGeneric implements
|
||||
break;
|
||||
case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
|
||||
case AudioDeviceInfo.TYPE_WIRED_HEADSET:
|
||||
case TYPE_HEARING_AID:
|
||||
case TYPE_USB_HEADSET:
|
||||
devices.add(AudioModeModule.DEVICE_HEADPHONES);
|
||||
break;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
277
conference.js
277
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.
|
||||
*
|
||||
@@ -559,7 +576,7 @@ export default {
|
||||
);
|
||||
}
|
||||
|
||||
let tryCreateLocalTracks;
|
||||
let tryCreateLocalTracks = Promise.resolve([]);
|
||||
|
||||
// On Electron there is no permission prompt for granting permissions. That's why we don't need to
|
||||
// spend much time displaying the overlay screen. If GUM is not resolved within 15 seconds it will
|
||||
@@ -600,76 +617,66 @@ export default {
|
||||
|
||||
return [];
|
||||
});
|
||||
} else if (!requestedAudio && !requestedVideo) {
|
||||
// Resolve with no tracks
|
||||
tryCreateLocalTracks = Promise.resolve([]);
|
||||
} else {
|
||||
} else if (requestedAudio || requestedVideo) {
|
||||
APP.store.dispatch(gumPending(initialDevices, IGUMPendingState.PENDING_UNMUTE));
|
||||
tryCreateLocalTracks = createLocalTracksF({
|
||||
devices: initialDevices,
|
||||
timeout,
|
||||
firePermissionPromptIsShownEvent: true
|
||||
})
|
||||
.catch(err => {
|
||||
if (requestedAudio && requestedVideo) {
|
||||
|
||||
// Try audio only...
|
||||
errors.audioAndVideoError = err;
|
||||
|
||||
if (err.name === JitsiTrackErrors.TIMEOUT && !browser.isElectron()) {
|
||||
// In this case we expect that the permission prompt is still visible. There is no point of
|
||||
// executing GUM with different source. Also at the time of writing the following
|
||||
// inconsistency have been noticed in some browsers - if the permissions prompt is visible
|
||||
// and another GUM is executed the prompt does not change its content but if the user
|
||||
// clicks allow the user action isassociated with the latest GUM call.
|
||||
errors.audioOnlyError = err;
|
||||
errors.videoOnlyError = err;
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return createLocalTracksF(audioOptions);
|
||||
} else if (requestedAudio && !requestedVideo) {
|
||||
errors.audioOnlyError = err;
|
||||
|
||||
return [];
|
||||
} else if (requestedVideo && !requestedAudio) {
|
||||
errors.videoOnlyError = err;
|
||||
|
||||
return [];
|
||||
}
|
||||
logger.error('Should never happen');
|
||||
})
|
||||
.catch(err => {
|
||||
// Log this just in case...
|
||||
if (!requestedAudio) {
|
||||
logger.error('The impossible just happened', err);
|
||||
}
|
||||
errors.audioOnlyError = err;
|
||||
|
||||
// Try video only...
|
||||
return requestedVideo
|
||||
? createLocalTracksF({
|
||||
devices: [ MEDIA_TYPE.VIDEO ],
|
||||
firePermissionPromptIsShownEvent: true
|
||||
})
|
||||
: [];
|
||||
})
|
||||
.catch(err => {
|
||||
// Log this just in case...
|
||||
if (!requestedVideo) {
|
||||
logger.error('The impossible just happened', err);
|
||||
}
|
||||
errors.videoOnlyError = err;
|
||||
.catch(async error => {
|
||||
if (error.name === JitsiTrackErrors.TIMEOUT && !browser.isElectron()) {
|
||||
errors.audioAndVideoError = error;
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
// Retry with separate gUM calls.
|
||||
const gUMPromises = [];
|
||||
const tracks = [];
|
||||
|
||||
if (requestedAudio) {
|
||||
gUMPromises.push(createLocalTracksF(audioOptions));
|
||||
}
|
||||
|
||||
if (requestedVideo) {
|
||||
gUMPromises.push(createLocalTracksF({
|
||||
devices: [ MEDIA_TYPE.VIDEO ],
|
||||
timeout,
|
||||
firePermissionPromptIsShownEvent: true
|
||||
}));
|
||||
}
|
||||
|
||||
const results = await Promise.allSettled(gUMPromises);
|
||||
let errorMsg;
|
||||
|
||||
results.forEach((result, idx) => {
|
||||
if (result.status === 'fulfilled') {
|
||||
tracks.push(result.value[0]);
|
||||
} else {
|
||||
errorMsg = result.reason;
|
||||
const isAudio = idx === 0;
|
||||
|
||||
logger.error(`${isAudio ? 'Audio' : 'Video'} track creation failed with error ${errorMsg}`);
|
||||
if (isAudio) {
|
||||
errors.audioOnlyError = errorMsg;
|
||||
} else {
|
||||
errors.videoOnlyError = errorMsg;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (errors.audioOnlyError && errors.videoOnlyError) {
|
||||
errors.audioAndVideoError = errorMsg;
|
||||
}
|
||||
|
||||
return tracks;
|
||||
});
|
||||
}
|
||||
|
||||
// Hide the permissions prompt/overlay as soon as the tracks are
|
||||
// created. Don't wait for the connection to be made, since in some
|
||||
// cases, when auth is required, for instance, that won't happen until
|
||||
// the user inputs their credentials, but the dialog would be
|
||||
// overshadowed by the overlay.
|
||||
// Hide the permissions prompt/overlay as soon as the tracks are created. Don't wait for the connection to
|
||||
// be established, as in some cases like when auth is required, connection won't be established until the user
|
||||
// inputs their credentials, but the dialog would be overshadowed by the overlay.
|
||||
tryCreateLocalTracks.then(tracks => {
|
||||
APP.store.dispatch(mediaPermissionPromptVisibilityChanged(false));
|
||||
|
||||
@@ -810,43 +817,51 @@ export default {
|
||||
const initialOptions = {
|
||||
startAudioOnly: config.startAudioOnly,
|
||||
startScreenSharing: config.startScreenSharing,
|
||||
startWithAudioMuted: getStartWithAudioMuted(state)
|
||||
|| isUserInteractionRequiredForUnmute(state),
|
||||
startWithVideoMuted: getStartWithVideoMuted(state)
|
||||
|| isUserInteractionRequiredForUnmute(state)
|
||||
startWithAudioMuted: getStartWithAudioMuted(state) || isUserInteractionRequiredForUnmute(state),
|
||||
startWithVideoMuted: getStartWithVideoMuted(state) || isUserInteractionRequiredForUnmute(state)
|
||||
};
|
||||
|
||||
this.roomName = roomName;
|
||||
|
||||
try {
|
||||
// Initialize the device list first. This way, when creating tracks
|
||||
// based on preferred devices, loose label matching can be done in
|
||||
// cases where the exact ID match is no longer available, such as
|
||||
// when the camera device has switched USB ports.
|
||||
// when in startSilent mode we want to start with audio muted
|
||||
// Initialize the device list first. This way, when creating tracks based on preferred devices, loose label
|
||||
// matching can be done in cases where the exact ID match is no longer available, such as -
|
||||
// 1. When the camera device has switched USB ports.
|
||||
// 2. When in startSilent mode we want to start with audio muted
|
||||
await this._initDeviceList();
|
||||
} catch (error) {
|
||||
logger.warn('initial device list initialization failed', error);
|
||||
}
|
||||
|
||||
const handleStartAudioMuted = (options, tracks) => {
|
||||
if (options.startWithAudioMuted) {
|
||||
// Filter out the local tracks based on various config options, i.e., when user joins muted or is muted by
|
||||
// focus. However, audio track will always be created even though it is not added to the conference since we
|
||||
// want audio related features (noisy mic, talk while muted, etc.) to work even if the mic is muted.
|
||||
const handleInitialTracks = (options, tracks) => {
|
||||
let localTracks = tracks;
|
||||
|
||||
// No local tracks are added when user joins as a visitor.
|
||||
if (iAmVisitor(state)) {
|
||||
return [];
|
||||
}
|
||||
if (options.startWithAudioMuted || room?.isStartAudioMuted()) {
|
||||
// Always add the track on Safari because of a known issue where audio playout doesn't happen
|
||||
// if the user joins audio and video muted, i.e., if there is no local media capture.
|
||||
if (browser.isWebKitBased()) {
|
||||
this.muteAudio(true, true);
|
||||
} else {
|
||||
return tracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
|
||||
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
|
||||
}
|
||||
}
|
||||
if (room?.isStartVideoMuted()) {
|
||||
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.VIDEO);
|
||||
}
|
||||
|
||||
return tracks;
|
||||
return localTracks;
|
||||
};
|
||||
|
||||
if (isPrejoinPageVisible(state)) {
|
||||
_connectionPromise = connect(roomName).then(c => {
|
||||
// we want to initialize it early, in case of errors to be able
|
||||
// to gather logs
|
||||
// We want to initialize it early, in case of errors to be able to gather logs.
|
||||
APP.connection = c;
|
||||
|
||||
return c;
|
||||
@@ -859,48 +874,38 @@ export default {
|
||||
APP.store.dispatch(makePrecallTest(this._getConferenceOptions()));
|
||||
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
|
||||
const tracks = await tryCreateLocalTracks;
|
||||
const localTracks = await tryCreateLocalTracks;
|
||||
|
||||
// Initialize device list a second time to ensure device labels
|
||||
// get populated in case of an initial gUM acceptance; otherwise
|
||||
// they may remain as empty strings.
|
||||
// Initialize device list a second time to ensure device labels get populated in case of an initial gUM
|
||||
// acceptance; otherwise they may remain as empty strings.
|
||||
this._initDeviceList(true);
|
||||
|
||||
if (isPrejoinPageVisible(state)) {
|
||||
return APP.store.dispatch(initPrejoin(tracks, errors));
|
||||
APP.store.dispatch(gumPending([ MEDIA_TYPE.AUDIO, MEDIA_TYPE.VIDEO ], IGUMPendingState.NONE));
|
||||
|
||||
return APP.store.dispatch(initPrejoin(localTracks, errors));
|
||||
}
|
||||
|
||||
logger.debug('Prejoin screen no longer displayed at the time when tracks were created');
|
||||
|
||||
this._displayErrorsForCreateInitialLocalTracks(errors);
|
||||
|
||||
let localTracks = handleStartAudioMuted(initialOptions, tracks);
|
||||
const tracks = handleInitialTracks(initialOptions, localTracks);
|
||||
|
||||
// In case where gUM is slow and resolves after the startAudio/VideoMuted coming from jicofo, we can be
|
||||
// join unmuted even though jicofo had instruct us to mute, so let's respect that before passing the tracks
|
||||
if (!browser.isWebKitBased()) {
|
||||
if (room?.isStartAudioMuted()) {
|
||||
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.AUDIO);
|
||||
}
|
||||
}
|
||||
setGUMPendingStateOnFailedTracks(tracks);
|
||||
|
||||
if (room?.isStartVideoMuted()) {
|
||||
localTracks = localTracks.filter(track => track.getType() !== MEDIA_TYPE.VIDEO);
|
||||
}
|
||||
|
||||
// Do not add the tracks if the user has joined the call as a visitor.
|
||||
if (iAmVisitor(state)) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this._setLocalAudioVideoStreams(localTracks);
|
||||
return this._setLocalAudioVideoStreams(tracks);
|
||||
}
|
||||
|
||||
const [ tracks, con ] = await this.createInitialLocalTracksAndConnect(roomName, initialOptions);
|
||||
|
||||
this._initDeviceList(true);
|
||||
|
||||
return this.startConference(con, handleStartAudioMuted(initialOptions, tracks));
|
||||
const filteredTracks = handleInitialTracks(initialOptions, tracks);
|
||||
|
||||
setGUMPendingStateOnFailedTracks(filteredTracks);
|
||||
|
||||
return this.startConference(con, filteredTracks);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1023,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 => {
|
||||
@@ -1034,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);
|
||||
@@ -1073,7 +1082,7 @@ export default {
|
||||
*/
|
||||
muteVideo(mute, showUI = true) {
|
||||
if (this.videoSwitchInProgress) {
|
||||
console.warn('muteVideo - unable to perform operations while video switch is in progress');
|
||||
logger.warn('muteVideo - unable to perform operations while video switch is in progress');
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1114,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
|
||||
@@ -1138,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)
|
||||
@@ -1450,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);
|
||||
}
|
||||
@@ -1466,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`);
|
||||
});
|
||||
@@ -2008,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,
|
||||
@@ -2179,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'));
|
||||
|
||||
@@ -2423,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);
|
||||
}
|
||||
@@ -2461,7 +2492,7 @@ export default {
|
||||
}
|
||||
|
||||
// check for video
|
||||
if (!requestedInput.video) {
|
||||
if (requestedInput.video) {
|
||||
APP.store.dispatch(checkAndNotifyForNewDevice(newAvailDevices.videoInput, oldDevices.videoInput));
|
||||
}
|
||||
|
||||
@@ -2505,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}`);
|
||||
|
||||
@@ -2643,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
|
||||
|
||||
@@ -74,10 +74,6 @@
|
||||
a:active {
|
||||
color: black;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-corner {
|
||||
background: #3a3a3a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
3
debian/jitsi-meet-web-config.install
vendored
3
debian/jitsi-meet-web-config.install
vendored
@@ -1,3 +1,6 @@
|
||||
doc/debian/jitsi-meet/jitsi-meet.example /usr/share/jitsi-meet-web-config/
|
||||
doc/debian/jitsi-meet/jitsi-meet.example-apache /usr/share/jitsi-meet-web-config/
|
||||
config.js /usr/share/jitsi-meet-web-config/
|
||||
doc/jaas/nginx-jaas.conf /usr/share/jitsi-meet-web-config/
|
||||
doc/jaas/index-jaas.html /usr/share/jitsi-meet-web-config/
|
||||
doc/jaas/8x8.vc-config.js /usr/share/jitsi-meet-web-config/
|
||||
|
||||
2
debian/jitsi-meet-web.install
vendored
2
debian/jitsi-meet-web.install
vendored
@@ -12,3 +12,5 @@ resources/robots.txt /usr/share/jitsi-meet/
|
||||
resources/*.sh /usr/share/jitsi-meet/scripts/
|
||||
pwa-worker.js /usr/share/jitsi-meet/
|
||||
manifest.json /usr/share/jitsi-meet/
|
||||
doc/jaas/move-to-jaas.sh /usr/share/jitsi-meet/scripts/
|
||||
doc/jaas/update-asap-daily.sh /usr/share/jitsi-meet/scripts/
|
||||
|
||||
@@ -58,6 +58,8 @@ server {
|
||||
|
||||
add_header Strict-Transport-Security "max-age=63072000" always;
|
||||
set $prefix "";
|
||||
set $custom_index "";
|
||||
set $config_js_location /etc/jitsi/meet/jitsi-meet.example.com-config.js;
|
||||
|
||||
ssl_certificate /etc/jitsi/meet/jitsi-meet.example.com.crt;
|
||||
ssl_certificate_key /etc/jitsi/meet/jitsi-meet.example.com.key;
|
||||
@@ -77,8 +79,10 @@ server {
|
||||
gzip_proxied no-cache no-store private expired auth;
|
||||
gzip_min_length 512;
|
||||
|
||||
include /etc/jitsi/meet/jaas/*.conf;
|
||||
|
||||
location = /config.js {
|
||||
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
|
||||
alias $config_js_location;
|
||||
}
|
||||
|
||||
location = /external_api.js {
|
||||
@@ -92,6 +96,11 @@ server {
|
||||
proxy_set_header Host $http_host;
|
||||
}
|
||||
|
||||
location ~ ^/_api/public/(.*)$ {
|
||||
autoindex off;
|
||||
alias /etc/jitsi/meet/public/$1;
|
||||
}
|
||||
|
||||
# ensure all static content can always be found first
|
||||
location ~ ^/(libs|css|static|images|fonts|lang|sounds|.well-known)/(.*)$
|
||||
{
|
||||
@@ -142,11 +151,12 @@ server {
|
||||
#}
|
||||
|
||||
location ~ ^/([^/?&:'"]+)$ {
|
||||
set $roomname "$1";
|
||||
try_files $uri @root_path;
|
||||
}
|
||||
|
||||
location @root_path {
|
||||
rewrite ^/(.*)$ / break;
|
||||
rewrite ^/(.*)$ /$custom_index break;
|
||||
}
|
||||
|
||||
location ~ ^/([^/?&:'"]+)/config.js$
|
||||
@@ -154,7 +164,7 @@ server {
|
||||
set $subdomain "$1.";
|
||||
set $subdir "$1/";
|
||||
|
||||
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
|
||||
alias $config_js_location;
|
||||
}
|
||||
|
||||
# Matches /(TENANT)/pwa-worker.js or /(TENANT)/manifest.json to rewrite to / and look for file
|
||||
|
||||
7
doc/jaas/8x8.vc-config.js
Normal file
7
doc/jaas/8x8.vc-config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
</script>
|
||||
<script src="https://8x8.vc/<!--# echo var="subdir" default="" -->config.js" onload="{
|
||||
config.p2p.disabledCodec='VP9';
|
||||
config.videoQuality.disabledCodec='VP9';
|
||||
config.e2ee = { externallyManagedKey: true };
|
||||
}"/>
|
||||
<script>
|
||||
22
doc/jaas/README.md
Normal file
22
doc/jaas/README.md
Normal file
@@ -0,0 +1,22 @@
|
||||
## How to switch your deployment to [JaaS](https://jaas.8x8.vc) in one easy step
|
||||
|
||||
Note: By default it will have e2ee(end-to-end) encryption enabled that works only on chromium based browsers (Chrome, Edge, ...). If a participant joins from another browser or mobile the e2ee is turned off.
|
||||
|
||||
In order to use your deployment with JaaS you first need to login to your [JaaS Developer console](https://jaas.8x8.vc/#/apikeys) and generate a key pair.
|
||||
Use `Add API key` button and then `Generate API key pair`. Make sure you download the generated private key from:
|
||||
|
||||
<img src="generated_key_dialog.png" height="250">
|
||||
|
||||
Make sure you transfer this downloaded private key to your server. Copy the key id from:
|
||||
|
||||
<img src="api_keys_kid.png" height="200">
|
||||
|
||||
Now on your server run the helper script passing the private key file and the key id:
|
||||
|
||||
```
|
||||
sudo /usr/share/jitsi-meet/scripts/move-to-jaas.sh /my/path/test-key.pk <key_id>
|
||||
```
|
||||
|
||||
More information about JaaS Api keys at: https://developer.8x8.com/jaas/docs/jaas-console-api-keys
|
||||
|
||||
If you want to adjust the enabled services you can do that in /etc/jits/meet/jaas/nginx-jaas.conf. The part after `proxy_set_body` is the jwt token content that will be used for the client tokens. More info about the JaaS tokens: https://developer.8x8.com/jaas/docs/api-keys-jwt
|
||||
BIN
doc/jaas/api_keys_kid.png
Normal file
BIN
doc/jaas/api_keys_kid.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 23 KiB |
BIN
doc/jaas/generated_key_dialog.png
Normal file
BIN
doc/jaas/generated_key_dialog.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
33
doc/jaas/index-jaas.html
Normal file
33
doc/jaas/index-jaas.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src='external_api.js' async></script>
|
||||
<style>html, body, #jaas-container { height: 100%; }</style>
|
||||
<script type="text/javascript">
|
||||
function getRoomName(pathname) {
|
||||
const contextRootEndIndex = pathname.lastIndexOf('/');
|
||||
|
||||
return pathname.substring(contextRootEndIndex + 1);
|
||||
}
|
||||
window.onload = () => {
|
||||
const jaasJwt = <!--#include virtual="/jaas-jwt" -->;
|
||||
const api = new JitsiMeetExternalAPI(
|
||||
window.location.host, {
|
||||
roomName: `${jaasJwt.tenant}/${jaasJwt.confId}`,
|
||||
parentNode: document.querySelector('#jaas-container'),
|
||||
jwt: jaasJwt.token,
|
||||
e2eeKey: jaasJwt.e2eeKey
|
||||
});
|
||||
api.addListener('videoConferenceJoined', () => {
|
||||
if (jaasJwt.e2eeKey) {
|
||||
console.info('Toggling e2ee on!')
|
||||
api.executeCommand('toggleE2EE', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="jaas-container" />
|
||||
</body>
|
||||
</html>
|
||||
59
doc/jaas/move-to-jaas.sh
Executable file
59
doc/jaas/move-to-jaas.sh
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
PRIVATE_KEY=$1
|
||||
JAAS_KEY_ID=$2
|
||||
|
||||
if [ ! -f "${PRIVATE_KEY}" ] ; then
|
||||
echo "You need to specify a correct path for the private key as a first argument."
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ ! "${JAAS_KEY_ID}" =~ ^vpaas-magic-cookie-[0-9a-z]+/[0-9a-z]+$ ]]; then
|
||||
echo "Invalid key id passed as a second argument."
|
||||
exit 2;
|
||||
fi
|
||||
|
||||
command -v node >/dev/null 2>&1 || { echo >&2 "You must install node first, go to https://nodejs.org. Aborting."; exit 4; }
|
||||
|
||||
NODE_VER=$(node -v);
|
||||
NODE_MAJOR_VER=$(echo ${NODE_VER:1} | cut -d. -f1);
|
||||
|
||||
if [ "$NODE_MAJOR_VER" -lt "18" ]; then
|
||||
echo "Please install latest LTS version of node (18+)";
|
||||
exit 3;
|
||||
fi
|
||||
|
||||
# we need this util for debconf-set-selections
|
||||
sudo apt install debconf-utils
|
||||
|
||||
# Let's pre-set some settings for token-generator
|
||||
cat << EOF | sudo debconf-set-selections
|
||||
token-generator token-generator/private-key string ${PRIVATE_KEY}
|
||||
token-generator token-generator/kid string ${JAAS_KEY_ID}
|
||||
EOF
|
||||
|
||||
apt install token-generator
|
||||
|
||||
mkdir -p /etc/jitsi/meet/jaas
|
||||
|
||||
VPASS_COOKIE=$(echo -n ${JAAS_KEY_ID}| cut -d/ -f1)
|
||||
cp /usr/share/jitsi-meet-web-config/nginx-jaas.conf /etc/jitsi/meet/jaas
|
||||
sed -i "s/jaas_magic_cookie/${VPASS_COOKIE}/g" /etc/jitsi/meet/jaas/nginx-jaas.conf
|
||||
|
||||
cp /usr/share/jitsi-meet-web-config/8x8.vc-config.js /etc/jitsi/meet/jaas/
|
||||
echo "set \$config_js_location /etc/jitsi/meet/jaas/8x8.vc-config.js;" >> /etc/jitsi/meet/jaas/jaas-vars
|
||||
echo "set \$custom_index index-jaas.html;" >> /etc/jitsi/meet/jaas/jaas-vars
|
||||
|
||||
ln -s /usr/share/jitsi-meet-web-config/index-jaas.html /usr/share/jitsi-meet/index-jaas.html
|
||||
|
||||
# let's create the daily key now
|
||||
/usr/share/jitsi-meet/scripts/update-asap-daily.sh
|
||||
|
||||
# let's add to cron daily the update of the asap key
|
||||
if [ -d /etc/cron.daily ]; then
|
||||
ln -s /usr/share/jitsi-meet/scripts/update-asap-daily.sh /etc/cron.daily/update-jaas-asap.sh
|
||||
else
|
||||
echo "No /etc/cron.daily. Please add to your cron jobs to execute as root daily the script: /usr/share/jitsi-meet/scripts/update-asap-daily.sh"
|
||||
fi
|
||||
23
doc/jaas/nginx-jaas.conf
Normal file
23
doc/jaas/nginx-jaas.conf
Normal file
@@ -0,0 +1,23 @@
|
||||
include /etc/jitsi/meet/jaas/jaas-vars;
|
||||
location = /jaas-jwt {
|
||||
include /etc/jitsi/token-generator/daily-key;
|
||||
ssi on;
|
||||
proxy_method POST;
|
||||
proxy_set_header content-type "application/json";
|
||||
proxy_set_header Accept-Encoding "";
|
||||
proxy_set_header Authorization "Bearer $jaas_asap_key";
|
||||
proxy_pass_request_body off;
|
||||
proxy_set_body '{"sub":"jaas_magic_cookie","context":{"features":{"livestreaming":false,"outbound-call":false,"sip-outbound-call":false,"transcription":false,"recording":false},"user":{"moderator":true}},"room": "$roomname"}';
|
||||
proxy_pass http://127.0.0.1:8017/generate/client?e2eeKey=true&confId=true;
|
||||
}
|
||||
|
||||
location @magic_root_path {
|
||||
rewrite ^/(.*)$ /index.html break;
|
||||
}
|
||||
|
||||
# Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
|
||||
location ~ ^/jaas_magic_cookie/(.*)$ {
|
||||
set $subdomain "jaas_magic_cookie.";
|
||||
set $subdir "jaas_magic_cookie/";
|
||||
try_files $1 @magic_root_path;
|
||||
}
|
||||
9
doc/jaas/update-asap-daily.sh
Executable file
9
doc/jaas/update-asap-daily.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
JWT_KID=$(cat /etc/jitsi/token-generator/config | grep SYSTEM_ASAP_BASE_URL_MAPPINGS | cut -d= -f2- | jq -r .[].kid)
|
||||
JWT_DATE=$(echo -n $JWT_KID | cut -d/ -f2-)
|
||||
JWT_DATE=${JWT_DATE#jwt-}
|
||||
KEY_FILE=/etc/jitsi/token-generator/daily-key
|
||||
echo -n "set \$jaas_asap_key " > ${KEY_FILE}
|
||||
ASAP_KEY=$(ASAP_SIGNING_KEY_FILE=/etc/jitsi/token-generator/asap-${JWT_DATE}.key ASAP_JWT_KID="${JWT_KID}" ASAP_EXPIRES_IN="1 day" node /usr/share/token-generator/jwt.js| tail -n1)
|
||||
echo -n "${ASAP_KEY};" >> ${KEY_FILE}
|
||||
|
||||
service nginx reload
|
||||
1
globals.d.ts
vendored
1
globals.d.ts
vendored
@@ -21,6 +21,7 @@ declare global {
|
||||
JitsiMeetElectron?: any;
|
||||
// selenium tests handler
|
||||
_sharedVideoPlayer: any;
|
||||
alwaysOnTop: { api: any };
|
||||
}
|
||||
|
||||
interface Document {
|
||||
|
||||
1
globals.native.d.ts
vendored
1
globals.native.d.ts
vendored
@@ -30,6 +30,7 @@ interface IWindow {
|
||||
setImmediate: typeof setImmediate;
|
||||
clearImmediate: typeof clearImmediate;
|
||||
addEventListener: Function;
|
||||
removeEventListener: Function;
|
||||
}
|
||||
|
||||
interface INavigator {
|
||||
|
||||
10
ios/Podfile
10
ios/Podfile
@@ -1,11 +1,13 @@
|
||||
require_relative '../node_modules/react-native/scripts/react_native_pods'
|
||||
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
|
||||
|
||||
platform :ios, '12.0'
|
||||
platform :ios, '12.4'
|
||||
workspace 'jitsi-meet'
|
||||
|
||||
install! 'cocoapods', :deterministic_uuids => false
|
||||
|
||||
production = ENV["PRODUCTION"] == "1"
|
||||
|
||||
target 'JitsiMeet' do
|
||||
project 'app/app.xcodeproj'
|
||||
|
||||
@@ -21,8 +23,10 @@ target 'JitsiMeetSDK' do
|
||||
#
|
||||
|
||||
config = use_native_modules!
|
||||
flags = get_default_flags()
|
||||
use_react_native!(
|
||||
:path => config["reactNativePath"],
|
||||
:path => config[:reactNativePath],
|
||||
:production => production,
|
||||
:hermes_enabled => false,
|
||||
:fabric_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
@@ -81,7 +85,7 @@ post_install do |installer|
|
||||
end
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['SUPPORTS_MACCATALYST'] = 'NO'
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
|
||||
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.4'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
470
ios/Podfile.lock
470
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.10)
|
||||
- FBReactNativeSpec (0.69.10):
|
||||
- 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.10)
|
||||
- RCTTypeSafety (= 0.69.10)
|
||||
- React-Core (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- 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):
|
||||
@@ -134,7 +134,7 @@ PODS:
|
||||
- AppAuth/Core (~> 1.6)
|
||||
- GTMSessionFetcher/Core (< 3.0, >= 1.5)
|
||||
- GTMSessionFetcher/Core (2.3.0)
|
||||
- JitsiWebRTC (111.0.1)
|
||||
- JitsiWebRTC (111.0.2)
|
||||
- libwebp (1.2.4):
|
||||
- libwebp/demux (= 1.2.4)
|
||||
- libwebp/mux (= 1.2.4)
|
||||
@@ -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.10)
|
||||
- RCTTypeSafety (0.69.10):
|
||||
- FBLazyVector (= 0.69.10)
|
||||
- RCTRequired (= 0.69.10)
|
||||
- React-Core (= 0.69.10)
|
||||
- React (0.69.10):
|
||||
- React-Core (= 0.69.10)
|
||||
- React-Core/DevSupport (= 0.69.10)
|
||||
- React-Core/RCTWebSocket (= 0.69.10)
|
||||
- React-RCTActionSheet (= 0.69.10)
|
||||
- React-RCTAnimation (= 0.69.10)
|
||||
- React-RCTBlob (= 0.69.10)
|
||||
- React-RCTImage (= 0.69.10)
|
||||
- React-RCTLinking (= 0.69.10)
|
||||
- React-RCTNetwork (= 0.69.10)
|
||||
- React-RCTSettings (= 0.69.10)
|
||||
- React-RCTText (= 0.69.10)
|
||||
- React-RCTVibration (= 0.69.10)
|
||||
- React-bridging (0.69.10):
|
||||
- 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.10)
|
||||
- React-callinvoker (0.69.10)
|
||||
- React-Codegen (0.69.10):
|
||||
- FBReactNativeSpec (= 0.69.10)
|
||||
- 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.10)
|
||||
- RCTTypeSafety (= 0.69.10)
|
||||
- React-Core (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-Core (0.69.10):
|
||||
- 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.10)
|
||||
- React-cxxreact (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.68.6):
|
||||
- React-Core/CoreModulesHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/Default (0.68.6):
|
||||
- React-Core/Default (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.68.6):
|
||||
- React-Core/DevSupport (0.69.10):
|
||||
- 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.10)
|
||||
- React-Core/RCTWebSocket (= 0.69.10)
|
||||
- React-cxxreact (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-jsinspector (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.68.6):
|
||||
- React-Core/RCTActionSheetHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.68.6):
|
||||
- React-Core/RCTAnimationHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.68.6):
|
||||
- React-Core/RCTBlobHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.68.6):
|
||||
- React-Core/RCTImageHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.68.6):
|
||||
- React-Core/RCTLinkingHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.68.6):
|
||||
- React-Core/RCTNetworkHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.68.6):
|
||||
- React-Core/RCTSettingsHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.68.6):
|
||||
- React-Core/RCTTextHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.68.6):
|
||||
- React-Core/RCTVibrationHeaders (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.68.6):
|
||||
- React-Core/RCTWebSocket (0.69.10):
|
||||
- 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.10)
|
||||
- React-cxxreact (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsiexecutor (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- Yoga
|
||||
- React-CoreModules (0.68.6):
|
||||
- React-CoreModules (0.69.10):
|
||||
- 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.10)
|
||||
- React-Codegen (= 0.69.10)
|
||||
- React-Core/CoreModulesHeaders (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-RCTImage (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-cxxreact (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-jsinspector (= 0.69.10)
|
||||
- React-logger (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- React-runtimeexecutor (= 0.69.10)
|
||||
- React-jsi (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi/Default (0.69.10):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.68.6):
|
||||
- React-jsiexecutor (0.69.10):
|
||||
- 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.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- React-jsinspector (0.69.10)
|
||||
- React-logger (0.69.10):
|
||||
- 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.10)
|
||||
- React-RCTActionSheet (0.69.10):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.69.10)
|
||||
- React-RCTAnimation (0.69.10):
|
||||
- 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.10)
|
||||
- React-Codegen (= 0.69.10)
|
||||
- React-Core/RCTAnimationHeaders (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-RCTBlob (0.69.10):
|
||||
- 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.10)
|
||||
- React-Core/RCTBlobHeaders (= 0.69.10)
|
||||
- React-Core/RCTWebSocket (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-RCTNetwork (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-RCTImage (0.69.10):
|
||||
- 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.10)
|
||||
- React-Codegen (= 0.69.10)
|
||||
- React-Core/RCTImageHeaders (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-RCTNetwork (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-RCTLinking (0.69.10):
|
||||
- React-Codegen (= 0.69.10)
|
||||
- React-Core/RCTLinkingHeaders (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-RCTNetwork (0.69.10):
|
||||
- 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.10)
|
||||
- React-Codegen (= 0.69.10)
|
||||
- React-Core/RCTNetworkHeaders (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-RCTSettings (0.69.10):
|
||||
- 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.10)
|
||||
- React-Codegen (= 0.69.10)
|
||||
- React-Core/RCTSettingsHeaders (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-RCTText (0.69.10):
|
||||
- React-Core/RCTTextHeaders (= 0.69.10)
|
||||
- React-RCTVibration (0.69.10):
|
||||
- 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.10)
|
||||
- React-Core/RCTVibrationHeaders (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (= 0.69.10)
|
||||
- React-runtimeexecutor (0.69.10):
|
||||
- React-jsi (= 0.69.10)
|
||||
- ReactCommon/turbomodule/core (0.69.10):
|
||||
- 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.10)
|
||||
- React-callinvoker (= 0.69.10)
|
||||
- React-Core (= 0.69.10)
|
||||
- React-cxxreact (= 0.69.10)
|
||||
- React-jsi (= 0.69.10)
|
||||
- React-logger (= 0.69.10)
|
||||
- React-perflogger (= 0.69.10)
|
||||
- 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: a8af91c2b5a0029d12ff6b32e428863d63c48991
|
||||
FBReactNativeSpec: ec5e878f6452a3de5430e0b2324a4d4ae6ac63f6
|
||||
Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
|
||||
FirebaseAnalytics: 7761cbadb00a717d8d0939363eb46041526474fa
|
||||
FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1
|
||||
@@ -716,59 +716,59 @@ 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
|
||||
GoogleUtilities: 9aa0ad5a7bc171f8bae016300bfcfa3fb8425749
|
||||
GTMAppAuth: 0ff230db599948a9ad7470ca667337803b3fc4dd
|
||||
GTMSessionFetcher: 3a63d75eecd6aa32c2fc79f578064e1214dfdec2
|
||||
JitsiWebRTC: 9619c1f71cc16eeca76df68aa2d213c6d63274a8
|
||||
JitsiWebRTC: 80f62908fcf2a1160e0d14b584323fb6e6be630b
|
||||
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
|
||||
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
|
||||
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: 3581db0757e7ff9be10718a56b3d79b6a6bd3bdf
|
||||
RCTTypeSafety: ce13e630c48340401ebfb28710959913f74b8b36
|
||||
React: cca8f2b7cce018f79847ca79847fa367b206e8a1
|
||||
React-bridging: b893643f09d3964afba6c347e00dd86cf10691e5
|
||||
React-callinvoker: 9ac7cba30428eddf7a06d1253f8e7561b5c97334
|
||||
React-Codegen: 65ff9fbddf8a17a6d4f495f71d365288f934a93a
|
||||
React-Core: 550b694774bc778b5c7bf7608fc12a484e01ec05
|
||||
React-CoreModules: c332d5b416cb3ccf972e7af79d496498a700e073
|
||||
React-cxxreact: c5c4106bfd2d0cee80b848e33b7ff4e35a721b16
|
||||
React-jsi: 6ff3fb9b9764a499c959e0096c0d384fa2b4beef
|
||||
React-jsiexecutor: 388f1c99404c848141d7ea162f61233d04829ede
|
||||
React-jsinspector: a4463b3411b8b9b37153255ef694a84c77ba3c7f
|
||||
React-logger: 2a0497622cbabc47fb769d97620952df14c1f814
|
||||
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: bc57c4a953c1ec913b0d984cf4f2b9842a12bde0
|
||||
React-RCTActionSheet: 3efa3546119a1050f6c34a461b386dd9e36eaf0b
|
||||
React-RCTAnimation: e58fb9f1adf7b38af329881ea2740f43ffeea854
|
||||
React-RCTBlob: d2238645553c3ec787324268c0676148d86e6cc4
|
||||
React-RCTImage: e6d7c9ab978cae99364fcc96b9238fc7740a13da
|
||||
React-RCTLinking: 329e88ce217dad464ef34b5d0c40b3ceaac6c9ec
|
||||
React-RCTNetwork: c8967f2382aac31761ddb750fee53fa34cf7a4ee
|
||||
React-RCTSettings: 8a825b4b5ea58f6713a7c97eea6cc82e9895188b
|
||||
React-RCTText: ffcaac5c66bc065f2ccf79b6fe34585adb9e589b
|
||||
React-RCTVibration: 0039c986626b78242401931bb23c803935fae9d1
|
||||
React-runtimeexecutor: 5ebf1ddaa706bf2986123f22d2cad905443c2c5f
|
||||
ReactCommon: 65754b8932ea80272714988268bbfb9f303264a5
|
||||
RNCalendarEvents: 7e65eb4a94f53c1744d1e275f7fafcfaa619f7a3
|
||||
RNCAsyncStorage: 005c0e2f09575360f142d0d1f1f15e4ec575b1af
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
@@ -780,8 +780,8 @@ SPEC CHECKSUMS:
|
||||
RNSound: 27e8268bdb0a1f191f219a33267f7e0445e8d62f
|
||||
RNSVG: f3b60aeeaa81960e2e0536c3a9eef50b667ef3a9
|
||||
RNWatch: dae6c858a2051dbdcfb00b9a86cf4d90400263b4
|
||||
Yoga: 7929b92b1828675c1bebeb114dae8cb8fa7ef6a3
|
||||
Yoga: d24d6184b6b85f742536bd93bd07d69d7b9bb4c1
|
||||
|
||||
PODFILE CHECKSUM: d9116cb59cd7e921956e45de7cbbd75bef3862c1
|
||||
PODFILE CHECKSUM: e3579df5272b8b697c9fdc0e55aa0845b189c4dd
|
||||
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
@@ -439,7 +439,7 @@
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "app" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
compatibilityVersion = "Xcode 12.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
@@ -1025,9 +1025,10 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
@@ -1078,8 +1079,9 @@
|
||||
"$(inherited)",
|
||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -98,7 +98,6 @@ platform :ios do
|
||||
demo_account_required: false,
|
||||
distribute_external: true,
|
||||
groups: ENV["JITSI_BETA_TESTING_GROUPS"],
|
||||
reject_build_waiting_for_review: true,
|
||||
uses_non_exempt_encryption: false
|
||||
)
|
||||
|
||||
|
||||
@@ -472,7 +472,7 @@
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 0BD906DF1EC0C00300C8C18E /* Build configuration list for PBXProject "sdk" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
compatibilityVersion = "Xcode 12.0";
|
||||
developmentRegion = en;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
@@ -526,7 +526,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "export NODE_BINARY=node\nexport NODE_ARGS=\"--max_old_space_size=4096\"\n../../node_modules/react-native/scripts/react-native-xcode.sh\n";
|
||||
shellScript = "WITH_ENVIRONMENT=\"../../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n";
|
||||
};
|
||||
26796D8589142D80C8AFDA51 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -551,17 +551,12 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK-resources.sh",
|
||||
"${PODS_ROOT}/Amplitude/Sources/Resources/ComodoRsaDomainValidationCA.der",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/GoogleSignIn/GoogleSignIn.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoRsaDomainValidationCA.der",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleSignIn.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -641,15 +636,12 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources.sh",
|
||||
"${PODS_ROOT}/Amplitude/Sources/Resources/ComodoRsaDomainValidationCA.der",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle",
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ComodoRsaDomainValidationCA.der",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle",
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-JitsiMeetSDKLite/Pods-JitsiMeetSDKLite-resources-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
@@ -781,9 +773,10 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@@ -837,8 +830,9 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 12.4;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>99.0.0</string>
|
||||
<string>8.2.1</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.1</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
@@ -156,6 +156,7 @@
|
||||
"localport_plural": "Portas locais:",
|
||||
"maxEnabledResolution": "enviar máx",
|
||||
"more": "Mostrar mais",
|
||||
"no": "não",
|
||||
"packetloss": "Perda de pacote:",
|
||||
"participant_id": "Participante id:",
|
||||
"quality": {
|
||||
@@ -174,7 +175,8 @@
|
||||
"status": "Ligação:",
|
||||
"transport": "Transporte:",
|
||||
"transport_plural": "Transportes:",
|
||||
"video_ssrc": "Vídeo SSRC:"
|
||||
"video_ssrc": "Vídeo SSRC:",
|
||||
"yes": "sim"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "Mais cedo",
|
||||
@@ -319,13 +321,13 @@
|
||||
"micPermissionDeniedError": "Não concedeu autorização para utilizar o seu microfone. Ainda pode participar na conferência, mas outros não o ouvirão. Use o botão da câmara na barra de endereço para corrigir isto.",
|
||||
"micTimeoutError": "Não foi possível iniciar a fonte de áudio. Tempo limite expirado!",
|
||||
"micUnknownError": "Não pode usar microfone por uma razão desconhecida.",
|
||||
"moderationAudioLabel": "Permitir aos participantes reativar o som",
|
||||
"moderationVideoLabel": "Permitir aos participantes reativar o vídeo",
|
||||
"muteEveryoneDialog": "Os participantes podem reativar o som a qualquer momento.",
|
||||
"moderationAudioLabel": "Permitir aos participantes ligar o som",
|
||||
"moderationVideoLabel": "Permitir aos participantes ligar a câmara",
|
||||
"muteEveryoneDialog": "Os participantes podem ligar o som a qualquer momento.",
|
||||
"muteEveryoneDialogModerationOn": "Os participantes podem enviar um pedido para falar a qualquer momento.",
|
||||
"muteEveryoneElseDialog": "Uma vez silenciados, não poderá reativá-los, mas eles podem reativar-se a qualquer momento.",
|
||||
"muteEveryoneElseDialog": "Uma vez silenciados, não poderá reativá-los, mas eles podem ligar o microfone a qualquer momento.",
|
||||
"muteEveryoneElseTitle": "Silenciar todos excepto {{whom}}?",
|
||||
"muteEveryoneElsesVideoDialog": "Quando a câmara for desativada, não poderá voltar a ligá-la, mas eles podem voltar a ligá-la em qualquer momento.",
|
||||
"muteEveryoneElsesVideoDialog": "Quando a câmara for desligada, não poderá voltar a ligá-la, mas eles podem voltar a ligá-la em qualquer momento.",
|
||||
"muteEveryoneElsesVideoTitle": "Parar o vídeo de todos excepto {{whom}}?",
|
||||
"muteEveryoneSelf": "você mesmo",
|
||||
"muteEveryoneStartMuted": "A partir de agora, toda a gente começa a ficar calada",
|
||||
@@ -673,8 +675,10 @@
|
||||
"connectedTwoMembers": "{{first}} e {{second}} entraram na reunião",
|
||||
"dataChannelClosed": "Deficiência na qualidade do vídeo",
|
||||
"dataChannelClosedDescription": "O canal de ponte foi desconectado e, portanto, a qualidade do vídeo está limitada à sua configuração mais baixa.",
|
||||
"disabledIframe": "A incorporação destina-se apenas a fins de demonstração, pelo que esta chamada será desligada em {{timeout}} minutos.",
|
||||
"disconnected": "desconectado",
|
||||
"displayNotifications": "Mostrar notificações para",
|
||||
"dontRemindMe": "Não me lembre",
|
||||
"focus": "Foco da conferência",
|
||||
"focusFail": "{{component}} não disponĩvel - tente em {{ms}} seg.",
|
||||
"gifsMenu": "GIPHY",
|
||||
@@ -754,8 +758,8 @@
|
||||
"actions": {
|
||||
"allow": "Permitir aos participantes:",
|
||||
"allowVideo": "Permitir vídeo",
|
||||
"askUnmute": "Pedir para ligar o microfone",
|
||||
"audioModeration": "Ativar o microfone deles",
|
||||
"askUnmute": "Pedir para ligar o som",
|
||||
"audioModeration": "Ligar o microfone deles",
|
||||
"blockEveryoneMicCamera": "Bloquear o microfone e a câmara de todos",
|
||||
"invite": "Convidar alguém",
|
||||
"moreModerationActions": "Mais opções de moderação",
|
||||
@@ -866,9 +870,11 @@
|
||||
"lookGood": "O seu microfone funciona corretamente",
|
||||
"or": "ou",
|
||||
"premeeting": "Pré-reunião",
|
||||
"proceedAnyway": "Continuar na mesma",
|
||||
"screenSharingError": "Erro de partilha de ecrã:",
|
||||
"showScreen": "Ativar o ecrã de pré-reunião",
|
||||
"startWithPhone": "Iniciar com o áudio do telefone",
|
||||
"unsafeRoomConsent": "Compreendo os riscos, quero participar na reunião",
|
||||
"videoOnlyError": "Erro de vídeo:",
|
||||
"videoTrackError": "Não foi possível criar a pista de vídeo.",
|
||||
"viewAllNumbers": "ver todos os números"
|
||||
@@ -944,7 +950,7 @@
|
||||
"noStreams": "Não foi detetado nenhum sinal áudio ou vídeo.",
|
||||
"off": "Gravação parada",
|
||||
"offBy": "{{name}} parou a gravação",
|
||||
"on": "Gravando",
|
||||
"on": "Começou a gravação",
|
||||
"onBy": "{{name}} iniciou a gravação",
|
||||
"onlyRecordSelf": "Gravar apenas as minhas transmissões áudio e vídeo",
|
||||
"pending": "Preparando para gravar a reunião...",
|
||||
@@ -970,8 +976,14 @@
|
||||
"security": {
|
||||
"about": "Pode adicionar uma $t(lockRoomPassword) à sua reunião. Os participantes terão de fornecer a $t(lockRoomPassword) antes de serem autorizados a participar na reunião.",
|
||||
"aboutReadOnly": "Os participantes moderadores podem acrescentar uma $t(lockRoomPassword) à reunião. Os participantes terão de fornecer a $t(lockRoomPassword) antes de serem autorizados a participar na reunião.",
|
||||
"insecureRoomNameWarning": "O nome da sala é inseguro. Participantes indesejados podem juntar-se à sua conferência. Considere proteger a sua reunião utilizando o botão de segurança.",
|
||||
"title": "Opções de segurança"
|
||||
"insecureRoomNameWarningNative": "O nome da sala não é seguro. Participantes indesejados podem juntar-se à sua reunião. {{recommendAction}} Saiba mais sobre como proteger a sua reunião ",
|
||||
"insecureRoomNameWarningWeb": "O nome da sala não é seguro. Participantes indesejados podem juntar-se à sua reunião. {{recommendAction}} Saiba mais sobre como proteger a sua reunião <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">here</a>.",
|
||||
"title": "Opções de Segurança",
|
||||
"unsafeRoomActions": {
|
||||
"meeting": "Considere a possibilidade de proteger a sua reunião utilizando o botão de segurança.",
|
||||
"prejoin": "Considere a utilização de um nome de reunião mais personalizado.",
|
||||
"welcome": "Considere utilizar um nome de reunião mais personalizado ou selecione uma das sugestões."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"audio": "Áudio",
|
||||
@@ -1146,6 +1158,7 @@
|
||||
"privateMessage": "Enviar mensagem privada",
|
||||
"profile": "Editar o seu perfil",
|
||||
"raiseHand": "Levantar a mão",
|
||||
"reactions": "Reações",
|
||||
"reactionsMenu": "Menu de reações",
|
||||
"recording": "Mudar gravação",
|
||||
"remoteMute": "Participante sem som",
|
||||
@@ -1243,6 +1256,7 @@
|
||||
"reactionLike": "Enviar reação de aprovado",
|
||||
"reactionSilence": "Enviar reação de silêncio",
|
||||
"reactionSurprised": "Enviar reação de surpreendido",
|
||||
"reactions": "Reações",
|
||||
"security": "Opções de segurança",
|
||||
"selectBackground": "Selecionar plano de fundo",
|
||||
"shareRoom": "Convidar alguém",
|
||||
@@ -1376,7 +1390,14 @@
|
||||
"webAssemblyWarning": "WebAssembly não suportado",
|
||||
"webAssemblyWarningDescription": "WebAssembly desactivado ou não suportado por este navegador"
|
||||
},
|
||||
"visitorsLabel": "Número de visitantes: {{count}}",
|
||||
"visitors": {
|
||||
"chatIndicator": "(visitante)",
|
||||
"labelTooltip": "Número de visitantes: {{count}}",
|
||||
"notification": {
|
||||
"description": "Para participar levante a sua mão",
|
||||
"title": "É um visitante na reunião"
|
||||
}
|
||||
},
|
||||
"volumeSlider": "Controlo de volume",
|
||||
"welcomepage": {
|
||||
"accessibilityLabel": {
|
||||
|
||||
@@ -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.",
|
||||
@@ -870,9 +890,11 @@
|
||||
"lookGood": "Your microphone is working properly",
|
||||
"or": "or",
|
||||
"premeeting": "Pre meeting",
|
||||
"proceedAnyway": "Proceed anyway",
|
||||
"screenSharingError": "Screen sharing error:",
|
||||
"showScreen": "Enable pre meeting screen",
|
||||
"startWithPhone": "Start with phone audio",
|
||||
"unsafeRoomConsent": "I understand the risks, I want to join the meeting",
|
||||
"videoOnlyError": "Video error:",
|
||||
"videoTrackError": "Could not create video track.",
|
||||
"viewAllNumbers": "view all numbers"
|
||||
@@ -974,8 +996,14 @@
|
||||
"security": {
|
||||
"about": "You can add a $t(lockRoomPassword) to your meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
|
||||
"aboutReadOnly": "Moderator participants can add a $t(lockRoomPassword) to the meeting. Participants will need to provide the $t(lockRoomPassword) before they are allowed to join the meeting.",
|
||||
"insecureRoomNameWarning": "The room name is unsafe. Unwanted participants may join your conference. Consider securing your meeting using the security button.",
|
||||
"title": "Security Options"
|
||||
"insecureRoomNameWarningNative": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting ",
|
||||
"insecureRoomNameWarningWeb": "The room name is unsafe. Unwanted participants may join your meeting. {{recommendAction}} Learn more about securing you meeting <a href=\"{{securityUrl}}\" rel=\"security\" target=\"_blank\">here</a>.",
|
||||
"title": "Security Options",
|
||||
"unsafeRoomActions": {
|
||||
"meeting": "Consider securing your meeting using the security button.",
|
||||
"prejoin": "Consider using a more unique meeting name.",
|
||||
"welcome": "Consider using a more unique meeting name, or pick one of the suggestions."
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"audio": "Audio",
|
||||
@@ -1143,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",
|
||||
@@ -1150,6 +1179,7 @@
|
||||
"privateMessage": "Send private message",
|
||||
"profile": "Edit your profile",
|
||||
"raiseHand": "Raise your hand",
|
||||
"reactions": "Reactions",
|
||||
"reactionsMenu": "Reactions menu",
|
||||
"recording": "Toggle recording",
|
||||
"remoteMute": "Mute participant",
|
||||
@@ -1175,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",
|
||||
@@ -1225,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:",
|
||||
@@ -1247,6 +1279,7 @@
|
||||
"reactionLike": "Send thumbs up reaction",
|
||||
"reactionSilence": "Send silence reaction",
|
||||
"reactionSurprised": "Send surprised reaction",
|
||||
"reactions": "Reactions",
|
||||
"security": "Security options",
|
||||
"selectBackground": "Select background",
|
||||
"shareRoom": "Invite someone",
|
||||
@@ -1269,6 +1302,7 @@
|
||||
"unmute": "Unmute",
|
||||
"videoSettings": "Video settings",
|
||||
"videomute": "Stop camera",
|
||||
"videomuteGUMPending": "Connecting your camera",
|
||||
"videounmute": "Start camera"
|
||||
},
|
||||
"transcribing": {
|
||||
@@ -1315,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",
|
||||
@@ -1357,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.",
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// @flow
|
||||
|
||||
/* global APP */
|
||||
import Logger from '@jitsi/logger';
|
||||
|
||||
import { createApiEvent } from '../../react/features/analytics/AnalyticsEvents';
|
||||
@@ -18,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';
|
||||
@@ -113,18 +113,16 @@ import { isAudioMuteButtonDisabled } from '../../react/features/toolbox/function
|
||||
import { setTileView, toggleTileView } from '../../react/features/video-layout/actions.any';
|
||||
import { muteAllParticipants } from '../../react/features/video-menu/actions';
|
||||
import { setVideoQuality } from '../../react/features/video-quality/actions';
|
||||
import { toggleWhiteboard } from '../../react/features/whiteboard/actions.any';
|
||||
import { getJitsiMeetTransport } from '../transport';
|
||||
|
||||
import {
|
||||
API_ID,
|
||||
ASSUMED_BANDWIDTH_BPS,
|
||||
ENDPOINT_TEXT_MESSAGE_NAME
|
||||
} from './constants';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
declare var APP: Object;
|
||||
|
||||
/**
|
||||
* List of the available commands.
|
||||
*/
|
||||
@@ -323,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');
|
||||
@@ -344,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);
|
||||
@@ -363,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));
|
||||
@@ -833,6 +827,9 @@ function initCommands() {
|
||||
} else {
|
||||
logger.error(' End Conference not supported');
|
||||
}
|
||||
},
|
||||
'toggle-whiteboard': () => {
|
||||
APP.store.dispatch(toggleWhiteboard());
|
||||
}
|
||||
};
|
||||
transport.on('event', ({ data, name }) => {
|
||||
@@ -984,6 +981,10 @@ function initCommands() {
|
||||
callback(getRoomsInfo(APP.store.getState()));
|
||||
break;
|
||||
}
|
||||
case 'get-p2p-status': {
|
||||
callback(isP2pActive(APP.store.getState()));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -1030,7 +1031,7 @@ function toggleScreenSharing(enable) {
|
||||
* @param {MouseEvent} event - The mouse event to sanitize.
|
||||
* @returns {Object}
|
||||
*/
|
||||
function sanitizeMouseEvent(event: MouseEvent) {
|
||||
function sanitizeMouseEvent(event) {
|
||||
const {
|
||||
clientX,
|
||||
clientY,
|
||||
@@ -1068,7 +1069,7 @@ function sanitizeMouseEvent(event: MouseEvent) {
|
||||
* Jitsi Meet.
|
||||
*/
|
||||
class API {
|
||||
_enabled: boolean;
|
||||
_enabled;
|
||||
|
||||
/**
|
||||
* Initializes the API. Setups message event listeners that will receive
|
||||
@@ -1103,7 +1104,7 @@ class API {
|
||||
* otherwise.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyLargeVideoVisibilityChanged(isHidden: boolean) {
|
||||
notifyLargeVideoVisibilityChanged(isHidden) {
|
||||
this._sendEvent({
|
||||
name: 'large-video-visibility-changed',
|
||||
isVisible: !isHidden
|
||||
@@ -1117,7 +1118,7 @@ class API {
|
||||
* @param {Object} event - The message to pass onto spot.
|
||||
* @returns {void}
|
||||
*/
|
||||
sendProxyConnectionEvent(event: Object) {
|
||||
sendProxyConnectionEvent(event) {
|
||||
this._sendEvent({
|
||||
name: 'proxy-connection-event',
|
||||
...event
|
||||
@@ -1130,7 +1131,7 @@ class API {
|
||||
* @param {Object} event - The event to be sent.
|
||||
* @returns {void}
|
||||
*/
|
||||
_sendEvent(event: Object = {}) {
|
||||
_sendEvent(event = {}) {
|
||||
if (this._enabled) {
|
||||
transport.sendEvent(event);
|
||||
}
|
||||
@@ -1143,7 +1144,7 @@ class API {
|
||||
* @param {boolean} isOpen - True if the chat panel is open.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyChatUpdated(unreadCount: number, isOpen: boolean) {
|
||||
notifyChatUpdated(unreadCount, isOpen) {
|
||||
this._sendEvent({
|
||||
name: 'chat-updated',
|
||||
unreadCount,
|
||||
@@ -1158,7 +1159,7 @@ class API {
|
||||
* @param {boolean} privateMessage - True if the message was a private message.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifySendingChatMessage(message: string, privateMessage: boolean) {
|
||||
notifySendingChatMessage(message, privateMessage) {
|
||||
this._sendEvent({
|
||||
name: 'outgoing-message',
|
||||
message,
|
||||
@@ -1172,7 +1173,7 @@ class API {
|
||||
* @param {MouseEvent} event - The mousemove event.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyMouseEnter(event: MouseEvent) {
|
||||
notifyMouseEnter(event) {
|
||||
this._sendEvent({
|
||||
name: 'mouse-enter',
|
||||
event: sanitizeMouseEvent(event)
|
||||
@@ -1185,7 +1186,7 @@ class API {
|
||||
* @param {MouseEvent} event - The mousemove event.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyMouseLeave(event: MouseEvent) {
|
||||
notifyMouseLeave(event) {
|
||||
this._sendEvent({
|
||||
name: 'mouse-leave',
|
||||
event: sanitizeMouseEvent(event)
|
||||
@@ -1198,7 +1199,7 @@ class API {
|
||||
* @param {MouseEvent} event - The mousemove event.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyMouseMove(event: MouseEvent) {
|
||||
notifyMouseMove(event) {
|
||||
this._sendEvent({
|
||||
name: 'mouse-move',
|
||||
event: sanitizeMouseEvent(event)
|
||||
@@ -1212,7 +1213,7 @@ class API {
|
||||
* @param {boolean} enabled - Whether or not the new moderation status is enabled.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyModerationChanged(mediaType: string, enabled: boolean) {
|
||||
notifyModerationChanged(mediaType, enabled) {
|
||||
this._sendEvent({
|
||||
name: 'moderation-status-changed',
|
||||
mediaType,
|
||||
@@ -1227,7 +1228,7 @@ class API {
|
||||
* @param {string} mediaType - Media type for which the participant was approved.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyParticipantApproved(participantId: string, mediaType: string) {
|
||||
notifyParticipantApproved(participantId, mediaType) {
|
||||
this._sendEvent({
|
||||
name: 'moderation-participant-approved',
|
||||
id: participantId,
|
||||
@@ -1242,7 +1243,7 @@ class API {
|
||||
* @param {string} mediaType - Media type for which the participant was rejected.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyParticipantRejected(participantId: string, mediaType: string) {
|
||||
notifyParticipantRejected(participantId, mediaType) {
|
||||
this._sendEvent({
|
||||
name: 'moderation-participant-rejected',
|
||||
id: participantId,
|
||||
@@ -1258,7 +1259,7 @@ class API {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyNotificationTriggered(title: string, description: string) {
|
||||
notifyNotificationTriggered(title, description) {
|
||||
this._sendEvent({
|
||||
description,
|
||||
name: 'notification-triggered',
|
||||
@@ -1272,7 +1273,7 @@ class API {
|
||||
* @param {number} videoQuality - The video quality. The number represents the maximum height of the video streams.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyVideoQualityChanged(videoQuality: number) {
|
||||
notifyVideoQualityChanged(videoQuality) {
|
||||
this._sendEvent({
|
||||
name: 'video-quality-changed',
|
||||
videoQuality
|
||||
@@ -1287,9 +1288,7 @@ class API {
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyReceivedChatMessage(
|
||||
{ body, id, nick, privateMessage, ts }: {
|
||||
body: *, id: string, nick: string, privateMessage: boolean, ts: *
|
||||
} = {}) {
|
||||
{ body, id, nick, privateMessage, ts } = {}) {
|
||||
if (APP.conference.isLocalId(id)) {
|
||||
return;
|
||||
}
|
||||
@@ -1312,7 +1311,7 @@ class API {
|
||||
* @param {Object} props - The display name of the user.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyUserJoined(id: string, props: Object) {
|
||||
notifyUserJoined(id, props) {
|
||||
this._sendEvent({
|
||||
name: 'participant-joined',
|
||||
id,
|
||||
@@ -1327,7 +1326,7 @@ class API {
|
||||
* @param {string} id - User id.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyUserLeft(id: string) {
|
||||
notifyUserLeft(id) {
|
||||
this._sendEvent({
|
||||
name: 'participant-left',
|
||||
id
|
||||
@@ -1342,7 +1341,7 @@ class API {
|
||||
* @param {string} role - The new user role.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyUserRoleChanged(id: string, role: string) {
|
||||
notifyUserRoleChanged(id, role) {
|
||||
this._sendEvent({
|
||||
name: 'participant-role-changed',
|
||||
id,
|
||||
@@ -1358,7 +1357,7 @@ class API {
|
||||
* @param {string} avatarURL - The new avatar URL of the participant.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyAvatarChanged(id: string, avatarURL: string) {
|
||||
notifyAvatarChanged(id, avatarURL) {
|
||||
this._sendEvent({
|
||||
name: 'avatar-changed',
|
||||
avatarURL,
|
||||
@@ -1373,7 +1372,7 @@ class API {
|
||||
* @param {Object} data - The event data.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyEndpointTextMessageReceived(data: Object) {
|
||||
notifyEndpointTextMessageReceived(data) {
|
||||
this._sendEvent({
|
||||
name: 'endpoint-text-message-received',
|
||||
data
|
||||
@@ -1387,7 +1386,7 @@ class API {
|
||||
* @param {string} faceExpression - Detected face expression.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyFaceLandmarkDetected(faceBox: Object, faceExpression: string) {
|
||||
notifyFaceLandmarkDetected(faceBox, faceExpression) {
|
||||
this._sendEvent({
|
||||
name: 'face-landmark-detected',
|
||||
faceBox,
|
||||
@@ -1401,7 +1400,7 @@ class API {
|
||||
* @param {Object} data - The event data.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifySharingParticipantsChanged(data: Object) {
|
||||
notifySharingParticipantsChanged(data) {
|
||||
this._sendEvent({
|
||||
name: 'content-sharing-participants-changed',
|
||||
data
|
||||
@@ -1415,7 +1414,7 @@ class API {
|
||||
* @param {Object} devices - The new device list.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyDeviceListChanged(devices: Object) {
|
||||
notifyDeviceListChanged(devices) {
|
||||
this._sendEvent({
|
||||
name: 'device-list-changed',
|
||||
devices
|
||||
@@ -1433,8 +1432,8 @@ class API {
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyDisplayNameChanged(
|
||||
id: string,
|
||||
{ displayName, formattedDisplayName }: Object) {
|
||||
id,
|
||||
{ displayName, formattedDisplayName }) {
|
||||
this._sendEvent({
|
||||
name: 'display-name-change',
|
||||
displayname: displayName,
|
||||
@@ -1452,8 +1451,8 @@ class API {
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyEmailChanged(
|
||||
id: string,
|
||||
{ email }: Object) {
|
||||
id,
|
||||
{ email }) {
|
||||
this._sendEvent({
|
||||
name: 'email-change',
|
||||
email,
|
||||
@@ -1465,10 +1464,10 @@ class API {
|
||||
* Notify external application (if API is enabled) that the an error has been logged.
|
||||
*
|
||||
* @param {string} logLevel - The message log level.
|
||||
* @param {Array} args - Array of strings composing the log message.
|
||||
* @param {Array<string>} args - Array of strings composing the log message.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyLog(logLevel: string, args: Array<string>) {
|
||||
notifyLog(logLevel, args) {
|
||||
this._sendEvent({
|
||||
name: 'log',
|
||||
logLevel,
|
||||
@@ -1486,7 +1485,7 @@ class API {
|
||||
* user and the type of the room.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyConferenceJoined(roomName: string, id: string, props: Object) {
|
||||
notifyConferenceJoined(roomName, id, props) {
|
||||
this._sendEvent({
|
||||
name: 'video-conference-joined',
|
||||
roomName,
|
||||
@@ -1501,7 +1500,7 @@ class API {
|
||||
* @param {string} roomName - User id.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyConferenceLeft(roomName: string) {
|
||||
notifyConferenceLeft(roomName) {
|
||||
this._sendEvent({
|
||||
name: 'video-conference-left',
|
||||
roomName
|
||||
@@ -1516,7 +1515,7 @@ class API {
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyDataChannelClosed(code: number, reason: string) {
|
||||
notifyDataChannelClosed(code, reason) {
|
||||
this._sendEvent({
|
||||
name: 'data-channel-closed',
|
||||
code,
|
||||
@@ -1559,7 +1558,7 @@ class API {
|
||||
* @param {boolean} muted - The new muted status.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyAudioMutedStatusChanged(muted: boolean) {
|
||||
notifyAudioMutedStatusChanged(muted) {
|
||||
this._sendEvent({
|
||||
name: 'audio-mute-status-changed',
|
||||
muted
|
||||
@@ -1573,7 +1572,7 @@ class API {
|
||||
* @param {boolean} muted - The new muted status.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyVideoMutedStatusChanged(muted: boolean) {
|
||||
notifyVideoMutedStatusChanged(muted) {
|
||||
this._sendEvent({
|
||||
name: 'video-mute-status-changed',
|
||||
muted
|
||||
@@ -1587,7 +1586,7 @@ class API {
|
||||
* @param {boolean} available - True if available and false otherwise.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyAudioAvailabilityChanged(available: boolean) {
|
||||
notifyAudioAvailabilityChanged(available) {
|
||||
audioAvailable = available;
|
||||
this._sendEvent({
|
||||
name: 'audio-availability-changed',
|
||||
@@ -1602,7 +1601,7 @@ class API {
|
||||
* @param {boolean} available - True if available and false otherwise.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyVideoAvailabilityChanged(available: boolean) {
|
||||
notifyVideoAvailabilityChanged(available) {
|
||||
videoAvailable = available;
|
||||
this._sendEvent({
|
||||
name: 'video-availability-changed',
|
||||
@@ -1617,7 +1616,7 @@ class API {
|
||||
* @param {string} id - User id of the new on stage participant.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyOnStageParticipantChanged(id: string) {
|
||||
notifyOnStageParticipantChanged(id) {
|
||||
this._sendEvent({
|
||||
name: 'on-stage-participant-changed',
|
||||
id
|
||||
@@ -1631,7 +1630,7 @@ class API {
|
||||
* @param {boolean} isVisible - Whether the prejoin video is visible.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyPrejoinVideoVisibilityChanged(isVisible: boolean) {
|
||||
notifyPrejoinVideoVisibilityChanged(isVisible) {
|
||||
this._sendEvent({
|
||||
name: 'on-prejoin-video-changed',
|
||||
isVisible
|
||||
@@ -1665,7 +1664,7 @@ class API {
|
||||
* @param {string} message - Additional information about the error.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyOnCameraError(type: string, message: string) {
|
||||
notifyOnCameraError(type, message) {
|
||||
this._sendEvent({
|
||||
name: 'camera-error',
|
||||
type,
|
||||
@@ -1681,7 +1680,7 @@ class API {
|
||||
* @param {string} message - Additional information about the error.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyOnMicError(type: string, message: string) {
|
||||
notifyOnMicError(type, message) {
|
||||
this._sendEvent({
|
||||
name: 'mic-error',
|
||||
type,
|
||||
@@ -1697,7 +1696,7 @@ class API {
|
||||
* @param {string} error - A failure message, if any.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyFeedbackSubmitted(error: string) {
|
||||
notifyFeedbackSubmitted(error) {
|
||||
this._sendEvent({
|
||||
name: 'feedback-submitted',
|
||||
error
|
||||
@@ -1722,7 +1721,7 @@ class API {
|
||||
* be displayed or hidden.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyFilmstripDisplayChanged(visible: boolean) {
|
||||
notifyFilmstripDisplayChanged(visible) {
|
||||
this._sendEvent({
|
||||
name: 'filmstrip-display-changed',
|
||||
visible
|
||||
@@ -1739,7 +1738,7 @@ class API {
|
||||
* other participant.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyKickedOut(kicked: Object, kicker: Object) {
|
||||
notifyKickedOut(kicked, kicker) {
|
||||
this._sendEvent({
|
||||
name: 'participant-kicked-out',
|
||||
kicked,
|
||||
@@ -1768,7 +1767,7 @@ class API {
|
||||
* share is capturing.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyScreenSharingStatusChanged(on: boolean, details: Object) {
|
||||
notifyScreenSharingStatusChanged(on, details) {
|
||||
this._sendEvent({
|
||||
name: 'screen-sharing-status-changed',
|
||||
on,
|
||||
@@ -1783,7 +1782,7 @@ class API {
|
||||
* @param {string} id - Id of the dominant participant.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyDominantSpeakerChanged(id: string) {
|
||||
notifyDominantSpeakerChanged(id) {
|
||||
this._sendEvent({
|
||||
name: 'dominant-speaker-changed',
|
||||
id
|
||||
@@ -1797,7 +1796,7 @@ class API {
|
||||
* @param {string} subject - Conference subject.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifySubjectChanged(subject: string) {
|
||||
notifySubjectChanged(subject) {
|
||||
this._sendEvent({
|
||||
name: 'subject-change',
|
||||
subject
|
||||
@@ -1812,7 +1811,7 @@ class API {
|
||||
* otherwise.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyTileViewChanged(enabled: boolean) {
|
||||
notifyTileViewChanged(enabled) {
|
||||
this._sendEvent({
|
||||
name: 'tile-view-changed',
|
||||
enabled
|
||||
@@ -1825,7 +1824,7 @@ class API {
|
||||
* @param {string} localStorageContent - The new localStorageContent.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyLocalStorageChanged(localStorageContent: string) {
|
||||
notifyLocalStorageChanged(localStorageContent) {
|
||||
this._sendEvent({
|
||||
name: 'local-storage-changed',
|
||||
localStorageContent
|
||||
@@ -1839,7 +1838,7 @@ class API {
|
||||
* @param {boolean} handRaised - Whether user has raised hand.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyRaiseHandUpdated(id: string, handRaised: boolean) {
|
||||
notifyRaiseHandUpdated(id, handRaised) {
|
||||
this._sendEvent({
|
||||
name: 'raise-hand-updated',
|
||||
handRaised,
|
||||
@@ -1855,7 +1854,7 @@ class API {
|
||||
* @param {string} error - Error type or null if success.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyRecordingStatusChanged(on: boolean, mode: string, error?: string) {
|
||||
notifyRecordingStatusChanged(on, mode, error) {
|
||||
this._sendEvent({
|
||||
name: 'recording-status-changed',
|
||||
on,
|
||||
@@ -1872,7 +1871,7 @@ class API {
|
||||
* @param {number} ttl - The recording download link time to live.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyRecordingLinkAvailable(link: string, ttl: number) {
|
||||
notifyRecordingLinkAvailable(link, ttl) {
|
||||
this._sendEvent({
|
||||
name: 'recording-link-available',
|
||||
link,
|
||||
@@ -1886,7 +1885,7 @@ class API {
|
||||
* @param {Object} participant - Participant data such as id and name.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyKnockingParticipant(participant: Object) {
|
||||
notifyKnockingParticipant(participant) {
|
||||
this._sendEvent({
|
||||
name: 'knocking-participant',
|
||||
participant
|
||||
@@ -1899,7 +1898,7 @@ class API {
|
||||
* @param {Object} error - The error.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyError(error: Object) {
|
||||
notifyError(error) {
|
||||
this._sendEvent({
|
||||
name: 'error-occurred',
|
||||
error
|
||||
@@ -1913,7 +1912,7 @@ class API {
|
||||
* @param {boolean} preventExecution - Whether execution of the button click was prevented or not.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyToolbarButtonClicked(key: string, preventExecution: boolean) {
|
||||
notifyToolbarButtonClicked(key, preventExecution) {
|
||||
this._sendEvent({
|
||||
name: 'toolbar-button-clicked',
|
||||
key,
|
||||
@@ -1927,7 +1926,7 @@ class API {
|
||||
* @param {boolean} supported - If browser is supported or not.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyBrowserSupport(supported: boolean) {
|
||||
notifyBrowserSupport(supported) {
|
||||
this._sendEvent({
|
||||
name: 'browser-support',
|
||||
supported
|
||||
@@ -2014,6 +2013,50 @@ class API {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) if whiteboard state is
|
||||
* changed.
|
||||
*
|
||||
* @param {WhiteboardStatus} status - The new whiteboard status.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyWhiteboardStatusChanged(status) {
|
||||
this._sendEvent({
|
||||
name: 'whiteboard-status-changed',
|
||||
status
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
|
||||
51
modules/API/external/external_api.js
vendored
51
modules/API/external/external_api.js
vendored
@@ -36,7 +36,6 @@ const commands = {
|
||||
cancelPrivateChat: 'cancel-private-chat',
|
||||
closeBreakoutRoom: 'close-breakout-room',
|
||||
displayName: 'display-name',
|
||||
e2eeKey: 'e2ee-key',
|
||||
endConference: 'end-conference',
|
||||
email: 'email',
|
||||
grantModerator: 'grant-moderator',
|
||||
@@ -90,7 +89,8 @@ const commands = {
|
||||
toggleSubtitles: 'toggle-subtitles',
|
||||
toggleTileView: 'toggle-tile-view',
|
||||
toggleVirtualBackgroundDialog: 'toggle-virtual-background',
|
||||
toggleVideo: 'toggle-video'
|
||||
toggleVideo: 'toggle-video',
|
||||
toggleWhiteboard: 'toggle-whiteboard'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -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',
|
||||
@@ -154,7 +156,8 @@ const events = {
|
||||
'subject-change': 'subjectChange',
|
||||
'suspend-detected': 'suspendDetected',
|
||||
'tile-view-changed': 'tileViewChanged',
|
||||
'toolbar-button-clicked': 'toolbarButtonClicked'
|
||||
'toolbar-button-clicked': 'toolbarButtonClicked',
|
||||
'whiteboard-status-changed': 'whiteboardStatusChanged'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -314,6 +317,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
* @param {string} [options.e2eeKey] - The key used for End-to-End encryption.
|
||||
* THIS IS EXPERIMENTAL.
|
||||
* @param {string} [options.release] - The key used for specifying release if enabled on the backend.
|
||||
* @param {string} [options.sandbox] - Sandbox directive for the created iframe, if desired.
|
||||
*/
|
||||
constructor(domain, ...args) {
|
||||
super();
|
||||
@@ -331,7 +335,8 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
devices,
|
||||
userInfo,
|
||||
e2eeKey,
|
||||
release
|
||||
release,
|
||||
sandbox = ''
|
||||
} = parseArguments(args);
|
||||
const localStorageContent = jitsiLocalStorage.getItem('jitsiLocalStorage');
|
||||
|
||||
@@ -349,7 +354,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
},
|
||||
release
|
||||
});
|
||||
this._createIFrame(height, width, onload);
|
||||
this._createIFrame(height, width, onload, sandbox);
|
||||
this._transport = new Transport({
|
||||
backend: new PostMessageTransportBackend({
|
||||
postisOptions: {
|
||||
@@ -382,11 +387,12 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
* parseSizeParam for format details.
|
||||
* @param {Function} onload - The function that will listen
|
||||
* for onload event.
|
||||
* @param {string} sandbox - Sandbox directive for the created iframe, if desired.
|
||||
* @returns {void}
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_createIFrame(height, width, onload) {
|
||||
_createIFrame(height, width, onload, sandbox) {
|
||||
const frameName = `jitsiConferenceFrame${id}`;
|
||||
|
||||
this._frame = document.createElement('iframe');
|
||||
@@ -397,6 +403,10 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
this._frame.setAttribute('allowFullScreen', 'true');
|
||||
this._frame.style.border = 0;
|
||||
|
||||
if (sandbox) {
|
||||
this._frame.sandbox = sandbox;
|
||||
}
|
||||
|
||||
if (onload) {
|
||||
// waits for iframe resources to load
|
||||
// and fires event when it is done
|
||||
@@ -552,7 +562,22 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
switch (name) {
|
||||
case 'video-conference-joined': {
|
||||
if (typeof this._tmpE2EEKey !== 'undefined') {
|
||||
this.executeCommand(commands.e2eeKey, this._tmpE2EEKey);
|
||||
|
||||
const hexToBytes = hex => {
|
||||
const bytes = [];
|
||||
|
||||
for (let c = 0; c < hex.length; c += 2) {
|
||||
bytes.push(parseInt(hex.substring(c, c + 2), 16));
|
||||
}
|
||||
|
||||
return bytes;
|
||||
};
|
||||
|
||||
this.executeCommand('setMediaEncryptionKey', JSON.stringify({
|
||||
exportedKey: hexToBytes(this._tmpE2EEKey),
|
||||
index: 0
|
||||
}));
|
||||
|
||||
this._tmpE2EEKey = undefined;
|
||||
}
|
||||
|
||||
@@ -670,7 +695,6 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
this._numberOfParticipants = allParticipants;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the rooms info in the conference.
|
||||
*
|
||||
@@ -682,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.
|
||||
*
|
||||
|
||||
20
modules/API/external/functions.js
vendored
20
modules/API/external/functions.js
vendored
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import Logger from '@jitsi/logger';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
@@ -11,7 +9,7 @@ const logger = Logger.getLogger(__filename);
|
||||
* the external communication.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getAvailableDevices(transport: Object) {
|
||||
export function getAvailableDevices(transport) {
|
||||
return transport.sendRequest({
|
||||
type: 'devices',
|
||||
name: 'getAvailableDevices'
|
||||
@@ -29,7 +27,7 @@ export function getAvailableDevices(transport: Object) {
|
||||
* the external communication.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function getCurrentDevices(transport: Object) {
|
||||
export function getCurrentDevices(transport) {
|
||||
return transport.sendRequest({
|
||||
type: 'devices',
|
||||
name: 'getCurrentDevices'
|
||||
@@ -50,7 +48,7 @@ export function getCurrentDevices(transport: Object) {
|
||||
* Default - 'input'.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function isDeviceChangeAvailable(transport: Object, deviceType: string) {
|
||||
export function isDeviceChangeAvailable(transport, deviceType) {
|
||||
return transport.sendRequest({
|
||||
deviceType,
|
||||
type: 'devices',
|
||||
@@ -66,7 +64,7 @@ export function isDeviceChangeAvailable(transport: Object, deviceType: string) {
|
||||
* the external communication.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function isDeviceListAvailable(transport: Object) {
|
||||
export function isDeviceListAvailable(transport) {
|
||||
return transport.sendRequest({
|
||||
type: 'devices',
|
||||
name: 'isDeviceListAvailable'
|
||||
@@ -81,7 +79,7 @@ export function isDeviceListAvailable(transport: Object) {
|
||||
* the external communication.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function isMultipleAudioInputSupported(transport: Object) {
|
||||
export function isMultipleAudioInputSupported(transport) {
|
||||
return transport.sendRequest({
|
||||
type: 'devices',
|
||||
name: 'isMultipleAudioInputSupported'
|
||||
@@ -97,7 +95,7 @@ export function isMultipleAudioInputSupported(transport: Object) {
|
||||
* @param {string} id - The id of the new device.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function setAudioInputDevice(transport: Object, label: string, id: string) {
|
||||
export function setAudioInputDevice(transport, label, id) {
|
||||
return _setDevice(transport, {
|
||||
id,
|
||||
kind: 'audioinput',
|
||||
@@ -114,7 +112,7 @@ export function setAudioInputDevice(transport: Object, label: string, id: string
|
||||
* @param {string} id - The id of the new device.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function setAudioOutputDevice(transport: Object, label: string, id: string) {
|
||||
export function setAudioOutputDevice(transport, label, id) {
|
||||
return _setDevice(transport, {
|
||||
id,
|
||||
kind: 'audiooutput',
|
||||
@@ -130,7 +128,7 @@ export function setAudioOutputDevice(transport: Object, label: string, id: strin
|
||||
* @param {Object} device - The new device to be used.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function _setDevice(transport: Object, device) {
|
||||
function _setDevice(transport, device) {
|
||||
return transport.sendRequest({
|
||||
type: 'devices',
|
||||
name: 'setDevice',
|
||||
@@ -147,7 +145,7 @@ function _setDevice(transport: Object, device) {
|
||||
* @param {string} id - The id of the new device.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function setVideoInputDevice(transport: Object, label: string, id: string) {
|
||||
export function setVideoInputDevice(transport, label, id) {
|
||||
return _setDevice(transport, {
|
||||
id,
|
||||
kind: 'videoinput',
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// @flow
|
||||
|
||||
/* global APP */
|
||||
import Logger from '@jitsi/logger';
|
||||
|
||||
import { openConnection } from '../../../connection';
|
||||
@@ -23,7 +22,6 @@ import ExternalLoginDialog from './LoginDialog';
|
||||
|
||||
|
||||
let externalAuthWindow;
|
||||
declare var APP: Object;
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
@@ -77,7 +75,7 @@ function doExternalAuth(room, lockPassword) {
|
||||
* back with "?jwt={the JWT token}" query parameter added.
|
||||
* @param {string} [roomName] the name of the conference room.
|
||||
*/
|
||||
export function redirectToTokenAuthService(roomName: string) {
|
||||
export function redirectToTokenAuthService(roomName) {
|
||||
const config = APP.store.getState()['features/base/config'];
|
||||
|
||||
// FIXME: This method will not preserve the other URL params that were
|
||||
@@ -174,7 +172,7 @@ function initJWTTokenListener(room) {
|
||||
* @param {JitsiConference} room
|
||||
* @param {string} [lockPassword] password to use if the conference is locked
|
||||
*/
|
||||
function authenticate(room: Object, lockPassword: string) {
|
||||
function authenticate(room, lockPassword) {
|
||||
const config = APP.store.getState()['features/base/config'];
|
||||
|
||||
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
|
||||
@@ -189,7 +187,7 @@ function authenticate(room: Object, lockPassword: string) {
|
||||
* @param {JitsiConference} room
|
||||
* @param {string} [lockPassword] password to use if the conference is locked
|
||||
*/
|
||||
function requireAuth(room: Object, lockPassword: string) {
|
||||
function requireAuth(room, lockPassword) {
|
||||
if (isDialogOpen(APP.store, WaitForOwnerDialog) || isDialogOpen(APP.store, LoginDialog)) {
|
||||
return;
|
||||
}
|
||||
@@ -207,7 +205,7 @@ function requireAuth(room: Object, lockPassword: string) {
|
||||
* @param {string} [lockPassword] password to use if the conference is locked
|
||||
* @returns {Promise}
|
||||
*/
|
||||
function logout(room: Object) {
|
||||
function logout(room) {
|
||||
return new Promise(resolve => {
|
||||
room.room.moderator.logout(resolve);
|
||||
}).then(url => {
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// @flow
|
||||
|
||||
declare var APP: Object;
|
||||
/* global APP */
|
||||
|
||||
export default {
|
||||
|
||||
@@ -10,7 +8,7 @@ export default {
|
||||
* @param {function} callback - callback to invoke when auth popup is closed.
|
||||
* @returns auth dialog
|
||||
*/
|
||||
showExternalAuthDialog(url: string, callback: ?Function) {
|
||||
showExternalAuthDialog(url, callback) {
|
||||
const dialog = APP.UI.messageHandler.openCenteredPopup(
|
||||
url, 910, 660,
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
/* @flow */
|
||||
|
||||
import $ from 'jquery';
|
||||
import jqueryI18next from 'jquery-i18next';
|
||||
|
||||
import i18next from '../../react/features/base/i18n/i18next';
|
||||
|
||||
|
||||
type DocumentElement = {
|
||||
lang: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies that the {@link i18next} instance has finished its initialization.
|
||||
*
|
||||
@@ -18,7 +11,7 @@ type DocumentElement = {
|
||||
*/
|
||||
function _onI18nInitialized() {
|
||||
|
||||
const documentElement: DocumentElement
|
||||
const documentElement
|
||||
= document.documentElement || {};
|
||||
|
||||
$('[data-i18n]').localize();
|
||||
@@ -47,7 +40,7 @@ class Translation {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
generateTranslationHTML(key: string, options: Object) {
|
||||
generateTranslationHTML(key, options) {
|
||||
const optAttr
|
||||
= options ? ` data-i18n-options='${JSON.stringify(options)}'` : '';
|
||||
|
||||
@@ -60,7 +53,7 @@ class Translation {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
translateElement(selector: Object, options: Object) {
|
||||
translateElement(selector, options) {
|
||||
// XXX i18next expects undefined if options are missing.
|
||||
selector.localize(options ? options : undefined);
|
||||
}
|
||||
|
||||
5647
package-lock.json
generated
5647
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
48
package.json
48
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.12/jitsi-excalidraw-0.0.12.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/v1626.0.0+a41aa571/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",
|
||||
@@ -73,13 +73,13 @@
|
||||
"optional-require": "1.0.3",
|
||||
"promise.allsettled": "1.0.4",
|
||||
"punycode": "2.1.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"react-emoji-render": "1.2.4",
|
||||
"react-focus-lock": "2.5.1",
|
||||
"react-focus-on": "3.8.1",
|
||||
"react-i18next": "10.11.4",
|
||||
"react-linkify": "1.0.0-alpha",
|
||||
"react-native": "0.68.6",
|
||||
"react-native": "0.69.10",
|
||||
"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",
|
||||
@@ -125,21 +125,22 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.16.0",
|
||||
"@babel/eslint-parser": "7.16.0",
|
||||
"@babel/eslint-parser": "7.21.8",
|
||||
"@babel/plugin-proposal-export-default-from": "7.16.0",
|
||||
"@babel/preset-env": "7.16.0",
|
||||
"@babel/preset-flow": "7.16.0",
|
||||
"@babel/preset-react": "7.16.0",
|
||||
"@jitsi/eslint-config": "4.1.5",
|
||||
"@types/amplitude-js": "8.16.2",
|
||||
"@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",
|
||||
"@types/react": "17.0.14",
|
||||
"@types/react-dom": "17.0.14",
|
||||
"@types/react-linkify": "1.0.1",
|
||||
"@types/react-native": "0.68.9",
|
||||
"@types/react-native": "0.69.20",
|
||||
"@types/react-native-keep-awake": "2.0.3",
|
||||
"@types/react-native-video": "5.0.14",
|
||||
"@types/react-redux": "7.1.24",
|
||||
"@types/react-window": "1.8.5",
|
||||
@@ -149,29 +150,28 @@
|
||||
"@types/w3c-image-capture": "1.0.6",
|
||||
"@types/w3c-web-hid": "1.0.3",
|
||||
"@types/zxcvbn": "4.4.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.5",
|
||||
"@typescript-eslint/parser": "5.30.4",
|
||||
"@typescript-eslint/eslint-plugin": "5.59.5",
|
||||
"@typescript-eslint/parser": "5.59.5",
|
||||
"babel-loader": "8.2.3",
|
||||
"babel-plugin-optional-require": "0.3.1",
|
||||
"circular-dependency-plugin": "5.2.0",
|
||||
"clean-css-cli": "4.3.0",
|
||||
"css-loader": "3.6.0",
|
||||
"eslint": "8.35.0",
|
||||
"eslint-plugin-flowtype": "8.0.3",
|
||||
"eslint-plugin-import": "2.25.2",
|
||||
"eslint": "8.40.0",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eslint-plugin-jsdoc": "37.0.3",
|
||||
"eslint-plugin-react": "7.26.1",
|
||||
"eslint-plugin-react-native": "3.11.0",
|
||||
"eslint-plugin-typescript-sort-keys": "2.1.0",
|
||||
"eslint-plugin-react": "7.32.2",
|
||||
"eslint-plugin-react-native": "4.0.0",
|
||||
"eslint-plugin-typescript-sort-keys": "2.3.0",
|
||||
"jetifier": "1.6.4",
|
||||
"metro-react-native-babel-preset": "0.67.0",
|
||||
"metro-react-native-babel-preset": "0.70.3",
|
||||
"patch-package": "6.4.7",
|
||||
"process": "0.11.10",
|
||||
"sass": "1.26.8",
|
||||
"style-loader": "3.3.1",
|
||||
"traverse": "0.6.6",
|
||||
"ts-loader": "9.4.1",
|
||||
"typescript": "4.7.4",
|
||||
"ts-loader": "9.4.2",
|
||||
"typescript": "5.0.4",
|
||||
"unorm": "1.6.0",
|
||||
"webpack": "5.76.0",
|
||||
"webpack-bundle-analyzer": "4.4.2",
|
||||
@@ -179,7 +179,7 @@
|
||||
"webpack-dev-server": "4.7.3"
|
||||
},
|
||||
"overrides": {
|
||||
"strophe.js@1.6.0": {
|
||||
"strophe.js@1.5.0": {
|
||||
"@xmldom/xmldom": "0.8.7"
|
||||
}
|
||||
},
|
||||
@@ -193,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 .",
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
diff --git a/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json b/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json
|
||||
index 90a0d69..2ad7d68 100644
|
||||
--- a/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json
|
||||
+++ b/node_modules/eslint-plugin-flowtype/dist/configs/recommended.json
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
- "parser": "@babel/eslint",
|
||||
+ "parser": "@babel/eslint-parser",
|
||||
"parserOptions": {
|
||||
"babelOptions": {
|
||||
"plugins": [
|
||||
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`
|
||||
);
|
||||
@@ -26,10 +26,5 @@ module.exports = {
|
||||
ios: null
|
||||
}
|
||||
}
|
||||
},
|
||||
project: {
|
||||
ios: {
|
||||
project: '.ios/jitsi-meet.xcworkspace'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
module.exports = {
|
||||
'extends': [
|
||||
'../.eslintrc.js',
|
||||
'@jitsi/eslint-config/flow',
|
||||
'@jitsi/eslint-config/jsdoc',
|
||||
'@jitsi/eslint-config/react',
|
||||
'.eslintrc-react-native.js'
|
||||
@@ -30,15 +29,10 @@ module.exports = {
|
||||
}
|
||||
],
|
||||
'rules': {
|
||||
'flowtype/no-types-missing-file-annotation': 0,
|
||||
|
||||
// XXX remove this eventually.
|
||||
'react/jsx-indent-props': 0
|
||||
},
|
||||
'settings': {
|
||||
'flowtype': {
|
||||
'onlyFilesWithFlowAnnotation': true
|
||||
},
|
||||
'react': {
|
||||
'version': 'detect'
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// We need to reference these files directly to avoid loading things that are not available
|
||||
@@ -19,15 +17,15 @@ const TOOLBAR_TIMEOUT = 4000;
|
||||
/**
|
||||
* The type of the React {@code Component} state of {@link AlwaysOnTop}.
|
||||
*/
|
||||
type State = {
|
||||
avatarURL: string,
|
||||
customAvatarBackgrounds: Array<string>,
|
||||
displayName: string,
|
||||
formattedDisplayName: string,
|
||||
isVideoDisplayed: boolean,
|
||||
userID: string,
|
||||
visible: boolean
|
||||
};
|
||||
interface IState {
|
||||
avatarURL: string;
|
||||
customAvatarBackgrounds: Array<string>;
|
||||
displayName: string;
|
||||
formattedDisplayName: string;
|
||||
isVideoDisplayed: boolean;
|
||||
userID: string;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the always on top page.
|
||||
@@ -35,7 +33,7 @@ type State = {
|
||||
* @class AlwaysOnTop
|
||||
* @augments Component
|
||||
*/
|
||||
export default class AlwaysOnTop extends Component<*, State> {
|
||||
export default class AlwaysOnTop extends Component<any, IState> {
|
||||
_hovered: boolean;
|
||||
|
||||
/**
|
||||
@@ -44,7 +42,7 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
* @param {*} props - The read-only properties with which the new instance
|
||||
* is to be initialized.
|
||||
*/
|
||||
constructor(props: *) {
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
@@ -68,28 +66,25 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
this._onMouseOver = this._onMouseOver.bind(this);
|
||||
}
|
||||
|
||||
_avatarChangedListener: () => void;
|
||||
|
||||
/**
|
||||
* Handles avatar changed api events.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_avatarChangedListener({ avatarURL, id }) {
|
||||
_avatarChangedListener({ avatarURL, id }: { avatarURL: string; id: string; }) {
|
||||
if (api._getOnStageParticipant() === id
|
||||
&& avatarURL !== this.state.avatarURL) {
|
||||
this.setState({ avatarURL });
|
||||
}
|
||||
}
|
||||
|
||||
_displayNameChangedListener: () => void;
|
||||
|
||||
/**
|
||||
* Handles display name changed api events.
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
_displayNameChangedListener({ displayname, formattedDisplayName, id }) {
|
||||
_displayNameChangedListener({ displayname, formattedDisplayName, id }: { displayname: string;
|
||||
formattedDisplayName: string; id: string; }) {
|
||||
if (api._getOnStageParticipant() === id
|
||||
&& (formattedDisplayName !== this.state.formattedDisplayName
|
||||
|| displayname !== this.state.displayName)) {
|
||||
@@ -118,8 +113,6 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
TOOLBAR_TIMEOUT);
|
||||
}
|
||||
|
||||
_videoChangedListener: () => void;
|
||||
|
||||
/**
|
||||
* Handles large video changed api events.
|
||||
*
|
||||
@@ -141,8 +134,6 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
});
|
||||
}
|
||||
|
||||
_mouseMove: () => void;
|
||||
|
||||
/**
|
||||
* Handles mouse move events.
|
||||
*
|
||||
@@ -152,8 +143,6 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
this.state.visible || this.setState({ visible: true });
|
||||
}
|
||||
|
||||
_onMouseOut: () => void;
|
||||
|
||||
/**
|
||||
* Toolbar mouse out handler.
|
||||
*
|
||||
@@ -163,8 +152,6 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
this._hovered = false;
|
||||
}
|
||||
|
||||
_onMouseOver: () => void;
|
||||
|
||||
/**
|
||||
* Toolbar mouse over handler.
|
||||
*
|
||||
@@ -229,7 +216,7 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
|
||||
this._hideToolbarAfterTimeout();
|
||||
api.getCustomAvatarBackgrounds()
|
||||
.then(res =>
|
||||
.then((res: { avatarBackgrounds?: string[]; }) =>
|
||||
this.setState({
|
||||
customAvatarBackgrounds: res.avatarBackgrounds || []
|
||||
}))
|
||||
@@ -242,7 +229,7 @@ export default class AlwaysOnTop extends Component<*, State> {
|
||||
* @inheritdoc
|
||||
* @returns {void}
|
||||
*/
|
||||
componentDidUpdate(prevProps: *, prevState: State) {
|
||||
componentDidUpdate(_prevProps: any, prevState: IState) {
|
||||
if (!prevState.visible && this.state.visible) {
|
||||
this._hideToolbarAfterTimeout();
|
||||
}
|
||||
@@ -1,11 +1,9 @@
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// We need to reference these files directly to avoid loading things that are not available
|
||||
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
|
||||
import { IconMic, IconMicSlash } from '../base/icons/svg';
|
||||
import type { Props } from '../base/toolbox/components/AbstractButton';
|
||||
import { IProps } from '../base/toolbox/components/AbstractButton';
|
||||
|
||||
import ToolbarButton from './ToolbarButton';
|
||||
|
||||
@@ -14,23 +12,25 @@ const { api } = window.alwaysOnTop;
|
||||
/**
|
||||
* The type of the React {@code Component} state of {@link AudioMuteButton}.
|
||||
*/
|
||||
type State = {
|
||||
interface IState {
|
||||
|
||||
/**
|
||||
* Whether audio is available is not.
|
||||
*/
|
||||
audioAvailable: boolean,
|
||||
audioAvailable: boolean;
|
||||
|
||||
/**
|
||||
* Whether audio is muted or not.
|
||||
*/
|
||||
audioMuted: boolean
|
||||
};
|
||||
audioMuted: boolean;
|
||||
}
|
||||
|
||||
type Props = Partial<IProps>;
|
||||
|
||||
/**
|
||||
* Stateless "mute/unmute audio" button for the Always-on-Top windows.
|
||||
*/
|
||||
export default class AudioMuteButton extends Component<Props, State> {
|
||||
export default class AudioMuteButton extends Component<Props, IState> {
|
||||
icon = IconMic;
|
||||
toggledIcon = IconMicSlash;
|
||||
accessibilityLabel = 'Audio mute';
|
||||
@@ -38,7 +38,7 @@ export default class AudioMuteButton extends Component<Props, State> {
|
||||
/**
|
||||
* Initializes a new {@code AudioMuteButton} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* @param {IProps} props - The React {@code Component} props to initialize
|
||||
* the new {@code AudioMuteButton} instance with.
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
@@ -94,27 +94,23 @@ export default class AudioMuteButton extends Component<Props, State> {
|
||||
this._audioMutedListener);
|
||||
}
|
||||
|
||||
_audioAvailabilityListener: ({ available: boolean }) => void;
|
||||
|
||||
/**
|
||||
* Handles audio available api events.
|
||||
*
|
||||
* @param {{ available: boolean }} status - The new available status.
|
||||
* @returns {void}
|
||||
*/
|
||||
_audioAvailabilityListener({ available }) {
|
||||
_audioAvailabilityListener({ available }: { available: boolean; }) {
|
||||
this.setState({ audioAvailable: available });
|
||||
}
|
||||
|
||||
_audioMutedListener: ({ muted: boolean }) => void;
|
||||
|
||||
/**
|
||||
* Handles audio muted api events.
|
||||
*
|
||||
* @param {{ muted: boolean }} status - The new muted status.
|
||||
* @returns {void}
|
||||
*/
|
||||
_audioMutedListener({ muted }) {
|
||||
_audioMutedListener({ muted }: { muted: boolean; }) {
|
||||
this.setState({ audioMuted: muted });
|
||||
}
|
||||
|
||||
@@ -144,16 +140,14 @@ export default class AudioMuteButton extends Component<Props, State> {
|
||||
* Changes the muted state.
|
||||
*
|
||||
* @override
|
||||
* @param {boolean} audioMuted - Whether audio should be muted or not.
|
||||
* @param {boolean} _audioMuted - Whether audio should be muted or not.
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_setAudioMuted(audioMuted: boolean) { // eslint-disable-line no-unused-vars
|
||||
_setAudioMuted(_audioMuted: boolean) {
|
||||
this.state.audioAvailable && api.executeCommand('toggleAudio');
|
||||
}
|
||||
|
||||
_onClick: () => {};
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and toggles the audio mute state
|
||||
* accordingly.
|
||||
@@ -173,11 +167,13 @@ export default class AudioMuteButton extends Component<Props, State> {
|
||||
render() {
|
||||
const toggled = this._isAudioMuted();
|
||||
|
||||
return (<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
disabled = { this._isDisabled() }
|
||||
icon = { toggled ? this.toggledIcon : this.icon }
|
||||
onClick = { this._onClick }
|
||||
toggled = { toggled } />);
|
||||
return (
|
||||
<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
disabled = { this._isDisabled() }
|
||||
icon = { toggled ? this.toggledIcon : this.icon }
|
||||
onClick = { this._onClick }
|
||||
toggled = { toggled } />
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,20 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// We need to reference these files directly to avoid loading things that are not available
|
||||
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
|
||||
import { IconHangup } from '../base/icons/svg';
|
||||
import type { Props } from '../base/toolbox/components/AbstractButton';
|
||||
import { IProps } from '../base/toolbox/components/AbstractButton';
|
||||
|
||||
import ToolbarButton from './ToolbarButton';
|
||||
|
||||
const { api } = window.alwaysOnTop;
|
||||
|
||||
type Props = Partial<IProps>;
|
||||
|
||||
/**
|
||||
* Stateless hangup button for the Always-on-Top windows.
|
||||
*/
|
||||
export default class HangupButton extends Component<Props, *> {
|
||||
export default class HangupButton extends Component<Props> {
|
||||
|
||||
accessibilityLabel = 'Hangup';
|
||||
icon = IconHangup;
|
||||
@@ -21,7 +22,7 @@ export default class HangupButton extends Component<Props, *> {
|
||||
/**
|
||||
* Initializes a new {@code HangupButton} instance.
|
||||
*
|
||||
* @param {Props} props - The React {@code Component} props to initialize
|
||||
* @param {IProps} props - The React {@code Component} props to initialize
|
||||
* the new {@code HangupButton} instance with.
|
||||
*/
|
||||
constructor(props: Props) {
|
||||
@@ -31,8 +32,6 @@ export default class HangupButton extends Component<Props, *> {
|
||||
this._onClick = this._onClick.bind(this);
|
||||
}
|
||||
|
||||
_onClick: () => {};
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and disconnects the conference.
|
||||
*
|
||||
@@ -50,10 +49,12 @@ export default class HangupButton extends Component<Props, *> {
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
return (<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
customClass = 'hangup-button'
|
||||
icon = { this.icon }
|
||||
onClick = { this._onClick } />);
|
||||
return (
|
||||
<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
customClass = 'hangup-button'
|
||||
icon = { this.icon }
|
||||
onClick = { this._onClick } />
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import AudioMuteButton from './AudioMuteButton';
|
||||
@@ -9,30 +7,30 @@ import VideoMuteButton from './VideoMuteButton';
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link Toolbar}.
|
||||
*/
|
||||
type Props = {
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* Additional CSS class names to add to the root of the toolbar.
|
||||
*/
|
||||
className: string,
|
||||
className: string;
|
||||
|
||||
/**
|
||||
* Callback invoked when no longer moused over the toolbar.
|
||||
*/
|
||||
onMouseOut: Function,
|
||||
onMouseOut: (e?: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* Callback invoked when the mouse has moved over the toolbar.
|
||||
*/
|
||||
onMouseOver: Function
|
||||
};
|
||||
onMouseOver: (e?: React.MouseEvent) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the toolbar in the Always On Top window.
|
||||
*
|
||||
* @augments Component
|
||||
*/
|
||||
export default class Toolbar extends Component<Props> {
|
||||
export default class Toolbar extends Component<IProps> {
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
@@ -2,38 +2,38 @@ import React, { useCallback } from 'react';
|
||||
|
||||
import Icon from '../base/icons/components/Icon';
|
||||
|
||||
type Props = {
|
||||
interface IProps {
|
||||
|
||||
/**
|
||||
* Accessibility label for button.
|
||||
*/
|
||||
accessibilityLabel: string,
|
||||
accessibilityLabel: string;
|
||||
|
||||
/**
|
||||
* An extra class name to be added at the end of the element's class name
|
||||
* in order to enable custom styling.
|
||||
*/
|
||||
customClass?: string,
|
||||
customClass?: string;
|
||||
|
||||
/**
|
||||
* Whether or not the button is disabled.
|
||||
*/
|
||||
disabled?: boolean,
|
||||
|
||||
/**
|
||||
* Click handler.
|
||||
*/
|
||||
onClick: Function,
|
||||
disabled?: boolean;
|
||||
|
||||
/**
|
||||
* Button icon.
|
||||
*/
|
||||
icon: Object,
|
||||
icon: Function;
|
||||
|
||||
/**
|
||||
* Click handler.
|
||||
*/
|
||||
onClick: (e?: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* Whether or not the button is toggled.
|
||||
*/
|
||||
toggled?: boolean
|
||||
toggled?: boolean;
|
||||
}
|
||||
|
||||
const ToolbarButton = ({
|
||||
@@ -43,7 +43,7 @@ const ToolbarButton = ({
|
||||
onClick,
|
||||
icon,
|
||||
toggled = false
|
||||
}: Props) => {
|
||||
}: IProps) => {
|
||||
const onKeyPress = useCallback(event => {
|
||||
if (event.key === 'Enter' || event.key === ' ') {
|
||||
event.preventDefault();
|
||||
@@ -1,15 +1,16 @@
|
||||
// @flow
|
||||
import React, { Component } from 'react';
|
||||
|
||||
// We need to reference these files directly to avoid loading things that are not available
|
||||
// in this environment (e.g. JitsiMeetJS or interfaceConfig)
|
||||
import { IconVideo, IconVideoOff } from '../base/icons/svg';
|
||||
import type { Props } from '../base/toolbox/components/AbstractButton';
|
||||
import { IProps } from '../base/toolbox/components/AbstractButton';
|
||||
|
||||
import ToolbarButton from './ToolbarButton';
|
||||
|
||||
const { api } = window.alwaysOnTop;
|
||||
|
||||
type Props = Partial<IProps>;
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} state of {@link VideoMuteButton}.
|
||||
*/
|
||||
@@ -18,12 +19,12 @@ type State = {
|
||||
/**
|
||||
* Whether video is available is not.
|
||||
*/
|
||||
videoAvailable: boolean,
|
||||
videoAvailable: boolean;
|
||||
|
||||
/**
|
||||
* Whether video is muted or not.
|
||||
*/
|
||||
videoMuted: boolean
|
||||
videoMuted: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -119,40 +120,34 @@ export default class VideoMuteButton extends Component<Props, State> {
|
||||
* Changes the muted state.
|
||||
*
|
||||
* @override
|
||||
* @param {boolean} videoMuted - Whether video should be muted or not.
|
||||
* @param {boolean} _videoMuted - Whether video should be muted or not.
|
||||
* @protected
|
||||
* @returns {void}
|
||||
*/
|
||||
_setVideoMuted(videoMuted: boolean) { // eslint-disable-line no-unused-vars
|
||||
_setVideoMuted(_videoMuted: boolean) {
|
||||
this.state.videoAvailable && api.executeCommand('toggleVideo', false, true);
|
||||
}
|
||||
|
||||
_videoAvailabilityListener: ({ available: boolean }) => void;
|
||||
|
||||
/**
|
||||
* Handles video available api events.
|
||||
*
|
||||
* @param {{ available: boolean }} status - The new available status.
|
||||
* @returns {void}
|
||||
*/
|
||||
_videoAvailabilityListener({ available }) {
|
||||
_videoAvailabilityListener({ available }: { available: boolean; }) {
|
||||
this.setState({ videoAvailable: available });
|
||||
}
|
||||
|
||||
_videoMutedListener: ({ muted: boolean }) => void;
|
||||
|
||||
/**
|
||||
* Handles video muted api events.
|
||||
*
|
||||
* @param {{ muted: boolean }} status - The new muted status.
|
||||
* @returns {void}
|
||||
*/
|
||||
_videoMutedListener({ muted }) {
|
||||
_videoMutedListener({ muted }: { muted: boolean; }) {
|
||||
this.setState({ videoMuted: muted });
|
||||
}
|
||||
|
||||
_onClick: () => {};
|
||||
|
||||
/**
|
||||
* Handles clicking / pressing the button, and toggles the video mute state
|
||||
* accordingly.
|
||||
@@ -173,11 +168,13 @@ export default class VideoMuteButton extends Component<Props, State> {
|
||||
render() {
|
||||
const toggled = this._isVideoMuted();
|
||||
|
||||
return (<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
disabled = { this._isDisabled() }
|
||||
icon = { toggled ? this.toggledIcon : this.icon }
|
||||
onClick = { this._onClick }
|
||||
toggled = { toggled } />);
|
||||
return (
|
||||
<ToolbarButton
|
||||
accessibilityLabel = { this.accessibilityLabel }
|
||||
disabled = { this._isDisabled() }
|
||||
icon = { toggled ? this.toggledIcon : this.icon }
|
||||
onClick = { this._onClick }
|
||||
toggled = { toggled } />
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
|
||||
import AlwaysOnTop from './AlwaysOnTop';
|
||||
|
||||
// Render the main/root Component.
|
||||
// $FlowExpectedError
|
||||
ReactDOM.render(<AlwaysOnTop />, document.getElementById('react'));
|
||||
|
||||
window.addEventListener(
|
||||
'beforeunload',
|
||||
() => ReactDOM.unmountComponentAtNode(document.getElementById('react')));
|
||||
() => ReactDOM.unmountComponentAtNode(document.getElementById('react') ?? document.body));
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable lines-around-comment */
|
||||
import { setRoom } from '../base/conference/actions';
|
||||
import {
|
||||
configWillLoad,
|
||||
@@ -9,10 +8,11 @@ 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 {
|
||||
appendURLParam,
|
||||
@@ -20,16 +20,14 @@ import {
|
||||
parseURIString,
|
||||
toURLString
|
||||
} from '../base/util/uri';
|
||||
// @ts-ignore
|
||||
import { isPrejoinPageEnabled } from '../mobile/navigation/functions';
|
||||
import {
|
||||
goBackToRoot,
|
||||
navigateRoot
|
||||
// @ts-ignore
|
||||
} from '../mobile/navigation/rootNavigationContainerRef';
|
||||
// @ts-ignore
|
||||
import { screen } from '../mobile/navigation/routes';
|
||||
import { clearNotifications } from '../notifications/actions';
|
||||
import { isUnsafeRoomWarningEnabled } from '../prejoin/functions';
|
||||
|
||||
import { addTrackStateToURL, getDefaultURL } from './functions.native';
|
||||
import logger from './logger';
|
||||
@@ -55,7 +53,7 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
|
||||
|
||||
// If the specified location (URI) does not identify a host, use the app's
|
||||
// default.
|
||||
if (!location || !location.host) {
|
||||
if (!location?.host) {
|
||||
const defaultLocation = parseURIString(getDefaultURL(getState));
|
||||
|
||||
if (location) {
|
||||
@@ -140,10 +138,14 @@ export function appNavigate(uri?: string, options: IReloadNowOptions = {}) {
|
||||
dispatch(setRoom(room));
|
||||
|
||||
if (room) {
|
||||
if (isUnsafeRoomWarningEnabled(getState()) && isInsecureRoomName(room)) {
|
||||
navigateRoot(screen.unsafeRoomWarning);
|
||||
|
||||
return;
|
||||
}
|
||||
dispatch(createDesiredLocalTracks());
|
||||
dispatch(clearNotifications());
|
||||
|
||||
// @ts-ignore
|
||||
const { hidePrejoin } = options;
|
||||
|
||||
if (!hidePrejoin && isPrejoinPageEnabled(getState())) {
|
||||
|
||||
@@ -49,7 +49,7 @@ export function appNavigate(uri?: string) {
|
||||
|
||||
// If the specified location (URI) does not identify a host, use the app's
|
||||
// default.
|
||||
if (!location || !location.host) {
|
||||
if (!location?.host) {
|
||||
const defaultLocation = parseURIString(getDefaultURL(getState));
|
||||
|
||||
if (location) {
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -5,8 +5,6 @@ import { IStateful } from '../base/app/types';
|
||||
import { isRoomValid } from '../base/conference/functions';
|
||||
import { isSupportedBrowser } from '../base/environment/environment';
|
||||
import { toState } from '../base/redux/functions';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
import Conference from '../conference/components/web/Conference';
|
||||
import { getDeepLinkingPage } from '../deep-linking/functions';
|
||||
import UnsupportedDesktopBrowser from '../unsupported-browser/components/UnsupportedDesktopBrowser';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import '../base/devices/reducer';
|
||||
import '../base/premeeting/reducer';
|
||||
import '../base/tooltip/reducer';
|
||||
import '../e2ee/reducer';
|
||||
import '../face-landmarks/reducer';
|
||||
|
||||
@@ -20,6 +20,7 @@ import { ILoggingState } from '../base/logging/reducer';
|
||||
import { IMediaState } from '../base/media/reducer';
|
||||
import { INetInfoState } from '../base/net-info/reducer';
|
||||
import { IParticipantsState } from '../base/participants/reducer';
|
||||
import { IPreMeetingState } from '../base/premeeting/types';
|
||||
import { IResponsiveUIState } from '../base/responsive-ui/reducer';
|
||||
import { ISettingsState } from '../base/settings/reducer';
|
||||
import { ISoundsState } from '../base/sounds/reducer';
|
||||
@@ -110,6 +111,7 @@ export interface IReduxState {
|
||||
'features/base/net-info': INetInfoState;
|
||||
'features/base/no-src-data': INoSrcDataState;
|
||||
'features/base/participants': IParticipantsState;
|
||||
'features/base/premeeting': IPreMeetingState;
|
||||
'features/base/responsive-ui': IResponsiveUIState;
|
||||
'features/base/settings': ISettingsState;
|
||||
'features/base/sounds': ISoundsState;
|
||||
|
||||
@@ -27,13 +27,13 @@ export function cancelLogin() {
|
||||
// a reaction to CONNECTION_FAILED). Since the
|
||||
// app/user is going to navigate to WelcomePage, the SDK
|
||||
// clients/consumers need an event.
|
||||
const { error, passwordRequired }
|
||||
const { error = { recoverable: undefined }, passwordRequired }
|
||||
= getState()['features/base/connection'];
|
||||
|
||||
passwordRequired
|
||||
&& dispatch(
|
||||
connectionFailed(
|
||||
passwordRequired, // @ts-ignore
|
||||
passwordRequired,
|
||||
set(error, 'recoverable', false) as any));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
export { default as LoginDialog } from './native/LoginDialog';
|
||||
// eslint-disable-next-line lines-around-comment
|
||||
// @ts-ignore
|
||||
export { default as WaitForOwnerDialog } from './native/WaitForOwnerDialog';
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -24,7 +24,7 @@ import {
|
||||
openLoginDialog,
|
||||
openWaitForOwnerDialog,
|
||||
stopWaitForOwner,
|
||||
waitForOwner } from './actions.native'; // @ts-ignore
|
||||
waitForOwner } from './actions.native';
|
||||
import { LoginDialog, WaitForOwnerDialog } from './components';
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user