mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-08 15:50:21 +00:00
Compare commits
305 Commits
saghul-pat
...
6340
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d51aedde0 | ||
|
|
058c82a704 | ||
|
|
7e2f3f7d68 | ||
|
|
30b0bb7bd6 | ||
|
|
f02a75bc9d | ||
|
|
6b5a821696 | ||
|
|
ad46df0a1a | ||
|
|
b0deb9ec0c | ||
|
|
61a6ce2a2e | ||
|
|
bacdbeff21 | ||
|
|
7fc9f6f515 | ||
|
|
d34aae4a4b | ||
|
|
ab86d336fb | ||
|
|
ffc412c18d | ||
|
|
077901cd2b | ||
|
|
ba3cd53017 | ||
|
|
0d50f1867d | ||
|
|
e9cfa78aaf | ||
|
|
76f7f3943f | ||
|
|
b9b8090996 | ||
|
|
d42e18c7bb | ||
|
|
a685f096a0 | ||
|
|
49357e3cd2 | ||
|
|
049a3eb7fb | ||
|
|
a31cc62c25 | ||
|
|
75ddf3e75f | ||
|
|
40128277bc | ||
|
|
7770d59c93 | ||
|
|
2dd3c72473 | ||
|
|
4a4856f3de | ||
|
|
47bdf800e7 | ||
|
|
f6d088149c | ||
|
|
cbe3d6d505 | ||
|
|
b41c71e80b | ||
|
|
a4b997362a | ||
|
|
a5da90ddaf | ||
|
|
dffa71666c | ||
|
|
892751154c | ||
|
|
935e4d3261 | ||
|
|
f115028961 | ||
|
|
d910b9db57 | ||
|
|
b2b576f6fb | ||
|
|
a39d9f283d | ||
|
|
0913cf2c4f | ||
|
|
51f7b46628 | ||
|
|
d029045fda | ||
|
|
ddab27e292 | ||
|
|
6df2e4009c | ||
|
|
21cf7f23c2 | ||
|
|
bac1347961 | ||
|
|
c4f39e9c34 | ||
|
|
ee266160f9 | ||
|
|
730d42cba1 | ||
|
|
3f795cd1ff | ||
|
|
252441da29 | ||
|
|
b89c470366 | ||
|
|
6e32a146e3 | ||
|
|
6f02382472 | ||
|
|
de37c3e809 | ||
|
|
ec47f530bc | ||
|
|
7b538fc3e9 | ||
|
|
d5146aaf2e | ||
|
|
efb46df3d9 | ||
|
|
88e6aa3323 | ||
|
|
a7c96e302f | ||
|
|
b85da1e1bb | ||
|
|
e7c5421e33 | ||
|
|
4b4caf5b1c | ||
|
|
8f1fae79e4 | ||
|
|
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 | ||
|
|
5ebe308953 | ||
|
|
7420113079 | ||
|
|
221ecac12d | ||
|
|
744607a5cc | ||
|
|
8f641b7bb1 | ||
|
|
045bd44407 | ||
|
|
13cfc3ba66 | ||
|
|
bbfe7b4f32 | ||
|
|
4a375aa2a4 | ||
|
|
a6ad592d25 | ||
|
|
00bb013373 | ||
|
|
95baf34ba6 | ||
|
|
64385d48e9 | ||
|
|
5d8c87eb76 |
@@ -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=99.0.0
|
||||
sdkVersion=99.0.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,8 +30,9 @@
|
||||
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:theme="@style/JitsiMeetActivityStyle"
|
||||
android:resizeableActivity="true"
|
||||
android:supportsPictureInPicture="true"
|
||||
android:windowSoftInputMode="adjustResize"/>
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2018-present 8x8, Inc.
|
||||
* Copyright @ 2018 Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.rnimmersive.RNImmersiveModule;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
/**
|
||||
* Base class for all views which are backed by a React Native view.
|
||||
*/
|
||||
public abstract class BaseReactView<ListenerT>
|
||||
extends FrameLayout {
|
||||
|
||||
/**
|
||||
* Background color used by {@code BaseReactView} and the React Native root
|
||||
* view.
|
||||
*/
|
||||
protected static int BACKGROUND_COLOR = 0xFF111111;
|
||||
|
||||
/**
|
||||
* The collection of all existing {@code BaseReactView}s. Used to find the
|
||||
* {@code BaseReactView} when delivering events coming from
|
||||
* {@link ExternalAPIModule}.
|
||||
*/
|
||||
static final Set<BaseReactView> views
|
||||
= Collections.newSetFromMap(new WeakHashMap<BaseReactView, Boolean>());
|
||||
|
||||
/**
|
||||
* Finds a {@code BaseReactView} which matches a specific external API
|
||||
* scope.
|
||||
*
|
||||
* @param externalAPIScope - The external API scope associated with the
|
||||
* {@code BaseReactView} to find.
|
||||
* @return The {@code BaseReactView}, if any, associated with the specified
|
||||
* {@code externalAPIScope}; otherwise, {@code null}.
|
||||
*/
|
||||
public static BaseReactView findViewByExternalAPIScope(
|
||||
String externalAPIScope) {
|
||||
synchronized (views) {
|
||||
for (BaseReactView view : views) {
|
||||
if (view.externalAPIScope.equals(externalAPIScope)) {
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all registered React views.
|
||||
*
|
||||
* @return An {@link ArrayList} containing all views currently held by React.
|
||||
*/
|
||||
static ArrayList<BaseReactView> getViews() {
|
||||
return new ArrayList<>(views);
|
||||
}
|
||||
|
||||
/**
|
||||
* The unique identifier of this {@code BaseReactView} within the process
|
||||
* for the purposes of {@link ExternalAPIModule}. The name scope was
|
||||
* inspired by postis which we use on Web for the similar purposes of the
|
||||
* iframe-based external API.
|
||||
*/
|
||||
protected String externalAPIScope;
|
||||
|
||||
/**
|
||||
* The listener (e.g. {@link JitsiMeetViewListener}) instance for reporting
|
||||
* events occurring in Jitsi Meet.
|
||||
*/
|
||||
@Deprecated
|
||||
private ListenerT listener;
|
||||
|
||||
/**
|
||||
* React Native root view.
|
||||
*/
|
||||
private ReactRootView reactRootView;
|
||||
|
||||
public BaseReactView(@NonNull Context context) {
|
||||
super(context);
|
||||
initialize((Activity)context);
|
||||
}
|
||||
|
||||
public BaseReactView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialize((Activity)context);
|
||||
}
|
||||
|
||||
public BaseReactView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initialize((Activity)context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the {@code ReactRootView} for the given app name with the given
|
||||
* props. Once created it's set as the view of this {@code FrameLayout}.
|
||||
*
|
||||
* @param appName - The name of the "app" (in React Native terms) to load.
|
||||
* @param props - The React Component props to pass to the app.
|
||||
*/
|
||||
public void createReactRootView(String appName, @Nullable Bundle props) {
|
||||
if (props == null) {
|
||||
props = new Bundle();
|
||||
}
|
||||
|
||||
props.putString("externalAPIScope", externalAPIScope);
|
||||
|
||||
if (reactRootView == null) {
|
||||
reactRootView = new ReactRootView(getContext());
|
||||
reactRootView.startReactApplication(
|
||||
ReactInstanceManagerHolder.getReactInstanceManager(),
|
||||
appName,
|
||||
props);
|
||||
reactRootView.setBackgroundColor(BACKGROUND_COLOR);
|
||||
addView(reactRootView);
|
||||
} else {
|
||||
reactRootView.setAppProperties(props);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the React resources (specifically the {@link ReactRootView})
|
||||
* associated with this view.
|
||||
*
|
||||
* MUST be called when the {@link Activity} holding this view is destroyed,
|
||||
* typically in the {@code onDestroy} method.
|
||||
*/
|
||||
public void dispose() {
|
||||
if (reactRootView != null) {
|
||||
removeView(reactRootView);
|
||||
reactRootView.unmountReactApplication();
|
||||
reactRootView = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the listener set on this {@code BaseReactView}.
|
||||
*
|
||||
* @return The listener set on this {@code BaseReactView}.
|
||||
*/
|
||||
@Deprecated
|
||||
public ListenerT getListener() {
|
||||
return listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract method called by {@link ExternalAPIModule} when an event is
|
||||
* received for this view.
|
||||
*
|
||||
* @param name - The name of the event.
|
||||
* @param data - The details of the event associated with/specific to the
|
||||
* specified {@code name}.
|
||||
*/
|
||||
@Deprecated
|
||||
protected abstract void onExternalAPIEvent(String name, ReadableMap data);
|
||||
|
||||
@Deprecated
|
||||
protected void onExternalAPIEvent(
|
||||
Map<String, Method> listenerMethods,
|
||||
String name, ReadableMap data) {
|
||||
ListenerT listener = getListener();
|
||||
|
||||
if (listener != null) {
|
||||
ListenerUtils.runListenerMethod(
|
||||
listener, listenerMethods, name, data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the window containing this view gains or loses focus.
|
||||
*
|
||||
* @param hasFocus If the window of this view now has focus, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
|
||||
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
|
||||
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
|
||||
|
||||
if (hasFocus && immersive != null) {
|
||||
immersive.emitImmersiveStateChangeEvent();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific listener on this {@code BaseReactView}.
|
||||
*
|
||||
* @param listener The listener to set on this {@code BaseReactView}.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setListener(ListenerT listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private void initialize(Activity activity) {
|
||||
setBackgroundColor(BACKGROUND_COLOR);
|
||||
|
||||
ReactInstanceManagerHolder.initReactInstanceManager(activity);
|
||||
|
||||
// Hook this BaseReactView into ExternalAPI.
|
||||
externalAPIScope = UUID.randomUUID().toString();
|
||||
synchronized (views) {
|
||||
views.add(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,37 +95,25 @@ 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatches an event that occurred on the JavaScript side of the SDK to
|
||||
* the specified {@link BaseReactView}'s listener.
|
||||
* the native side.
|
||||
*
|
||||
* @param name The name of the event.
|
||||
* @param data The details/specifics of the event to send determined
|
||||
* by/associated with the specified {@code name}.
|
||||
* @param scope
|
||||
*/
|
||||
@ReactMethod
|
||||
public void sendEvent(String name, ReadableMap data, String scope) {
|
||||
public void sendEvent(String name, ReadableMap data) {
|
||||
// Keep track of the current ongoing conference.
|
||||
OngoingConferenceTracker.getInstance().onExternalAPIEvent(name, data);
|
||||
|
||||
// The JavaScript App needs to provide uniquely identifying information
|
||||
// to the native ExternalAPI module so that the latter may match the
|
||||
// former to the native BaseReactView which hosts it.
|
||||
BaseReactView view = BaseReactView.findViewByExternalAPIScope(scope);
|
||||
|
||||
if (view != null) {
|
||||
JitsiMeetLogger.d(TAG + " Sending event: " + name + " with data: " + data);
|
||||
try {
|
||||
view.onExternalAPIEvent(name, data);
|
||||
broadcastEmitter.sendBroadcast(name, data);
|
||||
} catch (Exception e) {
|
||||
JitsiMeetLogger.e(e, TAG + " onExternalAPIEvent: error sending event");
|
||||
}
|
||||
}
|
||||
JitsiMeetLogger.d(TAG + " Sending event: " + name + " with data: " + data);
|
||||
broadcastEmitter.sendBroadcast(name, data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,12 +167,9 @@ public class JitsiMeetActivity extends AppCompatActivity
|
||||
}
|
||||
}
|
||||
|
||||
public void leave() {
|
||||
if (this.jitsiView != null) {
|
||||
this.jitsiView .leave();
|
||||
} else {
|
||||
JitsiMeetLogger.w("Cannot leave, view is null");
|
||||
}
|
||||
protected void leave() {
|
||||
Intent hangupBroadcastIntent = BroadcastIntentHelper.buildHangUpIntent();
|
||||
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(hangupBroadcastIntent);
|
||||
}
|
||||
|
||||
private @Nullable
|
||||
@@ -213,7 +210,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) {
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
* Copyright @ 2017-2018 Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
/**
|
||||
* Base {@link Fragment} for applications integrating Jitsi Meet at a higher level. It
|
||||
* contains all the required wiring between the {@code JitsiMeetView} and
|
||||
* the Fragment lifecycle methods already implemented.
|
||||
*
|
||||
* In this fragment we use a single {@code JitsiMeetView} instance. This
|
||||
* instance gives us access to a view which displays the welcome page and the
|
||||
* conference itself. All lifecycle methods associated with this Fragment are
|
||||
* hooked to the React Native subsystem via proxy calls through the
|
||||
* {@code JitsiMeetActivityDelegate} static methods.
|
||||
*
|
||||
* @deprecated use {@link JitsiMeetActivity} or directly {@link JitsiMeetView}
|
||||
*/
|
||||
@Deprecated
|
||||
public class JitsiMeetFragment extends Fragment {
|
||||
|
||||
/**
|
||||
* Instance of the {@link JitsiMeetView} which this activity will display.
|
||||
*/
|
||||
private JitsiMeetView view;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
return this.view = new JitsiMeetView(getActivity());
|
||||
}
|
||||
|
||||
public JitsiMeetView getJitsiView() {
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
JitsiMeetActivityDelegate.onHostDestroy(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
JitsiMeetActivityDelegate.onHostResume(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
|
||||
JitsiMeetActivityDelegate.onHostPause(getActivity());
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
public 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;
|
||||
|
||||
@@ -70,7 +80,7 @@ public class JitsiMeetOngoingConferenceService extends Service
|
||||
}
|
||||
}
|
||||
|
||||
static void abort(Context context) {
|
||||
public static void abort(Context context) {
|
||||
Intent intent = new Intent(context, JitsiMeetOngoingConferenceService.class);
|
||||
context.stopService(intent);
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,36 +16,33 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.ReactRootView;
|
||||
import com.rnimmersive.RNImmersiveModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
implements OngoingConferenceTracker.OngoingConferenceListener {
|
||||
public class JitsiMeetView extends FrameLayout {
|
||||
|
||||
/**
|
||||
* The {@code Method}s of {@code JitsiMeetViewListener} by event name i.e.
|
||||
* redux action types.
|
||||
* Background color used by {@code BaseReactView} and the React Native root
|
||||
* view.
|
||||
*/
|
||||
private static final Map<String, Method> LISTENER_METHODS
|
||||
= ListenerUtils.mapListenerMethods(JitsiMeetViewListener.class);
|
||||
private static final int BACKGROUND_COLOR = 0xFF111111;
|
||||
|
||||
/**
|
||||
* The URL of the current conference.
|
||||
* React Native root view.
|
||||
*/
|
||||
// XXX Currently, one thread writes and one thread reads, so it should be
|
||||
// fine to have this field volatile without additional synchronization.
|
||||
private volatile String url;
|
||||
private ReactRootView reactRootView;
|
||||
|
||||
/**
|
||||
* Helper method to recursively merge 2 {@link Bundle} objects representing React Native props.
|
||||
@@ -109,10 +106,19 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
initialize(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Releases the React resources (specifically the {@link ReactRootView})
|
||||
* associated with this view.
|
||||
*
|
||||
* MUST be called when the {@link Activity} holding this view is destroyed,
|
||||
* typically in the {@code onDestroy} method.
|
||||
*/
|
||||
public void dispose() {
|
||||
OngoingConferenceTracker.getInstance().removeListener(this);
|
||||
super.dispose();
|
||||
if (reactRootView != null) {
|
||||
removeView(reactRootView);
|
||||
reactRootView.unmountReactApplication();
|
||||
reactRootView = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,8 +136,7 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
PictureInPictureModule.class);
|
||||
if (pipModule != null
|
||||
&& pipModule.isPictureInPictureSupported()
|
||||
&& !JitsiMeetActivityDelegate.arePermissionsBeingRequested()
|
||||
&& this.url != null) {
|
||||
&& !JitsiMeetActivityDelegate.arePermissionsBeingRequested()) {
|
||||
try {
|
||||
pipModule.enterPictureInPicture();
|
||||
} catch (RuntimeException re) {
|
||||
@@ -151,10 +156,40 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaves the currently active conference.
|
||||
* Creates the {@code ReactRootView} for the given app name with the given
|
||||
* props. Once created it's set as the view of this {@code FrameLayout}.
|
||||
*
|
||||
* @param appName - The name of the "app" (in React Native terms) to load.
|
||||
* @param props - The React Component props to pass to the app.
|
||||
*/
|
||||
public void leave() {
|
||||
setProps(new Bundle());
|
||||
private void createReactRootView(String appName, @Nullable Bundle props) {
|
||||
if (props == null) {
|
||||
props = new Bundle();
|
||||
}
|
||||
|
||||
if (reactRootView == null) {
|
||||
reactRootView = new ReactRootView(getContext());
|
||||
reactRootView.startReactApplication(
|
||||
ReactInstanceManagerHolder.getReactInstanceManager(),
|
||||
appName,
|
||||
props);
|
||||
reactRootView.setBackgroundColor(BACKGROUND_COLOR);
|
||||
addView(reactRootView);
|
||||
} else {
|
||||
reactRootView.setAppProperties(props);
|
||||
}
|
||||
}
|
||||
|
||||
private void initialize(@NonNull Context context) {
|
||||
// Check if the parent Activity implements JitsiMeetActivityInterface,
|
||||
// otherwise things may go wrong.
|
||||
if (!(context instanceof JitsiMeetActivityInterface)) {
|
||||
throw new RuntimeException("Enclosing Activity must implement JitsiMeetActivityInterface");
|
||||
}
|
||||
|
||||
setBackgroundColor(BACKGROUND_COLOR);
|
||||
|
||||
ReactInstanceManagerHolder.initReactInstanceManager((Activity) context);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,46 +214,27 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
createReactRootView("App", props);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for {@link OngoingConferenceTracker} events.
|
||||
* @param conferenceUrl
|
||||
*/
|
||||
@Override
|
||||
public void onCurrentConferenceChanged(String conferenceUrl) {
|
||||
// This property was introduced in order to address
|
||||
// an exception in the Picture-in-Picture functionality which arose
|
||||
// because of delays related to bridging between JavaScript and Java. To
|
||||
// reduce these delays do not wait for the call to be transferred to the
|
||||
// UI thread.
|
||||
this.url = conferenceUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for {@link ExternalAPIModule} events.
|
||||
*
|
||||
* @param name The name of the event.
|
||||
* @param data The details/specifics of the event to send determined
|
||||
* by/associated with the specified {@code name}.
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
protected void onExternalAPIEvent(String name, ReadableMap data) {
|
||||
onExternalAPIEvent(LISTENER_METHODS, name, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
dispose();
|
||||
super.onDetachedFromWindow();
|
||||
}
|
||||
|
||||
private void initialize(@NonNull Context context) {
|
||||
// Check if the parent Activity implements JitsiMeetActivityInterface,
|
||||
// otherwise things may go wrong.
|
||||
if (!(context instanceof JitsiMeetActivityInterface)) {
|
||||
throw new RuntimeException("Enclosing Activity must implement JitsiMeetActivityInterface");
|
||||
}
|
||||
/**
|
||||
* Called when the window containing this view gains or loses focus.
|
||||
*
|
||||
* @param hasFocus If the window of this view now has focus, {@code true};
|
||||
* otherwise, {@code false}.
|
||||
*/
|
||||
@Override
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
|
||||
OngoingConferenceTracker.getInstance().addListener(this);
|
||||
// https://github.com/mockingbot/react-native-immersive#restore-immersive-state
|
||||
RNImmersiveModule immersive = RNImmersiveModule.getInstance();
|
||||
|
||||
if (hasFocus && immersive != null) {
|
||||
immersive.emitImmersiveStateChangeEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Interface for listening to events coming from Jitsi Meet.
|
||||
*/
|
||||
@Deprecated
|
||||
public interface JitsiMeetViewListener {
|
||||
/**
|
||||
* Called when a conference was joined.
|
||||
*
|
||||
* @param data Map with a "url" key with the conference URL.
|
||||
*/
|
||||
void onConferenceJoined(Map<String, Object> data);
|
||||
|
||||
/**
|
||||
* Called when the active conference ends, be it because of user choice or
|
||||
* because of a failure.
|
||||
*
|
||||
* @param data Map with an "error" key with the error and a "url" key with
|
||||
* the conference URL. If the conference finished gracefully no `error`
|
||||
* key will be present. The possible values for "error" are described here:
|
||||
* https://github.com/jitsi/lib-jitsi-meet/blob/master/JitsiConnectionErrors.js
|
||||
* https://github.com/jitsi/lib-jitsi-meet/blob/master/JitsiConferenceErrors.js
|
||||
*/
|
||||
void onConferenceTerminated(Map<String, Object> data);
|
||||
|
||||
/**
|
||||
* Called before the conference is joined.
|
||||
*
|
||||
* @param data Map with a "url" key with the conference URL.
|
||||
*/
|
||||
void onConferenceWillJoin(Map<String, Object> data);
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2018-present Atlassian Pty Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableMapKeySetIterator;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Utility methods for helping with transforming {@link ExternalAPIModule}
|
||||
* events into listener methods. Used with descendants of {@link BaseReactView}.
|
||||
*/
|
||||
@Deprecated
|
||||
public final class ListenerUtils {
|
||||
/**
|
||||
* Extracts the methods defined in a listener and creates a mapping of this
|
||||
* form: event name -> method.
|
||||
*
|
||||
* @param listener - The listener whose methods we want to slurp.
|
||||
* @return A mapping with event names - methods.
|
||||
*/
|
||||
public static Map<String, Method> mapListenerMethods(Class listener) {
|
||||
Map<String, Method> methods = new HashMap<>();
|
||||
|
||||
// Figure out the mapping between the listener methods
|
||||
// and the events i.e. redux action types.
|
||||
Pattern onPattern = Pattern.compile("^on[A-Z]+");
|
||||
Pattern camelcasePattern = Pattern.compile("([a-z0-9]+)([A-Z0-9]+)");
|
||||
|
||||
for (Method method : listener.getDeclaredMethods()) {
|
||||
// * The method must be public (because it is declared by an
|
||||
// interface).
|
||||
// * The method must be/return void.
|
||||
if (!Modifier.isPublic(method.getModifiers())
|
||||
|| !Void.TYPE.equals(method.getReturnType())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// * The method name must start with "on" followed by a
|
||||
// capital/uppercase letter (in agreement with the camelcase
|
||||
// coding style customary to Java in general and the projects of
|
||||
// the Jitsi community in particular).
|
||||
String name = method.getName();
|
||||
|
||||
if (!onPattern.matcher(name).find()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// * The method must accept/have exactly 1 parameter of a type
|
||||
// assignable from HashMap.
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
|
||||
if (parameterTypes.length != 1
|
||||
|| !parameterTypes[0].isAssignableFrom(HashMap.class)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Convert the method name to an event name.
|
||||
name
|
||||
= camelcasePattern.matcher(name.substring(2))
|
||||
.replaceAll("$1_$2")
|
||||
.toUpperCase(Locale.ROOT);
|
||||
methods.put(name, method);
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the right listener method for the given event.
|
||||
* NOTE: This function will run asynchronously on the UI thread.
|
||||
*
|
||||
* @param listener - The listener on which the method will be called.
|
||||
* @param listenerMethods - Mapping with event names and the matching
|
||||
* methods.
|
||||
* @param eventName - Name of the event.
|
||||
* @param eventData - Data associated with the event.
|
||||
*/
|
||||
public static void runListenerMethod(
|
||||
final Object listener,
|
||||
final Map<String, Method> listenerMethods,
|
||||
final String eventName,
|
||||
final ReadableMap eventData) {
|
||||
// Make sure listener methods are invoked on the UI thread. It
|
||||
// was requested by SDK consumers.
|
||||
if (UiThreadUtil.isOnUiThread()) {
|
||||
runListenerMethodOnUiThread(
|
||||
listener, listenerMethods, eventName, eventData);
|
||||
} else {
|
||||
UiThreadUtil.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runListenerMethodOnUiThread(
|
||||
listener, listenerMethods, eventName, eventData);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper companion for {@link ListenerUtils#runListenerMethod} which runs
|
||||
* in the UI thread.
|
||||
*/
|
||||
private static void runListenerMethodOnUiThread(
|
||||
Object listener,
|
||||
Map<String, Method> listenerMethods,
|
||||
String eventName,
|
||||
ReadableMap eventData) {
|
||||
UiThreadUtil.assertOnUiThread();
|
||||
|
||||
Method method = listenerMethods.get(eventName);
|
||||
if (method != null) {
|
||||
try {
|
||||
method.invoke(listener, toHashMap(eventData));
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new {@code HashMap} instance with the key-value
|
||||
* associations of a specific {@code ReadableMap}.
|
||||
*
|
||||
* @param readableMap the {@code ReadableMap} specifying the key-value
|
||||
* associations with which the new {@code HashMap} instance is to be
|
||||
* initialized.
|
||||
* @return a new {@code HashMap} instance initialized with the key-value
|
||||
* associations of the specified {@code readableMap}.
|
||||
*/
|
||||
private static HashMap<String, Object> toHashMap(ReadableMap readableMap) {
|
||||
HashMap<String, Object> hashMap = new HashMap<>();
|
||||
|
||||
for (ReadableMapKeySetIterator i = readableMap.keySetIterator();
|
||||
i.hasNextKey();) {
|
||||
String key = i.nextKey();
|
||||
|
||||
hashMap.put(key, readableMap.getString(key));
|
||||
}
|
||||
|
||||
return hashMap;
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,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,7 +84,7 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public void enterPictureInPicture() {
|
||||
if (isDisabled) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ class PictureInPictureModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void setPictureInPictureDisabled(Boolean disabled) {
|
||||
this.isDisabled = disabled;
|
||||
public void setPictureInPictureEnabled(Boolean enabled) {
|
||||
this.isEnabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isPictureInPictureSupported() {
|
||||
|
||||
3
android/sdk/src/main/res/values/styles.xml
Normal file
3
android/sdk/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<style name="JitsiMeetActivityStyle" parent="Theme.AppCompat.Light.NoActionBar"/>
|
||||
</resources>
|
||||
@@ -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'
|
||||
|
||||
158
conference.js
158
conference.js
@@ -54,7 +54,10 @@ import {
|
||||
sendLocalParticipant,
|
||||
nonParticipantMessageReceived
|
||||
} from './react/features/base/conference';
|
||||
import { getReplaceParticipant, getMultipleVideoSupportFeatureFlag } from './react/features/base/config/functions';
|
||||
import {
|
||||
getReplaceParticipant,
|
||||
getMultipleVideoSendingSupportFeatureFlag
|
||||
} from './react/features/base/config/functions';
|
||||
import {
|
||||
checkAndNotifyForNewDevice,
|
||||
getAvailableDevices,
|
||||
@@ -93,6 +96,7 @@ import {
|
||||
dominantSpeakerChanged,
|
||||
getLocalParticipant,
|
||||
getNormalizedDisplayName,
|
||||
getVirtualScreenshareParticipantByOwnerId,
|
||||
localParticipantAudioLevelChanged,
|
||||
localParticipantConnectionStatusChanged,
|
||||
localParticipantRoleChanged,
|
||||
@@ -102,6 +106,7 @@ import {
|
||||
participantPresenceChanged,
|
||||
participantRoleChanged,
|
||||
participantUpdated,
|
||||
screenshareParticipantDisplayNameChanged,
|
||||
updateRemoteParticipantFeatures
|
||||
} from './react/features/base/participants';
|
||||
import {
|
||||
@@ -918,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.
|
||||
@@ -971,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);
|
||||
}
|
||||
@@ -1466,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);
|
||||
@@ -1612,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));
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1707,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) {
|
||||
@@ -2258,6 +2310,15 @@ export default {
|
||||
id,
|
||||
name: formattedDisplayName
|
||||
}));
|
||||
|
||||
const virtualScreenshareParticipantId = getVirtualScreenshareParticipantByOwnerId(state, id)?.id;
|
||||
|
||||
if (virtualScreenshareParticipantId) {
|
||||
APP.store.dispatch(
|
||||
screenshareParticipantDisplayNameChanged(virtualScreenshareParticipantId, formattedDisplayName)
|
||||
);
|
||||
}
|
||||
|
||||
APP.API.notifyDisplayNameChanged(id, {
|
||||
displayName: formattedDisplayName,
|
||||
formattedDisplayName:
|
||||
@@ -2558,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);
|
||||
})
|
||||
@@ -2598,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);
|
||||
}
|
||||
|
||||
@@ -3042,34 +3094,12 @@ export default {
|
||||
* @param email {string} the new email
|
||||
*/
|
||||
changeLocalEmail(email = '') {
|
||||
const localParticipant = getLocalParticipant(APP.store.getState());
|
||||
|
||||
const formattedEmail = String(email).trim();
|
||||
|
||||
if (formattedEmail === localParticipant.email) {
|
||||
return;
|
||||
}
|
||||
|
||||
const localId = localParticipant.id;
|
||||
|
||||
APP.store.dispatch(participantUpdated({
|
||||
// XXX Only the local participant is allowed to update without
|
||||
// stating the JitsiConference instance (i.e. participant property
|
||||
// `conference` for a remote participant) because the local
|
||||
// participant is uniquely identified by the very fact that there is
|
||||
// only one local participant.
|
||||
|
||||
id: localId,
|
||||
local: true,
|
||||
email: formattedEmail
|
||||
}));
|
||||
|
||||
APP.store.dispatch(updateSettings({
|
||||
email: formattedEmail
|
||||
}));
|
||||
APP.API.notifyEmailChanged(localId, {
|
||||
email: formattedEmail
|
||||
});
|
||||
|
||||
sendData(commands.EMAIL, formattedEmail);
|
||||
},
|
||||
|
||||
@@ -3078,29 +3108,12 @@ export default {
|
||||
* @param url {string} the new url
|
||||
*/
|
||||
changeLocalAvatarUrl(url = '') {
|
||||
const { avatarURL, id } = getLocalParticipant(APP.store.getState());
|
||||
|
||||
const formattedUrl = String(url).trim();
|
||||
|
||||
if (formattedUrl === avatarURL) {
|
||||
return;
|
||||
}
|
||||
|
||||
APP.store.dispatch(participantUpdated({
|
||||
// XXX Only the local participant is allowed to update without
|
||||
// stating the JitsiConference instance (i.e. participant property
|
||||
// `conference` for a remote participant) because the local
|
||||
// participant is uniquely identified by the very fact that there is
|
||||
// only one local participant.
|
||||
|
||||
id,
|
||||
local: true,
|
||||
avatarURL: formattedUrl
|
||||
}));
|
||||
|
||||
APP.store.dispatch(updateSettings({
|
||||
avatarURL: formattedUrl
|
||||
}));
|
||||
|
||||
sendData(commands.AVATAR_URL, url);
|
||||
},
|
||||
|
||||
@@ -3141,23 +3154,6 @@ export default {
|
||||
*/
|
||||
changeLocalDisplayName(nickname = '') {
|
||||
const formattedNickname = getNormalizedDisplayName(nickname);
|
||||
const { id, name } = getLocalParticipant(APP.store.getState());
|
||||
|
||||
if (formattedNickname === name) {
|
||||
return;
|
||||
}
|
||||
|
||||
APP.store.dispatch(participantUpdated({
|
||||
// XXX Only the local participant is allowed to update without
|
||||
// stating the JitsiConference instance (i.e. participant property
|
||||
// `conference` for a remote participant) because the local
|
||||
// participant is uniquely identified by the very fact that there is
|
||||
// only one local participant.
|
||||
|
||||
id,
|
||||
local: true,
|
||||
name: formattedNickname
|
||||
}));
|
||||
|
||||
APP.store.dispatch(updateSettings({
|
||||
displayName: formattedNickname
|
||||
|
||||
197
config.js
197
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.
|
||||
@@ -133,6 +143,7 @@ var config = {
|
||||
|
||||
// Disable measuring of audio levels.
|
||||
// disableAudioLevels: false,
|
||||
|
||||
// audioLevelsInterval: 200,
|
||||
|
||||
// Enabling this will run the lib-jitsi-meet no audio detection module which
|
||||
@@ -261,8 +272,9 @@ var config = {
|
||||
|
||||
// Recording
|
||||
|
||||
// Whether to enable file recording or not.
|
||||
// DEPRECATED. Use recordingService.enabled instead.
|
||||
// fileRecordingsEnabled: false,
|
||||
|
||||
// Enable the dropbox integration.
|
||||
// dropbox: {
|
||||
// appKey: '<APP_KEY>' // Specify your app key here.
|
||||
@@ -272,38 +284,77 @@ var config = {
|
||||
// redirectURI:
|
||||
// 'https://jitsi-meet.example.com/subfolder/static/oauth.html'
|
||||
// },
|
||||
// When integrations like dropbox are enabled only that will be shown,
|
||||
// by enabling fileRecordingsServiceEnabled, we show both the integrations
|
||||
// and the generic recording service (its configuration and storage type
|
||||
// depends on jibri configuration)
|
||||
|
||||
// recordingService: {
|
||||
// // When integrations like dropbox are enabled only that will be shown,
|
||||
// // by enabling fileRecordingsServiceEnabled, we show both the integrations
|
||||
// // and the generic recording service (its configuration and storage type
|
||||
// // depends on jibri configuration)
|
||||
// enabled: false,
|
||||
|
||||
// // Whether to show the possibility to share file recording with other people
|
||||
// // (e.g. meeting participants), based on the actual implementation
|
||||
// // on the backend.
|
||||
// sharingEnabled: false,
|
||||
|
||||
// // Hide the warning that says we only store the recording for 24 hours.
|
||||
// hideStorageWarning: false
|
||||
// },
|
||||
|
||||
// DEPRECATED. Use recordingService.enabled instead.
|
||||
// fileRecordingsServiceEnabled: false,
|
||||
// Whether to show the possibility to share file recording with other people
|
||||
// (e.g. meeting participants), based on the actual implementation
|
||||
// on the backend.
|
||||
|
||||
// DEPRECATED. Use recordingService.sharingEnabled instead.
|
||||
// fileRecordingsServiceSharingEnabled: false,
|
||||
|
||||
// Whether to enable live streaming or not.
|
||||
// liveStreamingEnabled: false,
|
||||
|
||||
// Transcription (in interface_config,
|
||||
// subtitles and buttons can be configured)
|
||||
// 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
|
||||
// },
|
||||
|
||||
// DEPRECATED. Use transcription.enabled instead.
|
||||
// transcribingEnabled: false,
|
||||
|
||||
// If true transcriber will use the application language.
|
||||
// The application language is either explicitly set by participants in their settings or automatically
|
||||
// detected based on the environment, e.g. if the app is opened in a chrome instance which is using french as its
|
||||
// default language then transcriptions for that participant will be in french.
|
||||
// Defaults to true.
|
||||
// DEPRECATED. Use transcription.useAppLanguage instead.
|
||||
// transcribeWithAppLanguage: true,
|
||||
|
||||
// Transcriber language. This settings will only work if "transcribeWithAppLanguage" is explicitly set to false.
|
||||
// Available languages can be found in
|
||||
// ./src/react/features/transcribing/transcriber-langs.json.
|
||||
// DEPRECATED. Use transcription.preferredLanguage instead.
|
||||
// preferredTranscribeLanguage: 'en-US',
|
||||
|
||||
// Enables automatic turning on captions when recording is started
|
||||
// DEPRECATED. Use transcription.autoCaptionOnRecord instead.
|
||||
// autoCaptionOnRecord: false,
|
||||
|
||||
// Transcription options.
|
||||
// transcription: {
|
||||
// // Whether the feature should be enabled or not.
|
||||
// enabled: false,
|
||||
|
||||
// // If true transcriber will use the application language.
|
||||
// // The application language is either explicitly set by participants in their settings or automatically
|
||||
// // detected based on the environment, e.g. if the app is opened in a chrome instance which
|
||||
// // is using french as its default language then transcriptions for that participant will be in french.
|
||||
// // Defaults to true.
|
||||
// useAppLanguage: true,
|
||||
|
||||
// // Transcriber language. This settings will only work if "useAppLanguage"
|
||||
// // is explicitly set to false.
|
||||
// // Available languages can be found in
|
||||
// // ./src/react/features/transcribing/transcriber-langs.json.
|
||||
// preferredLanguage: 'en-US',
|
||||
|
||||
// // Disable start transcription for all participants.
|
||||
// disableStartForAll: false,
|
||||
|
||||
// // Enables automatic turning on captions when recording is started
|
||||
// autoCaptionOnRecord: false
|
||||
// },
|
||||
|
||||
// Misc
|
||||
|
||||
// Default value for the channel "last N" attribute. -1 for unlimited.
|
||||
@@ -365,7 +416,7 @@ var config = {
|
||||
// // This will result in Safari not being able to decode video from endpoints sending VP9 video.
|
||||
// // When set to false, the conference falls back to VP8 whenever there is an endpoint that doesn't support the
|
||||
// // preferred codec and goes back to the preferred codec when that endpoint leaves.
|
||||
// // enforcePreferredCodec: false,
|
||||
// enforcePreferredCodec: false,
|
||||
//
|
||||
// // Provides a way to configure the maximum bitrates that will be enforced on the simulcast streams for
|
||||
// // video tracks. The keys in the object represent the type of the stream (LD, SD or HD) and the values
|
||||
@@ -533,8 +584,8 @@ var config = {
|
||||
// enableFeaturesBasedOnToken: false,
|
||||
|
||||
// When enabled the password used for locking a room is restricted to up to the number of digits specified
|
||||
// roomPasswordNumberOfDigits: 10,
|
||||
// default: roomPasswordNumberOfDigits: false,
|
||||
// roomPasswordNumberOfDigits: 10,
|
||||
|
||||
// Message to show the users. Example: 'The service will be down for
|
||||
// maintenance at 01:00 AM GMT,
|
||||
@@ -549,6 +600,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 +631,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 +663,7 @@ var config = {
|
||||
// 'chat',
|
||||
// 'closedcaptions',
|
||||
// 'desktop',
|
||||
// 'dock-iframe'
|
||||
// 'download',
|
||||
// 'embedmeeting',
|
||||
// 'etherpad',
|
||||
@@ -612,8 +677,6 @@ var config = {
|
||||
// 'linktosalesforce',
|
||||
// 'livestreaming',
|
||||
// 'microphone',
|
||||
// 'mute-everyone',
|
||||
// 'mute-video-everyone',
|
||||
// 'participants-pane',
|
||||
// 'profile',
|
||||
// 'raisehand',
|
||||
@@ -627,6 +690,7 @@ var config = {
|
||||
// 'stats',
|
||||
// 'tileview',
|
||||
// 'toggle-camera',
|
||||
// 'undock-iframe',
|
||||
// 'videoquality',
|
||||
// '__end'
|
||||
// ],
|
||||
@@ -753,7 +817,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 +826,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 +913,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 +991,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 +1052,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 +1150,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 +1196,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',
|
||||
@@ -1133,7 +1206,8 @@ var config = {
|
||||
// 'transcribing',
|
||||
// 'video-quality',
|
||||
// 'insecure-room',
|
||||
// 'highlight-moment'
|
||||
// 'highlight-moment',
|
||||
// 'top-panel-toggle'
|
||||
// ]
|
||||
// },
|
||||
|
||||
@@ -1167,14 +1241,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 +1343,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 +1388,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,
|
||||
|
||||
@@ -1315,7 +1401,14 @@ var config = {
|
||||
|
||||
// // Disables the stage filmstrip
|
||||
// // (displaying multiple participants on stage besides the vertical filmstrip)
|
||||
// disableStageFilmstrip: false
|
||||
// disableStageFilmstrip: false,
|
||||
|
||||
// // Disables the top panel (only shown when a user is sharing their screen).
|
||||
// disableTopPanel: false,
|
||||
|
||||
// // The minimum number of participants that must be in the call for
|
||||
// // the top panel layout to be used.
|
||||
// minParticipantCountForTopPanel: 50
|
||||
// },
|
||||
|
||||
// Tile view related config options.
|
||||
|
||||
@@ -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,9 @@ 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
|
||||
} from './react/features/prejoin/actions';
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
/**
|
||||
@@ -81,12 +84,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 +101,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);
|
||||
|
||||
@@ -46,18 +46,12 @@
|
||||
}
|
||||
|
||||
.audio-preview > div:nth-child(2),
|
||||
.video-preview > div:nth-child(2),
|
||||
.reactions-menu-popup > div:nth-child(2) {
|
||||
.video-preview > div:nth-child(2) {
|
||||
margin-bottom: 4px;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.reactions-menu-popup > div:nth-child(2) {
|
||||
margin-bottom: 6px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* The following selectors keep the chat modal full-size anywhere between 100px
|
||||
* and 580px for desktop or 680px for mobile.
|
||||
|
||||
@@ -104,6 +104,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.reactions-menu-container {
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
|
||||
.reactions-animations-container {
|
||||
position: absolute;
|
||||
width: 20%;
|
||||
@@ -112,8 +116,7 @@
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.reactions-menu-popup-container,
|
||||
.reactions-menu-popup {
|
||||
.reactions-menu-popup-container {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -19,11 +19,34 @@
|
||||
font-size: 14px;
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
&.space-top {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.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 +63,7 @@
|
||||
border-radius: 4px;
|
||||
height: 40px;
|
||||
justify-content: center;
|
||||
width: 56px;
|
||||
width: 42px;
|
||||
}
|
||||
|
||||
.cloud-content-recording-icon-container {
|
||||
@@ -52,7 +75,7 @@
|
||||
}
|
||||
|
||||
.jitsi-recording-header {
|
||||
margin-bottom: 32px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.jitsi-content-recording-icon-container-with-switch {
|
||||
|
||||
@@ -60,3 +60,15 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.settings-button-small-icon-container {
|
||||
position: absolute;
|
||||
right: -4px;
|
||||
top: -3px;
|
||||
|
||||
& .settings-button-small-icon {
|
||||
position: relative;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
26
debian/jitsi-meet-tokens.postinst
vendored
26
debian/jitsi-meet-tokens.postinst
vendored
@@ -50,37 +50,15 @@ case "$1" in
|
||||
if [ -f "$PROSODY_HOST_CONFIG" ] ; then
|
||||
# search for the token auth, if this is not enabled this is the
|
||||
# first time we install tokens package and needs a config change
|
||||
if ! egrep -q '^\s*authentication\s*=\s*"token"' "$PROSODY_HOST_CONFIG"; then
|
||||
if ! egrep -q '^\s*authentication\s*=\s*"token" -- do not delete me' "$PROSODY_HOST_CONFIG"; then
|
||||
# enable tokens in prosody host config
|
||||
sed -i 's/--plugin_paths/plugin_paths/g' $PROSODY_HOST_CONFIG
|
||||
sed -i 's/authentication = "anonymous"/authentication = "token"/g' $PROSODY_HOST_CONFIG
|
||||
sed -i 's/ --allow_unencrypted_plain_auth/ allow_unencrypted_plain_auth/g' $PROSODY_HOST_CONFIG
|
||||
sed -i 's/authentication = "jitsi-anonymous" -- do not delete me/authentication = "token" -- do not delete me/g' $PROSODY_HOST_CONFIG
|
||||
sed -i "s/ --app_id=\"example_app_id\"/ app_id=\"$APP_ID\"/g" $PROSODY_HOST_CONFIG
|
||||
sed -i "s/ --app_secret=\"example_app_secret\"/ app_secret=\"$APP_SECRET\"/g" $PROSODY_HOST_CONFIG
|
||||
sed -i 's/ --modules_enabled = { "token_verification" }/ modules_enabled = { "token_verification" }/g' $PROSODY_HOST_CONFIG
|
||||
sed -i '/^\s*--\s*"token_verification"/ s/--\s*//' $PROSODY_HOST_CONFIG
|
||||
|
||||
# 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)
|
||||
if [ "$PR10_INSTALL_CHECK" = "installed" ] \
|
||||
|| [ "$PR10_INSTALL_CHECK" = "unpacked" ] \
|
||||
|| [ "$PRTRUNK_INSTALL_CHECK" = "installed" ] \
|
||||
|| [ "$PRTRUNK_INSTALL_CHECK" = "unpacked" ] \
|
||||
|| dpkg --compare-versions "$PR_VER_INSTALLED" lt "0.11" ; then
|
||||
sed -i 's/module:hook_global(/module:hook(/g' /usr/share/jitsi-meet/prosody-plugins/mod_auth_token.lua
|
||||
fi
|
||||
|
||||
if [ -x "/etc/init.d/prosody" ]; then
|
||||
invoke-rc.d prosody restart || true
|
||||
fi
|
||||
|
||||
2
debian/jitsi-meet-tokens.postrm
vendored
2
debian/jitsi-meet-tokens.postrm
vendored
@@ -37,7 +37,7 @@ case "$1" in
|
||||
APP_SECRET=$RET
|
||||
|
||||
# Revert prosody config
|
||||
sed -i 's/authentication = "token"/authentication = "anonymous"/g' $PROSODY_HOST_CONFIG
|
||||
sed -i 's/authentication = "token" -- do not delete me/authentication = "jitsi-anonymous" -- do not delete me/g' $PROSODY_HOST_CONFIG
|
||||
sed -i "s/ app_id=\"$APP_ID\"/ --app_id=\"example_app_id\"/g" $PROSODY_HOST_CONFIG
|
||||
sed -i "s/ app_secret=\"$APP_SECRET\"/ --app_secret=\"example_app_secret\"/g" $PROSODY_HOST_CONFIG
|
||||
sed -i '/^\s*"token_verification"/ s/"token_verification"/-- "token_verification"/' $PROSODY_HOST_CONFIG
|
||||
|
||||
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/
|
||||
|
||||
@@ -36,8 +36,7 @@ unlimited_jids = {
|
||||
}
|
||||
|
||||
VirtualHost "jitmeet.example.com"
|
||||
-- enabled = false -- Remove this line to enable this host
|
||||
authentication = "anonymous"
|
||||
authentication = "jitsi-anonymous" -- do not delete me
|
||||
-- Properties below are modified by jitsi-meet-tokens package config
|
||||
-- and authentication above is switched to "token"
|
||||
--app_id="example_app_id"
|
||||
@@ -137,3 +136,19 @@ 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";
|
||||
"muc_password_check";
|
||||
}
|
||||
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" }
|
||||
|
||||
@@ -73,6 +73,13 @@ server {
|
||||
alias /usr/share/jitsi-meet/libs/external_api.min.js;
|
||||
}
|
||||
|
||||
location = /_api/room-info {
|
||||
proxy_pass http://prosody/room-info?prefix=$prefix&$args;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header X-Forwarded-For $remote_addr;
|
||||
proxy_set_header Host $http_host;
|
||||
}
|
||||
|
||||
# ensure all static content can always be found first
|
||||
location ~ ^/(libs|css|static|images|fonts|lang|sounds|connection_optimization|.well-known)/(.*)$
|
||||
{
|
||||
@@ -156,6 +163,14 @@ server {
|
||||
rewrite ^/(.*)$ /xmpp-websocket;
|
||||
}
|
||||
|
||||
location ~ ^/([^/?&:'"]+)/_api/room-info {
|
||||
set $subdomain "$1.";
|
||||
set $subdir "$1/";
|
||||
set $prefix "$1";
|
||||
|
||||
rewrite ^/(.*)$ /_api/room-info;
|
||||
}
|
||||
|
||||
# Anything that didn't match above, and isn't a real file, assume it's a room name and redirect to /
|
||||
location ~ ^/([^/?&:'"]+)/(.*)$ {
|
||||
set $subdomain "$1.";
|
||||
|
||||
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();
|
||||
|
||||
@@ -144,7 +144,7 @@ var interfaceConfig = {
|
||||
RECENT_LIST_ENABLED: true,
|
||||
REMOTE_THUMBNAIL_RATIO: 1, // 1:1
|
||||
|
||||
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar', 'sounds' ],
|
||||
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar', 'sounds', 'more' ],
|
||||
|
||||
/**
|
||||
* Specify which sharing features should be displayed. If the value is not set
|
||||
|
||||
11
ios/Podfile
11
ios/Podfile
@@ -9,9 +9,9 @@ install! 'cocoapods', :deterministic_uuids => false
|
||||
target 'JitsiMeet' do
|
||||
project 'app/app.xcodeproj'
|
||||
|
||||
pod 'Firebase/Analytics', '~> 6.33.0'
|
||||
pod 'Firebase/Crashlytics', '~> 6.33.0'
|
||||
pod 'Firebase/DynamicLinks', '~> 6.33.0'
|
||||
pod 'Firebase/Analytics', '~> 8.0'
|
||||
pod 'Firebase/Crashlytics', '~> 8.0'
|
||||
pod 'Firebase/DynamicLinks', '~> 8.0'
|
||||
end
|
||||
|
||||
target 'JitsiMeetSDK' do
|
||||
@@ -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
|
||||
|
||||
623
ios/Podfile.lock
623
ios/Podfile.lock
@@ -13,58 +13,68 @@ 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)
|
||||
- Firebase/Analytics (6.33.0):
|
||||
- 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 (8.15.0):
|
||||
- Firebase/Core
|
||||
- Firebase/Core (6.33.0):
|
||||
- Firebase/Core (8.15.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (= 6.8.3)
|
||||
- Firebase/CoreOnly (6.33.0):
|
||||
- FirebaseCore (= 6.10.3)
|
||||
- Firebase/Crashlytics (6.33.0):
|
||||
- FirebaseAnalytics (~> 8.15.0)
|
||||
- Firebase/CoreOnly (8.15.0):
|
||||
- FirebaseCore (= 8.15.0)
|
||||
- Firebase/Crashlytics (8.15.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseCrashlytics (~> 4.6.1)
|
||||
- Firebase/DynamicLinks (6.33.0):
|
||||
- FirebaseCrashlytics (~> 8.15.0)
|
||||
- Firebase/DynamicLinks (8.15.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseDynamicLinks (~> 4.3.1)
|
||||
- FirebaseAnalytics (6.8.3):
|
||||
- FirebaseCore (~> 6.10)
|
||||
- FirebaseInstallations (~> 1.6)
|
||||
- GoogleAppMeasurement (= 6.8.3)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 6.7)
|
||||
- GoogleUtilities/Network (~> 6.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 6.7)"
|
||||
- nanopb (~> 1.30906.0)
|
||||
- FirebaseCore (6.10.3):
|
||||
- FirebaseCoreDiagnostics (~> 1.6)
|
||||
- GoogleUtilities/Environment (~> 6.7)
|
||||
- GoogleUtilities/Logger (~> 6.7)
|
||||
- FirebaseCoreDiagnostics (1.7.0):
|
||||
- GoogleDataTransport (~> 7.4)
|
||||
- GoogleUtilities/Environment (~> 6.7)
|
||||
- GoogleUtilities/Logger (~> 6.7)
|
||||
- nanopb (~> 1.30906.0)
|
||||
- FirebaseCrashlytics (4.6.2):
|
||||
- FirebaseCore (~> 6.10)
|
||||
- FirebaseInstallations (~> 1.6)
|
||||
- GoogleDataTransport (~> 7.2)
|
||||
- nanopb (~> 1.30906.0)
|
||||
- PromisesObjC (~> 1.2)
|
||||
- FirebaseDynamicLinks (4.3.1):
|
||||
- FirebaseCore (~> 6.10)
|
||||
- FirebaseInstallations (1.7.0):
|
||||
- FirebaseCore (~> 6.10)
|
||||
- GoogleUtilities/Environment (~> 6.7)
|
||||
- GoogleUtilities/UserDefaults (~> 6.7)
|
||||
- PromisesObjC (~> 1.2)
|
||||
- FirebaseDynamicLinks (~> 8.15.0)
|
||||
- FirebaseAnalytics (8.15.0):
|
||||
- FirebaseAnalytics/AdIdSupport (= 8.15.0)
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseAnalytics/AdIdSupport (8.15.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleAppMeasurement (= 8.15.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseCore (8.15.0):
|
||||
- FirebaseCoreDiagnostics (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Logger (~> 7.7)
|
||||
- FirebaseCoreDiagnostics (8.15.0):
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/Logger (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- FirebaseCrashlytics (8.15.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (~> 8.0)
|
||||
- GoogleDataTransport (~> 9.1)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (~> 2.30908.0)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- FirebaseDynamicLinks (8.15.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- FirebaseInstallations (8.15.0):
|
||||
- FirebaseCore (~> 8.0)
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- GoogleUtilities/UserDefaults (~> 7.7)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- fmt (6.2.1)
|
||||
- Giphy (2.1.20):
|
||||
- libwebp
|
||||
@@ -72,36 +82,52 @@ PODS:
|
||||
- Giphy (= 2.1.20)
|
||||
- React-Core
|
||||
- glog (0.3.5)
|
||||
- GoogleAppMeasurement (6.8.3):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 6.7)
|
||||
- GoogleUtilities/Network (~> 6.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 6.7)"
|
||||
- nanopb (~> 1.30906.0)
|
||||
- GoogleDataTransport (7.5.1):
|
||||
- nanopb (~> 1.30906.0)
|
||||
- GoogleAppMeasurement (8.15.0):
|
||||
- GoogleAppMeasurement/AdIdSupport (= 8.15.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleAppMeasurement/AdIdSupport (8.15.0):
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (= 8.15.0)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleAppMeasurement/WithoutAdIdSupport (8.15.0):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 7.7)
|
||||
- GoogleUtilities/MethodSwizzler (~> 7.7)
|
||||
- GoogleUtilities/Network (~> 7.7)
|
||||
- "GoogleUtilities/NSData+zlib (~> 7.7)"
|
||||
- nanopb (~> 2.30908.0)
|
||||
- GoogleDataTransport (9.1.4):
|
||||
- GoogleUtilities/Environment (~> 7.7)
|
||||
- nanopb (< 2.30910.0, >= 2.30908.0)
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleSignIn (6.0.2):
|
||||
- AppAuth (~> 1.4)
|
||||
- GTMAppAuth (~> 1.0)
|
||||
- GTMSessionFetcher/Core (~> 1.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
|
||||
- GoogleUtilities/AppDelegateSwizzler (7.7.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Environment (6.7.2):
|
||||
- PromisesObjC (~> 1.2)
|
||||
- GoogleUtilities/Logger (6.7.2):
|
||||
- GoogleUtilities/Environment (7.7.0):
|
||||
- PromisesObjC (< 3.0, >= 1.2)
|
||||
- GoogleUtilities/Logger (7.7.0):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/MethodSwizzler (6.7.2):
|
||||
- GoogleUtilities/MethodSwizzler (7.7.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network (6.7.2):
|
||||
- GoogleUtilities/Network (7.7.0):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (6.7.2)"
|
||||
- GoogleUtilities/Reachability (6.7.2):
|
||||
- "GoogleUtilities/NSData+zlib (7.7.0)"
|
||||
- GoogleUtilities/Reachability (7.7.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (6.7.2):
|
||||
- GoogleUtilities/UserDefaults (7.7.0):
|
||||
- GoogleUtilities/Logger
|
||||
- GTMAppAuth (1.2.2):
|
||||
- AppAuth/Core (~> 1.4)
|
||||
@@ -116,13 +142,13 @@ PODS:
|
||||
- libwebp/mux (1.2.1):
|
||||
- libwebp/demux
|
||||
- libwebp/webp (1.2.1)
|
||||
- nanopb (1.30906.0):
|
||||
- nanopb/decode (= 1.30906.0)
|
||||
- nanopb/encode (= 1.30906.0)
|
||||
- nanopb/decode (1.30906.0)
|
||||
- nanopb/encode (1.30906.0)
|
||||
- nanopb (2.30908.0):
|
||||
- nanopb/decode (= 2.30908.0)
|
||||
- nanopb/encode (= 2.30908.0)
|
||||
- nanopb/decode (2.30908.0)
|
||||
- nanopb/encode (2.30908.0)
|
||||
- ObjectiveDropboxOfficial (6.2.3)
|
||||
- PromisesObjC (1.2.12)
|
||||
- PromisesObjC (2.1.1)
|
||||
- RCT-Folly (2021.06.28.00-v2):
|
||||
- boost
|
||||
- DoubleConversion
|
||||
@@ -134,192 +160,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 +379,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):
|
||||
@@ -432,7 +467,7 @@ PODS:
|
||||
- React-Core
|
||||
- RNReanimated (1.13.4):
|
||||
- React-Core
|
||||
- RNScreens (3.10.1):
|
||||
- RNScreens (3.13.1):
|
||||
- React-Core
|
||||
- React-RCTImage
|
||||
- RNSound (0.11.1):
|
||||
@@ -453,9 +488,9 @@ DEPENDENCIES:
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
|
||||
- Firebase/Analytics (~> 6.33.0)
|
||||
- Firebase/Crashlytics (~> 6.33.0)
|
||||
- Firebase/DynamicLinks (~> 6.33.0)
|
||||
- Firebase/Analytics (~> 8.0)
|
||||
- Firebase/Crashlytics (~> 8.0)
|
||||
- Firebase/DynamicLinks (~> 8.0)
|
||||
- "giphy-react-native-sdk (from `../node_modules/@giphy/react-native-sdk`)"
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- ObjectiveDropboxOfficial (= 6.2.3)
|
||||
@@ -464,6 +499,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 +598,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,41 +698,42 @@ SPEC CHECKSUMS:
|
||||
boost: a7c83b31436843459a1961bfd74b96033dc77234
|
||||
CocoaLumberjack: b7e05132ff94f6ae4dfa9d5bce9141893a21d9da
|
||||
DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662
|
||||
FBLazyVector: f7b0632c6437e312acf6349288d9aa4cb6d59030
|
||||
FBReactNativeSpec: 0f4e1f4cfeace095694436e7c7fcc5bf4b03a0ff
|
||||
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
|
||||
FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193
|
||||
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
|
||||
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
|
||||
FirebaseCrashlytics: 1a747c9cc084a24dc6d9511c991db1cd078154eb
|
||||
FirebaseDynamicLinks: 6eac37d86910382eafb6315d952cc44c9e176094
|
||||
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2
|
||||
FBLazyVector: 2c76493a346ef8cacf1f442926a39f805fffec1f
|
||||
FBReactNativeSpec: 371350f24afa87b6aba606972ec959dcd4a95c9a
|
||||
Firebase: 5f8193dff4b5b7c5d5ef72ae54bb76c08e2b841d
|
||||
FirebaseAnalytics: 7761cbadb00a717d8d0939363eb46041526474fa
|
||||
FirebaseCore: 5743c5785c074a794d35f2fff7ecc254a91e08b1
|
||||
FirebaseCoreDiagnostics: 92e07a649aeb66352b319d43bdd2ee3942af84cb
|
||||
FirebaseCrashlytics: feb07e4e9187be3c23c6a846cce4824e5ce2dd0b
|
||||
FirebaseDynamicLinks: 1dc816ef789c5adac6fede0b46d11478175c70e4
|
||||
FirebaseInstallations: 40bd9054049b2eae9a2c38ef1c3dd213df3605cd
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
Giphy: b6d5087521d251bb8c99cdc0eb07bbdf86d142d5
|
||||
giphy-react-native-sdk: 7abccf2b52123a0f30ce99da895ab6288023680c
|
||||
glog: 85ecdd10ee8d8ec362ef519a6a45ff9aa27b2e85
|
||||
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
|
||||
GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833
|
||||
glog: 476ee3e89abb49e07f822b48323c51c57124b572
|
||||
GoogleAppMeasurement: 4c19f031220c72464d460c9daa1fb5d1acce958e
|
||||
GoogleDataTransport: 5fffe35792f8b96ec8d6775f5eccd83c998d5a3b
|
||||
GoogleSignIn: fd381840dbe7c1137aa6dc30849a5c3e070c034a
|
||||
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
|
||||
GoogleUtilities: e0913149f6b0625b553d70dae12b49fc62914fd1
|
||||
GTMAppAuth: ad5c2b70b9a8689e1a04033c9369c4915bfcbe89
|
||||
GTMSessionFetcher: 43748f93435c2aa068b1cbe39655aaf600652e91
|
||||
libwebp: 98a37e597e40bfdb4c911fc98f2c53d0b12d05fc
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
nanopb: a0ba3315591a9ae0a16a309ee504766e90db0c96
|
||||
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
|
||||
PromisesObjC: ab77feca74fa2823e7af4249b8326368e61014cb
|
||||
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 +744,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
|
||||
@@ -728,12 +767,12 @@ SPEC CHECKSUMS:
|
||||
RNGestureHandler: e5c7cab5f214503dcefd6b2b0cefb050e1f51c4a
|
||||
RNGoogleSignin: c4381751eefd73c552b923ba347a9bfc6f18771c
|
||||
RNReanimated: c1b56d030d1616239861534d9adb531f8cffab68
|
||||
RNScreens: 522705f2e5c9d27efb17f24aceb2bf8335bc7b8e
|
||||
RNScreens: 40a2cb40a02a609938137a1e0acfbf8fc9eebf19
|
||||
RNSound: 27e8268bdb0a1f191f219a33267f7e0445e8d62f
|
||||
RNSVG: ce9d996113475209013317e48b05c21ee988d42e
|
||||
RNWatch: 99637948ec9b5c9ec5a41920642594ad5ba07e80
|
||||
Yoga: d6b6a80659aa3e91aaba01d0012e7edcbedcbecd
|
||||
Yoga: 17cd9a50243093b547c1e539c749928dd68152da
|
||||
|
||||
PODFILE CHECKSUM: 2167362b8c8cacb433b763a9ae6c3f4b590190c7
|
||||
PODFILE CHECKSUM: 0e8826a5cb9ee147354a83321ecb3104132f510b
|
||||
|
||||
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>99.0.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>99.0.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>99.0.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>99.0.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
|
||||
|
||||
@@ -24,8 +24,14 @@
|
||||
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */ = {isa = PBXBuildFile; fileRef = 0BD906E81EC0C00300C8C18E /* JitsiMeet.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */ = {isa = PBXBuildFile; fileRef = 4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */; };
|
||||
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */; };
|
||||
4EBA6E61286072E300B31882 /* JitsiMeetViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */; };
|
||||
4EBA6E62286072E300B31882 /* JitsiMeetViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */; };
|
||||
4EBA6E652860B1E800B31882 /* JitsiMeetRenderingView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */; };
|
||||
4EBA6E662860B1E800B31882 /* JitsiMeetRenderingView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */; };
|
||||
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */; };
|
||||
4EEC9630286C73A2008705FA /* JitsiMeetView+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */; };
|
||||
4EEC9631286C73A2008705FA /* JitsiMeetView+Private.m in Sources */ = {isa = PBXBuildFile; fileRef = 4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */; };
|
||||
6F08DF7D4458EE3CF3F36F6D /* libPods-JitsiMeetSDK.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E4376CA6886DE68FD7A4294B /* libPods-JitsiMeetSDK.a */; };
|
||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */ = {isa = PBXBuildFile; fileRef = A4A934E8212F3ADB001E9388 /* Dropbox.m */; };
|
||||
C6245F5D2053091D0040BE68 /* image-resize@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = C6245F5B2053091D0040BE68 /* image-resize@2x.png */; };
|
||||
@@ -79,9 +85,15 @@
|
||||
0BD906E91EC0C00300C8C18E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
4E51B76225E5345E0038575A /* ScheenshareEventEmiter.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScheenshareEventEmiter.h; sourceTree = "<group>"; };
|
||||
4E51B76325E5345E0038575A /* ScheenshareEventEmiter.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScheenshareEventEmiter.m; sourceTree = "<group>"; };
|
||||
4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetViewController.h; sourceTree = "<group>"; };
|
||||
4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetViewController.m; sourceTree = "<group>"; };
|
||||
4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiMeetRenderingView.h; sourceTree = "<group>"; };
|
||||
4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiMeetRenderingView.m; sourceTree = "<group>"; };
|
||||
4ED4FFF12721B9B90074E620 /* JitsiAudioSession.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JitsiAudioSession.h; sourceTree = "<group>"; };
|
||||
4ED4FFF22721B9B90074E620 /* JitsiAudioSession.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JitsiAudioSession.m; sourceTree = "<group>"; };
|
||||
4ED4FFF52721BAE10074E620 /* JitsiAudioSession+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiAudioSession+Private.h"; sourceTree = "<group>"; };
|
||||
4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
|
||||
4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "JitsiMeetView+Private.m"; sourceTree = "<group>"; };
|
||||
891FE43DAD30BC8976683100 /* Pods-JitsiMeetSDK.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeetSDK.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeetSDK/Pods-JitsiMeetSDK.release.xcconfig"; sourceTree = "<group>"; };
|
||||
98E09B5C73D9036B4ED252FC /* Pods-JitsiMeet.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.debug.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
9C77CA3CC919B081F1A52982 /* Pods-JitsiMeet.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-JitsiMeet.release.xcconfig"; path = "../Pods/Target Support Files/Pods-JitsiMeet/Pods-JitsiMeet.release.xcconfig"; sourceTree = "<group>"; };
|
||||
@@ -94,7 +106,6 @@
|
||||
C69EFA0B209A0F660027712B /* JMCallKitListener.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JMCallKitListener.swift; sourceTree = "<group>"; };
|
||||
C6A3425E204EF76800E062DD /* DragGestureController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DragGestureController.swift; sourceTree = "<group>"; };
|
||||
C6CC49AE207412CF000DFA42 /* PiPViewCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PiPViewCoordinator.swift; sourceTree = "<group>"; };
|
||||
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JitsiMeetView+Private.h"; sourceTree = "<group>"; };
|
||||
C81E9AB825AC5AD800B134D9 /* ExternalAPI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ExternalAPI.h; sourceTree = "<group>"; };
|
||||
C8AFD27D2462C613000293D2 /* InfoPlistUtil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InfoPlistUtil.h; sourceTree = "<group>"; };
|
||||
C8AFD27E2462C613000293D2 /* InfoPlistUtil.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InfoPlistUtil.m; sourceTree = "<group>"; };
|
||||
@@ -194,12 +205,17 @@
|
||||
DE65AACB2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h */,
|
||||
DE81A2DD2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m */,
|
||||
0B412F161EDEC65D00B1A0A6 /* JitsiMeetView.h */,
|
||||
4EEC962E286C73A2008705FA /* JitsiMeetView+Private.h */,
|
||||
4EEC962F286C73A2008705FA /* JitsiMeetView+Private.m */,
|
||||
0B412F171EDEC65D00B1A0A6 /* JitsiMeetView.m */,
|
||||
4EBA6E632860B1E800B31882 /* JitsiMeetRenderingView.h */,
|
||||
4EBA6E642860B1E800B31882 /* JitsiMeetRenderingView.m */,
|
||||
4EBA6E5F286072E300B31882 /* JitsiMeetViewController.h */,
|
||||
4EBA6E60286072E300B31882 /* JitsiMeetViewController.m */,
|
||||
DE81A2D72316AC7600AE1940 /* LogBridge.m */,
|
||||
DE65AAC92317FFCD00290BEC /* LogUtils.h */,
|
||||
DEAFA777229EAD3B0033A7FA /* RNRootView.h */,
|
||||
DEAFA778229EAD520033A7FA /* RNRootView.m */,
|
||||
C6F99C13204DB63D0001F710 /* JitsiMeetView+Private.h */,
|
||||
0B412F1B1EDEC80100B1A0A6 /* JitsiMeetViewDelegate.h */,
|
||||
DEFC743D21B178FA00E4DD96 /* LocaleDetector.m */,
|
||||
C6A3426B204F127900E062DD /* picture-in-picture */,
|
||||
@@ -284,11 +300,14 @@
|
||||
DEA9F284258A5D9900D4CD74 /* JitsiMeetSDK.h in Headers */,
|
||||
4E51B76425E5345E0038575A /* ScheenshareEventEmiter.h in Headers */,
|
||||
DE65AACC2318028300290BEC /* JitsiMeetBaseLogHandler+Private.h in Headers */,
|
||||
4EBA6E652860B1E800B31882 /* JitsiMeetRenderingView.h in Headers */,
|
||||
0B412F221EDEF6EA00B1A0A6 /* JitsiMeetViewDelegate.h in Headers */,
|
||||
4ED4FFF32721B9B90074E620 /* JitsiAudioSession.h in Headers */,
|
||||
4EEC9630286C73A2008705FA /* JitsiMeetView+Private.h in Headers */,
|
||||
0BD906EA1EC0C00300C8C18E /* JitsiMeet.h in Headers */,
|
||||
DE81A2D42316AC4D00AE1940 /* JitsiMeetLogger.h in Headers */,
|
||||
DE65AACA2317FFCD00290BEC /* LogUtils.h in Headers */,
|
||||
4EBA6E61286072E300B31882 /* JitsiMeetViewController.h in Headers */,
|
||||
DEAD3226220C497000E93636 /* JitsiMeetConferenceOptions.h in Headers */,
|
||||
C81E9AB925AC5AD800B134D9 /* ExternalAPI.h in Headers */,
|
||||
C8AFD27F2462C613000293D2 /* InfoPlistUtil.h in Headers */,
|
||||
@@ -449,6 +468,7 @@
|
||||
files = (
|
||||
0BB9AD7B1F5EC8F4001C08DB /* CallKit.m in Sources */,
|
||||
DE81A2DF2317ED5400AE1940 /* JitsiMeetBaseLogHandler.m in Sources */,
|
||||
4EBA6E662860B1E800B31882 /* JitsiMeetRenderingView.m in Sources */,
|
||||
4ED4FFF42721B9B90074E620 /* JitsiAudioSession.m in Sources */,
|
||||
0BB9AD7D1F60356D001C08DB /* AppInfo.m in Sources */,
|
||||
DE81A2D92316AC7600AE1940 /* LogBridge.m in Sources */,
|
||||
@@ -465,9 +485,11 @@
|
||||
0BCA49611EC4B6C600B793EE /* Proximity.m in Sources */,
|
||||
C69EFA0C209A0F660027712B /* JMCallKitEmitter.swift in Sources */,
|
||||
DEFE535621FB2E8300011A3A /* ReactUtils.m in Sources */,
|
||||
4EEC9631286C73A2008705FA /* JitsiMeetView+Private.m in Sources */,
|
||||
C6A34261204EF76800E062DD /* DragGestureController.swift in Sources */,
|
||||
4E51B76525E5345E0038575A /* ScheenshareEventEmiter.m in Sources */,
|
||||
A4A934E9212F3ADB001E9388 /* Dropbox.m in Sources */,
|
||||
4EBA6E62286072E300B31882 /* JitsiMeetViewController.m in Sources */,
|
||||
C69EFA0D209A0F660027712B /* JMCallKitProxy.swift in Sources */,
|
||||
DE81A2D52316AC4D00AE1940 /* JitsiMeetLogger.m in Sources */,
|
||||
C69EFA0E209A0F660027712B /* JMCallKitListener.swift in Sources */,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
static NSString * const sendEventNotificationName = @"org.jitsi.meet.SendEvent";
|
||||
|
||||
@interface ExternalAPI : RCTEventEmitter<RCTBridgeModule>
|
||||
|
||||
- (void)sendHangUp;
|
||||
@@ -27,5 +29,6 @@
|
||||
- (void)closeChat;
|
||||
- (void)sendChatMessage:(NSString*)message :(NSString*)to ;
|
||||
- (void)sendSetVideoMuted:(BOOL)muted;
|
||||
- (void)sendSetClosedCaptionsEnabled:(BOOL)enabled;
|
||||
|
||||
@end
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
|
||||
#import "ExternalAPI.h"
|
||||
#import "JitsiMeetView+Private.h"
|
||||
|
||||
// Events
|
||||
static NSString * const hangUpAction = @"org.jitsi.meet.HANG_UP";
|
||||
@@ -27,6 +26,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 +49,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 +74,8 @@ RCT_EXPORT_MODULE();
|
||||
openChatAction,
|
||||
closeChatAction,
|
||||
sendChatMessageAction,
|
||||
setVideoMutedAction
|
||||
setVideoMutedAction,
|
||||
setClosedCaptionsEnabledAction
|
||||
];
|
||||
}
|
||||
|
||||
@@ -86,33 +88,15 @@ RCT_EXPORT_MODULE();
|
||||
* @param scope
|
||||
*/
|
||||
RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
||||
data:(NSDictionary *)data
|
||||
scope:(NSString *)scope) {
|
||||
// The JavaScript App needs to provide uniquely identifying information to
|
||||
// the native ExternalAPI module so that the latter may match the former
|
||||
// to the native JitsiMeetView which hosts it.
|
||||
JitsiMeetView *view = [JitsiMeetView viewForExternalAPIScope:scope];
|
||||
|
||||
if (!view) {
|
||||
return;
|
||||
}
|
||||
|
||||
id delegate = view.delegate;
|
||||
|
||||
if (!delegate) {
|
||||
return;
|
||||
}
|
||||
|
||||
data:(NSDictionary *)data) {
|
||||
if ([name isEqual: @"PARTICIPANTS_INFO_RETRIEVED"]) {
|
||||
[self onParticipantsInfoRetrieved: data];
|
||||
return;
|
||||
}
|
||||
|
||||
SEL sel = NSSelectorFromString([self methodNameFromEventName:name]);
|
||||
|
||||
if (sel && [delegate respondsToSelector:sel]) {
|
||||
[delegate performSelector:sel withObject:data];
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:sendEventNotificationName
|
||||
object:nil
|
||||
userInfo:@{@"name": name, @"data": data}];
|
||||
}
|
||||
|
||||
- (void) onParticipantsInfoRetrieved:(NSDictionary *)data {
|
||||
@@ -124,28 +108,6 @@ RCT_EXPORT_METHOD(sendEvent:(NSString *)name
|
||||
[participantInfoCompletionHandlers removeObjectForKey:completionHandlerId];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a specific event name i.e. redux action type description to a
|
||||
* method name.
|
||||
*
|
||||
* @param eventName The event name to convert to a method name.
|
||||
* @return A method name constructed from the specified `eventName`.
|
||||
*/
|
||||
- (NSString *)methodNameFromEventName:(NSString *)eventName {
|
||||
NSMutableString *methodName
|
||||
= [NSMutableString stringWithCapacity:eventName.length];
|
||||
|
||||
for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
|
||||
if (c.length) {
|
||||
[methodName appendString:
|
||||
methodName.length ? c.capitalizedString : c.lowercaseString];
|
||||
}
|
||||
}
|
||||
[methodName appendString:@":"];
|
||||
|
||||
return methodName;
|
||||
}
|
||||
|
||||
- (void)sendHangUp {
|
||||
[self sendEventWithName:hangUpAction body:nil];
|
||||
}
|
||||
@@ -205,5 +167,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>99.0.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
|
||||
#import <Intents/Intents.h>
|
||||
#import <RNGoogleSignin/RNGoogleSignin.h>
|
||||
#import <WebRTC/RTCLogging.h>
|
||||
|
||||
#import "Dropbox.h"
|
||||
#import "JitsiMeet+Private.h"
|
||||
@@ -25,9 +27,6 @@
|
||||
#import "RNSplashScreen.h"
|
||||
#import "ScheenshareEventEmiter.h"
|
||||
|
||||
#import <RNGoogleSignin/RNGoogleSignin.h>
|
||||
#import <WebRTC/RTCLogging.h>
|
||||
|
||||
@implementation JitsiMeet {
|
||||
RCTBridgeWrapper *_bridgeWrapper;
|
||||
NSDictionary *_launchOptions;
|
||||
@@ -87,8 +86,12 @@
|
||||
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *))restorationHandler {
|
||||
|
||||
JitsiMeetConferenceOptions *options = [self optionsFromUserActivity:userActivity];
|
||||
if (options) {
|
||||
[JitsiMeetView updateProps:[options asProps]];
|
||||
return true;
|
||||
}
|
||||
|
||||
return options && [JitsiMeetView setPropsInViews:[options asProps]];
|
||||
return false;
|
||||
}
|
||||
|
||||
- (BOOL)application:(UIApplication *)app
|
||||
@@ -112,8 +115,9 @@
|
||||
JitsiMeetConferenceOptions *conferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
|
||||
builder.room = [url absoluteString];
|
||||
}];
|
||||
[JitsiMeetView updateProps:[conferenceOptions asProps]];
|
||||
|
||||
return [JitsiMeetView setPropsInViews:[conferenceOptions asProps]];
|
||||
return true;
|
||||
}
|
||||
|
||||
#pragma mark - Utility methods
|
||||
|
||||
30
ios/sdk/src/JitsiMeetRenderingView.h
Normal file
30
ios/sdk/src/JitsiMeetRenderingView.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright @ 2022-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "JitsiMeetViewDelegate.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface JitsiMeetRenderingView : UIView
|
||||
|
||||
@property (nonatomic, assign) BOOL isPiPEnabled;
|
||||
|
||||
- (void)setProps:(NSDictionary *_Nonnull)newProps;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
83
ios/sdk/src/JitsiMeetRenderingView.m
Normal file
83
ios/sdk/src/JitsiMeetRenderingView.m
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright @ 2022-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <mach/mach_time.h>
|
||||
|
||||
#import "JitsiMeetRenderingView.h"
|
||||
#import "ReactUtils.h"
|
||||
#import "RNRootView.h"
|
||||
#import "JitsiMeet+Private.h"
|
||||
|
||||
/**
|
||||
* Backwards compatibility: turn the boolean prop into a feature flag.
|
||||
*/
|
||||
static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
|
||||
|
||||
@interface JitsiMeetRenderingView ()
|
||||
@end
|
||||
|
||||
@implementation JitsiMeetRenderingView {
|
||||
/**
|
||||
* React Native view where the entire content will be rendered.
|
||||
*/
|
||||
RNRootView *rootView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes the given props to the React Native application. The props which we pass
|
||||
* are a combination of 3 different sources:
|
||||
*
|
||||
* - JitsiMeet.defaultConferenceOptions
|
||||
* - This function's parameters
|
||||
* - Some extras which are added by this function
|
||||
*/
|
||||
- (void)setProps:(NSDictionary *_Nonnull)newProps {
|
||||
NSMutableDictionary *props = mergeProps([[JitsiMeet sharedInstance] getDefaultProps], newProps);
|
||||
|
||||
// Set the PiP flag if it wasn't manually set.
|
||||
NSMutableDictionary *featureFlags = props[@"flags"];
|
||||
// TODO: temporary implementation
|
||||
if (featureFlags[PiPEnabledFeatureFlag] == nil) {
|
||||
featureFlags[PiPEnabledFeatureFlag] = @(self.isPiPEnabled);
|
||||
}
|
||||
|
||||
// This method is supposed to be imperative i.e. a second
|
||||
// invocation with one and the same URL is expected to join the respective
|
||||
// conference again if the first invocation was followed by leaving the
|
||||
// conference. However, React and, respectively,
|
||||
// appProperties/initialProperties are declarative expressions i.e. one and
|
||||
// the same URL will not trigger an automatic re-render in the JavaScript
|
||||
// source code. The workaround implemented below introduces imperativeness
|
||||
// in React Component props by defining a unique value per invocation.
|
||||
props[@"timestamp"] = @(mach_absolute_time());
|
||||
|
||||
if (rootView) {
|
||||
// Update props with the new URL.
|
||||
rootView.appProperties = props;
|
||||
} else {
|
||||
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
|
||||
rootView = [[RNRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"App"
|
||||
initialProperties:props];
|
||||
rootView.backgroundColor = self.backgroundColor;
|
||||
|
||||
// Add rootView as a subview which completely covers this one.
|
||||
[rootView setFrame:[self bounds]];
|
||||
rootView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
[self addSubview:rootView];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright @ 2018-present 8x8, Inc.
|
||||
* Copyright @ 2017-2018 Atlassian Pty Ltd
|
||||
* Copyright @ 2022-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -15,11 +14,16 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "JitsiMeetView.h"
|
||||
#import <JitsiMeetSDK/JitsiMeetSDK.h>
|
||||
|
||||
@interface JitsiMeetView ()
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
+ (instancetype _Nullable)viewForExternalAPIScope:(NSString *_Nonnull)externalAPIScope;
|
||||
+ (BOOL)setPropsInViews:(NSDictionary *_Nonnull)newProps;
|
||||
static NSString * const updateViewPropsNotificationName = @"org.jitsi.meet.UpdateViewProps";
|
||||
|
||||
@interface JitsiMeetView (Private)
|
||||
|
||||
+ (void)updateProps:(NSDictionary *_Nonnull)newProps;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
25
ios/sdk/src/JitsiMeetView+Private.m
Normal file
25
ios/sdk/src/JitsiMeetView+Private.m
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright @ 2022-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "JitsiMeetView+Private.h"
|
||||
|
||||
@implementation JitsiMeetView (Private)
|
||||
|
||||
+ (void)updateProps:(NSDictionary *_Nonnull)newProps {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:updateViewPropsNotificationName object:nil userInfo:@{@"props": newProps}];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -45,5 +45,6 @@
|
||||
- (void)closeChat;
|
||||
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
|
||||
- (void)setVideoMuted:(BOOL)muted;
|
||||
- (void)setClosedCaptionsEnabled:(BOOL)enabled;
|
||||
|
||||
@end
|
||||
|
||||
@@ -20,43 +20,22 @@
|
||||
#import "ExternalAPI.h"
|
||||
#import "JitsiMeet+Private.h"
|
||||
#import "JitsiMeetConferenceOptions+Private.h"
|
||||
#import "JitsiMeetView+Private.h"
|
||||
#import "JitsiMeetView.h"
|
||||
#import "JitsiMeetViewController.h"
|
||||
#import "ReactUtils.h"
|
||||
#import "RNRootView.h"
|
||||
|
||||
@interface JitsiMeetView ()
|
||||
|
||||
/**
|
||||
* Backwards compatibility: turn the boolean prop into a feature flag.
|
||||
*/
|
||||
static NSString *const PiPEnabledFeatureFlag = @"pip.enabled";
|
||||
@property (nonatomic, strong) JitsiMeetViewController *jitsiMeetViewController;
|
||||
@property (nonatomic, strong) UINavigationController *navController;
|
||||
@property (nonatomic, readonly) BOOL isPiPEnabled;
|
||||
|
||||
@end
|
||||
|
||||
@implementation JitsiMeetView {
|
||||
/**
|
||||
* The unique identifier of this `JitsiMeetView` within the process for the
|
||||
* purposes of `ExternalAPI`. The name scope was inspired by postis which we
|
||||
* use on Web for the similar purposes of the iframe-based external API.
|
||||
*/
|
||||
NSString *externalAPIScope;
|
||||
@implementation JitsiMeetView
|
||||
|
||||
/**
|
||||
* React Native view where the entire content will be rendered.
|
||||
*/
|
||||
RNRootView *rootView;
|
||||
}
|
||||
|
||||
/**
|
||||
* The `JitsiMeetView`s associated with their `ExternalAPI` scopes (i.e. unique
|
||||
* identifiers within the process).
|
||||
*/
|
||||
static NSMapTable<NSString *, JitsiMeetView *> *views;
|
||||
/**
|
||||
* This gets called automagically when the program starts.
|
||||
*/
|
||||
__attribute__((constructor))
|
||||
static void initializeViewsMap() {
|
||||
views = [NSMapTable strongToWeakObjectsMapTable];
|
||||
}
|
||||
@dynamic isPiPEnabled;
|
||||
|
||||
#pragma mark Initializers
|
||||
|
||||
@@ -87,6 +66,10 @@ static void initializeViewsMap() {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal initialization:
|
||||
*
|
||||
@@ -94,145 +77,105 @@ static void initializeViewsMap() {
|
||||
* - initializes the external API scope
|
||||
*/
|
||||
- (void)initWithXXX {
|
||||
// Hook this JitsiMeetView into ExternalAPI.
|
||||
externalAPIScope = [NSUUID UUID].UUIDString;
|
||||
[views setObject:self forKey:externalAPIScope];
|
||||
|
||||
// Set a background color which is in accord with the JavaScript and Android
|
||||
// parts of the application and causes less perceived visual flicker than
|
||||
// the default background color.
|
||||
self.backgroundColor
|
||||
= [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
|
||||
self.jitsiMeetViewController = [[JitsiMeetViewController alloc] init];
|
||||
self.jitsiMeetViewController.view.frame = [self bounds];
|
||||
[self addSubview:self.jitsiMeetViewController.view];
|
||||
|
||||
[self registerObservers];
|
||||
}
|
||||
|
||||
#pragma mark API
|
||||
|
||||
- (void)join:(JitsiMeetConferenceOptions *)options {
|
||||
[self setProps:options == nil ? @{} : [options asProps]];
|
||||
[self.jitsiMeetViewController join:options withPiP:self.isPiPEnabled];
|
||||
}
|
||||
|
||||
- (void)leave {
|
||||
[self setProps:@{}];
|
||||
[self.jitsiMeetViewController leave];
|
||||
}
|
||||
|
||||
- (void)hangUp {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendHangUp];
|
||||
[self.jitsiMeetViewController hangUp];
|
||||
}
|
||||
|
||||
- (void)setAudioMuted:(BOOL)muted {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendSetAudioMuted:muted];
|
||||
[self.jitsiMeetViewController setAudioMuted:muted];
|
||||
}
|
||||
|
||||
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendEndpointTextMessage:message :to];
|
||||
[self.jitsiMeetViewController sendEndpointTextMessage:message :to];
|
||||
}
|
||||
|
||||
- (void)toggleScreenShare:(BOOL)enabled {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI toggleScreenShare:enabled];
|
||||
[self.jitsiMeetViewController toggleScreenShare:enabled];
|
||||
}
|
||||
|
||||
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI retrieveParticipantsInfo:completionHandler];
|
||||
[self.jitsiMeetViewController retrieveParticipantsInfo:completionHandler];
|
||||
}
|
||||
|
||||
- (void)openChat:(NSString*)to {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI openChat:to];
|
||||
[self.jitsiMeetViewController openChat:to];
|
||||
}
|
||||
|
||||
- (void)closeChat {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI closeChat];
|
||||
[self.jitsiMeetViewController closeChat];
|
||||
}
|
||||
|
||||
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendChatMessage:message :to];
|
||||
[self.jitsiMeetViewController sendChatMessage:message :to];
|
||||
}
|
||||
|
||||
- (void)setVideoMuted:(BOOL)muted {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendSetVideoMuted:muted];
|
||||
[self.jitsiMeetViewController setVideoMuted:muted];
|
||||
}
|
||||
|
||||
#pragma mark Private methods
|
||||
- (void)setClosedCaptionsEnabled:(BOOL)enabled {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendSetClosedCaptionsEnabled:enabled];
|
||||
}
|
||||
|
||||
#pragma mark Private
|
||||
|
||||
- (BOOL)isPiPEnabled {
|
||||
return self.delegate && [self.delegate respondsToSelector:@selector(enterPictureInPicture:)];
|
||||
}
|
||||
|
||||
- (void)registerObservers {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleSendEventNotification:) name:sendEventNotificationName object:nil];
|
||||
}
|
||||
|
||||
- (void)handleSendEventNotification:(NSNotification *)notification {
|
||||
NSString *eventName = notification.userInfo[@"name"];
|
||||
NSString *eventData = notification.userInfo[@"data"];
|
||||
|
||||
SEL sel = NSSelectorFromString([self methodNameFromEventName:eventName]);
|
||||
|
||||
if (sel && [self.delegate respondsToSelector:sel]) {
|
||||
[self.delegate performSelector:sel withObject:eventData];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Passes the given props to the React Native application. The props which we pass
|
||||
* are a combination of 3 different sources:
|
||||
* Converts a specific event name i.e. redux action type description to a
|
||||
* method name.
|
||||
*
|
||||
* - JitsiMeet.defaultConferenceOptions
|
||||
* - This function's parameters
|
||||
* - Some extras which are added by this function
|
||||
* @param eventName The event name to convert to a method name.
|
||||
* @return A method name constructed from the specified `eventName`.
|
||||
*/
|
||||
- (void)setProps:(NSDictionary *_Nonnull)newProps {
|
||||
NSMutableDictionary *props = mergeProps([[JitsiMeet sharedInstance] getDefaultProps], newProps);
|
||||
- (NSString *)methodNameFromEventName:(NSString *)eventName {
|
||||
NSMutableString *methodName
|
||||
= [NSMutableString stringWithCapacity:eventName.length];
|
||||
|
||||
// Set the PiP flag if it wasn't manually set.
|
||||
NSMutableDictionary *featureFlags = props[@"flags"];
|
||||
if (featureFlags[PiPEnabledFeatureFlag] == nil) {
|
||||
featureFlags[PiPEnabledFeatureFlag]
|
||||
= [NSNumber numberWithBool:
|
||||
self.delegate && [self.delegate respondsToSelector:@selector(enterPictureInPicture:)]];
|
||||
}
|
||||
for (NSString *c in [eventName componentsSeparatedByString:@"_"]) {
|
||||
if (c.length) {
|
||||
[methodName appendString:
|
||||
methodName.length ? c.capitalizedString : c.lowercaseString];
|
||||
}
|
||||
}
|
||||
[methodName appendString:@":"];
|
||||
|
||||
props[@"externalAPIScope"] = externalAPIScope;
|
||||
|
||||
// This method is supposed to be imperative i.e. a second
|
||||
// invocation with one and the same URL is expected to join the respective
|
||||
// conference again if the first invocation was followed by leaving the
|
||||
// conference. However, React and, respectively,
|
||||
// appProperties/initialProperties are declarative expressions i.e. one and
|
||||
// the same URL will not trigger an automatic re-render in the JavaScript
|
||||
// source code. The workaround implemented below introduces imperativeness
|
||||
// in React Component props by defining a unique value per invocation.
|
||||
props[@"timestamp"] = @(mach_absolute_time());
|
||||
|
||||
if (rootView) {
|
||||
// Update props with the new URL.
|
||||
rootView.appProperties = props;
|
||||
} else {
|
||||
RCTBridge *bridge = [[JitsiMeet sharedInstance] getReactBridge];
|
||||
rootView
|
||||
= [[RNRootView alloc] initWithBridge:bridge
|
||||
moduleName:@"App"
|
||||
initialProperties:props];
|
||||
rootView.backgroundColor = self.backgroundColor;
|
||||
|
||||
// Add rootView as a subview which completely covers this one.
|
||||
[rootView setFrame:[self bounds]];
|
||||
rootView.autoresizingMask
|
||||
= UIViewAutoresizingFlexibleWidth
|
||||
| UIViewAutoresizingFlexibleHeight;
|
||||
[self addSubview:rootView];
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)setPropsInViews:(NSDictionary *_Nonnull)newProps {
|
||||
BOOL handled = NO;
|
||||
|
||||
if (views) {
|
||||
for (NSString *externalAPIScope in views) {
|
||||
JitsiMeetView *view
|
||||
= [self viewForExternalAPIScope:externalAPIScope];
|
||||
|
||||
if (view) {
|
||||
[view setProps:newProps];
|
||||
handled = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
+ (instancetype)viewForExternalAPIScope:(NSString *)externalAPIScope {
|
||||
return [views objectForKey:externalAPIScope];
|
||||
return methodName;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
38
ios/sdk/src/JitsiMeetViewController.h
Normal file
38
ios/sdk/src/JitsiMeetViewController.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright @ 2022-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "JitsiMeetConferenceOptions.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface JitsiMeetViewController : UIViewController
|
||||
|
||||
- (void)join:(JitsiMeetConferenceOptions *)options withPiP:(BOOL)enablePiP;
|
||||
- (void)leave;
|
||||
- (void)hangUp;
|
||||
- (void)setAudioMuted:(BOOL)muted;
|
||||
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
|
||||
- (void)toggleScreenShare:(BOOL)enabled;
|
||||
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler;
|
||||
- (void)openChat:(NSString*)to;
|
||||
- (void)closeChat;
|
||||
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to;
|
||||
- (void)setVideoMuted:(BOOL)muted;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
127
ios/sdk/src/JitsiMeetViewController.m
Normal file
127
ios/sdk/src/JitsiMeetViewController.m
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright @ 2022-present 8x8, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#import "JitsiMeetViewController.h"
|
||||
#import "JitsiMeet+Private.h"
|
||||
#import "JitsiMeetConferenceOptions+Private.h"
|
||||
#import "JitsiMeetRenderingView.h"
|
||||
#import "JitsiMeetView+Private.h"
|
||||
|
||||
@interface JitsiMeetViewController ()
|
||||
|
||||
@property (strong, nonatomic) JitsiMeetRenderingView *view;
|
||||
|
||||
@end
|
||||
|
||||
@implementation JitsiMeetViewController
|
||||
|
||||
@dynamic view;
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self registerObservers];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
- (void)loadView {
|
||||
[super loadView];
|
||||
|
||||
self.view = [[JitsiMeetRenderingView alloc] init];
|
||||
self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
// Set a background color which is in accord with the JavaScript and Android
|
||||
// parts of the application and causes less perceived visual flicker than
|
||||
// the default background color.
|
||||
self.view.backgroundColor = [UIColor colorWithRed:.07f green:.07f blue:.07f alpha:1];
|
||||
}
|
||||
|
||||
- (void)join:(JitsiMeetConferenceOptions *)options withPiP:(BOOL)enablePiP {
|
||||
self.view.isPiPEnabled = enablePiP;
|
||||
[self.view setProps:options == nil ? @{} : [options asProps]];
|
||||
}
|
||||
|
||||
- (void)leave {
|
||||
[self.view setProps:@{}];
|
||||
}
|
||||
|
||||
- (void)hangUp {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendHangUp];
|
||||
}
|
||||
|
||||
- (void)setAudioMuted:(BOOL)muted {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendSetAudioMuted:muted];
|
||||
}
|
||||
|
||||
- (void)sendEndpointTextMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendEndpointTextMessage:message :to];
|
||||
}
|
||||
|
||||
- (void)toggleScreenShare:(BOOL)enabled {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI toggleScreenShare:enabled];
|
||||
}
|
||||
|
||||
- (void)retrieveParticipantsInfo:(void (^ _Nonnull)(NSArray * _Nullable))completionHandler {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI retrieveParticipantsInfo:completionHandler];
|
||||
}
|
||||
|
||||
- (void)openChat:(NSString*)to {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI openChat:to];
|
||||
}
|
||||
|
||||
- (void)closeChat {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI closeChat];
|
||||
}
|
||||
|
||||
- (void)sendChatMessage:(NSString * _Nonnull)message :(NSString * _Nullable)to {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendChatMessage:message :to];
|
||||
}
|
||||
|
||||
- (void)setVideoMuted:(BOOL)muted {
|
||||
ExternalAPI *externalAPI = [[JitsiMeet sharedInstance] getExternalAPI];
|
||||
[externalAPI sendSetVideoMuted:muted];
|
||||
}
|
||||
|
||||
#pragma mark Private
|
||||
|
||||
- (void)registerObservers {
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleUpdateViewPropsNotification:) name:updateViewPropsNotificationName object:nil];
|
||||
}
|
||||
|
||||
- (void)handleUpdateViewPropsNotification:(NSNotification *)notification {
|
||||
NSDictionary *props = [notification.userInfo objectForKey:@"props"];
|
||||
[self.view setProps:props];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"fr": "Französisch",
|
||||
"frCA": "Französisch (Kanada)",
|
||||
"hr": "Kroatisch",
|
||||
"hsb": "Obersorbisch",
|
||||
"hu": "Ungarisch",
|
||||
"hy": "Armenisch",
|
||||
"it": "Italienisch",
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
"fr": "French",
|
||||
"frCA": "French (Canadian)",
|
||||
"hr": "Croatian",
|
||||
"hsb": "Upper Sorbian",
|
||||
"hu": "Hungarian",
|
||||
"hy": "Armenian",
|
||||
"it": "Italian",
|
||||
|
||||
47
lang/languages-hsb.json
Normal file
47
lang/languages-hsb.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"ar": "arabšćina",
|
||||
"bg": "bołharšćina",
|
||||
"cs": "čěšćina",
|
||||
"da": "danšćina",
|
||||
"de": "němčina",
|
||||
"el": "grjekšćina",
|
||||
"en": "jendźelšćina",
|
||||
"enGB": "jendźelšćina (Wulka Britaniska)",
|
||||
"eo": "esperanto",
|
||||
"es": "španišćina",
|
||||
"esUS": "španišćina (Łaćonska)",
|
||||
"et": "estišćina",
|
||||
"eu": "baskišćina",
|
||||
"fa": "persišćina",
|
||||
"fi": "finšćina",
|
||||
"fr": "francošćina",
|
||||
"frCA": "francošćina (Kanada)",
|
||||
"he": "hebrejšćina",
|
||||
"hi": "hindišćina",
|
||||
"hr": "chorwatšćina",
|
||||
"hsb": "hornjoserbšćina",
|
||||
"hu": "madźaršćina",
|
||||
"hy": "armenšćina",
|
||||
"id": "indonešćina",
|
||||
"it": "italšćina",
|
||||
"ja": "japanšćina",
|
||||
"ko": "korejšćina",
|
||||
"lt": "litawšćina",
|
||||
"lv": "letišćina",
|
||||
"nl": "nižozemšćina",
|
||||
"pl": "pólšćina",
|
||||
"pt": "portugalšćina",
|
||||
"ptBR": "portugalšćina (Brazilska)",
|
||||
"ro": "rumunšćina",
|
||||
"ru": "rušćina",
|
||||
"sk": "słowakšćina",
|
||||
"sl": "słowjenšćina",
|
||||
"sq": "albanšćina",
|
||||
"sr": "serbišćina",
|
||||
"sv": "šwedšćina",
|
||||
"tr": "turkowšćina",
|
||||
"uk": "ukrainšćina",
|
||||
"vi": "vietnamšćina",
|
||||
"zhCN": "chinšćina (China)",
|
||||
"zhTW": "chinšćina (Taiwan)"
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
"he": "Hebrew",
|
||||
"hi": "Hindi",
|
||||
"hr": "Croatian",
|
||||
"hsb": "Upper Sorbian",
|
||||
"hu": "Hungarian",
|
||||
"hy": "Armenian",
|
||||
"id": "Indonesian",
|
||||
|
||||
@@ -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,13 +894,23 @@
|
||||
"limitNotificationDescriptionWeb": "نظرًا للضغط الكبير، سيقيَّد التسجيل إلى {{limit}} د، ولكن إن أردت التسجيل لمدة مفتوحة، جرِّب <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "لقد أنشأنا رابطًا لتسجيلك.",
|
||||
"live": "مباشر",
|
||||
"localRecordingNoNotificationWarning": "لن يتم الإعلان عن التسجيل للمشاركين الآخرين. ستحتاج إلى إخبارهم بأنه تم تسجيل الاجتماع.",
|
||||
"localRecordingNoVideo": "لا يتم تسجيل الفيديو",
|
||||
"localRecordingStartWarning": "يرجى التأكد من إيقاف التسجيل قبل الخروج من الاجتماع من أجل حفظه.",
|
||||
"localRecordingStartWarningTitle": "أوقف التسجيل لحفظه",
|
||||
"localRecordingVideoStop": "سيؤدي إيقاف الفيديو أيضًا إلى إيقاف التسجيل المحلي. هل أنت متأكد أنك تريد الاستمرار؟",
|
||||
"localRecordingVideoWarning": "لتسجيل الفيديو الخاص بك ، يجب أن يكون لديك عند بدء التسجيل",
|
||||
"localRecordingWarning": "تأكد من تحديد علامة التبويب الحالية لاستخدام الفيديو والصوت الصحيحين. التسجيل محدود حاليًا بـ 1 كيغابايت ، أي حوالي 100 دقيقة.",
|
||||
"loggedIn": "مُسجَّل باسم {{userName}}",
|
||||
"noStreams": "لم يتم الكشف عن دفق الصوت أو الفيديو.",
|
||||
"off": "أوقِف التسجيل",
|
||||
"offBy": "أوقَف {{name}} التسجيل",
|
||||
"on": "تسجيل",
|
||||
"onBy": "بدأ {{name}} التسجيل",
|
||||
"onlyRecordSelf": "تسجيل فقط دفق الصوت والفيديو الخاصة بي",
|
||||
"pending": "التحضير لتسجيل المُلتقى...",
|
||||
"rec": "تسجيل",
|
||||
"saveLocalRecording": "حفظ ملف التسجيل محليا",
|
||||
"serviceDescription": "ستحفظ خدمة التسجيل الفيديو المستجل",
|
||||
"serviceDescriptionCloud": "تسجيل سحابي",
|
||||
"serviceDescriptionCloudInfo": "يتم مسح المُلتقيات المسجلة تلقائيًا بعد 24 ساعة من وقت التسجيل.",
|
||||
@@ -889,10 +918,12 @@
|
||||
"sessionAlreadyActive": "هذه الجلسة قيد التسجيل أو البث المباشر.",
|
||||
"signIn": "دخول",
|
||||
"signOut": "خروج",
|
||||
"surfaceError": "الرجاء تحديد علامة التبويب الحالية.",
|
||||
"unavailable": "عجبًا! {{serviceName}} غير متاحة حاليًا. نعمل على حل المشكلة. حاول مرة أخرى لاحقًا.",
|
||||
"unavailableTitle": "التسجيل غير متاح",
|
||||
"uploadToCloud": "تحميل إلى السحابة"
|
||||
},
|
||||
"screenshareDisplayName": "شاشة {{name}}",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "اسحب للتحديث"
|
||||
},
|
||||
@@ -919,16 +950,19 @@
|
||||
"incomingMessage": "رسالة واردة",
|
||||
"language": "اللغة",
|
||||
"loggedIn": "الدخول باسم {{name}}",
|
||||
"maxStageParticipants": "الحد الأقصى لعدد المشاركين الذين يمكن تثبيتهم في المرحلة الرئيسية",
|
||||
"microphones": "المجهار (المايكروفون)",
|
||||
"moderator": "رئيس الجلسة",
|
||||
"more": "المزيد",
|
||||
"name": "الاسم",
|
||||
"noDevice": "لا يوجد",
|
||||
"participantJoined": "انضم مشارك",
|
||||
"participantKnocking": "دخل المشارك في الردهة",
|
||||
"participantLeft": "غادر المشارك",
|
||||
"playSounds": "تشغيل الصوت عند:",
|
||||
"reactions": "ردود فعل المُلتقى",
|
||||
"sameAsSystem": "مثل النظام ({{label}})",
|
||||
"screenTitle": "إعدادات",
|
||||
"selectAudioOutput": "خرج الصوت",
|
||||
"selectCamera": "الكاميرا",
|
||||
"selectMic": "المجهار (المايكروفون)",
|
||||
@@ -954,6 +988,7 @@
|
||||
"disableCrashReportingWarning": "أمتأكد من تعطيل تقارير الأعطال التقنية؟ ستسري الإعدادات الجديدة بعد إعادة تشغيل التطبيق",
|
||||
"disableP2P": "تعطيل وضع واحد شخص-لشخص",
|
||||
"displayName": "عرض الاسم",
|
||||
"displayNamePlaceholderText": "على سبيل المثال: علي الحيدري",
|
||||
"email": "البريد الإلكتروني",
|
||||
"header": "الإعدادات",
|
||||
"profileSection": "الملف الشخصي",
|
||||
@@ -998,6 +1033,7 @@
|
||||
"termsView": {
|
||||
"header": "مصطلحات"
|
||||
},
|
||||
"toggleTopPanelLabel": "تبديل اللوحة العلوية",
|
||||
"toolbar": {
|
||||
"Settings": "الإعدادات",
|
||||
"accessibilityLabel": {
|
||||
@@ -1007,10 +1043,12 @@
|
||||
"boo": "Boo",
|
||||
"breakoutRoom": "الانضمام / مغادرة غرفة فرعية",
|
||||
"callQuality": "اضبط دقة الفيديو",
|
||||
"carmode": "وضع السيارة",
|
||||
"cc": "اظهِر/اخفِ الترجمة",
|
||||
"chat": "اظهِر/اخفِ نافذة الدردشة",
|
||||
"clap": "تصفيق",
|
||||
"collapse": "قلّص",
|
||||
"dock": "إرساء في النافذة الرئيسية",
|
||||
"document": "اظهِر/اخفِ الملف المشارك",
|
||||
"download": "نزِّل التطبيق",
|
||||
"embedMeeting": "ضمِّن المُلتقى",
|
||||
@@ -1061,6 +1099,7 @@
|
||||
"tileView": "اظهِر/اخفِ عرض العنوان",
|
||||
"toggleCamera": "بدِّل الكاميرا",
|
||||
"toggleFilmstrip": "بدِّل وضع الشريط السينمائي (filmstrip)",
|
||||
"undock": "فك في نافذة منفصلة",
|
||||
"videoblur": "استعمل/اخرج من وضع تغبيش خلفية الفيديو",
|
||||
"videomute": "بدِّل وضع اخفاء الفيديو"
|
||||
},
|
||||
@@ -1077,6 +1116,7 @@
|
||||
"closeChat": "أغلق الدردشة",
|
||||
"closeReactionsMenu": "إغلاق قائمة ردود الفعل",
|
||||
"disableReactionSounds": "يمكنك تعطيل أصوات ردود الفعل لهذا المُلتقى",
|
||||
"dock": "إرساء في النافذة الرئيسية",
|
||||
"documentClose": "أغلق الملف المشارك",
|
||||
"documentOpen": "افتح الملف المشارك",
|
||||
"download": "نزِّل التطبيق",
|
||||
@@ -1145,6 +1185,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"
|
||||
},
|
||||
|
||||
@@ -40,9 +40,6 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "Geringe Bandbreite"
|
||||
},
|
||||
"blankPage": {
|
||||
"meetingEnded": "Konferenz beendet."
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "Breakout-Raum hinzufügen",
|
||||
@@ -80,6 +77,17 @@
|
||||
"refresh": "Kalender aktualisieren",
|
||||
"today": "Heute"
|
||||
},
|
||||
"carmode": {
|
||||
"actions": {
|
||||
"leaveMeeting": "Konferenz verlassen",
|
||||
"selectSoundDevice": "Audiogerät auswählen"
|
||||
},
|
||||
"labels": {
|
||||
"buttonLabel": "Automodus",
|
||||
"title": "Automodus",
|
||||
"videoStopped": "Ihre Kamera ist deaktiviert"
|
||||
}
|
||||
},
|
||||
"chat": {
|
||||
"enter": "Chat-Raum betreten",
|
||||
"error": "Fehler: Ihre Nachricht wurde nicht versendet. Grund: {{error}}",
|
||||
@@ -108,6 +116,7 @@
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "Chrome-Erweiterung installieren",
|
||||
"buttonTextEdge": "Edge-Erweiterung installieren",
|
||||
"close": "Schließen",
|
||||
"dontShowAgain": "Hinweis nicht mehr anzeigen",
|
||||
"installExtensionText": "Installieren Sie die Erweiterung für die Integration von Google Calendar und Office 365"
|
||||
@@ -199,6 +208,9 @@
|
||||
"selectADevice": "Ein Gerät wählen",
|
||||
"testAudio": "Prüfton wiedergeben"
|
||||
},
|
||||
"dialIn": {
|
||||
"screenTitle": "Einwahldaten"
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "ist jetzt {{status}}"
|
||||
},
|
||||
@@ -649,6 +661,8 @@
|
||||
"linkToSalesforceKey": "Konferenz verlinken",
|
||||
"linkToSalesforceProgress": "Konferenz wird mit Salesforce verlinkt...",
|
||||
"linkToSalesforceSuccess": "Die Konferenz wurde mit Salesforce verlinkt",
|
||||
"localRecordingStarted": "{{name}} hat eine lokale Aufzeichnung gestartet.",
|
||||
"localRecordingStopped": "{{name}} hat eine lokale Aufzeichnung gestoppt.",
|
||||
"me": "Ich",
|
||||
"moderationInEffectCSDescription": "Bitte melden um ein Video zu teilen",
|
||||
"moderationInEffectCSTitle": "Die Videofreigabe ist von der Moderation gesperrt",
|
||||
@@ -804,6 +818,7 @@
|
||||
"initiated": "Anruf gestartet",
|
||||
"joinAudioByPhone": "Per Telefon teilnehmen",
|
||||
"joinMeeting": "Konferenz beitreten",
|
||||
"joinMeetingInLowBandwidthMode": "Konferenz im Datensparmodus beitreten",
|
||||
"joinWithoutAudio": "Ohne Ton beitreten",
|
||||
"keyboardShortcuts": "Tastaturkurzbefehle aktivieren",
|
||||
"linkCopied": "Link in die Zwischenablage kopiert",
|
||||
@@ -879,13 +894,23 @@
|
||||
"limitNotificationDescriptionWeb": "Wegen hoher Nachfrage ist Ihre Aufnahme auf {{limit}} Min. begrenzt. Für unlimitierte Aufnahmen nutzen Sie bitte <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"linkGenerated": "Link zur Aufzeichnung wurde generiert.",
|
||||
"live": "LIVE",
|
||||
"localRecordingNoNotificationWarning": "Die Aufzeichnung wird anderen Anwesenden nicht mitgeteilt. Sie müssen diese selbst darauf hinweisen, dass die Konferenz aufgezeichnet wird.",
|
||||
"localRecordingNoVideo": "Videos werden nicht aufgenommen",
|
||||
"localRecordingStartWarning": "Bitte beenden Sie die Aufzeichnung vor dem Verlassen der Konferenz, um die Aufzeichnung zu speichern.",
|
||||
"localRecordingStartWarningTitle": "Aufzeichnung zum Speichern beenden",
|
||||
"localRecordingVideoStop": "Wenn Sie ihre Kamera abschalten wird auch die Aufnahme beendet. Sind Sie sicher, dass Sie fortfahren möchten?",
|
||||
"localRecordingVideoWarning": "Um Ihr eigenes Kamerabild aufzuzeichnen, müssen Sie Ihre Kamera beim Start der Aufnahme einschalten",
|
||||
"localRecordingWarning": "Bitte prüfen Sie, dass das aktuelle Tab auswählen, um Bild und Ton aufzuzeichnen. Die Länge der Aufzeichnung ist aktuell auf 1GB beschränkt, was ungefähr 100 Minuten entspricht.",
|
||||
"loggedIn": "Als {{userName}} angemeldet",
|
||||
"noStreams": "Kein Ton oder Video erkannt.",
|
||||
"off": "Aufnahme gestoppt",
|
||||
"offBy": "{{name}} stoppte die Aufnahme",
|
||||
"on": "Aufnahme",
|
||||
"onBy": "{{name}} startete die Aufnahme",
|
||||
"onlyRecordSelf": "Nur eigenes Kamerabild und Ton aufzeichnen",
|
||||
"pending": "Aufzeichnung des Meetings wird vorbereitet…",
|
||||
"rec": "AUFZ",
|
||||
"saveLocalRecording": "Aufzeichnung lokal abspeichern",
|
||||
"serviceDescription": "Ihre Aufzeichnung wird vom Aufzeichnungsdienst gespeichert",
|
||||
"serviceDescriptionCloud": "Cloud-Aufzeichnung",
|
||||
"serviceDescriptionCloudInfo": "Aufzeichnungen werden 24 Stunden nach Aufzeichnungsende automatisch gelöscht.",
|
||||
@@ -893,10 +918,12 @@
|
||||
"sessionAlreadyActive": "Diese Konferenz wird bereits aufgezeichnet.",
|
||||
"signIn": "Anmelden",
|
||||
"signOut": "Abmelden",
|
||||
"surfaceError": "Bitte das aktuelle Tab auswählen.",
|
||||
"unavailable": "Oh! Der {{serviceName}} ist aktuell nicht verfügbar. Wir arbeiten an der Behebung des Problems. Bitte versuchen Sie es später noch einmal.",
|
||||
"unavailableTitle": "Aufnahme nicht verfügbar",
|
||||
"uploadToCloud": "In die Cloud hochladen"
|
||||
},
|
||||
"screenshareDisplayName": "{{name}}s Bildschirmfreigabe",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Ziehen, um zu aktualisieren"
|
||||
},
|
||||
@@ -930,10 +957,12 @@
|
||||
"name": "Name",
|
||||
"noDevice": "Kein",
|
||||
"participantJoined": "Neue Person nimmt teil",
|
||||
"participantKnocking": "Person hat Lobby betreten",
|
||||
"participantLeft": "Person verlässt die Konferenz",
|
||||
"playSounds": "Hinweistöne aktiviert",
|
||||
"reactions": "Interaktionen",
|
||||
"sameAsSystem": "Wie System ({{label}})",
|
||||
"screenTitle": "Einstellungen",
|
||||
"selectAudioOutput": "Audioausgabe",
|
||||
"selectCamera": "Kamera",
|
||||
"selectMic": "Mikrofon",
|
||||
@@ -959,6 +988,7 @@
|
||||
"disableCrashReportingWarning": "Möchten Sie die Absturzberichte wirklich deaktivieren? Diese Einstellung wird nach einem Neustart der App wirksam.",
|
||||
"disableP2P": "Ende-zu-Ende-Modus deaktivieren",
|
||||
"displayName": "Anzeigename",
|
||||
"displayNamePlaceholderText": "z.B. Erika Musterfrau",
|
||||
"email": "E-Mail",
|
||||
"header": "Einstellungen",
|
||||
"profileSection": "Profil",
|
||||
@@ -1003,6 +1033,7 @@
|
||||
"termsView": {
|
||||
"header": "Nutzungsbedingungen"
|
||||
},
|
||||
"toggleTopPanelLabel": "Obere Leiste ein-/ausschalten",
|
||||
"toolbar": {
|
||||
"Settings": "Einstellungen",
|
||||
"accessibilityLabel": {
|
||||
@@ -1012,10 +1043,12 @@
|
||||
"boo": "Buhen",
|
||||
"breakoutRoom": "Breakout-Räume betreten/verlassen",
|
||||
"callQuality": "Qualitätseinstellungen",
|
||||
"carmode": "Automodus",
|
||||
"cc": "Untertitel ein-/ausschalten",
|
||||
"chat": "Chatfenster öffnen / schließen",
|
||||
"clap": "Klatschen",
|
||||
"collapse": "Einklappen",
|
||||
"dock": "In Hauptfenster einbinden",
|
||||
"document": "Geteiltes Dokument schließen",
|
||||
"download": "Unsere Apps herunterladen",
|
||||
"embedMeeting": "Konferenz einbetten",
|
||||
@@ -1066,6 +1099,7 @@
|
||||
"tileView": "Kachelansicht ein-/ausschalten",
|
||||
"toggleCamera": "Kamera wechseln",
|
||||
"toggleFilmstrip": "Miniaturansichten ein-/ausschalten",
|
||||
"undock": "In eigenem Fenster anzeigen",
|
||||
"videoblur": "Unscharfer Hintergrund ein-/ausschalten",
|
||||
"videomute": "„Video stummschalten“ ein-/ausschalten"
|
||||
},
|
||||
@@ -1082,6 +1116,7 @@
|
||||
"closeChat": "Chat schließen",
|
||||
"closeReactionsMenu": "Interaktionsmenü schließen",
|
||||
"disableReactionSounds": "Sie können die Interaktionstöne für diese Konferenz deaktivieren",
|
||||
"dock": "In Hauptfenster einbinden",
|
||||
"documentClose": "Geteiltes Dokument schließen",
|
||||
"documentOpen": "Geteiltes Dokument öffnen",
|
||||
"download": "Unsere Apps herunterladen",
|
||||
@@ -1150,6 +1185,7 @@
|
||||
"talkWhileMutedPopup": "Versuchen Sie zu sprechen? Ihr Mikrofon ist stummgeschaltet.",
|
||||
"tileViewToggle": "Kachelansicht ein-/ausschalten",
|
||||
"toggleCamera": "Kamera wechseln",
|
||||
"undock": "In eigenem Fenster anzeigen",
|
||||
"videoSettings": "Kameraeinstellungen",
|
||||
"videomute": "Kamera starten / stoppen"
|
||||
},
|
||||
|
||||
@@ -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",
|
||||
|
||||
1324
lang/main-hsb.json
Normal file
1324
lang/main-hsb.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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,11 +26,12 @@
|
||||
"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": {
|
||||
"bluetooth": "Bluetooth",
|
||||
"car": "Vivavoce Auto",
|
||||
"headphones": "Cuffie",
|
||||
"none": "Nessun dispositivo audio esistente",
|
||||
"phone": "Telefono",
|
||||
@@ -39,6 +40,25 @@
|
||||
"audioOnly": {
|
||||
"audioOnly": "Utilizzo di minore banda"
|
||||
},
|
||||
"breakoutRooms": {
|
||||
"actions": {
|
||||
"add": "Crea sottogruppo",
|
||||
"autoAssign": "Assegna automaticamente a sottogruppi",
|
||||
"close": "Chiudi",
|
||||
"join": "Entra",
|
||||
"leaveBreakoutRoom": "Esci",
|
||||
"more": "Mostra di più",
|
||||
"remove": "Elimina",
|
||||
"sendToBreakoutRoom": "Invia partecipante a:"
|
||||
},
|
||||
"defaultName": "Sottogruppo {{index}}",
|
||||
"mainRoom": "Riunione principale",
|
||||
"notifications": {
|
||||
"joined": "Entrato nel sottogruppo \"{{name}}\"",
|
||||
"joinedMainRoom": "Entrato nella riunione principale",
|
||||
"joinedTitle": "Sottogruppo"
|
||||
}
|
||||
},
|
||||
"calendarSync": {
|
||||
"addMeetingURL": "Aggiungi un collegamento alla riunione",
|
||||
"confirmAddLink": "Vuoi aggiungere un collegamento Jitsi a questo evento?",
|
||||
@@ -57,14 +77,26 @@
|
||||
"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}}",
|
||||
"fieldPlaceHolder": "Scrivi qui il tuo messaggio",
|
||||
"lobbyChatMessageTo": "Messaggio a {{recipient}} in sala d'attesa",
|
||||
"message": "Messaggio",
|
||||
"messageAccessibleTitle": "{{user}} dice:",
|
||||
"messageAccessibleTitleMe": "io dico:",
|
||||
"messageTo": "Messaggio privato per {{recipient}}",
|
||||
"messageTo": "Messaggio privato a {{recipient}}",
|
||||
"messagebox": "Digitare un messaggio",
|
||||
"nickname": {
|
||||
"popover": "Scegli un nickname",
|
||||
@@ -72,15 +104,15 @@
|
||||
"titleWithPolls": "Inserire un nickname per utilizzare la conversazione"
|
||||
},
|
||||
"noMessagesMessage": "Non ci sono ancora messaggi nella riunione. Comincia una conversazione, qui!",
|
||||
"privateNotice": "Messaggio privato per {{recipient}}",
|
||||
"privateNotice": "Messaggio privato a {{recipient}}",
|
||||
"smileysPanel": "Pannello emoji",
|
||||
"tabs": {
|
||||
"chat": "Chat",
|
||||
"chat": "Conversazione",
|
||||
"polls": "Sondaggi"
|
||||
},
|
||||
"title": "Conversazione",
|
||||
"titleWithPolls": "Conversazione",
|
||||
"you": "tu"
|
||||
"you": "te"
|
||||
},
|
||||
"chromeExtensionBanner": {
|
||||
"buttonText": "Installa l'estensione Chrome",
|
||||
@@ -158,7 +190,8 @@
|
||||
"joinInApp": "Entra in riunione usando l'app",
|
||||
"launchWebButton": "Avvia sul web",
|
||||
"title": "Sto avviando la riunione su {{app}}...",
|
||||
"tryAgainButton": "Prova di nuovo sul desktop"
|
||||
"tryAgainButton": "Prova di nuovo sul desktop",
|
||||
"unsupportedBrowser": "Sembra tu stia usando un browser che non supportiamo."
|
||||
},
|
||||
"defaultLink": "es. {{url}}",
|
||||
"defaultNickname": "es. Anna Rossi",
|
||||
@@ -186,12 +219,14 @@
|
||||
"Share": "Condividi",
|
||||
"Submit": "Invia",
|
||||
"WaitForHostMsg": "La riunione non è ancora cominciata. Se sei l'organizzatore, per favore autenticati. Altrimenti, aspetta l'arrivo dell'organizzatore.",
|
||||
"WaitingForHost": "In attesa dell'organizzatore...",
|
||||
"WaitingForHostTitle": "In attesa dell'organizzatore...",
|
||||
"Yes": "Sì",
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Diretta streaming"
|
||||
},
|
||||
"add": "Aggiungi",
|
||||
"addMeetingNote": "Aggiungi una a questa riunione",
|
||||
"addOptionalNote": "Aggiungi una nota (facoltativo):",
|
||||
"allow": "Consenti",
|
||||
"alreadySharedVideoMsg": "Un altro utente sta condividendo un video. Questa riunione permette di condividere un solo video alla volta.",
|
||||
"alreadySharedVideoTitle": "È permesso un solo video alla volta",
|
||||
@@ -243,6 +278,8 @@
|
||||
"kickParticipantDialog": "Sei sicuro di voler escludere questo partecipante?",
|
||||
"kickParticipantTitle": "Escludi questo partecipante?",
|
||||
"kickTitle": "Escluso dalla riunione",
|
||||
"linkMeeting": "Link meeting",
|
||||
"linkMeetingTitle": "Link meeting to Salesforce",
|
||||
"liveStreaming": "Diretta",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Impossibile durante la registrazione.",
|
||||
"liveStreamingDisabledTooltip": "Trasmissioni in diretta disabilitate.",
|
||||
@@ -262,9 +299,9 @@
|
||||
"micPermissionDeniedError": "Non hai concesso il permesso di usare il microfono. Puoi comunque partecipare alla riunione ma gli altri non potranno sentirti. Usa il bottone a forma di telecamera nella barra degli indirizzi per cambiare impostazioni.",
|
||||
"micTimeoutError": "Impossibile avviare la fonte audio. Tempo di attesa scaduto.",
|
||||
"micUnknownError": "Impossibile usare il microfono per un motivo sconosciuto.",
|
||||
"moderationAudioLabel": "Permetti ai partecipenti di accendere il microfono",
|
||||
"moderationVideoLabel": "Permetti ai partecipanti di arrivare la videocamera",
|
||||
"muteEveryoneDialog": "Sei sicuro di voler spegnere il microfono a tutti? Non potrai riattivarli, ma loro potranno farlo in qualsiasi momento.",
|
||||
"moderationAudioLabel": "Permetti ai partecipenti di riaccendere il microfono",
|
||||
"moderationVideoLabel": "Permetti ai partecipanti di riattivare la videocamera",
|
||||
"muteEveryoneDialog": "I partecipanti possono riaccenderli in quasiasi momento.",
|
||||
"muteEveryoneDialogModerationOn": "I partecipanti possono fare richiesta di parlare in ogni momento.",
|
||||
"muteEveryoneElseDialog": "Una volta spenti i microfoni non potrai riattivarli, ma loro potranno farlo in qualsiasi momento.",
|
||||
"muteEveryoneElseTitle": "Spengo il microfono a tutti, eccetto a {{whom}}?",
|
||||
@@ -278,12 +315,12 @@
|
||||
"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",
|
||||
"muteParticipantDialog": "Sei sicuro di voler spegnere il microfono di questo partecipante? Lui potrà riattivarlo in ogni momento.",
|
||||
"muteParticipantTitle": "Spengo il microfono a questo partecipante?",
|
||||
"muteParticipantButton": "Spegni audio",
|
||||
"muteParticipantsVideoBody": "Una volta spenta la videocamera non potrai riaccenderla, ma lui potrà riattivarla in qualsiasi momento.",
|
||||
"muteParticipantsVideoButton": "Spegni videocamera",
|
||||
"muteParticipantsVideoBodyModerationOn": "Non potrai riaccendere le videocamere, né potranno loro.",
|
||||
"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?",
|
||||
"noDropboxToken": "Token Dropbox non valido",
|
||||
"password": "Password",
|
||||
@@ -297,6 +334,7 @@
|
||||
"popupError": "Il tuo browser sta bloccando i pop-up da questo sito. Per favore abilita i pop-up dalle impostazioni di sicurezza del browser e riprova.",
|
||||
"popupErrorTitle": "Pop-up bloccato",
|
||||
"readMore": "continua",
|
||||
"recentlyUsedObjects": "Gli oggetti che hai usato di recente",
|
||||
"recording": "Registrazione",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Impossibile durante una diretta.",
|
||||
"recordingDisabledTooltip": "Registrazione disabilitata.",
|
||||
@@ -319,6 +357,12 @@
|
||||
"screenSharingFailed": "Ops! Non è stato possibile avviare la condivisione dello schermo!",
|
||||
"screenSharingFailedTitle": "Condivisione dello schermo fallita!",
|
||||
"screenSharingPermissionDeniedError": "Qualcosa non funziona nei permessi di condivisione dello schermo. Ricarica e riprova.",
|
||||
"searchInSalesforce": "Cerca in Salesforce",
|
||||
"searchResults": "Risultati ricerca({{count}})",
|
||||
"searchResultsDetailsError": "Qualcosa non ha funzionato nella ricezione dei dati del proprietario.",
|
||||
"searchResultsError": "Qualcosa non ha funzionato nella ricezione dei dati.",
|
||||
"searchResultsNotFound": "Nessun risultato.",
|
||||
"searchResultsTryAgain": "Prova altre parole di ricerca.",
|
||||
"sendPrivateMessage": "Hai ricevuto un messaggio privato poco fa. Vorresti rispondergli privatamente o vuoi mandare la risposta al gruppo?",
|
||||
"sendPrivateMessageCancel": "Invia al gruppo",
|
||||
"sendPrivateMessageOk": "Invia privatamente",
|
||||
@@ -341,8 +385,10 @@
|
||||
"shareVideoTitle": "Condividi un video",
|
||||
"shareYourScreen": "Condividi schermo",
|
||||
"shareYourScreenDisabled": "Condivisione schermo disabilitata.",
|
||||
"sharedVideoDialogError": "Errore: URL non valido",
|
||||
"sharedVideoLinkPlaceholder": "Link YouTube o link video diretto",
|
||||
"startLiveStreaming": "Inizia una diretta",
|
||||
"start": "Avvia ",
|
||||
"startLiveStreaming": "Avvia diretta",
|
||||
"startRecording": "Inizia a registrare",
|
||||
"startRemoteControlErrorMessage": "Si è verificato un errore nel tentativo di avviare la sessione di controllo remoto!",
|
||||
"stopLiveStreaming": "Ferma la diretta streaming",
|
||||
@@ -384,6 +430,10 @@
|
||||
"veryBad": "Pessima",
|
||||
"veryGood": "Ottima"
|
||||
},
|
||||
"giphy": {
|
||||
"noResults": "Trovato niente :(",
|
||||
"search": "Cerca in GIPHY"
|
||||
},
|
||||
"helpView": {
|
||||
"header": "Aiuto"
|
||||
},
|
||||
@@ -424,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"
|
||||
},
|
||||
@@ -450,6 +500,7 @@
|
||||
"focusLocal": "Sposta il focus sul tuo video",
|
||||
"focusRemote": "Sposta il focus sul video di un altro partecipante",
|
||||
"fullScreen": "Attiva o disattiva schermo intero",
|
||||
"giphyMenu": "Mostra menù GIPHY",
|
||||
"keyboardShortcuts": "Scorciatoie da tastiera",
|
||||
"localRecording": "Mostra o nascondi i controlli per la registrazione",
|
||||
"mute": "Attiva o disattiva il microfono",
|
||||
@@ -479,6 +530,7 @@
|
||||
"failedToStart": "Avvio trasmissione in diretta fallito",
|
||||
"getStreamKeyManually": "Non siamo stati in grado di trovare nessuna trasmissione dal vivo. Prova ad ottenere una chiave stream da Youtube",
|
||||
"googlePrivacyPolicy": "Norme sulla riservatezza di Google",
|
||||
"inProgress": "Diretta o registrazione in corso",
|
||||
"invalidStreamKey": "La chiave per le dirette potrebbe non essere corretta.",
|
||||
"limitNotificationDescriptionNative": "La tua diretta sarà limitata a {{limit}} minuti. Per dirette illimitate, prova {{app}}.",
|
||||
"limitNotificationDescriptionWeb": "Data l'alta domanda la tua diretta sarà limitata a {{limit}} minuti. Per dirette illimitate, prova <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
@@ -488,6 +540,7 @@
|
||||
"onBy": "{{name}} ha iniziato la diretta",
|
||||
"pending": "Avvio diretta...",
|
||||
"serviceName": "Servizio dirette",
|
||||
"sessionAlreadyActive": "Questa sessione è in già in fase di registrazione o trasmessione in diretta.",
|
||||
"signIn": "Collegati con Google",
|
||||
"signInCTA": "Collegati o inserisci la tua chiave YouTube per la trasmissione in diretta.",
|
||||
"signOut": "Scollegati",
|
||||
@@ -502,6 +555,7 @@
|
||||
"admitAll": "Ammetti tutti",
|
||||
"allow": "Autorizza",
|
||||
"backToKnockModeButton": "Nessuna password, richiedi l'accesso",
|
||||
"chat": "Conversazione",
|
||||
"dialogTitle": "Sala d'attesa",
|
||||
"disableDialogContent": "Sala d'attesa attiva. Questa funzione ti permette di non dare accesso alla riunione a partecipanti indesiderati. Vuoi disattivarla?",
|
||||
"disableDialogSubmit": "Disattiva",
|
||||
@@ -514,6 +568,7 @@
|
||||
"errorMissingPassword": "Per favore, mettere la password della riunione",
|
||||
"invalidPassword": "Password errata",
|
||||
"joinRejectedMessage": "La tua richiesta d'accesso è stata respinta da un moderatore.",
|
||||
"joinRejectedTitle": "Richiesta d'ingresso respinta.",
|
||||
"joinTitle": "Entra nella riunione",
|
||||
"joinWithPasswordMessage": "Ho inviato la password per entrare, attendi...",
|
||||
"joiningMessage": "Entrerai nella riunione non appena qualcuno approva la tua richiesta",
|
||||
@@ -522,6 +577,8 @@
|
||||
"knockButton": "Chiedi d'entrare",
|
||||
"knockTitle": "Qualcuno vuole entrare nella riunione",
|
||||
"knockingParticipantList": "Lista dei partecipanti in attesa",
|
||||
"lobbyChatStartedNotification": "{{moderator}} sta parlando con {{attendee}} in sala d'attesa",
|
||||
"lobbyChatStartedTitle": "{{moderator}} sta parlando con te in sala d'attesa.",
|
||||
"nameField": "Scrivi il tuo nome",
|
||||
"notificationLobbyAccessDenied": "{{targetParticipantName}} è stato respinto da {{originParticipantName}}",
|
||||
"notificationLobbyAccessGranted": "{{targetParticipantName}} è stato autorizzato ad entrare da {{originParticipantName}}",
|
||||
@@ -572,20 +629,36 @@
|
||||
"me": "io",
|
||||
"notify": {
|
||||
"OldElectronAPPTitle": "Falla di sicurezza!",
|
||||
"allowAction": "Permetti",
|
||||
"allowAction": "Autorizza",
|
||||
"allowedUnmute": "Puoi accendere il microfono, avviare la videocamera, o condividere il tuo schermo.",
|
||||
"connectedOneMember": "{{name}} si è connesso",
|
||||
"connectedThreePlusMembers": "{{name}} e altri {{count}} si sono connessi",
|
||||
"connectedTwoMembers": "{{first}} e {{second}} si sono connessi",
|
||||
"audioUnmuteBlockedDescription": "Lo sblocco dei microfoni è stato temporaneamente bloccato per limiti del sistema.",
|
||||
"audioUnmuteBlockedTitle": "Riattivazione dei microfoni bloccata!",
|
||||
"chatMessages": "Messaggi delle conversazioni",
|
||||
"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",
|
||||
"grantedTo": "Permessi di moderatore accordati a {{to}}!",
|
||||
"focusFail": "{{component}} non disponibile - riprovo tra {{ms}} sec",
|
||||
"gifsMenu": "GIPHY",
|
||||
"groupTitle": "Notifiche",
|
||||
"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}}",
|
||||
"kickParticipant": "{{kicked}} è stato espulso da {{kicker}}",
|
||||
"leftOneMember": "{{name}} ha lasciato la riunione",
|
||||
"leftThreePlusMembers": "{{name}} e molti altri hanno lasciato la riunione",
|
||||
"leftTwoMembers": "{{first}} e {{second}} hanno lasciato la riunione",
|
||||
"linkToSalesforce": "Collega a Salesforce",
|
||||
"linkToSalesforceDescription": "Puoi collegare il sommario della riunione ad un oggetto Salesforce.",
|
||||
"linkToSalesforceError": "Failed to link meeting to Salesforce",
|
||||
"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",
|
||||
@@ -599,23 +672,28 @@
|
||||
"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",
|
||||
"oldElectronClientDescription1": "Sembri stare usando una versione obsoleta del client Jitsi Meet che ha dei problemi di sicurezza noti. Assicurati di aggiornarla presso il nostro ",
|
||||
"oldElectronClientDescription2": "ultima build",
|
||||
"oldElectronClientDescription3": " ora!",
|
||||
"participantWantsToJoin": "Vuole unirsi alla riunione",
|
||||
"participantsWantToJoin": "Vogliono unirsi alla riunione",
|
||||
"passwordRemovedRemotely": "$t(lockRoomPasswordUppercase) è stata tolta da un altro partecipante",
|
||||
"passwordSetRemotely": "$t(lockRoomPasswordUppercase) è stata messa da un altro partecipante",
|
||||
"raiseHandAction": "Alza la mano",
|
||||
"raisedHand": "{{name}} vorrebbe intervenire.",
|
||||
"raisedHand": "Vorrebbe intervenire.",
|
||||
"raisedHands": "{{participantName}} e {{raisedHands}} altre persone",
|
||||
"reactionSounds": "Disattiva suoni",
|
||||
"screenShareNoAudio": " L'opzione di condivisione audio non era selezionata nella schermata di selezione della finestra da condividere.",
|
||||
"reactionSoundsForAll": "Disattiva suoni a tutti",
|
||||
"screenShareNoAudio": "L'opzione di condivisione audio non era selezionata nella schermata di selezione della finestra da condividere.",
|
||||
"screenShareNoAudioTitle": "Condividi audio non è stato selezionato",
|
||||
"selfViewTitle": "Puoi sempre ripristinare la tua immagine nelle impostazioni",
|
||||
"somebody": "Qualcuno",
|
||||
"startSilentDescription": "Entra di nuovo nella riunione, per attivare l'audio",
|
||||
"startSilentTitle": "Sei entrato nella riunione senza aver scelto un dispositivo audio per sentire!",
|
||||
@@ -623,39 +701,49 @@
|
||||
"suboptimalExperienceTitle": "Avviso sul browser",
|
||||
"unmute": "Accendi microfono",
|
||||
"videoMutedRemotelyDescription": "Puoi riaccenderla in qualsiasi momento.",
|
||||
"videoMutedRemotelyTitle": "La videocamera ti è stata spenta da {{participantDisplayName}}!"
|
||||
"videoMutedRemotelyTitle": "La videocamera ti è stata spenta da {{participantDisplayName}}!",
|
||||
"videoUnmuteBlockedDescription": "Riattivazione video e condivisione schermo sono state momentaneamente bloccate per limiti di sistema.",
|
||||
"videoUnmuteBlockedTitle": "Riattivazione video e condivisione schermo bloccate!",
|
||||
"viewLobby": "Vedi sala d'attesa",
|
||||
"waitingParticipants": "{{waitingParticipants}} persone"
|
||||
},
|
||||
"participantsPane": {
|
||||
"actions": {
|
||||
"allow": "Permetti ai partecipanti di:",
|
||||
"allowVideo": "Autorizza video",
|
||||
"askUnmute": "Chiedi di attivare audio",
|
||||
"audioModeration": "Possono attivare 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",
|
||||
"mute": "Silenzia",
|
||||
"muteAll": "Silenzia tutti",
|
||||
"muteEveryoneElse": "Silenzia tutti gli altri",
|
||||
"stopEveryonesVideo": "Ferma il video di tutti",
|
||||
"stopVideo": "Ferma il video",
|
||||
"unblockEveryoneMicCamera": "Sblocca audio e video a tutti",
|
||||
"videoModeration": "Avvia il loro video"
|
||||
"videoModeration": "Riavviare videocamera"
|
||||
},
|
||||
"close": "Chiudi",
|
||||
"header": "Partecipanti",
|
||||
"header": "Partecipanti e sala d'attesa",
|
||||
"headings": {
|
||||
"lobby": "Sala d'attesa ({{count}})",
|
||||
"participantsList": "Partecipanti alla riunione ({{count}})",
|
||||
"waitingLobby": "In attesa ({{count}})"
|
||||
}
|
||||
},
|
||||
"search": "Cerca partecipanti"
|
||||
},
|
||||
"passwordDigitsOnly": "Fino a {{number}} cifre",
|
||||
"passwordSetRemotely": "definita da altro utente",
|
||||
"pinnedParticipant": "Il partecipante è in evidenza",
|
||||
"polls": {
|
||||
"answer": {
|
||||
"skip": "Salta",
|
||||
"submit": "Invia"
|
||||
},
|
||||
"by": "Da {{ name }}",
|
||||
"create": {
|
||||
"addOption": "Aggiungi risposta",
|
||||
"answerPlaceholder": "Risposta {{index}}",
|
||||
@@ -731,9 +819,9 @@
|
||||
"linkCopied": "Collegamento copiato negli appunti",
|
||||
"lookGood": "Sembra che il tuo microfono funzioni correttamente",
|
||||
"or": "o",
|
||||
"premeeting": "Attesa riunione",
|
||||
"premeeting": "Pre-riunione",
|
||||
"screenSharingError": "Errore di condivisione dello schermo:",
|
||||
"showScreen": "Avvia la schermata d'attesa della riunione",
|
||||
"showScreen": "Attiva schermata pre-riunione",
|
||||
"startWithPhone": "Avvia usando il telefono, per parlare",
|
||||
"videoOnlyError": "Errore video:",
|
||||
"videoTrackError": "Impossibile creare la traccia video.",
|
||||
@@ -753,6 +841,9 @@
|
||||
"rejected": "Rifiutato",
|
||||
"ringing": "Sta suonando..."
|
||||
},
|
||||
"privacyView": {
|
||||
"header": "Privacy"
|
||||
},
|
||||
"profile": {
|
||||
"avatar": "avatar",
|
||||
"setDisplayNameLabel": "Imposta il nome da visualizzare",
|
||||
@@ -761,6 +852,19 @@
|
||||
"title": "Profilo"
|
||||
},
|
||||
"raisedHand": "Vorrebbe parlare",
|
||||
"raisedHandsLabel": "Numero di mani alzate",
|
||||
"record": {
|
||||
"already": {
|
||||
"linked": "La riunione è già collegata a questo oggetto Salesforce."
|
||||
},
|
||||
"type": {
|
||||
"account": "Account",
|
||||
"contact": "Contact",
|
||||
"lead": "Lead",
|
||||
"opportunity": "Opportunity",
|
||||
"owner": "Owner"
|
||||
}
|
||||
},
|
||||
"recording": {
|
||||
"authDropboxText": "Carica su Dropbox",
|
||||
"availableSpace": "Spazio disponibile: {{spaceLeft}} MB (rimangono approssimativamente {{duration}} minuti di registrazione)",
|
||||
@@ -775,10 +879,17 @@
|
||||
"expandedPending": "La registrazione è in fase di avvio...",
|
||||
"failedToStart": "Non è stato possibile avviare la registrazione",
|
||||
"fileSharingdescription": "Condividi la registrazione con i partecipanti alla riunione",
|
||||
"highlight": "Evidenzia",
|
||||
"highlightMoment": "Evidenzia momento",
|
||||
"highlightMomentDisabled": "Puoi evidenziare dei momenti quando parte la registrazione",
|
||||
"highlightMomentSuccess": "Momento evidenziato",
|
||||
"highlightMomentSucessDescription": "Il tuo momento evidenziato sarà aggiunto al riepilogo della riunione.",
|
||||
"inProgress": "Registrazione o diretta in corso",
|
||||
"limitNotificationDescriptionNative": "La tua registrazione sarà limitata a {{limit}} minuti. Per registrazioni illimitate, prova <3>{{app}}</3>.",
|
||||
"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",
|
||||
@@ -786,27 +897,32 @@
|
||||
"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.",
|
||||
"serviceName": "Servizio di registrazione",
|
||||
"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"
|
||||
},
|
||||
"settings": {
|
||||
"calendar": {
|
||||
"about": "L’integrazione del calendario con {{appName}} è usata per accedere in sicurezza al proprio calendario per poter leggere i prossimi appuntamenti ",
|
||||
"about": "L’integrazione del calendario con {{appName}} è usata per accedere in sicurezza al proprio calendario e poter leggere i prossimi appuntamenti ",
|
||||
"disconnect": "Disconnetti",
|
||||
"microsoftSignIn": "Connettiti con un account Microsoft",
|
||||
"signedIn": "Sto accedendo agli eventi del calendario per {{email}}. Fai click su «Disconnetti» per interrompere l’accesso agli eventi del calendario.",
|
||||
@@ -821,23 +937,26 @@
|
||||
"incomingMessage": "Messaggio in arrivo",
|
||||
"language": "Lingua",
|
||||
"loggedIn": "Connesso come {{name}}",
|
||||
"maxStageParticipants": "Numero massimo di partecipanti che possono essere aggiunti come oratori",
|
||||
"microphones": "Microfoni",
|
||||
"moderator": "Moderatore",
|
||||
"more": "Altro",
|
||||
"more": "Mostra di più",
|
||||
"name": "Nome",
|
||||
"noDevice": "Nessuno",
|
||||
"participantJoined": "Partecipante Entrato",
|
||||
"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",
|
||||
"selfView": "Tua immagine",
|
||||
"sounds": "Suoni",
|
||||
"speakers": "Altoparlanti",
|
||||
"startAudioMuted": "Tutti cominciano a microfono spento",
|
||||
"startVideoMuted": "Tutti cominciano a video disattivato",
|
||||
"startReactionsMuted": "Spegni i suoni delle reazioni a tutti",
|
||||
"startVideoMuted": "Tutti cominciano a videocamera disattivata",
|
||||
"talkWhileMuted": "Parla senza microfono",
|
||||
"title": "Impostazioni"
|
||||
},
|
||||
@@ -859,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": {
|
||||
@@ -869,13 +988,21 @@
|
||||
},
|
||||
"speaker": "Relatore",
|
||||
"speakerStats": {
|
||||
"angry": "Arrabbiato",
|
||||
"disgusted": "Disgustato",
|
||||
"displayEmotions": "Mostra Emozioni",
|
||||
"fearful": "Spaventato",
|
||||
"happy": "Contento",
|
||||
"hours": "{{count}}h",
|
||||
"minutes": "{{count}}m",
|
||||
"name": "Nome",
|
||||
"neutral": "Neutro",
|
||||
"sad": "Triste",
|
||||
"search": "Cerca",
|
||||
"seconds": "{{count}}s",
|
||||
"speakerStats": "Statistiche",
|
||||
"speakerTime": "Tempo"
|
||||
"speakerTime": "Tempo",
|
||||
"surprised": "Sorpreso"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"genericTitle": "Per la riunione devono essere usati il tuo microfono e la tua videocamera.",
|
||||
@@ -887,69 +1014,79 @@
|
||||
"text": "Premi il pulsante <i>Ricollegati</i> per ricollegarti.",
|
||||
"title": "La video chiamata si è interrotta perché il computer è stato sospeso."
|
||||
},
|
||||
"termsView": {
|
||||
"header": "Termini"
|
||||
},
|
||||
"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",
|
||||
"expand": "Espandi",
|
||||
"feedback": "Lascia un feedback",
|
||||
"fullScreen": "Apri/Chiudi schermo intero",
|
||||
"giphy": "Menù GIPHY",
|
||||
"grantModerator": "Autorizza moderatore",
|
||||
"hangup": "Lascia la riunione",
|
||||
"help": "Aiuto",
|
||||
"invite": "Invita persone",
|
||||
"invite": "Invita partecipanti",
|
||||
"kick": "Espelli partecipante",
|
||||
"laugh": "Ridi",
|
||||
"like": "Mi piace",
|
||||
"lobbyButton": "Attiva/disattiva sala d'attesa",
|
||||
"localRecording": "Abilita/disattiva controlli di registrazione locale",
|
||||
"linkToSalesforce": "Collega a Salesforce",
|
||||
"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",
|
||||
@@ -957,34 +1094,39 @@
|
||||
"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",
|
||||
"e2ee": "Crittografia punto-punto",
|
||||
"embedMeeting": "Incorpora riunione altrove",
|
||||
"enterFullScreen": "Visualizza a schermo intero",
|
||||
"enterFullScreen": "Schermo intero",
|
||||
"enterTileView": "Vedi tutti i partecipanti",
|
||||
"exitFullScreen": "Esci da schermo intero",
|
||||
"exitTileView": "Vedi una persona sola",
|
||||
"feedback": "Lascia un feedback",
|
||||
"giphy": "Menù GIPHY",
|
||||
"hangup": "Butta giù",
|
||||
"help": "Aiuto",
|
||||
"invite": "Invita persone",
|
||||
"invite": "Invita partecipanti",
|
||||
"joinBreakoutRoom": "Entra in sottogruppo",
|
||||
"laugh": "Ridi",
|
||||
"leaveBreakoutRoom": "Lascia breakout room",
|
||||
"like": "Mi piace",
|
||||
"linkToSalesforce": "Collega a Salesforce",
|
||||
"lobbyButtonDisable": "Disabilita sala d'attesa",
|
||||
"lobbyButtonEnable": "Abilita sala d'attesa",
|
||||
"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.",
|
||||
@@ -1000,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",
|
||||
@@ -1018,6 +1160,7 @@
|
||||
"speakerStats": "Statistiche",
|
||||
"startScreenSharing": "Inizia la condivisione dello schermo",
|
||||
"startSubtitles": "Avvia sottotitoli",
|
||||
"stopAudioSharing": "Ferma condivisione audio",
|
||||
"stopScreenSharing": "Ferma la condivisione dello schermo",
|
||||
"stopSharedVideo": "Ferma video",
|
||||
"stopSubtitles": "Ferma sottotitoli",
|
||||
@@ -1025,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.",
|
||||
@@ -1054,26 +1198,30 @@
|
||||
},
|
||||
"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": {
|
||||
"adjustFor": "Adjust for:",
|
||||
"audioOnly": "AUD",
|
||||
"audioOnlyExpanded": "Hai attivato la modalità con banda limitata. Questa modalità permette di risparmiare banda, ma non vedrai gli altri partecipanti.",
|
||||
"audioOnlyExpanded": "Hai attivato la modalità per banda limitata. Questa modalità permette di risparmiare banda, ma non vedrai gli altri partecipanti.",
|
||||
"bestPerformance": "Massime prestazioni",
|
||||
"callQuality": "Qualità video",
|
||||
"hd": "HD",
|
||||
"hdTooltip": "Stai vedendo in alta definizione",
|
||||
"highDefinition": "Alta definizione",
|
||||
"highestQuality": "Massima definizione",
|
||||
"labelTooiltipNoVideo": "Nessun video",
|
||||
"labelTooltipAudioOnly": "Hai attivato la modalità con banda limitata",
|
||||
"labelTooltipAudioOnly": "Hai attivato la modalità per banda limitata",
|
||||
"ld": "LD",
|
||||
"ldTooltip": "Stai vedendo a bassa definizione",
|
||||
"lowDefinition": "Bassa definizione",
|
||||
"performanceSettings": "Impostazione prestazioni",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Stai vedendo a definizione standard",
|
||||
"standardDefinition": "Definizione standard"
|
||||
@@ -1086,12 +1234,17 @@
|
||||
"domuteVideoOfOthers": "Disattiva video di tutti gli altri",
|
||||
"flip": "Rifletti",
|
||||
"grantModerator": "Autorizza moderatore",
|
||||
"hideSelfView": "Nascondi tua immagine",
|
||||
"kick": "Espelli",
|
||||
"moderator": "Moderatore",
|
||||
"mute": "Il partecipante ha il microfono spento",
|
||||
"muted": "Audio disattivato",
|
||||
"remoteControl": "Avvia/ferma il controllo remoto",
|
||||
"show": "Mostra in primo piano",
|
||||
"pinToStage": "Aggiungi agli oratori",
|
||||
"remoteControl": "Avvia/Ferma il controllo remoto",
|
||||
"screenSharing": "Il partecipante sta condividendo lo schermo",
|
||||
"show": "Mostra tra gli oratori",
|
||||
"showSelfView": "Mostra tua immagine",
|
||||
"unpinFromStage": "Togli",
|
||||
"videoMuted": "Video disattivato",
|
||||
"videomute": "Il partecipante ha la videocamera spenta"
|
||||
},
|
||||
@@ -1106,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",
|
||||
@@ -1116,13 +1269,14 @@
|
||||
"slightBlur": "Sfuoca leggermente",
|
||||
"title": "Sfondi",
|
||||
"uploadedImage": "Carica immagine {{index}}",
|
||||
"webAssemblyWarning": "Il WebAssembly not è supportato"
|
||||
"webAssemblyWarning": "Il WebAssembly non è supportato",
|
||||
"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.",
|
||||
@@ -1141,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",
|
||||
@@ -1157,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": {
|
||||
@@ -652,7 +652,7 @@
|
||||
"moderationInEffectTitle": "Ваш микрофон отключен модератором",
|
||||
"moderationInEffectVideoDescription": "Пожалуйста, поднимите руку, если хотите включить камеру.",
|
||||
"moderationInEffectVideoTitle": "Ваша камера заблокирована модератором",
|
||||
"moderationRequestFromModerator": "Хозяин хочет, чтобы вы включили звук",
|
||||
"moderationRequestFromModerator": "Модератор хочет, чтобы вы включили звук",
|
||||
"moderationRequestFromParticipant": "Хочет говорить",
|
||||
"moderationStartedTitle": "Началась модерация",
|
||||
"moderationStoppedTitle": "Модерация остановлена",
|
||||
@@ -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,13 +894,23 @@
|
||||
"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.",
|
||||
"localRecordingNoVideo": "Video is not being recorded",
|
||||
"localRecordingStartWarning": "Please make sure you stop the recording before exiting the meeting in order to save it.",
|
||||
"localRecordingStartWarningTitle": "Stop the recording to save it",
|
||||
"localRecordingVideoStop": "Stopping your video will also stop the local recording. Are you sure you want to continue?",
|
||||
"localRecordingVideoWarning": "To record your video you must have it on when starting the recording",
|
||||
"localRecordingWarning": "Make sure you select the current tab in order to use the right video and audio. The recording is currently limited to 1GB, which is around 100 minutes.",
|
||||
"loggedIn": "Logged in as {{userName}}",
|
||||
"noStreams": "No audio or video stream detected.",
|
||||
"off": "Recording stopped",
|
||||
"offBy": "{{name}} stopped the recording",
|
||||
"on": "Recording started",
|
||||
"onBy": "{{name}} started the recording",
|
||||
"onlyRecordSelf": "Record only my audio and video streams",
|
||||
"pending": "Preparing to record the meeting...",
|
||||
"rec": "REC",
|
||||
"saveLocalRecording": "Save recording file locally",
|
||||
"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,10 +918,12 @@
|
||||
"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"
|
||||
},
|
||||
"screenshareDisplayName": "{{name}}'s screen",
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Pull to refresh"
|
||||
},
|
||||
@@ -927,10 +957,12 @@
|
||||
"name": "Name",
|
||||
"noDevice": "None",
|
||||
"participantJoined": "Participant Joined",
|
||||
"participantKnocking": "Participant entered lobby",
|
||||
"participantLeft": "Participant Left",
|
||||
"playSounds": "Play sound on",
|
||||
"reactions": "Meeting reactions",
|
||||
"sameAsSystem": "Same as system ({{label}})",
|
||||
"screenTitle": "Settings",
|
||||
"selectAudioOutput": "Audio output",
|
||||
"selectCamera": "Camera",
|
||||
"selectMic": "Microphone",
|
||||
@@ -956,6 +988,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",
|
||||
@@ -1000,6 +1033,7 @@
|
||||
"termsView": {
|
||||
"header": "Terms"
|
||||
},
|
||||
"toggleTopPanelLabel": "Toggle top panel",
|
||||
"toolbar": {
|
||||
"Settings": "Settings",
|
||||
"accessibilityLabel": {
|
||||
@@ -1009,10 +1043,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",
|
||||
@@ -1063,6 +1099,7 @@
|
||||
"tileView": "Toggle tile view",
|
||||
"toggleCamera": "Toggle camera",
|
||||
"toggleFilmstrip": "Toggle filmstrip",
|
||||
"undock": "Undock into separate window",
|
||||
"videoblur": "Toggle video blur",
|
||||
"videomute": "Start / Stop camera"
|
||||
},
|
||||
@@ -1079,6 +1116,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",
|
||||
@@ -1147,6 +1185,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;
|
||||
@@ -725,6 +742,9 @@ function initCommands() {
|
||||
case 'is-sharing-screen':
|
||||
callback(Boolean(APP.conference.isSharingScreen));
|
||||
break;
|
||||
case 'is-start-silent':
|
||||
callback(Boolean(APP.store.getState()['features/base/config'].startSilent));
|
||||
break;
|
||||
case 'get-content-sharing-participants': {
|
||||
const tracks = getState()['features/base/tracks'];
|
||||
const sharingParticipantIds = tracks.filter(tr => tr.videoType === 'desktop').map(t => t.participantId);
|
||||
@@ -1441,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.
|
||||
@@ -1646,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.
|
||||
*
|
||||
|
||||
36
modules/API/external/external_api.js
vendored
36
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.
|
||||
*
|
||||
@@ -978,6 +999,17 @@ export default class JitsiMeetExternalAPI extends EventEmitter {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns wether meeting is started silent.
|
||||
*
|
||||
* @returns {Promise} - Resolves with start silent status.
|
||||
*/
|
||||
isStartSilent() {
|
||||
return this._transport.sendRequest({
|
||||
name: 'is-start-silent'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the avatar URL of a participant.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
3761
package-lock.json
generated
3761
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
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/stack": "6.2.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,11 +77,11 @@
|
||||
"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/v1415.0.0+fa916d41/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/v1466.0.0+2682b4ec/lib-jitsi-meet.tgz",
|
||||
"lodash": "4.17.21",
|
||||
"moment": "2.29.2",
|
||||
"moment": "2.29.4",
|
||||
"moment-duration-format": "2.2.2",
|
||||
"optional-require": "1.0.3",
|
||||
"promise.allsettled": "1.0.4",
|
||||
@@ -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,9 +107,9 @@
|
||||
"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-screens": "3.13.1",
|
||||
"react-native-sound": "0.11.1",
|
||||
"react-native-splash-screen": "3.3.0",
|
||||
"react-native-svg": "12.1.0",
|
||||
@@ -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",
|
||||
@@ -129,10 +130,12 @@
|
||||
"redux-thunk": "2.2.0",
|
||||
"resemblejs": "4.0.0",
|
||||
"rnnoise-wasm": "https://git@github.com/jitsi/rnnoise-wasm#566a16885897704d6e6d67a1d5ac5d39781db2af",
|
||||
"seamless-scroll-polyfill": "2.1.8",
|
||||
"styled-components": "3.4.9",
|
||||
"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 +148,13 @@
|
||||
"@babel/preset-react": "7.16.0",
|
||||
"@babel/runtime": "7.16.0",
|
||||
"@jitsi/eslint-config": "4.0.0",
|
||||
"@types/lodash": "4.14.182",
|
||||
"@types/react": "17.0.14",
|
||||
"@types/react-native": "0.67.6",
|
||||
"@types/react-redux": "7.1.24",
|
||||
"@types/uuid": "8.3.4",
|
||||
"@typescript-eslint/eslint-plugin": "5.30.5",
|
||||
"@typescript-eslint/parser": "5.30.4",
|
||||
"babel-loader": "8.2.3",
|
||||
"babel-plugin-optional-require": "0.3.1",
|
||||
"circular-dependency-plugin": "5.2.0",
|
||||
@@ -159,7 +169,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 +177,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",
|
||||
@@ -180,11 +190,15 @@
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"lint": "eslint --max-warnings 0 .",
|
||||
"lint": "eslint --ext .js,.ts,.tsx --max-warnings 0 .",
|
||||
"lang-sort": "./resources/lang-sort.sh",
|
||||
"lint-fix": "eslint --max-warnings 0 --fix .",
|
||||
"postinstall": "patch-package && jetify",
|
||||
"lint-fix": "eslint --ext .js,.ts,.tsx --max-warnings 0 --fix .",
|
||||
"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;',
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user