mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-05-29 22:47:48 +00:00
Compare commits
223 Commits
6094
...
new-mobile
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5916cdb3a | ||
|
|
9a99c517ab | ||
|
|
40a6240444 | ||
|
|
4d6ca4383f | ||
|
|
ddce2e6bec | ||
|
|
7dca91a50a | ||
|
|
31348179d4 | ||
|
|
e77679d025 | ||
|
|
44a9363f5b | ||
|
|
bb76090bce | ||
|
|
d0790736db | ||
|
|
0308ba71b1 | ||
|
|
f7d1a5ec80 | ||
|
|
d61fe58fcf | ||
|
|
b428ce2dcd | ||
|
|
d1c9720033 | ||
|
|
c29e8bbdd1 | ||
|
|
3fb3be9727 | ||
|
|
517ec29d85 | ||
|
|
6ad279f029 | ||
|
|
0e98f90205 | ||
|
|
2c5b132483 | ||
|
|
4d8f29d4fe | ||
|
|
22be96d838 | ||
|
|
ccc1157df5 | ||
|
|
f613126776 | ||
|
|
38b21e986d | ||
|
|
38abca8a65 | ||
|
|
f3c6b54ffa | ||
|
|
7dd85bb6ad | ||
|
|
624f88e069 | ||
|
|
fbf693b2dc | ||
|
|
dbf7bf4750 | ||
|
|
d31eb3b248 | ||
|
|
9b75fc98c1 | ||
|
|
1ee9f6a7e5 | ||
|
|
06d0cbd418 | ||
|
|
066dd71afb | ||
|
|
d573bd41b4 | ||
|
|
d06d190229 | ||
|
|
d3b650c741 | ||
|
|
4a04b8b5ee | ||
|
|
6718ba7423 | ||
|
|
e662433c2a | ||
|
|
08bb957672 | ||
|
|
78d8176cc8 | ||
|
|
59ee984e09 | ||
|
|
f6fab051ce | ||
|
|
f0ff6a9f1c | ||
|
|
dfa761b963 | ||
|
|
ad8cdcd81b | ||
|
|
98ef0e74d6 | ||
|
|
746fde7c10 | ||
|
|
bedddd4760 | ||
|
|
7ea78e9845 | ||
|
|
9383942cb9 | ||
|
|
2f1fe637ca | ||
|
|
15d453de1d | ||
|
|
a272995b8c | ||
|
|
10b800e57f | ||
|
|
ca77563bf1 | ||
|
|
44ff1aac11 | ||
|
|
79e648867d | ||
|
|
fc725c07e9 | ||
|
|
d49c86bd5f | ||
|
|
aee94ad6fb | ||
|
|
38011e537a | ||
|
|
13194ddfba | ||
|
|
7895abb9ea | ||
|
|
9060bebca9 | ||
|
|
38724458e3 | ||
|
|
1bce1524db | ||
|
|
def3c76e10 | ||
|
|
5be770cad1 | ||
|
|
dd867b2a92 | ||
|
|
958ffb3076 | ||
|
|
bab3c4abc4 | ||
|
|
1f342b79a8 | ||
|
|
3af782f894 | ||
|
|
e27069447b | ||
|
|
7ac573d628 | ||
|
|
b3db9ce6cf | ||
|
|
1397b9ac80 | ||
|
|
de294cae92 | ||
|
|
5cef3dc1ba | ||
|
|
1dce802031 | ||
|
|
11d61d6d7d | ||
|
|
b5f3cd14c2 | ||
|
|
f87ce0defe | ||
|
|
201ff8f1da | ||
|
|
0c44b9a478 | ||
|
|
9dba1d30b0 | ||
|
|
ad70f12cb4 | ||
|
|
6ea7ab2b46 | ||
|
|
0ef71f4368 | ||
|
|
ae565aaac6 | ||
|
|
7e942173aa | ||
|
|
e1b87c48bc | ||
|
|
8cd259c43f | ||
|
|
d2d2507e86 | ||
|
|
f3f9cd3d05 | ||
|
|
543f273792 | ||
|
|
d9eedb0dad | ||
|
|
7f2fec756d | ||
|
|
607021a890 | ||
|
|
b4febf728d | ||
|
|
769f0a8452 | ||
|
|
f5004a2a0c | ||
|
|
a707022d0b | ||
|
|
43b0118ff8 | ||
|
|
97ca3fb622 | ||
|
|
ffa55cca1e | ||
|
|
0098091a37 | ||
|
|
6c1cb5d4be | ||
|
|
8240c3703e | ||
|
|
35572700bf | ||
|
|
5df774c569 | ||
|
|
8a503e7b40 | ||
|
|
4f49cde73e | ||
|
|
ea5ce3f72f | ||
|
|
5152638529 | ||
|
|
e4b50ba419 | ||
|
|
05127467c2 | ||
|
|
420c7c87e3 | ||
|
|
c23d38807a | ||
|
|
fb6f38800b | ||
|
|
4fb698ea04 | ||
|
|
ebe81e2835 | ||
|
|
c4106b8d89 | ||
|
|
4a350df695 | ||
|
|
0638d9d303 | ||
|
|
0fe7383154 | ||
|
|
9d7b6cafc5 | ||
|
|
39d30ea0b4 | ||
|
|
1400b6ff0a | ||
|
|
3fc3a217eb | ||
|
|
6068a30488 | ||
|
|
36578696bb | ||
|
|
64d44f0ac2 | ||
|
|
5f2147f40f | ||
|
|
084f911699 | ||
|
|
01bd18b86a | ||
|
|
e6ce5fd75f | ||
|
|
0c021868b5 | ||
|
|
adef5095da | ||
|
|
61abf0d882 | ||
|
|
e628d99544 | ||
|
|
f34dde3376 | ||
|
|
94e39e19b2 | ||
|
|
d1ac4ea637 | ||
|
|
0b57bcb20b | ||
|
|
a7abe84479 | ||
|
|
bb0d3b4c66 | ||
|
|
5b86182f94 | ||
|
|
3ab47ff96c | ||
|
|
e1706e7868 | ||
|
|
8434dda6e5 | ||
|
|
346aadc23d | ||
|
|
b872ea855e | ||
|
|
e94607ae4b | ||
|
|
2a535bd50e | ||
|
|
f2c3740108 | ||
|
|
42632bd5fd | ||
|
|
0d0edc05e7 | ||
|
|
1f9a0e91d2 | ||
|
|
fe7327cd21 | ||
|
|
9dd44fc48e | ||
|
|
de7c9bd001 | ||
|
|
fd62ca6c67 | ||
|
|
8e67c8e74f | ||
|
|
f266418a3f | ||
|
|
1c79e6baa3 | ||
|
|
d78e8fba25 | ||
|
|
721f4dc3d3 | ||
|
|
625206db20 | ||
|
|
3f7eef5d13 | ||
|
|
7cd5708ea7 | ||
|
|
e3f3c00c06 | ||
|
|
d3fe246f61 | ||
|
|
b9c4d28dac | ||
|
|
6802a03b7f | ||
|
|
0b642fd225 | ||
|
|
27e2ee07a8 | ||
|
|
02aca27c46 | ||
|
|
9f3965800c | ||
|
|
0ad6bd4d83 | ||
|
|
8e65fab544 | ||
|
|
f62cb7a0c7 | ||
|
|
96ee61ec07 | ||
|
|
6be9f02111 | ||
|
|
fa48223aac | ||
|
|
132b44a8b6 | ||
|
|
72111114b6 | ||
|
|
550c730ed4 | ||
|
|
2ac2138982 | ||
|
|
a84d7c17fa | ||
|
|
586ad30ed4 | ||
|
|
f1c5f314e5 | ||
|
|
64d7305598 | ||
|
|
c03d86e0e3 | ||
|
|
0ae2693116 | ||
|
|
20f6ba1736 | ||
|
|
eb64ea6aba | ||
|
|
3e004811e0 | ||
|
|
037b9202a6 | ||
|
|
8b8a42e0d1 | ||
|
|
4315e19780 | ||
|
|
4d2bd932a7 | ||
|
|
6e1f56fad1 | ||
|
|
7d2f62a614 | ||
|
|
97b958e9ea | ||
|
|
b00fc92ee6 | ||
|
|
f9d1003527 | ||
|
|
0abefa87aa | ||
|
|
dde8c586da | ||
|
|
aa944e76ad | ||
|
|
4153097cc9 | ||
|
|
2a5be074d0 | ||
|
|
2e0ae75774 | ||
|
|
a8017149a0 | ||
|
|
e99fc4394d | ||
|
|
46dd88c91b | ||
|
|
dbc8f21b01 |
@@ -3,11 +3,9 @@ build/*
|
||||
|
||||
# Third-party source code which we (1) do not want to modify or (2) try to
|
||||
# modify as little as possible.
|
||||
flow-typed/*
|
||||
libs/*
|
||||
resources/*
|
||||
react/features/stream-effects/virtual-background/vendor/*
|
||||
load-test/*
|
||||
react/features/face-landmarks/resources/*
|
||||
|
||||
# ESLint will by default ignore its own configuration file. However, there does
|
||||
|
||||
28
Makefile
28
Makefile
@@ -2,13 +2,12 @@ BUILD_DIR = build
|
||||
CLEANCSS = ./node_modules/.bin/cleancss
|
||||
DEPLOY_DIR = libs
|
||||
LIBJITSIMEET_DIR = node_modules/lib-jitsi-meet
|
||||
LIBFLAC_DIR = node_modules/libflacjs/dist/min
|
||||
OLM_DIR = node_modules/@matrix-org/olm
|
||||
TF_WASM_DIR = node_modules/@tensorflow/tfjs-backend-wasm/dist/
|
||||
RNNOISE_WASM_DIR = node_modules/rnnoise-wasm/dist
|
||||
TFLITE_WASM = react/features/stream-effects/virtual-background/vendor/tflite
|
||||
MEET_MODELS_DIR = react/features/stream-effects/virtual-background/vendor/models
|
||||
FACE_MODELS_DIR = node_modules/@vladmandic/face-api/model
|
||||
FACE_MODELS_DIR = node_modules/@vladmandic/human-models/models
|
||||
NODE_SASS = ./node_modules/.bin/sass
|
||||
NPM = npm
|
||||
OUTPUT_DIR = .
|
||||
@@ -20,17 +19,14 @@ WEBPACK_DEV_SERVER = ./node_modules/.bin/webpack serve --mode development
|
||||
|
||||
all: compile deploy clean
|
||||
|
||||
compile: compile-load-test
|
||||
compile:
|
||||
$(WEBPACK)
|
||||
|
||||
compile-load-test:
|
||||
${NPM} install --prefix resources/load-test && ${NPM} run build --prefix resources/load-test
|
||||
|
||||
clean:
|
||||
rm -fr $(BUILD_DIR)
|
||||
|
||||
.NOTPARALLEL:
|
||||
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-tflite deploy-meet-models deploy-lib-jitsi-meet deploy-libflac deploy-olm deploy-tf-wasm deploy-css deploy-local deploy-face-landmarks
|
||||
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-tflite deploy-meet-models deploy-lib-jitsi-meet deploy-olm deploy-tf-wasm deploy-css deploy-local deploy-face-landmarks
|
||||
|
||||
deploy-init:
|
||||
rm -fr $(DEPLOY_DIR)
|
||||
@@ -44,8 +40,6 @@ deploy-appbundle:
|
||||
$(BUILD_DIR)/do_external_connect.min.js.map \
|
||||
$(BUILD_DIR)/external_api.min.js \
|
||||
$(BUILD_DIR)/external_api.min.js.map \
|
||||
$(BUILD_DIR)/flacEncodeWorker.min.js \
|
||||
$(BUILD_DIR)/flacEncodeWorker.min.js.map \
|
||||
$(BUILD_DIR)/dial_in_info_bundle.min.js \
|
||||
$(BUILD_DIR)/dial_in_info_bundle.min.js.map \
|
||||
$(BUILD_DIR)/alwaysontop.min.js \
|
||||
@@ -70,12 +64,6 @@ deploy-lib-jitsi-meet:
|
||||
$(LIBJITSIMEET_DIR)/modules/browser/capabilities.json \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-libflac:
|
||||
cp \
|
||||
$(LIBFLAC_DIR)/libflac4-1.3.2.min.js \
|
||||
$(LIBFLAC_DIR)/libflac4-1.3.2.min.js.mem \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-olm:
|
||||
cp \
|
||||
$(OLM_DIR)/olm.wasm \
|
||||
@@ -103,10 +91,10 @@ deploy-meet-models:
|
||||
|
||||
deploy-face-landmarks:
|
||||
cp \
|
||||
$(FACE_MODELS_DIR)/tiny_face_detector_model-weights_manifest.json \
|
||||
$(FACE_MODELS_DIR)/tiny_face_detector_model.bin \
|
||||
$(FACE_MODELS_DIR)/face_expression_model-weights_manifest.json \
|
||||
$(FACE_MODELS_DIR)/face_expression_model.bin \
|
||||
$(FACE_MODELS_DIR)/blazeface-front.bin \
|
||||
$(FACE_MODELS_DIR)/blazeface-front.json \
|
||||
$(FACE_MODELS_DIR)/emotion.bin \
|
||||
$(FACE_MODELS_DIR)/emotion.json \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-css:
|
||||
@@ -118,7 +106,7 @@ deploy-local:
|
||||
([ ! -x deploy-local.sh ] || ./deploy-local.sh)
|
||||
|
||||
.NOTPARALLEL:
|
||||
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-tflite deploy-meet-models deploy-lib-jitsi-meet deploy-libflac deploy-olm deploy-tf-wasm deploy-face-landmarks
|
||||
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-tflite deploy-meet-models deploy-lib-jitsi-meet deploy-olm deploy-tf-wasm deploy-face-landmarks
|
||||
$(WEBPACK_DEV_SERVER)
|
||||
|
||||
source-package:
|
||||
|
||||
@@ -76,13 +76,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
// https://github.com/facebook/react-native/issues/31572
|
||||
// We can update past 1.4.0 on RN 0.68
|
||||
implementation ('androidx.appcompat:appcompat:1.3.1') {
|
||||
version {
|
||||
strictly '1.3.1'
|
||||
}
|
||||
}
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
android:name="android.content.APP_RESTRICTIONS"
|
||||
android:resource="@xml/app_restrictions" />
|
||||
<activity
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleTask"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
<item name="android:navigationBarColor">@color/colorPrimaryDark</item>
|
||||
<item name="android:windowDisablePreview">true</item>
|
||||
</style>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import groovy.json.JsonSlurper
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
import org.gradle.util.VersionNumber
|
||||
|
||||
// Top-level build file where you can add configuration options common to all
|
||||
@@ -10,19 +11,30 @@ buildscript {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.2.2'
|
||||
classpath 'com.android.tools.build:gradle:7.0.4'
|
||||
classpath 'com.google.gms:google-services:4.3.10'
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.8.1'
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
buildToolsVersion = "30.0.3"
|
||||
buildToolsVersion = "31.0.0"
|
||||
compileSdkVersion = 31
|
||||
minSdkVersion = 23
|
||||
targetSdkVersion = 31
|
||||
supportLibVersion = "28.0.0"
|
||||
ndkVersion = "21.4.7075529"
|
||||
|
||||
if (System.properties['os.arch'] == "aarch64") {
|
||||
// For M1 Users we need to use the NDK 24 which added support for aarch64
|
||||
ndkVersion = "24.0.8215888"
|
||||
} else if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
||||
// For Android Users, we need to use NDK 23, otherwise the build will
|
||||
// fail due to paths longer than the OS limit
|
||||
ndkVersion = "23.1.7779620"
|
||||
} else {
|
||||
// Otherwise we default to the side-by-side NDK version from AGP.
|
||||
ndkVersion = "21.4.7075529"
|
||||
}
|
||||
|
||||
// The Maven artifact groupdId of the third-party react-native modules which
|
||||
// Jitsi Meet SDK for Android depends on and which are not available in
|
||||
|
||||
@@ -26,5 +26,5 @@ android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
android.bundle.enableUncompressedNativeLibs=false
|
||||
|
||||
appVersion=22.2.0
|
||||
sdkVersion=5.1.0
|
||||
appVersion=22.3.0
|
||||
sdkVersion=5.2.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
269
android/gradlew
vendored
269
android/gradlew
vendored
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env sh
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
# Copyright © 2015-2021 the original authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
@@ -17,67 +17,101 @@
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
#
|
||||
# Gradle start up script for POSIX generated by Gradle.
|
||||
#
|
||||
# Important for running:
|
||||
#
|
||||
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||
# noncompliant, but you have some other compliant shell such as ksh or
|
||||
# bash, then to run this script, type that shell name before the whole
|
||||
# command line, like:
|
||||
#
|
||||
# ksh Gradle
|
||||
#
|
||||
# Busybox and similar reduced shells will NOT work, because this script
|
||||
# requires all of these POSIX shell features:
|
||||
# * functions;
|
||||
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||
# * compound commands having a testable exit status, especially «case»;
|
||||
# * various built-in commands including «command», «set», and «ulimit».
|
||||
#
|
||||
# Important for patching:
|
||||
#
|
||||
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||
#
|
||||
# The "traditional" practice of packing multiple parameters into a
|
||||
# space-separated string is a well documented source of bugs and security
|
||||
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||
# options in "$@", and eventually passing that to Java.
|
||||
#
|
||||
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||
# see the in-line comments for details.
|
||||
#
|
||||
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
app_path=$0
|
||||
|
||||
# Need this for daisy-chained symlinks.
|
||||
while
|
||||
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||
[ -h "$app_path" ]
|
||||
do
|
||||
ls=$( ls -ld "$app_path" )
|
||||
link=${ls#*' -> '}
|
||||
case $link in #(
|
||||
/*) app_path=$link ;; #(
|
||||
*) app_path=$APP_HOME$link ;;
|
||||
esac
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
APP_BASE_NAME=${0##*/}
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
MAX_FD=maximum
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
} >&2
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
} >&2
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
case "$( uname )" in #(
|
||||
CYGWIN* ) cygwin=true ;; #(
|
||||
Darwin* ) darwin=true ;; #(
|
||||
MSYS* | MINGW* ) msys=true ;; #(
|
||||
NONSTOP* ) nonstop=true ;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
@@ -87,9 +121,9 @@ CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
JAVACMD=$JAVA_HOME/bin/java
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
@@ -98,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
JAVACMD=java
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
@@ -106,80 +140,95 @@ location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||
case $MAX_FD in #(
|
||||
max*)
|
||||
MAX_FD=$( ulimit -H -n ) ||
|
||||
warn "Could not query maximum file descriptor limit"
|
||||
esac
|
||||
case $MAX_FD in #(
|
||||
'' | soft) :;; #(
|
||||
*)
|
||||
ulimit -n "$MAX_FD" ||
|
||||
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
# Collect all arguments for the java command, stacking in reverse order:
|
||||
# * args from the command line
|
||||
# * the main class name
|
||||
# * -classpath
|
||||
# * -D...appname settings
|
||||
# * --module-path (only if needed)
|
||||
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if "$cygwin" || "$msys" ; then
|
||||
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||
|
||||
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
for arg do
|
||||
if
|
||||
case $arg in #(
|
||||
-*) false ;; # don't mess with options #(
|
||||
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||
[ -e "$t" ] ;; #(
|
||||
*) false ;;
|
||||
esac
|
||||
then
|
||||
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||
fi
|
||||
# Roll the args list around exactly as many times as the number of
|
||||
# args, so each arg winds up back in the position where it started, but
|
||||
# possibly modified.
|
||||
#
|
||||
# NB: a `for` loop captures its iteration list before it begins, so
|
||||
# changing the positional parameters here affects neither the number of
|
||||
# iterations, nor the values presented in `arg`.
|
||||
shift # remove old arg
|
||||
set -- "$@" "$arg" # push replacement arg
|
||||
done
|
||||
fi
|
||||
|
||||
# Collect all arguments for the java command;
|
||||
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
|
||||
# shell script including quotes and variable substitutions, so put them in
|
||||
# double quotes to make sure that they get re-expanded; and
|
||||
# * put everything else in single quotes, so that it's not re-expanded.
|
||||
|
||||
set -- \
|
||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||
-classpath "$CLASSPATH" \
|
||||
org.gradle.wrapper.GradleWrapperMain \
|
||||
"$@"
|
||||
|
||||
# Use "xargs" to parse quoted args.
|
||||
#
|
||||
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||
#
|
||||
# In Bash we could simply go:
|
||||
#
|
||||
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||
# set -- "${ARGS[@]}" "$@"
|
||||
#
|
||||
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||
# character that might be a shell metacharacter, then use eval to reverse
|
||||
# that process (while maintaining the separation between arguments), and wrap
|
||||
# the whole thing up as a single "set" statement.
|
||||
#
|
||||
# This will of course break if any of these variables contains a newline or
|
||||
# an unmatched quote.
|
||||
#
|
||||
|
||||
eval "set -- $(
|
||||
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||
xargs -n1 |
|
||||
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||
tr '\n' ' '
|
||||
)" '"$@"'
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
@@ -34,15 +34,8 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
// https://github.com/facebook/react-native/issues/31572
|
||||
// We can update past 1.4.0 on RN 0.68
|
||||
implementation ('androidx.appcompat:appcompat:1.3.1') {
|
||||
version {
|
||||
strictly '1.3.1'
|
||||
}
|
||||
}
|
||||
implementation 'androidx.fragment:fragment:1.4.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||
implementation 'androidx.fragment:fragment:1.4.1'
|
||||
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
|
||||
@@ -50,7 +43,7 @@ dependencies {
|
||||
api 'com.facebook.react:react-native:+'
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation 'org.webkit:android-jsc:+'
|
||||
|
||||
|
||||
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:4.0.1'
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
|
||||
<application android:usesCleartextTraffic="true">
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
|
||||
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" android:exported="false"/>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
android:supportsRtl="true">
|
||||
<activity
|
||||
android:name=".JitsiMeetActivity"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
||||
android:launchMode="singleTask"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsPictureInPicture="true"
|
||||
|
||||
@@ -76,7 +76,8 @@ public class BroadcastAction {
|
||||
OPEN_CHAT("org.jitsi.meet.OPEN_CHAT"),
|
||||
CLOSE_CHAT("org.jitsi.meet.CLOSE_CHAT"),
|
||||
SEND_CHAT_MESSAGE("org.jitsi.meet.SEND_CHAT_MESSAGE"),
|
||||
SET_VIDEO_MUTED("org.jitsi.meet.SET_VIDEO_MUTED");
|
||||
SET_VIDEO_MUTED("org.jitsi.meet.SET_VIDEO_MUTED"),
|
||||
SET_CLOSED_CAPTIONS_ENABLED("org.jitsi.meet.SET_CLOSED_CAPTIONS_ENABLED");
|
||||
|
||||
private final String action;
|
||||
|
||||
|
||||
@@ -48,4 +48,10 @@ public class BroadcastIntentHelper {
|
||||
intent.putExtra("muted", muted);
|
||||
return intent;
|
||||
}
|
||||
|
||||
public static Intent buildSetClosedCaptionsEnabledIntent(boolean enabled) {
|
||||
Intent intent = new Intent(BroadcastAction.Type.SET_CLOSED_CAPTIONS_ENABLED.getAction());
|
||||
intent.putExtra("enabled", enabled);
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,6 +95,7 @@ class ExternalAPIModule extends ReactContextBaseJavaModule {
|
||||
constants.put("CLOSE_CHAT", BroadcastAction.Type.CLOSE_CHAT.getAction());
|
||||
constants.put("SEND_CHAT_MESSAGE", BroadcastAction.Type.SEND_CHAT_MESSAGE.getAction());
|
||||
constants.put("SET_VIDEO_MUTED", BroadcastAction.Type.SET_VIDEO_MUTED.getAction());
|
||||
constants.put("SET_CLOSED_CAPTIONS_ENABLED", BroadcastAction.Type.SET_CLOSED_CAPTIONS_ENABLED.getAction());
|
||||
|
||||
return constants;
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
protected void onConferenceJoined(HashMap<String, Object> extraData) {
|
||||
JitsiMeetLogger.i("Conference joined: " + extraData);
|
||||
// Launch the service for the ongoing notification.
|
||||
JitsiMeetOngoingConferenceService.launch(this);
|
||||
JitsiMeetOngoingConferenceService.launch(this, extraData);
|
||||
}
|
||||
|
||||
protected void onConferenceTerminated(HashMap<String, Object> extraData) {
|
||||
|
||||
@@ -17,18 +17,22 @@
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Service;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* This class implements an Android {@link Service}, a foreground one specifically, and it's
|
||||
* responsible for presenting an ongoing notification when a conference is in progress.
|
||||
@@ -39,16 +43,22 @@ import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
public class JitsiMeetOngoingConferenceService extends Service
|
||||
implements OngoingConferenceTracker.OngoingConferenceListener {
|
||||
private static final String TAG = JitsiMeetOngoingConferenceService.class.getSimpleName();
|
||||
private static final String EXTRA_DATA_KEY = "extraDataKey";
|
||||
private static final String EXTRA_DATA_BUNDLE_KEY = "extraDataBundleKey";
|
||||
private static final String IS_AUDIO_MUTED_KEY = "isAudioMuted";
|
||||
|
||||
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver();
|
||||
|
||||
private boolean isAudioMuted;
|
||||
|
||||
static void launch(Context context) {
|
||||
static void launch(Context context, HashMap<String, Object> extraData) {
|
||||
OngoingNotification.createOngoingConferenceNotificationChannel();
|
||||
|
||||
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
|
||||
intent.setAction(Action.START.getName());
|
||||
|
||||
Bundle extraDataBundle = new Bundle();
|
||||
extraDataBundle.putSerializable(EXTRA_DATA_KEY, extraData);
|
||||
intent.putExtra(EXTRA_DATA_BUNDLE_KEY, extraDataBundle);
|
||||
|
||||
ComponentName componentName;
|
||||
|
||||
@@ -79,6 +89,15 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
} else {
|
||||
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
JitsiMeetLogger.i(TAG + " Service started");
|
||||
}
|
||||
|
||||
OngoingConferenceTracker.getInstance().addListener(this);
|
||||
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
@@ -101,37 +120,45 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
Boolean isAudioMuted = tryParseIsAudioMuted(intent);
|
||||
|
||||
if (isAudioMuted != null) {
|
||||
this.isAudioMuted = Boolean.parseBoolean(intent.getStringExtra("muted"));
|
||||
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
} else {
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
}
|
||||
}
|
||||
|
||||
final String actionName = intent.getAction();
|
||||
final Action action = Action.fromName(actionName);
|
||||
|
||||
switch (action) {
|
||||
case UNMUTE:
|
||||
case MUTE:
|
||||
Intent muteBroadcastIntent = BroadcastIntentHelper.buildSetAudioMutedIntent(action == Action.MUTE);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(muteBroadcastIntent);
|
||||
break;
|
||||
case START:
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
|
||||
if (notification == null) {
|
||||
// When starting the service, there is no action passed in the intent
|
||||
if (action != null) {
|
||||
switch (action) {
|
||||
case UNMUTE:
|
||||
case MUTE:
|
||||
Intent muteBroadcastIntent = BroadcastIntentHelper.buildSetAudioMutedIntent(action == Action.MUTE);
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(muteBroadcastIntent);
|
||||
break;
|
||||
case HANGUP:
|
||||
JitsiMeetLogger.i(TAG + " Hangup requested");
|
||||
|
||||
Intent hangupBroadcastIntent = BroadcastIntentHelper.buildHangUpIntent();
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(hangupBroadcastIntent);
|
||||
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
} else {
|
||||
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
JitsiMeetLogger.i(TAG + " Service started");
|
||||
}
|
||||
break;
|
||||
case HANGUP:
|
||||
JitsiMeetLogger.i(TAG + " Hangup requested");
|
||||
|
||||
Intent hangupBroadcastIntent = BroadcastIntentHelper.buildHangUpIntent();
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(hangupBroadcastIntent);
|
||||
|
||||
stopSelf();
|
||||
break;
|
||||
default:
|
||||
JitsiMeetLogger.w(TAG + " Unknown action received: " + action);
|
||||
stopSelf();
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
JitsiMeetLogger.w(TAG + " Unknown action received: " + action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return START_NOT_STICKY;
|
||||
@@ -147,7 +174,6 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
}
|
||||
|
||||
public enum Action {
|
||||
START(TAG + ":START"),
|
||||
HANGUP(TAG + ":HANGUP"),
|
||||
MUTE(TAG + ":MUTE"),
|
||||
UNMUTE(TAG + ":UNMUTE");
|
||||
@@ -172,6 +198,15 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
}
|
||||
}
|
||||
|
||||
private Boolean tryParseIsAudioMuted(Intent intent) {
|
||||
try {
|
||||
HashMap<String, Object> extraData = (HashMap<String, Object>) intent.getBundleExtra(EXTRA_DATA_BUNDLE_KEY).getSerializable(EXTRA_DATA_KEY);
|
||||
return Boolean.parseBoolean((String) extraData.get(IS_AUDIO_MUTED_KEY));
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class BroadcastReceiver extends android.content.BroadcastReceiver {
|
||||
|
||||
@Override
|
||||
@@ -180,10 +215,12 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
Notification notification = OngoingNotification.buildOngoingConferenceNotification(isAudioMuted);
|
||||
if (notification == null) {
|
||||
stopSelf();
|
||||
JitsiMeetLogger.w(TAG + " Couldn't start service, notification is null");
|
||||
JitsiMeetLogger.w(TAG + " Couldn't update service, notification is null");
|
||||
} else {
|
||||
startForeground(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
JitsiMeetLogger.i(TAG + " Service started");
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(OngoingNotification.NOTIFICATION_ID, notification);
|
||||
|
||||
JitsiMeetLogger.i(TAG + " audio muted changed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.oney.WebRTCModule.WebRTCModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
@@ -125,18 +126,14 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
* page.
|
||||
*/
|
||||
public void enterPictureInPicture() {
|
||||
PictureInPictureModule pipModule
|
||||
= ReactInstanceManagerHolder.getNativeModule(
|
||||
PictureInPictureModule.class);
|
||||
if (pipModule != null
|
||||
&& pipModule.isPictureInPictureSupported()
|
||||
&& !JitsiMeetActivityDelegate.arePermissionsBeingRequested()
|
||||
&& this.url != null) {
|
||||
try {
|
||||
pipModule.enterPictureInPicture();
|
||||
} catch (RuntimeException re) {
|
||||
JitsiMeetLogger.e(re, "Failed to enter PiP mode");
|
||||
}
|
||||
try {
|
||||
WebRTCModule pipModule
|
||||
= ReactInstanceManagerHolder.getNativeModule(
|
||||
WebRTCModule.class);
|
||||
pipModule.addDecryptors();
|
||||
}
|
||||
catch (Exception e) {
|
||||
int a = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.oney.WebRTCModule.WebRTCModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
@@ -43,7 +44,7 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
|
||||
private static final String TAG = NAME;
|
||||
|
||||
private static boolean isSupported;
|
||||
private boolean isDisabled;
|
||||
private boolean isEnabled;
|
||||
|
||||
public PictureInPictureModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
@@ -84,34 +85,10 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public void enterPictureInPicture() {
|
||||
if (isDisabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isSupported) {
|
||||
throw new IllegalStateException("Picture-in-Picture not supported");
|
||||
}
|
||||
|
||||
Activity currentActivity = getCurrentActivity();
|
||||
|
||||
if (currentActivity == null) {
|
||||
throw new IllegalStateException("No current Activity!");
|
||||
}
|
||||
|
||||
JitsiMeetLogger.i(TAG + " Entering Picture-in-Picture");
|
||||
|
||||
PictureInPictureParams.Builder builder
|
||||
= new PictureInPictureParams.Builder()
|
||||
.setAspectRatio(new Rational(1, 1));
|
||||
|
||||
// https://developer.android.com/reference/android/app/Activity.html#enterPictureInPictureMode(android.app.PictureInPictureParams)
|
||||
//
|
||||
// The system may disallow entering picture-in-picture in various cases,
|
||||
// including when the activity is not visible, if the screen is locked
|
||||
// or if the user has an activity pinned.
|
||||
if (!currentActivity.enterPictureInPictureMode(builder.build())) {
|
||||
throw new RuntimeException("Failed to enter Picture-in-Picture");
|
||||
}
|
||||
WebRTCModule pipModule
|
||||
= ReactInstanceManagerHolder.getNativeModule(
|
||||
WebRTCModule.class);
|
||||
pipModule.addDecryptors();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,17 +100,15 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
|
||||
*/
|
||||
@ReactMethod
|
||||
public void enterPictureInPicture(Promise promise) {
|
||||
try {
|
||||
enterPictureInPicture();
|
||||
promise.resolve(null);
|
||||
} catch (RuntimeException re) {
|
||||
promise.reject(re);
|
||||
}
|
||||
WebRTCModule pipModule
|
||||
= ReactInstanceManagerHolder.getNativeModule(
|
||||
WebRTCModule.class);
|
||||
pipModule.addDecryptors();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setPictureInPictureDisabled(Boolean disabled) {
|
||||
this.isDisabled = disabled;
|
||||
public void setPictureInPictureEnabled(Boolean enabled) {
|
||||
this.isEnabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isPictureInPictureSupported() {
|
||||
|
||||
@@ -35,6 +35,8 @@ import com.oney.WebRTCModule.RTCVideoViewManager;
|
||||
import com.oney.WebRTCModule.WebRTCModule;
|
||||
|
||||
import org.devio.rn.splashscreen.SplashScreenModule;
|
||||
import org.webrtc.Loggable;
|
||||
import org.webrtc.Logging;
|
||||
import org.webrtc.SoftwareVideoDecoderFactory;
|
||||
import org.webrtc.SoftwareVideoEncoderFactory;
|
||||
import org.webrtc.audio.AudioDeviceModule;
|
||||
@@ -57,6 +59,13 @@ class ReactInstanceManagerHolder {
|
||||
*/
|
||||
private static ReactInstanceManager reactInstanceManager;
|
||||
|
||||
private static Loggable webrtcLogger = new Loggable() {
|
||||
@Override
|
||||
public void onLogMessage(String message, Logging.Severity severity, String tag) {
|
||||
Log.d(tag,message);
|
||||
}
|
||||
};
|
||||
|
||||
private static List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
|
||||
List<NativeModule> nativeModules
|
||||
= new ArrayList<>(Arrays.<NativeModule>asList(
|
||||
@@ -88,6 +97,8 @@ class ReactInstanceManagerHolder {
|
||||
|
||||
options.setVideoDecoderFactory(new SoftwareVideoDecoderFactory());
|
||||
options.setVideoEncoderFactory(new SoftwareVideoEncoderFactory());
|
||||
options.setInjectableLogger(webrtcLogger);
|
||||
options.setLoggingSeverity(Logging.Severity.LS_VERBOSE);
|
||||
|
||||
nativeModules.add(new WebRTCModule(reactContext, options));
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
rootProject.name = 'jitsi-meet'
|
||||
|
||||
include ':app', ':sdk'
|
||||
includeBuild('../node_modules/react-native-gradle-plugin')
|
||||
|
||||
include ':react-native-amplitude'
|
||||
project(':react-native-amplitude').projectDir = new File(rootProject.projectDir, '../node_modules/@amplitude/react-native//android')
|
||||
include ':react-native-async-storage'
|
||||
|
||||
@@ -56,8 +56,7 @@ import {
|
||||
} from './react/features/base/conference';
|
||||
import {
|
||||
getReplaceParticipant,
|
||||
getMultipleVideoSupportFeatureFlag,
|
||||
getSourceNameSignalingFeatureFlag
|
||||
getMultipleVideoSendingSupportFeatureFlag
|
||||
} from './react/features/base/config/functions';
|
||||
import {
|
||||
checkAndNotifyForNewDevice,
|
||||
@@ -97,7 +96,7 @@ import {
|
||||
dominantSpeakerChanged,
|
||||
getLocalParticipant,
|
||||
getNormalizedDisplayName,
|
||||
getScreenshareParticipantByOwnerId,
|
||||
getVirtualScreenshareParticipantByOwnerId,
|
||||
localParticipantAudioLevelChanged,
|
||||
localParticipantConnectionStatusChanged,
|
||||
localParticipantRoleChanged,
|
||||
@@ -924,6 +923,35 @@ export default {
|
||||
: isVideoMutedByUser(APP.store);
|
||||
},
|
||||
|
||||
/**
|
||||
* Verify if there is an ongoing system audio sharing session and apply to the provided track
|
||||
* as a AudioMixer effect.
|
||||
*
|
||||
* @param {*} localAudioTrack - track to which system audio track will be applied as an effect, most likely
|
||||
* microphone local audio track.
|
||||
*/
|
||||
async _maybeApplyAudioMixerEffect(localAudioTrack) {
|
||||
|
||||
// At the time of writing this comment there were two separate flows for toggling screen-sharing
|
||||
// and system audio sharing, the first is the legacy method using the functionality from conference.js
|
||||
// the second is used when both sendMultipleVideoStreams and sourceNameSignaling flags are set to true.
|
||||
// The second flow uses functionality from base/conference/middleware.web.js.
|
||||
// We check if system audio sharing was done using the first flow by verifying this._desktopAudioStream and
|
||||
// for the second by checking 'features/screen-share' state.
|
||||
const { desktopAudioTrack } = APP.store.getState()['features/screen-share'];
|
||||
const currentDesktopAudioTrack = this._desktopAudioStream || desktopAudioTrack;
|
||||
|
||||
// If system audio is already being sent, mix it with the provided audio track.
|
||||
if (currentDesktopAudioTrack) {
|
||||
// In case system audio sharing was done in the absence of an initial mic audio track, there is no
|
||||
// AudioMixerEffect so we have to remove system audio track from the room before setting it as an effect.
|
||||
await room.replaceTrack(currentDesktopAudioTrack, null);
|
||||
this._mixerEffect = new AudioMixerEffect(currentDesktopAudioTrack);
|
||||
logger.debug('Mixing new audio track with existing screen audio track.');
|
||||
await localAudioTrack.setEffect(this._mixerEffect);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates toolbar button click for audio mute. Used by shortcuts and API.
|
||||
* @param {boolean} mute true for mute and false for unmute.
|
||||
@@ -977,7 +1005,11 @@ export default {
|
||||
// Rollback the audio muted status by using null track
|
||||
return null;
|
||||
})
|
||||
.then(audioTrack => this.useAudioStream(audioTrack));
|
||||
.then(async audioTrack => {
|
||||
await this._maybeApplyAudioMixerEffect(audioTrack);
|
||||
|
||||
this.useAudioStream(audioTrack);
|
||||
});
|
||||
} else {
|
||||
muteLocalAudio(mute);
|
||||
}
|
||||
@@ -1472,7 +1504,7 @@ export default {
|
||||
|
||||
// In the multi-stream mode, add the track to the conference if there is no existing track, replace it
|
||||
// otherwise.
|
||||
if (getMultipleVideoSupportFeatureFlag(state)) {
|
||||
if (getMultipleVideoSendingSupportFeatureFlag(state)) {
|
||||
const trackAction = oldTrack
|
||||
? replaceLocalTrack(oldTrack, newTrack, room)
|
||||
: addLocalTrack(newTrack);
|
||||
@@ -1618,12 +1650,26 @@ export default {
|
||||
let promise = _prevMutePresenterVideo = _prevMutePresenterVideo.then(() => {
|
||||
// mute the presenter track if it exists.
|
||||
if (this.localPresenterVideo) {
|
||||
APP.store.dispatch(setVideoMuted(true, MEDIA_TYPE.PRESENTER));
|
||||
return (
|
||||
this.localPresenterVideo.dispose().then(() => {
|
||||
APP.store.dispatch(trackRemoved(this.localPresenterVideo));
|
||||
this.localPresenterVideo = null;
|
||||
})
|
||||
.then(() => {
|
||||
|
||||
return this.localPresenterVideo.dispose().then(() => {
|
||||
APP.store.dispatch(trackRemoved(this.localPresenterVideo));
|
||||
this.localPresenterVideo = null;
|
||||
});
|
||||
// This is needed only for setting the correct muted state in features/base/media.
|
||||
// NOTE: It is important to be executed after we have disposed and removed the presenter track.
|
||||
// This way all the side effects won't be executed and we won't start additional O/A cycle for
|
||||
// replacing the track with video with the one without video. This O/A cycle is not needed since
|
||||
// we are trying to destroy all tracks. Also due to the current async nature of muting the
|
||||
// presenter, the final removal of the screen sharing track (see the code at the end of the
|
||||
// function) can be executed between the removal of the stream with video and adding the
|
||||
// original screen sharing stream to the peer connection. This will lead to a failure to remove
|
||||
// the screen sharing track, compromising the screen sharing state in jitsi-meet and the user
|
||||
// won't be able to turn off the screen sharing.
|
||||
APP.store.dispatch(setVideoMuted(true, MEDIA_TYPE.PRESENTER));
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1713,12 +1759,12 @@ export default {
|
||||
return Promise.reject('Cannot toggle screen sharing: not supported.');
|
||||
}
|
||||
|
||||
if (this.isAudioOnly()) {
|
||||
APP.store.dispatch(setAudioOnly(false));
|
||||
}
|
||||
if (toggle) {
|
||||
try {
|
||||
await this._switchToScreenSharing(options);
|
||||
if (this.isAudioOnly()) {
|
||||
APP.store.dispatch(setAudioOnly(false));
|
||||
}
|
||||
|
||||
return;
|
||||
} catch (err) {
|
||||
@@ -2265,14 +2311,12 @@ export default {
|
||||
name: formattedDisplayName
|
||||
}));
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(state)) {
|
||||
const screenshareParticipantId = getScreenshareParticipantByOwnerId(state, id)?.id;
|
||||
const virtualScreenshareParticipantId = getVirtualScreenshareParticipantByOwnerId(state, id)?.id;
|
||||
|
||||
if (screenshareParticipantId) {
|
||||
APP.store.dispatch(
|
||||
screenshareParticipantDisplayNameChanged(screenshareParticipantId, formattedDisplayName)
|
||||
);
|
||||
}
|
||||
if (virtualScreenshareParticipantId) {
|
||||
APP.store.dispatch(
|
||||
screenshareParticipantDisplayNameChanged(virtualScreenshareParticipantId, formattedDisplayName)
|
||||
);
|
||||
}
|
||||
|
||||
APP.API.notifyDisplayNameChanged(id, {
|
||||
@@ -2575,13 +2619,7 @@ export default {
|
||||
return stream;
|
||||
})
|
||||
.then(async stream => {
|
||||
// In case screen sharing audio is also shared we mix it with new input stream. The old _mixerEffect
|
||||
// will be cleaned up when the existing track is replaced.
|
||||
if (this._mixerEffect) {
|
||||
this._mixerEffect = new AudioMixerEffect(this._desktopAudioStream);
|
||||
|
||||
await stream.setEffect(this._mixerEffect);
|
||||
}
|
||||
await this._maybeApplyAudioMixerEffect(stream);
|
||||
|
||||
return this.useAudioStream(stream);
|
||||
})
|
||||
@@ -2615,12 +2653,9 @@ export default {
|
||||
// muteVideo logic in such case.
|
||||
const tracks = APP.store.getState()['features/base/tracks'];
|
||||
const isTrackInRedux
|
||||
= Boolean(
|
||||
tracks.find(
|
||||
track => track.jitsiTrack
|
||||
&& track.jitsiTrack.getType() === 'video'));
|
||||
= Boolean(tracks.find(track => track.jitsiTrack && track.jitsiTrack.getType() === MEDIA_TYPE.VIDEO));
|
||||
|
||||
if (!isTrackInRedux) {
|
||||
if (isTrackInRedux && !this.isSharingScreen) {
|
||||
this.muteVideo(audioOnly);
|
||||
}
|
||||
|
||||
|
||||
110
config.js
110
config.js
@@ -1,6 +1,11 @@
|
||||
|
||||
/* eslint-disable no-unused-vars, no-var */
|
||||
|
||||
/*
|
||||
* NOTE: If you add a new option please remember to document it here:
|
||||
* https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-configuration
|
||||
*/
|
||||
|
||||
var config = {
|
||||
// Connection
|
||||
//
|
||||
@@ -69,6 +74,11 @@ var config = {
|
||||
// or disabled for the screenshare.
|
||||
// capScreenshareBitrate: 1 // 0 to disable - deprecated.
|
||||
|
||||
// Whether to use fake constraints (height: 99999, width: 99999) when calling getDisplayMedia on
|
||||
// Chromium based browsers. This is intended as a workaround for
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1056311
|
||||
// setScreenSharingResolutionConstraints: true
|
||||
|
||||
// Enable callstats only for a percentage of users.
|
||||
// This takes a value between 0 and 100 which determines the probability for
|
||||
// the callstats to be enabled.
|
||||
@@ -285,6 +295,14 @@ var config = {
|
||||
// Whether to enable live streaming or not.
|
||||
// liveStreamingEnabled: false,
|
||||
|
||||
// Local recording configuration.
|
||||
// localRecording: {
|
||||
// // Whether to disable local recording or not.
|
||||
// disable: false,
|
||||
// // Whether to notify all participants when a participant is recording locally.
|
||||
// notifyAllParticipants: false
|
||||
// },
|
||||
|
||||
// Transcription (in interface_config,
|
||||
// subtitles and buttons can be configured)
|
||||
// transcribingEnabled: false,
|
||||
@@ -549,6 +567,10 @@ var config = {
|
||||
// // When 'true', it shows an intermediate page before joining, where the user can configure their devices.
|
||||
// // This replaces `prejoinPageEnabled`.
|
||||
// enabled: true,
|
||||
// // Hides the participant name editing field in the prejoin screen.
|
||||
// // If requireDisplayName is also set as true, a name should still be provided through
|
||||
// // either the jwt or the userInfo from the iframe api init object in order for this to have an effect.
|
||||
// hideDisplayName: false,
|
||||
// // List of buttons to hide from the extra join options dropdown.
|
||||
// hideExtraJoinButtons: ['no-audio', 'by-phone']
|
||||
// },
|
||||
@@ -576,8 +598,17 @@ var config = {
|
||||
// Array with avatar URL prefixes that need to use CORS.
|
||||
// corsAvatarURLs: [ 'https://www.gravatar.com/avatar/' ],
|
||||
|
||||
// Base URL for a Gravatar-compatible service. Defaults to libravatar.
|
||||
// gravatarBaseURL: 'https://seccdn.libravatar.org/avatar/',
|
||||
// Base URL for a Gravatar-compatible service. Defaults to Gravatar.
|
||||
// DEPRECATED! Use `gravatar.baseUrl` instead.
|
||||
// gravatarBaseURL: 'https://www.gravatar.com/avatar/',
|
||||
|
||||
// Setup for Gravatar-compatible services.
|
||||
// gravatar: {
|
||||
// // Defaults to Gravatar.
|
||||
// baseUrl: 'https://www.gravatar.com/avatar/',
|
||||
// // True if Gravatar should be disabled.
|
||||
// disabled: false
|
||||
// },
|
||||
|
||||
// App name to be displayed in the invitation email subject, as an alternative to
|
||||
// interfaceConfig.APP_NAME.
|
||||
@@ -599,6 +630,7 @@ var config = {
|
||||
// 'chat',
|
||||
// 'closedcaptions',
|
||||
// 'desktop',
|
||||
// 'dock-iframe'
|
||||
// 'download',
|
||||
// 'embedmeeting',
|
||||
// 'etherpad',
|
||||
@@ -612,8 +644,6 @@ var config = {
|
||||
// 'linktosalesforce',
|
||||
// 'livestreaming',
|
||||
// 'microphone',
|
||||
// 'mute-everyone',
|
||||
// 'mute-video-everyone',
|
||||
// 'participants-pane',
|
||||
// 'profile',
|
||||
// 'raisehand',
|
||||
@@ -627,6 +657,7 @@ var config = {
|
||||
// 'stats',
|
||||
// 'tileview',
|
||||
// 'toggle-camera',
|
||||
// 'undock-iframe',
|
||||
// 'videoquality',
|
||||
// '__end'
|
||||
// ],
|
||||
@@ -753,7 +784,7 @@ var config = {
|
||||
// enableEmailInStats: false,
|
||||
|
||||
// faceLandmarks: {
|
||||
// // Enables sharing your face cordinates. Used for centering faces within a video.
|
||||
// // Enables sharing your face coordinates. Used for centering faces within a video.
|
||||
// enableFaceCentering: false,
|
||||
|
||||
// // Enables detecting face expressions and sharing data with other participants
|
||||
@@ -762,11 +793,14 @@ var config = {
|
||||
// // Enables displaying face expressions in speaker stats
|
||||
// enableDisplayFaceExpressions: false,
|
||||
|
||||
// // Enable rtc stats for face landmarks
|
||||
// enableRTCStats: false,
|
||||
|
||||
// // Minimum required face movement percentage threshold for sending new face centering coordinates data.
|
||||
// faceCenteringThreshold: 10,
|
||||
|
||||
// // Miliseconds for processing a new image capture in order to detect face coordinates if they exist.
|
||||
// captureInterval: 100
|
||||
// // Milliseconds for processing a new image capture in order to detect face coordinates if they exist.
|
||||
// captureInterval: 1000
|
||||
// },
|
||||
|
||||
// Controls the percentage of automatic feedback shown to participants when callstats is enabled.
|
||||
@@ -846,6 +880,10 @@ var config = {
|
||||
// The Amplitude APP Key:
|
||||
// amplitudeAPPKey: '<APP_KEY>'
|
||||
|
||||
// Obfuscates room name sent to analytics (amplitude, rtcstats)
|
||||
// Default value is false.
|
||||
// obfuscateRoomName: false,
|
||||
|
||||
// Configuration for the rtcstats server:
|
||||
// By enabling rtcstats server every time a conference is joined the rtcstats
|
||||
// module connects to the provided rtcstatsEndpoint and sends statistics regarding
|
||||
@@ -920,33 +958,22 @@ var config = {
|
||||
// chromeExtensionBanner: {
|
||||
// // The chrome extension to be installed address
|
||||
// url: 'https://chrome.google.com/webstore/detail/jitsi-meetings/kglhbbefdnlheedjiejgomgmfplipfeb',
|
||||
// edgeUrl: 'https://microsoftedge.microsoft.com/addons/detail/jitsi-meetings/eeecajlpbgjppibfledfihobcabccihn',
|
||||
|
||||
// // Extensions info which allows checking if they are installed or not
|
||||
// chromeExtensionsInfo: [
|
||||
// {
|
||||
// id: 'kglhbbefdnlheedjiejgomgmfplipfeb',
|
||||
// path: 'jitsi-logo-48x48.png'
|
||||
// },
|
||||
// // Edge extension info
|
||||
// {
|
||||
// id: 'eeecajlpbgjppibfledfihobcabccihn',
|
||||
// path: 'jitsi-logo-48x48.png'
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
|
||||
// Local Recording
|
||||
//
|
||||
|
||||
// localRecording: {
|
||||
// Enables local recording.
|
||||
// Additionally, 'localrecording' (all lowercase) needs to be added to
|
||||
// the `toolbarButtons`-array for the Local Recording button to show up
|
||||
// on the toolbar.
|
||||
//
|
||||
// enabled: true,
|
||||
//
|
||||
|
||||
// The recording format, can be one of 'ogg', 'flac' or 'wav'.
|
||||
// format: 'flac'
|
||||
//
|
||||
|
||||
// },
|
||||
// e2ee: {
|
||||
// labels,
|
||||
// externallyManagedKey: false
|
||||
@@ -992,7 +1019,8 @@ var config = {
|
||||
// Disables all invite functions from the app (share, invite, dial out...etc)
|
||||
// disableInviteFunctions: true,
|
||||
|
||||
// Disables storing the room name to the recents list
|
||||
// Disables storing the room name to the recents list. When in an iframe this is ignored and
|
||||
// the room is never stored in the recents list.
|
||||
// doNotStoreRoom: true,
|
||||
|
||||
// Deployment specific URLs.
|
||||
@@ -1089,10 +1117,22 @@ var config = {
|
||||
*/
|
||||
// dynamicBrandingUrl: '',
|
||||
|
||||
// Options related to the participants pane.
|
||||
// participantsPane: {
|
||||
// // Hides the moderator settings tab.
|
||||
// hideModeratorSettingsTab: false,
|
||||
// // Hides the more actions button.
|
||||
// hideMoreActionsButton: false,
|
||||
// // Hides the mute all button.
|
||||
// hideMuteAllButton: false
|
||||
// },
|
||||
|
||||
// Options related to the breakout rooms feature.
|
||||
// breakoutRooms: {
|
||||
// // Hides the add breakout room button. This replaces `hideAddRoomButton`.
|
||||
// hideAddRoomButton: false,
|
||||
// // Hides the auto assign participants button.
|
||||
// hideAutoAssignButton: false,
|
||||
// // Hides the join breakout room button.
|
||||
// hideJoinRoomButton: false
|
||||
// },
|
||||
@@ -1123,7 +1163,7 @@ var config = {
|
||||
// If a label's id is not in any of the 2 arrays, it will not be visible at all on the header.
|
||||
// conferenceInfo: {
|
||||
// // those labels will not be hidden in tandem with the toolbox.
|
||||
// alwaysVisible: ['recording', 'local-recording', 'raised-hands-count'],
|
||||
// alwaysVisible: ['recording', 'raised-hands-count'],
|
||||
// // those labels will be auto-hidden in tandem with the toolbox buttons.
|
||||
// autoHide: [
|
||||
// 'subject',
|
||||
@@ -1167,14 +1207,24 @@ var config = {
|
||||
// will open an etherpad document.
|
||||
// etherpad_base: 'https://your-etherpad-installati.on/p/',
|
||||
|
||||
// To enable information about dial-in access to meetings you need to provide
|
||||
// dialInNumbersUrl and dialInConfCodeUrl.
|
||||
// dialInNumbersUrl returns a json array of numbers that can be used for dial-in.
|
||||
// {"countryCode":"US","tollFree":false,"formattedNumber":"+1 123-456-7890"}
|
||||
// dialInConfCodeUrl is the conference mapper converting a meeting id to a PIN used for dial-in
|
||||
// or the other way around (more info in resources/cloud-api.swagger)
|
||||
//
|
||||
// For JaaS customers the default values are:
|
||||
// dialInNumbersUrl: 'https://conference-mapper.jitsi.net/v1/access/dids',
|
||||
// dialInConfCodeUrl: 'https://conference-mapper.jitsi.net/v1/access',
|
||||
//
|
||||
|
||||
// List of undocumented settings used in jitsi-meet
|
||||
/**
|
||||
_immediateReloadThreshold
|
||||
debug
|
||||
debugAudioLevels
|
||||
deploymentInfo
|
||||
dialInConfCodeUrl
|
||||
dialInNumbersUrl
|
||||
dialOutAuthUrl
|
||||
dialOutCodesUrl
|
||||
disableRemoteControl
|
||||
@@ -1259,7 +1309,6 @@ var config = {
|
||||
// 'liveStreaming.unavailableTitle', // shown when livestreaming service is not reachable
|
||||
// 'lobby.joinRejectedMessage', // shown when while in a lobby, user's request to join is rejected
|
||||
// 'lobby.notificationTitle', // shown when lobby is toggled and when join requests are allowed / denied
|
||||
// 'localRecording.localRecording', // shown when a local recording is started
|
||||
// 'notify.chatMessages', // shown when receiving chat messages while the chat window is closed
|
||||
// 'notify.disconnected', // shown when a participant has left
|
||||
// 'notify.connectedOneMember', // show when a participant joined
|
||||
@@ -1305,6 +1354,9 @@ var config = {
|
||||
// 'transcribing.failedToStart' // shown when transcribing fails to start
|
||||
// ],
|
||||
|
||||
// List of notifications to be disabled. Works in tandem with the above setting.
|
||||
// disabledNotifications: [],
|
||||
|
||||
// Prevent the filmstrip from autohiding when screen width is under a certain threshold
|
||||
// disableFilmstripAutohiding: false,
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ import { LoginDialog } from './react/features/authentication/components';
|
||||
import { isTokenAuthEnabled } from './react/features/authentication/functions';
|
||||
import {
|
||||
connectionEstablished,
|
||||
connectionFailed
|
||||
connectionFailed,
|
||||
constructOptions
|
||||
} from './react/features/base/connection/actions';
|
||||
import { openDialog } from './react/features/base/dialog/actions';
|
||||
import { setJWT } from './react/features/base/jwt';
|
||||
@@ -19,7 +20,10 @@ import {
|
||||
import { isFatalJitsiConnectionError } from './react/features/base/lib-jitsi-meet/functions';
|
||||
import { getCustomerDetails } from './react/features/jaas/actions.any';
|
||||
import { isVpaasMeeting, getJaasJWT } from './react/features/jaas/functions';
|
||||
import { setPrejoinDisplayNameRequired } from './react/features/prejoin/actions';
|
||||
import {
|
||||
setPrejoinDisplayNameRequired,
|
||||
setPrejoinPageVisibility
|
||||
} from './react/features/prejoin/actions';
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
/**
|
||||
@@ -81,12 +85,10 @@ function checkForAttachParametersAndConnect(id, password, connection) {
|
||||
* Try to open connection using provided credentials.
|
||||
* @param {string} [id]
|
||||
* @param {string} [password]
|
||||
* @param {string} [roomName]
|
||||
* @returns {Promise<JitsiConnection>} connection if
|
||||
* everything is ok, else error.
|
||||
*/
|
||||
export async function connect(id, password, roomName) {
|
||||
const connectionConfig = Object.assign({}, config);
|
||||
export async function connect(id, password) {
|
||||
const state = APP.store.getState();
|
||||
let { jwt } = state['features/base/jwt'];
|
||||
const { iAmRecorder, iAmSipGateway } = state['features/base/config'];
|
||||
@@ -100,19 +102,7 @@ export async function connect(id, password, roomName) {
|
||||
}
|
||||
}
|
||||
|
||||
// Use Websocket URL for the web app if configured. Note that there is no 'isWeb' check, because there's assumption
|
||||
// that this code executes only on web browsers/electron. This needs to be changed when mobile and web are unified.
|
||||
let serviceUrl = connectionConfig.websocket || connectionConfig.bosh;
|
||||
|
||||
serviceUrl += `?room=${roomName}`;
|
||||
|
||||
connectionConfig.serviceUrl = serviceUrl;
|
||||
|
||||
if (connectionConfig.websocketKeepAliveUrl) {
|
||||
connectionConfig.websocketKeepAliveUrl += `?room=${roomName}`;
|
||||
}
|
||||
|
||||
const connection = new JitsiMeetJS.JitsiConnection(null, jwt, connectionConfig);
|
||||
const connection = new JitsiMeetJS.JitsiConnection(null, jwt, constructOptions(state));
|
||||
|
||||
if (config.iAmRecorder) {
|
||||
connection.addFeature(DISCO_JIBRI_FEATURE);
|
||||
@@ -257,6 +247,7 @@ function requestAuth(roomName) {
|
||||
resolve(connection);
|
||||
};
|
||||
|
||||
APP.store.dispatch(setPrejoinPageVisibility(false));
|
||||
APP.store.dispatch(
|
||||
openDialog(LoginDialog, { onSuccess,
|
||||
roomName })
|
||||
|
||||
@@ -23,7 +23,26 @@
|
||||
|
||||
.recording-header-line {
|
||||
border-top: 1px solid #5e6d7a;
|
||||
padding-top: 32px;
|
||||
padding-top: 16px;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.local-recording-warning {
|
||||
margin-top: 8px;
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
padding: 8px 16px;
|
||||
|
||||
&.text {
|
||||
color: #fff;
|
||||
background-color: #3D3D3D;
|
||||
}
|
||||
|
||||
&.notification {
|
||||
color: #040404;
|
||||
background-color: #F8AE1A;
|
||||
}
|
||||
}
|
||||
|
||||
.recording-switch-disabled {
|
||||
@@ -40,7 +59,7 @@
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
justify-content: center;
|
||||
width: 56px;
|
||||
width: 42px;
|
||||
}
|
||||
|
||||
.cloud-content-recording-icon-container {
|
||||
@@ -52,7 +71,7 @@
|
||||
}
|
||||
|
||||
.jitsi-recording-header {
|
||||
margin-bottom: 32px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.jitsi-content-recording-icon-container-with-switch {
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
.remote-videos {
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overscroll-behavior: contain;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,175 +1,177 @@
|
||||
.vertical-filmstrip span:not(.tile-view) .filmstrip {
|
||||
&.hide-videos {
|
||||
.remote-videos {
|
||||
& > div {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
.vertical-filmstrip, .stage-filmstrip {
|
||||
span:not(.tile-view) .filmstrip {
|
||||
&.hide-videos {
|
||||
.remote-videos {
|
||||
& > div {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Firefox sets flex items to min-height: auto and min-width: auto,
|
||||
* preventing flex children from shrinking like they do on other browsers.
|
||||
* Setting min-height and min-width 0 is a workaround for the issue so
|
||||
* Firefox behaves like other browsers.
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1043520
|
||||
*/
|
||||
@mixin minHWAutoFix() {
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
/*
|
||||
* Firefox sets flex items to min-height: auto and min-width: auto,
|
||||
* preventing flex children from shrinking like they do on other browsers.
|
||||
* Setting min-height and min-width 0 is a workaround for the issue so
|
||||
* Firefox behaves like other browsers.
|
||||
* https://bugzilla.mozilla.org/show_bug.cgi?id=1043520
|
||||
*/
|
||||
@mixin minHWAutoFix() {
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@extend %align-right;
|
||||
align-items: flex-end;
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
/**
|
||||
* fixed positioning is necessary for remote menus and tooltips to pop
|
||||
* out of the scrolling filmstrip. AtlasKit dialogs and tooltips use
|
||||
* a library called popper which will position its elements fixed if
|
||||
* any parent is also fixed.
|
||||
*/
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: $filmstripVideosZ;
|
||||
|
||||
&.no-vertical-padding {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide videos by making them slight to the right.
|
||||
*/
|
||||
.filmstrip__videos {
|
||||
@extend %align-right;
|
||||
align-items: flex-end;
|
||||
bottom: 0;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
position:relative;
|
||||
/**
|
||||
* fixed positioning is necessary for remote menus and tooltips to pop
|
||||
* out of the scrolling filmstrip. AtlasKit dialogs and tooltips use
|
||||
* a library called popper which will position its elements fixed if
|
||||
* any parent is also fixed.
|
||||
*/
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: auto;
|
||||
z-index: $filmstripVideosZ;
|
||||
|
||||
&.no-vertical-padding {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* An id selector is used to match id specificity with existing
|
||||
* filmstrip styles.
|
||||
* Hide videos by making them slight to the right.
|
||||
*/
|
||||
&#remoteVideos {
|
||||
border: $thumbnailsBorder solid transparent;
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
.filmstrip__videos {
|
||||
@extend %align-right;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
position:relative;
|
||||
right: 0;
|
||||
width: auto;
|
||||
|
||||
/**
|
||||
* An id selector is used to match id specificity with existing
|
||||
* filmstrip styles.
|
||||
*/
|
||||
&#remoteVideos {
|
||||
border: $thumbnailsBorder solid transparent;
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-styles the local Video to better fit vertical filmstrip layout.
|
||||
*/
|
||||
#filmstripLocalVideo {
|
||||
align-self: initial;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
height: auto;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-styles the local Video to better fit vertical filmstrip layout.
|
||||
*/
|
||||
#filmstripLocalVideo {
|
||||
align-self: initial;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
height: auto;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
#filmstripLocalVideoThumbnail {
|
||||
width: calc(100% - 15px);
|
||||
|
||||
#filmstripLocalVideoThumbnail {
|
||||
width: calc(100% - 15px);
|
||||
|
||||
.videocontainer {
|
||||
height: 0px;
|
||||
width: 100%;
|
||||
.videocontainer {
|
||||
height: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#filmstripLocalScreenShare {
|
||||
align-self: initial;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
height: auto;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
#filmstripLocalScreenShare {
|
||||
align-self: initial;
|
||||
margin-bottom: 5px;
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
height: auto;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
|
||||
#filmstripLocalScreenShareThumbnail {
|
||||
width: calc(100% - 15px);
|
||||
#filmstripLocalScreenShareThumbnail {
|
||||
width: calc(100% - 15px);
|
||||
|
||||
.videocontainer {
|
||||
height: 0px;
|
||||
width: 100%;
|
||||
.videocontainer {
|
||||
height: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove unnecssary padding that is normally used to prevent horizontal
|
||||
* filmstrip from overlapping the left edge of the screen.
|
||||
*/
|
||||
#filmstripLocalVideo,
|
||||
#filmstripLocalScreenShare,
|
||||
.remote-videos {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#remoteVideos {
|
||||
@include minHWAutoFix();
|
||||
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.resizable-filmstrip #remoteVideos .videocontainer {
|
||||
border-left: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.reduce-height {
|
||||
height: calc(100% - calc(#{$newToolbarSizeWithPadding} + #{$scrollHeight}));
|
||||
}
|
||||
|
||||
.filmstrip__videos.vertical-view-grid#remoteVideos {
|
||||
align-items: 'center';
|
||||
border: 0px;
|
||||
padding-right: 7px;
|
||||
|
||||
&.has-scroll {
|
||||
padding-right: 0px;
|
||||
/**
|
||||
* Remove unnecssary padding that is normally used to prevent horizontal
|
||||
* filmstrip from overlapping the left edge of the screen.
|
||||
*/
|
||||
#filmstripLocalVideo,
|
||||
#filmstripLocalScreenShare,
|
||||
.remote-videos {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.remote-videos > div {
|
||||
left: 0px; // fixes an issue on FF - the div is aligned to the right by default for some reason
|
||||
#remoteVideos {
|
||||
@include minHWAutoFix();
|
||||
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.videocontainer {
|
||||
.resizable-filmstrip #remoteVideos .videocontainer {
|
||||
border-left: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.reduce-height {
|
||||
height: calc(100% - calc(#{$newToolbarSizeWithPadding} + #{$scrollHeight}));
|
||||
}
|
||||
|
||||
.filmstrip__videos.vertical-view-grid#remoteVideos {
|
||||
align-items: 'center';
|
||||
border: 0px;
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
padding-right: 7px;
|
||||
|
||||
.remote-videos {
|
||||
display: flex;
|
||||
overscroll-behavior: contain;
|
||||
&.has-scroll {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
&.height-transition {
|
||||
transition: height .3s ease-in;
|
||||
.remote-videos > div {
|
||||
left: 0px; // fixes an issue on FF - the div is aligned to the right by default for some reason
|
||||
}
|
||||
|
||||
.videocontainer {
|
||||
border: 0px;
|
||||
margin: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
& > div {
|
||||
position: absolute;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
.remote-videos {
|
||||
display: flex;
|
||||
overscroll-behavior: contain;
|
||||
|
||||
&.is-not-overflowing > div {
|
||||
bottom: 0px;
|
||||
&.height-transition {
|
||||
transition: height .3s ease-in;
|
||||
}
|
||||
|
||||
& > div {
|
||||
position: absolute;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
|
||||
&.is-not-overflowing > div {
|
||||
bottom: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
* clashing with the filmstrip.
|
||||
*/
|
||||
.vertical-filmstrip #etherpad,
|
||||
.vertical-filmstrip #sharedvideo {
|
||||
.stage-filmstrip #etherpad,
|
||||
.vertical-filmstrip #sharedvideo,
|
||||
.stage-filmstrip #sharedvideo {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides for small videos in vertical filmstrip mode.
|
||||
*/
|
||||
.vertical-filmstrip .filmstrip__videos .videocontainer {
|
||||
.vertical-filmstrip .filmstrip__videos .videocontainer,
|
||||
.stage-filmstrip .filmstrip__videos .videocontainer {
|
||||
.self-view-mobile-portrait video {
|
||||
object-fit: contain;
|
||||
}
|
||||
@@ -27,7 +30,8 @@
|
||||
* The class opening is for when the filmstrip is transitioning from hidden
|
||||
* to visible.
|
||||
*/
|
||||
.vertical-filmstrip .large-video-labels {
|
||||
.vertical-filmstrip .large-video-labels,
|
||||
.stage-filmstrip .large-video-labels {
|
||||
&.with-filmstrip {
|
||||
right: 150px;
|
||||
}
|
||||
@@ -47,6 +51,7 @@
|
||||
* Overrides for self view when in portrait mode on mobile.
|
||||
* This is done in order to keep the aspect ratio.
|
||||
*/
|
||||
.vertical-filmstrip .self-view-mobile-portrait #localVideo_container {
|
||||
.vertical-filmstrip .self-view-mobile-portrait #localVideo_container,
|
||||
.stage-filmstrip .self-view-mobile-portrait #localVideo_container {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,6 @@ $flagsImagePath: "../images/";
|
||||
@import 'modals/invite/info';
|
||||
@import 'modals/screen-share/share-audio';
|
||||
@import 'modals/screen-share/share-screen-warning';
|
||||
@import 'modals/local-recording/local-recording';
|
||||
@import 'videolayout_default';
|
||||
@import 'notice';
|
||||
@import 'subject';
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
.localrec-participant-stats {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
font-weight: 500;
|
||||
|
||||
.localrec-participant-stats-item__status-dot {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 9px;
|
||||
height: 9px;
|
||||
border-radius: 50%;
|
||||
margin: 0 auto;
|
||||
|
||||
&.status-on {
|
||||
background: green;
|
||||
}
|
||||
|
||||
&.status-off {
|
||||
background: gray;
|
||||
}
|
||||
|
||||
&.status-unknown {
|
||||
background: darkgoldenrod;
|
||||
}
|
||||
|
||||
&.status-error {
|
||||
background: darkred;
|
||||
}
|
||||
}
|
||||
|
||||
.localrec-participant-stats-item__status,
|
||||
.localrec-participant-stats-item__name,
|
||||
.localrec-participant-stats-item__sessionid {
|
||||
display: inline-block;
|
||||
margin: 5px 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.localrec-participant-stats-item__status {
|
||||
width: 5%;
|
||||
}
|
||||
.localrec-participant-stats-item__name {
|
||||
width: 40%;
|
||||
}
|
||||
.localrec-participant-stats-item__sessionid {
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
.localrec-participant-stats-item__name,
|
||||
.localrec-participant-stats-item__sessionid {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.localrec-control-info-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.localrec-control-info-label:after {
|
||||
content: ' ';
|
||||
}
|
||||
|
||||
.localrec-control-action-link {
|
||||
display: inline-block;
|
||||
line-height: 1.5em;
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.localrec-control-action-link:before {
|
||||
color: $linkFontColor;
|
||||
content: '\2022';
|
||||
font-size: 1.5em;
|
||||
padding: 0 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.localrec-control-action-link:first-child:before {
|
||||
content: '';
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.localrec-control-action-links {
|
||||
font-weight: bold;
|
||||
margin-top: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
@import 'lobby';
|
||||
@import 'premeeting-screens';
|
||||
@import 'prejoin';
|
||||
@import 'prejoin-dialog';
|
||||
@import 'prejoin-third-party';
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
.prejoin-dialog {
|
||||
background: #1C2025;
|
||||
box-shadow: 0px 2px 20px rgba(0, 0, 0, 0.5);
|
||||
border-radius: 5px;
|
||||
color: #fff;
|
||||
height: 400px;
|
||||
width: 375px;
|
||||
|
||||
&--small {
|
||||
height: 300;
|
||||
width: 400;
|
||||
}
|
||||
|
||||
&-label {
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
|
||||
&-num {
|
||||
background: #2b3b4b;
|
||||
border: 1px solid #A4B8D1;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
height: 24px;
|
||||
margin-right: 8px;
|
||||
width: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
&-container {
|
||||
align-items: center;
|
||||
background: rgba(0,0,0,0.6);
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
justify-content: center;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
&-flag {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
&-title {
|
||||
display: inline-block;
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
&-icon {
|
||||
cursor: pointer;
|
||||
|
||||
> svg {
|
||||
fill: #A4B8D1;
|
||||
}
|
||||
}
|
||||
|
||||
&-btn {
|
||||
width: 309px;
|
||||
}
|
||||
|
||||
&-dialin-container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-delimiter {
|
||||
background: #5f6266;
|
||||
border: 0;
|
||||
height: 1px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
|
||||
&-container {
|
||||
margin: 16px 0 24px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
&-txt-container {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
top: -8px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-txt {
|
||||
background: #1C2025;
|
||||
color: #5f6266;
|
||||
font-size: 11px;
|
||||
text-transform: uppercase;
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.prejoin-dialog-btn.primary,
|
||||
.action-btn.prejoin-dialog-btn.text {
|
||||
width: 310px;
|
||||
}
|
||||
}
|
||||
|
||||
.prejoin-dialog-callout {
|
||||
padding: 16px;
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
&-picker {
|
||||
margin: 8px 0 16px 0;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,25 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-avatar {
|
||||
margin: 8px auto 16px;
|
||||
|
||||
&-name {
|
||||
color: white;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-container {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
&-error {
|
||||
background-color: #E04757;
|
||||
border-radius: 6px;
|
||||
|
||||
7
debian/control
vendored
7
debian/control
vendored
@@ -33,7 +33,7 @@ Description: Configuration for web serving of Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-prosody
|
||||
Architecture: all
|
||||
Depends: openssl, prosody (>= 0.11.0) | prosody-trunk | prosody-0.12 | prosody-0.11, lua-sec
|
||||
Depends: openssl, prosody (>= 0.11.0) | prosody-trunk | prosody-0.12 | prosody-0.11, lua-sec, lua-basexx, lua-luaossl, lua-cjson
|
||||
Replaces: jitsi-meet-tokens
|
||||
Description: Prosody configuration for Jitsi Meet
|
||||
Jitsi Meet is a WebRTC JavaScript application that uses Jitsi
|
||||
@@ -47,12 +47,11 @@ Description: Prosody configuration for Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-tokens
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, prosody-trunk (>= 1nightly747) | prosody-0.11 | prosody (>= 0.11.2), libssl1.0-dev | libssl-dev, luarocks, jitsi-meet-prosody, git
|
||||
Depends: ${misc:Depends}, prosody-trunk | prosody-0.11 | prosody-0.12 | prosody (>= 0.11.2), jitsi-meet-prosody
|
||||
Description: Prosody token authentication plugin for Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-turnserver
|
||||
Architecture: all
|
||||
Breaks: apache2
|
||||
Pre-Depends: jitsi-meet-web-config
|
||||
Depends: ${misc:Depends}, nginx (>= 1.13.10) | nginx-full (>= 1.13.10) | nginx-extras (>= 1.13.10), jitsi-meet-prosody, coturn, dnsutils
|
||||
Depends: ${misc:Depends}, jitsi-meet-prosody, coturn, dnsutils
|
||||
Description: Configures coturn to be used with Jitsi Meet
|
||||
|
||||
10
debian/jitsi-meet-tokens.postinst
vendored
10
debian/jitsi-meet-tokens.postinst
vendored
@@ -60,16 +60,6 @@ case "$1" in
|
||||
sed -i 's/ --modules_enabled = { "token_verification" }/ modules_enabled = { "token_verification" }/g' $PROSODY_HOST_CONFIG
|
||||
sed -i '/^\s*--\s*"token_verification"/ s/--\s*//' $PROSODY_HOST_CONFIG
|
||||
|
||||
# Install luajwt
|
||||
if ! luarocks install luajwtjitsi 2.0-0; then
|
||||
echo "Failed to install luajwtjitsi - try installing it manually"
|
||||
fi
|
||||
|
||||
# Install basexx
|
||||
if ! luarocks install basexx; then
|
||||
echo "Failed to install basexx - try installing it manually"
|
||||
fi
|
||||
|
||||
PR10_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-0.10' 2>/dev/null | awk '{print $3}' || true)"
|
||||
PRTRUNK_INSTALL_CHECK="$(dpkg-query -f '${Status}' -W 'prosody-trunk' 2>/dev/null | awk '{print $3}' || true)"
|
||||
PR_VER_INSTALLED=$(dpkg-query -f='${Version}\n' --show prosody 2>/dev/null || true)
|
||||
|
||||
16
debian/jitsi-meet-turnserver.postinst
vendored
16
debian/jitsi-meet-turnserver.postinst
vendored
@@ -33,7 +33,6 @@ case "$1" in
|
||||
JVB_HOSTNAME=$(echo "$RET" | xargs echo -n)
|
||||
|
||||
TURN_CONFIG="/etc/turnserver.conf"
|
||||
NGINX_CONFIG="/etc/nginx/sites-available/$JVB_HOSTNAME.conf"
|
||||
JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
|
||||
|
||||
# if there was a turn config backup it so we can configure
|
||||
@@ -51,19 +50,6 @@ case "$1" in
|
||||
fi
|
||||
fi
|
||||
|
||||
# this detect only old installations with no nginx
|
||||
db_get jitsi-meet/jvb-serve || true
|
||||
if [ ! -f $NGINX_CONFIG -o "$RET" = "true" ] ; then
|
||||
# nothing to do
|
||||
echo "------------------------------------------------"
|
||||
echo ""
|
||||
echo "turnserver not configured"
|
||||
echo ""
|
||||
echo "------------------------------------------------"
|
||||
db_stop
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f $TURN_CONFIG ]] ; then
|
||||
echo "------------------------------------------------"
|
||||
echo ""
|
||||
@@ -117,7 +103,7 @@ denied-peer-ip=240.0.0.0-255.255.255.255" >> $TURN_CONFIG
|
||||
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $TURN_CONFIG
|
||||
sed -i "s/__turnSecret__/$TURN_SECRET/g" $TURN_CONFIG
|
||||
|
||||
# SSL for nginx
|
||||
# SSL settings
|
||||
db_get jitsi-meet/cert-choice
|
||||
CERT_CHOICE="$RET"
|
||||
|
||||
|
||||
16
debian/jitsi-meet-turnserver.postrm
vendored
16
debian/jitsi-meet-turnserver.postrm
vendored
@@ -23,26 +23,12 @@ set -e
|
||||
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
if [ -x "/etc/init.d/nginx" ]; then
|
||||
invoke-rc.d nginx reload || true
|
||||
fi
|
||||
if [ -x "/etc/init.d/apache2" ]; then
|
||||
invoke-rc.d apache2 reload || true
|
||||
fi
|
||||
;;
|
||||
purge)
|
||||
rm -rf /etc/turnserver.conf
|
||||
if [ -x "/etc/init.d/nginx" ]; then
|
||||
invoke-rc.d nginx reload || true
|
||||
fi
|
||||
if [ -x "/etc/init.d/apache2" ]; then
|
||||
invoke-rc.d apache2 reload || true
|
||||
fi
|
||||
# Clear the debconf variable
|
||||
db_purge
|
||||
;;
|
||||
upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
|
||||
;;
|
||||
|
||||
*)
|
||||
|
||||
2
debian/jitsi-meet-web.install
vendored
2
debian/jitsi-meet-web.install
vendored
@@ -14,5 +14,3 @@ 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/
|
||||
resources/load-test/*.html /usr/share/jitsi-meet/load-test/
|
||||
resources/load-test/libs /usr/share/jitsi-meet/load-test/
|
||||
|
||||
@@ -137,3 +137,18 @@ Component "lobby.jitmeet.example.com" "muc"
|
||||
"muc_rate_limit";
|
||||
"polls";
|
||||
}
|
||||
|
||||
-- Enables dial-in for Jitsi meet components customers
|
||||
-- Note: make sure you have the following packages installed: lua-basexx, liblua5.3-dev, libssl-dev, luarocks
|
||||
-- and execute $ sudo luarocks install luajwtjitsi 3.0-0
|
||||
VirtualHost "jigasi.meet.jitsi"
|
||||
enabled = false -- Jitsi meet components customers remove this line
|
||||
modules_enabled = {
|
||||
"ping";
|
||||
"bosh";
|
||||
}
|
||||
authentication = "token"
|
||||
app_id = "jitsi";
|
||||
asap_key_server = "https://jaas-public-keys.jitsi.net/jitsi-components/prod-8x8"
|
||||
asap_accepted_issuers = { "jaas-components" }
|
||||
asap_accepted_audiences = { "jigasi.jitmeet.example.com" }
|
||||
|
||||
BIN
images/downloadLocalRecording.png
Normal file
BIN
images/downloadLocalRecording.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 490 B |
Binary file not shown.
|
Before Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 298 KiB After Width: | Height: | Size: 713 KiB |
@@ -54,7 +54,7 @@
|
||||
// redirected to a page that is known to have no newer js syntax.
|
||||
if (window.navigator.userAgent.match(/(MSIE|Trident)/)) {
|
||||
var roomName = encodeURIComponent(window.location.pathname);
|
||||
window.location.href = "static/recommendedBrowsers.html" + "?room=" + roomName;
|
||||
window.location.pathname = 'static/recommendedBrowsers.html';
|
||||
}
|
||||
|
||||
window.indexLoadedTime = window.performance.now();
|
||||
|
||||
@@ -23,7 +23,10 @@ target 'JitsiMeetSDK' do
|
||||
config = use_native_modules!
|
||||
use_react_native!(
|
||||
:path => config["reactNativePath"],
|
||||
:hermes_enabled => false
|
||||
:hermes_enabled => false,
|
||||
:fabric_enabled => false,
|
||||
# An absolute path to your application root.
|
||||
:app_path => "#{Pod::Config.instance.installation_root}/.."
|
||||
)
|
||||
|
||||
# Native pod dependencies
|
||||
|
||||
437
ios/Podfile.lock
437
ios/Podfile.lock
@@ -13,14 +13,14 @@ PODS:
|
||||
- CocoaLumberjack/Core (= 3.7.2)
|
||||
- CocoaLumberjack/Core (3.7.2)
|
||||
- DoubleConversion (1.1.6)
|
||||
- FBLazyVector (0.67.4)
|
||||
- FBReactNativeSpec (0.67.4):
|
||||
- FBLazyVector (0.68.1)
|
||||
- FBReactNativeSpec (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.67.4)
|
||||
- RCTTypeSafety (= 0.67.4)
|
||||
- React-Core (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- RCTRequired (= 0.68.1)
|
||||
- RCTTypeSafety (= 0.68.1)
|
||||
- React-Core (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- Firebase/Analytics (6.33.0):
|
||||
- Firebase/Core
|
||||
- Firebase/Core (6.33.0):
|
||||
@@ -134,192 +134,201 @@ PODS:
|
||||
- DoubleConversion
|
||||
- fmt (~> 6.2.1)
|
||||
- glog
|
||||
- RCTRequired (0.67.4)
|
||||
- RCTTypeSafety (0.67.4):
|
||||
- FBLazyVector (= 0.67.4)
|
||||
- RCTRequired (0.68.1)
|
||||
- RCTTypeSafety (0.68.1):
|
||||
- FBLazyVector (= 0.68.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.67.4)
|
||||
- React-Core (= 0.67.4)
|
||||
- React (0.67.4):
|
||||
- React-Core (= 0.67.4)
|
||||
- React-Core/DevSupport (= 0.67.4)
|
||||
- React-Core/RCTWebSocket (= 0.67.4)
|
||||
- React-RCTActionSheet (= 0.67.4)
|
||||
- React-RCTAnimation (= 0.67.4)
|
||||
- React-RCTBlob (= 0.67.4)
|
||||
- React-RCTImage (= 0.67.4)
|
||||
- React-RCTLinking (= 0.67.4)
|
||||
- React-RCTNetwork (= 0.67.4)
|
||||
- React-RCTSettings (= 0.67.4)
|
||||
- React-RCTText (= 0.67.4)
|
||||
- React-RCTVibration (= 0.67.4)
|
||||
- React-callinvoker (0.67.4)
|
||||
- React-Core (0.67.4):
|
||||
- RCTRequired (= 0.68.1)
|
||||
- React-Core (= 0.68.1)
|
||||
- React (0.68.1):
|
||||
- React-Core (= 0.68.1)
|
||||
- React-Core/DevSupport (= 0.68.1)
|
||||
- React-Core/RCTWebSocket (= 0.68.1)
|
||||
- React-RCTActionSheet (= 0.68.1)
|
||||
- React-RCTAnimation (= 0.68.1)
|
||||
- React-RCTBlob (= 0.68.1)
|
||||
- React-RCTImage (= 0.68.1)
|
||||
- React-RCTLinking (= 0.68.1)
|
||||
- React-RCTNetwork (= 0.68.1)
|
||||
- React-RCTSettings (= 0.68.1)
|
||||
- React-RCTText (= 0.68.1)
|
||||
- React-RCTVibration (= 0.68.1)
|
||||
- React-callinvoker (0.68.1)
|
||||
- React-Codegen (0.68.1):
|
||||
- FBReactNativeSpec (= 0.68.1)
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTRequired (= 0.68.1)
|
||||
- RCTTypeSafety (= 0.68.1)
|
||||
- React-Core (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-Core (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.4)
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-Core/Default (= 0.68.1)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/CoreModulesHeaders (0.67.4):
|
||||
- React-Core/CoreModulesHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/Default (0.67.4):
|
||||
- React-Core/Default (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/DevSupport (0.67.4):
|
||||
- React-Core/DevSupport (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.4)
|
||||
- React-Core/RCTWebSocket (= 0.67.4)
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-jsinspector (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-Core/Default (= 0.68.1)
|
||||
- React-Core/RCTWebSocket (= 0.68.1)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-jsinspector (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTActionSheetHeaders (0.67.4):
|
||||
- React-Core/RCTActionSheetHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTAnimationHeaders (0.67.4):
|
||||
- React-Core/RCTAnimationHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTBlobHeaders (0.67.4):
|
||||
- React-Core/RCTBlobHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTImageHeaders (0.67.4):
|
||||
- React-Core/RCTImageHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTLinkingHeaders (0.67.4):
|
||||
- React-Core/RCTLinkingHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTNetworkHeaders (0.67.4):
|
||||
- React-Core/RCTNetworkHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTSettingsHeaders (0.67.4):
|
||||
- React-Core/RCTSettingsHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTTextHeaders (0.67.4):
|
||||
- React-Core/RCTTextHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTVibrationHeaders (0.67.4):
|
||||
- React-Core/RCTVibrationHeaders (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-Core/RCTWebSocket (0.67.4):
|
||||
- React-Core/RCTWebSocket (0.68.1):
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/Default (= 0.67.4)
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsiexecutor (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-Core/Default (= 0.68.1)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsiexecutor (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- Yoga
|
||||
- React-CoreModules (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- React-CoreModules (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.4)
|
||||
- React-Core/CoreModulesHeaders (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-RCTImage (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-cxxreact (0.67.4):
|
||||
- RCTTypeSafety (= 0.68.1)
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/CoreModulesHeaders (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-RCTImage (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-cxxreact (0.68.1):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-jsinspector (= 0.67.4)
|
||||
- React-logger (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-runtimeexecutor (= 0.67.4)
|
||||
- React-jsi (0.67.4):
|
||||
- React-callinvoker (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-jsinspector (= 0.68.1)
|
||||
- React-logger (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- React-runtimeexecutor (= 0.68.1)
|
||||
- React-jsi (0.68.1):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsi/Default (= 0.67.4)
|
||||
- React-jsi/Default (0.67.4):
|
||||
- React-jsi/Default (= 0.68.1)
|
||||
- React-jsi/Default (0.68.1):
|
||||
- boost (= 1.76.0)
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-jsiexecutor (0.67.4):
|
||||
- React-jsiexecutor (0.68.1):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-jsinspector (0.67.4)
|
||||
- React-logger (0.67.4):
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- React-jsinspector (0.68.1)
|
||||
- React-logger (0.68.1):
|
||||
- glog
|
||||
- react-native-background-timer (2.4.1):
|
||||
- React-Core
|
||||
@@ -344,75 +353,75 @@ PODS:
|
||||
- react-native-video/Video (= 5.2.0)
|
||||
- react-native-video/Video (5.2.0):
|
||||
- React-Core
|
||||
- react-native-webrtc (1.100.0):
|
||||
- react-native-webrtc (1.100.1):
|
||||
- React-Core
|
||||
- react-native-webview (11.15.1):
|
||||
- React-Core
|
||||
- React-perflogger (0.67.4)
|
||||
- React-RCTActionSheet (0.67.4):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.67.4)
|
||||
- React-RCTAnimation (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- React-perflogger (0.68.1)
|
||||
- React-RCTActionSheet (0.68.1):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.68.1)
|
||||
- React-RCTAnimation (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.4)
|
||||
- React-Core/RCTAnimationHeaders (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-RCTBlob (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- RCTTypeSafety (= 0.68.1)
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/RCTAnimationHeaders (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-RCTBlob (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTBlobHeaders (= 0.67.4)
|
||||
- React-Core/RCTWebSocket (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-RCTNetwork (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-RCTImage (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/RCTBlobHeaders (= 0.68.1)
|
||||
- React-Core/RCTWebSocket (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-RCTNetwork (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-RCTImage (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.4)
|
||||
- React-Core/RCTImageHeaders (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-RCTNetwork (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-RCTLinking (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- React-Core/RCTLinkingHeaders (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-RCTNetwork (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- RCTTypeSafety (= 0.68.1)
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/RCTImageHeaders (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-RCTNetwork (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-RCTLinking (0.68.1):
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/RCTLinkingHeaders (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-RCTNetwork (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.4)
|
||||
- React-Core/RCTNetworkHeaders (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-RCTSettings (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- RCTTypeSafety (= 0.68.1)
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/RCTNetworkHeaders (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-RCTSettings (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- RCTTypeSafety (= 0.67.4)
|
||||
- React-Core/RCTSettingsHeaders (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-RCTText (0.67.4):
|
||||
- React-Core/RCTTextHeaders (= 0.67.4)
|
||||
- React-RCTVibration (0.67.4):
|
||||
- FBReactNativeSpec (= 0.67.4)
|
||||
- RCTTypeSafety (= 0.68.1)
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/RCTSettingsHeaders (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-RCTText (0.68.1):
|
||||
- React-Core/RCTTextHeaders (= 0.68.1)
|
||||
- React-RCTVibration (0.68.1):
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-Core/RCTVibrationHeaders (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (= 0.67.4)
|
||||
- React-runtimeexecutor (0.67.4):
|
||||
- React-jsi (= 0.67.4)
|
||||
- ReactCommon/turbomodule/core (0.67.4):
|
||||
- React-Codegen (= 0.68.1)
|
||||
- React-Core/RCTVibrationHeaders (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (= 0.68.1)
|
||||
- React-runtimeexecutor (0.68.1):
|
||||
- React-jsi (= 0.68.1)
|
||||
- ReactCommon/turbomodule/core (0.68.1):
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- RCT-Folly (= 2021.06.28.00-v2)
|
||||
- React-callinvoker (= 0.67.4)
|
||||
- React-Core (= 0.67.4)
|
||||
- React-cxxreact (= 0.67.4)
|
||||
- React-jsi (= 0.67.4)
|
||||
- React-logger (= 0.67.4)
|
||||
- React-perflogger (= 0.67.4)
|
||||
- React-callinvoker (= 0.68.1)
|
||||
- React-Core (= 0.68.1)
|
||||
- React-cxxreact (= 0.68.1)
|
||||
- React-jsi (= 0.68.1)
|
||||
- React-logger (= 0.68.1)
|
||||
- React-perflogger (= 0.68.1)
|
||||
- RNCalendarEvents (2.2.0):
|
||||
- React
|
||||
- RNCAsyncStorage (1.15.14):
|
||||
@@ -464,6 +473,7 @@ DEPENDENCIES:
|
||||
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
|
||||
- React (from `../node_modules/react-native/`)
|
||||
- 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/`)
|
||||
@@ -562,6 +572,8 @@ EXTERNAL SOURCES:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-callinvoker:
|
||||
:path: "../node_modules/react-native/ReactCommon/callinvoker"
|
||||
React-Codegen:
|
||||
:path: build/generated/ios
|
||||
React-Core:
|
||||
:path: "../node_modules/react-native/"
|
||||
React-CoreModules:
|
||||
@@ -660,8 +672,8 @@ SPEC CHECKSUMS:
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: f7b0632c6437e312acf6349288d9aa4cb6d59030
|
||||
FBReactNativeSpec: 0f4e1f4cfeace095694436e7c7fcc5bf4b03a0ff
|
||||
FBLazyVector: 2c76493a346ef8cacf1f442926a39f805fffec1f
|
||||
FBReactNativeSpec: 371350f24afa87b6aba606972ec959dcd4a95c9a
|
||||
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
|
||||
FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193
|
||||
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
|
||||
@@ -672,7 +684,7 @@ SPEC CHECKSUMS:
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
Giphy: b6d5087521d251bb8c99cdc0eb07bbdf86d142d5
|
||||
giphy-react-native-sdk: 7abccf2b52123a0f30ce99da895ab6288023680c
|
||||
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
|
||||
glog: 476ee3e89abb49e07f822b48323c51c57124b572
|
||||
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
|
||||
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
|
||||
GoogleSignIn: fd381840dbe7c1137aa6dc30849a5c3e070c034a
|
||||
@@ -683,18 +695,19 @@ SPEC CHECKSUMS:
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
ObjectiveDropboxOfficial: fe206ce8c0bc49976c249d472db7fdbc53ebbd53
|
||||
PromisesObjC: 3113f7f76903778cf4a0586bd1ab89329a0b7b97
|
||||
RCT-Folly: 803a9cfd78114b2ec0f140cfa6fa2a6bafb2d685
|
||||
RCTRequired: 0aa6c1c27e1d65920df35ceea5341a5fe76bdb79
|
||||
RCTTypeSafety: d76a59d00632891e11ed7522dba3fd1a995e573a
|
||||
React: ab8c09da2e7704f4b3ebad4baa6cfdfcc852dcb5
|
||||
React-callinvoker: 216fb96b482da516b8aba4142b145938f6ea92f0
|
||||
React-Core: af99b93aff83599485e0e0879879aafa35ceae32
|
||||
React-CoreModules: 137a054ce8c547e81dc3502933b1bc0fd08df05d
|
||||
React-cxxreact: ec5ee6b08664f5b8ac71d8ad912f54d540c4f817
|
||||
React-jsi: 3e084c80fd364cee64668d5df46d40c39f7973e1
|
||||
React-jsiexecutor: cbdf37cebdc4f5d8b3d0bf5ccaa6147fd9de9f3d
|
||||
React-jsinspector: f4775ea9118cbe1f72b834f0f842baa7a99508d8
|
||||
React-logger: a1f028f6d8639a3f364ef80419e5e862e1115250
|
||||
RCT-Folly: 4d8508a426467c48885f1151029bc15fa5d7b3b8
|
||||
RCTRequired: 00581111c53531e39e3c6346ef0d2c0cf52a5a37
|
||||
RCTTypeSafety: 07e03ee7800e7dd65cba8e52ad0c2edb06c96604
|
||||
React: e61f4bf3c573d0c61c56b53dc3eb1d9daf0768a0
|
||||
React-callinvoker: 047d47230bb6fd66827f8cb0bea4e944ffd1309b
|
||||
React-Codegen: bb0403cde7374af091530e84e492589485aab480
|
||||
React-Core: a4a3a8e10d004b08e013c3d0438259dd89a3894c
|
||||
React-CoreModules: bb9f8bc36f1ae6d780b856927fa9d4aa01ccccc0
|
||||
React-cxxreact: 7dd472aefb8629d6080cbb859240bafccd902704
|
||||
React-jsi: b25808afe821b607d51c779bdd1717be8393b7ec
|
||||
React-jsiexecutor: 4a4bae5671b064a2248a690cf75957669489d08c
|
||||
React-jsinspector: 218a2503198ff28a085f8e16622a8d8f507c8019
|
||||
React-logger: f79dd3cc0f9b44f5611c6c7862badd891a862cf8
|
||||
react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe
|
||||
react-native-get-random-values: 30b3f74ca34e30e2e480de48e4add2706a40ac8f
|
||||
react-native-keep-awake: afad8a51dfef9fe9655a6344771be32c8596d774
|
||||
@@ -705,20 +718,20 @@ SPEC CHECKSUMS:
|
||||
react-native-slider: 6e9b86e76cce4b9e35b3403193a6432ed07e0c81
|
||||
react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457
|
||||
react-native-video: a4c2635d0802f983594b7057e1bce8f442f0ad28
|
||||
react-native-webrtc: b8f2769386d51a6a8c89778478618fe311226bc3
|
||||
react-native-webrtc: 206a0ac12a5633d2ec4605174d7c9f12f0d674b2
|
||||
react-native-webview: ea4899a1056c782afa96dd082179a66cbebf5504
|
||||
React-perflogger: 0afaf2f01a47fd0fc368a93bfbb5bd3b26db6e7f
|
||||
React-RCTActionSheet: 59f35c4029e0b532fc42114241a06e170b7431a2
|
||||
React-RCTAnimation: aae4f4bed122e78bdab72f7118d291d70a932ce2
|
||||
React-RCTBlob: f6fb23394b4f28cd86fa7e9f5f6ae45c23669fda
|
||||
React-RCTImage: 638815cf96124386dd296067246d91441932ae3f
|
||||
React-RCTLinking: 254dd06283dd6fdb784285f95e7cec8053c3270f
|
||||
React-RCTNetwork: 8a4c2d4f357268e520b060572d02bc69a9b991fb
|
||||
React-RCTSettings: 35d44cbb9972ab933bd0a59ea3e6646dcb030ba3
|
||||
React-RCTText: cc5315df8458cfa7b537e621271ef43273955a97
|
||||
React-RCTVibration: 3b52a7dced19cdb025b4f88ab26ceb2d85f30ba2
|
||||
React-runtimeexecutor: a9d3c82ddf7ffdad9fbe6a81c6d6f8c06385464d
|
||||
ReactCommon: 07d0c460b9ba9af3eaf1b8f5abe7daaad28c9c4e
|
||||
React-perflogger: 30ab8d6db10e175626069e742eead3ebe8f24fd5
|
||||
React-RCTActionSheet: 4b45da334a175b24dabe75f856b98fed3dfd6201
|
||||
React-RCTAnimation: d6237386cb04500889877845b3e9e9291146bc2e
|
||||
React-RCTBlob: bc9e2cd738c43bd2948e862e371402ef9584730a
|
||||
React-RCTImage: 9f8cac465c6e5837007f59ade2a0a741016dd6a3
|
||||
React-RCTLinking: 5073abb7d30cc0824b2172bd4582fc15bfc40510
|
||||
React-RCTNetwork: 28ff94aa7d8fc117fc800b87dd80869a00d2bef3
|
||||
React-RCTSettings: f27aa036f7270fe6ca43f8cdd1819e821fa429a0
|
||||
React-RCTText: 7cb6f86fa7bc86f22f16333ad243b158e63b2a68
|
||||
React-RCTVibration: 9e344c840176b0af9c84d5019eb4fed8b3c105a1
|
||||
React-runtimeexecutor: 7285b499d0339104b2813a1f58ad1ada4adbd6c0
|
||||
ReactCommon: bf2888a826ceedf54b99ad1b6182d1bc4a8a3984
|
||||
RNCalendarEvents: 7e65eb4a94f53c1744d1e275f7fafcfaa619f7a3
|
||||
RNCAsyncStorage: ea6b5c280997b2b32a587793163b1f10e580c4f7
|
||||
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
|
||||
@@ -732,8 +745,8 @@ SPEC CHECKSUMS:
|
||||
RNSound: 27e8268bdb0a1f191f219a33267f7e0445e8d62f
|
||||
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
|
||||
RNWatch: 99637948ec9b5c9ec5a41920642594ad5ba07e80
|
||||
Yoga: d6b6a80659aa3e91aaba01d0012e7edcbedcbecd
|
||||
Yoga: 17cd9a50243093b547c1e539c749928dd68152da
|
||||
|
||||
PODFILE CHECKSUM: 2167362b8c8cacb433b763a9ae6c3f4b590190c7
|
||||
PODFILE CHECKSUM: bef1335067eaa4e8c558b1248f8ab3948de855bc
|
||||
|
||||
COCOAPODS: 1.11.2
|
||||
COCOAPODS: 1.11.3
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>22.2.0</string>
|
||||
<string>22.3.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>22.2.0</string>
|
||||
<string>22.3.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>22.2.0</string>
|
||||
<string>22.3.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>22.2.0</string>
|
||||
<string>22.3.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CLKComplicationPrincipalClass</key>
|
||||
|
||||
@@ -12,6 +12,8 @@ DO_GIT_TAG=${GIT_TAG:-0}
|
||||
|
||||
echo "Releasing Jitsi Meet SDK ${SDK_VERSION}"
|
||||
|
||||
${THIS_DIR}/../../node_modules/react-native-webrtc/tools/downloadBitcode.sh
|
||||
|
||||
pushd ${RELEASE_REPO}
|
||||
|
||||
# Generate podspec file
|
||||
@@ -35,7 +37,7 @@ xcodebuild archive \
|
||||
-sdk iphonesimulator \
|
||||
-destination='generic/platform=iOS Simulator' \
|
||||
-archivePath ios/sdk/out/ios-simulator \
|
||||
ENABLE_BITCODE=NO \
|
||||
ENABLE_BITCODE=YES \
|
||||
SKIP_INSTALL=NO \
|
||||
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
|
||||
xcodebuild archive \
|
||||
@@ -45,7 +47,7 @@ xcodebuild archive \
|
||||
-sdk iphoneos \
|
||||
-destination='generic/platform=iOS' \
|
||||
-archivePath ios/sdk/out/ios-device \
|
||||
ENABLE_BITCODE=NO \
|
||||
ENABLE_BITCODE=YES \
|
||||
SKIP_INSTALL=NO \
|
||||
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
|
||||
xcodebuild -create-xcframework \
|
||||
@@ -61,7 +63,6 @@ pushd ${RELEASE_REPO}
|
||||
|
||||
# Put the new files in the repo
|
||||
cp -a ${PROJECT_REPO}/ios/sdk/out/JitsiMeetSDK.xcframework Frameworks/
|
||||
cp -a ${PROJECT_REPO}/node_modules/react-native-webrtc/apple/WebRTC.xcframework Frameworks/
|
||||
|
||||
# Add all files to git
|
||||
if [[ $DO_GIT_TAG == 1 ]]; then
|
||||
|
||||
@@ -248,6 +248,8 @@ RCT_EXPORT_METHOD(updateDeviceList) {
|
||||
- (void)audioSessionDidChangeRoute:(RTCAudioSession *)session
|
||||
reason:(AVAudioSessionRouteChangeReason)reason
|
||||
previousRoute:(AVAudioSessionRouteDescription *)previousRoute {
|
||||
DDLogInfo(@"[AudioMode] Route changed, reason: %lu", (unsigned long)reason);
|
||||
|
||||
// Update JS about the changes.
|
||||
[self notifyDevicesChanged];
|
||||
|
||||
@@ -259,16 +261,12 @@ RCT_EXPORT_METHOD(updateDeviceList) {
|
||||
self->forceSpeaker = NO;
|
||||
self->forceEarpiece = NO;
|
||||
break;
|
||||
case AVAudioSessionRouteChangeReasonCategoryChange: {
|
||||
// The category has changed. Check if it's the one we want and adjust as
|
||||
// needed.
|
||||
RTCAudioSessionConfiguration *currentConfig = [self configForMode:self->activeMode];
|
||||
if ([session.category isEqualToString:currentConfig.category]) {
|
||||
// We are in the desired category, nothing to do here.
|
||||
return;
|
||||
}
|
||||
case AVAudioSessionRouteChangeReasonCategoryChange:
|
||||
// The category has changed, re-apply our config.
|
||||
// NB: It's tempting to doa category check here and skip the processing,
|
||||
// but that won't work. If the config changes but the category remains
|
||||
// the same we'll still find ourselves here.
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,5 +27,6 @@
|
||||
- (void)closeChat;
|
||||
- (void)sendChatMessage:(NSString*)message :(NSString*)to ;
|
||||
- (void)sendSetVideoMuted:(BOOL)muted;
|
||||
- (void)sendSetClosedCaptionsEnabled:(BOOL)enabled;
|
||||
|
||||
@end
|
||||
|
||||
@@ -27,6 +27,7 @@ static NSString * const openChatAction = @"org.jitsi.meet.OPEN_CHAT";
|
||||
static NSString * const closeChatAction = @"org.jitsi.meet.CLOSE_CHAT";
|
||||
static NSString * const sendChatMessageAction = @"org.jitsi.meet.SEND_CHAT_MESSAGE";
|
||||
static NSString * const setVideoMutedAction = @"org.jitsi.meet.SET_VIDEO_MUTED";
|
||||
static NSString * const setClosedCaptionsEnabledAction = @"org.jitsi.meet.SET_CLOSED_CAPTIONS_ENABLED";
|
||||
|
||||
@implementation ExternalAPI
|
||||
|
||||
@@ -49,7 +50,8 @@ RCT_EXPORT_MODULE();
|
||||
@"OPEN_CHAT": openChatAction,
|
||||
@"CLOSE_CHAT": closeChatAction,
|
||||
@"SEND_CHAT_MESSAGE": sendChatMessageAction,
|
||||
@"SET_VIDEO_MUTED" : setVideoMutedAction
|
||||
@"SET_VIDEO_MUTED" : setVideoMutedAction,
|
||||
@"SET_CLOSED_CAPTIONS_ENABLED": setClosedCaptionsEnabledAction
|
||||
};
|
||||
};
|
||||
|
||||
@@ -73,7 +75,8 @@ RCT_EXPORT_MODULE();
|
||||
openChatAction,
|
||||
closeChatAction,
|
||||
sendChatMessageAction,
|
||||
setVideoMutedAction
|
||||
setVideoMutedAction,
|
||||
setClosedCaptionsEnabledAction
|
||||
];
|
||||
}
|
||||
|
||||
@@ -205,5 +208,10 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
||||
[self sendEventWithName:setVideoMutedAction body:data];
|
||||
}
|
||||
|
||||
- (void)sendSetClosedCaptionsEnabled:(BOOL)enabled {
|
||||
NSDictionary *data = @{ @"enabled": [NSNumber numberWithBool:enabled]};
|
||||
|
||||
[self sendEventWithName:setClosedCaptionsEnabledAction body:data];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>5.1.0</string>
|
||||
<string>5.2.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -45,5 +45,6 @@
|
||||
- (void)closeChat;
|
||||
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
|
||||
- (void)setVideoMuted:(BOOL)muted;
|
||||
- (void)setClosedCaptionsEnabled:(BOOL)enabled;
|
||||
|
||||
@end
|
||||
|
||||
@@ -160,6 +160,11 @@ static void initializeViewsMap() {
|
||||
[externalAPI sendSetVideoMuted:muted];
|
||||
}
|
||||
|
||||
- (void)setClosedCaptionsEnabled:(BOOL)enabled {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendSetClosedCaptionsEnabled:enabled];
|
||||
}
|
||||
|
||||
#pragma mark Private methods
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
import UIKit
|
||||
|
||||
final class DragGestureController {
|
||||
|
||||
var insets: UIEdgeInsets = UIEdgeInsets.zero
|
||||
var currentPosition: PiPViewCoordinator.Position? = nil
|
||||
|
||||
private var frameBeforeDragging: CGRect = CGRect.zero
|
||||
private weak var view: UIView?
|
||||
private lazy var panGesture: UIPanGestureRecognizer = {
|
||||
return UIPanGestureRecognizer(target: self,
|
||||
action: #selector(handlePan(gesture:)))
|
||||
UIPanGestureRecognizer(target: self,
|
||||
action: #selector(handlePan(gesture:)))
|
||||
}()
|
||||
|
||||
func startDragListener(inView view: UIView) {
|
||||
@@ -40,7 +40,7 @@ final class DragGestureController {
|
||||
}
|
||||
|
||||
@objc private func handlePan(gesture: UIPanGestureRecognizer) {
|
||||
guard let view = self.view else { return }
|
||||
guard let view = view else { return }
|
||||
|
||||
let translation = gesture.translation(in: view.superview)
|
||||
let velocity = gesture.velocity(in: view.superview)
|
||||
@@ -65,7 +65,7 @@ final class DragGestureController {
|
||||
let velocityMagnitude = magnitude(vector: velocity)
|
||||
let animationDuration = 0.5
|
||||
let initialSpringVelocity =
|
||||
velocityMagnitude / distanceMagnitude / CGFloat(animationDuration)
|
||||
velocityMagnitude / distanceMagnitude / CGFloat(animationDuration)
|
||||
|
||||
frame.origin = CGPoint(x: finalPos.x, y: finalPos.y)
|
||||
|
||||
@@ -75,8 +75,7 @@ final class DragGestureController {
|
||||
initialSpringVelocity: initialSpringVelocity,
|
||||
options: .curveLinear,
|
||||
animations: {
|
||||
view.frame = frame
|
||||
}, completion: nil)
|
||||
view.frame = frame })
|
||||
|
||||
default:
|
||||
break
|
||||
@@ -85,9 +84,11 @@ final class DragGestureController {
|
||||
|
||||
private func calculateFinalPosition() -> CGPoint {
|
||||
guard
|
||||
let view = self.view,
|
||||
let view = view,
|
||||
let bounds = view.superview?.frame
|
||||
else { return CGPoint.zero }
|
||||
else {
|
||||
return CGPoint.zero
|
||||
}
|
||||
|
||||
let currentSize = view.frame.size
|
||||
let adjustedBounds = bounds.inset(by: insets)
|
||||
@@ -109,19 +110,26 @@ final class DragGestureController {
|
||||
goUp = location.y < bounds.midY
|
||||
}
|
||||
|
||||
let finalPosX: CGFloat =
|
||||
goLeft
|
||||
? adjustedBounds.origin.x
|
||||
: bounds.size.width - insets.right - currentSize.width
|
||||
let finalPosY: CGFloat =
|
||||
goUp
|
||||
? adjustedBounds.origin.y
|
||||
: bounds.size.height - insets.bottom - currentSize.height
|
||||
if (goLeft && goUp) {
|
||||
currentPosition = .upperLeftCorner
|
||||
}
|
||||
|
||||
return CGPoint(x: finalPosX, y: finalPosY)
|
||||
if (!goLeft && goUp) {
|
||||
currentPosition = .upperRightCorner
|
||||
}
|
||||
|
||||
if (!goLeft && !goUp) {
|
||||
currentPosition = .lowerRightCorner
|
||||
}
|
||||
|
||||
if (goLeft && !goUp) {
|
||||
currentPosition = .lowerLeftCorner
|
||||
}
|
||||
|
||||
return currentPosition!.getOriginIn(bounds: adjustedBounds, size: currentSize)
|
||||
}
|
||||
|
||||
private func magnitude(vector: CGPoint) -> CGFloat {
|
||||
return sqrt(pow(vector.x, 2) + pow(vector.y, 2))
|
||||
sqrt(pow(vector.x, 2) + pow(vector.y, 2))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,16 +19,23 @@ import UIKit
|
||||
public typealias AnimationCompletion = (Bool) -> Void
|
||||
|
||||
public protocol PiPViewCoordinatorDelegate: class {
|
||||
|
||||
|
||||
func exitPictureInPicture()
|
||||
}
|
||||
|
||||
/// Coordinates the view state of a specified view to allow
|
||||
/// to be presented in full screen or in a custom Picture in Picture mode.
|
||||
/// This object will also provide the drag and tap interactions of the view
|
||||
/// when is presented in Picure in Picture mode.
|
||||
/// when is presented in Picture in Picture mode.
|
||||
public class PiPViewCoordinator {
|
||||
|
||||
|
||||
public enum Position {
|
||||
case lowerRightCorner
|
||||
case upperRightCorner
|
||||
case lowerLeftCorner
|
||||
case upperLeftCorner
|
||||
}
|
||||
|
||||
/// Limits the boundaries of view position on screen when minimized
|
||||
public var dragBoundInsets: UIEdgeInsets = UIEdgeInsets(top: 25,
|
||||
left: 5,
|
||||
@@ -39,23 +46,15 @@ public class PiPViewCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
public enum Position {
|
||||
case lowerRightCorner
|
||||
case upperRightCorner
|
||||
case lowerLeftCorner
|
||||
case upperLeftCorner
|
||||
}
|
||||
|
||||
public var initialPositionInSuperview = Position.lowerRightCorner
|
||||
|
||||
public let initialPositionInSuperView: Position = .lowerRightCorner
|
||||
|
||||
// Unused. Remove on the next major release.
|
||||
@available(*, deprecated, message: "The PiP window size is now fixed to 150px.")
|
||||
public var c: CGFloat = 0.0
|
||||
|
||||
|
||||
public weak var delegate: PiPViewCoordinatorDelegate?
|
||||
|
||||
private(set) var isInPiP: Bool = false // true if view is in PiP mode
|
||||
|
||||
private(set) var view: UIView
|
||||
private var currentBounds: CGRect = CGRect.zero
|
||||
|
||||
@@ -66,6 +65,13 @@ public class PiPViewCoordinator {
|
||||
|
||||
public init(withView view: UIView) {
|
||||
self.view = view
|
||||
// Required because otherwise the view will not rotate correctly.
|
||||
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
|
||||
// Otherwise the enter/exit pip animation looks odd
|
||||
// when pip window is bottom left, top left or top right,
|
||||
// because the jitsi view content does not animate, but jumps to the new size immediately.
|
||||
view.clipsToBounds = true
|
||||
}
|
||||
|
||||
/// Configure the view to be always on top of all the contents
|
||||
@@ -74,7 +80,9 @@ public class PiPViewCoordinator {
|
||||
public func configureAsStickyView(withParentView parentView: UIView? = nil) {
|
||||
guard
|
||||
let parentView = parentView ?? UIApplication.shared.keyWindow
|
||||
else { return }
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
parentView.addSubview(view)
|
||||
currentBounds = parentView.bounds
|
||||
@@ -109,6 +117,9 @@ public class PiPViewCoordinator {
|
||||
/// around screen, and add a button of top of the view to be able to exit mode
|
||||
public func enterPictureInPicture() {
|
||||
isInPiP = true
|
||||
// Resizing is done by hand when in pip.
|
||||
view.autoresizingMask = []
|
||||
|
||||
animateViewChange()
|
||||
dragController.startDragListener(inView: view)
|
||||
dragController.insets = dragBoundInsets
|
||||
@@ -125,6 +136,9 @@ public class PiPViewCoordinator {
|
||||
/// exit pip button, and disable the drag gesture
|
||||
@objc public func exitPictureInPicture() {
|
||||
isInPiP = false
|
||||
// Enable autoresizing again, which got disabled for pip.
|
||||
view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
||||
|
||||
animateViewChange()
|
||||
dragController.stopDragListener()
|
||||
|
||||
@@ -136,7 +150,7 @@ public class PiPViewCoordinator {
|
||||
let exitSelector = #selector(toggleExitPiP)
|
||||
tapGestureRecognizer?.removeTarget(self, action: exitSelector)
|
||||
tapGestureRecognizer = nil
|
||||
|
||||
|
||||
delegate?.exitPictureInPicture()
|
||||
}
|
||||
|
||||
@@ -144,6 +158,12 @@ public class PiPViewCoordinator {
|
||||
/// screen size changes
|
||||
public func resetBounds(bounds: CGRect) {
|
||||
currentBounds = bounds
|
||||
|
||||
// Is required because otherwise the pip window is buggy when rotating the device.
|
||||
// When not in pip then autoresize will do the job.
|
||||
if (isInPiP) {
|
||||
view.frame = changeViewRect()
|
||||
}
|
||||
}
|
||||
|
||||
/// Stop the dragging gesture of the root view
|
||||
@@ -169,7 +189,6 @@ public class PiPViewCoordinator {
|
||||
}
|
||||
|
||||
// MARK: - Interactions
|
||||
|
||||
@objc private func toggleExitPiP() {
|
||||
if exitPiPButton == nil {
|
||||
// show button
|
||||
@@ -186,44 +205,28 @@ public class PiPViewCoordinator {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Size calculation
|
||||
|
||||
private func animateViewChange() {
|
||||
func animateViewChange() {
|
||||
UIView.animate(withDuration: 0.25) {
|
||||
self.view.frame = self.changeViewRect()
|
||||
self.view.setNeedsLayout()
|
||||
}
|
||||
}
|
||||
|
||||
private func changeViewRect() -> CGRect {
|
||||
let bounds = currentBounds
|
||||
|
||||
guard isInPiP else {
|
||||
if !isInPiP {
|
||||
return bounds
|
||||
}
|
||||
|
||||
// resize to suggested ratio and position to the bottom right
|
||||
let adjustedBounds = bounds.inset(by: dragBoundInsets)
|
||||
let size = CGSize(width: 150, height: 150)
|
||||
let origin = initialPositionFor(pipSize: size, bounds: adjustedBounds)
|
||||
let origin = (dragController.currentPosition ?? initialPositionInSuperView).getOriginIn(bounds: adjustedBounds, size: size)
|
||||
|
||||
return CGRect(x: origin.x, y: origin.y, width: size.width, height: size.height)
|
||||
}
|
||||
|
||||
private func initialPositionFor(pipSize size: CGSize, bounds: CGRect) -> CGPoint {
|
||||
switch initialPositionInSuperview {
|
||||
case .lowerLeftCorner:
|
||||
return CGPoint(x: bounds.minX, y: bounds.maxY - size.height)
|
||||
case .lowerRightCorner:
|
||||
return CGPoint(x: bounds.maxX - size.width, y: bounds.maxY - size.height)
|
||||
case .upperLeftCorner:
|
||||
return CGPoint(x: bounds.minX, y: bounds.minY)
|
||||
case .upperRightCorner:
|
||||
return CGPoint(x: bounds.maxX - size.width, y: bounds.minY)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Animation helpers
|
||||
|
||||
private func animateTransition(animations: @escaping () -> Void,
|
||||
completion: AnimationCompletion?) {
|
||||
UIView.animate(withDuration: 0.1,
|
||||
@@ -234,3 +237,19 @@ public class PiPViewCoordinator {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: -
|
||||
extension PiPViewCoordinator.Position {
|
||||
func getOriginIn(bounds: CGRect, size: CGSize) -> CGPoint {
|
||||
switch self {
|
||||
case .lowerLeftCorner:
|
||||
return CGPoint(x: bounds.minX, y: bounds.maxY - size.height)
|
||||
case .lowerRightCorner:
|
||||
return CGPoint(x: bounds.maxX - size.width, y: bounds.maxY - size.height)
|
||||
case .upperLeftCorner:
|
||||
return CGPoint(x: bounds.minX, y: bounds.minY)
|
||||
case .upperRightCorner:
|
||||
return CGPoint(x: bounds.maxX - size.width, y: bounds.minY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "بلوتوث",
|
||||
"car": "مسجل السيارة",
|
||||
"headphones": "سماعات رأس",
|
||||
"none": "لا يوجد أي أجهزة صوت",
|
||||
"phone": "هاتف",
|
||||
@@ -76,6 +77,17 @@
|
||||
"refresh": "حدِّث الرزنامة",
|
||||
"today": "اليوم"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"leaveMeeting": "اترك الاجتماع",
|
||||
"selectSoundDevice": "حدد جهاز الصوت"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "وضع السيارة",
|
||||
"title": "وضع القيادة الآمنة",
|
||||
"videoStopped": "تم إيقاف الفيديو الخاص بك"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "أدخل الغرفة",
|
||||
"error": "خطأ: لم تُرسَل رسالتك. السبب: {{error}}",
|
||||
@@ -104,6 +116,7 @@
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "نزِّل إضافة متصفح كروم",
|
||||
"buttonTextEdge": "قم بتثبيت ملحق Edge",
|
||||
"close": "إغلق",
|
||||
"dontShowAgain": "لا ترني هذه مرة أخرى",
|
||||
"installExtensionText": "نزِّل الإضافة للدمج مع رزنامة غوغل ورزنامة أوفيس 365"
|
||||
@@ -195,6 +208,9 @@
|
||||
"selectADevice": "اختر جهازًا",
|
||||
"testAudio": "اختبر الصوت"
|
||||
},
|
||||
"dialIn": {
|
||||
"screenTitle": "ملخص الطلب"
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "{{status}} الآن"
|
||||
},
|
||||
@@ -645,6 +661,8 @@
|
||||
"linkToSalesforceKey": "ربط هذا المُلتقى",
|
||||
"linkToSalesforceProgress": "جارٍ ربط الاجتماع بـ Salesforce ...",
|
||||
"linkToSalesforceSuccess": "تم ربط الاجتماع بـ Salesforce",
|
||||
"localRecordingStarted": "بدأ {{name}} تسجيلًا محليًا.",
|
||||
"localRecordingStopped": "أوقف {{name}} التسجيل المحلي.",
|
||||
"me": "أنا",
|
||||
"moderationInEffectCSDescription": "يرجى رفع اليد إذا كنت تريد مشاركة شاشتك.",
|
||||
"moderationInEffectCSTitle": "تم حظر مشاركة الشاشة من قبل المشرف",
|
||||
@@ -800,6 +818,7 @@
|
||||
"initiated": "بدأ الاتصال",
|
||||
"joinAudioByPhone": "انضم مع صوت من الجوال",
|
||||
"joinMeeting": "انضم للمُلتقى",
|
||||
"joinMeetingInLowBandwidthMode": "الانضمام في وضع النطاق الترددي المنخفض",
|
||||
"joinWithoutAudio": "انضم دون صوت",
|
||||
"keyboardShortcuts": "تفعيل اختصارات لوحة المفاتيح",
|
||||
"linkCopied": "نُسِخ الرابط",
|
||||
@@ -875,6 +894,7 @@
|
||||
"limitNotificationDescriptionWeb": "نظرًا للضغط الكبير، سيقيَّد التسجيل إلى {{limit}} د، ولكن إن أردت التسجيل لمدة مفتوحة، جرِّب <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "لقد أنشأنا رابطًا لتسجيلك.",
|
||||
"live": "مباشر",
|
||||
"localRecordingWarning": "تأكد من تحديد علامة التبويب الحالية لاستخدام الفيديو والصوت الصحيحين. التسجيل محدود حاليًا بـ 1 كيغابايت ، أي حوالي 100 دقيقة.",
|
||||
"loggedIn": "مُسجَّل باسم {{userName}}",
|
||||
"off": "أوقِف التسجيل",
|
||||
"offBy": "أوقَف {{name}} التسجيل",
|
||||
@@ -882,6 +902,7 @@
|
||||
"onBy": "بدأ {{name}} التسجيل",
|
||||
"pending": "التحضير لتسجيل المُلتقى...",
|
||||
"rec": "تسجيل",
|
||||
"saveLocalRecording": "حفظ ملف التسجيل محليا",
|
||||
"serviceDescription": "ستحفظ خدمة التسجيل الفيديو المستجل",
|
||||
"serviceDescriptionCloud": "تسجيل سحابي",
|
||||
"serviceDescriptionCloudInfo": "يتم مسح المُلتقيات المسجلة تلقائيًا بعد 24 ساعة من وقت التسجيل.",
|
||||
@@ -889,10 +910,12 @@
|
||||
"sessionAlreadyActive": "هذه الجلسة قيد التسجيل أو البث المباشر.",
|
||||
"signIn": "دخول",
|
||||
"signOut": "خروج",
|
||||
"surfaceError": "الرجاء تحديد علامة التبويب الحالية.",
|
||||
"unavailable": "عجبًا! {{serviceName}} غير متاحة حاليًا. نعمل على حل المشكلة. حاول مرة أخرى لاحقًا.",
|
||||
"unavailableTitle": "التسجيل غير متاح",
|
||||
"uploadToCloud": "تحميل إلى السحابة"
|
||||
},
|
||||
"screenshareDisplayName": "شاشة {{name}}",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "اسحب للتحديث"
|
||||
},
|
||||
@@ -919,6 +942,7 @@
|
||||
"incomingMessage": "رسالة واردة",
|
||||
"language": "اللغة",
|
||||
"loggedIn": "الدخول باسم {{name}}",
|
||||
"maxStageParticipants": "الحد الأقصى لعدد المشاركين الذين يمكن تثبيتهم في المرحلة الرئيسية",
|
||||
"microphones": "المجهار (المايكروفون)",
|
||||
"moderator": "رئيس الجلسة",
|
||||
"more": "المزيد",
|
||||
@@ -929,6 +953,7 @@
|
||||
"playSounds": "تشغيل الصوت عند:",
|
||||
"reactions": "ردود فعل المُلتقى",
|
||||
"sameAsSystem": "مثل النظام ({{label}})",
|
||||
"screenTitle": "إعدادات",
|
||||
"selectAudioOutput": "خرج الصوت",
|
||||
"selectCamera": "الكاميرا",
|
||||
"selectMic": "المجهار (المايكروفون)",
|
||||
@@ -954,6 +979,7 @@
|
||||
"disableCrashReportingWarning": "أمتأكد من تعطيل تقارير الأعطال التقنية؟ ستسري الإعدادات الجديدة بعد إعادة تشغيل التطبيق",
|
||||
"disableP2P": "تعطيل وضع واحد شخص-لشخص",
|
||||
"displayName": "عرض الاسم",
|
||||
"displayNamePlaceholderText": "على سبيل المثال: علي الحيدري",
|
||||
"email": "البريد الإلكتروني",
|
||||
"header": "الإعدادات",
|
||||
"profileSection": "الملف الشخصي",
|
||||
@@ -1007,10 +1033,12 @@
|
||||
"boo": "Boo",
|
||||
"breakoutRoom": "الانضمام / مغادرة غرفة فرعية",
|
||||
"callQuality": "اضبط دقة الفيديو",
|
||||
"carmode": "وضع السيارة",
|
||||
"cc": "اظهِر/اخفِ الترجمة",
|
||||
"chat": "اظهِر/اخفِ نافذة الدردشة",
|
||||
"clap": "تصفيق",
|
||||
"collapse": "قلّص",
|
||||
"dock": "إرساء في النافذة الرئيسية",
|
||||
"document": "اظهِر/اخفِ الملف المشارك",
|
||||
"download": "نزِّل التطبيق",
|
||||
"embedMeeting": "ضمِّن المُلتقى",
|
||||
@@ -1061,6 +1089,7 @@
|
||||
"tileView": "اظهِر/اخفِ عرض العنوان",
|
||||
"toggleCamera": "بدِّل الكاميرا",
|
||||
"toggleFilmstrip": "بدِّل وضع الشريط السينمائي (filmstrip)",
|
||||
"undock": "فك في نافذة منفصلة",
|
||||
"videoblur": "استعمل/اخرج من وضع تغبيش خلفية الفيديو",
|
||||
"videomute": "بدِّل وضع اخفاء الفيديو"
|
||||
},
|
||||
@@ -1077,6 +1106,7 @@
|
||||
"closeChat": "أغلق الدردشة",
|
||||
"closeReactionsMenu": "إغلاق قائمة ردود الفعل",
|
||||
"disableReactionSounds": "يمكنك تعطيل أصوات ردود الفعل لهذا المُلتقى",
|
||||
"dock": "إرساء في النافذة الرئيسية",
|
||||
"documentClose": "أغلق الملف المشارك",
|
||||
"documentOpen": "افتح الملف المشارك",
|
||||
"download": "نزِّل التطبيق",
|
||||
@@ -1145,6 +1175,7 @@
|
||||
"talkWhileMutedPopup": "أتحاول التحدث؟ المجهار مكتوم لديك.",
|
||||
"tileViewToggle": "بدِّل عنوان العرض",
|
||||
"toggleCamera": "بدِّل الكاميرا",
|
||||
"undock": "فك في نافذة منفصلة",
|
||||
"videoSettings": "اعدادات الفيديو",
|
||||
"videomute": "استعمل / أوقف الكاميرا"
|
||||
},
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
"car": "Àudio del cotxe",
|
||||
"headphones": "Auriculars",
|
||||
"none": "No hi ha disponible cap aparell d'àudio",
|
||||
"phone": "Telèfon",
|
||||
@@ -39,9 +40,6 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "Poca amplada de banda"
|
||||
},
|
||||
"blankPage": {
|
||||
"meetingEnded": "La reunió ha acabat"
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "Afegeix una sala de descans",
|
||||
@@ -79,10 +77,22 @@
|
||||
"refresh": "Actualitza l'agenda",
|
||||
"today": "Avui"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"leaveMeeting": "Abandona la reunió",
|
||||
"selectSoundDevice": "Seleccioneu l'aparell d'àudio"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "Mode cotxe",
|
||||
"title": "Mode conducció segura",
|
||||
"videoStopped": "El vídeo està aturat"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "Entra a la sala",
|
||||
"error": "Error: no s'ha enviat el missatge. Raó: {{error}}",
|
||||
"fieldPlaceHolder": "Escriviu aquí el missatge",
|
||||
"lobbyChatMessageTo": "Envia un missatge en la sala d'espera a {{recipient}}",
|
||||
"message": "Missatge",
|
||||
"messageAccessibleTitle": "{{user}} diu:",
|
||||
"messageAccessibleTitleMe": "jo dic:",
|
||||
@@ -208,13 +218,15 @@
|
||||
"Remove": "Elimina",
|
||||
"Share": "Comparteix",
|
||||
"Submit": "Tramet",
|
||||
"WaitForHostMsg": "La conferència encara no ha començat. Si en sou l'amfitrió autentiqueu-vos. Altrament, espereu que arribi l'amfitrió.",
|
||||
"WaitForHostMsg": "La conferència encara no ha començat. Si en sou l'amfitrió, autentiqueu-vos. Altrament, espereu que arribi l'amfitrió.",
|
||||
"WaitingForHostTitle": "S'està esperant l'amfitrió...",
|
||||
"Yes": "Sí",
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Transmissió en directe"
|
||||
},
|
||||
"add": "Afegeix",
|
||||
"addMeetingNote": "Afegiu una nota sobre aquesta reunió",
|
||||
"addOptionalNote": "Afegeix una nota (opcional):",
|
||||
"allow": "Permet",
|
||||
"alreadySharedVideoMsg": "Un altre participant està compartint un vídeo. Aquesta conferència només permet compartir un vídeo a la vegada.",
|
||||
"alreadySharedVideoTitle": "Només es permet un vídeo compartit a la vegada",
|
||||
@@ -266,6 +278,8 @@
|
||||
"kickParticipantDialog": "Esteu segur que voleu expulsar aquest participant?",
|
||||
"kickParticipantTitle": "Voleu expulsar aquest participant?",
|
||||
"kickTitle": "Ep! {{participantDisplayName}} us ha expulsat de la reunió",
|
||||
"linkMeeting": "Enllaça la reunió",
|
||||
"linkMeetingTitle": "Enllaça la reunió a Salesforce",
|
||||
"liveStreaming": "Transmissió en directe",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "No és possible mentre l'enregistrament estigui actiu",
|
||||
"liveStreamingDisabledTooltip": "No es pot iniciar la transmissió en directe.",
|
||||
@@ -320,6 +334,7 @@
|
||||
"popupError": "El vostre navegador bloca les finestres emergents d'aquest lloc. Habiliteu les finestres emergents a la configuració de seguretat del navegador i torneu-ho a intentar.",
|
||||
"popupErrorTitle": "Finestres emergents blocades",
|
||||
"readMore": "més",
|
||||
"recentlyUsedObjects": "Els objectes que heu usat recentment",
|
||||
"recording": "Enregistrament",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "No és possible mentre hi ha una transmissió en directe activa",
|
||||
"recordingDisabledTooltip": "No es pot enregistrar.",
|
||||
@@ -342,6 +357,12 @@
|
||||
"screenSharingFailed": "Ep! Alguna cosa ha anat malament, no hem pogut iniciar la compartició de pantalla!",
|
||||
"screenSharingFailedTitle": "La compartició de pantalla ha fallat!",
|
||||
"screenSharingPermissionDeniedError": "Ep! Alguna cosa ha anat malament amb els permisos de compartició de pantalla. Torna a carregar-la i prova-ho una altra vegada.",
|
||||
"searchInSalesforce": "Cerca a Salesforce",
|
||||
"searchResults": "Resultats de la cerca({{count}})",
|
||||
"searchResultsDetailsError": "Alguna cosa ha anat malament en recuperar les dades del propietari.",
|
||||
"searchResultsError": "Alguna cosa ha anat malament en recuperar les dades.",
|
||||
"searchResultsNotFound": "No s'ha trobat cap resultat.",
|
||||
"searchResultsTryAgain": "Proveu usant paraules clau alternatives.",
|
||||
"sendPrivateMessage": "Fa poc que heu rebut un missatge privat. Voleu respondre'l de forma privada, o voleu enviar el missatge al grup?",
|
||||
"sendPrivateMessageCancel": "Envia'l al grup",
|
||||
"sendPrivateMessageOk": "Envia'l en privat",
|
||||
@@ -351,20 +372,22 @@
|
||||
"sessionRestarted": "La trucada s'ha reiniciat a causa d'un problema de connexió.",
|
||||
"shareAudio": "Continua",
|
||||
"shareAudioTitle": "Com compartir l'àudio",
|
||||
"shareAudioWarningD1": "heu d'aturar la compartició de pantalla abans de compartir l'àudio.",
|
||||
"shareAudioWarningD2": "heu de reiniciar la compartició de pantalla i marcar l'opció «Comparteix l'àudio».",
|
||||
"shareAudioWarningD1": "cal que atureu la compartició de pantalla abans de compartir l'àudio.",
|
||||
"shareAudioWarningD2": "cal que reinicieu la compartició de pantalla i marqueu l'opció «Comparteix l'àudio».",
|
||||
"shareAudioWarningH1": "Si voleu compartir només l'àudio:",
|
||||
"shareAudioWarningTitle": "Heu d'aturar la compartició de pantalla abans de compartir l'àudio",
|
||||
"shareAudioWarningTitle": "Cal que atureu la compartició de pantalla abans de compartir l'àudio",
|
||||
"shareMediaWarningGenericH2": "Si voleu compartir la pantalla i l'àudio",
|
||||
"shareScreenWarningD1": "heu d'aturar l'ús compartit d'àudio abans de compartir la pantalla.",
|
||||
"shareScreenWarningD2": "heu d'aturar l'ús compartit d'àudio, iniciar l'ús compartit de la pantalla i marcar l'opció «Comparteix l'àudio».",
|
||||
"shareScreenWarningH1": "Si només voleu compartir la pantalla:",
|
||||
"shareScreenWarningTitle": "Heu d'aturar l'ús compartit d'àudio abans de compartir la pantalla",
|
||||
"shareScreenWarningTitle": "Cal que atureu l'ús compartit d'àudio abans de compartir la pantalla",
|
||||
"shareVideoLinkError": "Proporcioneu un enllaç de vídeo correcte.",
|
||||
"shareVideoTitle": "Comparteix el vídeo",
|
||||
"shareYourScreen": "Comparteix la pantalla",
|
||||
"shareYourScreenDisabled": "S'ha inhabilitat la compartició de pantalla.",
|
||||
"sharedVideoDialogError": "Error: URL no vàlid",
|
||||
"sharedVideoLinkPlaceholder": "Enllaç de YouTube o enllaç directe del vídeo",
|
||||
"start": "Inicia",
|
||||
"startLiveStreaming": "Inicia la transmissió en directe",
|
||||
"startRecording": "Inicia l'enregistrament",
|
||||
"startRemoteControlErrorMessage": "S'ha produït un error en intentar iniciar la sessió de control remot!",
|
||||
@@ -407,6 +430,10 @@
|
||||
"veryBad": "Molt dolenta",
|
||||
"veryGood": "Molt bona"
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "No s'ha trobat cap resultat :(",
|
||||
"search": "Cerca a GIPHY"
|
||||
},
|
||||
"helpView": {
|
||||
"header": "Centre d'ajuda"
|
||||
},
|
||||
@@ -473,6 +500,7 @@
|
||||
"focusLocal": "Focus al vostre vídeo",
|
||||
"focusRemote": "Focus en el vídeo d'una altra persona",
|
||||
"fullScreen": "Entra o surt de la pantalla completa",
|
||||
"giphyMenu": "Mostra o amaga el menú GIPHY",
|
||||
"keyboardShortcuts": "Dreceres de teclat",
|
||||
"localRecording": "Mostra o amaga els controls d'enregistrament local",
|
||||
"mute": "Silencia o activa el so",
|
||||
@@ -527,6 +555,7 @@
|
||||
"admitAll": "Admet tothom",
|
||||
"allow": "Permet",
|
||||
"backToKnockModeButton": "Demaneu per a unir-vos",
|
||||
"chat": "Xat",
|
||||
"dialogTitle": "Mode de sala d'espera",
|
||||
"disableDialogContent": "El mode de sala d'espera es troba activat. Aquesta funcionalitat evita que els participants no desitjats puguin unir-se a la reunió. Voleu desactivar-ho?",
|
||||
"disableDialogSubmit": "Desactiva",
|
||||
@@ -539,6 +568,7 @@
|
||||
"errorMissingPassword": "Introduïu la contrasenya de la reunió",
|
||||
"invalidPassword": "La contrasenya no és vàlida",
|
||||
"joinRejectedMessage": "La vostra sol·licitud ha estat rebutjada per un moderador.",
|
||||
"joinRejectedTitle": "S'ha rebutjat la petició d'unir-s'hi.",
|
||||
"joinTitle": "Entra a la reunió",
|
||||
"joinWithPasswordMessage": "S'està intentant unir-s'hi amb contrasenya, espereu...",
|
||||
"joiningMessage": "Us unireu a la reunió de seguida que algú accepti la sol·licitud",
|
||||
@@ -547,6 +577,8 @@
|
||||
"knockButton": "Demana d'unir-se",
|
||||
"knockTitle": "Algú vol unir-se a la reunió",
|
||||
"knockingParticipantList": "Llista de participants que piquen per a entrar",
|
||||
"lobbyChatStartedNotification": "{{moderator}} ha començat un xat en la sala d'espera amb {{attendee}}",
|
||||
"lobbyChatStartedTitle": "{{moderator}} ha començat un xat en la sala d'espera amb vós.",
|
||||
"nameField": "Introduïu el vostre nom",
|
||||
"notificationLobbyAccessDenied": "{{originParticipantName}} ha rebutjat l'entrada de {{targetParticipantName}}",
|
||||
"notificationLobbyAccessGranted": "{{originParticipantName}} ha acceptat l'entrada de {{targetParticipantName}}",
|
||||
@@ -609,6 +641,7 @@
|
||||
"displayNotifications": "Mostra les notificacions sobre",
|
||||
"focus": "Focus de la conferència",
|
||||
"focusFail": "{{component}} no és disponible, torneu a intentar en {{ms}} segons",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Notificacions",
|
||||
"hostAskedUnmute": "El moderador vol que parleu",
|
||||
"invitedOneMember": "S'ha convidat {{name}}",
|
||||
@@ -618,6 +651,12 @@
|
||||
"leftOneMember": "{{name}} ha sortit de la reunió",
|
||||
"leftThreePlusMembers": "{{name}} i molts d'altres han sortit de la reunió",
|
||||
"leftTwoMembers": "{{first}} i {{second}} han sortit de la reunió",
|
||||
"linkToSalesforce": "Enllaç a Salesforce",
|
||||
"linkToSalesforceDescription": "Podeu enllaçar el resum de la reunió a un objecte Salesforce.",
|
||||
"linkToSalesforceError": "No s'ha pogut enllaçar la reunió a Salesforce",
|
||||
"linkToSalesforceKey": "Enllaça aquesta reunió",
|
||||
"linkToSalesforceProgress": "S'està enllaçant la reunió a Salesforce...",
|
||||
"linkToSalesforceSuccess": "La reunió s'ha enllaçat a Salesforce",
|
||||
"me": "Jo",
|
||||
"moderationInEffectCSDescription": "Aixequeu la mà si voleu compartir la pantalla.",
|
||||
"moderationInEffectCSTitle": "El moderador ha blocat la compartició de pantalla",
|
||||
@@ -641,6 +680,8 @@
|
||||
"oldElectronClientDescription1": "Sembla que useu una versió antiga del client Jitsi Meet, que té vulnerabilitats de seguretat conegudes. Assegureu-vos d'actualitzar-lo",
|
||||
"oldElectronClientDescription2": "última construcció",
|
||||
"oldElectronClientDescription3": "ara!",
|
||||
"participantWantsToJoin": "Vol unir-se a la reunió",
|
||||
"participantsWantToJoin": "Volen unir-se a la reunió",
|
||||
"passwordRemovedRemotely": "Un altre participant ha eliminat $t(lockRoomPasswordUppercase)",
|
||||
"passwordSetRemotely": "Un altre participant ha establert la $t(lockRoomPassword)",
|
||||
"raiseHandAction": "Aixeca la mà",
|
||||
@@ -648,7 +689,7 @@
|
||||
"raisedHands": "{{participantName}} i {{raisedHands}} persones més",
|
||||
"reactionSounds": "Desactiva el so",
|
||||
"reactionSoundsForAll": "Desactiva el so per a tothom",
|
||||
"screenShareNoAudio": "La casella Comparteix l'àudio no s'ha marcat a la pantalla de selecció de la finestra.",
|
||||
"screenShareNoAudio": "No s'ha marcat la compartició d'àudio en la pantalla de selecció de la finestra.",
|
||||
"screenShareNoAudioTitle": "No s'ha pogut compartir l'àudio del sistema!",
|
||||
"selfViewTitle": "Sempre podeu activar la vista pròpia des de la configuració",
|
||||
"somebody": "Algú",
|
||||
@@ -660,7 +701,9 @@
|
||||
"videoMutedRemotelyDescription": "Sempre la podeu activar de nou.",
|
||||
"videoMutedRemotelyTitle": "{{participantDisplayName}} us ha apagat el vídeo",
|
||||
"videoUnmuteBlockedDescription": "L'activació de la càmera i la compartició d'escriptori s'han blocat temporalment per limitacions del sistema.",
|
||||
"videoUnmuteBlockedTitle": "L'activació de la càmera i la compartició d'escriptori estan blocades!"
|
||||
"videoUnmuteBlockedTitle": "L'activació de la càmera i la compartició d'escriptori estan blocades!",
|
||||
"viewLobby": "Mostra la sala d'espera",
|
||||
"waitingParticipants": "{{waitingParticipants}} persones"
|
||||
},
|
||||
"participantsPane": {
|
||||
"actions": {
|
||||
@@ -692,6 +735,7 @@
|
||||
},
|
||||
"passwordDigitsOnly": "Fins a {{number}} dígits",
|
||||
"passwordSetRemotely": "Establerta per un altre participant",
|
||||
"pinnedParticipant": "El participant està fixat",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"skip": "Omet",
|
||||
@@ -748,7 +792,7 @@
|
||||
"veryPoorConnection": "És esperable que la qualitat de la trucada sigui realment terrible.",
|
||||
"videoFreezing": "És esperable que el vídeo es congeli, passi a negre i aparegui pixelat.",
|
||||
"videoHighQuality": "És esperable que el vídeo tingui una bona qualitat.",
|
||||
"videoLowQuality": "És esperable que el vídeo sigui de poca qualitat en termes de marcs per segon i resolució.",
|
||||
"videoLowQuality": "És esperable que el vídeo sigui de poca qualitat en termes de fotogrames per segon i resolució.",
|
||||
"videoTearing": "És esperable que el vídeo aparegui pixelat o amb defectes visuals."
|
||||
},
|
||||
"copyAndShare": "Copia i comparteix l'enllaç de la reunió",
|
||||
@@ -807,6 +851,18 @@
|
||||
},
|
||||
"raisedHand": "Vull parlar",
|
||||
"raisedHandsLabel": "Nombre de mans aixecades",
|
||||
"record": {
|
||||
"already": {
|
||||
"linked": "La reunió ja està enllaçada amb aquest objecte de Salesforce."
|
||||
},
|
||||
"type": {
|
||||
"account": "Compte",
|
||||
"contact": "Contacte",
|
||||
"lead": "Principal",
|
||||
"opportunity": "Oportunitat",
|
||||
"owner": "Propietari"
|
||||
}
|
||||
},
|
||||
"recording": {
|
||||
"authDropboxText": "Puja a Dropbox",
|
||||
"availableSpace": "Espai disponible: {{spaceLeft}} MB (aproximadament {{duration}} minuts d'enregistrament)",
|
||||
@@ -820,7 +876,12 @@
|
||||
"expandedOn": "S'està enregistrant la reunió.",
|
||||
"expandedPending": "S'ha iniciat l'enregistrament...",
|
||||
"failedToStart": "No s'ha pogut iniciar l'enregistrament",
|
||||
"fileSharingdescription": "Comparteix l'enregistrament amb els participants de la reunió",
|
||||
"fileSharingdescription": "Compartiu l'enllaç de l'enregistrament de la reunió amb els participants",
|
||||
"highlight": "Destaca",
|
||||
"highlightMoment": "Destaca el moment",
|
||||
"highlightMomentDisabled": "Podeu destacar moment en iniciar-se l'enregistrament",
|
||||
"highlightMomentSuccess": "Moment destacat",
|
||||
"highlightMomentSucessDescription": "S'ha afegit el moment destacat al resum de la reunió.",
|
||||
"inProgress": "L'enregistrament o la transmissió en directe és en progrés",
|
||||
"limitNotificationDescriptionNative": "A causa de la gran demanda, el vostre enregistrament es limitarà a {{limit}} min. Per a enregistraments il·limitats, proveu <3>{{app}}</3>.",
|
||||
"limitNotificationDescriptionWeb": "A causa de la gran demanda, l'enregistrament es limitarà a {{limit}} min. Per a enregistraments il·limitats, proveu <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
@@ -835,6 +896,7 @@
|
||||
"rec": "ENREG",
|
||||
"serviceDescription": "El servei d'enregistrament desarà el vostre enregistrament",
|
||||
"serviceDescriptionCloud": "Enregistrament al núvol",
|
||||
"serviceDescriptionCloudInfo": "Les reunions enregistrades s'esborren automàticament 24 hores després de l'enregistrament.",
|
||||
"serviceName": "Servei d'enregistrament",
|
||||
"sessionAlreadyActive": "Aquesta sessió ja s'està enregistrant o emetent en directe.",
|
||||
"signIn": "Inicia la sessió",
|
||||
@@ -843,6 +905,7 @@
|
||||
"unavailableTitle": "L'enregistrament no és disponible",
|
||||
"uploadToCloud": "Puja al núvol"
|
||||
},
|
||||
"screenshareDisplayName": "Pantalla de: {{name}}",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Estireu per a actualitzar"
|
||||
},
|
||||
@@ -862,13 +925,14 @@
|
||||
},
|
||||
"desktopShareFramerate": "Velocitat de fotogrames en la compartició d'escriptori",
|
||||
"desktopShareHighFpsWarning": "Una velocitat de fotogrames més alta per a compartir escriptori pot afectar l'amplada de banda. Heu de reiniciar la compartició de pantalla perquè la nova configuració tingui efecte.",
|
||||
"desktopShareWarning": "Heu de reiniciar la compartició de pantalla perquè la nova configuració tingui efecte.",
|
||||
"desktopShareWarning": "Cal que reinicieu la compartició de pantalla perquè la nova configuració tingui efecte.",
|
||||
"devices": "Aparells",
|
||||
"followMe": "Tothom que em segueix",
|
||||
"framesPerSecond": "marcs per segon",
|
||||
"framesPerSecond": "fotogrames per segon",
|
||||
"incomingMessage": "Missatge entrant",
|
||||
"language": "Llengua",
|
||||
"loggedIn": "Sessió iniciada com a {{name}}",
|
||||
"maxStageParticipants": "El nombre màxim de participants que es poden fixar en la escena principal",
|
||||
"microphones": "Micròfons",
|
||||
"moderator": "Moderador",
|
||||
"more": "Més",
|
||||
@@ -921,6 +985,7 @@
|
||||
"speakerStats": {
|
||||
"angry": "Enuig",
|
||||
"disgusted": "Disgust",
|
||||
"displayEmotions": "Mostra les emocions",
|
||||
"fearful": "Temor",
|
||||
"happy": "Felicitat",
|
||||
"hours": "{{count}}h",
|
||||
@@ -955,16 +1020,19 @@
|
||||
"boo": "Esbroncada",
|
||||
"breakoutRoom": "Entra o surt de la sala de descans",
|
||||
"callQuality": "Gestiona la qualitat de la trucada",
|
||||
"carmode": "Mode cotxe",
|
||||
"cc": "Activa o desactiva els subtítols",
|
||||
"chat": "Obre o tanca el xat",
|
||||
"clap": "Picament de mans",
|
||||
"collapse": "Col·lapsa",
|
||||
"dock": "Acobla a la finestra principal",
|
||||
"document": "Activa o desactiva el document compartit",
|
||||
"download": "Baixeu les nostres aplicacions",
|
||||
"embedMeeting": "Insereix la reunió",
|
||||
"expand": "Expandeix",
|
||||
"feedback": "Deixa comentaris",
|
||||
"fullScreen": "Activa o desactiva la pantalla completa",
|
||||
"giphy": "Mostra o amaga el menú GIPHY",
|
||||
"grantModerator": "Concedir drets de moderador",
|
||||
"hangup": "Surt de la reunió",
|
||||
"help": "Ajuda",
|
||||
@@ -972,6 +1040,7 @@
|
||||
"kick": "Expulsa el participant",
|
||||
"laugh": "Riure",
|
||||
"like": "Polzes amunt",
|
||||
"linkToSalesforce": "Enllaç a Salesforce",
|
||||
"lobbyButton": "Activa o desactiva la sala d'espera",
|
||||
"localRecording": "Activa o desactiva els controls d'enregistrament local",
|
||||
"lockRoom": "Activa o desactiva la contrasenya de la reunió",
|
||||
@@ -994,10 +1063,11 @@
|
||||
"remoteVideoMute": "Desactiva la càmera del participant",
|
||||
"security": "Opcions de seguretat",
|
||||
"selectBackground": "Trieu un fons",
|
||||
"selfView": "Mostra o amaga la visualització d'un mateix",
|
||||
"shareRoom": "Convida-hi algú",
|
||||
"shareYourScreen": "Inicia o atura la compartició de pantalla",
|
||||
"shareaudio": "Comparteix l'àudio",
|
||||
"sharedvideo": "Activa o desactiva la compartició de vídeo",
|
||||
"sharedvideo": "Mostra o amaga la compartició de vídeo",
|
||||
"shortcuts": "Activa o desactiva les dreceres",
|
||||
"show": "Mostra-ho en l'escena",
|
||||
"silence": "Silenci",
|
||||
@@ -1006,6 +1076,7 @@
|
||||
"tileView": "Activa o desactiva el mode mosaic",
|
||||
"toggleCamera": "Activa o desactiva la càmera",
|
||||
"toggleFilmstrip": "Mostra o amaga la cinta",
|
||||
"undock": "Desacobla en una finestra separada",
|
||||
"videoblur": "Activa o desactiva el desenfocament del vídeo",
|
||||
"videomute": "Activa o desactiva la càmera"
|
||||
},
|
||||
@@ -1022,6 +1093,7 @@
|
||||
"closeChat": "Tanca el xat",
|
||||
"closeReactionsMenu": "Tanca el menú de reaccions",
|
||||
"disableReactionSounds": "Podeu desactivar els sons de reacció per a aquesta reunió",
|
||||
"dock": "Acobla en la finestra principal",
|
||||
"documentClose": "Tanca el document compartit",
|
||||
"documentOpen": "Obre el document compartit",
|
||||
"download": "Baixeu les nostres aplicacions",
|
||||
@@ -1032,6 +1104,7 @@
|
||||
"exitFullScreen": "Surt de la pantalla completa",
|
||||
"exitTileView": "Surt del mode mosaic",
|
||||
"feedback": "Deixa comentaris",
|
||||
"giphy": "Mostra o amaga el menú GIPHY",
|
||||
"hangup": "Surt la reunió",
|
||||
"help": "Ajuda",
|
||||
"invite": "Convida-hi persones",
|
||||
@@ -1039,6 +1112,7 @@
|
||||
"laugh": "Riure",
|
||||
"leaveBreakoutRoom": "Surt de la sala de descans",
|
||||
"like": "Polzes amunt",
|
||||
"linkToSalesforce": "Enllaç a Salesforce",
|
||||
"lobbyButtonDisable": "Desactiva el mode de sala d'espera",
|
||||
"lobbyButtonEnable": "Activa el mode de sala d'espera",
|
||||
"login": "Inicia sessió",
|
||||
@@ -1088,6 +1162,7 @@
|
||||
"talkWhileMutedPopup": "Intenteu parlar? Esteu silenciat.",
|
||||
"tileViewToggle": "Activa o desactiva el mode mosaic",
|
||||
"toggleCamera": "Activa o desactiva la càmera",
|
||||
"undock": "Desacobla en una finestra principal",
|
||||
"videoSettings": "Paràmetres de vídeo",
|
||||
"videomute": "Inicia o atura la càmera"
|
||||
},
|
||||
@@ -1158,8 +1233,12 @@
|
||||
"moderator": "Moderador",
|
||||
"mute": "El participant està silenciat",
|
||||
"muted": "Silenciat",
|
||||
"pinToStage": "Fixa a l'escena",
|
||||
"remoteControl": "Inicia o atura el control remot",
|
||||
"screenSharing": "El participant està compartint la pantalla",
|
||||
"show": "Mostra-ho en l'escena",
|
||||
"showSelfView": "Mostra la visualització d'un mateix",
|
||||
"unpinFromStage": "Deixa de fixar",
|
||||
"videoMuted": "La càmera està desactivada",
|
||||
"videomute": "El participant ha aturat la càmera"
|
||||
},
|
||||
|
||||
@@ -935,7 +935,7 @@
|
||||
"security": "Opciones de seguridad",
|
||||
"selectBackground": "Seleccione el fondo",
|
||||
"shareRoom": "Invitar a alguien",
|
||||
"shareYourScreen": "Alternar pantalla compartida",
|
||||
"shareYourScreen": "Comenzar / detener compartir pantalla",
|
||||
"shareaudio": "Compartir audio",
|
||||
"sharedvideo": "Alternar vídeo compartido",
|
||||
"shortcuts": "Alternar accesos directos",
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
"countryNotSupported": "Non supportiamo ancora questa destinazione.",
|
||||
"countryReminder": "Stai chiamando fuori dagli Stati Uniti? Assicurati d'inserire il prefisso internazionale!",
|
||||
"defaultEmail": "Tua email di default",
|
||||
"disabled": "Non puoi invitare persone.",
|
||||
"failedToAdd": "L'aggiunta di nuove persone è fallita",
|
||||
"disabled": "Non puoi invitare partecipanti.",
|
||||
"failedToAdd": "L'aggiunta di nuovi partecipanti è fallita",
|
||||
"footerText": "La chiamata all'esterno è disabilitata.",
|
||||
"googleEmail": "Email Google",
|
||||
"inviteMoreHeader": "Sei l'unico presente nella riunione",
|
||||
"inviteMoreMailSubject": "Unisciti alla riunione {{appName}}",
|
||||
"inviteMorePrompt": "Invita altre persone",
|
||||
"inviteMorePrompt": "Invita altri partecipanti",
|
||||
"linkCopied": "Collegamento copiato negli appunti",
|
||||
"noResults": "Nessun risultato corrispondente",
|
||||
"outlookEmail": "Email Outlook",
|
||||
@@ -26,7 +26,7 @@
|
||||
"shareStream": "Condividi il collegamento alla diretta",
|
||||
"sipAddresses": "indirizzi SIP",
|
||||
"telephone": "Telefono: {{number}}",
|
||||
"title": "Invita persone a questa riunione",
|
||||
"title": "Invita partecipanti a questa riunione",
|
||||
"yahooEmail": "Email Yahoo"
|
||||
},
|
||||
"audioDevices": {
|
||||
@@ -77,6 +77,17 @@
|
||||
"refresh": "Aggiorna calendario",
|
||||
"today": "Oggi"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"leaveMeeting": " Lascia riunione",
|
||||
"selectSoundDevice": "Scegli audio"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "Modalità in auto",
|
||||
"title": "Modalità guida sicura",
|
||||
"videoStopped": "Il tuo video è fermo"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "Entra nella conversazione",
|
||||
"error": "Errore: il tuo messaggio non è stato inviato. Motivo: {{error}}",
|
||||
@@ -101,7 +112,7 @@
|
||||
},
|
||||
"title": "Conversazione",
|
||||
"titleWithPolls": "Conversazione",
|
||||
"you": "tu"
|
||||
"you": "te"
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "Installa l'estensione Chrome",
|
||||
@@ -304,10 +315,10 @@
|
||||
"muteEveryonesVideoDialogOk": "Spegni",
|
||||
"muteEveryonesVideoTitle": "Vuoi spegnere le videocamere di tutti?",
|
||||
"muteParticipantBody": "Non sarai in grado di riattivare il loro microfono, ma loro potranno riattivarlo in qualsiasi momento.",
|
||||
"muteParticipantButton": "Spegni microfono",
|
||||
"muteParticipantButton": "Spegni audio",
|
||||
"muteParticipantsVideoBody": "Una volta spenta la videocamera non potrai riaccenderla, ma lui potrà riattivarla in qualsiasi momento.",
|
||||
"muteParticipantsVideoBodyModerationOn": "Non potrai riaccendere le videocamere, né potranno loro.",
|
||||
"muteParticipantsVideoButton": "Spegni videocamera",
|
||||
"muteParticipantsVideoButton": "Spegni video",
|
||||
"muteParticipantsVideoDialog": "Sei sicuro di voler spegnere la videocamera di questo partecipante? Lui potrà riattivarla in ogni momento.",
|
||||
"muteParticipantsVideoDialogModerationOn": "Are you sure you want to turn off this participant's camera? You won't be able to turn the camera back on and neither will they.",
|
||||
"muteParticipantsVideoTitle": "Vuoi spegnere la videocamera di questo partecipante?",
|
||||
@@ -463,10 +474,10 @@
|
||||
"moreNumbers": "Più numeri",
|
||||
"noNumbers": "Nessun numero da chiamare.",
|
||||
"noPassword": "Nessuna",
|
||||
"noRoom": "Non è stata specificata nessuna stanza da chiamare.",
|
||||
"noRoom": "Non è stata specificata nessuna riunione da chiamare.",
|
||||
"numbers": "Numeri da chiamare",
|
||||
"password": "$t(lockRoomPasswordUppercase):",
|
||||
"sip": "SIP address",
|
||||
"sip": "Indirizzo SIP",
|
||||
"title": "Condividi",
|
||||
"tooltip": "Invia il collegamento e i numeri telefonici di questa riunione"
|
||||
},
|
||||
@@ -618,21 +629,21 @@
|
||||
"me": "io",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Falla di sicurezza!",
|
||||
"allowAction": "Permetti",
|
||||
"allowAction": "Autorizza",
|
||||
"allowedUnmute": "Puoi accendere il microfono, avviare la videocamera, o condividere il tuo schermo.",
|
||||
"audioUnmuteBlockedDescription": "Lo sblocco dei microfoni è stato temporaneament bloccato per limiti del sistema.",
|
||||
"audioUnmuteBlockedDescription": "Lo sblocco dei microfoni è stato temporaneamente bloccato per limiti del sistema.",
|
||||
"audioUnmuteBlockedTitle": "Riattivazione dei microfoni bloccata!",
|
||||
"chatMessages": "Messaggi delle conversazioni",
|
||||
"connectedOneMember": "{{name}} si è connesso",
|
||||
"connectedThreePlusMembers": "{{name}} e altri {{count}} si sono connessi",
|
||||
"connectedTwoMembers": "{{first}} e {{second}} si sono connessi",
|
||||
"connectedOneMember": "{{name}} è entrato in riunione",
|
||||
"connectedThreePlusMembers": "{{name}} e altri {{count}} sono entrati in riunione",
|
||||
"connectedTwoMembers": "{{first}} e {{second}} sono entrati in riunione",
|
||||
"disconnected": "disconnesso",
|
||||
"displayNotifications": "Mostra le notifiche per",
|
||||
"focus": "Focus su riunione",
|
||||
"focusFail": "{{component}} non disponibile - riprova in {{ms}} sec",
|
||||
"focusFail": "{{component}} non disponibile - riprovo tra {{ms}} sec",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Notifiche",
|
||||
"hostAskedUnmute": "Il moderatore vorrebbe che tu parlassi",
|
||||
"hostAskedUnmute": "Il moderatore ti dice di accendere il microfono",
|
||||
"invitedOneMember": "{{displayName}} è stato invitato",
|
||||
"invitedThreePlusMembers": "Hai invitato {{name}} e altri {{count}}",
|
||||
"invitedTwoMembers": "Hai invitato {{first}} e {{second}}",
|
||||
@@ -646,6 +657,8 @@
|
||||
"linkToSalesforceKey": "Link this meeting",
|
||||
"linkToSalesforceProgress": "Linking meeting to Salesforce...",
|
||||
"linkToSalesforceSuccess": "The meeting was linked to Salesforce",
|
||||
"localRecordingStarted": "{{name}} ha cominciato a registrare.",
|
||||
"localRecordingStopped": "{{name}} ha smesso di registrare.",
|
||||
"me": "Io",
|
||||
"moderationInEffectCSDescription": "Alza la mano, se vuoi condividere lo schermo, per favore.",
|
||||
"moderationInEffectCSTitle": "La condivisione schermo è stata bloccata dal moderatore",
|
||||
@@ -659,10 +672,10 @@
|
||||
"moderationStoppedTitle": "Moderazione interrotta",
|
||||
"moderationToggleDescription": "da {{participantDisplayName}}",
|
||||
"moderator": "Impostati i permessi di moderatore!",
|
||||
"muted": "Hai iniziato la conversazione con l'audio disattivato.",
|
||||
"muted": "Hai iniziato la conversazione con audio disattivato.",
|
||||
"mutedRemotelyDescription": "Puoi sempre attivare il microfono, quando vuoi parlare. Spegni il microfono quando hai finito, per non introdurre rumori di fondo nella riunione.",
|
||||
"mutedRemotelyTitle": "Ti è stato disattivato l'audio da {{participantDisplayName}}!",
|
||||
"mutedTitle": "Hai l'audio disattivato!",
|
||||
"mutedTitle": "Hai audio disattivato!",
|
||||
"newDeviceAction": "OK, usala",
|
||||
"newDeviceAudioTitle": "Trovata nuova origine audio",
|
||||
"newDeviceCameraTitle": "Trovata nuova videocamera",
|
||||
@@ -698,10 +711,10 @@
|
||||
"actions": {
|
||||
"allow": "Permetti ai partecipanti di:",
|
||||
"allowVideo": "Autorizza video",
|
||||
"askUnmute": "Chiedi di riattivare audio",
|
||||
"askUnmute": "Chiedi di accendere microfono",
|
||||
"audioModeration": "Riattivare audio",
|
||||
"blockEveryoneMicCamera": "Blocca audio e video a tutti",
|
||||
"invite": "Invita persone",
|
||||
"invite": "Invita partecipanti",
|
||||
"moreModerationActions": "Altre opzioni di moderazione",
|
||||
"moreModerationControls": "Altri controlli di moderazione",
|
||||
"moreParticipantOptions": "Altre opzioni partecipanti",
|
||||
@@ -714,7 +727,7 @@
|
||||
"videoModeration": "Riavviare videocamera"
|
||||
},
|
||||
"close": "Chiudi",
|
||||
"header": "Partecipanti",
|
||||
"header": "Partecipanti e sala d'attesa",
|
||||
"headings": {
|
||||
"lobby": "Sala d'attesa ({{count}})",
|
||||
"participantsList": "Partecipanti alla riunione ({{count}})",
|
||||
@@ -876,6 +889,7 @@
|
||||
"limitNotificationDescriptionWeb": "Data l'alta domanda la tua registrazione sarà limitata a {{limit}} minuti. Per registrazioni illimitate, prova <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "Abbiamo generato un collegamento alla tua registrazione.",
|
||||
"live": "DIRETTA",
|
||||
"localRecordingWarning": "Assicurati di aver selezionato la scheda corrente, per regitrare gli audio e video corretti. La registrazione è limitata ad 1GB, cioè circa 100 minuti.",
|
||||
"loggedIn": "Accesso effettuato come {{userName}}",
|
||||
"off": "Registrazione interrotta",
|
||||
"offBy": "{{name}} ha interrotto la registrazione",
|
||||
@@ -883,6 +897,7 @@
|
||||
"onBy": "Registrazione iniziata da {{name}}",
|
||||
"pending": "In preparazione alla registrazione della riunione",
|
||||
"rec": "REC",
|
||||
"saveLocalRecording": "Salva localmente il file della registrazione",
|
||||
"serviceDescription": "La tua registrazione verrà salvata dal servizio di registrazione che hai scelto",
|
||||
"serviceDescriptionCloud": "Registrazione in rete",
|
||||
"serviceDescriptionCloudInfo": "Le riunioni registrate vengono automaticamente cancellate 24 ore dopo la registrazione.",
|
||||
@@ -890,15 +905,17 @@
|
||||
"sessionAlreadyActive": "Questa sessione è già in corso di registrazione o trasmissione in diretta.",
|
||||
"signIn": "Entra",
|
||||
"signOut": "Esci",
|
||||
"surfaceError": "Selezionare la scheda corrente, per favore.",
|
||||
"unavailable": "Ops! Il {{serviceName}} non è al momento disponibile. Stiamo lavorando per risolvere il problema. Riprova più tardi.",
|
||||
"unavailableTitle": "Registrazione non disponibile",
|
||||
"uploadToCloud": "Carica in cloud"
|
||||
},
|
||||
"screenshareDisplayName": "Schermo di {{name}}",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Trascina per aggiornare"
|
||||
},
|
||||
"security": {
|
||||
"about": "Puoi aggiungere una $t(lockRoomPassword) alla riunione. I partecipanti dovranno fornire la $t(lockRoomPassword) per essere autorizzati a partecipare alla riunione.",
|
||||
"about": "Puoi aggiungere una $t(lockRoomPassword) alla riunione. I partecipanti dovranno fornire la $t(lockRoomPassword) per essere autorizzati a partecipare alla riunione.",
|
||||
"aboutReadOnly": "I moderatori della riunione possono aggiungere $t(lockRoomPassword). I partecipanti dovranno fornire la $t(lockRoomPassword) per essere autorizzati a partecipare alla riunione.",
|
||||
"insecureRoomNameWarning": "Il nome della riunione non è sicuro. Dei partecipanti indesiderati potrebbero unirsi alla riunione. Puoi proteggere l'accesso alla riunione col bottone sicurezza.",
|
||||
"securityOptions": "Impostazioni di sicurezza"
|
||||
@@ -930,7 +947,7 @@
|
||||
"participantLeft": "Partecipante Uscito",
|
||||
"playSounds": "Suoni attivati",
|
||||
"reactions": "Reazioni riunione",
|
||||
"sameAsSystem": "Come nel sistema ({{label}})",
|
||||
"sameAsSystem": "Stesso del computer ({{label}})",
|
||||
"selectAudioOutput": "Uscita audio",
|
||||
"selectCamera": "Videocamera",
|
||||
"selectMic": "Microfono",
|
||||
@@ -961,8 +978,8 @@
|
||||
"profileSection": "Profilo",
|
||||
"serverURL": "URL del server",
|
||||
"showAdvanced": "Impostazioni avanzate",
|
||||
"startWithAudioMuted": "Inizia con l'audio disattivato",
|
||||
"startWithVideoMuted": "Avvia con il video disattivato",
|
||||
"startWithAudioMuted": "Inizia con audio disattivato",
|
||||
"startWithVideoMuted": "Inizia con video disattivato",
|
||||
"version": "Versione"
|
||||
},
|
||||
"share": {
|
||||
@@ -1003,16 +1020,18 @@
|
||||
"toolbar": {
|
||||
"Settings": "Impostazioni",
|
||||
"accessibilityLabel": {
|
||||
"Settings": "Attiva/disattiva impostazioni",
|
||||
"Settings": "Attiva/Disattiva impostazioni",
|
||||
"audioOnly": "Spegni/Accendi audio",
|
||||
"audioRoute": "Scegli l'uscita audio",
|
||||
"boo": "Boo",
|
||||
"breakoutRoom": "Entra/Lascia sottogruppo",
|
||||
"callQuality": "Imposta qualità della chiamata",
|
||||
"carmode": "Modalità in auto",
|
||||
"cc": "Avvia/Ferma sottotitoli",
|
||||
"chat": "Entra/Esci da conversazione",
|
||||
"clap": "Applaudi",
|
||||
"collapse": "Riduci",
|
||||
"dock": "Aggancia alla finestra principale",
|
||||
"document": "Apri/Chiudi documenti condivisi",
|
||||
"download": "Scarica le nostre app",
|
||||
"embedMeeting": "Incorpora riunione altrove",
|
||||
@@ -1023,50 +1042,51 @@
|
||||
"grantModerator": "Autorizza moderatore",
|
||||
"hangup": "Lascia la riunione",
|
||||
"help": "Aiuto",
|
||||
"invite": "Invita persone",
|
||||
"invite": "Invita partecipanti",
|
||||
"kick": "Espelli partecipante",
|
||||
"laugh": "Ridi",
|
||||
"like": "Mi piace",
|
||||
"linkToSalesforce": "Collega a Salesforce",
|
||||
"lobbyButton": "Attiva/disattiva sala d'attesa",
|
||||
"localRecording": "Abilita/disattiva controlli di registrazione locale",
|
||||
"lobbyButton": "Attiva/Disattiva sala d'attesa",
|
||||
"localRecording": "Abilita/Disattiva controlli di registrazione locale",
|
||||
"lockRoom": "Attiva o disattiva password",
|
||||
"moreActions": "Attiva o disattiva menu avanzato",
|
||||
"moreActionsMenu": "Menu avanzato",
|
||||
"moreOptions": "Più opzioni",
|
||||
"mute": "Attiva/disattiva audio",
|
||||
"moreOptions": "Altre opzioni",
|
||||
"mute": "Attiva/Disattiva audio",
|
||||
"muteEveryone": "Spegni i microfoni a tutti",
|
||||
"muteEveryoneElse": "Spegni i microfoni di tutti gli altri",
|
||||
"muteEveryoneElsesVideo": "Spegni le videocamere di tutti gli altri",
|
||||
"muteEveryonesVideo": "Spegni le videocamere a tutti",
|
||||
"participants": "Partecipanti",
|
||||
"pip": "Attiva/disattiva immagine nell’immagine",
|
||||
"pip": "Attiva/Disattiva immagine nell’immagine",
|
||||
"privateMessage": "Invia messaggio privato",
|
||||
"profile": "Modifica profilo",
|
||||
"raiseHand": "Alza/Abbassa la mano",
|
||||
"reactionsMenu": "Apri/chiudi menù delle reaction",
|
||||
"recording": "Avvia/ferma registrazione",
|
||||
"reactionsMenu": "Apri/Chiudi menù delle reaction",
|
||||
"recording": "Avvia/Ferma registrazione",
|
||||
"remoteMute": "Spegni microfono al partecipante",
|
||||
"remoteVideoMute": "Spegni videocamera del partecipante",
|
||||
"security": "Impostazioni di sicurezza",
|
||||
"selectBackground": "Scegli sfondo",
|
||||
"selfView": "Mostra tua immagine",
|
||||
"shareRoom": "Invita qualcuno",
|
||||
"shareYourScreen": "Attiva/disattiva condivisione schermo",
|
||||
"shareYourScreen": "Attiva/Disattiva condivisione schermo",
|
||||
"shareaudio": "Condividi audio",
|
||||
"sharedvideo": "Attiva/disattiva condivisione",
|
||||
"shortcuts": "Attiva/disattiva scorciatoie",
|
||||
"sharedvideo": "Attiva/Disattiva condivisione",
|
||||
"shortcuts": "Attiva/Disattiva scorciatoie",
|
||||
"show": "Mostra in primo piano",
|
||||
"silence": "Silenzio",
|
||||
"speakerStats": "Attiva/disattiva statistiche relatore",
|
||||
"speakerStats": "Attiva/Disattiva statistiche relatore",
|
||||
"surprised": "Sorpreso",
|
||||
"tileView": "Vedi tutti i partecipanti insieme, o uno solo",
|
||||
"tileView": "Vedi tutti i partecipanti, o uno solo",
|
||||
"toggleCamera": "Cambia videocamera",
|
||||
"toggleFilmstrip": "Attiva/disattiva pellicola",
|
||||
"toggleFilmstrip": "Attiva/Disattiva pellicola",
|
||||
"undock": "Sgancia in una finestra separata",
|
||||
"videoblur": "Sfoca video",
|
||||
"videomute": "Attiva/disattiva videocamera"
|
||||
"videomute": "Attiva/Disattiva videocamera"
|
||||
},
|
||||
"addPeople": "Aggiungi persone alla chiamata",
|
||||
"addPeople": "Aggiungi partecipanti alla chiamata",
|
||||
"audioOnlyOff": "Disabilita modalità per banda limitata",
|
||||
"audioOnlyOn": "Abilita modalità per banda limitata",
|
||||
"audioRoute": "Scegli l'uscita audio",
|
||||
@@ -1074,11 +1094,12 @@
|
||||
"authenticate": "Autenticazione",
|
||||
"boo": "Boo",
|
||||
"callQuality": "Imposta qualità video",
|
||||
"chat": "Apri / Chiudi conversazione",
|
||||
"chat": "Apri/Chiudi conversazione",
|
||||
"clap": "Applaudi",
|
||||
"closeChat": "Chiudi conversazione",
|
||||
"closeReactionsMenu": "Chiudi il menù reazioni",
|
||||
"disableReactionSounds": "Puoi disattivare i suoni delle reaction, in questa riunione",
|
||||
"dock": "Aggancia nella finestra principale",
|
||||
"documentClose": "Chiudi documento condiviso",
|
||||
"documentOpen": "Apri documento condiviso",
|
||||
"download": "Scarica le nostre app",
|
||||
@@ -1092,7 +1113,7 @@
|
||||
"giphy": "Menù GIPHY",
|
||||
"hangup": "Butta giù",
|
||||
"help": "Aiuto",
|
||||
"invite": "Invita persone",
|
||||
"invite": "Invita partecipanti",
|
||||
"joinBreakoutRoom": "Entra in sottogruppo",
|
||||
"laugh": "Ridi",
|
||||
"leaveBreakoutRoom": "Lascia breakout room",
|
||||
@@ -1103,9 +1124,9 @@
|
||||
"login": "Accedi",
|
||||
"logout": "Scollegati",
|
||||
"lowerYourHand": "Abbassa la mano",
|
||||
"moreActions": "Più azioni",
|
||||
"moreOptions": "Più opzioni",
|
||||
"mute": "Attiva / Disattiva microfono",
|
||||
"moreActions": "Altre azioni",
|
||||
"moreOptions": "Altre opzioni",
|
||||
"mute": "Attiva/Disattiva microfono",
|
||||
"muteEveryone": "Spegni audio a tutti",
|
||||
"muteEveryonesVideo": "Spegni videocamera di tutti",
|
||||
"noAudioSignalDesc": "Se non l'hai disabilitato intenzionalmente nelle impostazioni, prova a cambiare dispositivo di input.",
|
||||
@@ -1121,7 +1142,7 @@
|
||||
"pip": "Abilita visualizzazione immagine nell'immagine",
|
||||
"privateMessage": "invia un messaggio privato",
|
||||
"profile": "Modifica profilo",
|
||||
"raiseHand": "Alza / Abbassa la mano",
|
||||
"raiseHand": "Alza/Abbassa la mano",
|
||||
"raiseYourHand": "Alza la mano",
|
||||
"reactionBoo": "Invia boo",
|
||||
"reactionClap": "Invia applauso",
|
||||
@@ -1147,11 +1168,12 @@
|
||||
"talkWhileMutedPopup": "Stai provando a parlare? Il microfono è disattivato.",
|
||||
"tileViewToggle": "Vedi tutti i partecipanti insieme, o uno solo",
|
||||
"toggleCamera": "Cambia videocamera",
|
||||
"undock": "Sgancia in una finestra separata",
|
||||
"videoSettings": "Impostazioni video",
|
||||
"videomute": "Attiva / Disattiva videocamera"
|
||||
"videomute": "Attiva/Disattiva videocamera"
|
||||
},
|
||||
"transcribing": {
|
||||
"ccButtonTooltip": "Inizia / Ferma i sottotitoli",
|
||||
"ccButtonTooltip": "Inizia/Ferma i sottotitoli",
|
||||
"error": "Trascrizione fallita. Prova di nuovo.",
|
||||
"expandedLabel": "La trascrizione della riunione è attiva",
|
||||
"failedToStart": "C'è stato un errore nell'avvio del servizio di trascrizione.",
|
||||
@@ -1176,12 +1198,12 @@
|
||||
},
|
||||
"videoSIPGW": {
|
||||
"busy": "Stiamo lavorando per liberare le risorse. Riprova tra qualche minuto.",
|
||||
"busyTitle": "Il servizio Stanza al momento è occupato",
|
||||
"busyTitle": "Il servizio Riunione al momento è occupato",
|
||||
"errorAlreadyInvited": "{{displayName}} già invitato",
|
||||
"errorInvite": "Riunione non ancora stabilita. Riprova più tardi.",
|
||||
"errorInviteFailed": "Stiamo lavorando per risolvere il problema. Riprova più tardi.",
|
||||
"errorInviteFailedTitle": "Invito a {{displayName}} fallito",
|
||||
"errorInviteTitle": "Errore nell'invito alla stanza",
|
||||
"errorInviteTitle": "Errore nell'invito alla riunione",
|
||||
"pending": "{{displayName}} è stato invitato"
|
||||
},
|
||||
"videoStatus": {
|
||||
@@ -1218,7 +1240,7 @@
|
||||
"mute": "Il partecipante ha il microfono spento",
|
||||
"muted": "Audio disattivato",
|
||||
"pinToStage": "Aggiungi agli oratori",
|
||||
"remoteControl": "Avvia/ferma il controllo remoto",
|
||||
"remoteControl": "Avvia/Ferma il controllo remoto",
|
||||
"screenSharing": "Il partecipante sta condividendo lo schermo",
|
||||
"show": "Mostra tra gli oratori",
|
||||
"showSelfView": "Mostra tua immagine",
|
||||
@@ -1237,7 +1259,7 @@
|
||||
"image1": "Spiaggia",
|
||||
"image2": "Parete neutra bianca",
|
||||
"image3": "Stanza bianca vuota",
|
||||
"image4": "Lampanda da pavimento nera",
|
||||
"image4": "Lampada da pavimento nera",
|
||||
"image5": "Montagna",
|
||||
"image6": "Foresta",
|
||||
"image7": "Alba",
|
||||
@@ -1248,13 +1270,13 @@
|
||||
"title": "Sfondi",
|
||||
"uploadedImage": "Carica immagine {{index}}",
|
||||
"webAssemblyWarning": "Il WebAssembly non è supportato",
|
||||
"webAssemblyWarningDescription": "Il WebAssembly è disabilitato o non è supportat da questo browser"
|
||||
"webAssemblyWarningDescription": "Il WebAssembly è disabilitato o non è supportato da questo browser"
|
||||
},
|
||||
"volumeSlider": "Sbarra volume",
|
||||
"welcomepage": {
|
||||
"accessibilityLabel": {
|
||||
"join": "Tocca per accedere",
|
||||
"roomname": "Inserisci nome stanza"
|
||||
"roomname": "Inserisci nome riunione"
|
||||
},
|
||||
"addMeetingName": "Aggiungi Nome riunione",
|
||||
"appDescription": "Avvia una videochiamata con tutto il team. Invita tutti quelli che conosci. {{app}} è una soluzione per effettuare videoconferenze totalmente crittografata, 100% open source, che puoi usare sempre, ogni giorno, gratuitamente – senza bisogno di un account.",
|
||||
@@ -1273,7 +1295,7 @@
|
||||
"headerTitle": "Jitsi Meet",
|
||||
"info": "Informazioni chiamata",
|
||||
"jitsiOnMobile": "Jitsi su mobile – scarica le nostre app e dai inizio ad una riunione dovunque tu sia",
|
||||
"join": "CREA / UNISCITI",
|
||||
"join": "CREA/UNISCITI",
|
||||
"logo": {
|
||||
"calendar": "Logo calendario",
|
||||
"desktopPreviewThumbnail": "Icona anteprima desktop",
|
||||
@@ -1289,11 +1311,11 @@
|
||||
"privacy": "Riservatezza",
|
||||
"recentList": "Recenti",
|
||||
"recentListDelete": "Cancella",
|
||||
"recentListEmpty": "La tua lista è vuota. Conversa con qualcuno del tuo team e lo vedrai apparire nella lista delle riunioni recenti.",
|
||||
"recentListEmpty": "La lista delle riunioni recenti è vuota. Partecipa almeno ad una riunione e potrai riavviarla in seguito.",
|
||||
"reducedUIText": "Benvenuto in {{app}}!",
|
||||
"roomNameAllowedChars": "Il nome della riunione non deve contenere questi caratteri: ?, &, :, ', \", %, #.",
|
||||
"roomname": "Inserisci il nome della stanza",
|
||||
"roomnameHint": "Inserisci il nome o l'URL della stanza alla quale vuoi accedere. Puoi anche inventarti un nome, assicurati solo che le persone che vuoi contattare lo conoscano, così che possano inserire lo stesso nome.",
|
||||
"roomname": "Inserisci il nome della riunione",
|
||||
"roomnameHint": "Inserisci il nome o l'URL della alla quale vuoi accedere. Puoi anche inventarti un nome, assicurati solo che le persone che vuoi contattare lo conoscano, così che possano inserire lo stesso nome.",
|
||||
"sendFeedback": "Invia feedback",
|
||||
"startMeeting": "Inizia riunione",
|
||||
"terms": "Termini di utilizzo",
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
"car": "Sistema áudio do automóvel",
|
||||
"headphones": "Auscultadores",
|
||||
"none": "Sem dispositivos de áudio disponíveis",
|
||||
"phone": "Telemóvel",
|
||||
@@ -76,6 +77,17 @@
|
||||
"refresh": "Atualizar calendário",
|
||||
"today": "Hoje"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"leaveMeeting": " Deixar a reunião",
|
||||
"selectSoundDevice": "Seleccionar dispositivo de som"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "Modo carro",
|
||||
"title": "Modo de condução segura",
|
||||
"videoStopped": "O seu vídeo está parado"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "Entrar na sala",
|
||||
"error": "Erro: a sua mensagem não foi enviada. Motivo: {{error}}",
|
||||
@@ -104,6 +116,7 @@
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "Instalar extensão do Chrome",
|
||||
"buttonTextEdge": "Instalar extensão do Edge",
|
||||
"close": "Fechar",
|
||||
"dontShowAgain": "Não me mostre isto outra vez",
|
||||
"installExtensionText": "Instalar a extensão para a integração Google Calendar e Office 365"
|
||||
@@ -182,7 +195,7 @@
|
||||
"unsupportedBrowser": "Parece que está a usar um browser que não suportamos."
|
||||
},
|
||||
"defaultLink": "ex.: {{url}}",
|
||||
"defaultNickname": "ex.: João Pedro",
|
||||
"defaultNickname": "ex.: João Dias",
|
||||
"deviceError": {
|
||||
"cameraError": "Falha ao aceder à sua câmara",
|
||||
"cameraPermission": "Erro ao obter permissão para a câmara",
|
||||
@@ -195,6 +208,9 @@
|
||||
"selectADevice": "Selecione um dispositivo",
|
||||
"testAudio": "Tocar um som de teste"
|
||||
},
|
||||
"dialIn": {
|
||||
"screenTitle": "Resumo da marcação"
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "está agora {{status}}"
|
||||
},
|
||||
@@ -276,7 +292,7 @@
|
||||
"lockRoom": "Adicionar reunião $t(lockRoomPassword)",
|
||||
"lockTitle": "Bloqueio falhado",
|
||||
"login": "Entrar",
|
||||
"logoutQuestion": "Tem a certeza de que quer terminar a sessão e interromper a conferência?",
|
||||
"logoutQuestion": "Tem a certeza de que quer terminar a sessão e sair da conferência?",
|
||||
"logoutTitle": "Sair",
|
||||
"maxUsersLimitReached": "O limite para o número máximo de participantes foi atingido. A conferência está cheia. Por favor contacte o proprietário da reunião ou tente novamente mais tarde!",
|
||||
"maxUsersLimitReachedTitle": "Limite máximo de participantes atingido",
|
||||
@@ -345,7 +361,7 @@
|
||||
"screenSharingFailed": "Oops! Algo correu mal, não fomos capazes de começar a partilhar o ecrã!",
|
||||
"screenSharingFailedTitle": "A partilha de ecrã falhou!",
|
||||
"screenSharingPermissionDeniedError": "Oops! Alguma coisa correu mal com as vossas permissões de partilha de ecrã. Por favor, volte a carregar e tente novamente.",
|
||||
"searchInSalesforce": "Pesquisar na Força de Vendas",
|
||||
"searchInSalesforce": "Pesquisar na Salesforce",
|
||||
"searchResults": "Resultados da pesquisa({{count}})",
|
||||
"searchResultsDetailsError": "Algo correu mal enquanto se recuperava os dados do proprietário.",
|
||||
"searchResultsError": "Alguma coisa correu mal durante a recuperação de dados.",
|
||||
@@ -565,8 +581,8 @@
|
||||
"knockButton": "Pedir para participar",
|
||||
"knockTitle": "Alguém quer juntar-se à reunião",
|
||||
"knockingParticipantList": "Lista de participantes a expulsar",
|
||||
"lobbyChatStartedNotification": "{{moderator}} iniciou uma conversa na sala de espera com {{attendee}}",
|
||||
"lobbyChatStartedTitle": "{{moderator}} iniciou uma conversa na sala de espera consigo.",
|
||||
"lobbyChatStartedNotification": "{{moderator}} iniciou com {{attendee}} uma conversa na sala de espera",
|
||||
"lobbyChatStartedTitle": "{{moderator}} iniciou consigo uma conversa na sala de espera.",
|
||||
"nameField": "Introduza o seu nome",
|
||||
"notificationLobbyAccessDenied": "{{targetParticipantName}} foi recusada a adesão por {{originParticipantName}}",
|
||||
"notificationLobbyAccessGranted": "{{targetParticipantName}} foi autorizado a aderir por {{originParticipantName}}",
|
||||
@@ -639,12 +655,14 @@
|
||||
"leftOneMember": "{{name}} deixou a reunião",
|
||||
"leftThreePlusMembers": "{{name}} e muitos outros deixaram a reunião",
|
||||
"leftTwoMembers": "{{first}} e {{second}} deixaram a reunião",
|
||||
"linkToSalesforce": "Link para a Força de Vendas",
|
||||
"linkToSalesforceDescription": "Pode ligar o resumo da reunião a um objecto da Força de Vendas.",
|
||||
"linkToSalesforceError": "Falha na ligação da reunião à Força de Vendas",
|
||||
"linkToSalesforce": "Link para a Salesforce",
|
||||
"linkToSalesforceDescription": "Pode ligar o resumo da reunião a um objecto da Salesforce.",
|
||||
"linkToSalesforceError": "Falha na ligação da reunião à Salesforce",
|
||||
"linkToSalesforceKey": "Ligar esta reunião",
|
||||
"linkToSalesforceProgress": "A ligar a reunião à Força de Vendas...",
|
||||
"linkToSalesforceSuccess": "A reunião foi ligada à Força de Vendas",
|
||||
"linkToSalesforceProgress": "A ligar a reunião à Salesforce...",
|
||||
"linkToSalesforceSuccess": "A reunião foi ligada à Salesforce",
|
||||
"localRecordingStarted": "{{name}} iniciou uma gravação local.",
|
||||
"localRecordingStopped": "{{name}} parou uma gravação local.",
|
||||
"me": "Eu",
|
||||
"moderationInEffectCSDescription": "Por favor, levantem a mão se quiserem partilhar o vosso ecrã.",
|
||||
"moderationInEffectCSTitle": "A partilha de ecrã é bloqueada pelo moderador",
|
||||
@@ -723,7 +741,7 @@
|
||||
},
|
||||
"passwordDigitsOnly": "Até {{number}} dígitos",
|
||||
"passwordSetRemotely": "Definido por outro participante",
|
||||
"pinnedParticipant": "O participante está fixado",
|
||||
"pinnedParticipant": "O participante está afixado",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"skip": "Ignorar",
|
||||
@@ -800,6 +818,7 @@
|
||||
"initiated": "Chamada iniciada",
|
||||
"joinAudioByPhone": "Entrar com o áudio do telefone",
|
||||
"joinMeeting": "Entrar na reunião",
|
||||
"joinMeetingInLowBandwidthMode": "Entrar em modo de baixa largura de banda",
|
||||
"joinWithoutAudio": "Entrar sem áudio",
|
||||
"keyboardShortcuts": "Ativar os atalhos de teclado",
|
||||
"linkCopied": "Link copiado para a área de transferência",
|
||||
@@ -875,6 +894,7 @@
|
||||
"limitNotificationDescriptionWeb": "Devido à grande procura, a sua gravação será limitada a {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "Gerámos um link para a sua gravação.",
|
||||
"live": "DIRETO",
|
||||
"localRecordingWarning": "Certifique-se de seleccionar o separador actual a fim de utilizar o vídeo e áudio correctos. A gravação está actualmente limitada a 1 GB, o que é cerca de 100 minutos.",
|
||||
"loggedIn": "Conectado como {{userName}}",
|
||||
"off": "Gravação parada",
|
||||
"offBy": "{{name}} parou a gravação",
|
||||
@@ -882,6 +902,7 @@
|
||||
"onBy": "{{name}} iniciou a gravação",
|
||||
"pending": "Preparando para gravar a reunião...",
|
||||
"rec": "REC",
|
||||
"saveLocalRecording": "Guardar ficheiro de gravação localmente",
|
||||
"serviceDescription": "Sua gravação será salva pelo serviço de gravação",
|
||||
"serviceDescriptionCloud": "Gravação na nuvem",
|
||||
"serviceDescriptionCloudInfo": "As reuniões gravadas são automaticamente apagadas 24h após a hora de gravação.",
|
||||
@@ -889,10 +910,12 @@
|
||||
"sessionAlreadyActive": "Esta sessão já está a ser gravada ou transmitida em direto.",
|
||||
"signIn": "Entrar",
|
||||
"signOut": "Sair",
|
||||
"surfaceError": "Por favor, seleccione o separador actual.",
|
||||
"unavailable": "Oops! O {{serviceName}} está indisponível. Estamos trabalhando para resolver o problema. Por favor, tente mais tarde.",
|
||||
"unavailableTitle": "Gravação indisponível",
|
||||
"uploadToCloud": "Enviar para a nuvem"
|
||||
},
|
||||
"screenshareDisplayName": "Ecrã de {{name}}",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Puxe para atualizar"
|
||||
},
|
||||
@@ -919,6 +942,7 @@
|
||||
"incomingMessage": "Receber uma mensagem",
|
||||
"language": "Idioma",
|
||||
"loggedIn": "Sessão iniciada como {{name}}",
|
||||
"maxStageParticipants": "Número máximo de participantes que podem ser afixados",
|
||||
"microphones": "Microfones",
|
||||
"moderator": "Moderador",
|
||||
"more": "Mais",
|
||||
@@ -929,6 +953,7 @@
|
||||
"playSounds": "Reproduzir som quando",
|
||||
"reactions": "Expressarem uma reação",
|
||||
"sameAsSystem": "O mesmo que o sistema ({{label}})",
|
||||
"screenTitle": "Definições",
|
||||
"selectAudioOutput": "Saída de áudio",
|
||||
"selectCamera": "Câmara",
|
||||
"selectMic": "Microfone",
|
||||
@@ -954,6 +979,7 @@
|
||||
"disableCrashReportingWarning": "Tem a certeza de que quer desativar o relatório de falhas? A configuração será aplicada depois de reiniciar a aplicação.",
|
||||
"disableP2P": "Desactivar o modo Peer-To-Peer",
|
||||
"displayName": "Nome de exibição",
|
||||
"displayNamePlaceholderText": "Ex: João Dias",
|
||||
"email": "Email",
|
||||
"header": "Configurações",
|
||||
"profileSection": "Perfil",
|
||||
@@ -1007,10 +1033,12 @@
|
||||
"boo": "Vaia",
|
||||
"breakoutRoom": "Entrar/Sair salas instantâneas",
|
||||
"callQuality": "Gerir a qualidade do vídeo",
|
||||
"carmode": "Modo carro",
|
||||
"cc": "Mudar legendas",
|
||||
"chat": "Abrir / Fechar chat",
|
||||
"clap": "Aplausos",
|
||||
"collapse": "Colapsar",
|
||||
"dock": "Encaixar na janela principal",
|
||||
"document": "Mudar para documento partilhado",
|
||||
"download": "Descarregar as nossas aplicações",
|
||||
"embedMeeting": "Reunião incorporada",
|
||||
@@ -1025,7 +1053,7 @@
|
||||
"kick": "Remover participante",
|
||||
"laugh": "Risos",
|
||||
"like": "Aprovado",
|
||||
"linkToSalesforce": "Link para a Força de Vendas",
|
||||
"linkToSalesforce": "Link para a Salesforce",
|
||||
"lobbyButton": "Ativar/desativar sala de espera",
|
||||
"localRecording": "Mudar os controlos locais de gravação",
|
||||
"lockRoom": "Mudar palavra-chave de reunião",
|
||||
@@ -1061,6 +1089,7 @@
|
||||
"tileView": "Mudar a vista em quadrícula",
|
||||
"toggleCamera": "Mudar a câmara",
|
||||
"toggleFilmstrip": "Mudar a película de filme",
|
||||
"undock": "Soltar numa janela separada",
|
||||
"videoblur": "Mudar o desfoque de vídeo",
|
||||
"videomute": "Iniciar / Parar câmara"
|
||||
},
|
||||
@@ -1077,6 +1106,7 @@
|
||||
"closeChat": "Fechar chat",
|
||||
"closeReactionsMenu": "Fechar menu de reações",
|
||||
"disableReactionSounds": "Pode desactivar os sons de reacção para esta reunião",
|
||||
"dock": "Encaixar na janela principal",
|
||||
"documentClose": "Fechar documento partilhado",
|
||||
"documentOpen": "Abrir documento partilhado",
|
||||
"download": "Descarregar as nossas aplicações",
|
||||
@@ -1095,7 +1125,7 @@
|
||||
"laugh": "Risos",
|
||||
"leaveBreakoutRoom": "Sair da sala",
|
||||
"like": "Aprovado",
|
||||
"linkToSalesforce": "Link para a Força de Vendas",
|
||||
"linkToSalesforce": "Link para a Salesforce",
|
||||
"lobbyButtonDisable": "Desativar sala de espera",
|
||||
"lobbyButtonEnable": "Ativar sala de espera",
|
||||
"login": "Iniciar sessão",
|
||||
@@ -1145,6 +1175,7 @@
|
||||
"talkWhileMutedPopup": "Está a tentar falar? Está com o microfone desativado.",
|
||||
"tileViewToggle": "Mudar para vista em quadrícula",
|
||||
"toggleCamera": "Mudar a câmara",
|
||||
"undock": "Soltar numa janela separada",
|
||||
"videoSettings": "Definições de vídeo",
|
||||
"videomute": "Iniciar / Parar câmara"
|
||||
},
|
||||
@@ -1215,12 +1246,12 @@
|
||||
"moderator": "Moderador",
|
||||
"mute": "Participante está sem som",
|
||||
"muted": "Sem som",
|
||||
"pinToStage": "Fixar no ecrã",
|
||||
"pinToStage": "Afixar",
|
||||
"remoteControl": "Iniciar / Parar controlo remoto",
|
||||
"screenSharing": "Participante está a partilhar o seu ecrã",
|
||||
"show": "Mostrar no palco",
|
||||
"showSelfView": "Mostrar autovisualização",
|
||||
"unpinFromStage": "Soltar",
|
||||
"unpinFromStage": "Desafixar",
|
||||
"videoMuted": "Câmara desativada",
|
||||
"videomute": "Participante parou a câmara"
|
||||
},
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
},
|
||||
"calendarSync": {
|
||||
"addMeetingURL": "Добавить ссылку конференции",
|
||||
"confirmAddLink": "Вы хотите добавить ссылку Jitsi к этому календарному событию?",
|
||||
"confirmAddLink": "Вы хотите добавить ссылку {{app}} к этому календарному событию?",
|
||||
"error": {
|
||||
"appConfiguration": "Неправильно настроена интеграция календаря.",
|
||||
"generic": "Произошла ошибка. Проверьте настройки календаря или попробуйте обновить его.",
|
||||
@@ -429,7 +429,7 @@
|
||||
"answer": "Ответ",
|
||||
"audioCallTitle": "Входящий звонок",
|
||||
"decline": "Отклонить",
|
||||
"productLabel": "из Jitsi Meet",
|
||||
"productLabel": "из {{app}}",
|
||||
"videoCallTitle": "Входящий видеозвонок"
|
||||
},
|
||||
"info": {
|
||||
@@ -665,7 +665,7 @@
|
||||
"newDeviceAction": "Использовать",
|
||||
"newDeviceAudioTitle": "Обнаружено новое аудиоустройство",
|
||||
"newDeviceCameraTitle": "Обнаружена новая камера",
|
||||
"oldElectronClientDescription1": "Похоже, вы используете старую версию клиента Jitsi Meet, которая имеет известные уязвимости в системе безопасности. Убедитесь, что вы обновили до нашей ",
|
||||
"oldElectronClientDescription1": "Похоже, вы используете старую версию клиента {{app}}, которая имеет известные уязвимости в системе безопасности. Убедитесь, что вы обновили до нашей ",
|
||||
"oldElectronClientDescription2": "последней версии",
|
||||
"oldElectronClientDescription3": " сейчас!",
|
||||
"participantWantsToJoin": "Хочет присоединиться к митингу",
|
||||
@@ -1268,9 +1268,9 @@
|
||||
"go": "ОК",
|
||||
"goSmall": "ОК",
|
||||
"headerSubtitle": "Защищенная высококачественная видеосвязь",
|
||||
"headerTitle": "Сервер видеоконференцсвязи Jitsi Meet",
|
||||
"headerTitle": "Сервер видеоконференцсвязи {{app}}",
|
||||
"info": "Инфо",
|
||||
"jitsiOnMobile": "Jitsy для мобильных устройств — загрузите наши приложения и начните встречу из любого места",
|
||||
"jitsiOnMobile": "{{app}} для мобильных устройств — загрузите наши приложения и начните встречу из любого места",
|
||||
"join": "СОЗДАТЬ / ПРИСОЕДИНИТЬСЯ",
|
||||
"logo": {
|
||||
"calendar": "Calendar логотип",
|
||||
|
||||
@@ -602,10 +602,12 @@
|
||||
"OldElectronAPPTitle": "Güvenlik açığı!",
|
||||
"allowAction": "İzin ver",
|
||||
"allowedUnmute": "Mikrofonunuzu sessizden çıkarabilir, kameranızı başlatabilir veya ekranınızı paylaşabilirsiniz.",
|
||||
"chatMessages": "Sohbet mesajları",
|
||||
"connectedOneMember": "{{name}} toplantıya katıldı",
|
||||
"connectedThreePlusMembers": "{{name}} ve {{count}} kişi daha toplantıya katıldı",
|
||||
"connectedTwoMembers": "{{first}} ve {{second}} toplantıya katıldı",
|
||||
"disconnected": "bağlantı kesildi",
|
||||
"displayNotifications": "Bildirimleri görüntüle",
|
||||
"focus": "Toplantı odağı",
|
||||
"focusFail": "{{component}} uygun değil - {{ms}} saniye içinde tekrar deneyin",
|
||||
"grantedTo": "{{to}} kişisine yönetici hakları verildi!",
|
||||
@@ -662,6 +664,9 @@
|
||||
"audioModeration": "Seslerini aç",
|
||||
"blockEveryoneMicCamera": "Herkesin mikrofonunu ve kamerasını blokla",
|
||||
"invite": "Birini davet et",
|
||||
"moreModerationActions": "Daha fazla denetleme seçeneği",
|
||||
"moreModerationControls": "Daha fazla denetleme kontrolü",
|
||||
"moreParticipantOptions": "Daha fazla katılımcı seçeneği",
|
||||
"mute": "Sustur",
|
||||
"muteAll": "Herkesi sustur",
|
||||
"muteEveryoneElse": "Diğer herkesi sessize al",
|
||||
@@ -676,7 +681,8 @@
|
||||
"lobby": "Lobi ({{count}})",
|
||||
"participantsList": "Toplantı Katılımcıları ({{count}})",
|
||||
"waitingLobby": "Lobide bekleyen ({{count}})"
|
||||
}
|
||||
},
|
||||
"search": "Katılımcıları ara"
|
||||
},
|
||||
"passwordDigitsOnly": "{{number}} rakama kadar",
|
||||
"passwordSetRemotely": "başka katılımcı tarafından ayarlandı",
|
||||
@@ -850,6 +856,7 @@
|
||||
"incomingMessage": "Gelen mesaj",
|
||||
"language": "Dil",
|
||||
"loggedIn": "{{name}} olarak giriş yapıldı",
|
||||
"maxStageParticipants": "Ana ekrana sabitlenecek maksimum katılımcı sayısı",
|
||||
"microphones": "Mikrofonlar",
|
||||
"moderator": "Yönetici",
|
||||
"more": "Daha fazla",
|
||||
@@ -1109,6 +1116,7 @@
|
||||
"lowDefinition": "Düşük çözünürlük",
|
||||
"onlyAudioAvailable": "Yalnızca ses kullanılabilir",
|
||||
"onlyAudioSupported": "Bu tarayıcıda yalnızca sesi destekliyoruz.",
|
||||
"performanceSettings": "Performans ayarları",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Standart çözünürlüklü video görüntüleme",
|
||||
"standardDefinition": "Standart çözünürlük"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "藍牙",
|
||||
"car": "汽車音響",
|
||||
"headphones": "耳機",
|
||||
"none": "沒有可用的音效裝置",
|
||||
"phone": "電話",
|
||||
@@ -39,9 +40,6 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "低頻寬"
|
||||
},
|
||||
"blankPage": {
|
||||
"meetingEnded": "會議已結束。"
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "新增討論室",
|
||||
@@ -83,6 +81,7 @@
|
||||
"enter": "加入聊天室",
|
||||
"error": "錯誤:您的訊息未被傳送。原因:{{error}}",
|
||||
"fieldPlaceHolder": "在此輸入您的訊息",
|
||||
"lobbyChatMessageTo": "Lobby chat message to {{recipient}}",
|
||||
"message": "訊息",
|
||||
"messageAccessibleTitle": "{{user}} 說:",
|
||||
"messageAccessibleTitleMe": "您說:",
|
||||
@@ -130,11 +129,11 @@
|
||||
},
|
||||
"connectionindicator": {
|
||||
"address": "位址:",
|
||||
"audio_ssrc": "Audio SSRC:",
|
||||
"audio_ssrc": "音訊 SSRC:",
|
||||
"bandwidth": "估計頻寬:",
|
||||
"bitrate": "位元率:",
|
||||
"bridgeCount": "伺服器數量:",
|
||||
"codecs": "Codecs (A/V):",
|
||||
"codecs": "編碼 (A/V):",
|
||||
"connectedTo": "已連接至:",
|
||||
"e2e_rtt": "E2E RTT:",
|
||||
"framerate": "影格率:",
|
||||
@@ -163,7 +162,7 @@
|
||||
"status": "連接:",
|
||||
"transport": "傳輸:",
|
||||
"transport_plural": "傳輸:",
|
||||
"video_ssrc": "Video SSRC:"
|
||||
"video_ssrc": "視訊 SSRC:"
|
||||
},
|
||||
"dateUtils": {
|
||||
"earlier": "稍早",
|
||||
@@ -180,7 +179,8 @@
|
||||
"joinInApp": "使用 App 加入會議",
|
||||
"launchWebButton": "在瀏覽器開啟",
|
||||
"title": "正在 {{app}} 發起您的會議...",
|
||||
"tryAgainButton": "在桌面上再試一次"
|
||||
"tryAgainButton": "在桌面上再試一次",
|
||||
"unsupportedBrowser": "您似乎正在使用我們不支援的瀏覽器。"
|
||||
},
|
||||
"defaultLink": "例如 {{url}}",
|
||||
"defaultNickname": "例如 春嬌 志明",
|
||||
@@ -207,15 +207,17 @@
|
||||
"Remove": "移除",
|
||||
"Share": "分享",
|
||||
"Submit": "提交",
|
||||
"WaitForHostMsg": "此會議 尚未啟動。如果您是會議主人,請進行認證;否則,請等待會議主人到達。",
|
||||
"WaitForHostMsg": "此會議尚未開始。如果您是主辦人,請進行認證;否則,請等待主辦人到達。",
|
||||
"WaitingForHost": "等侯主辦人...",
|
||||
"Yes": "是的",
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "直播串流"
|
||||
},
|
||||
"add": "新增",
|
||||
"addMeetingNote": "新增此會議的備註",
|
||||
"addOptionalNote": "新增備註 (選填):",
|
||||
"allow": "允許",
|
||||
"alreadySharedVideoMsg": "另一位參與者已經進行分享影像了。此會議同個時間只能允許一人分享影像畫面。",
|
||||
"alreadySharedVideoMsg": "另一位參與者已經正在分享影像了。此會議同時僅允許一人分享影像畫面。",
|
||||
"alreadySharedVideoTitle": "一次只允許一位影像分享",
|
||||
"applicationWindow": "應用程式視窗",
|
||||
"authenticationRequired": "需要驗證",
|
||||
@@ -265,11 +267,13 @@
|
||||
"kickParticipantDialog": "您確定要將這位參與者踢出會議嗎?",
|
||||
"kickParticipantTitle": "踢出這位參與者?",
|
||||
"kickTitle": "噢!{{participantDisplayName}} 已將您踢出會議",
|
||||
"linkMeeting": "連結會議",
|
||||
"linkMeetingTitle": "將會議連結至 Salesforce",
|
||||
"liveStreaming": "直播串流中",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "正在錄影,無法使用",
|
||||
"liveStreamingDisabledTooltip": "啟動直播串流已停用。",
|
||||
"localUserControls": "本機使用者控制",
|
||||
"lockMessage": "鎖定會議失敗。",
|
||||
"lockMessage": "無法鎖定會議。",
|
||||
"lockRoom": "增加會議 $t(lockRoomPasswordUppercase)",
|
||||
"lockTitle": "鎖定失敗",
|
||||
"login": "登入",
|
||||
@@ -319,6 +323,7 @@
|
||||
"popupError": "您的瀏覽器在此網站上阻擋彈出視窗。請在瀏覽器的安全設定中啟用並再試一次。",
|
||||
"popupErrorTitle": "彈出視窗遭到阻擋",
|
||||
"readMore": "更多",
|
||||
"recentlyUsedObjects": "您近期使用過的物件",
|
||||
"recording": "錄影中",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "正在直播時無法使用",
|
||||
"recordingDisabledTooltip": "啟動錄影已停用。",
|
||||
@@ -335,19 +340,25 @@
|
||||
"removeSharedVideoMsg": "您確定要移除自己分享的影像嗎?",
|
||||
"removeSharedVideoTitle": "移除分享的影像",
|
||||
"reservationError": "預約系統錯誤",
|
||||
"reservationErrorMsg": "錯誤碼: {{code}} , 訊息: {{msg}}",
|
||||
"reservationErrorMsg": "錯誤碼:{{code}}, 訊息:{{msg}}",
|
||||
"retry": "重試",
|
||||
"screenSharingAudio": "分享音訊",
|
||||
"screenSharingFailed": "噢喔!發生錯誤,我們無法啟動螢幕分享!",
|
||||
"screenSharingFailedTitle": "螢幕分享失敗!",
|
||||
"screenSharingPermissionDeniedError": "噢喔!您的影像分享權限發生問題。請重新載入,再試一次。",
|
||||
"sendPrivateMessage": "您最近有收到私人訊息。您要進行私人回覆,或是要將自己的訊息發佈至群組?",
|
||||
"searchInSalesforce": "在 Salesforce 中搜尋",
|
||||
"searchResults": "搜尋結果 ({{count}})",
|
||||
"searchResultsDetailsError": "取得擁有者資料時發生錯誤。",
|
||||
"searchResultsError": "取得資料時發生錯誤。",
|
||||
"searchResultsNotFound": "找不到任何結果。",
|
||||
"searchResultsTryAgain": "請嘗試使用其他關鍵字。",
|
||||
"sendPrivateMessage": "您最近有收到私人訊息。您要進行私人回覆,還是要將自己的訊息發佈至群組?",
|
||||
"sendPrivateMessageCancel": "發佈至群組",
|
||||
"sendPrivateMessageOk": "私人回覆",
|
||||
"sendPrivateMessageTitle": "私人傳訊?",
|
||||
"sendPrivateMessageTitle": "私人回覆?",
|
||||
"serviceUnavailable": "服務無法使用",
|
||||
"sessTerminated": "通話已經終止",
|
||||
"sessionRestarted": "通話被橋接器重新啟動",
|
||||
"sessionRestarted": "通話因連線問題重新啟動。",
|
||||
"shareAudio": "繼續",
|
||||
"shareAudioTitle": "如何分享音訊",
|
||||
"shareAudioWarningD1": "您必須先停止分享畫面才能分享音訊。",
|
||||
@@ -359,11 +370,13 @@
|
||||
"shareScreenWarningD2": "您必須先停止分享音訊,啟動畫面分享,然後勾選 \"分享音訊\" 選項。",
|
||||
"shareScreenWarningH1": "如果您只要分享畫面:",
|
||||
"shareScreenWarningTitle": "您必須先停止分享音訊才能分享畫面",
|
||||
"shareVideoLinkError": "請提供正確的 YouTube 連結。",
|
||||
"shareVideoLinkError": "請提供正確的影片網址。",
|
||||
"shareVideoTitle": "分享影像",
|
||||
"shareYourScreen": "分享自己的螢幕",
|
||||
"shareYourScreenDisabled": "螢幕分享已停用。",
|
||||
"sharedVideoLinkPlaceholder": "YouTube 或影片連結",
|
||||
"sharedVideoDialogError": "錯誤:網址無效",
|
||||
"sharedVideoLinkPlaceholder": "YouTube 或影片網址",
|
||||
"start": "開始 ",
|
||||
"startLiveStreaming": "啟動直播串流",
|
||||
"startRecording": "啟動錄影作業",
|
||||
"startRemoteControlErrorMessage": "嘗試啟動遠端控制階段時發生錯誤!",
|
||||
@@ -388,7 +401,7 @@
|
||||
"yourEntireScreen": "您的畫面"
|
||||
},
|
||||
"documentSharing": {
|
||||
"title": "分享的文件"
|
||||
"title": "分享的檔案"
|
||||
},
|
||||
"e2ee": {
|
||||
"labelToolTip": "此通話的音訊及視訊皆已使用端對端加密"
|
||||
@@ -406,6 +419,10 @@
|
||||
"veryBad": "極差",
|
||||
"veryGood": "極好"
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "找不到任何結果 :(",
|
||||
"search": "搜尋 GIPHY"
|
||||
},
|
||||
"helpView": {
|
||||
"header": "說明中心"
|
||||
},
|
||||
@@ -423,8 +440,8 @@
|
||||
"conferenceURL": "連結:",
|
||||
"copyNumber": "複製號碼",
|
||||
"country": "國家",
|
||||
"dialANumber": "要參加您的會議,撥打以下其中一支號碼,然後輸入 PIN 碼。",
|
||||
"dialInConferenceID": "PIN 號碼:",
|
||||
"dialANumber": "若要參加您的會議,請撥打以下其中一支號碼,然後輸入 PIN 碼。",
|
||||
"dialInConferenceID": "PIN 碼:",
|
||||
"dialInNotSupported": "抱歉,目前不支援電話撥入。",
|
||||
"dialInNumber": "撥入:",
|
||||
"dialInSummaryError": "目前解析撥入資訊錯誤。請稍後再試一次。",
|
||||
@@ -472,6 +489,7 @@
|
||||
"focusLocal": "聚焦於自己的影像",
|
||||
"focusRemote": "聚焦於另一人的影像",
|
||||
"fullScreen": "觀看或離開全螢幕",
|
||||
"giphyMenu": "切換 GIPHY 選單",
|
||||
"keyboardShortcuts": "快捷鍵",
|
||||
"localRecording": "顯示或隱藏本機端錄影操控",
|
||||
"mute": "靜音或解除靜音",
|
||||
@@ -525,7 +543,8 @@
|
||||
"admit": "准許",
|
||||
"admitAll": "准許所有人",
|
||||
"allow": "允許",
|
||||
"backToKnockModeButton": "沒有密碼,請要求加入",
|
||||
"backToKnockModeButton": "請求加入",
|
||||
"chat": "聊天",
|
||||
"dialogTitle": "大廳模式",
|
||||
"disableDialogContent": "已開啟大廳模式。此功能能夠確保閒雜人等無法加入您的會議。您確定要停用嗎?",
|
||||
"disableDialogSubmit": "停用",
|
||||
@@ -538,6 +557,7 @@
|
||||
"errorMissingPassword": "請輸入會議密碼",
|
||||
"invalidPassword": "密碼錯誤",
|
||||
"joinRejectedMessage": "您的加入請求遭到管理員拒絕。",
|
||||
"joinRejectedTitle": "加入請求遭拒。",
|
||||
"joinTitle": "加入會議",
|
||||
"joinWithPasswordMessage": "正在嘗試透過密碼加入,請稍候...",
|
||||
"joiningMessage": "一旦他人接受您的請求,即可加入會議",
|
||||
@@ -546,6 +566,8 @@
|
||||
"knockButton": "請求加入",
|
||||
"knockTitle": "有人想要加入會議",
|
||||
"knockingParticipantList": "要求加入的參與者名單",
|
||||
"lobbyChatStartedNotification": "{{moderator}} 與 {{attendee}} 開始了大廳聊天",
|
||||
"lobbyChatStartedTitle": "{{moderator}} 與您開始了大廳聊天。",
|
||||
"nameField": "輸入您的名字",
|
||||
"notificationLobbyAccessDenied": "{{originParticipantName}} 拒絕了 {{targetParticipantName}} 的加入請求",
|
||||
"notificationLobbyAccessGranted": "{{originParticipantName}} 同意了 {{targetParticipantName}} 的加入請求",
|
||||
@@ -600,13 +622,15 @@
|
||||
"allowedUnmute": "您可以將麥克風解除靜音、開啟視訊,或是分享您的畫面。",
|
||||
"audioUnmuteBlockedDescription": "麥克風解除靜音操作由於系統限制而被暫時封鎖。",
|
||||
"audioUnmuteBlockedTitle": "麥克風解除靜音遭封鎖!",
|
||||
"chatMessages": "聊天訊息",
|
||||
"connectedOneMember": "{{name}} 加入了會議",
|
||||
"connectedThreePlusMembers": "{{name}} 及 {{count}} 位人員加入了會議",
|
||||
"connectedTwoMembers": "{{first}} 及 {{second}} 加入了會議",
|
||||
"disconnected": "已經中斷連接",
|
||||
"displayNotifications": "顯示通知",
|
||||
"focus": "會議焦點",
|
||||
"focusFail": "{{component}} 無法使用 - 請在 {{ms}} 秒後重試",
|
||||
"grantedTo": "主持人權限已授予 {{to}}!",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "通知",
|
||||
"hostAskedUnmute": "主持人希望您能解除靜音",
|
||||
"invitedOneMember": "{{name}} 已受邀請",
|
||||
@@ -616,6 +640,12 @@
|
||||
"leftOneMember": "{{name}} 已離開會議",
|
||||
"leftThreePlusMembers": "{{name}} 和其他人已離開會議",
|
||||
"leftTwoMembers": "{{first}} 和 {{second}} 已離開會議",
|
||||
"linkToSalesforce": "連結至 Salesforce",
|
||||
"linkToSalesforceDescription": "您可以將會議摘要連結至 Salesforce 物件。",
|
||||
"linkToSalesforceError": "無法將會議連結至 Salesforce",
|
||||
"linkToSalesforceKey": "連結此會議",
|
||||
"linkToSalesforceProgress": "正在將會議連結至 Salesforce...",
|
||||
"linkToSalesforceSuccess": "會議已連結至 Salesforce",
|
||||
"me": "自己",
|
||||
"moderationInEffectCSDescription": "若要分享視訊,請舉手",
|
||||
"moderationInEffectCSTitle": "內容分享已被管理員停用",
|
||||
@@ -639,14 +669,18 @@
|
||||
"oldElectronClientDescription1": "您似乎正在使用 Jitsi Meet 客戶端的舊版本,其有已知的安全漏洞。請更新到",
|
||||
"oldElectronClientDescription2": "最新版本",
|
||||
"oldElectronClientDescription3": "!",
|
||||
"participantWantsToJoin": "想要加入會議",
|
||||
"participantsWantToJoin": "想要加入會議",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) 已被其他參與者移除",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) 已被其他參與者設定",
|
||||
"raiseHandAction": "舉手",
|
||||
"raisedHand": "{{name}} 想要發言。",
|
||||
"raisedHands": "{{participantName}} 和其他 {{raisedHands}} 人",
|
||||
"reactionSounds": "停用音效",
|
||||
"reactionSoundsForAll": "為所有人停用音效",
|
||||
"screenShareNoAudio": "您未在選擇視窗時勾選分享音訊",
|
||||
"screenShareNoAudioTitle": "未勾選分享音訊",
|
||||
"selfViewTitle": "您隨時可以在設定中取消隱藏自己的畫面",
|
||||
"somebody": "某人",
|
||||
"startSilentDescription": "重新加入會議以啟用語音",
|
||||
"startSilentTitle": "您加入了會議而無聲音輸出!",
|
||||
@@ -656,7 +690,9 @@
|
||||
"videoMutedRemotelyDescription": "您隨時可以再次啟用。",
|
||||
"videoMutedRemotelyTitle": "您的攝影機已被 {{participantDisplayName}} 停用!",
|
||||
"videoUnmuteBlockedDescription": "視訊鏡頭解除靜音操作由於系統限制而被暫時封鎖。",
|
||||
"videoUnmuteBlockedTitle": "視訊鏡頭解除靜音遭封鎖!"
|
||||
"videoUnmuteBlockedTitle": "視訊鏡頭解除靜音遭封鎖!",
|
||||
"viewLobby": "檢視大廳",
|
||||
"waitingParticipants": "{{waitingParticipants}} 人"
|
||||
},
|
||||
"participantsPane": {
|
||||
"actions": {
|
||||
@@ -688,6 +724,7 @@
|
||||
},
|
||||
"passwordDigitsOnly": "上限為 {{number}} 位數",
|
||||
"passwordSetRemotely": "由其他參與者設定",
|
||||
"pinnedParticipant": "參與者被釘選",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"skip": "跳過",
|
||||
@@ -801,7 +838,20 @@
|
||||
"setEmailLabel": "設定您的 Gravatar 電子信箱",
|
||||
"title": "簡介"
|
||||
},
|
||||
"raisedHand": "請求發言",
|
||||
"raisedHand": "想要發言",
|
||||
"raisedHandsLabel": "舉手人數",
|
||||
"record": {
|
||||
"already": {
|
||||
"linked": "會議已連結至此 Salesforce 物件。"
|
||||
},
|
||||
"type": {
|
||||
"account": "帳號",
|
||||
"contact": "聯絡",
|
||||
"lead": "淺在客戶",
|
||||
"opportunity": "機會",
|
||||
"owner": "擁有者"
|
||||
}
|
||||
},
|
||||
"recording": {
|
||||
"authDropboxText": "上傳至 Dropbox",
|
||||
"availableSpace": "可用空間:{{spaceLeft}} MB (錄影時間大約 {{duration}} 分鐘)",
|
||||
@@ -816,6 +866,11 @@
|
||||
"expandedPending": "錄影正在啟動...",
|
||||
"failedToStart": "錄影啟動失敗",
|
||||
"fileSharingdescription": "分享錄影給會議參與者",
|
||||
"highlight": "精選",
|
||||
"highlightMoment": "精選時刻",
|
||||
"highlightMomentDisabled": "您可以在錄製開始後精選時刻",
|
||||
"highlightMomentSuccess": "已精選的時刻",
|
||||
"highlightMomentSucessDescription": "您的精選時刻將新增至會議摘要。",
|
||||
"inProgress": "正在錄製或直播",
|
||||
"limitNotificationDescriptionNative": "由於目前流量過大,您的錄影時間被限制在 {{limit}} 分鐘。若要無限制的錄影,請試試 <3>{{app}}</3>。",
|
||||
"limitNotificationDescriptionWeb": "由於目前流量過大,您的錄影時間被限制在 {{limit}} 分鐘。若要無限制的錄影,請試試 <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>。",
|
||||
@@ -830,6 +885,7 @@
|
||||
"rec": "錄影",
|
||||
"serviceDescription": "您的錄影會由錄影服務儲存",
|
||||
"serviceDescriptionCloud": "雲端錄製",
|
||||
"serviceDescriptionCloudInfo": "已錄製的會議將在 24 小時後自動清除。",
|
||||
"serviceName": "錄影服務",
|
||||
"sessionAlreadyActive": "已在錄製或直播此工作階段。",
|
||||
"signIn": "登入",
|
||||
@@ -838,8 +894,9 @@
|
||||
"unavailableTitle": "錄影無法使用",
|
||||
"uploadToCloud": "上傳至雲端"
|
||||
},
|
||||
"screenshareDisplayName": "{{name}} 的畫面",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "拉下以重新整理"
|
||||
"pullToRefresh": "下拉以重新整理"
|
||||
},
|
||||
"security": {
|
||||
"about": "您可以新增 $t(lockRoomPassword) 至您的會議。參與者在加入會議前必須先輸入 $t(lockRoomPassword)。",
|
||||
@@ -864,6 +921,7 @@
|
||||
"incomingMessage": "新訊息",
|
||||
"language": "語言",
|
||||
"loggedIn": "以 {{name}} 登入",
|
||||
"maxStageParticipants": "能夠被釘選至主舞台的參與者最大人數",
|
||||
"microphones": "麥克風",
|
||||
"moderator": "主持人",
|
||||
"more": "更多",
|
||||
@@ -877,6 +935,7 @@
|
||||
"selectAudioOutput": "音訊輸出",
|
||||
"selectCamera": "攝影裝置",
|
||||
"selectMic": "麥克風",
|
||||
"selfView": "自我檢視",
|
||||
"sounds": "音效",
|
||||
"speakers": "喇叭",
|
||||
"startAudioMuted": "全部人啟動時處於靜音",
|
||||
@@ -915,6 +974,7 @@
|
||||
"speakerStats": {
|
||||
"angry": "憤怒",
|
||||
"disgusted": "作嘔",
|
||||
"displayEmotions": "顯示表情",
|
||||
"fearful": "害怕",
|
||||
"happy": "開心",
|
||||
"hours": "{{count}}時",
|
||||
@@ -948,6 +1008,7 @@
|
||||
"audioOnly": "切換僅聲音",
|
||||
"audioRoute": "選擇音訊裝置",
|
||||
"boo": "喝倒彩",
|
||||
"breakoutRoom": "加入/離開分組討論室",
|
||||
"callQuality": "管理影像品質",
|
||||
"cc": "切換字幕",
|
||||
"chat": "切換聊天視窗",
|
||||
@@ -965,7 +1026,9 @@
|
||||
"invite": "邀請人員",
|
||||
"joy": "笑到流淚",
|
||||
"kick": "踢出參與者",
|
||||
"laugh": "大笑",
|
||||
"like": "比讚",
|
||||
"linkToSalesforce": "連結至 Salesforce",
|
||||
"lobbyButton": "啟用/停用大廳模式",
|
||||
"localRecording": "切換本地端錄影控制",
|
||||
"lockRoom": "切換會議密碼",
|
||||
@@ -1027,6 +1090,7 @@
|
||||
"exitFullScreen": "離開全螢幕",
|
||||
"exitTileView": "跳出格狀檢視",
|
||||
"feedback": "回饋",
|
||||
"giphy": "切換 GIPHY 選單",
|
||||
"hangup": "離開",
|
||||
"help": "說明",
|
||||
"invite": "邀請人員",
|
||||
@@ -1034,6 +1098,7 @@
|
||||
"laugh": "大笑",
|
||||
"leaveBreakoutRoom": "離開分組討論室",
|
||||
"like": "比讚",
|
||||
"linkToSalesforce": "連結至 Salesforce",
|
||||
"lobbyButtonDisable": "停用大廳模式",
|
||||
"lobbyButtonEnable": "啟用大廳模式",
|
||||
"login": "登入",
|
||||
@@ -1148,13 +1213,18 @@
|
||||
"domuteVideoOfOthers": "停用其他人的攝影機",
|
||||
"flip": "翻轉",
|
||||
"grantModerator": "授予管理員",
|
||||
"hideSelfView": "隱藏自我檢視",
|
||||
"kick": "踢出",
|
||||
"moderator": "主持人",
|
||||
"mute": "參與者處於靜音",
|
||||
"muted": "處於靜音",
|
||||
"pinToStage": "釘選至舞台",
|
||||
"remoteControl": "開始/停止遠端控制",
|
||||
"screenSharing": "參與者正在分享他們的畫面",
|
||||
"show": "顯示在台上",
|
||||
"videoMuted": "已停用攝影機",
|
||||
"showSelfView": "顯示自我檢視",
|
||||
"unpinFromStage": "取消釘選",
|
||||
"videoMuted": "已停用攝影裝置",
|
||||
"videomute": "參與者已經停止攝影裝置"
|
||||
},
|
||||
"virtualBackground": {
|
||||
@@ -1178,7 +1248,8 @@
|
||||
"slightBlur": "稍微模糊",
|
||||
"title": "虛擬背景",
|
||||
"uploadedImage": "上傳圖片 {{index}}",
|
||||
"webAssemblyWarning": "不支援 WebAssembly"
|
||||
"webAssemblyWarning": "不支援 WebAssembly",
|
||||
"webAssemblyWarningDescription": "WebAssembly 遭停用或不被此連覽器支援"
|
||||
},
|
||||
"volumeSlider": "音量滑條",
|
||||
"welcomepage": {
|
||||
|
||||
@@ -77,6 +77,17 @@
|
||||
"refresh": "Refresh calendar",
|
||||
"today": "Today"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"leaveMeeting": " Leave meeting",
|
||||
"selectSoundDevice": "Select sound device"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "Car mode",
|
||||
"title": "Safe driving mode",
|
||||
"videoStopped": "Your video is stopped"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "Enter room",
|
||||
"error": "Error: your message was not sent. Reason: {{error}}",
|
||||
@@ -105,6 +116,7 @@
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "Install Chrome Extension",
|
||||
"buttonTextEdge": "Install Edge Extension",
|
||||
"close": "Close",
|
||||
"dontShowAgain": "Don’t show me this again",
|
||||
"installExtensionText": "Install the extension for Google Calendar and Office 365 integration"
|
||||
@@ -196,6 +208,9 @@
|
||||
"selectADevice": "Select a device",
|
||||
"testAudio": "Play a test sound"
|
||||
},
|
||||
"dialIn": {
|
||||
"screenTitle": "Dial-in summary"
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "is now {{status}}"
|
||||
},
|
||||
@@ -277,7 +292,7 @@
|
||||
"lockRoom": "Add meeting $t(lockRoomPassword)",
|
||||
"lockTitle": "Lock failed",
|
||||
"login": "Login",
|
||||
"logoutQuestion": "Are you sure you want to logout and stop the conference?",
|
||||
"logoutQuestion": "Are you sure you want to logout and leave the conference?",
|
||||
"logoutTitle": "Logout",
|
||||
"maxUsersLimitReached": "The limit for maximum number of participants has been reached. The conference is full. Please contact the meeting owner or try again later!",
|
||||
"maxUsersLimitReachedTitle": "Maximum participants limit reached",
|
||||
@@ -646,6 +661,8 @@
|
||||
"linkToSalesforceKey": "Link this meeting",
|
||||
"linkToSalesforceProgress": "Linking meeting to Salesforce...",
|
||||
"linkToSalesforceSuccess": "The meeting was linked to Salesforce",
|
||||
"localRecordingStarted": "{{name}} has started a local recording.",
|
||||
"localRecordingStopped": "{{name}} has stopped a local recording.",
|
||||
"me": "Me",
|
||||
"moderationInEffectCSDescription": "Please raise hand if you want to share your screen.",
|
||||
"moderationInEffectCSTitle": "Screen sharing is blocked by the moderator",
|
||||
@@ -801,6 +818,7 @@
|
||||
"initiated": "Call initiated",
|
||||
"joinAudioByPhone": "Join with phone audio",
|
||||
"joinMeeting": "Join meeting",
|
||||
"joinMeetingInLowBandwidthMode": "Join in low bandwidth mode",
|
||||
"joinWithoutAudio": "Join without audio",
|
||||
"keyboardShortcuts": "Enable Keyboard shortcuts",
|
||||
"linkCopied": "Link copied to clipboard",
|
||||
@@ -876,6 +894,8 @@
|
||||
"limitNotificationDescriptionWeb": "Due to high demand your recording will be limited to {{limit}} min. For unlimited recordings try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "We have generated a link to your recording.",
|
||||
"live": "LIVE",
|
||||
"localRecordingNoNotificationWarning": "The recording will not be announced to other participants. You will need to let them know that the meeting is recorded.",
|
||||
"localRecordingWarning": "Make sure you select the current tab in order to use the right video and audio. The recording is currently limited to 1GB, which is around 100 minutes.",
|
||||
"loggedIn": "Logged in as {{userName}}",
|
||||
"off": "Recording stopped",
|
||||
"offBy": "{{name}} stopped the recording",
|
||||
@@ -883,6 +903,7 @@
|
||||
"onBy": "{{name}} started the recording",
|
||||
"pending": "Preparing to record the meeting...",
|
||||
"rec": "REC",
|
||||
"saveLocalRecording": "Save recording file locally",
|
||||
"serviceDescription": "Your recording will be saved by the recording service",
|
||||
"serviceDescriptionCloud": "Cloud recording",
|
||||
"serviceDescriptionCloudInfo": "Recorded meetings are automatically cleared 24h after their recording time.",
|
||||
@@ -890,6 +911,7 @@
|
||||
"sessionAlreadyActive": "This session is already being recorded or live streamed.",
|
||||
"signIn": "Sign in",
|
||||
"signOut": "Sign out",
|
||||
"surfaceError": "Please select the current tab.",
|
||||
"unavailable": "Oops! The {{serviceName}} is currently unavailable. We're working on resolving the issue. Please try again later.",
|
||||
"unavailableTitle": "Recording unavailable",
|
||||
"uploadToCloud": "Upload to the cloud"
|
||||
@@ -932,6 +954,7 @@
|
||||
"playSounds": "Play sound on",
|
||||
"reactions": "Meeting reactions",
|
||||
"sameAsSystem": "Same as system ({{label}})",
|
||||
"screenTitle": "Settings",
|
||||
"selectAudioOutput": "Audio output",
|
||||
"selectCamera": "Camera",
|
||||
"selectMic": "Microphone",
|
||||
@@ -957,6 +980,7 @@
|
||||
"disableCrashReportingWarning": "Are you sure you want to disable crash reporting? The setting will be applied after you restart the app.",
|
||||
"disableP2P": "Disable Peer-To-Peer mode",
|
||||
"displayName": "Display name",
|
||||
"displayNamePlaceholderText": "Eg: John Doe",
|
||||
"email": "Email",
|
||||
"header": "Settings",
|
||||
"profileSection": "Profile",
|
||||
@@ -1010,10 +1034,12 @@
|
||||
"boo": "Boo",
|
||||
"breakoutRoom": "Join/leave breakout room",
|
||||
"callQuality": "Manage video quality",
|
||||
"carmode": "Car Mode",
|
||||
"cc": "Toggle subtitles",
|
||||
"chat": "Open / Close chat",
|
||||
"clap": "Clap",
|
||||
"collapse": "Collapse",
|
||||
"dock": "Dock in main window",
|
||||
"document": "Toggle shared document",
|
||||
"download": "Download our apps",
|
||||
"embedMeeting": "Embed meeting",
|
||||
@@ -1064,6 +1090,7 @@
|
||||
"tileView": "Toggle tile view",
|
||||
"toggleCamera": "Toggle camera",
|
||||
"toggleFilmstrip": "Toggle filmstrip",
|
||||
"undock": "Undock into separate window",
|
||||
"videoblur": "Toggle video blur",
|
||||
"videomute": "Start / Stop camera"
|
||||
},
|
||||
@@ -1080,6 +1107,7 @@
|
||||
"closeChat": "Close chat",
|
||||
"closeReactionsMenu": "Close reactions menu",
|
||||
"disableReactionSounds": "You can disable reaction sounds for this meeting",
|
||||
"dock": "Dock in main window",
|
||||
"documentClose": "Close shared document",
|
||||
"documentOpen": "Open shared document",
|
||||
"download": "Download our apps",
|
||||
@@ -1148,6 +1176,7 @@
|
||||
"talkWhileMutedPopup": "Trying to speak? You are muted.",
|
||||
"tileViewToggle": "Toggle tile view",
|
||||
"toggleCamera": "Toggle camera",
|
||||
"undock": "Undock into separate window",
|
||||
"videoSettings": "Video settings",
|
||||
"videomute": "Start / Stop camera"
|
||||
},
|
||||
|
||||
@@ -40,7 +40,8 @@ import {
|
||||
isParticipantModerator,
|
||||
isLocalParticipantModerator,
|
||||
hasRaisedHand,
|
||||
grantModerator
|
||||
grantModerator,
|
||||
overwriteParticipantsNames
|
||||
} from '../../react/features/base/participants';
|
||||
import { updateSettings } from '../../react/features/base/settings';
|
||||
import { isToggleCameraEnabled, toggleCamera } from '../../react/features/base/tracks';
|
||||
@@ -87,6 +88,8 @@ import { toggleScreenshotCaptureSummary } from '../../react/features/screenshot-
|
||||
import { isScreenshotCaptureEnabled } from '../../react/features/screenshot-capture/functions';
|
||||
import { playSharedVideo, stopSharedVideo } from '../../react/features/shared-video/actions.any';
|
||||
import { extractYoutubeIdOrURL } from '../../react/features/shared-video/functions';
|
||||
import { toggleRequestingSubtitles, setRequestingSubtitles } from '../../react/features/subtitles/actions';
|
||||
import { isAudioMuteButtonDisabled } from '../../react/features/toolbox/functions';
|
||||
import { toggleTileView, setTileView } from '../../react/features/video-layout';
|
||||
import { muteAllParticipants } from '../../react/features/video-menu/actions';
|
||||
import { setVideoQuality } from '../../react/features/video-quality';
|
||||
@@ -371,6 +374,12 @@ function initCommands() {
|
||||
sendAnalytics(createApiEvent('screen.sharing.toggled'));
|
||||
toggleScreenSharing(options.enable);
|
||||
},
|
||||
'toggle-subtitles': () => {
|
||||
APP.store.dispatch(toggleRequestingSubtitles());
|
||||
},
|
||||
'set-subtitles': enabled => {
|
||||
APP.store.dispatch(setRequestingSubtitles(enabled));
|
||||
},
|
||||
'toggle-tile-view': () => {
|
||||
sendAnalytics(createApiEvent('tile-view.toggled'));
|
||||
|
||||
@@ -420,6 +429,11 @@ function initCommands() {
|
||||
logger.error('Failed sending endpoint text message', err);
|
||||
}
|
||||
},
|
||||
'overwrite-names': participantList => {
|
||||
logger.debug('Overwrite names command received');
|
||||
|
||||
APP.store.dispatch(overwriteParticipantsNames(participantList));
|
||||
},
|
||||
'toggle-e2ee': enabled => {
|
||||
logger.debug('Toggle E2EE key command received');
|
||||
APP.store.dispatch(toggleE2EE(enabled));
|
||||
@@ -693,6 +707,9 @@ function initCommands() {
|
||||
case 'is-audio-muted':
|
||||
callback(APP.conference.isLocalAudioMuted());
|
||||
break;
|
||||
case 'is-audio-disabled':
|
||||
callback(isAudioMuteButtonDisabled(APP.store.getState()));
|
||||
break;
|
||||
case 'is-moderation-on': {
|
||||
const { mediaType } = request;
|
||||
const type = mediaType || MEDIA_TYPE.AUDIO;
|
||||
@@ -1444,6 +1461,22 @@ class API {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application (if API is enabled) that the iframe
|
||||
* docked state has been changed. The responsibility for implementing
|
||||
* the dock / undock functionality lies with the external application.
|
||||
*
|
||||
* @param {boolean} docked - Whether or not the iframe has been set to
|
||||
* be docked or undocked.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyIframeDockStateChanged(docked: boolean) {
|
||||
this._sendEvent({
|
||||
name: 'iframe-dock-state-changed',
|
||||
docked
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application of a participant, remote or local, being
|
||||
* removed from the conference by another participant.
|
||||
@@ -1649,6 +1682,32 @@ class API {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify external application that the breakout rooms changed.
|
||||
*
|
||||
* @param {Array} rooms - Array of breakout rooms.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyBreakoutRoomsUpdated(rooms) {
|
||||
this._sendEvent({
|
||||
name: 'breakout-rooms-updated',
|
||||
rooms
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the external application that the state of the participants pane changed.
|
||||
*
|
||||
* @param {boolean} open - Wether the panel is open or not.
|
||||
* @returns {void}
|
||||
*/
|
||||
notifyParticipantsPaneToggled(open) {
|
||||
this._sendEvent({
|
||||
name: 'participants-pane-toggled',
|
||||
open
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the allocated resources.
|
||||
*
|
||||
|
||||
25
modules/API/external/external_api.js
vendored
25
modules/API/external/external_api.js
vendored
@@ -46,6 +46,7 @@ const commands = {
|
||||
kickParticipant: 'kick-participant',
|
||||
muteEveryone: 'mute-everyone',
|
||||
overwriteConfig: 'overwrite-config',
|
||||
overwriteNames: 'overwrite-names',
|
||||
password: 'password',
|
||||
pinParticipant: 'pin-participant',
|
||||
rejectParticipant: 'reject-participant',
|
||||
@@ -59,6 +60,7 @@ const commands = {
|
||||
setLargeVideoParticipant: 'set-large-video-participant',
|
||||
setMediaEncryptionKey: 'set-media-encryption-key',
|
||||
setParticipantVolume: 'set-participant-volume',
|
||||
setSubtitles: 'set-subtitles',
|
||||
setTileView: 'set-tile-view',
|
||||
setVideoQuality: 'set-video-quality',
|
||||
startRecording: 'start-recording',
|
||||
@@ -79,6 +81,7 @@ const commands = {
|
||||
toggleRaiseHand: 'toggle-raise-hand',
|
||||
toggleShareAudio: 'toggle-share-audio',
|
||||
toggleShareScreen: 'toggle-share-screen',
|
||||
toggleSubtitles: 'toggle-subtitles',
|
||||
toggleTileView: 'toggle-tile-view',
|
||||
toggleVirtualBackgroundDialog: 'toggle-virtual-background',
|
||||
toggleVideo: 'toggle-video'
|
||||
@@ -92,6 +95,7 @@ const events = {
|
||||
'avatar-changed': 'avatarChanged',
|
||||
'audio-availability-changed': 'audioAvailabilityChanged',
|
||||
'audio-mute-status-changed': 'audioMuteStatusChanged',
|
||||
'breakout-rooms-updated': 'breakoutRoomsUpdated',
|
||||
'browser-support': 'browserSupport',
|
||||
'camera-error': 'cameraError',
|
||||
'chat-updated': 'chatUpdated',
|
||||
@@ -106,6 +110,7 @@ const events = {
|
||||
'feedback-submitted': 'feedbackSubmitted',
|
||||
'feedback-prompt-displayed': 'feedbackPromptDisplayed',
|
||||
'filmstrip-display-changed': 'filmstripDisplayChanged',
|
||||
'iframe-dock-state-changed': 'iframeDockStateChanged',
|
||||
'incoming-message': 'incomingMessage',
|
||||
'knocking-participant': 'knockingParticipant',
|
||||
'log': 'log',
|
||||
@@ -121,6 +126,7 @@ const events = {
|
||||
'participant-kicked-out': 'participantKickedOut',
|
||||
'participant-left': 'participantLeft',
|
||||
'participant-role-changed': 'participantRoleChanged',
|
||||
'participants-pane-toggled': 'participantsPaneToggled',
|
||||
'password-required': 'passwordRequired',
|
||||
'proxy-connection-event': 'proxyConnectionEvent',
|
||||
'raise-hand-updated': 'raiseHandUpdated',
|
||||
@@ -296,6 +302,7 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
* the participant opening the meeting.
|
||||
* @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.
|
||||
*/
|
||||
constructor(domain, ...args) {
|
||||
super();
|
||||
@@ -312,7 +319,8 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
invitees,
|
||||
devices,
|
||||
userInfo,
|
||||
e2eeKey
|
||||
e2eeKey,
|
||||
release
|
||||
} = parseArguments(args);
|
||||
const localStorageContent = jitsiLocalStorage.getItem('jitsiLocalStorage');
|
||||
|
||||
@@ -327,7 +335,8 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
userInfo,
|
||||
appData: {
|
||||
localStorageContent
|
||||
}
|
||||
},
|
||||
release
|
||||
});
|
||||
this._createIFrame(height, width, onload);
|
||||
this._transport = new Transport({
|
||||
@@ -925,6 +934,18 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the audio disabled status.
|
||||
*
|
||||
* @returns {Promise} - Resolves with the audio disabled status and rejects on
|
||||
* failure.
|
||||
*/
|
||||
isAudioDisabled() {
|
||||
return this._transport.sendRequest({
|
||||
name: 'is-audio-disabled'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the moderation on status on the given mediaType.
|
||||
*
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
import { getReplaceParticipant } from '../../../react/features/base/config/functions';
|
||||
import { isDialogOpen } from '../../../react/features/base/dialog';
|
||||
import { setJWT } from '../../../react/features/base/jwt';
|
||||
import { setPrejoinPageVisibility } from '../../../react/features/prejoin';
|
||||
import UIUtil from '../util/UIUtil';
|
||||
|
||||
import ExternalLoginDialog from './LoginDialog';
|
||||
@@ -180,6 +181,7 @@ function authenticate(room: Object, lockPassword: string) {
|
||||
if (isTokenAuthEnabled(config) || room.isExternalAuthEnabled()) {
|
||||
doExternalAuth(room, lockPassword);
|
||||
} else {
|
||||
APP.store.dispatch(setPrejoinPageVisibility(false));
|
||||
APP.store.dispatch(openLoginDialog());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,15 +9,20 @@ import { Provider } from 'react-redux';
|
||||
import { createScreenSharingIssueEvent, sendAnalytics } from '../../../react/features/analytics';
|
||||
import { Avatar } from '../../../react/features/base/avatar';
|
||||
import theme from '../../../react/features/base/components/themes/participantsPaneTheme.json';
|
||||
import { getSourceNameSignalingFeatureFlag } from '../../../react/features/base/config';
|
||||
import {
|
||||
getMultipleVideoSupportFeatureFlag,
|
||||
getSourceNameSignalingFeatureFlag
|
||||
} from '../../../react/features/base/config';
|
||||
import { i18next } from '../../../react/features/base/i18n';
|
||||
import { JitsiTrackEvents } from '../../../react/features/base/lib-jitsi-meet';
|
||||
import { VIDEO_TYPE } from '../../../react/features/base/media';
|
||||
import {
|
||||
getParticipantById,
|
||||
getParticipantDisplayName
|
||||
} from '../../../react/features/base/participants';
|
||||
import {
|
||||
getVideoTrackByParticipant
|
||||
getVideoTrackByParticipant,
|
||||
trackStreamingStatusChanged
|
||||
} from '../../../react/features/base/tracks';
|
||||
import { CHAT_SIZE } from '../../../react/features/chat';
|
||||
import {
|
||||
@@ -116,6 +121,14 @@ export default class LargeVideoManager {
|
||||
*/
|
||||
this._videoAspectRatio = 0;
|
||||
|
||||
/**
|
||||
* The video track in effect.
|
||||
* This is used to add and remove listeners on track streaming status change.
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
this.videoTrack = undefined;
|
||||
|
||||
this.$container = $('#largeVideoContainer');
|
||||
|
||||
this.$container.css({
|
||||
@@ -147,6 +160,18 @@ export default class LargeVideoManager {
|
||||
this.videoContainer.removeResizeListener(
|
||||
this._onVideoResolutionUpdate);
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(APP.store.getState())) {
|
||||
// Remove track streaming status listener.
|
||||
// TODO: when this class is converted to a function react component,
|
||||
// use a custom hook to update a local track streaming status.
|
||||
if (this.videoTrack && !this.videoTrack.local) {
|
||||
this.videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
|
||||
this.handleTrackStreamingStatusChanged);
|
||||
APP.store.dispatch(trackStreamingStatusChanged(this.videoTrack.jitsiTrack,
|
||||
this.videoTrack.jitsiTrack.getTrackStreamingStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
this.removePresenceLabel();
|
||||
|
||||
ReactDOM.unmountComponentAtNode(this._dominantSpeakerAvatarContainer);
|
||||
@@ -242,6 +267,28 @@ export default class LargeVideoManager {
|
||||
const tracks = state['features/base/tracks'];
|
||||
const videoTrack = getVideoTrackByParticipant(tracks, participant);
|
||||
|
||||
// Remove track streaming status listener from the old track and add it to the new track,
|
||||
// in order to stop updating track streaming status for the old track and start it for the new track.
|
||||
// TODO: when this class is converted to a function react component,
|
||||
// use a custom hook to update a local track streaming status.
|
||||
if (this.videoTrack?.jitsiTrack?.getSourceName() !== videoTrack?.jitsiTrack?.getSourceName()) {
|
||||
if (this.videoTrack && !this.videoTrack.local) {
|
||||
this.videoTrack.jitsiTrack.off(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
|
||||
this.handleTrackStreamingStatusChanged);
|
||||
APP.store.dispatch(trackStreamingStatusChanged(this.videoTrack.jitsiTrack,
|
||||
this.videoTrack.jitsiTrack.getTrackStreamingStatus()));
|
||||
}
|
||||
|
||||
this.videoTrack = videoTrack;
|
||||
|
||||
if (this.videoTrack && !this.videoTrack.local) {
|
||||
this.videoTrack.jitsiTrack.on(JitsiTrackEvents.TRACK_STREAMING_STATUS_CHANGED,
|
||||
this.handleTrackStreamingStatusChanged);
|
||||
APP.store.dispatch(trackStreamingStatusChanged(this.videoTrack.jitsiTrack,
|
||||
this.videoTrack.jitsiTrack.getTrackStreamingStatus()));
|
||||
}
|
||||
}
|
||||
|
||||
isVideoRenderable = !isVideoMuted && (
|
||||
APP.conference.isLocalId(id)
|
||||
|| participant?.isLocalScreenShare
|
||||
@@ -253,9 +300,18 @@ export default class LargeVideoManager {
|
||||
}
|
||||
|
||||
const isAudioOnly = APP.conference.isAudioOnly();
|
||||
|
||||
// Multi-stream is not supported on plan-b endpoints even if its is enabled via config.js. A virtual
|
||||
// screenshare tile is still created when a remote endpoint starts screenshare to keep the behavior
|
||||
// consistent and an avatar is displayed on the original participant thumbnail as long as screenshare is in
|
||||
// progress.
|
||||
const legacyScreenshare = getMultipleVideoSupportFeatureFlag(state)
|
||||
&& videoType === VIDEO_TYPE.DESKTOP
|
||||
&& !participant.isVirtualScreenshareParticipant;
|
||||
|
||||
const showAvatar
|
||||
= isVideoContainer
|
||||
&& ((isAudioOnly && videoType !== VIDEO_TYPE.DESKTOP) || !isVideoRenderable);
|
||||
&& ((isAudioOnly && videoType !== VIDEO_TYPE.DESKTOP) || !isVideoRenderable || legacyScreenshare);
|
||||
|
||||
let promise;
|
||||
|
||||
@@ -340,6 +396,19 @@ export default class LargeVideoManager {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle track streaming status change event by
|
||||
* by dispatching an action to update track streaming status for the given track in app state.
|
||||
*
|
||||
* @param {JitsiTrack} jitsiTrack the track with streaming status updated
|
||||
* @param {JitsiTrackStreamingStatus} streamingStatus the updated track streaming status
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
handleTrackStreamingStatusChanged(jitsiTrack, streamingStatus) {
|
||||
APP.store.dispatch(trackStreamingStatusChanged(jitsiTrack, streamingStatus));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows/hides notification about participant's connectivity issues to be
|
||||
* shown on the large video area.
|
||||
|
||||
@@ -6,7 +6,7 @@ import ReactDOM from 'react-dom';
|
||||
|
||||
import { browser } from '../../../react/features/base/lib-jitsi-meet';
|
||||
import { isTestModeEnabled } from '../../../react/features/base/testing';
|
||||
import { FILMSTRIP_BREAKPOINT, shouldDisplayStageFilmstrip } from '../../../react/features/filmstrip';
|
||||
import { FILMSTRIP_BREAKPOINT } from '../../../react/features/filmstrip';
|
||||
import { ORIENTATION, LargeVideoBackground, updateLastLargeVideoMediaEvent } from '../../../react/features/large-video';
|
||||
import { LAYOUTS, getCurrentLayout } from '../../../react/features/video-layout';
|
||||
/* eslint-enable no-unused-vars */
|
||||
@@ -414,7 +414,7 @@ export class VideoContainer extends LargeContainer {
|
||||
|
||||
const verticalFilmstripWidth = state['features/filmstrip'].width?.current;
|
||||
|
||||
if (currentLayout === LAYOUTS.TILE_VIEW || shouldDisplayStageFilmstrip(state)) {
|
||||
if (currentLayout === LAYOUTS.TILE_VIEW || currentLayout === LAYOUTS.STAGE_FILMSTRIP_VIEW) {
|
||||
// We don't need to resize the large video since it won't be displayed and we'll resize when returning back
|
||||
// to stage view.
|
||||
return;
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
} from '../../../react/features/base/participants';
|
||||
import {
|
||||
getTrackByMediaTypeAndParticipant,
|
||||
getFakeScreenshareParticipantTrack
|
||||
getVirtualScreenshareParticipantTrack
|
||||
} from '../../../react/features/base/tracks';
|
||||
|
||||
import LargeVideoManager from './LargeVideoManager';
|
||||
@@ -95,7 +95,7 @@ const VideoLayout = {
|
||||
return VIDEO_TYPE.CAMERA;
|
||||
}
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(state) && participant?.isFakeScreenShareParticipant) {
|
||||
if (getSourceNameSignalingFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
|
||||
return VIDEO_TYPE.DESKTOP;
|
||||
}
|
||||
|
||||
@@ -190,8 +190,8 @@ const VideoLayout = {
|
||||
|
||||
let videoTrack;
|
||||
|
||||
if (getSourceNameSignalingFeatureFlag(state) && participant?.isFakeScreenShareParticipant) {
|
||||
videoTrack = getFakeScreenshareParticipantTrack(tracks, id);
|
||||
if (getSourceNameSignalingFeatureFlag(state) && participant?.isVirtualScreenshareParticipant) {
|
||||
videoTrack = getVirtualScreenshareParticipantTrack(tracks, id);
|
||||
} else {
|
||||
videoTrack = getTrackByMediaTypeAndParticipant(tracks, MEDIA_TYPE.VIDEO, id);
|
||||
}
|
||||
|
||||
3033
package-lock.json
generated
3033
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@@ -39,7 +39,7 @@
|
||||
"@hapi/bourne": "2.0.0",
|
||||
"@jitsi/js-utils": "2.0.0",
|
||||
"@jitsi/logger": "2.0.0",
|
||||
"@jitsi/rtcstats": "9.0.1",
|
||||
"@jitsi/rtcstats": "9.2.0",
|
||||
"@material-ui/core": "4.11.3",
|
||||
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.3.tgz",
|
||||
"@microsoft/microsoft-graph-client": "3.0.1",
|
||||
@@ -54,11 +54,12 @@
|
||||
"@react-navigation/elements": "1.2.1",
|
||||
"@react-navigation/material-top-tabs": "6.0.6",
|
||||
"@react-navigation/native": "6.0.6",
|
||||
"@react-navigation/stack": "6.0.11",
|
||||
"@react-navigation/native-stack": "6.6.2",
|
||||
"@svgr/webpack": "4.3.2",
|
||||
"@tensorflow/tfjs-backend-wasm": "3.13.0",
|
||||
"@tensorflow/tfjs-core": "3.13.0",
|
||||
"@vladmandic/face-api": "1.6.4",
|
||||
"@vladmandic/human": "2.6.5",
|
||||
"@vladmandic/human-models": "2.5.9",
|
||||
"@xmldom/xmldom": "0.7.5",
|
||||
"amplitude-js": "8.2.1",
|
||||
"base64-js": "1.3.1",
|
||||
@@ -76,9 +77,9 @@
|
||||
"jquery": "3.5.1",
|
||||
"jquery-i18next": "1.2.1",
|
||||
"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/v1418.0.0+da6d04c2/lib-jitsi-meet.tgz",
|
||||
"libflacjs": "https://git@github.com/mmig/libflac.js#93d37e7f811f01cf7d8b6a603e38bd3c3810907d",
|
||||
"lib-jitsi-meet": "https://github.com/jitsi/lib-jitsi-meet/releases/download/v1457.0.0+ad75454f/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.2",
|
||||
"moment-duration-format": "2.2.2",
|
||||
@@ -91,14 +92,14 @@
|
||||
"react-focus-lock": "2.5.1",
|
||||
"react-i18next": "10.11.4",
|
||||
"react-linkify": "1.0.0-alpha",
|
||||
"react-native": "0.67.4",
|
||||
"react-native": "0.68.1",
|
||||
"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": "9.2.1",
|
||||
"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-gesture-handler": "2.1.0",
|
||||
"react-native-get-random-values": "1.7.2",
|
||||
"react-native-immersive": "2.0.0",
|
||||
@@ -106,7 +107,7 @@
|
||||
"react-native-pager-view": "5.4.9",
|
||||
"react-native-paper": "4.11.1",
|
||||
"react-native-performance": "2.1.0",
|
||||
"react-native-reanimated": "1.13.4",
|
||||
"react-native-reanimated": "https://git@github.com/software-mansion/react-native-reanimated#c4a6b6f687ede090f6081064abe83a2ef9a05784",
|
||||
"react-native-safe-area-context": "3.3.2",
|
||||
"react-native-screens": "3.10.1",
|
||||
"react-native-sound": "0.11.1",
|
||||
@@ -117,7 +118,7 @@
|
||||
"react-native-url-polyfill": "1.3.0",
|
||||
"react-native-video": "https://git@github.com/jitsi/react-native-video#4f6dad990d17ce42894df993780b5386a9c11b85",
|
||||
"react-native-watch-connectivity": "1.0.4",
|
||||
"react-native-webrtc": "1.100.0",
|
||||
"react-native-webrtc": "1.100.1",
|
||||
"react-native-webview": "11.15.1",
|
||||
"react-native-youtube-iframe": "2.2.1",
|
||||
"react-redux": "7.1.0",
|
||||
@@ -133,6 +134,7 @@
|
||||
"util": "0.12.1",
|
||||
"uuid": "8.3.2",
|
||||
"wasm-check": "2.0.1",
|
||||
"webm-duration-fix": "1.0.4",
|
||||
"windows-iana": "^3.1.0",
|
||||
"zxcvbn": "4.4.2"
|
||||
},
|
||||
@@ -145,6 +147,10 @@
|
||||
"@babel/preset-react": "7.16.0",
|
||||
"@babel/runtime": "7.16.0",
|
||||
"@jitsi/eslint-config": "4.0.0",
|
||||
"@types/react": "17.0.14",
|
||||
"@types/react-native": "0.67.6",
|
||||
"@types/react-redux": "7.1.24",
|
||||
"@types/uuid": "8.3.4",
|
||||
"babel-loader": "8.2.3",
|
||||
"babel-plugin-optional-require": "0.3.1",
|
||||
"circular-dependency-plugin": "5.2.0",
|
||||
@@ -159,7 +165,7 @@
|
||||
"expose-loader": "3.0.0",
|
||||
"imports-loader": "0.7.1",
|
||||
"jetifier": "1.6.4",
|
||||
"metro-react-native-babel-preset": "0.66.2",
|
||||
"metro-react-native-babel-preset": "0.67.0",
|
||||
"patch-package": "6.4.7",
|
||||
"process": "0.11.10",
|
||||
"sass": "1.26.8",
|
||||
@@ -167,7 +173,7 @@
|
||||
"style-loader": "0.19.0",
|
||||
"traverse": "0.6.6",
|
||||
"ts-loader": "9.2.6",
|
||||
"typescript": "4.3.5",
|
||||
"typescript": "4.6.4",
|
||||
"unorm": "1.6.0",
|
||||
"webpack": "5.57.1",
|
||||
"webpack-bundle-analyzer": "4.4.2",
|
||||
@@ -183,8 +189,12 @@
|
||||
"lint": "eslint --max-warnings 0 .",
|
||||
"lang-sort": "./resources/lang-sort.sh",
|
||||
"lint-fix": "eslint --max-warnings 0 --fix .",
|
||||
"postinstall": "patch-package && jetify",
|
||||
"postinstall": "patch-package --error-on-fail && jetify",
|
||||
"validate": "npm ls",
|
||||
"start": "make dev"
|
||||
},
|
||||
"resolutions": {
|
||||
"@types/react": "17.0.14",
|
||||
"@types/react-dom": "17.0.14"
|
||||
}
|
||||
}
|
||||
|
||||
14
patches/@giphy+js-analytics+4.0.7.patch
Normal file
14
patches/@giphy+js-analytics+4.0.7.patch
Normal file
@@ -0,0 +1,14 @@
|
||||
diff --git a/node_modules/@giphy/js-analytics/dist/send-pingback.js b/node_modules/@giphy/js-analytics/dist/send-pingback.js
|
||||
index 001345a..f303443 100644
|
||||
--- a/node_modules/@giphy/js-analytics/dist/send-pingback.js
|
||||
+++ b/node_modules/@giphy/js-analytics/dist/send-pingback.js
|
||||
@@ -10,6 +10,9 @@ var global_1 = __importDefault(require("./global"));
|
||||
var environment = (global_1.default === null || global_1.default === void 0 ? void 0 : global_1.default.GIPHY_PINGBACK_URL) || 'https://pingback.giphy.com';
|
||||
var pingBackUrl = environment + "/v2/pingback?apikey=l0HlIwPWyBBUDAUgM";
|
||||
var sendPingback = function (events) {
|
||||
+ // Disabled.
|
||||
+ return Promise.resolve();
|
||||
+
|
||||
var headers = js_util_1.getGiphySDKRequestHeaders();
|
||||
/* istanbul ignore next */
|
||||
headers === null || headers === void 0 ? void 0 : headers.set('Content-Type', 'application/json');
|
||||
12
patches/@giphy+js-brand+2.0.4.patch
Normal file
12
patches/@giphy+js-brand+2.0.4.patch
Normal file
@@ -0,0 +1,12 @@
|
||||
diff --git a/node_modules/@giphy/js-brand/dist/typography.js b/node_modules/@giphy/js-brand/dist/typography.js
|
||||
index af796bc..585fa00 100644
|
||||
--- a/node_modules/@giphy/js-brand/dist/typography.js
|
||||
+++ b/node_modules/@giphy/js-brand/dist/typography.js
|
||||
@@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.css = exports.fontSize = exports.fontFamily = void 0;
|
||||
var emotion_1 = require("emotion");
|
||||
// eslint-disable-next-line
|
||||
-emotion_1.injectGlobal(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff') format('woff');\n}\n\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: bold;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff') format('woff');\n}\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: 900;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_XBd.woff') format('woff');\n}\n@font-face {\n font-family: 'nexablack'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff') format('woff');\n}\n@font-face {\n font-family: 'SSStandard'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-standard.woff') format('woff');\n}\n@font-face {\n font-family: 'SSSocial'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-social.woff') format('woff');\n}\n"], ["\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Rg.woff') format('woff');\n}\n\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: bold;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_Bd.woff') format('woff');\n}\n@font-face {\n font-family: 'interface';\n font-style: normal;\n font-weight: 900;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/InterFace_W_XBd.woff') format('woff');\n}\n@font-face {\n font-family: 'nexablack'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff2') format('woff2'),\n url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/nexa_black-webfont.woff') format('woff');\n}\n@font-face {\n font-family: 'SSStandard'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-standard.woff') format('woff');\n}\n@font-face {\n font-family: 'SSSocial'; \n font-style: normal;\n font-weight: normal;\n src: url('https://s3.amazonaws.com/giphyscripts/react-giphy-brand/fonts/ss-social.woff') format('woff');\n}\n"])));
|
||||
exports.fontFamily = {
|
||||
title: "'nexablack', sans-serif",
|
||||
body: 'interface, Helvetica Neue, helvetica, sans-serif;',
|
||||
@@ -1,5 +1,5 @@
|
||||
diff --git a/node_modules/react-native/React/CoreModules/RCTTiming.mm b/node_modules/react-native/React/CoreModules/RCTTiming.mm
|
||||
index 70f0543..d003662 100644
|
||||
index 13d0d57..00e5d4c 100644
|
||||
--- a/node_modules/react-native/React/CoreModules/RCTTiming.mm
|
||||
+++ b/node_modules/react-native/React/CoreModules/RCTTiming.mm
|
||||
@@ -127,7 +127,15 @@ - (void)setup
|
||||
@@ -1,118 +0,0 @@
|
||||
diff --git a/node_modules/react-native-dialog/lib/Button.js b/node_modules/react-native-dialog/lib/Button.js
|
||||
index 19eeb22..b8a66f4 100644
|
||||
--- a/node_modules/react-native-dialog/lib/Button.js
|
||||
+++ b/node_modules/react-native-dialog/lib/Button.js
|
||||
@@ -50,7 +50,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
backgroundColor: "transparent",
|
||||
},
|
||||
android: {
|
||||
- color: PlatformColor(`@android:color/${isDark ? "link_text_dark" : "link_text_dark_light"}`),
|
||||
+ color: isDark ? '#BFC7C7C7' : '#BF727272',
|
||||
textAlign: "center",
|
||||
backgroundColor: "transparent",
|
||||
padding: 8,
|
||||
diff --git a/node_modules/react-native-dialog/lib/CodeInput.js b/node_modules/react-native-dialog/lib/CodeInput.js
|
||||
index eceae56..cc4339d 100644
|
||||
--- a/node_modules/react-native-dialog/lib/CodeInput.js
|
||||
+++ b/node_modules/react-native-dialog/lib/CodeInput.js
|
||||
@@ -97,7 +97,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
color: PlatformColor("label"),
|
||||
},
|
||||
android: {
|
||||
- color: PlatformColor(`@android:color/${isDark ? "primary_text_dark" : "primary_text_light"}`),
|
||||
+ color: isDark ? '#FAFAFA' : '#212121',
|
||||
fontSize: 20,
|
||||
},
|
||||
default: {},
|
||||
@@ -107,7 +107,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
color: PlatformColor("label"),
|
||||
},
|
||||
android: {
|
||||
- color: PlatformColor(`@android:color/${isDark ? "primary_text_dark" : "primary_text_light"}`),
|
||||
+ color: isDark ? '#FAFAFA' : '#212121',
|
||||
fontSize: 14,
|
||||
},
|
||||
default: {},
|
||||
diff --git a/node_modules/react-native-dialog/lib/Container.js b/node_modules/react-native-dialog/lib/Container.js
|
||||
index 69e3764..d7569fb 100644
|
||||
--- a/node_modules/react-native-dialog/lib/Container.js
|
||||
+++ b/node_modules/react-native-dialog/lib/Container.js
|
||||
@@ -82,7 +82,7 @@ DialogContainer.propTypes = {
|
||||
useNativeDriver: PropTypes.bool,
|
||||
children: PropTypes.node.isRequired,
|
||||
};
|
||||
-const buildStyles = () => StyleSheet.create({
|
||||
+const buildStyles = (isDark) => StyleSheet.create({
|
||||
centeredView: {
|
||||
marginTop: 22,
|
||||
},
|
||||
@@ -103,7 +103,7 @@ const buildStyles = () => StyleSheet.create({
|
||||
overflow: "hidden",
|
||||
},
|
||||
android: {
|
||||
- backgroundColor: PlatformColor("?attr/colorBackgroundFloating"),
|
||||
+ backgroundColor: isDark ? '#212121' : '#FFFFFF',
|
||||
flexDirection: "column",
|
||||
borderRadius: 3,
|
||||
padding: 16,
|
||||
diff --git a/node_modules/react-native-dialog/lib/Description.js b/node_modules/react-native-dialog/lib/Description.js
|
||||
index 2da9ed3..248ac2f 100644
|
||||
--- a/node_modules/react-native-dialog/lib/Description.js
|
||||
+++ b/node_modules/react-native-dialog/lib/Description.js
|
||||
@@ -28,7 +28,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
marginTop: 4,
|
||||
},
|
||||
android: {
|
||||
- color: PlatformColor(`@android:color/${isDark ? "secondary_text_dark" : "secondary_text_light"}`),
|
||||
+ color: isDark ? '#C7C7C7' : '#727272',
|
||||
fontSize: 16,
|
||||
marginTop: 10,
|
||||
},
|
||||
diff --git a/node_modules/react-native-dialog/lib/Input.js b/node_modules/react-native-dialog/lib/Input.js
|
||||
index b33a1a0..063d7f8 100644
|
||||
--- a/node_modules/react-native-dialog/lib/Input.js
|
||||
+++ b/node_modules/react-native-dialog/lib/Input.js
|
||||
@@ -48,7 +48,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
color: PlatformColor("label"),
|
||||
},
|
||||
android: {
|
||||
- color: PlatformColor(`@android:color/${isDark ? "primary_text_dark" : "primary_text_light"}`),
|
||||
+ color: isDark ? '#FAFAFA' : '#212121',
|
||||
fontSize: 14,
|
||||
},
|
||||
default: {},
|
||||
@@ -58,7 +58,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
color: PlatformColor("label"),
|
||||
},
|
||||
android: {
|
||||
- color: PlatformColor(`@android:color/${isDark ? "primary_text_dark" : "primary_text_light"}`),
|
||||
+ color: isDark ? '#FAFAFA' : '#212121',
|
||||
marginLeft: -4,
|
||||
paddingLeft: 4,
|
||||
},
|
||||
diff --git a/node_modules/react-native-dialog/lib/Switch.js b/node_modules/react-native-dialog/lib/Switch.js
|
||||
index 26a05ca..05114fa 100644
|
||||
--- a/node_modules/react-native-dialog/lib/Switch.js
|
||||
+++ b/node_modules/react-native-dialog/lib/Switch.js
|
||||
@@ -52,7 +52,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
flex: 1,
|
||||
paddingRight: 8,
|
||||
fontSize: 16,
|
||||
- color: PlatformColor(`@android:color/${isDark ? "primary_text_dark" : "primary_text_light"}`),
|
||||
+ color: isDark ? '#FAFAFA' : '#212121',
|
||||
},
|
||||
default: {},
|
||||
}),
|
||||
diff --git a/node_modules/react-native-dialog/lib/Title.js b/node_modules/react-native-dialog/lib/Title.js
|
||||
index 1c6fd87..b5511cc 100644
|
||||
--- a/node_modules/react-native-dialog/lib/Title.js
|
||||
+++ b/node_modules/react-native-dialog/lib/Title.js
|
||||
@@ -28,7 +28,7 @@ const buildStyles = (isDark) => StyleSheet.create({
|
||||
fontWeight: "600",
|
||||
},
|
||||
android: {
|
||||
- color: PlatformColor(`@android:color/${isDark ? "primary_text_dark" : "primary_text_light"}`),
|
||||
+ color: isDark ? '#FAFAFA' : '#212121',
|
||||
fontWeight: "500",
|
||||
fontSize: 18,
|
||||
},
|
||||
@@ -69,11 +69,11 @@ export default class AudioMuteButton extends Component<Props, State> {
|
||||
Promise.all([
|
||||
api.isAudioAvailable(),
|
||||
api.isAudioMuted(),
|
||||
api.isStartSilent()
|
||||
api.isAudioDisabled?.() || Promise.resolve(false)
|
||||
])
|
||||
.then(([ audioAvailable, audioMuted, startSilent ]) =>
|
||||
.then(([ audioAvailable, audioMuted, audioDisabled ]) =>
|
||||
this.setState({
|
||||
audioAvailable: audioAvailable && !startSilent,
|
||||
audioAvailable: audioAvailable && !audioDisabled,
|
||||
audioMuted
|
||||
}))
|
||||
.catch(console.error);
|
||||
|
||||
@@ -641,18 +641,20 @@ export function createSharedVideoEvent(action, attributes = {}) {
|
||||
* of ACTION_SHORTCUT_PRESSED, ACTION_SHORTCUT_RELEASED
|
||||
* or ACTION_SHORTCUT_TRIGGERED).
|
||||
* @param {Object} attributes - Attributes to attach to the event.
|
||||
* @param {string} source - The event's source.
|
||||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
*/
|
||||
export function createShortcutEvent(
|
||||
shortcut,
|
||||
action = ACTION_SHORTCUT_TRIGGERED,
|
||||
attributes = {}) {
|
||||
attributes = {},
|
||||
source = 'keyboard.shortcut') {
|
||||
return {
|
||||
action,
|
||||
actionSubjectId: shortcut,
|
||||
attributes,
|
||||
source: 'keyboard.shortcut',
|
||||
source,
|
||||
type: TYPE_UI
|
||||
};
|
||||
}
|
||||
@@ -901,7 +903,7 @@ export function createBreakoutRoomsEvent(actionSubject) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and event which indicates a GIF was sent.
|
||||
* Creates an event which indicates a GIF was sent.
|
||||
*
|
||||
* @returns {Object} The event in a format suitable for sending via
|
||||
* sendAnalytics.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import { API_ID } from '../../../modules/API/constants';
|
||||
import { getName as getAppName } from '../app/functions';
|
||||
import { getAnalyticsRoomName } from '../base/conference';
|
||||
import {
|
||||
checkChromeExtensionsInstalled,
|
||||
isMobileBrowser
|
||||
@@ -12,6 +13,7 @@ import JitsiMeetJS, {
|
||||
} from '../base/lib-jitsi-meet';
|
||||
import { isAnalyticsEnabled } from '../base/lib-jitsi-meet/functions';
|
||||
import { getJitsiMeetGlobalNS, loadScript, parseURIString } from '../base/util';
|
||||
import { inIframe } from '../base/util/iframeUtils';
|
||||
|
||||
import { AmplitudeHandler, MatomoHandler } from './handlers';
|
||||
import logger from './logger';
|
||||
@@ -154,7 +156,9 @@ export async function createHandlers({ getState }: { getState: Function }) {
|
||||
* @param {Array<Object>} handlers - The analytics handlers.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function initAnalytics({ getState }: { getState: Function }, handlers: Array<Object>) {
|
||||
export function initAnalytics(store: Store, handlers: Array<Object>) {
|
||||
const { getState, dispatch } = store;
|
||||
|
||||
if (!isAnalyticsEnabled(getState) || handlers.length === 0) {
|
||||
return;
|
||||
}
|
||||
@@ -165,7 +169,6 @@ export function initAnalytics({ getState }: { getState: Function }, handlers: Ar
|
||||
deploymentInfo
|
||||
} = config;
|
||||
const { group, server } = state['features/base/jwt'];
|
||||
const roomName = state['features/base/conference'].room;
|
||||
const { locationURL = {} } = state['features/base/connection'];
|
||||
const { tenant } = parseURIString(locationURL.href) || {};
|
||||
const permanentProperties = {};
|
||||
@@ -203,7 +206,7 @@ export function initAnalytics({ getState }: { getState: Function }, handlers: Ar
|
||||
}
|
||||
|
||||
analytics.addPermanentProperties(permanentProperties);
|
||||
analytics.setConferenceName(roomName);
|
||||
analytics.setConferenceName(getAnalyticsRoomName(state, dispatch));
|
||||
|
||||
// Set the handlers last, since this triggers emptying of the cache
|
||||
analytics.setAnalyticsHandlers(handlers);
|
||||
@@ -221,24 +224,6 @@ export function initAnalytics({ getState }: { getState: Function }, handlers: Ar
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether we are loaded in iframe.
|
||||
*
|
||||
* @returns {boolean} Returns {@code true} if loaded in iframe.
|
||||
* @private
|
||||
*/
|
||||
export function inIframe() {
|
||||
if (navigator.product === 'ReactNative') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
return window.self !== window.top;
|
||||
} catch (e) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load the scripts for the external analytics handlers and creates them.
|
||||
*
|
||||
|
||||
@@ -15,11 +15,17 @@ import { connect, disconnect, setLocationURL } from '../base/connection';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet/functions.native';
|
||||
import { createDesiredLocalTracks } from '../base/tracks';
|
||||
import {
|
||||
appendURLParam,
|
||||
getBackendSafeRoomName,
|
||||
parseURIString,
|
||||
parseURLParams,
|
||||
toURLString
|
||||
} from '../base/util';
|
||||
import { navigateRoot } from '../mobile/navigation/rootNavigationContainerRef';
|
||||
import { isPrejoinPageEnabled } from '../mobile/navigation/functions';
|
||||
import {
|
||||
goBackToRoot,
|
||||
navigateRoot
|
||||
} from '../mobile/navigation/rootNavigationContainerRef';
|
||||
import { screen } from '../mobile/navigation/routes';
|
||||
import { setFatalError } from '../overlay';
|
||||
|
||||
@@ -86,7 +92,11 @@ export function appNavigate(uri: ?string) {
|
||||
let url = `${baseURL}config.js`;
|
||||
|
||||
// XXX In order to support multiple shards, tell the room to the deployment.
|
||||
room && (url += `?room=${getBackendSafeRoomName(room)}`);
|
||||
room && (url = appendURLParam(url, 'room', getBackendSafeRoomName(room)));
|
||||
|
||||
const { release } = parseURLParams(location, true, 'search');
|
||||
|
||||
release && (url = appendURLParam(url, 'release', release));
|
||||
|
||||
let config;
|
||||
|
||||
@@ -128,7 +138,15 @@ export function appNavigate(uri: ?string) {
|
||||
|
||||
if (room) {
|
||||
dispatch(createDesiredLocalTracks());
|
||||
dispatch(connect());
|
||||
|
||||
if (isPrejoinPageEnabled(getState())) {
|
||||
navigateRoot(screen.preJoin);
|
||||
} else {
|
||||
dispatch(connect());
|
||||
navigateRoot(screen.conference.root);
|
||||
}
|
||||
} else {
|
||||
goBackToRoot(getState(), dispatch);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,8 +15,10 @@ import {
|
||||
import { setLocationURL } from '../base/connection';
|
||||
import { loadConfig } from '../base/lib-jitsi-meet/functions.web';
|
||||
import {
|
||||
appendURLParam,
|
||||
getBackendSafeRoomName,
|
||||
parseURIString
|
||||
parseURIString,
|
||||
parseURLParams
|
||||
} from '../base/util';
|
||||
import { isVpaasMeeting } from '../jaas/functions';
|
||||
import {
|
||||
@@ -93,7 +95,11 @@ export function appNavigate(uri: ?string) {
|
||||
let url = `${baseURL}config.js`;
|
||||
|
||||
// XXX In order to support multiple shards, tell the room to the deployment.
|
||||
room && (url += `?room=${getBackendSafeRoomName(room)}`);
|
||||
room && (url = appendURLParam(url, 'room', getBackendSafeRoomName(room)));
|
||||
|
||||
const { release } = parseURLParams(location, true, 'search');
|
||||
|
||||
release && (url = appendURLParam(url, 'release', release));
|
||||
|
||||
let config;
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
// @flow
|
||||
|
||||
import React from 'react';
|
||||
import { Platform, StyleSheet, View } from 'react-native';
|
||||
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
||||
import { FullWindowOverlay } from 'react-native-screens';
|
||||
import SplashScreen from 'react-native-splash-screen';
|
||||
|
||||
import { DialogContainer } from '../../base/dialog';
|
||||
import BottomSheetContainer from '../../base/dialog/components/native/BottomSheetContainer';
|
||||
import { updateFlags } from '../../base/flags/actions';
|
||||
import { CALL_INTEGRATION_ENABLED, SERVER_URL_CHANGE_ENABLED } from '../../base/flags/constants';
|
||||
import { getFeatureFlag } from '../../base/flags/functions';
|
||||
import { Platform } from '../../base/react';
|
||||
import { DimensionsDetector, clientResized } from '../../base/responsive-ui';
|
||||
import { DimensionsDetector, clientResized, setSafeAreaInsets } from '../../base/responsive-ui';
|
||||
import { updateSettings } from '../../base/settings';
|
||||
import { _getRouteToRender } from '../getRouteToRender.native';
|
||||
import logger from '../logger';
|
||||
@@ -22,16 +23,16 @@ import '../reducers';
|
||||
|
||||
declare var __DEV__;
|
||||
|
||||
const DialogContainerWrapper = Platform.select({
|
||||
ios: FullWindowOverlay,
|
||||
default: View
|
||||
});
|
||||
|
||||
/**
|
||||
* The type of React {@code Component} props of {@link App}.
|
||||
*/
|
||||
type Props = AbstractAppProps & {
|
||||
|
||||
/**
|
||||
* An object of colors that override the default colors of the app/sdk.
|
||||
*/
|
||||
colorScheme: ?Object,
|
||||
|
||||
/**
|
||||
* Identifier for this app on the native side.
|
||||
*/
|
||||
@@ -76,6 +77,7 @@ export class App extends AbstractApp {
|
||||
|
||||
// Bind event handler so it is only bound once per instance.
|
||||
this._onDimensionsChanged = this._onDimensionsChanged.bind(this);
|
||||
this._onSafeAreaInsetsChanged = this._onSafeAreaInsetsChanged.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,13 +100,31 @@ export class App extends AbstractApp {
|
||||
*/
|
||||
async _extraInit() {
|
||||
const { dispatch, getState } = this.state.store;
|
||||
|
||||
// We set these early enough so then we avoid any unnecessary re-renders.
|
||||
dispatch(updateFlags(this.props.flags));
|
||||
|
||||
const route = await _getRouteToRender();
|
||||
|
||||
// We need the root navigator to be set early.
|
||||
await this._navigate(route);
|
||||
|
||||
// We set these early enough so then we avoid any unnecessary re-renders.
|
||||
dispatch(updateFlags(this.props.flags));
|
||||
// HACK ALERT!
|
||||
// Wait until the root navigator is ready.
|
||||
// We really need to break the inheritance relationship between App,
|
||||
// AbstractApp and BaseApp, it's very inflexible and cumbersome right now.
|
||||
const rootNavigationReady = new Promise(resolve => {
|
||||
const i = setInterval(() => {
|
||||
const { ready } = getState()['features/app'] || {};
|
||||
|
||||
if (ready) {
|
||||
clearInterval(i);
|
||||
resolve();
|
||||
}
|
||||
}, 50);
|
||||
});
|
||||
|
||||
await rootNavigationReady;
|
||||
|
||||
// Check if serverURL is configured externally and not allowed to change.
|
||||
const serverURLChangeEnabled = getFeatureFlag(getState(), SERVER_URL_CHANGE_ENABLED, true);
|
||||
@@ -138,10 +158,13 @@ export class App extends AbstractApp {
|
||||
*/
|
||||
_createMainElement(component, props) {
|
||||
return (
|
||||
<DimensionsDetector
|
||||
onDimensionsChanged = { this._onDimensionsChanged }>
|
||||
{ super._createMainElement(component, props) }
|
||||
</DimensionsDetector>
|
||||
<SafeAreaProvider>
|
||||
<DimensionsDetector
|
||||
onDimensionsChanged = { this._onDimensionsChanged }
|
||||
onSafeAreaInsetsChanged = { this._onSafeAreaInsetsChanged }>
|
||||
{ super._createMainElement(component, props) }
|
||||
</DimensionsDetector>
|
||||
</SafeAreaProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -198,6 +221,23 @@ export class App extends AbstractApp {
|
||||
dispatch(clientResized(width, height));
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the safe are insets values.
|
||||
*
|
||||
* @param {Object} insets - The insets.
|
||||
* @param {number} insets.top - The top inset.
|
||||
* @param {number} insets.right - The right inset.
|
||||
* @param {number} insets.bottom - The bottom inset.
|
||||
* @param {number} insets.left - The left inset.
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onSafeAreaInsetsChanged(insets) {
|
||||
const { dispatch } = this.state.store;
|
||||
|
||||
dispatch(setSafeAreaInsets(insets));
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the platform specific dialog container.
|
||||
*
|
||||
@@ -205,7 +245,12 @@ export class App extends AbstractApp {
|
||||
*/
|
||||
_renderDialogContainer() {
|
||||
return (
|
||||
<DialogContainer />
|
||||
<DialogContainerWrapper
|
||||
pointerEvents = 'box-none'
|
||||
style = { StyleSheet.absoluteFill }>
|
||||
<BottomSheetContainer />
|
||||
<DialogContainer />
|
||||
</DialogContainerWrapper>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ import { toState } from '../base/redux';
|
||||
import { Conference } from '../conference';
|
||||
import { getDeepLinkingPage } from '../deep-linking';
|
||||
import { UnsupportedDesktopBrowser } from '../unsupported-browser';
|
||||
import { BlankPage, isWelcomePageUserEnabled, WelcomePage } from '../welcome';
|
||||
import { BlankPage, WelcomePage } from '../welcome';
|
||||
import { isWelcomePageEnabled } from '../welcome/functions';
|
||||
|
||||
/**
|
||||
* Determines which route is to be rendered in order to depict a specific Redux
|
||||
@@ -72,7 +73,7 @@ function _getWebConferenceRoute(state) {
|
||||
function _getWebWelcomePageRoute(state) {
|
||||
const route = _getEmptyRoute();
|
||||
|
||||
if (isWelcomePageUserEnabled(state)) {
|
||||
if (isWelcomePageEnabled(state)) {
|
||||
if (isSupportedBrowser()) {
|
||||
route.component = WelcomePage;
|
||||
} else {
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import {
|
||||
createConnectionEvent,
|
||||
inIframe,
|
||||
sendAnalytics
|
||||
} from '../analytics';
|
||||
import { SET_ROOM } from '../base/conference';
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
getURLWithoutParams
|
||||
} from '../base/connection';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { inIframe } from '../base/util/iframeUtils';
|
||||
|
||||
import { reloadNow } from './actions';
|
||||
import { _getRouteToRender } from './getRouteToRender';
|
||||
|
||||
@@ -36,6 +36,7 @@ import '../large-video/middleware';
|
||||
import '../lobby/middleware';
|
||||
import '../notifications/middleware';
|
||||
import '../overlay/middleware';
|
||||
import '../participants-pane/middleware';
|
||||
import '../polls/middleware';
|
||||
import '../reactions/middleware';
|
||||
import '../recent-list/middleware';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// @flow
|
||||
|
||||
import '../authentication/middleware';
|
||||
import '../dynamic-branding/middleware';
|
||||
import '../gifs/middleware';
|
||||
import '../mobile/audio-mode/middleware';
|
||||
import '../mobile/background/middleware';
|
||||
|
||||
@@ -7,7 +7,6 @@ import '../dynamic-branding/middleware';
|
||||
import '../e2ee/middleware';
|
||||
import '../external-api/middleware';
|
||||
import '../keyboard-shortcuts/middleware';
|
||||
import '../local-recording/middleware';
|
||||
import '../no-audio-signal/middleware';
|
||||
import '../notifications/middleware';
|
||||
import '../noise-detection/middleware';
|
||||
|
||||
22
react/features/app/reducer.native.js
Normal file
22
react/features/app/reducer.native.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import { ReducerRegistry } from '../base/redux';
|
||||
import { _ROOT_NAVIGATION_READY } from '../mobile/navigation/actionTypes';
|
||||
|
||||
/**
|
||||
* Listen for actions which changes the state of the app feature.
|
||||
*
|
||||
* @param {Object} state - The Redux state of the feature features/app.
|
||||
* @param {Object} action - Action object.
|
||||
* @param {string} action.type - Type of action.
|
||||
* @returns {Object}
|
||||
*/
|
||||
ReducerRegistry.register('features/app', (state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case _ROOT_NAVIGATION_READY:
|
||||
return {
|
||||
...state,
|
||||
ready: action.ready
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
});
|
||||
@@ -8,4 +8,6 @@ import '../mobile/full-screen/reducer';
|
||||
import '../mobile/watchos/reducer';
|
||||
import '../shared-video/reducer';
|
||||
|
||||
import './reducer.native';
|
||||
|
||||
import './reducers.any';
|
||||
|
||||
@@ -4,7 +4,6 @@ import '../base/devices/reducer';
|
||||
import '../e2ee/reducer';
|
||||
import '../face-landmarks/reducer';
|
||||
import '../feedback/reducer';
|
||||
import '../local-recording/reducer';
|
||||
import '../no-audio-signal/reducer';
|
||||
import '../noise-detection/reducer';
|
||||
import '../participants-pane/reducer';
|
||||
|
||||
4
react/features/app/types.ts
Normal file
4
react/features/app/types.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface IStore {
|
||||
getState: Function,
|
||||
dispatch: Function
|
||||
}
|
||||
@@ -29,14 +29,11 @@ export function authenticateAndUpgradeRole(
|
||||
id: string,
|
||||
password: string,
|
||||
conference: Object) {
|
||||
return (dispatch: Dispatch<any>, getState: Function) => {
|
||||
const { password: roomPassword }
|
||||
= getState()['features/base/conference'];
|
||||
return (dispatch: Dispatch<any>) => {
|
||||
const process
|
||||
= conference.authenticateAndUpgradeRole({
|
||||
id,
|
||||
password,
|
||||
roomPassword,
|
||||
|
||||
onLoginSuccessful() {
|
||||
// When the login succeeds, the process has completed half
|
||||
|
||||
@@ -1,23 +1,15 @@
|
||||
/* @flow */
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import Dialog from 'react-native-dialog';
|
||||
import { connect as reduxConnect } from 'react-redux';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { ColorSchemeRegistry } from '../../../base/color-scheme';
|
||||
import { toJid } from '../../../base/connection';
|
||||
import { connect } from '../../../base/connection/actions.native';
|
||||
import { _abstractMapStateToProps } from '../../../base/dialog';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { JitsiConnectionErrors } from '../../../base/lib-jitsi-meet';
|
||||
import type { StyleType } from '../../../base/styles';
|
||||
import { authenticateAndUpgradeRole, cancelLogin } from '../../actions.native';
|
||||
|
||||
// Register styles.
|
||||
import './styles';
|
||||
|
||||
/**
|
||||
* The type of the React {@link Component} props of {@link LoginDialog}.
|
||||
*/
|
||||
@@ -44,22 +36,12 @@ type Props = {
|
||||
*/
|
||||
_error: Object,
|
||||
|
||||
/**
|
||||
* Extra handler for cancel functionality.
|
||||
*/
|
||||
_onCancel: Function,
|
||||
|
||||
/**
|
||||
* The progress in the floating range between 0 and 1 of the authenticating
|
||||
* and upgrading the role of the local participant/user.
|
||||
*/
|
||||
_progress: number,
|
||||
|
||||
/**
|
||||
* The color-schemed stylesheet of this feature.
|
||||
*/
|
||||
_styles: StyleType,
|
||||
|
||||
/**
|
||||
* Redux store dispatch method.
|
||||
*/
|
||||
@@ -68,12 +50,7 @@ type Props = {
|
||||
/**
|
||||
* Invoked to obtain translated strings.
|
||||
*/
|
||||
t: Function,
|
||||
|
||||
/**
|
||||
* Override the default visibility.
|
||||
*/
|
||||
visible: boolean
|
||||
t: Function
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -120,10 +97,6 @@ type State = {
|
||||
* of the configuration parameters.
|
||||
*/
|
||||
class LoginDialog extends Component<Props, State> {
|
||||
static defaultProps = {
|
||||
visible: true
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes a new LoginDialog instance.
|
||||
*
|
||||
@@ -154,42 +127,40 @@ class LoginDialog extends Component<Props, State> {
|
||||
render() {
|
||||
const {
|
||||
_connecting: connecting,
|
||||
t,
|
||||
visible
|
||||
t
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<View>
|
||||
<Dialog.Container
|
||||
visible = { visible }>
|
||||
<Dialog.Title>
|
||||
{ t('dialog.login') }
|
||||
</Dialog.Title>
|
||||
<Dialog.Input
|
||||
autoCapitalize = { 'none' }
|
||||
autoCorrect = { false }
|
||||
onChangeText = { this._onUsernameChange }
|
||||
placeholder = { 'user@domain.com' }
|
||||
spellCheck = { false }
|
||||
value = { this.state.username } />
|
||||
<Dialog.Input
|
||||
autoCapitalize = { 'none' }
|
||||
onChangeText = { this._onPasswordChange }
|
||||
placeholder = { t('dialog.userPassword') }
|
||||
secureTextEntry = { true }
|
||||
value = { this.state.password } />
|
||||
<Dialog.Description>
|
||||
{ this._renderMessage() }
|
||||
</Dialog.Description>
|
||||
<Dialog.Button
|
||||
label = { t('dialog.Cancel') }
|
||||
onPress = { this._onCancel } />
|
||||
<Dialog.Button
|
||||
disabled = { connecting }
|
||||
label = { t('dialog.Ok') }
|
||||
onPress = { this._onLogin } />
|
||||
</Dialog.Container>
|
||||
</View>
|
||||
<Dialog.Container
|
||||
coverScreen = { false }
|
||||
visible = { true }>
|
||||
<Dialog.Title>
|
||||
{ t('dialog.login') }
|
||||
</Dialog.Title>
|
||||
<Dialog.Input
|
||||
autoCapitalize = { 'none' }
|
||||
autoCorrect = { false }
|
||||
onChangeText = { this._onUsernameChange }
|
||||
placeholder = { 'user@domain.com' }
|
||||
spellCheck = { false }
|
||||
value = { this.state.username } />
|
||||
<Dialog.Input
|
||||
autoCapitalize = { 'none' }
|
||||
onChangeText = { this._onPasswordChange }
|
||||
placeholder = { t('dialog.userPassword') }
|
||||
secureTextEntry = { true }
|
||||
value = { this.state.password } />
|
||||
<Dialog.Description>
|
||||
{ this._renderMessage() }
|
||||
</Dialog.Description>
|
||||
<Dialog.Button
|
||||
label = { t('dialog.Cancel') }
|
||||
onPress = { this._onCancel } />
|
||||
<Dialog.Button
|
||||
disabled = { connecting }
|
||||
label = { t('dialog.Ok') }
|
||||
onPress = { this._onLogin } />
|
||||
</Dialog.Container>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -204,12 +175,10 @@ class LoginDialog extends Component<Props, State> {
|
||||
_connecting: connecting,
|
||||
_error: error,
|
||||
_progress: progress,
|
||||
_styles: styles,
|
||||
t
|
||||
} = this.props;
|
||||
|
||||
let messageKey;
|
||||
let messageIsError = false;
|
||||
const messageOptions = {};
|
||||
|
||||
if (progress && progress < 1) {
|
||||
@@ -230,34 +199,22 @@ class LoginDialog extends Component<Props, State> {
|
||||
this.props._configHosts)
|
||||
&& credentials.password === this.state.password) {
|
||||
messageKey = 'dialog.incorrectPassword';
|
||||
messageIsError = true;
|
||||
}
|
||||
} else if (name) {
|
||||
messageKey = 'dialog.connectErrorWithMsg';
|
||||
messageOptions.msg = `${name} ${error.message}`;
|
||||
messageIsError = true;
|
||||
}
|
||||
} else if (connecting) {
|
||||
messageKey = 'connection.CONNECTING';
|
||||
}
|
||||
|
||||
if (messageKey) {
|
||||
const message = t(messageKey, messageOptions);
|
||||
const messageStyles
|
||||
= messageIsError ? styles.errorMessage : styles.progressMessage;
|
||||
|
||||
return (
|
||||
<Text style = { messageStyles }>
|
||||
{ message }
|
||||
</Text>
|
||||
);
|
||||
return t(messageKey, messageOptions);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
_onUsernameChange: (string) => void;
|
||||
|
||||
/**
|
||||
* Called when user edits the username.
|
||||
*
|
||||
@@ -271,8 +228,6 @@ class LoginDialog extends Component<Props, State> {
|
||||
});
|
||||
}
|
||||
|
||||
_onPasswordChange: (string) => void;
|
||||
|
||||
/**
|
||||
* Called when user edits the password.
|
||||
*
|
||||
@@ -286,8 +241,6 @@ class LoginDialog extends Component<Props, State> {
|
||||
});
|
||||
}
|
||||
|
||||
_onCancel: () => void;
|
||||
|
||||
/**
|
||||
* Notifies this LoginDialog that it has been dismissed by cancel.
|
||||
*
|
||||
@@ -295,14 +248,9 @@ class LoginDialog extends Component<Props, State> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_onCancel() {
|
||||
const { _onCancel, dispatch } = this.props;
|
||||
|
||||
_onCancel && _onCancel();
|
||||
dispatch(cancelLogin());
|
||||
this.props.dispatch(cancelLogin());
|
||||
}
|
||||
|
||||
_onLogin: () => void;
|
||||
|
||||
/**
|
||||
* Notifies this LoginDialog that the login button (OK) has been pressed by
|
||||
* the user.
|
||||
@@ -355,8 +303,7 @@ function _mapStateToProps(state) {
|
||||
_configHosts: configHosts,
|
||||
_connecting: Boolean(connecting) || Boolean(thenableWithCancel),
|
||||
_error: connectionError || authenticateAndUpgradeRoleError,
|
||||
_progress: progress,
|
||||
_styles: ColorSchemeRegistry.get(state, 'LoginDialog')
|
||||
_progress: progress
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,10 @@
|
||||
// @flow
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import type { Dispatch } from 'redux';
|
||||
|
||||
import { ConfirmDialog } from '../../../base/dialog';
|
||||
import { translate } from '../../../base/i18n';
|
||||
import { connect } from '../../../base/redux';
|
||||
import { cancelWaitForOwner } from '../../actions.native';
|
||||
|
||||
import LoginDialog from './LoginDialog';
|
||||
import { openLoginDialog, cancelWaitForOwner } from '../../actions.native';
|
||||
|
||||
/**
|
||||
* The type of the React {@code Component} props of {@link WaitForOwnerDialog}.
|
||||
@@ -42,14 +38,9 @@ class WaitForOwnerDialog extends Component<Props> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
showLoginDialog: false
|
||||
};
|
||||
|
||||
// Bind event handlers so they are only bound once per instance.
|
||||
this._onCancel = this._onCancel.bind(this);
|
||||
this._onLogin = this._onLogin.bind(this);
|
||||
this._onLoginDialogCancel = this._onLoginDialogCancel.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,17 +56,10 @@ class WaitForOwnerDialog extends Component<Props> {
|
||||
confirmLabel = 'dialog.IamHost'
|
||||
descriptionKey = 'dialog.WaitForHostMsg'
|
||||
onCancel = { this._onCancel }
|
||||
onSubmit = { this._onLogin }>
|
||||
<LoginDialog
|
||||
// eslint-disable-next-line react/jsx-handler-names
|
||||
_onCancel = { this._onLoginDialogCancel }
|
||||
visible = { this.state.showLoginDialog } />
|
||||
</ConfirmDialog>
|
||||
onSubmit = { this._onLogin } />
|
||||
);
|
||||
}
|
||||
|
||||
_onCancel: () => void;
|
||||
|
||||
/**
|
||||
* Called when the cancel button is clicked.
|
||||
*
|
||||
@@ -86,8 +70,6 @@ class WaitForOwnerDialog extends Component<Props> {
|
||||
this.props.dispatch(cancelWaitForOwner());
|
||||
}
|
||||
|
||||
_onLogin: () => void;
|
||||
|
||||
/**
|
||||
* Called when the OK button is clicked.
|
||||
*
|
||||
@@ -95,17 +77,7 @@ class WaitForOwnerDialog extends Component<Props> {
|
||||
* @returns {void}
|
||||
*/
|
||||
_onLogin() {
|
||||
this.setState({ showLoginDialog: true });
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the nested login dialog is cancelled.
|
||||
*
|
||||
* @private
|
||||
* @returns {void}
|
||||
*/
|
||||
_onLoginDialogCancel() {
|
||||
this.setState({ showLoginDialog: false });
|
||||
this.props.dispatch(openLoginDialog());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import { ColorSchemeRegistry, schemeColor } from '../../../base/color-scheme';
|
||||
import { BoxModel } from '../../../base/styles';
|
||||
|
||||
/**
|
||||
* The styles of the authentication feature.
|
||||
*/
|
||||
ColorSchemeRegistry.register('LoginDialog', {
|
||||
|
||||
/**
|
||||
* The style of {@code Text} rendered by the {@code Dialog}s of the
|
||||
* feature authentication.
|
||||
*/
|
||||
dialogText: {
|
||||
margin: BoxModel.margin,
|
||||
marginTop: BoxModel.margin * 2
|
||||
},
|
||||
|
||||
/**
|
||||
* The style used when an error message is rendered.
|
||||
*/
|
||||
errorMessage: {
|
||||
color: schemeColor('errorText')
|
||||
},
|
||||
|
||||
/**
|
||||
* The style of {@code LoginDialog}.
|
||||
*/
|
||||
loginDialog: {
|
||||
flex: 0,
|
||||
flexDirection: 'column',
|
||||
marginBottom: BoxModel.margin,
|
||||
marginTop: BoxModel.margin
|
||||
},
|
||||
|
||||
/**
|
||||
* The style used then a progress message is rendered.
|
||||
*/
|
||||
progressMessage: {
|
||||
color: schemeColor('text')
|
||||
}
|
||||
});
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
JitsiConnectionErrors
|
||||
} from '../base/lib-jitsi-meet';
|
||||
import { MiddlewareRegistry } from '../base/redux';
|
||||
import { setPrejoinPageVisibility } from '../prejoin';
|
||||
|
||||
import {
|
||||
CANCEL_LOGIN,
|
||||
@@ -120,6 +121,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
&& error.name === JitsiConnectionErrors.PASSWORD_REQUIRED
|
||||
&& typeof error.recoverable === 'undefined') {
|
||||
error.recoverable = true;
|
||||
store.dispatch(setPrejoinPageVisibility(false));
|
||||
store.dispatch(openLoginDialog());
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -51,9 +51,10 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
dispatch(hideLoginDialog());
|
||||
|
||||
const { authRequired, conference } = getState()['features/base/conference'];
|
||||
const { passwordRequired } = getState()['features/base/connection'];
|
||||
|
||||
// Only end the meeting if we are not already inside and trying to upgrade.
|
||||
if (authRequired && !conference) {
|
||||
if ((authRequired && !conference) || passwordRequired) {
|
||||
dispatch(maybeRedirectToWelcomePage());
|
||||
}
|
||||
}
|
||||
@@ -83,9 +84,7 @@ MiddlewareRegistry.register(store => next => action => {
|
||||
}
|
||||
|
||||
case CONFERENCE_JOINED:
|
||||
if (_isWaitingForOwner(store)) {
|
||||
store.dispatch(stopWaitForOwner());
|
||||
}
|
||||
store.dispatch(stopWaitForOwner());
|
||||
store.dispatch(hideLoginDialog());
|
||||
break;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user