mirror of
https://gitcode.com/GitHub_Trending/ji/jitsi-meet.git
synced 2026-01-03 21:32:28 +00:00
Compare commits
385 Commits
4189
...
fix/preven
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c91aef29a3 | ||
|
|
b5310573fc | ||
|
|
aa488cb75c | ||
|
|
de8e62ac51 | ||
|
|
f6d375f565 | ||
|
|
c54fed78c8 | ||
|
|
3d7ea52416 | ||
|
|
0c4d649459 | ||
|
|
af416ad487 | ||
|
|
1cd6f2b4da | ||
|
|
1fb37a0216 | ||
|
|
c261682a29 | ||
|
|
49548ba564 | ||
|
|
dc6d3daef7 | ||
|
|
014f3b615f | ||
|
|
25271d7eec | ||
|
|
7ef4de9c1c | ||
|
|
e6e088d197 | ||
|
|
0e034a686f | ||
|
|
d9f85c70f1 | ||
|
|
de8079cc98 | ||
|
|
2a9805f9b1 | ||
|
|
00ec0f03a6 | ||
|
|
91f636a813 | ||
|
|
fa4df19733 | ||
|
|
1d17cc91e0 | ||
|
|
93f4098dc0 | ||
|
|
11ae187ece | ||
|
|
0f9e01a7cf | ||
|
|
ddbd3f292a | ||
|
|
b153bf2fb8 | ||
|
|
919be21912 | ||
|
|
1a339100ab | ||
|
|
ce4ef96941 | ||
|
|
993ded9936 | ||
|
|
a8b9ae2b12 | ||
|
|
812af33a4d | ||
|
|
7f17c2eceb | ||
|
|
09124ad7e9 | ||
|
|
7a9a6855b7 | ||
|
|
8dcf04897a | ||
|
|
69b7301b9d | ||
|
|
794713b930 | ||
|
|
89cd6e8e3e | ||
|
|
7a7937c072 | ||
|
|
4765ab9d63 | ||
|
|
1d5decc14f | ||
|
|
119b79fd84 | ||
|
|
188771751d | ||
|
|
d2ec0ea6f3 | ||
|
|
ed6e75b241 | ||
|
|
dedd3f4ef0 | ||
|
|
bbb4fbd5f8 | ||
|
|
92235ae535 | ||
|
|
ebb1b8d76b | ||
|
|
42d559de93 | ||
|
|
2838aefccc | ||
|
|
ca306f47b6 | ||
|
|
56da400f19 | ||
|
|
ab21e3cd5e | ||
|
|
2c026754ef | ||
|
|
8dbe3e37b9 | ||
|
|
7f67f78db6 | ||
|
|
312949eef6 | ||
|
|
41ea94c0c2 | ||
|
|
e70adef2ef | ||
|
|
57bbe3f75a | ||
|
|
e2731ce73e | ||
|
|
d5dae945a8 | ||
|
|
4d1dba937f | ||
|
|
b6792db65f | ||
|
|
9815b633fc | ||
|
|
b4bf82429c | ||
|
|
53d485b397 | ||
|
|
0354dbe889 | ||
|
|
7cafa205ee | ||
|
|
2b4f33bef8 | ||
|
|
31dee0bb68 | ||
|
|
fc75d45c6c | ||
|
|
25839b18d2 | ||
|
|
43f36c8cfd | ||
|
|
b02d96231c | ||
|
|
651d713206 | ||
|
|
9e5f469e0c | ||
|
|
493ce8249e | ||
|
|
fdffb688c1 | ||
|
|
4807badac8 | ||
|
|
5e3bd746e9 | ||
|
|
8fa41bebb7 | ||
|
|
cb7c280da6 | ||
|
|
0e50f1887e | ||
|
|
476ca54711 | ||
|
|
70aa19e6d9 | ||
|
|
7778a17b90 | ||
|
|
7ff41217ac | ||
|
|
e8c44c10dd | ||
|
|
b087b22d4f | ||
|
|
e988bf6565 | ||
|
|
d169bd5007 | ||
|
|
ac17db9df5 | ||
|
|
322618357c | ||
|
|
79c1358f4b | ||
|
|
5e85b5f63a | ||
|
|
74f7c4141f | ||
|
|
4866ddc2ad | ||
|
|
71d0577a49 | ||
|
|
b7529863d5 | ||
|
|
4ded94d130 | ||
|
|
eb8b730227 | ||
|
|
4bd57692b7 | ||
|
|
5d012c24a7 | ||
|
|
4f52a29120 | ||
|
|
8a4fb72eae | ||
|
|
6453ceb048 | ||
|
|
e51bbe6125 | ||
|
|
d725c0ab8a | ||
|
|
2c2edace2a | ||
|
|
d3d5847605 | ||
|
|
89ad76142d | ||
|
|
1e76b8b6ea | ||
|
|
55175e2e95 | ||
|
|
453c07cb17 | ||
|
|
af71d80150 | ||
|
|
b765adca75 | ||
|
|
92e6cf7618 | ||
|
|
10c2652a4f | ||
|
|
c3329ec931 | ||
|
|
9cf7199c0e | ||
|
|
d82bb0a89b | ||
|
|
295dd8a45d | ||
|
|
25ae83bcf4 | ||
|
|
82b1408454 | ||
|
|
36565f0c50 | ||
|
|
0c48e205d7 | ||
|
|
5e35b69fc9 | ||
|
|
3fd85720bc | ||
|
|
e439d065b7 | ||
|
|
5dcecdbb54 | ||
|
|
8d2a52d0e8 | ||
|
|
2aa6f7ff4b | ||
|
|
d716665f27 | ||
|
|
4ca4e242b1 | ||
|
|
cdd782a82f | ||
|
|
713ae817c0 | ||
|
|
d05fa32413 | ||
|
|
e6676bb09a | ||
|
|
8e9a51f742 | ||
|
|
3da7798e9f | ||
|
|
6fc9606c0d | ||
|
|
004c1b65ad | ||
|
|
eabcc078ef | ||
|
|
5b1f852783 | ||
|
|
5cf9a76f9e | ||
|
|
3f33adc5d0 | ||
|
|
d9250aa986 | ||
|
|
5b10d8f5ef | ||
|
|
02885ea716 | ||
|
|
7e70a57eb3 | ||
|
|
dbaa1168b3 | ||
|
|
b1d691ca07 | ||
|
|
10a4612230 | ||
|
|
21767fa7cf | ||
|
|
0bd100f027 | ||
|
|
f14a595462 | ||
|
|
5e4b8c747c | ||
|
|
c4155575f9 | ||
|
|
11ee71a51c | ||
|
|
c998d83f34 | ||
|
|
b670b29d7f | ||
|
|
9b7e8c98ad | ||
|
|
ad44558153 | ||
|
|
1a957ed85b | ||
|
|
1dbb47b84f | ||
|
|
4adaa6f1fd | ||
|
|
b3b561f27a | ||
|
|
a6a19a3002 | ||
|
|
1426a5b4bc | ||
|
|
858ee557d4 | ||
|
|
bd64c14aaa | ||
|
|
ce286f9be8 | ||
|
|
cc9cb6a874 | ||
|
|
168dbd6276 | ||
|
|
400c86ad5e | ||
|
|
b0650b8448 | ||
|
|
027cc1be96 | ||
|
|
9b32811ff2 | ||
|
|
a67d0fbf6c | ||
|
|
af5d4c850b | ||
|
|
7bfb2fc219 | ||
|
|
b814827df1 | ||
|
|
240b033e76 | ||
|
|
00b41dbb41 | ||
|
|
2689be5d24 | ||
|
|
f3da009d61 | ||
|
|
ddc2b4f26e | ||
|
|
b106e51a10 | ||
|
|
0cef706b6a | ||
|
|
b9c20a3fd4 | ||
|
|
23507da59a | ||
|
|
4bfc80ecb9 | ||
|
|
52ce8031a3 | ||
|
|
aa9f06fa84 | ||
|
|
a758e98101 | ||
|
|
63d4c2b84b | ||
|
|
4161e7bfe1 | ||
|
|
1c3cf325cb | ||
|
|
fdbd681c8f | ||
|
|
f6433668d5 | ||
|
|
1ae5630590 | ||
|
|
b1e12d33ab | ||
|
|
28094947a7 | ||
|
|
a23dac2ab6 | ||
|
|
d70f9d6fd6 | ||
|
|
9e7a477797 | ||
|
|
0fc748dc44 | ||
|
|
b831bb8350 | ||
|
|
16547b91a5 | ||
|
|
1e3e15fc72 | ||
|
|
9d6e21b77b | ||
|
|
48a58f8dae | ||
|
|
eb1ef0fa9c | ||
|
|
eaa715879a | ||
|
|
fde7cf4ab8 | ||
|
|
46b444c498 | ||
|
|
3cbadc72a1 | ||
|
|
ddaaeccafa | ||
|
|
0751c6ab48 | ||
|
|
76e4929add | ||
|
|
e39c8d8ed6 | ||
|
|
4687187cca | ||
|
|
7858f12df2 | ||
|
|
f2c3401a79 | ||
|
|
828e578af4 | ||
|
|
43189f3e66 | ||
|
|
335b43036d | ||
|
|
b3ca51c7d0 | ||
|
|
f9d545c531 | ||
|
|
5f5468995f | ||
|
|
4289b23135 | ||
|
|
bf7aa39947 | ||
|
|
ad948bdbe2 | ||
|
|
29366a0029 | ||
|
|
0bec7c7ab7 | ||
|
|
29805edd02 | ||
|
|
11fd5363ce | ||
|
|
1790c71c80 | ||
|
|
36d95ed51f | ||
|
|
ef0af1a8c0 | ||
|
|
b85cd2348f | ||
|
|
035f720a50 | ||
|
|
c8444a9a0d | ||
|
|
7f5751b918 | ||
|
|
fc6bd3667c | ||
|
|
2c42dd0773 | ||
|
|
1891ce0b24 | ||
|
|
e34c5673b2 | ||
|
|
41ba55a6a9 | ||
|
|
099820b6ac | ||
|
|
25ded0bdeb | ||
|
|
758b60f92b | ||
|
|
fcc69b92bb | ||
|
|
a697caea03 | ||
|
|
51fd10278b | ||
|
|
5b89709483 | ||
|
|
e4ce3928dc | ||
|
|
b0188a7184 | ||
|
|
53281c2d42 | ||
|
|
3da1b65757 | ||
|
|
0e5091adba | ||
|
|
f376542441 | ||
|
|
bd65108692 | ||
|
|
546b0abe32 | ||
|
|
62ad7d3451 | ||
|
|
5bc3128c71 | ||
|
|
b91d6b97a9 | ||
|
|
ce812591f9 | ||
|
|
f32140c4b7 | ||
|
|
7d513738d2 | ||
|
|
8d1bde3cb1 | ||
|
|
95825dcdd7 | ||
|
|
a61f272303 | ||
|
|
3538761543 | ||
|
|
f22d5ed629 | ||
|
|
f30dd9d881 | ||
|
|
4a3cd2596a | ||
|
|
4e1f42a665 | ||
|
|
1fff5d2567 | ||
|
|
bbcc40a97e | ||
|
|
bbf76296ed | ||
|
|
e0b3a81a41 | ||
|
|
1c122705bf | ||
|
|
29c16e42bd | ||
|
|
8a19a34d19 | ||
|
|
d5832f226d | ||
|
|
4cfc8cd7a2 | ||
|
|
873ede0e06 | ||
|
|
f73e9947c0 | ||
|
|
82711b3f23 | ||
|
|
2f841fab73 | ||
|
|
b3a2905849 | ||
|
|
5f579e9a15 | ||
|
|
ea2ea89ef7 | ||
|
|
a5f17a8033 | ||
|
|
4c6e9e7788 | ||
|
|
a7e0df2623 | ||
|
|
da9a70129e | ||
|
|
6d3d15a64b | ||
|
|
b10a45bf98 | ||
|
|
858a3d953c | ||
|
|
1ff27b7298 | ||
|
|
bc43f00d28 | ||
|
|
bfd5db355d | ||
|
|
a4ca247056 | ||
|
|
eac891585b | ||
|
|
7d62020787 | ||
|
|
7d18183bf9 | ||
|
|
346dac476a | ||
|
|
b4ecef429a | ||
|
|
ea07515138 | ||
|
|
79231914b9 | ||
|
|
0e1ecd3256 | ||
|
|
0d15c01077 | ||
|
|
24c75b7332 | ||
|
|
2327a6d0b4 | ||
|
|
b94c357cc2 | ||
|
|
216801720a | ||
|
|
312813e677 | ||
|
|
2b5787163e | ||
|
|
28632752ba | ||
|
|
7dfff1b455 | ||
|
|
99e7d636b7 | ||
|
|
4b1743bb2f | ||
|
|
3b1ad9faff | ||
|
|
87b14c3711 | ||
|
|
5811e0476c | ||
|
|
59750ba1f1 | ||
|
|
b3de7fd52b | ||
|
|
f68b9b7df9 | ||
|
|
b534c4f624 | ||
|
|
ab1c5805f4 | ||
|
|
0c6b0641f5 | ||
|
|
093254d948 | ||
|
|
0494200383 | ||
|
|
16f1c167b8 | ||
|
|
97fd36a19a | ||
|
|
701d34248b | ||
|
|
e72dae5c32 | ||
|
|
811ee40d99 | ||
|
|
76eabf1f29 | ||
|
|
01a8cc1478 | ||
|
|
047c9b43ea | ||
|
|
22d040ab76 | ||
|
|
4ac9ea258c | ||
|
|
6bd64ee552 | ||
|
|
7a1595f162 | ||
|
|
07cad2a98f | ||
|
|
6fbba52c6d | ||
|
|
311d1c67ba | ||
|
|
0aa54d8650 | ||
|
|
74e0e10928 | ||
|
|
4f169988a3 | ||
|
|
ec6ed6e8ec | ||
|
|
7b429afee6 | ||
|
|
cab830aad1 | ||
|
|
bd42c81cb8 | ||
|
|
f230fd4d04 | ||
|
|
eed57e7999 | ||
|
|
8115f86f59 | ||
|
|
28e5edfb50 | ||
|
|
e936c6dc2c | ||
|
|
8efd0f0829 | ||
|
|
a49f04f25b | ||
|
|
bcffe0bba5 | ||
|
|
482ba23954 | ||
|
|
e87167dd2d | ||
|
|
cf047a3c90 | ||
|
|
a8b8612304 | ||
|
|
95a5b8a8c1 | ||
|
|
5867eaf560 | ||
|
|
9143bb42d1 | ||
|
|
0e5dac623e | ||
|
|
0c09ded76b | ||
|
|
929622b27c | ||
|
|
430125a8bd | ||
|
|
66505666df |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -84,3 +84,4 @@ android/app/google-services.json
|
||||
ios/app/dropbox.key
|
||||
ios/app/GoogleService-Info.plist
|
||||
|
||||
.vscode
|
||||
|
||||
17
Makefile
17
Makefile
@@ -3,8 +3,9 @@ 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/olm
|
||||
RNNOISE_WASM_DIR = node_modules/rnnoise-wasm/dist/
|
||||
NODE_SASS = ./node_modules/.bin/node-sass
|
||||
NODE_SASS = ./node_modules/.bin/sass
|
||||
NPM = npm
|
||||
OUTPUT_DIR = .
|
||||
STYLES_BUNDLE = css/all.bundle.css
|
||||
@@ -22,7 +23,7 @@ clean:
|
||||
rm -fr $(BUILD_DIR)
|
||||
|
||||
.NOTPARALLEL:
|
||||
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac deploy-css deploy-local
|
||||
deploy: deploy-init deploy-appbundle deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac deploy-olm deploy-css deploy-local
|
||||
|
||||
deploy-init:
|
||||
rm -fr $(DEPLOY_DIR)
|
||||
@@ -51,12 +52,15 @@ deploy-appbundle:
|
||||
$(BUILD_DIR)/video-blur-effect.min.map \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.js \
|
||||
$(BUILD_DIR)/rnnoise-processor.min.map \
|
||||
$(BUILD_DIR)/close3.min.js \
|
||||
$(BUILD_DIR)/close3.min.map \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-lib-jitsi-meet:
|
||||
cp \
|
||||
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.min.js \
|
||||
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.min.map \
|
||||
$(LIBJITSIMEET_DIR)/lib-jitsi-meet.e2ee-worker.js \
|
||||
$(LIBJITSIMEET_DIR)/connection_optimization/external_connect.js \
|
||||
$(LIBJITSIMEET_DIR)/modules/browser/capabilities.json \
|
||||
$(DEPLOY_DIR)
|
||||
@@ -67,6 +71,11 @@ deploy-libflac:
|
||||
$(LIBFLAC_DIR)/libflac4-1.3.2.min.js.mem \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-olm:
|
||||
cp \
|
||||
$(OLM_DIR)/olm.wasm \
|
||||
$(DEPLOY_DIR)
|
||||
|
||||
deploy-rnnoise-binary:
|
||||
cp \
|
||||
$(RNNOISE_WASM_DIR)/rnnoise.wasm \
|
||||
@@ -74,14 +83,14 @@ deploy-rnnoise-binary:
|
||||
|
||||
deploy-css:
|
||||
$(NODE_SASS) $(STYLES_MAIN) $(STYLES_BUNDLE) && \
|
||||
$(CLEANCSS) $(STYLES_BUNDLE) > $(STYLES_DESTINATION) ; \
|
||||
$(CLEANCSS) --skip-rebase $(STYLES_BUNDLE) > $(STYLES_DESTINATION) ; \
|
||||
rm $(STYLES_BUNDLE)
|
||||
|
||||
deploy-local:
|
||||
([ ! -x deploy-local.sh ] || ./deploy-local.sh)
|
||||
|
||||
.NOTPARALLEL:
|
||||
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac
|
||||
dev: deploy-init deploy-css deploy-rnnoise-binary deploy-lib-jitsi-meet deploy-libflac deploy-olm
|
||||
$(WEBPACK_DEV_SERVER) --detect-circular-deps
|
||||
|
||||
source-package:
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# Security
|
||||
|
||||
## Reporting security issuess
|
||||
## Reporting security issues
|
||||
|
||||
We take security very seriously and develop all Jitsi projects to be secure and safe.
|
||||
|
||||
If you find (or simply suspect) a security issue in any of the Jitsi projects, please send us an email to security@jitsi.org.
|
||||
If you find (or simply suspect) a security issue in any of the Jitsi projects, please report it to us via [HackerOne](https://hackerone.com/8x8) or send us an email to security@jitsi.org.
|
||||
|
||||
**We encourage responsible disclosure for the sake of our users, so please reach out before posting in a public space.**
|
||||
|
||||
@@ -3,7 +3,7 @@ apply plugin: 'com.android.application'
|
||||
// Crashlytics integration is done as part of Firebase now, so it gets
|
||||
// automagically activated with google-services.json
|
||||
if (googleServicesEnabled) {
|
||||
apply plugin: 'io.fabric'
|
||||
apply plugin: 'com.google.firebase.crashlytics'
|
||||
}
|
||||
|
||||
// Use the number of seconds/10 since Jan 1 2019 as the versionCode.
|
||||
@@ -16,6 +16,10 @@ android {
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
buildToolsVersion rootProject.ext.buildToolsVersion
|
||||
|
||||
packagingOptions {
|
||||
exclude 'lib/*/libhermes*.so'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId 'org.jitsi.meet'
|
||||
versionCode vcode
|
||||
@@ -70,16 +74,11 @@ android {
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.0-beta-5'
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.2'
|
||||
|
||||
if (!rootProject.ext.libreBuild) {
|
||||
implementation 'com.google.android.gms:play-services-auth:16.0.1'
|
||||
@@ -87,9 +86,9 @@ dependencies {
|
||||
// Firebase
|
||||
// - Crashlytics
|
||||
// - Dynamic Links
|
||||
implementation 'com.google.firebase:firebase-core:16.0.6'
|
||||
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'
|
||||
implementation 'com.google.firebase:firebase-dynamic-links:16.1.5'
|
||||
implementation 'com.google.firebase:firebase-analytics:17.5.0'
|
||||
implementation 'com.google.firebase:firebase-crashlytics:17.2.1'
|
||||
implementation 'com.google.firebase:firebase-dynamic-links:19.1.0'
|
||||
}
|
||||
|
||||
implementation project(':sdk')
|
||||
|
||||
6
android/app/proguard-rules.pro
vendored
6
android/app/proguard-rules.pro
vendored
@@ -85,8 +85,4 @@
|
||||
# ^^^ We added the above when we switched minifyEnabled on.
|
||||
|
||||
# Rule to avoid build errors related to SVGs.
|
||||
-keep public class com.horcrux.svg.** {*;}
|
||||
|
||||
# Hermes
|
||||
-keep class com.facebook.hermes.unicode.** { *; }
|
||||
|
||||
-keep public class com.horcrux.svg.** {*;}
|
||||
@@ -1,12 +1,16 @@
|
||||
<manifest
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.jitsi.meet">
|
||||
package="org.jitsi.meet"
|
||||
android:installLocation="auto">
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:networkSecurityConfig="@xml/network_security_config"
|
||||
android:theme="@style/AppTheme">
|
||||
<meta-data
|
||||
android:name="android.content.APP_RESTRICTIONS"
|
||||
android:resource="@xml/app_restrictions" />
|
||||
<activity
|
||||
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize"
|
||||
android:label="@string/app_name"
|
||||
|
||||
@@ -3,9 +3,8 @@ package org.jitsi.meet;
|
||||
import android.net.Uri;
|
||||
import android.util.Log;
|
||||
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.google.firebase.crashlytics.FirebaseCrashlytics;
|
||||
import com.google.firebase.dynamiclinks.FirebaseDynamicLinks;
|
||||
import io.fabric.sdk.android.Fabric;
|
||||
|
||||
import org.jitsi.meet.sdk.JitsiMeet;
|
||||
import org.jitsi.meet.sdk.JitsiMeetActivity;
|
||||
@@ -22,10 +21,7 @@ final class GoogleServicesHelper {
|
||||
if (BuildConfig.GOOGLE_SERVICES_ENABLED) {
|
||||
Log.d(activity.getClass().getSimpleName(), "Initializing Google Services");
|
||||
|
||||
if (!JitsiMeet.isCrashReportingDisabled(activity)) {
|
||||
Fabric.with(activity, new Crashlytics());
|
||||
}
|
||||
|
||||
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(!JitsiMeet.isCrashReportingDisabled(activity));
|
||||
FirebaseDynamicLinks.getInstance().getDynamicLink(activity.getIntent())
|
||||
.addOnSuccessListener(activity, pendingDynamicLinkData -> {
|
||||
Uri dynamicLink = null;
|
||||
|
||||
@@ -16,9 +16,14 @@
|
||||
|
||||
package org.jitsi.meet;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.RestrictionEntry;
|
||||
import android.content.RestrictionsManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
@@ -31,6 +36,7 @@ import org.jitsi.meet.sdk.JitsiMeetConferenceOptions;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -48,6 +54,27 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
private static final int OVERLAY_PERMISSION_REQUEST_CODE
|
||||
= (int) (Math.random() * Short.MAX_VALUE);
|
||||
|
||||
/**
|
||||
* ServerURL configuration key for restriction configuration using {@link android.content.RestrictionsManager}
|
||||
*/
|
||||
public static final String RESTRICTION_SERVER_URL = "SERVER_URL";
|
||||
|
||||
/**
|
||||
* Broadcast receiver for restrictions handling
|
||||
*/
|
||||
private BroadcastReceiver broadcastReceiver;
|
||||
|
||||
/**
|
||||
* Flag if configuration is provided by RestrictionManager
|
||||
*/
|
||||
private boolean configurationByRestrictions = false;
|
||||
|
||||
/**
|
||||
* Default URL as could be obtained from RestrictionManager
|
||||
*/
|
||||
private String defaultURL;
|
||||
|
||||
|
||||
// JitsiMeetActivity overrides
|
||||
//
|
||||
|
||||
@@ -68,7 +95,7 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
// In Debug builds React needs permission to write over other apps in
|
||||
// order to display the warning and error overlays.
|
||||
if (BuildConfig.DEBUG) {
|
||||
if (canRequestOverlayPermission() && !Settings.canDrawOverlays(this)) {
|
||||
if (!Settings.canDrawOverlays(this)) {
|
||||
Intent intent
|
||||
= new Intent(
|
||||
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
|
||||
@@ -85,16 +112,67 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
broadcastReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// As new restrictions including server URL are received,
|
||||
// conference should be restarted with new configuration.
|
||||
leave();
|
||||
recreate();
|
||||
}
|
||||
};
|
||||
registerReceiver(broadcastReceiver,
|
||||
new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED));
|
||||
|
||||
resolveRestrictions();
|
||||
setJitsiMeetConferenceDefaultOptions();
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
if (broadcastReceiver != null) {
|
||||
unregisterReceiver(broadcastReceiver);
|
||||
broadcastReceiver = null;
|
||||
}
|
||||
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void setJitsiMeetConferenceDefaultOptions() {
|
||||
// Set default options
|
||||
JitsiMeetConferenceOptions defaultOptions
|
||||
= new JitsiMeetConferenceOptions.Builder()
|
||||
.setWelcomePageEnabled(true)
|
||||
.setServerURL(buildURL("https://meet.jit.si"))
|
||||
.setFeatureFlag("call-integration.enabled", false)
|
||||
.build();
|
||||
.setWelcomePageEnabled(true)
|
||||
.setServerURL(buildURL(defaultURL))
|
||||
.setFeatureFlag("call-integration.enabled", false)
|
||||
.setFeatureFlag("resolution", 360)
|
||||
.setFeatureFlag("server-url-change.enabled", !configurationByRestrictions)
|
||||
.build();
|
||||
JitsiMeet.setDefaultConferenceOptions(defaultOptions);
|
||||
}
|
||||
|
||||
super.initialize();
|
||||
private void resolveRestrictions() {
|
||||
RestrictionsManager manager =
|
||||
(RestrictionsManager) getSystemService(Context.RESTRICTIONS_SERVICE);
|
||||
Bundle restrictions = manager.getApplicationRestrictions();
|
||||
Collection<RestrictionEntry> entries = manager.getManifestRestrictions(
|
||||
getApplicationContext().getPackageName());
|
||||
for (RestrictionEntry restrictionEntry : entries) {
|
||||
String key = restrictionEntry.getKey();
|
||||
if (RESTRICTION_SERVER_URL.equals(key)) {
|
||||
// If restrictions are passed to the application.
|
||||
if (restrictions != null &&
|
||||
restrictions.containsKey(RESTRICTION_SERVER_URL)) {
|
||||
defaultURL = restrictions.getString(RESTRICTION_SERVER_URL);
|
||||
configurationByRestrictions = true;
|
||||
// Otherwise use default URL from app-restrictions.xml.
|
||||
} else {
|
||||
defaultURL = restrictionEntry.getSelectedString();
|
||||
configurationByRestrictions = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,8 +185,7 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == OVERLAY_PERMISSION_REQUEST_CODE
|
||||
&& canRequestOverlayPermission()) {
|
||||
if (requestCode == OVERLAY_PERMISSION_REQUEST_CODE) {
|
||||
if (Settings.canDrawOverlays(this)) {
|
||||
initialize();
|
||||
return;
|
||||
@@ -131,6 +208,18 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
return super.onKeyUp(keyCode, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPictureInPictureModeChanged(boolean isInPictureInPictureMode) {
|
||||
super.onPictureInPictureModeChanged(isInPictureInPictureMode);
|
||||
|
||||
Log.d(TAG, "Is in picture-in-picture mode: " + isInPictureInPictureMode);
|
||||
|
||||
if (!isInPictureInPictureMode) {
|
||||
this.startActivity(new Intent(this, getClass())
|
||||
.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT));
|
||||
}
|
||||
}
|
||||
|
||||
// Helper methods
|
||||
//
|
||||
|
||||
@@ -141,10 +230,4 @@ public class MainActivity extends JitsiMeetActivity {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canRequestOverlayPermission() {
|
||||
return
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
|
||||
&& getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.M;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">Jitsi Meet</string>
|
||||
<string name="restriction_server_url_description">URL of Jitsi Meet server instance to connect to</string>
|
||||
<string name="restriction_server_url_title">Server URL</string>
|
||||
</resources>
|
||||
|
||||
11
android/app/src/main/res/xml/app_restrictions.xml
Normal file
11
android/app/src/main/res/xml/app_restrictions.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- Server URL configuration -->
|
||||
<restriction
|
||||
android:defaultValue="https://meet.jit.si"
|
||||
android:description="@string/restriction_server_url_description"
|
||||
android:key="SERVER_URL"
|
||||
android:restrictionType="string"
|
||||
android:title="@string/restriction_server_url_title"/>
|
||||
</restrictions>
|
||||
@@ -1,6 +1,12 @@
|
||||
<network-security-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="false">localhost</domain>
|
||||
<domain includeSubdomains="false">10.0.2.2</domain>
|
||||
</domain-config>
|
||||
<network-security-config>
|
||||
<base-config>
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
<certificates src="user" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="false">localhost</domain>
|
||||
<domain includeSubdomains="false">10.0.2.2</domain>
|
||||
</domain-config>
|
||||
</network-security-config>
|
||||
|
||||
@@ -7,26 +7,46 @@ buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.3.2'
|
||||
classpath 'com.android.tools.build:gradle:4.0.1'
|
||||
classpath 'com.google.gms:google-services:4.3.3'
|
||||
classpath 'io.fabric.tools:gradle:1.28.1'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files.
|
||||
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.3.0'
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
buildToolsVersion = "29.0.3"
|
||||
compileSdkVersion = 29
|
||||
minSdkVersion = 23
|
||||
targetSdkVersion = 29
|
||||
supportLibVersion = "28.0.0"
|
||||
|
||||
// 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
|
||||
// third-party Maven repositories so we have to deploy to a Maven repository
|
||||
// of ours.
|
||||
moduleGroupId = 'com.facebook.react'
|
||||
|
||||
// Maven repo where artifacts will be published
|
||||
mavenRepo = System.env.MVN_REPO ?: ""
|
||||
mavenUser = System.env.MVN_USER ?: ""
|
||||
mavenPassword = System.env.MVN_PASSWORD ?: ""
|
||||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
// React Native (JS, Obj-C sources, Android binaries) is installed from npm.
|
||||
maven { url "$rootDir/../node_modules/react-native/android" }
|
||||
// Android JSC is installed from npm.
|
||||
maven { url("$rootDir/../node_modules/jsc-android/dist") }
|
||||
}
|
||||
|
||||
// Make sure we use the react-native version in node_modules and not the one
|
||||
@@ -141,30 +161,6 @@ allprojects {
|
||||
}
|
||||
}
|
||||
|
||||
ext {
|
||||
buildToolsVersion = "28.0.3"
|
||||
compileSdkVersion = 28
|
||||
minSdkVersion = 21
|
||||
targetSdkVersion = 28
|
||||
supportLibVersion = "28.0.0"
|
||||
|
||||
// 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
|
||||
// third-party Maven repositories so we have to deploy to a Maven repository
|
||||
// of ours.
|
||||
moduleGroupId = 'com.facebook.react'
|
||||
|
||||
// Maven repo where artifacts will be published
|
||||
mavenRepo = System.env.MVN_REPO ?: ""
|
||||
mavenUser = System.env.MVN_USER ?: ""
|
||||
mavenPassword = System.env.MVN_PASSWORD ?: ""
|
||||
|
||||
// Libre build
|
||||
libreBuild = (System.env.LIBRE_BUILD ?: "false").toBoolean()
|
||||
|
||||
googleServicesEnabled = project.file('app/google-services.json').exists() && !libreBuild
|
||||
}
|
||||
|
||||
// Force the version of the Android build tools we have chosen on all
|
||||
// subprojects. The forcing was introduced for react-native and the third-party
|
||||
// modules that we utilize such as react-native-background-timer.
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
# Default value: -Xmx10248m -XX:MaxPermSize=256m
|
||||
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
@@ -20,5 +21,5 @@
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
appVersion=20.3.0
|
||||
sdkVersion=2.9.0
|
||||
appVersion=20.5.0
|
||||
sdkVersion=2.11.0
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Fri Mar 08 13:36:51 CET 2019
|
||||
#Wed Sep 23 11:48:00 EEST 2020
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip
|
||||
|
||||
@@ -10,7 +10,7 @@ MVN_HTTP=0
|
||||
DEFAULT_SDK_VERSION=$(grep sdkVersion ${THIS_DIR}/../gradle.properties | cut -d"=" -f2)
|
||||
SDK_VERSION=${OVERRIDE_SDK_VERSION:-${DEFAULT_SDK_VERSION}}
|
||||
RN_VERSION=$(jq -r '.version' ${THIS_DIR}/../../node_modules/react-native/package.json)
|
||||
HERMES_VERSION=$(jq -r '.dependencies."hermes-engine"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -c 2-)
|
||||
JSC_VERSION="r"$(jq -r '.dependencies."jsc-android"' ${THIS_DIR}/../../node_modules/react-native/package.json | cut -d . -f 1 | cut -c 2-)
|
||||
DO_GIT_TAG=${GIT_TAG:-0}
|
||||
|
||||
if [[ $THE_MVN_REPO == http* ]]; then
|
||||
@@ -38,19 +38,17 @@ if [[ $MVN_HTTP == 1 ]]; then
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=react-native-${RN_VERSION}.pom || true
|
||||
popd
|
||||
# Push Hermes
|
||||
echo "Pushing Hermes ${HERMES_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/hermes-engine/android/
|
||||
# Push JSC
|
||||
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/jsc-android/dist/org/webkit/android-jsc/${JSC_VERSION}
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-DrepositoryId=${MVN_REPO_ID} \
|
||||
-Dfile=hermes-release.aar \
|
||||
-Dfile=android-jsc-${JSC_VERSION}.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgroupId=com.facebook \
|
||||
-DartifactId=hermes \
|
||||
-Dversion=${HERMES_VERSION} \
|
||||
-DgeneratePom=true || true
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=android-jsc-${JSC_VERSION}.pom || true
|
||||
popd
|
||||
else
|
||||
# Push React Native, if necessary
|
||||
@@ -67,19 +65,17 @@ else
|
||||
popd
|
||||
fi
|
||||
|
||||
# Push Hermes, if necessary
|
||||
if [[ ! -d ${MVN_REPO}/com/facebook/hermes/${HERMES_VERSION} ]]; then
|
||||
echo "Pushing Hermes ${HERMES_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/hermes-engine/android/
|
||||
# Push JSC, if necessary
|
||||
if [[ ! -d ${MVN_REPO}/org/webkit/android-jsc/${JSC_VERSION} ]]; then
|
||||
echo "Pushing JSC ${JSC_VERSION} to the Maven repo"
|
||||
pushd ${THIS_DIR}/../../node_modules/jsc-android/dist/org/webkit/android-jsc/${JSC_VERSION}
|
||||
mvn \
|
||||
deploy:deploy-file \
|
||||
-Durl=${MVN_REPO} \
|
||||
-Dfile=hermes-release.aar \
|
||||
-Dfile=android-jsc-${JSC_VERSION}.aar \
|
||||
-Dpackaging=aar \
|
||||
-DgroupId=com.facebook \
|
||||
-DartifactId=hermes \
|
||||
-Dversion=${HERMES_VERSION} \
|
||||
-DgeneratePom=true
|
||||
-DgeneratePom=false \
|
||||
-DpomFile=android-jsc-${JSC_VERSION}.pom
|
||||
popd
|
||||
fi
|
||||
|
||||
|
||||
5
android/scripts/run-packager-helper.command
Executable file
5
android/scripts/run-packager-helper.command
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
|
||||
exec ${THIS_DIR}/../../node_modules/react-native/scripts/launchPackager.command --reset-cache
|
||||
@@ -8,7 +8,7 @@ THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOUR
|
||||
export RCT_METRO_PORT="${RCT_METRO_PORT:=8081}"
|
||||
echo "export RCT_METRO_PORT=${RCT_METRO_PORT}" > "${THIS_DIR}/../../node_modules/react-native/scripts/.packager.env"
|
||||
|
||||
adb reverse tcp:8081 tcp:8081
|
||||
adb reverse tcp:$RCT_METRO_PORT tcp:$RCT_METRO_PORT
|
||||
|
||||
if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then
|
||||
if ! curl -s "http://localhost:${RCT_METRO_PORT}/status" | grep -q "packager-status:running" ; then
|
||||
@@ -16,11 +16,10 @@ if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
CMD="${THIS_DIR}/../../node_modules/react-native/scripts/launchPackager.command"
|
||||
CMD="$THIS_DIR/run-packager-helper.command"
|
||||
if [[ `uname` == "Darwin" ]]; then
|
||||
open -g "${CMD}" || echo "Can't start packager automatically"
|
||||
else
|
||||
xdg-open "${CMD}" || echo "Can't start packager automatically"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import groovy.json.JsonSlurper
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
@@ -35,26 +33,19 @@ android {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst '**/libc++_shared.so'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.fragment:fragment:1.2.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.fragment:fragment:1.2.5'
|
||||
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
api 'com.facebook.react:react-native:+'
|
||||
|
||||
// Hermes JS engine
|
||||
def hermesPath = "../../node_modules/hermes-engine/android/"
|
||||
debugImplementation files(hermesPath + "hermes-debug.aar")
|
||||
releaseImplementation files(hermesPath + "hermes-release.aar")
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation 'org.webkit:android-jsc:+'
|
||||
|
||||
implementation 'com.dropbox.core:dropbox-core-sdk:3.0.8'
|
||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||
@@ -153,7 +144,7 @@ android.libraryVariants.all { def variant ->
|
||||
mergeResourcesTask.dependsOn(currentBundleTask)
|
||||
|
||||
mergeAssetsTask.doLast {
|
||||
def assetsDir = mergeAssetsTask.outputDir
|
||||
def assetsDir = mergeAssetsTask.outputDir.get()
|
||||
|
||||
// Bundle sounds
|
||||
//
|
||||
@@ -187,7 +178,7 @@ android.libraryVariants.all { def variant ->
|
||||
if (currentBundleTask.enabled) {
|
||||
copy {
|
||||
from(resourcesDir)
|
||||
into(mergeResourcesTask.outputDir)
|
||||
into(mergeResourcesTask.outputDir.get())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -227,14 +218,6 @@ publishing {
|
||||
dependency.appendNode('artifactId', artifactId)
|
||||
dependency.appendNode('version', it.moduleVersion)
|
||||
}
|
||||
|
||||
// Add Hermes dependency.
|
||||
def hermesPkg = new File("$rootDir/../node_modules/hermes-engine/package.json")
|
||||
def hermesVersion = new JsonSlurper().parseText(hermesPkg.text).version
|
||||
def hermesDependency = dependencies.appendNode('dependency')
|
||||
hermesDependency.appendNode('groupId', "com.facebook")
|
||||
hermesDependency.appendNode('artifactId', "hermes")
|
||||
hermesDependency.appendNode('version', hermesVersion)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.content.Context;
|
||||
import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
@@ -34,7 +31,6 @@ import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
* default it's only used on versions < O, since versions >= O use ConnectionService, but it
|
||||
* can be disabled.
|
||||
*/
|
||||
@RequiresApi(Build.VERSION_CODES.M)
|
||||
class AudioDeviceHandlerGeneric implements
|
||||
AudioModeModule.AudioDeviceHandlerInterface,
|
||||
AudioManager.OnAudioFocusChangeListener {
|
||||
|
||||
@@ -1,230 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2017-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.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
|
||||
/**
|
||||
* {@link AudioModeModule.AudioDeviceHandlerInterface} module implementing device handling for
|
||||
* legacy (pre-M) Android versions.
|
||||
*/
|
||||
class AudioDeviceHandlerLegacy implements
|
||||
AudioModeModule.AudioDeviceHandlerInterface,
|
||||
AudioManager.OnAudioFocusChangeListener,
|
||||
BluetoothHeadsetMonitor.Listener {
|
||||
|
||||
private final static String TAG = AudioDeviceHandlerLegacy.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* Reference to the main {@code AudioModeModule}.
|
||||
*/
|
||||
private AudioModeModule module;
|
||||
|
||||
/**
|
||||
* Indicator that we have lost audio focus.
|
||||
*/
|
||||
private boolean audioFocusLost = false;
|
||||
|
||||
/**
|
||||
* {@link AudioManager} instance used to interact with the Android audio
|
||||
* subsystem.
|
||||
*/
|
||||
private AudioManager audioManager;
|
||||
|
||||
/**
|
||||
* {@link BluetoothHeadsetMonitor} for detecting Bluetooth device changes in
|
||||
* old (< M) Android versions.
|
||||
*/
|
||||
private BluetoothHeadsetMonitor bluetoothHeadsetMonitor;
|
||||
|
||||
public AudioDeviceHandlerLegacy(AudioManager audioManager) {
|
||||
this.audioManager = audioManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to trigger an audio route update when Bluetooth devices are
|
||||
* connected / disconnected.
|
||||
*/
|
||||
@Override
|
||||
public void onBluetoothDeviceChange(final boolean deviceAvailable) {
|
||||
module.runInAudioThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (deviceAvailable) {
|
||||
module.addDevice(AudioModeModule.DEVICE_BLUETOOTH);
|
||||
} else {
|
||||
module.removeDevice(AudioModeModule.DEVICE_BLUETOOTH);
|
||||
}
|
||||
|
||||
module.updateAudioRoute();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to trigger an audio route update when a headset is plugged
|
||||
* or unplugged.
|
||||
*/
|
||||
private void onHeadsetDeviceChange() {
|
||||
module.runInAudioThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
// XXX: isWiredHeadsetOn is not deprecated when used just for
|
||||
// knowing if there is a wired headset connected, regardless of
|
||||
// audio being routed to it.
|
||||
//noinspection deprecation
|
||||
if (audioManager.isWiredHeadsetOn()) {
|
||||
module.addDevice(AudioModeModule.DEVICE_HEADPHONES);
|
||||
} else {
|
||||
module.removeDevice(AudioModeModule.DEVICE_HEADPHONES);
|
||||
}
|
||||
|
||||
module.updateAudioRoute();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link AudioManager.OnAudioFocusChangeListener} interface method. Called
|
||||
* when the audio focus of the system is updated.
|
||||
*
|
||||
* @param focusChange - The type of focus change.
|
||||
*/
|
||||
@Override
|
||||
public void onAudioFocusChange(final int focusChange) {
|
||||
module.runInAudioThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
switch (focusChange) {
|
||||
case AudioManager.AUDIOFOCUS_GAIN: {
|
||||
JitsiMeetLogger.d(TAG + " Audio focus gained");
|
||||
// Some other application potentially stole our audio focus
|
||||
// temporarily. Restore our mode.
|
||||
if (audioFocusLost) {
|
||||
module.updateAudioRoute();
|
||||
}
|
||||
audioFocusLost = false;
|
||||
break;
|
||||
}
|
||||
case AudioManager.AUDIOFOCUS_LOSS:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
|
||||
case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: {
|
||||
JitsiMeetLogger.d(TAG + " Audio focus lost");
|
||||
audioFocusLost = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to set the output route to a Bluetooth device.
|
||||
*
|
||||
* @param enabled true if Bluetooth should use used, false otherwise.
|
||||
*/
|
||||
private void setBluetoothAudioRoute(boolean enabled) {
|
||||
if (enabled) {
|
||||
audioManager.startBluetoothSco();
|
||||
audioManager.setBluetoothScoOn(true);
|
||||
} else {
|
||||
audioManager.setBluetoothScoOn(false);
|
||||
audioManager.stopBluetoothSco();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(AudioModeModule audioModeModule) {
|
||||
JitsiMeetLogger.i("Using " + TAG + " as the audio device handler");
|
||||
|
||||
module = audioModeModule;
|
||||
Context context = module.getContext();
|
||||
|
||||
// Setup runtime device change detection.
|
||||
//
|
||||
|
||||
// Detect changes in wired headset connections.
|
||||
IntentFilter wiredHeadSetFilter = new IntentFilter(AudioManager.ACTION_HEADSET_PLUG);
|
||||
BroadcastReceiver wiredHeadsetReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
JitsiMeetLogger.d(TAG + " Wired headset added / removed");
|
||||
onHeadsetDeviceChange();
|
||||
}
|
||||
};
|
||||
context.registerReceiver(wiredHeadsetReceiver, wiredHeadSetFilter);
|
||||
|
||||
// Detect Bluetooth device changes.
|
||||
bluetoothHeadsetMonitor = new BluetoothHeadsetMonitor(context, this);
|
||||
|
||||
// On Android < M, detect if we have an earpiece.
|
||||
PackageManager pm = context.getPackageManager();
|
||||
if (pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
|
||||
module.addDevice(AudioModeModule.DEVICE_EARPIECE);
|
||||
}
|
||||
|
||||
// Always assume there is a speaker.
|
||||
module.addDevice(AudioModeModule.DEVICE_SPEAKER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
bluetoothHeadsetMonitor.stop();
|
||||
bluetoothHeadsetMonitor = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAudioRoute(String device) {
|
||||
// Turn speaker on / off
|
||||
audioManager.setSpeakerphoneOn(device.equals(AudioModeModule.DEVICE_SPEAKER));
|
||||
|
||||
// Turn bluetooth on / off
|
||||
setBluetoothAudioRoute(device.equals(AudioModeModule.DEVICE_BLUETOOTH));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setMode(int mode) {
|
||||
if (mode == AudioModeModule.DEFAULT) {
|
||||
audioFocusLost = false;
|
||||
audioManager.setMode(AudioManager.MODE_NORMAL);
|
||||
audioManager.abandonAudioFocus(this);
|
||||
audioManager.setSpeakerphoneOn(false);
|
||||
setBluetoothAudioRoute(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
||||
audioManager.setMicrophoneMute(false);
|
||||
|
||||
if (audioManager.requestAudioFocus(this, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN)
|
||||
== AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
|
||||
JitsiMeetLogger.w(TAG + " Audio focus request failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -222,10 +222,8 @@ class AudioModeModule extends ReactContextBaseJavaModule {
|
||||
|
||||
if (useConnectionService()) {
|
||||
audioDeviceHandler = new AudioDeviceHandlerConnectionService(audioManager);
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
audioDeviceHandler = new AudioDeviceHandlerGeneric(audioManager);
|
||||
} else {
|
||||
audioDeviceHandler = new AudioDeviceHandlerLegacy(audioManager);
|
||||
audioDeviceHandler = new AudioDeviceHandlerGeneric(audioManager);
|
||||
}
|
||||
|
||||
audioDeviceHandler.start(this);
|
||||
@@ -427,15 +425,6 @@ class AudioModeModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Needed on the legacy handler...
|
||||
*
|
||||
* @return Context for the application.
|
||||
*/
|
||||
Context getContext() {
|
||||
return getReactApplicationContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for the modules implementing the actual audio device management.
|
||||
*/
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
/*
|
||||
* Copyright @ 2017-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.
|
||||
*/
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothHeadset;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.media.AudioManager;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
/**
|
||||
* Helper class to detect and handle Bluetooth device changes. It monitors
|
||||
* Bluetooth headsets being connected / disconnected and notifies the module
|
||||
* about device changes when this occurs.
|
||||
*/
|
||||
class BluetoothHeadsetMonitor {
|
||||
private final static String TAG = BluetoothHeadsetMonitor.class.getSimpleName();
|
||||
|
||||
/**
|
||||
* The {@link Context} in which this module executes.
|
||||
*/
|
||||
private final Context context;
|
||||
|
||||
/**
|
||||
* Reference to the {@link BluetoothAdapter} object, used to access Bluetooth functionality.
|
||||
*/
|
||||
private BluetoothAdapter adapter;
|
||||
|
||||
/**
|
||||
* Reference to a proxy object which allows us to query connected devices.
|
||||
*/
|
||||
private BluetoothHeadset headset;
|
||||
|
||||
/**
|
||||
* receiver registered for receiving Bluetooth connection state changes.
|
||||
*/
|
||||
private BroadcastReceiver receiver;
|
||||
|
||||
/**
|
||||
* Listener for receiving Bluetooth device change events.
|
||||
*/
|
||||
private Listener listener;
|
||||
|
||||
public BluetoothHeadsetMonitor(Context context, Listener listener) {
|
||||
this.context = context;
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
private boolean getBluetoothHeadsetProfileProxy() {
|
||||
adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
|
||||
if (adapter == null) {
|
||||
JitsiMeetLogger.w(TAG + " Device doesn't support Bluetooth");
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX: The profile listener listens for system services of the given
|
||||
// type being available to the application. That is, if our Bluetooth
|
||||
// adapter has the "headset" profile.
|
||||
BluetoothProfile.ServiceListener listener
|
||||
= new BluetoothProfile.ServiceListener() {
|
||||
@Override
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
headset = (BluetoothHeadset) proxy;
|
||||
updateDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(int profile) {
|
||||
// The logic is the same as the logic of onServiceConnected.
|
||||
onServiceConnected(profile, /* proxy */ null);
|
||||
}
|
||||
};
|
||||
|
||||
return adapter.getProfileProxy(context, listener, BluetoothProfile.HEADSET);
|
||||
}
|
||||
|
||||
private void onBluetoothReceiverReceive(Context context, Intent intent) {
|
||||
final String action = intent.getAction();
|
||||
|
||||
if (action.equals(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)) {
|
||||
// XXX: This action will be fired when a Bluetooth headset is
|
||||
// connected or disconnected to the system. This is not related to
|
||||
// audio routing.
|
||||
int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -99);
|
||||
|
||||
switch (state) {
|
||||
case BluetoothHeadset.STATE_CONNECTED:
|
||||
case BluetoothHeadset.STATE_DISCONNECTED:
|
||||
JitsiMeetLogger.d(TAG + " BT headset connection state changed: " + state);
|
||||
updateDevices();
|
||||
break;
|
||||
}
|
||||
} else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
|
||||
// XXX: This action will be fired when the connection established
|
||||
// with a Bluetooth headset (called a SCO connection) changes state.
|
||||
// When the SCO connection is active we route audio to it.
|
||||
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -99);
|
||||
|
||||
switch (state) {
|
||||
case AudioManager.SCO_AUDIO_STATE_CONNECTED:
|
||||
case AudioManager.SCO_AUDIO_STATE_DISCONNECTED:
|
||||
JitsiMeetLogger.d(TAG + " BT SCO connection state changed: " + state);
|
||||
updateDevices();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerBluetoothReceiver() {
|
||||
receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
onBluetoothReceiverReceive(context, intent);
|
||||
}
|
||||
};
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
|
||||
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
|
||||
|
||||
context.registerReceiver(receiver, filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects if there are new devices connected / disconnected and fires the
|
||||
* {@link Listener} registered event.
|
||||
*/
|
||||
private void updateDevices() {
|
||||
boolean headsetAvailable = (headset != null) && !headset.getConnectedDevices().isEmpty();
|
||||
listener.onBluetoothDeviceChange(headsetAvailable);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
|
||||
|
||||
if (!audioManager.isBluetoothScoAvailableOffCall()) {
|
||||
JitsiMeetLogger.w(TAG + " Bluetooth SCO is not available");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!getBluetoothHeadsetProfileProxy()) {
|
||||
JitsiMeetLogger.w(TAG + " Couldn't get BT profile proxy");
|
||||
return;
|
||||
}
|
||||
|
||||
registerBluetoothReceiver();
|
||||
|
||||
// Initial detection.
|
||||
updateDevices();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (receiver != null) {
|
||||
context.unregisterReceiver(receiver);
|
||||
}
|
||||
|
||||
if (adapter != null && headset != null) {
|
||||
adapter.closeProfileProxy(BluetoothProfile.HEADSET, headset);
|
||||
}
|
||||
|
||||
receiver = null;
|
||||
headset = null;
|
||||
adapter = null;
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
void onBluetoothDeviceChange(boolean deviceAvailable);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright @ 2019-present 8x8, Inc.
|
||||
* Copyright @ 2018 Atlassian Pty Ltd
|
||||
* Copyright @ 2018-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.
|
||||
@@ -17,16 +16,16 @@
|
||||
|
||||
package org.jitsi.meet.sdk;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.bridge.Callback;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.modules.core.PermissionListener;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
/**
|
||||
* Helper class to encapsulate the work which needs to be done on
|
||||
* {@link Activity} lifecycle methods in order for the React side to be aware of
|
||||
@@ -178,9 +177,18 @@ public class JitsiMeetActivityDelegate {
|
||||
};
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.M)
|
||||
public static void requestPermissions(Activity activity, String[] permissions, int requestCode, PermissionListener listener) {
|
||||
permissionListener = listener;
|
||||
activity.requestPermissions(permissions, requestCode);
|
||||
|
||||
// The RN Permissions module calls this in a non-UI thread. What we observe is a crash in ViewGroup.dispatchCancelPendingInputEvents,
|
||||
// which is called on the calling (ie, non-UI) thread. This doesn't look very safe, so try to avoid a crash by pretending the permission
|
||||
// was denied.
|
||||
|
||||
try {
|
||||
activity.requestPermissions(permissions, requestCode);
|
||||
} catch (Exception e) {
|
||||
JitsiMeetLogger.e(e, "Error requesting permissions");
|
||||
onRequestPermissionsResult(requestCode, permissions, new int[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Copyright @ 2018-present 8x8, Inc.
|
||||
* Copyright @ 2017-2018 Atlassian Pty Ltd
|
||||
* Copyright @ 2017-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.
|
||||
@@ -126,7 +125,7 @@ public class JitsiMeetView extends BaseReactView<JitsiMeetViewListener>
|
||||
= ReactInstanceManagerHolder.getNativeModule(
|
||||
PictureInPictureModule.class);
|
||||
if (pipModule != null
|
||||
&& PictureInPictureModule.isPictureInPictureSupported()
|
||||
&& pipModule.isPictureInPictureSupported()
|
||||
&& !JitsiMeetActivityDelegate.arePermissionsBeingRequested()
|
||||
&& this.url != null) {
|
||||
try {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||
* Copyright @ 2017-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.
|
||||
@@ -18,6 +18,7 @@ package org.jitsi.meet.sdk;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.PictureInPictureParams;
|
||||
import android.os.Build;
|
||||
import android.util.Rational;
|
||||
@@ -30,20 +31,41 @@ import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static android.content.Context.ACTIVITY_SERVICE;
|
||||
|
||||
@ReactModule(name = PictureInPictureModule.NAME)
|
||||
class PictureInPictureModule
|
||||
extends ReactContextBaseJavaModule {
|
||||
class PictureInPictureModule extends ReactContextBaseJavaModule {
|
||||
|
||||
public static final String NAME = "PictureInPicture";
|
||||
|
||||
private static final String TAG = NAME;
|
||||
|
||||
static boolean isPictureInPictureSupported() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||
}
|
||||
private static boolean isSupported;
|
||||
|
||||
public PictureInPictureModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
|
||||
ActivityManager am = (ActivityManager) reactContext.getSystemService(ACTIVITY_SERVICE);
|
||||
|
||||
// Android Go devices don't support PiP. There doesn't seem to be a better way to detect it than
|
||||
// to use ActivityManager.isLowRamDevice().
|
||||
// https://stackoverflow.com/questions/58340558/how-to-detect-android-go
|
||||
isSupported = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !am.isLowRamDevice();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a {@code Map} of constants this module exports to JS. Supports JSON
|
||||
* types.
|
||||
*
|
||||
* @return a {@link Map} of constants this module exports to JS
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getConstants() {
|
||||
Map<String, Object> constants = new HashMap<>();
|
||||
constants.put("SUPPORTED", isSupported);
|
||||
return constants;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +83,7 @@ class PictureInPictureModule
|
||||
*/
|
||||
@TargetApi(Build.VERSION_CODES.O)
|
||||
public void enterPictureInPicture() {
|
||||
if (!isPictureInPictureSupported()) {
|
||||
if (!isSupported) {
|
||||
throw new IllegalStateException("Picture-in-Picture not supported");
|
||||
}
|
||||
|
||||
@@ -104,6 +126,10 @@ class PictureInPictureModule
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPictureInPictureSupported() {
|
||||
return isSupported;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return NAME;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright @ 2017-present Atlassian Pty Ltd
|
||||
* Copyright @ 2017-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.
|
||||
@@ -33,21 +33,10 @@ import com.facebook.react.module.annotations.ReactModule;
|
||||
* is used with the conference audio-only mode.
|
||||
*/
|
||||
@ReactModule(name = ProximityModule.NAME)
|
||||
class ProximityModule
|
||||
extends ReactContextBaseJavaModule {
|
||||
class ProximityModule extends ReactContextBaseJavaModule {
|
||||
|
||||
public static final String NAME = "Proximity";
|
||||
|
||||
/**
|
||||
* This type of wake lock (the one activated by the proximity sensor) has
|
||||
* been available for a while, but the constant was only exported in API
|
||||
* level 21 (Android Marshmallow) so make no assumptions and use its value
|
||||
* directly.
|
||||
*
|
||||
* TODO: Remove when we bump the API level to 21.
|
||||
*/
|
||||
private static final int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32;
|
||||
|
||||
/**
|
||||
* {@link WakeLock} instance.
|
||||
*/
|
||||
@@ -71,7 +60,7 @@ class ProximityModule
|
||||
try {
|
||||
wakeLock
|
||||
= powerManager.newWakeLock(
|
||||
PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
||||
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
||||
"jitsi:"+NAME);
|
||||
} catch (Throwable ignored) {
|
||||
wakeLock = null;
|
||||
|
||||
@@ -20,7 +20,6 @@ import android.app.Activity;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.hermes.reactexecutor.HermesExecutorFactory;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
@@ -28,6 +27,7 @@ import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.common.LifecycleState;
|
||||
import com.facebook.react.devsupport.DevInternalSettings;
|
||||
import com.facebook.react.jscexecutor.JSCExecutorFactory;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
@@ -35,6 +35,7 @@ import com.facebook.soloader.SoLoader;
|
||||
import com.oney.WebRTCModule.RTCVideoViewManager;
|
||||
import com.oney.WebRTCModule.WebRTCModule;
|
||||
|
||||
import org.jitsi.meet.sdk.log.JitsiMeetLogger;
|
||||
import org.webrtc.SoftwareVideoDecoderFactory;
|
||||
import org.webrtc.SoftwareVideoEncoderFactory;
|
||||
import org.webrtc.audio.AudioDeviceModule;
|
||||
@@ -216,8 +217,9 @@ class ReactInstanceManagerHolder {
|
||||
// Ignore any error, the module is not compiled when LIBRE_BUILD is enabled.
|
||||
}
|
||||
|
||||
// Use the Hermes JavaScript engine.
|
||||
HermesExecutorFactory jsFactory = new HermesExecutorFactory();
|
||||
// Keep on using JSC, the jury is out on Hermes.
|
||||
JSCExecutorFactory jsFactory
|
||||
= new JSCExecutorFactory("", "");
|
||||
|
||||
reactInstanceManager
|
||||
= ReactInstanceManager.builder()
|
||||
|
||||
15
app.js
15
app.js
@@ -4,6 +4,13 @@ import 'jquery';
|
||||
import 'jquery-contextmenu';
|
||||
import 'jQuery-Impromptu';
|
||||
|
||||
import 'olm';
|
||||
|
||||
// We need to setup the jitsi-local-storage as early as possible so that we can start using it.
|
||||
// NOTE: If jitsi-local-storage is used before the initial setup is performed this will break the use case when we use
|
||||
// the local storage from the parent page when the localStorage is disabled. Also the setup is relying that
|
||||
// window.location is not changed and still has all URL parameters.
|
||||
import './react/features/base/jitsi-local-storage/setup';
|
||||
import conference from './conference';
|
||||
import API from './modules/API';
|
||||
import UI from './modules/UI/UI';
|
||||
@@ -11,6 +18,14 @@ import keyboardshortcut from './modules/keyboardshortcut/keyboardshortcut';
|
||||
import remoteControl from './modules/remotecontrol/RemoteControl';
|
||||
import translation from './modules/translation/translation';
|
||||
|
||||
// Initialize Olm as early as possible.
|
||||
if (window.Olm) {
|
||||
window.Olm.init().catch(e => {
|
||||
console.error('Failed to initialize Olm, E2EE will be disabled', e);
|
||||
delete window.Olm;
|
||||
});
|
||||
}
|
||||
|
||||
window.APP = {
|
||||
API,
|
||||
conference,
|
||||
|
||||
240
conference.js
240
conference.js
@@ -1,4 +1,4 @@
|
||||
/* global $, APP, JitsiMeetJS, config, interfaceConfig */
|
||||
/* global APP, JitsiMeetJS, config, interfaceConfig */
|
||||
|
||||
import EventEmitter from 'events';
|
||||
import Logger from 'jitsi-meet-logger';
|
||||
@@ -95,6 +95,8 @@ import {
|
||||
createLocalPresenterTrack,
|
||||
createLocalTracksF,
|
||||
destroyLocalTracks,
|
||||
getLocalJitsiAudioTrack,
|
||||
getLocalJitsiVideoTrack,
|
||||
isLocalVideoTrackMuted,
|
||||
isLocalTrackMuted,
|
||||
isUserInteractionRequiredForUnmute,
|
||||
@@ -106,9 +108,9 @@ import {
|
||||
getBackendSafePath,
|
||||
getJitsiMeetGlobalNS
|
||||
} from './react/features/base/util';
|
||||
import { downloadJSON } from './react/features/base/util/downloadJSON';
|
||||
import { showDesktopPicker } from './react/features/desktop-picker';
|
||||
import { appendSuffix } from './react/features/display-name';
|
||||
import { setE2EEKey } from './react/features/e2ee';
|
||||
import {
|
||||
maybeOpenFeedbackDialog,
|
||||
submitFeedback
|
||||
@@ -120,8 +122,7 @@ import {
|
||||
initPrejoin,
|
||||
isPrejoinPageEnabled,
|
||||
isPrejoinPageVisible,
|
||||
replacePrejoinAudioTrack,
|
||||
replacePrejoinVideoTrack
|
||||
makePrecallTest
|
||||
} from './react/features/prejoin';
|
||||
import { createRnnoiseProcessorPromise } from './react/features/rnnoise';
|
||||
import { toggleScreenshotCaptureEffect } from './react/features/screenshot-capture';
|
||||
@@ -411,6 +412,10 @@ function disconnect() {
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
if (!connection) {
|
||||
return onDisconnected();
|
||||
}
|
||||
|
||||
return connection.disconnect().then(onDisconnected, onDisconnected);
|
||||
}
|
||||
|
||||
@@ -741,8 +746,6 @@ export default {
|
||||
|
||||
this.roomName = roomName;
|
||||
|
||||
window.addEventListener('hashchange', this.onHashChange.bind(this), false);
|
||||
|
||||
try {
|
||||
// Initialize the device list first. This way, when creating tracks
|
||||
// based on preferred devices, loose label matching can be done in
|
||||
@@ -755,7 +758,15 @@ export default {
|
||||
}
|
||||
|
||||
if (isPrejoinPageEnabled(APP.store.getState())) {
|
||||
_connectionPromise = connect(roomName);
|
||||
_connectionPromise = connect(roomName).then(c => {
|
||||
// we want to initialize it early, in case of errors to be able
|
||||
// to gather logs
|
||||
APP.connection = c;
|
||||
|
||||
return c;
|
||||
});
|
||||
|
||||
APP.store.dispatch(makePrecallTest(this._getConferenceOptions()));
|
||||
|
||||
const { tryCreateLocalTracks, errors } = this.createInitialLocalTracks(initialOptions);
|
||||
const tracks = await tryCreateLocalTracks;
|
||||
@@ -1202,10 +1213,6 @@ export default {
|
||||
|
||||
// end used by torture
|
||||
|
||||
getLogs() {
|
||||
return room.getLogs();
|
||||
},
|
||||
|
||||
/**
|
||||
* Download logs, a function that can be called from console while
|
||||
* debugging.
|
||||
@@ -1214,48 +1221,9 @@ export default {
|
||||
saveLogs(filename = 'meetlog.json') {
|
||||
// this can be called from console and will not have reference to this
|
||||
// that's why we reference the global var
|
||||
const logs = APP.conference.getLogs();
|
||||
const data = encodeURIComponent(JSON.stringify(logs, null, ' '));
|
||||
const logs = APP.connection.getLogs();
|
||||
|
||||
const elem = document.createElement('a');
|
||||
|
||||
elem.download = filename;
|
||||
elem.href = `data:application/json;charset=utf-8,\n${data}`;
|
||||
elem.dataset.downloadurl
|
||||
= [ 'text/json', elem.download, elem.href ].join(':');
|
||||
elem.dispatchEvent(new MouseEvent('click', {
|
||||
view: window,
|
||||
bubbles: true,
|
||||
cancelable: false
|
||||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
* Handled location hash change events.
|
||||
*/
|
||||
onHashChange() {
|
||||
const items = {};
|
||||
const parts = window.location.hash.substr(1).split('&');
|
||||
|
||||
for (const part of parts) {
|
||||
const param = part.split('=');
|
||||
const key = param[0];
|
||||
|
||||
if (!key) {
|
||||
continue; // eslint-disable-line no-continue
|
||||
}
|
||||
|
||||
items[key] = param[1];
|
||||
}
|
||||
|
||||
if (typeof items.e2eekey !== 'undefined') {
|
||||
APP.store.dispatch(setE2EEKey(items.e2eekey));
|
||||
|
||||
// Clean URL in browser history.
|
||||
const cleanUrl = window.location.href.split('#')[0];
|
||||
|
||||
history.replaceState(history.state, document.title, cleanUrl);
|
||||
}
|
||||
downloadJSON(logs, filename);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1403,31 +1371,32 @@ export default {
|
||||
/**
|
||||
* Start using provided video stream.
|
||||
* Stops previous video stream.
|
||||
* @param {JitsiLocalTrack} [stream] new stream to use or null
|
||||
* @param {JitsiLocalTrack} newTrack - new track to use or null
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useVideoStream(newStream) {
|
||||
useVideoStream(newTrack) {
|
||||
return new Promise((resolve, reject) => {
|
||||
_replaceLocalVideoTrackQueue.enqueue(onFinish => {
|
||||
/**
|
||||
* When the prejoin page is visible there is no conference object
|
||||
* created. The prejoin tracks are managed separately,
|
||||
* so this updates the prejoin video track.
|
||||
*/
|
||||
if (isPrejoinPageVisible(APP.store.getState())) {
|
||||
return APP.store.dispatch(replacePrejoinVideoTrack(newStream))
|
||||
const state = APP.store.getState();
|
||||
|
||||
// When the prejoin page is displayed localVideo is not set
|
||||
// so just replace the video track from the store with the new one.
|
||||
if (isPrejoinPageVisible(state)) {
|
||||
const oldTrack = getLocalJitsiVideoTrack(state);
|
||||
|
||||
return APP.store.dispatch(replaceLocalTrack(oldTrack, newTrack))
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
.then(onFinish);
|
||||
}
|
||||
|
||||
APP.store.dispatch(
|
||||
replaceLocalTrack(this.localVideo, newStream, room))
|
||||
replaceLocalTrack(this.localVideo, newTrack, room))
|
||||
.then(() => {
|
||||
this.localVideo = newStream;
|
||||
this._setSharingScreen(newStream);
|
||||
if (newStream) {
|
||||
APP.UI.addLocalVideoStream(newStream);
|
||||
this.localVideo = newTrack;
|
||||
this._setSharingScreen(newTrack);
|
||||
if (newTrack) {
|
||||
APP.UI.addLocalVideoStream(newTrack);
|
||||
}
|
||||
this.setVideoMuteStatus(this.isLocalVideoMuted());
|
||||
})
|
||||
@@ -1468,28 +1437,29 @@ export default {
|
||||
/**
|
||||
* Start using provided audio stream.
|
||||
* Stops previous audio stream.
|
||||
* @param {JitsiLocalTrack} [stream] new stream to use or null
|
||||
* @param {JitsiLocalTrack} newTrack - new track to use or null
|
||||
* @returns {Promise}
|
||||
*/
|
||||
useAudioStream(newStream) {
|
||||
useAudioStream(newTrack) {
|
||||
return new Promise((resolve, reject) => {
|
||||
_replaceLocalAudioTrackQueue.enqueue(onFinish => {
|
||||
/**
|
||||
* When the prejoin page is visible there is no conference object
|
||||
* created. The prejoin tracks are managed separately,
|
||||
* so this updates the prejoin audio stream.
|
||||
*/
|
||||
if (isPrejoinPageVisible(APP.store.getState())) {
|
||||
return APP.store.dispatch(replacePrejoinAudioTrack(newStream))
|
||||
const state = APP.store.getState();
|
||||
|
||||
// When the prejoin page is displayed localAudio is not set
|
||||
// so just replace the audio track from the store with the new one.
|
||||
if (isPrejoinPageVisible(state)) {
|
||||
const oldTrack = getLocalJitsiAudioTrack(state);
|
||||
|
||||
return APP.store.dispatch(replaceLocalTrack(oldTrack, newTrack))
|
||||
.then(resolve)
|
||||
.catch(reject)
|
||||
.then(onFinish);
|
||||
}
|
||||
|
||||
APP.store.dispatch(
|
||||
replaceLocalTrack(this.localAudio, newStream, room))
|
||||
replaceLocalTrack(this.localAudio, newTrack, room))
|
||||
.then(() => {
|
||||
this.localAudio = newStream;
|
||||
this.localAudio = newTrack;
|
||||
this.setAudioMuteStatus(this.isLocalAudioMuted());
|
||||
})
|
||||
.then(resolve)
|
||||
@@ -1582,10 +1552,6 @@ export default {
|
||||
if (didHaveVideo) {
|
||||
promise = promise.then(() => createLocalTracksF({ devices: [ 'video' ] }))
|
||||
.then(([ stream ]) => this.useVideoStream(stream))
|
||||
.then(() => {
|
||||
sendAnalytics(createScreenSharingEvent('stopped'));
|
||||
logger.log('Screen sharing stopped.');
|
||||
})
|
||||
.catch(error => {
|
||||
logger.error('failed to switch back to local video', error);
|
||||
|
||||
@@ -1602,6 +1568,8 @@ export default {
|
||||
return promise.then(
|
||||
() => {
|
||||
this.videoSwitchInProgress = false;
|
||||
sendAnalytics(createScreenSharingEvent('stopped'));
|
||||
logger.info('Screen sharing stopped.');
|
||||
},
|
||||
error => {
|
||||
this.videoSwitchInProgress = false;
|
||||
@@ -1669,8 +1637,6 @@ export default {
|
||||
* @private
|
||||
*/
|
||||
_createDesktopTrack(options = {}) {
|
||||
let externalInstallation = false;
|
||||
let DSExternalInstallationInProgress = false;
|
||||
const didHaveVideo = !this.isLocalVideoMuted();
|
||||
|
||||
const getDesktopStreamPromise = options.desktopStream
|
||||
@@ -1679,43 +1645,7 @@ export default {
|
||||
desktopSharingSourceDevice: options.desktopSharingSources
|
||||
? null : config._desktopSharingSourceDevice,
|
||||
desktopSharingSources: options.desktopSharingSources,
|
||||
devices: [ 'desktop' ],
|
||||
desktopSharingExtensionExternalInstallation: {
|
||||
interval: 500,
|
||||
checkAgain: () => DSExternalInstallationInProgress,
|
||||
listener: (status, url) => {
|
||||
switch (status) {
|
||||
case 'waitingForExtension': {
|
||||
DSExternalInstallationInProgress = true;
|
||||
externalInstallation = true;
|
||||
const listener = () => {
|
||||
// Wait a little bit more just to be sure that
|
||||
// we won't miss the extension installation
|
||||
setTimeout(() => {
|
||||
DSExternalInstallationInProgress = false;
|
||||
},
|
||||
500);
|
||||
APP.UI.removeListener(
|
||||
UIEvents.EXTERNAL_INSTALLATION_CANCELED,
|
||||
listener);
|
||||
};
|
||||
|
||||
APP.UI.addListener(
|
||||
UIEvents.EXTERNAL_INSTALLATION_CANCELED,
|
||||
listener);
|
||||
APP.UI.showExtensionExternalInstallationDialog(url);
|
||||
break;
|
||||
}
|
||||
case 'extensionFound':
|
||||
// Close the dialog.
|
||||
externalInstallation && $.prompt.close();
|
||||
break;
|
||||
default:
|
||||
|
||||
// Unknown status
|
||||
}
|
||||
}
|
||||
}
|
||||
devices: [ 'desktop' ]
|
||||
});
|
||||
|
||||
return getDesktopStreamPromise.then(desktopStreams => {
|
||||
@@ -1739,15 +1669,8 @@ export default {
|
||||
);
|
||||
}
|
||||
|
||||
// close external installation dialog on success.
|
||||
externalInstallation && $.prompt.close();
|
||||
|
||||
return desktopStreams;
|
||||
}, error => {
|
||||
DSExternalInstallationInProgress = false;
|
||||
|
||||
// close external installation dialog on success.
|
||||
externalInstallation && $.prompt.close();
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
@@ -1951,70 +1874,36 @@ export default {
|
||||
/**
|
||||
* Handles {@link JitsiTrackError} returned by the lib-jitsi-meet when
|
||||
* trying to create screensharing track. It will either do nothing if
|
||||
* the dialog was canceled on user's request or display inline installation
|
||||
* dialog and ask the user to install the extension, once the extension is
|
||||
* installed it will switch the conference to screensharing. The last option
|
||||
* is that an unrecoverable error dialog will be displayed.
|
||||
* the dialog was canceled on user's request or display an error if
|
||||
* screensharing couldn't be started.
|
||||
* @param {JitsiTrackError} error - The error returned by
|
||||
* {@link _createDesktopTrack} Promise.
|
||||
* @private
|
||||
*/
|
||||
_handleScreenSharingError(error) {
|
||||
if (error.name === JitsiTrackErrors.CHROME_EXTENSION_USER_CANCELED) {
|
||||
if (error.name === JitsiTrackErrors.SCREENSHARING_USER_CANCELED) {
|
||||
return;
|
||||
}
|
||||
|
||||
logger.error('failed to share local desktop', error);
|
||||
|
||||
if (error.name
|
||||
=== JitsiTrackErrors.CHROME_EXTENSION_USER_GESTURE_REQUIRED) {
|
||||
// If start with screen sharing the extension will fail to install
|
||||
// (if not found), because the request has been triggered by the
|
||||
// script. Show a dialog which asks user to click "install" and try
|
||||
// again switching to the screen sharing.
|
||||
APP.UI.showExtensionInlineInstallationDialog(
|
||||
() => {
|
||||
// eslint-disable-next-line no-empty-function
|
||||
this.toggleScreenSharing().catch(() => {});
|
||||
}
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Handling:
|
||||
// JitsiTrackErrors.PERMISSION_DENIED
|
||||
// JitsiTrackErrors.CHROME_EXTENSION_INSTALLATION_ERROR
|
||||
// JitsiTrackErrors.CONSTRAINT_FAILED
|
||||
// JitsiTrackErrors.GENERAL
|
||||
// JitsiTrackErrors.PERMISSION_DENIED
|
||||
// JitsiTrackErrors.SCREENSHARING_GENERIC_ERROR
|
||||
// and any other
|
||||
let descriptionKey;
|
||||
let titleKey;
|
||||
|
||||
if (error.name === JitsiTrackErrors.PERMISSION_DENIED) {
|
||||
|
||||
// in FF the only option for user is to deny access temporary or
|
||||
// permanently and we only receive permission_denied
|
||||
// we always show some info cause in case of permanently, no info
|
||||
// shown will be bad experience
|
||||
//
|
||||
// TODO: detect interval between requesting permissions and received
|
||||
// error, this way we can detect user interaction which will have
|
||||
// longer delay
|
||||
if (JitsiMeetJS.util.browser.isFirefox()) {
|
||||
descriptionKey
|
||||
= 'dialog.screenSharingFirefoxPermissionDeniedError';
|
||||
titleKey = 'dialog.screenSharingFirefoxPermissionDeniedTitle';
|
||||
} else {
|
||||
descriptionKey = 'dialog.screenSharingPermissionDeniedError';
|
||||
titleKey = 'dialog.screenSharingFailedToInstallTitle';
|
||||
}
|
||||
descriptionKey = 'dialog.screenSharingPermissionDeniedError';
|
||||
titleKey = 'dialog.screenSharingFailedTitle';
|
||||
} else if (error.name === JitsiTrackErrors.CONSTRAINT_FAILED) {
|
||||
descriptionKey = 'dialog.cameraConstraintFailedError';
|
||||
titleKey = 'deviceError.cameraError';
|
||||
} else {
|
||||
descriptionKey = 'dialog.screenSharingFailedToInstall';
|
||||
titleKey = 'dialog.screenSharingFailedToInstallTitle';
|
||||
} else if (error.name === JitsiTrackErrors.SCREENSHARING_GENERIC_ERROR) {
|
||||
descriptionKey = 'dialog.screenSharingFailed';
|
||||
titleKey = 'dialog.screenSharingFailedTitle';
|
||||
}
|
||||
|
||||
APP.UI.messageHandler.showError({
|
||||
@@ -2931,7 +2820,14 @@ export default {
|
||||
this._room = undefined;
|
||||
room = undefined;
|
||||
|
||||
APP.API.notifyReadyToClose();
|
||||
/**
|
||||
* Don't call {@code notifyReadyToClose} if the promotional page flag is set
|
||||
* and let the page take care of sending the message, since there will be
|
||||
* a redirect to the page regardlessly.
|
||||
*/
|
||||
if (!interfaceConfig.SHOW_PROMOTIONAL_CLOSE_PAGE) {
|
||||
APP.API.notifyReadyToClose();
|
||||
}
|
||||
APP.store.dispatch(maybeRedirectToWelcomePage(values[0]));
|
||||
});
|
||||
},
|
||||
|
||||
177
config.js
177
config.js
@@ -14,9 +14,6 @@ var config = {
|
||||
// Domain for authenticated users. Defaults to <domain>.
|
||||
// authdomain: 'jitsi-meet.example.com',
|
||||
|
||||
// Jirecon recording component domain.
|
||||
// jirecon: 'jirecon.jitsi-meet.example.com',
|
||||
|
||||
// Call control component (Jigasi).
|
||||
// call_control: 'callcontrol.jitsi-meet.example.com',
|
||||
|
||||
@@ -37,6 +34,8 @@ var config = {
|
||||
clientNode: 'http://jitsi.org/jitsimeet',
|
||||
|
||||
// The real JID of focus participant - can be overridden here
|
||||
// Do not change username - FIXME: Make focus username configurable
|
||||
// https://github.com/jitsi/jitsi-meet/issues/7376
|
||||
// focusUserJid: 'focus@auth.jitsi-meet.example.com',
|
||||
|
||||
|
||||
@@ -44,6 +43,10 @@ var config = {
|
||||
//
|
||||
|
||||
testing: {
|
||||
// Disables the End to End Encryption feature. Useful for debugging
|
||||
// issues related to insertable streams.
|
||||
// disableE2EE: false,
|
||||
|
||||
// P2P test mode disables automatic switching to P2P when there are 2
|
||||
// participants in the conference.
|
||||
p2pTestMode: false
|
||||
@@ -61,6 +64,11 @@ var config = {
|
||||
// adjusted to 2.5 Mbps. This takes a value between 0 and 1 which determines
|
||||
// the probability for this to be enabled.
|
||||
// capScreenshareBitrate: 1 // 0 to disable
|
||||
|
||||
// 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.
|
||||
// callStatsThreshold: 5 // enable callstats for 5% of the users.
|
||||
},
|
||||
|
||||
// Disables ICE/UDP by filtering out local and remote UDP candidates in
|
||||
@@ -107,11 +115,23 @@ var config = {
|
||||
// participants and to enable it back a reload is needed.
|
||||
// startSilent: false
|
||||
|
||||
// Sets the preferred target bitrate for the Opus audio codec by setting its
|
||||
// 'maxaveragebitrate' parameter. Currently not available in p2p mode.
|
||||
// Valid values are in the range 6000 to 510000
|
||||
// opusMaxAverageBitrate: 20000,
|
||||
|
||||
// Enables redundancy for Opus
|
||||
// enableOpusRed: false
|
||||
|
||||
// Video
|
||||
|
||||
// Sets the preferred resolution (height) for local video. Defaults to 720.
|
||||
// resolution: 720,
|
||||
|
||||
// How many participants while in the tile view mode, before the receiving video quality is reduced from HD to SD.
|
||||
// Use -1 to disable.
|
||||
// maxFullResolutionParticipants: 2,
|
||||
|
||||
// w3c spec-compliant video constraints to use for video capture. Currently
|
||||
// used by browsers that return true from lib-jitsi-meet's
|
||||
// util#browser#usesNewGumFlow. The constraints are independent from
|
||||
@@ -146,6 +166,7 @@ var config = {
|
||||
// Note that it's not recommended to do this because simulcast is not
|
||||
// supported when using H.264. For 1-to-1 calls this setting is enabled by
|
||||
// default and can be toggled in the p2p section.
|
||||
// This option has been deprecated, use preferredCodec under videoQuality section instead.
|
||||
// preferH264: true,
|
||||
|
||||
// If set to true, disable H.264 video codec by stripping it out of the
|
||||
@@ -154,22 +175,6 @@ var config = {
|
||||
|
||||
// Desktop sharing
|
||||
|
||||
// The ID of the jidesha extension for Chrome.
|
||||
desktopSharingChromeExtId: null,
|
||||
|
||||
// Whether desktop sharing should be disabled on Chrome.
|
||||
// desktopSharingChromeDisabled: false,
|
||||
|
||||
// The media sources to use when using screen sharing with the Chrome
|
||||
// extension.
|
||||
desktopSharingChromeSources: [ 'screen', 'window', 'tab' ],
|
||||
|
||||
// Required version of Chrome extension
|
||||
desktopSharingChromeMinExtVersion: '0.1',
|
||||
|
||||
// Whether desktop sharing should be disabled on Firefox.
|
||||
// desktopSharingFirefoxDisabled: false,
|
||||
|
||||
// Optional desktop sharing frame rate options. Default value: min:5, max:5.
|
||||
// desktopSharingFrameRate: {
|
||||
// min: 5,
|
||||
@@ -217,6 +222,64 @@ var config = {
|
||||
// Default value for the channel "last N" attribute. -1 for unlimited.
|
||||
channelLastN: -1,
|
||||
|
||||
// Provides a way to use different "last N" values based on the number of participants in the conference.
|
||||
// The keys in an Object represent number of participants and the values are "last N" to be used when number of
|
||||
// participants gets to or above the number.
|
||||
//
|
||||
// For the given example mapping, "last N" will be set to 20 as long as there are at least 5, but less than
|
||||
// 29 participants in the call and it will be lowered to 15 when the 30th participant joins. The 'channelLastN'
|
||||
// will be used as default until the first threshold is reached.
|
||||
//
|
||||
// lastNLimits: {
|
||||
// 5: 20,
|
||||
// 30: 15,
|
||||
// 50: 10,
|
||||
// 70: 5,
|
||||
// 90: 2
|
||||
// },
|
||||
|
||||
// Specify the settings for video quality optimizations on the client.
|
||||
// videoQuality: {
|
||||
// // Provides a way to prevent a video codec from being negotiated on the JVB connection. The codec specified
|
||||
// // here will be removed from the list of codecs present in the SDP answer generated by the client. If the
|
||||
// // same codec is specified for both the disabled and preferred option, the disable settings will prevail.
|
||||
// // Note that 'VP8' cannot be disabled since it's a mandatory codec, the setting will be ignored in this case.
|
||||
// disabledCodec: 'H264',
|
||||
//
|
||||
// // Provides a way to set a preferred video codec for the JVB connection. If 'H264' is specified here,
|
||||
// // simulcast will be automatically disabled since JVB doesn't support H264 simulcast yet. This will only
|
||||
// // rearrange the the preference order of the codecs in the SDP answer generated by the browser only if the
|
||||
// // preferred codec specified here is present. Please ensure that the JVB offers the specified codec for this
|
||||
// // to take effect.
|
||||
// preferredCodec: 'VP8',
|
||||
//
|
||||
// // 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
|
||||
// // are the max.bitrates to be set on that particular type of stream. The actual send may vary based on
|
||||
// // the available bandwidth calculated by the browser, but it will be capped by the values specified here.
|
||||
// // This is currently not implemented on app based clients on mobile.
|
||||
// maxBitratesVideo: {
|
||||
// low: 200000,
|
||||
// standard: 500000,
|
||||
// high: 1500000
|
||||
// },
|
||||
//
|
||||
// // The options can be used to override default thresholds of video thumbnail heights corresponding to
|
||||
// // the video quality levels used in the application. At the time of this writing the allowed levels are:
|
||||
// // 'low' - for the low quality level (180p at the time of this writing)
|
||||
// // 'standard' - for the medium quality level (360p)
|
||||
// // 'high' - for the high quality level (720p)
|
||||
// // The keys should be positive numbers which represent the minimal thumbnail height for the quality level.
|
||||
// //
|
||||
// // With the default config value below the application will use 'low' quality until the thumbnails are
|
||||
// // at least 360 pixels tall. If the thumbnail height reaches 720 pixels then the application will switch to
|
||||
// // the high quality.
|
||||
// minHeightForQualityLvl: {
|
||||
// 360: 'standard,
|
||||
// 720: 'high'
|
||||
// }
|
||||
// },
|
||||
|
||||
// // Options for the recording limit notification.
|
||||
// recordingLimit: {
|
||||
//
|
||||
@@ -260,24 +323,28 @@ var config = {
|
||||
// is set in Jicofo and set to 2).
|
||||
// minParticipants: 2,
|
||||
|
||||
// Use XEP-0215 to fetch STUN and TURN servers.
|
||||
// Use the TURN servers discovered via XEP-0215 for the jitsi-videobridge
|
||||
// connection
|
||||
// useStunTurn: true,
|
||||
|
||||
// Enable IPv6 support.
|
||||
// useIPv6: true,
|
||||
// Use TURN/UDP servers for the jitsi-videobridge connection (by default
|
||||
// we filter out TURN/UDP because it is usually not needed since the
|
||||
// bridge itself is reachable via UDP)
|
||||
// useTurnUdp: false
|
||||
|
||||
// Enables / disables a data communication channel with the Videobridge.
|
||||
// Values can be 'datachannel', 'websocket', true (treat it as
|
||||
// 'datachannel'), undefined (treat it as 'datachannel') and false (don't
|
||||
// open any channel).
|
||||
// openBridgeChannel: true,
|
||||
openBridgeChannel: 'websocket',
|
||||
|
||||
|
||||
// UI
|
||||
//
|
||||
|
||||
// Use display name as XMPP nickname.
|
||||
// useNicks: false,
|
||||
// Hides lobby button
|
||||
// hideLobbyButton: false,
|
||||
|
||||
// Require users to always specify a display name.
|
||||
// requireDisplayName: true,
|
||||
@@ -319,9 +386,18 @@ var config = {
|
||||
// and microsoftApiApplicationClientID
|
||||
// enableCalendarIntegration: false,
|
||||
|
||||
// When 'true', it shows an intermediate page before joining, where the user can configure its devices.
|
||||
// When 'true', it shows an intermediate page before joining, where the user can configure their devices.
|
||||
// prejoinPageEnabled: false,
|
||||
|
||||
// If true, shows the unsafe room name warning label when a room name is
|
||||
// deemed unsafe (due to the simplicity in the name) and a password is not
|
||||
// set or the lobby is not enabled.
|
||||
// enableInsecureRoomNameWarning: false,
|
||||
|
||||
// Whether to automatically copy invitation URL after creating a room.
|
||||
// Document should be focused for this option to work
|
||||
// enableAutomaticUrlCopy: false,
|
||||
|
||||
// Stats
|
||||
//
|
||||
|
||||
@@ -339,10 +415,10 @@ var config = {
|
||||
// callStatsID: '',
|
||||
// callStatsSecret: '',
|
||||
|
||||
// enables sending participants display name to callstats
|
||||
// Enables sending participants' display names to callstats
|
||||
// enableDisplayNameInStats: false,
|
||||
|
||||
// enables sending participants email if available to callstats and other analytics
|
||||
// Enables sending participants' emails (if available) to callstats and other analytics
|
||||
// enableEmailInStats: false,
|
||||
|
||||
// Privacy
|
||||
@@ -372,7 +448,7 @@ var config = {
|
||||
// The STUN servers that will be used in the peer to peer connections
|
||||
stunServers: [
|
||||
|
||||
// { urls: 'stun:jitsi-meet.example.com:4446' },
|
||||
// { urls: 'stun:jitsi-meet.example.com:3478' },
|
||||
{ urls: 'stun:meet-jit-si-turnrelay.jitsi.net:443' }
|
||||
]
|
||||
|
||||
@@ -385,13 +461,20 @@ var config = {
|
||||
// iceTransportPolicy: 'all',
|
||||
|
||||
// If set to true, it will prefer to use H.264 for P2P calls (if H.264
|
||||
// is supported).
|
||||
// is supported). This setting is deprecated, use preferredCodec instead.
|
||||
// preferH264: true
|
||||
|
||||
// Provides a way to set the video codec preference on the p2p connection. Acceptable
|
||||
// codec values are 'VP8', 'VP9' and 'H264'.
|
||||
// preferredCodec: 'H264',
|
||||
|
||||
// If set to true, disable H.264 video codec by stripping it out of the
|
||||
// SDP.
|
||||
// SDP. This setting is deprecated, use disabledCodec instead.
|
||||
// disableH264: false,
|
||||
|
||||
// Provides a way to prevent a video codec from being negotiated on the p2p connection.
|
||||
// disabledCodec: '',
|
||||
|
||||
// How long we're going to wait, before going back to P2P after the 3rd
|
||||
// participant has left the conference (to filter out page reload).
|
||||
// backToP2PDelay: 5
|
||||
@@ -408,6 +491,21 @@ var config = {
|
||||
// The Amplitude APP Key:
|
||||
// amplitudeAPPKey: '<APP_KEY>'
|
||||
|
||||
// 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
|
||||
// PeerConnection states along with getStats metrics polled at the specified
|
||||
// interval.
|
||||
// rtcstatsEnabled: true,
|
||||
|
||||
// In order to enable rtcstats one needs to provide a endpoint url.
|
||||
// rtcstatsEndpoint: wss://rtcstats-server-pilot.jitsi.net/,
|
||||
|
||||
// The interval at which rtcstats will poll getStats, defaults to 1000ms.
|
||||
// If the value is set to 0 getStats won't be polled and the rtcstats client
|
||||
// will only send data related to RTCPeerConnection events.
|
||||
// rtcstatsPolIInterval: 1000
|
||||
|
||||
// Array of script URLs to load as lib-jitsi-meet "analytics handlers".
|
||||
// scriptURLs: [
|
||||
// "libs/analytics-ga.min.js", // google-analytics
|
||||
@@ -415,6 +513,9 @@ var config = {
|
||||
// ],
|
||||
},
|
||||
|
||||
// Logs that should go be passed through the 'log' event if a handler is defined for it
|
||||
// apiLogLevels: ['warn', 'log', 'error', 'info', 'debug'],
|
||||
|
||||
// Information about the jitsi-meet instance we are connecting to, including
|
||||
// the user region as seen by the server.
|
||||
deploymentInfo: {
|
||||
@@ -515,7 +616,7 @@ var config = {
|
||||
/**
|
||||
External API url used to receive branding specific information.
|
||||
If there is no url set or there are missing fields, the defaults are applied.
|
||||
None of the fieds are mandatory and the response must have the shape:
|
||||
None of the fields are mandatory and the response must have the shape:
|
||||
{
|
||||
// The hex value for the colour used as background
|
||||
backgroundColor: '#fff',
|
||||
@@ -529,11 +630,14 @@ var config = {
|
||||
*/
|
||||
// brandingDataUrl: '',
|
||||
|
||||
// The URL of the moderated rooms microservice, if available. If it
|
||||
// is present, a link to the service will be rendered on the welcome page,
|
||||
// otherwise the app doesn't render it.
|
||||
// moderatedRoomServiceUrl: 'https://moderated.jitsi-meet.example.com',
|
||||
|
||||
// List of undocumented settings used in jitsi-meet
|
||||
/**
|
||||
_immediateReloadThreshold
|
||||
autoRecord
|
||||
autoRecordToken
|
||||
debug
|
||||
debugAudioLevels
|
||||
deploymentInfo
|
||||
@@ -556,6 +660,13 @@ var config = {
|
||||
tokenAuthUrl
|
||||
*/
|
||||
|
||||
/**
|
||||
* This property can be used to alter the generated meeting invite links (in combination with a branding domain
|
||||
* which is retrieved internally by jitsi meet) (e.g. https://meet.jit.si/someMeeting
|
||||
* can become https://brandedDomain/roomAlias)
|
||||
*/
|
||||
// brandingRoomAlias: null,
|
||||
|
||||
// List of undocumented settings used in lib-jitsi-meet
|
||||
/**
|
||||
_peerConnStatusOutOfLastNTimeout
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* global APP, JitsiMeetJS, config */
|
||||
|
||||
import { jitsiLocalStorage } from '@jitsi/js-utils';
|
||||
import Logger from 'jitsi-meet-logger';
|
||||
import { jitsiLocalStorage } from 'js-utils';
|
||||
|
||||
import AuthHandler from './modules/UI/authentication/AuthHandler';
|
||||
import {
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
JitsiConnectionErrors,
|
||||
JitsiConnectionEvents
|
||||
} from './react/features/base/lib-jitsi-meet';
|
||||
import { setPrejoinDisplayNameRequired } from './react/features/prejoin/actions';
|
||||
|
||||
const logger = Logger.getLogger(__filename);
|
||||
|
||||
@@ -81,7 +82,7 @@ function checkForAttachParametersAndConnect(id, password, connection) {
|
||||
*/
|
||||
function connect(id, password, roomName) {
|
||||
const connectionConfig = Object.assign({}, config);
|
||||
const { issuer, jwt } = APP.store.getState()['features/base/jwt'];
|
||||
const { jwt } = APP.store.getState()['features/base/jwt'];
|
||||
|
||||
// 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.
|
||||
@@ -93,11 +94,7 @@ function connect(id, password, roomName) {
|
||||
// in future). It's included for the time being for Jitsi Meet and lib-jitsi-meet versions interoperability.
|
||||
connectionConfig.serviceUrl = connectionConfig.bosh = serviceUrl;
|
||||
|
||||
const connection
|
||||
= new JitsiMeetJS.JitsiConnection(
|
||||
null,
|
||||
jwt && issuer && issuer !== 'anonymous' ? jwt : undefined,
|
||||
connectionConfig);
|
||||
const connection = new JitsiMeetJS.JitsiConnection(null, jwt, connectionConfig);
|
||||
|
||||
if (config.iAmRecorder) {
|
||||
connection.addFeature(DISCO_JIBRI_FEATURE);
|
||||
@@ -113,6 +110,10 @@ function connect(id, password, roomName) {
|
||||
connection.addEventListener(
|
||||
JitsiConnectionEvents.CONNECTION_FAILED,
|
||||
connectionFailedHandler);
|
||||
connection.addEventListener(
|
||||
JitsiConnectionEvents.DISPLAY_NAME_REQUIRED,
|
||||
displayNameRequiredHandler
|
||||
);
|
||||
|
||||
/* eslint-disable max-params */
|
||||
/**
|
||||
@@ -166,6 +167,14 @@ function connect(id, password, roomName) {
|
||||
reject(err);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks the display name for the prejoin screen as required.
|
||||
* This can happen if a user tries to join a room with lobby enabled.
|
||||
*/
|
||||
function displayNameRequiredHandler() {
|
||||
APP.store.dispatch(setPrejoinDisplayNameRequired());
|
||||
}
|
||||
|
||||
checkForAttachParametersAndConnect(id, password, connection);
|
||||
});
|
||||
}
|
||||
@@ -198,10 +207,9 @@ export function openConnection({ id, password, retry, roomName }) {
|
||||
|
||||
return connect(id, password, roomName).catch(err => {
|
||||
if (retry) {
|
||||
const { issuer, jwt } = APP.store.getState()['features/base/jwt'];
|
||||
const { jwt } = APP.store.getState()['features/base/jwt'];
|
||||
|
||||
if (err === JitsiConnectionErrors.PASSWORD_REQUIRED
|
||||
&& (!jwt || issuer === 'anonymous')) {
|
||||
if (err === JitsiConnectionErrors.PASSWORD_REQUIRED && !jwt) {
|
||||
return AuthHandler.requestAuth(roomName, connect);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Move the @atlaskit/flag container up a little bit so it does not cover the
|
||||
* toolbar with the first notification.
|
||||
*/
|
||||
.cjMOOK{
|
||||
.jIMojv{
|
||||
bottom: calc(#{$newToolbarSizeWithPadding}) !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,26 @@ body {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AtlasKit sets a default margin on the rendered modals, so
|
||||
* when the shift-right class is set when the chat opens, we
|
||||
* pad the modal container in order for the modals to be centered
|
||||
* while also taking the chat size into consideration.
|
||||
*/
|
||||
@media (min-width: 480px + $sidebarWidth) {
|
||||
.shift-right [class^="Modal__FillScreen"] {
|
||||
padding-left: $sidebarWidth;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Similarly, we offset the notifications when the chat is open by
|
||||
* padding the container.
|
||||
*/
|
||||
.shift-right [class^="styledFlagGroup-"] {
|
||||
padding-left: $sidebarWidth;
|
||||
}
|
||||
|
||||
.jitsi-icon svg {
|
||||
fill: white;
|
||||
}
|
||||
|
||||
@@ -4,16 +4,11 @@
|
||||
color: #FFF;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/**
|
||||
* Make the sidebar flush with the top of the toolbar. Take the size of
|
||||
* the toolbar and subtract from 100%.
|
||||
*/
|
||||
height: calc(100% - #{$newToolbarSizeWithPadding});
|
||||
height: 100%;
|
||||
left: -$sidebarWidth;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
transition: left 0.5s;
|
||||
width: $sidebarWidth;
|
||||
z-index: $sideToolbarContainerZ;
|
||||
|
||||
|
||||
@@ -45,10 +45,8 @@
|
||||
@extend .connection-info__icon;
|
||||
}
|
||||
|
||||
.showmore {
|
||||
display: block;
|
||||
.connection-actions {
|
||||
margin: 10px auto;
|
||||
text-align: center;
|
||||
width: 90px;
|
||||
}
|
||||
}
|
||||
|
||||
60
css/_connection-status.scss
Normal file
60
css/_connection-status.scss
Normal file
@@ -0,0 +1,60 @@
|
||||
.con-status {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
width: 100%;
|
||||
z-index: $toolbarZ + 3;
|
||||
|
||||
&-container {
|
||||
background: rgba(28, 32, 37, .5);
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
margin: 0 auto;
|
||||
width: 304px;
|
||||
}
|
||||
|
||||
&-header {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
&-circle {
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
&--good {
|
||||
background: #31B76A;
|
||||
}
|
||||
|
||||
&--poor {
|
||||
background: #E12D2D;
|
||||
}
|
||||
|
||||
&--non-optimal {
|
||||
background: #E39623;
|
||||
}
|
||||
|
||||
&-arrow {
|
||||
&--up {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
&>svg {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&-text {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&-details {
|
||||
border-top: 1px solid #5E6D7A;
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
26
css/_e2ee.scss
Normal file
26
css/_e2ee.scss
Normal file
@@ -0,0 +1,26 @@
|
||||
#e2ee-section {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
margin: 15px 0;
|
||||
|
||||
.read-more {
|
||||
cursor: pointer;
|
||||
opacity: .7;
|
||||
}
|
||||
}
|
||||
|
||||
.control-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
margin-top: 15px;
|
||||
|
||||
label {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
top: 30px;
|
||||
right: 30px;
|
||||
transition: right 0.5s;
|
||||
z-index: $zindex3;
|
||||
z-index: $filmstripVideosZ + 1;
|
||||
|
||||
.circular-label {
|
||||
align-items: center;
|
||||
|
||||
@@ -34,6 +34,10 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.control-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
||||
@@ -96,6 +96,11 @@
|
||||
padding: 0 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.prejoin-dialog-btn.primary,
|
||||
.action-btn.prejoin-dialog-btn.text {
|
||||
width: 310px;
|
||||
}
|
||||
}
|
||||
|
||||
.prejoin-dialog-callout {
|
||||
|
||||
@@ -36,15 +36,19 @@
|
||||
}
|
||||
|
||||
&-checkbox-container {
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
display: none;
|
||||
font-size: 13px;
|
||||
justify-content: center;
|
||||
line-height: 20px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 14px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&-error {
|
||||
color: white;
|
||||
background-color: rgba(229, 75, 75, 0.5);
|
||||
width: 100%;
|
||||
padding: 3px;
|
||||
margin-top: 4px;
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin name-placeholder {
|
||||
|
||||
@@ -1,22 +1,90 @@
|
||||
/**
|
||||
* Shared style for full screen local track based dialogs/modals.
|
||||
*/
|
||||
.premeeting-screen,
|
||||
.preview-overlay {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.premeeting-screen {
|
||||
align-items: stretch;
|
||||
background: #1C2025;
|
||||
bottom: 0;
|
||||
background: radial-gradient(50% 50% at 50% 50%, #5D95C7 0%, #376288 100%), #FFFFFF;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
font-size: 1.3em;
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: $toolbarZ + 1;
|
||||
|
||||
.action-btn {
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin-top: 16px;
|
||||
padding: 7px 16px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: 286px;
|
||||
|
||||
&.primary {
|
||||
background: #0376DA;
|
||||
border: 1px solid #0376DA;
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background: transparent;
|
||||
border: 1px solid #5E6D7A;
|
||||
}
|
||||
|
||||
&.text {
|
||||
width: auto;
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background: #5E6D7A;
|
||||
border: 1px solid #5E6D7A;
|
||||
color: #AFB6BC;
|
||||
cursor: initial;
|
||||
|
||||
.icon {
|
||||
& > svg {
|
||||
fill: #AFB6BC;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
border-left: 1px solid #AFB6BC;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
align-items: center;
|
||||
border-left: 1px solid #fff;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-overlay {
|
||||
background-image: linear-gradient(transparent, black);
|
||||
z-index: $toolbarZ + 1;
|
||||
}
|
||||
|
||||
.content {
|
||||
align-items: center;
|
||||
background-image: linear-gradient(transparent, black);
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
@@ -40,6 +108,7 @@
|
||||
font-weight: 300;
|
||||
justify-content: center;
|
||||
line-height: 24px;
|
||||
margin-bottom: 16px;
|
||||
|
||||
.url {
|
||||
display: flex;
|
||||
@@ -59,6 +128,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
.copy-meeting-text {
|
||||
width: 266px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
align-self: stretch;
|
||||
}
|
||||
@@ -77,8 +153,9 @@
|
||||
border: 1px solid transparent;
|
||||
color: white;
|
||||
outline-width: 0;
|
||||
padding: 20px;
|
||||
padding: 8px 0;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
|
||||
&.focused {
|
||||
border-bottom: 1px solid white;
|
||||
@@ -88,66 +165,6 @@
|
||||
color: $defaultWarningColor;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
margin: 10px;
|
||||
padding: 7px 16px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
width: 286px;
|
||||
|
||||
&.primary {
|
||||
background: #0376DA;
|
||||
border: 1px solid #0376DA;
|
||||
}
|
||||
|
||||
&.secondary {
|
||||
background: transparent;
|
||||
border: 1px solid #5E6D7A;
|
||||
}
|
||||
|
||||
&.text {
|
||||
width: auto;
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
background: #5E6D7A;
|
||||
border: 1px solid #5E6D7A;
|
||||
color: #AFB6BC;
|
||||
cursor: initial;
|
||||
|
||||
.icon {
|
||||
& > svg {
|
||||
fill: #AFB6BC;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
border-left: 1px solid #AFB6BC;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
align-items: center;
|
||||
border-left: 1px solid #fff;
|
||||
display: flex;
|
||||
height: 100%;
|
||||
justify-content: center;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.media-btn-container {
|
||||
@@ -182,7 +199,7 @@
|
||||
|
||||
.avatar {
|
||||
background: #A4B8D1;
|
||||
margin: 200px auto 0 auto;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
video {
|
||||
@@ -191,4 +208,67 @@
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@mixin flex-centered() {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
@mixin icon-container($bg, $fill) {
|
||||
.toggle-button-icon-container {
|
||||
background: $bg;
|
||||
|
||||
svg {
|
||||
fill: $fill
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-button {
|
||||
border-radius: 3px;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
font-size: 13px;
|
||||
height: 40px;
|
||||
margin: 0 auto;
|
||||
width: 320px;
|
||||
|
||||
@include flex-centered();
|
||||
|
||||
svg {
|
||||
fill: transparent;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: #1C2025;
|
||||
|
||||
@include icon-container(#A4B8D1, #1C2025);
|
||||
}
|
||||
|
||||
&-container {
|
||||
position: relative;
|
||||
|
||||
@include flex-centered();
|
||||
}
|
||||
|
||||
&-icon-container {
|
||||
border-radius: 50%;
|
||||
left: -22px;
|
||||
padding: 2px;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&--toggled {
|
||||
background: #75757A;
|
||||
|
||||
&:hover {
|
||||
background: #75757A;
|
||||
|
||||
@include icon-container(#A4B8D1, #75757A);
|
||||
}
|
||||
|
||||
@include icon-container(#A4B8D1, #75757A);
|
||||
}
|
||||
}
|
||||
|
||||
70
css/_responsive.scss
Normal file
70
css/_responsive.scss
Normal file
@@ -0,0 +1,70 @@
|
||||
@media only screen and (max-width: $smallScreen) {
|
||||
.watermark {
|
||||
width: 20%;
|
||||
height: 20%;
|
||||
}
|
||||
|
||||
.new-toolbox {
|
||||
.toolbox-content {
|
||||
.button-group-center, .button-group-left, .button-group-right {
|
||||
.toolbox-button {
|
||||
.toolbox-icon {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
.toolbox-icon {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: $verySmallScreen) {
|
||||
#videoResolutionLabel {
|
||||
display: none;
|
||||
}
|
||||
.desktop-browser {
|
||||
.vertical-filmstrip .filmstrip {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.new-toolbox {
|
||||
.toolbox-content {
|
||||
.button-group-center, .button-group-left, .button-group-right {
|
||||
.settings-button-small-icon {
|
||||
display: none;
|
||||
}
|
||||
.toolbox-button {
|
||||
.toolbox-icon {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
.toolbox-icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.chrome-extension-banner {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,10 @@
|
||||
cursor: initial;
|
||||
color: #fff;
|
||||
background-color: #a4b8d1;
|
||||
|
||||
&:hover {
|
||||
background-color: #a4b8d1;
|
||||
}
|
||||
}
|
||||
|
||||
svg {
|
||||
|
||||
@@ -42,6 +42,11 @@
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.shift-right {
|
||||
margin-left: $sidebarWidth;
|
||||
width: calc(100% - #{$sidebarWidth});
|
||||
}
|
||||
|
||||
.toolbox-background {
|
||||
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0));
|
||||
transition: bottom .3s ease-in;
|
||||
|
||||
@@ -164,6 +164,9 @@ $unsupportedDesktopBrowserTextFontSize: 21px;
|
||||
$watermarkWidth: 186px;
|
||||
$watermarkHeight: 74px;
|
||||
|
||||
$welcomePageWatermarkWidth: 186px;
|
||||
$welcomePageWatermarkHeight: 74px;
|
||||
|
||||
/**
|
||||
* Welcome page variables.
|
||||
*/
|
||||
@@ -178,9 +181,12 @@ $welcomePageHeaderBackgroundPosition: none;
|
||||
$welcomePageHeaderBackgroundRepeat: none;
|
||||
$welcomePageHeaderBackgroundSize: none;
|
||||
$welcomePageHeaderPaddingBottom: 0px;
|
||||
$welcomePageHeaderMinHeight: fit-content;
|
||||
|
||||
$welcomePageHeaderTextMarginTop: 35px;
|
||||
$welcomePageHeaderTextMarginBottom: 35px;
|
||||
$welcomePageHeaderTextDisplay: flex;
|
||||
$welcomePageHeaderTextWidth: 650px;
|
||||
|
||||
$welcomePageHeaderTextTitleMarginBottom: 16px;
|
||||
$welcomePageHeaderTextTitleFontSize: 2.5rem;
|
||||
@@ -195,6 +201,7 @@ $welcomePageHeaderTextDescriptionLineHeight: 24px;
|
||||
$welcomePageHeaderTextDescriptionMarginBottom: 20px;
|
||||
$welcomePageHeaderTextDescriptionAlignSelf: inherit;
|
||||
|
||||
$welcomePageEnterRoomDisplay: flex;
|
||||
$welcomePageEnterRoomWidth: 680px;
|
||||
$welcomePageEnterRoomPadding: 25px 30px;
|
||||
$welcomePageEnterRoomBorderRadius: 0px;
|
||||
@@ -269,3 +276,9 @@ $chromeExtensionBannerTop: 80px;
|
||||
$chromeExtensionBannerRight: 16px;
|
||||
$chromeExtensionBannerTopInMeeting: 10px;
|
||||
$chromeExtensionBannerRightInMeeeting: 10px;
|
||||
|
||||
/**
|
||||
* media type thresholds
|
||||
*/
|
||||
$smallScreen: 700px;
|
||||
$verySmallScreen: 500px;
|
||||
|
||||
@@ -181,6 +181,13 @@
|
||||
visibility: hidden;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
&.shift-right {
|
||||
&#largeVideoContainer {
|
||||
margin-left: $sidebarWidth;
|
||||
width: calc(100% - #{$sidebarWidth});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#localVideoWrapper {
|
||||
|
||||
@@ -21,18 +21,18 @@ body.welcome-page {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: fit-content;
|
||||
min-height: $welcomePageHeaderMinHeight;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
|
||||
.header-text {
|
||||
display: flex;
|
||||
display: $welcomePageHeaderTextDisplay;
|
||||
flex-direction: column;
|
||||
margin-top: $watermarkHeight + $welcomePageHeaderTextMarginTop;
|
||||
margin-bottom: $welcomePageHeaderTextMarginBottom;
|
||||
max-width: calc(100% - 40px);
|
||||
width: 650px;
|
||||
width: $welcomePageHeaderTextWidth;
|
||||
z-index: $zindex2;
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ body.welcome-page {
|
||||
}
|
||||
|
||||
#enter_room {
|
||||
display: flex;
|
||||
display: $welcomePageEnterRoomDisplay;
|
||||
align-items: center;
|
||||
max-width: calc(100% - 40px);
|
||||
width: $welcomePageEnterRoomWidth;
|
||||
@@ -95,8 +95,12 @@ body.welcome-page {
|
||||
flex-direction: row;
|
||||
margin-top: 5px;
|
||||
|
||||
svg {
|
||||
fill: $defaultWarningColor
|
||||
.jitsi-icon {
|
||||
margin-right: 15px;
|
||||
|
||||
svg {
|
||||
fill: $defaultWarningColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,6 +111,22 @@ body.welcome-page {
|
||||
|
||||
}
|
||||
|
||||
#moderated-meetings {
|
||||
max-width: calc(100% - 40px);
|
||||
padding: 16px 0 39px 0;
|
||||
width: $welcomePageEnterRoomWidth;
|
||||
|
||||
p {
|
||||
color: $welcomePageDescriptionColor;
|
||||
text-align: left;
|
||||
|
||||
a {
|
||||
color: inherit;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tab-container {
|
||||
font-size: 16px;
|
||||
position: relative;
|
||||
@@ -191,5 +211,10 @@ body.welcome-page {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.watermark.leftwatermark {
|
||||
width: $welcomePageWatermarkWidth;
|
||||
height: $welcomePageWatermarkHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
38
css/buttons/copy.scss
Normal file
38
css/buttons/copy.scss
Normal file
@@ -0,0 +1,38 @@
|
||||
.copy-button {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 8px 8px 16px;
|
||||
margin-top: 8px;
|
||||
width: calc(100% - 24px);
|
||||
height: 24px;
|
||||
|
||||
background: #0376DA;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: #278ADF;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&-content {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 292px;
|
||||
margin-right: 16px;
|
||||
|
||||
&.selected {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
&.clicked {
|
||||
background: #31B76A;
|
||||
}
|
||||
|
||||
& > div > svg > path {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,16 @@
|
||||
position: fixed;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
z-index: $filmstripVideosZ
|
||||
z-index: $filmstripVideosZ;
|
||||
|
||||
&.shift-right {
|
||||
margin-left: $sidebarWidth;
|
||||
width: calc(100% - #{$sidebarWidth});
|
||||
|
||||
#filmstripRemoteVideos {
|
||||
width: calc(100vw - #{$sidebarWidth});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,9 +33,11 @@ $flagsImagePath: "../images/";
|
||||
@import 'inlay';
|
||||
@import 'reload_overlay/reload_overlay';
|
||||
@import 'mini_toolbox';
|
||||
@import 'buttons/copy.scss';
|
||||
@import 'modals/desktop-picker/desktop-picker';
|
||||
@import 'modals/device-selection/device-selection';
|
||||
@import 'modals/dialog';
|
||||
@import 'modals/embed-meeting/embed-meeting';
|
||||
@import 'modals/feedback/feedback';
|
||||
@import 'modals/invite/info';
|
||||
@import 'modals/settings/settings';
|
||||
@@ -98,5 +100,8 @@ $flagsImagePath: "../images/";
|
||||
@import 'modals/invite/invite_more';
|
||||
@import 'modals/security/security';
|
||||
@import 'premeeting-screens';
|
||||
@import 'e2ee';
|
||||
@import 'responsive';
|
||||
@import 'connection-status';
|
||||
|
||||
/* Modules END */
|
||||
|
||||
59
css/modals/embed-meeting/_embed-meeting.scss
Normal file
59
css/modals/embed-meeting/_embed-meeting.scss
Normal file
@@ -0,0 +1,59 @@
|
||||
.embed-meeting {
|
||||
&-dialog {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin: 16px 16px 24px;
|
||||
width: calc(100% - 32px);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
|
||||
& > div > svg {
|
||||
cursor: pointer;
|
||||
fill: #A4B8D1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-copy {
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
margin-left: auto;
|
||||
margin-top: 16px;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
&-code {
|
||||
background: transparent;
|
||||
border: 1px solid #A4B8D1;
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
height: 165px;
|
||||
line-height: 24px;
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
&-trigger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 8px 8px 16px;
|
||||
margin-top: 24px;
|
||||
width: calc(100% - 24px);
|
||||
height: 24px;
|
||||
background: #2A3A4B;
|
||||
border: 1px solid #5E6D7A;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
.jitsi-icon {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,10 +47,6 @@
|
||||
font-size: 15px;
|
||||
line-height: 24px;
|
||||
|
||||
& > span {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -67,44 +63,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
&.copy-link {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 8px 8px 16px;
|
||||
margin-top: 8px;
|
||||
width: calc(100% - 24px);
|
||||
height: 24px;
|
||||
|
||||
background: #0376DA;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: #278ADF;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
&-text {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 292px;
|
||||
|
||||
&.selected {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
&.clicked {
|
||||
background: #31B76A;
|
||||
}
|
||||
|
||||
& > div > svg > path {
|
||||
fill: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&.separator {
|
||||
margin: 24px 0 24px -20px;
|
||||
padding: 0 20px;
|
||||
@@ -208,6 +166,12 @@
|
||||
padding: 8px 16px;
|
||||
background: #0376DA;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
& > a {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.stream {
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.description {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.password {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
@@ -22,17 +26,13 @@
|
||||
color: #6FB1EA;
|
||||
}
|
||||
|
||||
&>a+a {
|
||||
margin-left: 24px;
|
||||
& > :first-child:not(:last-child) {
|
||||
margin-right: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&> :first-child:not(:last-child) {
|
||||
margin-right: 24px;
|
||||
}
|
||||
|
||||
.separator-line {
|
||||
margin: 24px 0 24px -20px;
|
||||
padding: 0 20px;
|
||||
@@ -47,13 +47,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
.new-toolbox .toolbox-content .toolbox-icon.security-toolbar-button,
|
||||
.new-toolbox .toolbox-content .toolbox-icon.toggled.security-toolbar-button {
|
||||
background: rgba(241, 173, 51, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||
border-width: 0;
|
||||
|
||||
&:hover {
|
||||
background: rgba(241, 173, 51, 0.7);
|
||||
border: 1px solid rgba(255, 255, 255, 0.4);
|
||||
&:not(:hover) {
|
||||
background: unset;
|
||||
}
|
||||
}
|
||||
@@ -30,10 +30,12 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.profile-edit-field,
|
||||
.settings-sub-pane {
|
||||
.profile-edit-field {
|
||||
flex: 1;
|
||||
}
|
||||
.settings-sub-pane {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.profile-edit-field {
|
||||
margin-right: 20px;
|
||||
|
||||
2
debian/control
vendored
2
debian/control
vendored
@@ -47,7 +47,7 @@ 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), libssl-dev, luarocks, jitsi-meet-prosody
|
||||
Depends: ${misc:Depends}, prosody-trunk (>= 1nightly747) | prosody-0.11 | prosody (>= 0.11.2), libssl1.0-dev | libssl-dev, luarocks, jitsi-meet-prosody, git
|
||||
Description: Prosody token authentication plugin for Jitsi Meet
|
||||
|
||||
Package: jitsi-meet-turnserver
|
||||
|
||||
8
debian/jitsi-meet-prosody.postrm
vendored
8
debian/jitsi-meet-prosody.postrm
vendored
@@ -45,8 +45,12 @@ case "$1" in
|
||||
rm -rf /var/lib/prosody/$JICOFO_AUTH_DOMAIN.*
|
||||
rm -rf /var/lib/prosody/$JVB_HOSTNAME.*
|
||||
|
||||
# clean created users
|
||||
rm -rf /var/lib/prosody/`echo $JICOFO_AUTH_DOMAIN | sed -e "s/\./%2e/g"`
|
||||
# clean created users, replace '.' with '%2e', replace '-' with '%2d'
|
||||
rm -rf /var/lib/prosody/`echo $JICOFO_AUTH_DOMAIN | sed -e "s/\./%2e/g"| sed -e "s/-/%2d/g"`
|
||||
|
||||
# clean the prosody cert from the trust store
|
||||
rm -rf /usr/local/share/ca-certificates/$JICOFO_AUTH_DOMAIN.*
|
||||
update-ca-certificates -f
|
||||
fi
|
||||
|
||||
# Clear the debconf variable
|
||||
|
||||
11
debian/jitsi-meet-tokens.postinst
vendored
11
debian/jitsi-meet-tokens.postinst
vendored
@@ -48,9 +48,9 @@ case "$1" in
|
||||
db_stop
|
||||
|
||||
if [ -f "$PROSODY_HOST_CONFIG" ] ; then
|
||||
# search for --plugin_paths, if this is not enabled this is the
|
||||
# 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 grep -q "\-\-plugin_paths" "$PROSODY_HOST_CONFIG"; then
|
||||
if ! egrep -q '^\s*authentication\s*=\s*"token"' "$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
|
||||
@@ -58,6 +58,7 @@ case "$1" in
|
||||
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; then
|
||||
@@ -73,9 +74,9 @@ case "$1" in
|
||||
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" \
|
||||
|| [ "$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
|
||||
|
||||
3
debian/jitsi-meet-tokens.postrm
vendored
3
debian/jitsi-meet-tokens.postrm
vendored
@@ -37,11 +37,10 @@ case "$1" in
|
||||
APP_SECRET=$RET
|
||||
|
||||
# Revert prosody config
|
||||
sed -i 's/plugin_paths/--plugin_paths/g' $PROSODY_HOST_CONFIG
|
||||
sed -i 's/authentication = "token"/authentication = "anonymous"/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"/ "token_verification"/g' $PROSODY_HOST_CONFIG
|
||||
sed -i '/^\s*"token_verification"/ s/"token_verification"/-- "token_verification"/' $PROSODY_HOST_CONFIG
|
||||
|
||||
if [ -x "/etc/init.d/prosody" ]; then
|
||||
invoke-rc.d prosody restart || true
|
||||
|
||||
79
debian/jitsi-meet-turnserver.postinst
vendored
79
debian/jitsi-meet-turnserver.postinst
vendored
@@ -36,26 +36,6 @@ case "$1" in
|
||||
NGINX_CONFIG="/etc/nginx/sites-available/$JVB_HOSTNAME.conf"
|
||||
JITSI_MEET_CONFIG="/etc/jitsi/meet/$JVB_HOSTNAME-config.js"
|
||||
|
||||
NGINX_SITES_ENABLED="/etc/nginx/sites-enabled/"
|
||||
NGINX_CONFIG_ENABLED="${NGINX_SITES_ENABLED}${JVB_HOSTNAME}.conf"
|
||||
NGINX_MULTIPLEXING="true"
|
||||
for site in ${NGINX_SITES_ENABLED}*; do
|
||||
# if it is not a file continue
|
||||
[ -f "${site}" ] || continue
|
||||
# if it is our config skip
|
||||
[ "${site}" != "${NGINX_CONFIG_ENABLED}" ] || continue
|
||||
# check whether other enabled hosts has listen 443
|
||||
if cat ${site} | grep -v "^[[:space:]]*#" | grep listen | grep -q "^.*[[:space:]:]443[;[:space:]].*" ; then
|
||||
# nothing to do
|
||||
echo "------------------------------------------------"
|
||||
echo ""
|
||||
echo "turnserver is listening on tcp 4445 as other nginx sites use port 443"
|
||||
echo ""
|
||||
echo "------------------------------------------------"
|
||||
NGINX_MULTIPLEXING="false"
|
||||
fi
|
||||
done
|
||||
|
||||
# if there was a turn config backup it so we can configure
|
||||
# we cannot recognize at the moment is this a user config or default config when installing coturn
|
||||
if [[ -f $TURN_CONFIG ]] && ! grep -q "jitsi-meet coturn config" "$TURN_CONFIG" ; then
|
||||
@@ -87,9 +67,36 @@ case "$1" in
|
||||
if [[ -f $TURN_CONFIG ]] ; then
|
||||
echo "------------------------------------------------"
|
||||
echo ""
|
||||
echo "turnserver is already configured on this machine, skipping."
|
||||
echo "turnserver is already configured on this machine."
|
||||
echo ""
|
||||
echo "------------------------------------------------"
|
||||
|
||||
if grep -q "jitsi-meet coturn config" "$TURN_CONFIG" && ! grep -q "jitsi-meet coturn relay disable config" "$TURN_CONFIG" ; then
|
||||
echo "Updating coturn config"
|
||||
echo "# jitsi-meet coturn relay disable config. Do not modify this line
|
||||
no-multicast-peers
|
||||
no-cli
|
||||
no-loopback-peers
|
||||
no-tcp-relay
|
||||
denied-peer-ip=0.0.0.0-0.255.255.255
|
||||
denied-peer-ip=10.0.0.0-10.255.255.255
|
||||
denied-peer-ip=100.64.0.0-100.127.255.255
|
||||
denied-peer-ip=127.0.0.0-127.255.255.255
|
||||
denied-peer-ip=169.254.0.0-169.254.255.255
|
||||
denied-peer-ip=127.0.0.0-127.255.255.255
|
||||
denied-peer-ip=172.16.0.0-172.31.255.255
|
||||
denied-peer-ip=192.0.0.0-192.0.0.255
|
||||
denied-peer-ip=192.0.2.0-192.0.2.255
|
||||
denied-peer-ip=192.88.99.0-192.88.99.255
|
||||
denied-peer-ip=192.168.0.0-192.168.255.255
|
||||
denied-peer-ip=198.18.0.0-198.19.255.255
|
||||
denied-peer-ip=198.51.100.0-198.51.100.255
|
||||
denied-peer-ip=203.0.113.0-203.0.113.255
|
||||
denied-peer-ip=240.0.0.0-255.255.255.255" >> $TURN_CONFIG
|
||||
|
||||
invoke-rc.d coturn restart || true
|
||||
fi
|
||||
|
||||
db_stop
|
||||
exit 0
|
||||
fi
|
||||
@@ -106,19 +113,9 @@ case "$1" in
|
||||
TURN_SECRET="$RET"
|
||||
|
||||
# no turn config exists, lt's copy template and fill it in
|
||||
PUBLIC_IP=$(dig -4 +short myip.opendns.com a @resolver1.opendns.com) || true
|
||||
if [ -z "$PUBLIC_IP" ] ; then
|
||||
PUBLIC_IP="127.0.0.1"
|
||||
echo "------------------------------------------------"
|
||||
echo "Warning! Could not resolve your external ip address! Error:^"
|
||||
echo "Your turn server will not work till you edit your $TURN_CONFIG config file."
|
||||
echo "You need to set your external ip address in external-ip and restart coturn service."
|
||||
echo "------------------------------------------------"
|
||||
fi
|
||||
cp /usr/share/jitsi-meet-turnserver/turnserver.conf $TURN_CONFIG
|
||||
sed -i "s/jitsi-meet.example.com/$JVB_HOSTNAME/g" $TURN_CONFIG
|
||||
sed -i "s/__turnSecret__/$TURN_SECRET/g" $TURN_CONFIG
|
||||
sed -i "s/__external_ip_address__/$PUBLIC_IP/g" $TURN_CONFIG
|
||||
|
||||
# SSL for nginx
|
||||
db_get jitsi-meet/cert-choice
|
||||
@@ -143,18 +140,14 @@ case "$1" in
|
||||
invoke-rc.d coturn restart || true
|
||||
|
||||
NGINX_STREAM_CONFIG="/etc/nginx/modules-enabled/60-jitsi-meet.conf"
|
||||
if [ $NGINX_MULTIPLEXING = "true" ] && [ ! -f $NGINX_STREAM_CONFIG ] && [ -f $NGINX_CONFIG ] ; then
|
||||
ln -s /usr/share/jitsi-meet-turnserver/jitsi-meet.conf $NGINX_STREAM_CONFIG
|
||||
sed -i "s/listen 443 ssl/listen 4444 ssl http2/g" $NGINX_CONFIG
|
||||
sed -i "s/listen \[\:\:\]\:443 ssl/listen \[\:\:\]\:4444 ssl http2/g" $NGINX_CONFIG
|
||||
invoke-rc.d nginx reload || true
|
||||
else
|
||||
PROSODY_HOST_CONFIG="/etc/prosody/conf.avail/$JVB_HOSTNAME.cfg.lua"
|
||||
if [ -f $PROSODY_HOST_CONFIG ] ; then
|
||||
# If we are not multiplexing we need to change the port in prosody config
|
||||
sed -i 's/"443"/"4445"/g' $PROSODY_HOST_CONFIG
|
||||
invoke-rc.d prosody restart || true
|
||||
fi
|
||||
if [ -f $NGINX_STREAM_CONFIG ] ; then
|
||||
echo "------------------------------------------------"
|
||||
echo ""
|
||||
echo "You have multiplexing enabled, it is recommended to disable it and migrate to using websockets for the bridge channel."
|
||||
echo "The support for sctp data channels is deprecated and will be dropped at some point."
|
||||
echo "How to do it at: https://jitsi.org/multiplexing-to-bridge-ws-howto"
|
||||
echo ""
|
||||
echo "------------------------------------------------"
|
||||
fi
|
||||
|
||||
# Enable turn server in config.js
|
||||
|
||||
2
debian/jitsi-meet-turnserver.postrm
vendored
2
debian/jitsi-meet-turnserver.postrm
vendored
@@ -24,7 +24,6 @@ set -e
|
||||
|
||||
case "$1" in
|
||||
remove)
|
||||
rm -rf /etc/nginx/modules-enabled/60-jitsi-meet.conf
|
||||
if [ -x "/etc/init.d/nginx" ]; then
|
||||
invoke-rc.d nginx reload || true
|
||||
fi
|
||||
@@ -33,7 +32,6 @@ case "$1" in
|
||||
fi
|
||||
;;
|
||||
purge)
|
||||
rm -rf /etc/nginx/modules-enabled/60-jitsi-meet.conf
|
||||
rm -rf /etc/turnserver.conf
|
||||
if [ -x "/etc/init.d/nginx" ]; then
|
||||
invoke-rc.d nginx reload || true
|
||||
|
||||
8
debian/jitsi-meet-web-config.postinst
vendored
8
debian/jitsi-meet-web-config.postinst
vendored
@@ -91,10 +91,14 @@ case "$1" in
|
||||
CERT_CRT="/etc/jitsi/meet/$JVB_HOSTNAME.crt"
|
||||
HOST="$( (hostname -s; echo localhost) | head -n 1)"
|
||||
DOMAIN="$( (hostname -d; echo localdomain) | head -n 1)"
|
||||
openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -subj \
|
||||
openssl req -new -newkey rsa:4096 -days 3650 -nodes -x509 -subj \
|
||||
"/O=$DOMAIN/OU=$HOST/CN=$JVB_HOSTNAME/emailAddress=webmaster@$HOST.$DOMAIN" \
|
||||
-keyout $CERT_KEY \
|
||||
-out $CERT_CRT
|
||||
-out $CERT_CRT \
|
||||
-reqexts SAN \
|
||||
-extensions SAN \
|
||||
-config <(cat /etc/ssl/openssl.cnf \
|
||||
<(printf "[SAN]\nsubjectAltName=DNS:localhost,DNS:$JVB_HOSTNAME"))
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Documentation
|
||||
|
||||
The Jitsi documentation has been moved to [The Handbook](https://jitsi.github.io/handbook/).
|
||||
The Jitsi documentation has been moved to [The Handbook](https://jitsi.github.io/handbook/). The repo is https://github.com/jitsi/handbook.
|
||||
|
||||
@@ -6,9 +6,9 @@ muc_mapper_domain_base = "jitmeet.example.com";
|
||||
turncredentials_secret = "__turnSecret__";
|
||||
|
||||
turncredentials = {
|
||||
{ type = "stun", host = "jitmeet.example.com", port = "4446" },
|
||||
{ type = "turn", host = "jitmeet.example.com", port = "4446", transport = "udp" },
|
||||
{ type = "turns", host = "jitmeet.example.com", port = "443", transport = "tcp" }
|
||||
{ type = "stun", host = "jitmeet.example.com", port = "3478" },
|
||||
{ type = "turn", host = "jitmeet.example.com", port = "3478", transport = "udp" },
|
||||
{ type = "turns", host = "jitmeet.example.com", port = "5349", transport = "tcp" }
|
||||
};
|
||||
|
||||
cross_domain_bosh = false;
|
||||
|
||||
@@ -5,14 +5,31 @@ static-auth-secret=__turnSecret__
|
||||
realm=jitsi-meet.example.com
|
||||
cert=/etc/jitsi/meet/jitsi-meet.example.com.crt
|
||||
pkey=/etc/jitsi/meet/jitsi-meet.example.com.key
|
||||
|
||||
no-multicast-peers
|
||||
no-cli
|
||||
no-loopback-peers
|
||||
no-tcp-relay
|
||||
no-tcp
|
||||
listening-port=4446
|
||||
tls-listening-port=4445
|
||||
external-ip=__external_ip_address__
|
||||
listening-port=3478
|
||||
tls-listening-port=5349
|
||||
no-tlsv1
|
||||
no-tlsv1_1
|
||||
# https://ssl-config.mozilla.org/#server=haproxy&version=2.1&config=intermediate&openssl=1.1.0g&guideline=5.4
|
||||
cipher-list=ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
|
||||
|
||||
# jitsi-meet coturn relay disable config. Do not modify this line
|
||||
denied-peer-ip=0.0.0.0-0.255.255.255
|
||||
denied-peer-ip=10.0.0.0-10.255.255.255
|
||||
denied-peer-ip=100.64.0.0-100.127.255.255
|
||||
denied-peer-ip=127.0.0.0-127.255.255.255
|
||||
denied-peer-ip=169.254.0.0-169.254.255.255
|
||||
denied-peer-ip=127.0.0.0-127.255.255.255
|
||||
denied-peer-ip=172.16.0.0-172.31.255.255
|
||||
denied-peer-ip=192.0.0.0-192.0.0.255
|
||||
denied-peer-ip=192.0.2.0-192.0.2.255
|
||||
denied-peer-ip=192.88.99.0-192.88.99.255
|
||||
denied-peer-ip=192.168.0.0-192.168.255.255
|
||||
denied-peer-ip=198.18.0.0-198.19.255.255
|
||||
denied-peer-ip=198.51.100.0-198.51.100.255
|
||||
denied-peer-ip=203.0.113.0-203.0.113.255
|
||||
denied-peer-ip=240.0.0.0-255.255.255.255
|
||||
syslog
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
# this is jitsi-meet nginx module configuration
|
||||
# this forward all http traffic to the nginx virtual host port
|
||||
# and the rest to the turn server
|
||||
|
||||
#
|
||||
# Multiplexing based on ALPN is DEPRECATED. ALPN does not play well with websockets on some browsers and reverse proxies.
|
||||
# To migrate away from using it read: https://jitsi.org/multiplexing-to-bridge-ws-howto
|
||||
# This file will be removed at some point and if deployment is still using it, will break.
|
||||
#
|
||||
stream {
|
||||
upstream web {
|
||||
server 127.0.0.1:4444;
|
||||
}
|
||||
upstream turn {
|
||||
server 127.0.0.1:4445;
|
||||
server 127.0.0.1:5349;
|
||||
}
|
||||
# since 1.13.10
|
||||
map $ssl_preread_alpn_protocols $upstream {
|
||||
|
||||
@@ -45,8 +45,10 @@ server {
|
||||
error_page 404 /static/404.html;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/javascript application/json;
|
||||
gzip_types text/plain text/css application/javascript application/json image/x-icon application/octet-stream application/wasm;
|
||||
gzip_vary on;
|
||||
gzip_proxied no-cache no-store private expired auth;
|
||||
gzip_min_length 512;
|
||||
|
||||
location = /config.js {
|
||||
alias /etc/jitsi/meet/jitsi-meet.example.com-config.js;
|
||||
@@ -61,6 +63,11 @@ server {
|
||||
{
|
||||
add_header 'Access-Control-Allow-Origin' '*';
|
||||
alias /usr/share/jitsi-meet/$1/$2;
|
||||
|
||||
# cache all versioned files
|
||||
if ($arg_v) {
|
||||
expires 1y;
|
||||
}
|
||||
}
|
||||
|
||||
# BOSH
|
||||
@@ -80,6 +87,15 @@ server {
|
||||
tcp_nodelay on;
|
||||
}
|
||||
|
||||
# colibri (JVB) websockets for jvb1
|
||||
location ~ ^/colibri-ws/default-id/(.*) {
|
||||
proxy_pass http://127.0.0.1:9090/colibri-ws/default-id/$1$is_args$args;
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
tcp_nodelay on;
|
||||
}
|
||||
|
||||
location ~ ^/([^/?&:'"]+)$ {
|
||||
try_files $uri @root_path;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ server {
|
||||
ssi on;
|
||||
}
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/javascript application/json image/x-icon application/octet-stream application/wasm;
|
||||
gzip_vary on;
|
||||
gzip_proxied no-cache no-store private expired auth;
|
||||
gzip_min_length 512;
|
||||
|
||||
# BOSH
|
||||
location /http-bind {
|
||||
proxy_pass http://localhost:5280/http-bind;
|
||||
|
||||
@@ -28,6 +28,12 @@ server {
|
||||
tcp_nodelay on;
|
||||
}
|
||||
|
||||
gzip on;
|
||||
gzip_types text/plain text/css application/javascript application/json image/x-icon application/octet-stream application/wasm;
|
||||
gzip_vary on;
|
||||
gzip_proxied no-cache no-store private expired auth;
|
||||
gzip_min_length 512;
|
||||
|
||||
location ~ ^/([^/?&:'"]+)$ {
|
||||
try_files $uri @root_path;
|
||||
}
|
||||
|
||||
10
index.html
10
index.html
@@ -8,7 +8,17 @@
|
||||
|
||||
<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
|
||||
<link rel="stylesheet" href="css/all.css">
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
if (!JitsiMeetJS.app) {
|
||||
return;
|
||||
}
|
||||
|
||||
JitsiMeetJS.app.renderEntryPoint({
|
||||
Component: JitsiMeetJS.app.entryPoints.APP
|
||||
})
|
||||
})
|
||||
</script>
|
||||
<script>
|
||||
// IE11 and earlier can be identified via their user agent and be
|
||||
// redirected to a page that is known to have no newer js syntax.
|
||||
|
||||
@@ -1,132 +1,23 @@
|
||||
/* eslint-disable no-unused-vars, no-var, max-len */
|
||||
/* eslint sort-keys: ["error", "asc", {"caseSensitive": false}] */
|
||||
|
||||
var interfaceConfig = {
|
||||
DEFAULT_BACKGROUND: '#474747',
|
||||
DEFAULT_LOGO_URL: '../images/watermark.png',
|
||||
|
||||
/**
|
||||
* Whether or not the blurred video background for large video should be
|
||||
* displayed on browsers that can support it.
|
||||
*/
|
||||
DISABLE_VIDEO_BACKGROUND: false,
|
||||
|
||||
INITIAL_TOOLBAR_TIMEOUT: 20000,
|
||||
TOOLBAR_TIMEOUT: 4000,
|
||||
TOOLBAR_ALWAYS_VISIBLE: false,
|
||||
DEFAULT_REMOTE_DISPLAY_NAME: 'Fellow Jitster',
|
||||
DEFAULT_LOCAL_DISPLAY_NAME: 'me',
|
||||
SHOW_JITSI_WATERMARK: true,
|
||||
JITSI_WATERMARK_LINK: 'https://jitsi.org',
|
||||
|
||||
// if watermark is disabled by default, it can be shown only for guests
|
||||
SHOW_WATERMARK_FOR_GUESTS: true,
|
||||
SHOW_BRAND_WATERMARK: false,
|
||||
BRAND_WATERMARK_LINK: '',
|
||||
SHOW_POWERED_BY: false,
|
||||
SHOW_DEEP_LINKING_IMAGE: false,
|
||||
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
|
||||
DISPLAY_WELCOME_PAGE_CONTENT: true,
|
||||
DISPLAY_WELCOME_PAGE_TOOLBAR_ADDITIONAL_CONTENT: false,
|
||||
APP_NAME: 'Jitsi Meet',
|
||||
NATIVE_APP_NAME: 'Jitsi Meet',
|
||||
PROVIDER_NAME: 'Jitsi',
|
||||
LANG_DETECTION: true, // Allow i18n to detect the system language
|
||||
|
||||
/**
|
||||
* Hide the invite prompt in the header when alone in the meeting.
|
||||
*/
|
||||
HIDE_INVITE_MORE_HEADER: false,
|
||||
|
||||
/**
|
||||
* The name of the toolbar buttons to display in the toolbar. If present,
|
||||
* the button will display. Exceptions are "livestreaming" and "recording"
|
||||
* which also require being a moderator and some values in config.js to be
|
||||
* enabled. Also, the "profile" button will not display for user's with a
|
||||
* jwt.
|
||||
*/
|
||||
TOOLBAR_BUTTONS: [
|
||||
'microphone', 'camera', 'closedcaptions', 'desktop', 'fullscreen',
|
||||
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
||||
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
||||
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone',
|
||||
'e2ee', 'security'
|
||||
],
|
||||
|
||||
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar' ],
|
||||
|
||||
// Determines how the video would fit the screen. 'both' would fit the whole
|
||||
// screen, 'height' would fit the original video height to the height of the
|
||||
// screen, 'width' would fit the original video width to the width of the
|
||||
// screen respecting ratio.
|
||||
VIDEO_LAYOUT_FIT: 'both',
|
||||
|
||||
/**
|
||||
* Whether to only show the filmstrip (and hide the toolbar).
|
||||
*/
|
||||
filmStripOnly: false,
|
||||
|
||||
/**
|
||||
* Whether to show thumbnails in filmstrip as a column instead of as a row.
|
||||
*/
|
||||
VERTICAL_FILMSTRIP: true,
|
||||
|
||||
// A html text to be shown to guests on the close page, false disables it
|
||||
CLOSE_PAGE_GUEST_HINT: false,
|
||||
SHOW_PROMOTIONAL_CLOSE_PAGE: false,
|
||||
FILM_STRIP_MAX_HEIGHT: 120,
|
||||
|
||||
// Enables feedback star animation.
|
||||
ENABLE_FEEDBACK_ANIMATION: false,
|
||||
DISABLE_FOCUS_INDICATOR: false,
|
||||
DISABLE_DOMINANT_SPEAKER_INDICATOR: false,
|
||||
|
||||
/**
|
||||
* Whether the speech to text transcription subtitles panel is disabled.
|
||||
* If {@code undefined}, defaults to {@code false}.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
DISABLE_TRANSCRIPTION_SUBTITLES: false,
|
||||
|
||||
/**
|
||||
* Whether the ringing sound in the call/ring overlay is disabled. If
|
||||
* {@code undefined}, defaults to {@code false}.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
DISABLE_RINGING: false,
|
||||
AUDIO_LEVEL_PRIMARY_COLOR: 'rgba(255,255,255,0.4)',
|
||||
AUDIO_LEVEL_SECONDARY_COLOR: 'rgba(255,255,255,0.2)',
|
||||
POLICY_LOGO: null,
|
||||
LOCAL_THUMBNAIL_RATIO: 16 / 9, // 16:9
|
||||
REMOTE_THUMBNAIL_RATIO: 1, // 1:1
|
||||
// Documentation reference for the live streaming feature.
|
||||
LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live',
|
||||
|
||||
/**
|
||||
* Whether the mobile app Jitsi Meet is to be promoted to participants
|
||||
* attempting to join a conference in a mobile Web browser. If
|
||||
* {@code undefined}, defaults to {@code true}.
|
||||
* A UX mode where the last screen share participant is automatically
|
||||
* pinned. Valid values are the string "remote-only" so remote participants
|
||||
* get pinned but not local, otherwise any truthy value for all participants,
|
||||
* and any falsy value to disable the feature.
|
||||
*
|
||||
* @type {boolean}
|
||||
* Note: this mode is experimental and subject to breakage.
|
||||
*/
|
||||
MOBILE_APP_PROMO: true,
|
||||
|
||||
/**
|
||||
* Maximum coeficient of the ratio of the large video to the visible area
|
||||
* after the large video is scaled to fit the window.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
MAXIMUM_ZOOMING_COEFFICIENT: 1.3,
|
||||
|
||||
/*
|
||||
* If indicated some of the error dialogs may point to the support URL for
|
||||
* help.
|
||||
*/
|
||||
SUPPORT_URL: 'https://community.jitsi.org/',
|
||||
AUTO_PIN_LATEST_SCREEN_SHARE: 'remote-only',
|
||||
BRAND_WATERMARK_LINK: '',
|
||||
|
||||
CLOSE_PAGE_GUEST_HINT: false, // A html text to be shown to guests on the close page, false disables it
|
||||
/**
|
||||
* Whether the connection indicator icon should hide itself based on
|
||||
* connection strength. If true, the connection indicator will remain
|
||||
@@ -153,51 +44,120 @@ var interfaceConfig = {
|
||||
*/
|
||||
CONNECTION_INDICATOR_DISABLED: false,
|
||||
|
||||
/**
|
||||
* If true, hides the video quality label indicating the resolution status
|
||||
* of the current large video.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
VIDEO_QUALITY_LABEL_DISABLED: false,
|
||||
DEFAULT_BACKGROUND: '#474747',
|
||||
DEFAULT_LOCAL_DISPLAY_NAME: 'me',
|
||||
DEFAULT_LOGO_URL: 'images/watermark.png',
|
||||
DEFAULT_REMOTE_DISPLAY_NAME: 'Fellow Jitster',
|
||||
DEFAULT_WELCOME_PAGE_LOGO_URL: 'images/watermark.png',
|
||||
|
||||
/**
|
||||
* If true, will display recent list
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
RECENT_LIST_ENABLED: true,
|
||||
DISABLE_DOMINANT_SPEAKER_INDICATOR: false,
|
||||
|
||||
// Names of browsers which should show a warning stating the current browser
|
||||
// has a suboptimal experience. Browsers which are not listed as optimal or
|
||||
// unsupported are considered suboptimal. Valid values are:
|
||||
// chrome, chromium, edge, electron, firefox, nwjs, opera, safari
|
||||
OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'nwjs', 'electron', 'safari' ],
|
||||
|
||||
// Browsers, in addition to those which do not fully support WebRTC, that
|
||||
// are not supported and should show the unsupported browser page.
|
||||
UNSUPPORTED_BROWSERS: [],
|
||||
|
||||
/**
|
||||
* A UX mode where the last screen share participant is automatically
|
||||
* pinned. Valid values are the string "remote-only" so remote participants
|
||||
* get pinned but not local, otherwise any truthy value for all participants,
|
||||
* and any falsy value to disable the feature.
|
||||
*
|
||||
* Note: this mode is experimental and subject to breakage.
|
||||
*/
|
||||
AUTO_PIN_LATEST_SCREEN_SHARE: 'remote-only',
|
||||
|
||||
/**
|
||||
* If true, presence status: busy, calling, connected etc. is not displayed.
|
||||
*/
|
||||
DISABLE_PRESENCE_STATUS: false,
|
||||
DISABLE_FOCUS_INDICATOR: false,
|
||||
|
||||
/**
|
||||
* If true, notifications regarding joining/leaving are no longer displayed.
|
||||
*/
|
||||
DISABLE_JOIN_LEAVE_NOTIFICATIONS: false,
|
||||
|
||||
/**
|
||||
* If true, presence status: busy, calling, connected etc. is not displayed.
|
||||
*/
|
||||
DISABLE_PRESENCE_STATUS: false,
|
||||
|
||||
/**
|
||||
* Whether the ringing sound in the call/ring overlay is disabled. If
|
||||
* {@code undefined}, defaults to {@code false}.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
DISABLE_RINGING: false,
|
||||
|
||||
/**
|
||||
* Whether the speech to text transcription subtitles panel is disabled.
|
||||
* If {@code undefined}, defaults to {@code false}.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
DISABLE_TRANSCRIPTION_SUBTITLES: false,
|
||||
|
||||
/**
|
||||
* Whether or not the blurred video background for large video should be
|
||||
* displayed on browsers that can support it.
|
||||
*/
|
||||
DISABLE_VIDEO_BACKGROUND: false,
|
||||
|
||||
DISPLAY_WELCOME_PAGE_CONTENT: true,
|
||||
DISPLAY_WELCOME_PAGE_TOOLBAR_ADDITIONAL_CONTENT: false,
|
||||
|
||||
ENABLE_DIAL_OUT: true,
|
||||
|
||||
ENABLE_FEEDBACK_ANIMATION: false, // Enables feedback star animation.
|
||||
|
||||
FILM_STRIP_MAX_HEIGHT: 120,
|
||||
|
||||
/**
|
||||
* Whether to only show the filmstrip (and hide the toolbar).
|
||||
*/
|
||||
filmStripOnly: false,
|
||||
|
||||
GENERATE_ROOMNAMES_ON_WELCOME_PAGE: true,
|
||||
|
||||
/**
|
||||
* Hide the logo on the deep linking pages.
|
||||
*/
|
||||
HIDE_DEEP_LINKING_LOGO: false,
|
||||
|
||||
/**
|
||||
* Hide the invite prompt in the header when alone in the meeting.
|
||||
*/
|
||||
HIDE_INVITE_MORE_HEADER: false,
|
||||
|
||||
INITIAL_TOOLBAR_TIMEOUT: 20000,
|
||||
JITSI_WATERMARK_LINK: 'https://jitsi.org',
|
||||
|
||||
LANG_DETECTION: true, // Allow i18n to detect the system language
|
||||
LIVE_STREAMING_HELP_LINK: 'https://jitsi.org/live', // Documentation reference for the live streaming feature.
|
||||
LOCAL_THUMBNAIL_RATIO: 16 / 9, // 16:9
|
||||
|
||||
/**
|
||||
* Maximum coefficient of the ratio of the large video to the visible area
|
||||
* after the large video is scaled to fit the window.
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
MAXIMUM_ZOOMING_COEFFICIENT: 1.3,
|
||||
|
||||
/**
|
||||
* Whether the mobile app Jitsi Meet is to be promoted to participants
|
||||
* attempting to join a conference in a mobile Web browser. If
|
||||
* {@code undefined}, defaults to {@code true}.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
MOBILE_APP_PROMO: true,
|
||||
|
||||
NATIVE_APP_NAME: 'Jitsi Meet',
|
||||
|
||||
// Names of browsers which should show a warning stating the current browser
|
||||
// has a suboptimal experience. Browsers which are not listed as optimal or
|
||||
// unsupported are considered suboptimal. Valid values are:
|
||||
// chrome, chromium, edge, electron, firefox, nwjs, opera, safari
|
||||
OPTIMAL_BROWSERS: [ 'chrome', 'chromium', 'firefox', 'nwjs', 'electron', 'safari' ],
|
||||
|
||||
POLICY_LOGO: null,
|
||||
PROVIDER_NAME: 'Jitsi',
|
||||
|
||||
/**
|
||||
* If true, will display recent list
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
RECENT_LIST_ENABLED: true,
|
||||
REMOTE_THUMBNAIL_RATIO: 1, // 1:1
|
||||
|
||||
SETTINGS_SECTIONS: [ 'devices', 'language', 'moderator', 'profile', 'calendar' ],
|
||||
SHOW_BRAND_WATERMARK: false,
|
||||
|
||||
/**
|
||||
* Decides whether the chrome extension banner should be rendered on the landing page and during the meeting.
|
||||
* If this is set to false, the banner will not be rendered at all. If set to true, the check for extension(s)
|
||||
@@ -205,6 +165,64 @@ var interfaceConfig = {
|
||||
*/
|
||||
SHOW_CHROME_EXTENSION_BANNER: false,
|
||||
|
||||
SHOW_DEEP_LINKING_IMAGE: false,
|
||||
SHOW_JITSI_WATERMARK: true,
|
||||
SHOW_POWERED_BY: false,
|
||||
SHOW_PROMOTIONAL_CLOSE_PAGE: false,
|
||||
SHOW_WATERMARK_FOR_GUESTS: true, // if watermark is disabled by default, it can be shown only for guests
|
||||
|
||||
/*
|
||||
* If indicated some of the error dialogs may point to the support URL for
|
||||
* help.
|
||||
*/
|
||||
SUPPORT_URL: 'https://community.jitsi.org/',
|
||||
|
||||
TOOLBAR_ALWAYS_VISIBLE: false,
|
||||
|
||||
/**
|
||||
* The name of the toolbar buttons to display in the toolbar, including the
|
||||
* "More actions" menu. If present, the button will display. Exceptions are
|
||||
* "livestreaming" and "recording" which also require being a moderator and
|
||||
* some values in config.js to be enabled. Also, the "profile" button will
|
||||
* not display for users with a JWT.
|
||||
* Notes:
|
||||
* - it's impossible to choose which buttons go in the "More actions" menu
|
||||
* - it's impossible to control the placement of buttons
|
||||
* - 'desktop' controls the "Share your screen" button
|
||||
*/
|
||||
TOOLBAR_BUTTONS: [
|
||||
'microphone', 'camera', 'closedcaptions', 'desktop', 'embedmeeting', 'fullscreen',
|
||||
'fodeviceselection', 'hangup', 'profile', 'chat', 'recording',
|
||||
'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand',
|
||||
'videoquality', 'filmstrip', 'invite', 'feedback', 'stats', 'shortcuts',
|
||||
'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', 'security'
|
||||
],
|
||||
|
||||
TOOLBAR_TIMEOUT: 4000,
|
||||
|
||||
// Browsers, in addition to those which do not fully support WebRTC, that
|
||||
// are not supported and should show the unsupported browser page.
|
||||
UNSUPPORTED_BROWSERS: [],
|
||||
|
||||
/**
|
||||
* Whether to show thumbnails in filmstrip as a column instead of as a row.
|
||||
*/
|
||||
VERTICAL_FILMSTRIP: true,
|
||||
|
||||
// Determines how the video would fit the screen. 'both' would fit the whole
|
||||
// screen, 'height' would fit the original video height to the height of the
|
||||
// screen, 'width' would fit the original video width to the width of the
|
||||
// screen respecting ratio.
|
||||
VIDEO_LAYOUT_FIT: 'both',
|
||||
|
||||
/**
|
||||
* If true, hides the video quality label indicating the resolution status
|
||||
* of the current large video.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
VIDEO_QUALITY_LABEL_DISABLED: false,
|
||||
|
||||
/**
|
||||
* When enabled, the kick participant button will not be presented for users without a JWT
|
||||
*/
|
||||
@@ -262,9 +280,10 @@ var interfaceConfig = {
|
||||
|
||||
// Allow all above example options to include a trailing comma and
|
||||
// prevent fear when commenting out the last value.
|
||||
// eslint-disable-next-line sort-keys
|
||||
makeJsonParserHappy: 'even if last key had a trailing comma'
|
||||
|
||||
// no configuration value should follow this line.
|
||||
// No configuration value should follow this line.
|
||||
};
|
||||
|
||||
/* eslint-enable no-unused-vars, no-var, max-len */
|
||||
|
||||
@@ -5,10 +5,9 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ
|
||||
target 'jitsi-meet' do
|
||||
project 'app/app.xcodeproj'
|
||||
|
||||
pod 'Crashlytics', '~> 3.14.0'
|
||||
pod 'Fabric', '~> 1.10.2'
|
||||
pod 'Firebase/Core', '~> 6.16.0'
|
||||
pod 'Firebase/DynamicLinks', '~> 6.16.0'
|
||||
pod 'Firebase/Analytics', '~> 6.33.0'
|
||||
pod 'Firebase/Crashlytics', '~> 6.33.0'
|
||||
pod 'Firebase/DynamicLinks', '~> 6.33.0'
|
||||
end
|
||||
|
||||
target 'JitsiMeet' do
|
||||
|
||||
189
ios/Podfile.lock
189
ios/Podfile.lock
@@ -11,10 +11,7 @@ PODS:
|
||||
- CocoaLumberjack (3.5.3):
|
||||
- CocoaLumberjack/Core (= 3.5.3)
|
||||
- CocoaLumberjack/Core (3.5.3)
|
||||
- Crashlytics (3.14.0):
|
||||
- Fabric (~> 1.10.2)
|
||||
- DoubleConversion (1.1.6)
|
||||
- Fabric (1.10.2)
|
||||
- FBLazyVector (0.61.5-jitsi.1)
|
||||
- FBReactNativeSpec (0.61.5-jitsi.1):
|
||||
- Folly (= 2018.10.22.00)
|
||||
@@ -23,48 +20,50 @@ PODS:
|
||||
- React-Core (= 0.61.5-jitsi.1)
|
||||
- React-jsi (= 0.61.5-jitsi.1)
|
||||
- ReactCommon/turbomodule/core (= 0.61.5-jitsi.1)
|
||||
- Firebase/Core (6.16.0):
|
||||
- Firebase/Analytics (6.33.0):
|
||||
- Firebase/Core
|
||||
- Firebase/Core (6.33.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseAnalytics (= 6.2.2)
|
||||
- Firebase/CoreOnly (6.16.0):
|
||||
- FirebaseCore (= 6.6.1)
|
||||
- Firebase/DynamicLinks (6.16.0):
|
||||
- FirebaseAnalytics (= 6.8.3)
|
||||
- Firebase/CoreOnly (6.33.0):
|
||||
- FirebaseCore (= 6.10.3)
|
||||
- Firebase/Crashlytics (6.33.0):
|
||||
- Firebase/CoreOnly
|
||||
- FirebaseDynamicLinks (~> 4.0.6)
|
||||
- FirebaseAnalytics (6.2.2):
|
||||
- FirebaseCore (~> 6.6)
|
||||
- FirebaseInstanceID (~> 4.3)
|
||||
- GoogleAppMeasurement (= 6.2.2)
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
|
||||
- GoogleUtilities/MethodSwizzler (~> 6.0)
|
||||
- GoogleUtilities/Network (~> 6.0)
|
||||
- "GoogleUtilities/NSData+zlib (~> 6.0)"
|
||||
- nanopb (= 0.3.9011)
|
||||
- FirebaseAnalyticsInterop (1.5.0)
|
||||
- FirebaseCore (6.6.1):
|
||||
- FirebaseCoreDiagnostics (~> 1.2)
|
||||
- FirebaseCoreDiagnosticsInterop (~> 1.2)
|
||||
- GoogleUtilities/Environment (~> 6.5)
|
||||
- GoogleUtilities/Logger (~> 6.5)
|
||||
- FirebaseCoreDiagnostics (1.2.2):
|
||||
- FirebaseCoreDiagnosticsInterop (~> 1.2)
|
||||
- GoogleDataTransportCCTSupport (~> 2.0)
|
||||
- GoogleUtilities/Environment (~> 6.5)
|
||||
- GoogleUtilities/Logger (~> 6.5)
|
||||
- nanopb (~> 0.3.901)
|
||||
- FirebaseCoreDiagnosticsInterop (1.2.0)
|
||||
- FirebaseDynamicLinks (4.0.8):
|
||||
- FirebaseAnalyticsInterop (~> 1.3)
|
||||
- FirebaseCore (~> 6.2)
|
||||
- FirebaseInstallations (1.1.1):
|
||||
- FirebaseCore (~> 6.6)
|
||||
- GoogleUtilities/UserDefaults (~> 6.5)
|
||||
- FirebaseCrashlytics (~> 4.6.1)
|
||||
- Firebase/DynamicLinks (6.33.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.1):
|
||||
- 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)
|
||||
- FirebaseInstanceID (4.3.2):
|
||||
- FirebaseCore (~> 6.6)
|
||||
- FirebaseInstallations (~> 1.0)
|
||||
- GoogleUtilities/Environment (~> 6.5)
|
||||
- GoogleUtilities/UserDefaults (~> 6.5)
|
||||
- Folly (2018.10.22.00):
|
||||
- boost-for-react-native
|
||||
- DoubleConversion
|
||||
@@ -75,37 +74,36 @@ PODS:
|
||||
- DoubleConversion
|
||||
- glog
|
||||
- glog (0.3.5)
|
||||
- GoogleAppMeasurement (6.2.2):
|
||||
- GoogleUtilities/AppDelegateSwizzler (~> 6.0)
|
||||
- GoogleUtilities/MethodSwizzler (~> 6.0)
|
||||
- GoogleUtilities/Network (~> 6.0)
|
||||
- "GoogleUtilities/NSData+zlib (~> 6.0)"
|
||||
- nanopb (= 0.3.9011)
|
||||
- GoogleDataTransport (5.1.0)
|
||||
- GoogleDataTransportCCTSupport (2.0.1):
|
||||
- GoogleDataTransport (~> 5.1)
|
||||
- nanopb (~> 0.3.901)
|
||||
- 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.4.0):
|
||||
- nanopb (~> 1.30906.0)
|
||||
- GoogleSignIn (5.0.1):
|
||||
- AppAuth (~> 1.2)
|
||||
- GTMAppAuth (~> 1.0)
|
||||
- GTMSessionFetcher/Core (~> 1.1)
|
||||
- GoogleUtilities/AppDelegateSwizzler (6.5.2):
|
||||
- GoogleUtilities/AppDelegateSwizzler (6.7.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network
|
||||
- GoogleUtilities/Environment (6.5.2)
|
||||
- GoogleUtilities/Logger (6.5.2):
|
||||
- GoogleUtilities/Environment (6.7.2):
|
||||
- PromisesObjC (~> 1.2)
|
||||
- GoogleUtilities/Logger (6.7.2):
|
||||
- GoogleUtilities/Environment
|
||||
- GoogleUtilities/MethodSwizzler (6.5.2):
|
||||
- GoogleUtilities/MethodSwizzler (6.7.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/Network (6.5.2):
|
||||
- GoogleUtilities/Network (6.7.2):
|
||||
- GoogleUtilities/Logger
|
||||
- "GoogleUtilities/NSData+zlib"
|
||||
- GoogleUtilities/Reachability
|
||||
- "GoogleUtilities/NSData+zlib (6.5.2)"
|
||||
- GoogleUtilities/Reachability (6.5.2):
|
||||
- "GoogleUtilities/NSData+zlib (6.7.2)"
|
||||
- GoogleUtilities/Reachability (6.7.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GoogleUtilities/UserDefaults (6.5.2):
|
||||
- GoogleUtilities/UserDefaults (6.7.2):
|
||||
- GoogleUtilities/Logger
|
||||
- GTMAppAuth (1.0.0):
|
||||
- AppAuth/Core (~> 1.0)
|
||||
@@ -115,13 +113,13 @@ PODS:
|
||||
- GTMSessionFetcher/Core (1.2.2)
|
||||
- GTMSessionFetcher/Full (1.2.2):
|
||||
- GTMSessionFetcher/Core (= 1.2.2)
|
||||
- nanopb (0.3.9011):
|
||||
- nanopb/decode (= 0.3.9011)
|
||||
- nanopb/encode (= 0.3.9011)
|
||||
- nanopb/decode (0.3.9011)
|
||||
- nanopb/encode (0.3.9011)
|
||||
- nanopb (1.30906.0):
|
||||
- nanopb/decode (= 1.30906.0)
|
||||
- nanopb/encode (= 1.30906.0)
|
||||
- nanopb/decode (1.30906.0)
|
||||
- nanopb/encode (1.30906.0)
|
||||
- ObjectiveDropboxOfficial (3.9.4)
|
||||
- PromisesObjC (1.2.8)
|
||||
- PromisesObjC (1.2.10)
|
||||
- RCTRequired (0.61.5-jitsi.1)
|
||||
- RCTTypeSafety (0.61.5-jitsi.1):
|
||||
- FBLazyVector (= 0.61.5-jitsi.1)
|
||||
@@ -285,7 +283,7 @@ PODS:
|
||||
- React-cxxreact (= 0.61.5-jitsi.1)
|
||||
- React-jsi (= 0.61.5-jitsi.1)
|
||||
- React-jsinspector (0.61.5-jitsi.1)
|
||||
- react-native-background-timer (2.1.1):
|
||||
- react-native-background-timer (2.4.0):
|
||||
- React
|
||||
- react-native-calendar-events (2.0.0):
|
||||
- React
|
||||
@@ -293,9 +291,9 @@ PODS:
|
||||
- React
|
||||
- react-native-netinfo (4.1.5):
|
||||
- React
|
||||
- react-native-webrtc (1.75.3):
|
||||
- react-native-webrtc (1.84.0):
|
||||
- React
|
||||
- react-native-webview (7.4.1):
|
||||
- react-native-webview (10.9.0):
|
||||
- React
|
||||
- React-RCTActionSheet (0.61.5-jitsi.1):
|
||||
- React-Core/RCTActionSheetHeaders (= 0.61.5-jitsi.1)
|
||||
@@ -373,13 +371,12 @@ DEPENDENCIES:
|
||||
- Amplitude-iOS (~> 4.0.4)
|
||||
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
|
||||
- CocoaLumberjack (~> 3.5.3)
|
||||
- Crashlytics (~> 3.14.0)
|
||||
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
|
||||
- Fabric (~> 1.10.2)
|
||||
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector/`)
|
||||
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec/`)
|
||||
- Firebase/Core (~> 6.16.0)
|
||||
- Firebase/DynamicLinks (~> 6.16.0)
|
||||
- Firebase/Analytics (~> 6.33.0)
|
||||
- Firebase/Crashlytics (~> 6.33.0)
|
||||
- Firebase/DynamicLinks (~> 6.33.0)
|
||||
- Folly (from `../node_modules/react-native/third-party-podspecs/Folly.podspec`)
|
||||
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
|
||||
- ObjectiveDropboxOfficial (~> 3.9.4)
|
||||
@@ -424,20 +421,15 @@ SPEC REPOS:
|
||||
- AppAuth
|
||||
- boost-for-react-native
|
||||
- CocoaLumberjack
|
||||
- Crashlytics
|
||||
- Fabric
|
||||
- Firebase
|
||||
- FirebaseAnalytics
|
||||
- FirebaseAnalyticsInterop
|
||||
- FirebaseCore
|
||||
- FirebaseCoreDiagnostics
|
||||
- FirebaseCoreDiagnosticsInterop
|
||||
- FirebaseCrashlytics
|
||||
- FirebaseDynamicLinks
|
||||
- FirebaseInstallations
|
||||
- FirebaseInstanceID
|
||||
- GoogleAppMeasurement
|
||||
- GoogleDataTransport
|
||||
- GoogleDataTransportCCTSupport
|
||||
- GoogleSignIn
|
||||
- GoogleUtilities
|
||||
- GTMAppAuth
|
||||
@@ -530,32 +522,27 @@ SPEC CHECKSUMS:
|
||||
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
|
||||
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
|
||||
CocoaLumberjack: 2f44e60eb91c176d471fdba43b9e3eae6a721947
|
||||
Crashlytics: 540b7e5f5da5a042647227a5e3ac51d85eed06df
|
||||
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
|
||||
Fabric: 706c8b8098fff96c33c0db69cbf81f9c551d0d74
|
||||
FBLazyVector: 4a5251159a3ed05dc11cc8b74cf937869935814b
|
||||
FBReactNativeSpec: 6fa602a20993212cc9877a81838578ffb0008bc9
|
||||
Firebase: 497158b816d0a86fc31babbd05546fcd7e6083ff
|
||||
FirebaseAnalytics: cf95d3aab897612783020fbd98401d5366f135ee
|
||||
FirebaseAnalyticsInterop: 3f86269c38ae41f47afeb43ebf32a001f58fcdae
|
||||
FirebaseCore: 85064903ed6c28e47fec9c7bd149d94ba1b6b6e7
|
||||
FirebaseCoreDiagnostics: e9b4cd8ba60dee0f2d13347332e4b7898cca5b61
|
||||
FirebaseCoreDiagnosticsInterop: 296e2c5f5314500a850ad0b83e9e7c10b011a850
|
||||
FirebaseDynamicLinks: 417dc6dbb6013233c77558290d73296f429656a6
|
||||
FirebaseInstallations: acb3216eb9784d3b1d2d2d635ff74fa892cc0c44
|
||||
FirebaseInstanceID: 7ee0d6777013bb952f377b41965bf132b6a075be
|
||||
Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5
|
||||
FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193
|
||||
FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd
|
||||
FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1
|
||||
FirebaseCrashlytics: 5777d3462fb8c3ab9e80a2473bd7d667a2e8411c
|
||||
FirebaseDynamicLinks: 6eac37d86910382eafb6315d952cc44c9e176094
|
||||
FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2
|
||||
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
|
||||
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
|
||||
GoogleAppMeasurement: d0560d915abf15e692e8538ba1d58442217b6aff
|
||||
GoogleDataTransport: b29a21d813e906014ca16c00897827e40e4a24ab
|
||||
GoogleDataTransportCCTSupport: 6f15a89b0ca35d6fa523e1f752ef818588885988
|
||||
GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436
|
||||
GoogleDataTransport: b7f406340a291370045a270c599e53c6fa6ec20f
|
||||
GoogleSignIn: 3a51b9bb8e48b635fd7f4272cee06ca260345b86
|
||||
GoogleUtilities: ad0f3b691c67909d03a3327cc205222ab8f42e0e
|
||||
GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3
|
||||
GTMAppAuth: 4deac854479704f348309e7b66189e604cf5e01e
|
||||
GTMSessionFetcher: 61bb0f61a4cb560030f1222021178008a5727a23
|
||||
nanopb: 18003b5e52dab79db540fe93fe9579f399bd1ccd
|
||||
nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc
|
||||
ObjectiveDropboxOfficial: a5afefc83f6467c42c45f2253f583f2ad1ffc701
|
||||
PromisesObjC: c119f3cd559f50b7ae681fa59dc1acd19173b7e6
|
||||
PromisesObjC: b14b1c6b68e306650688599de8a45e49fae81151
|
||||
RCTRequired: f63dd90a89a60602acdd44c42e5d2645ca60ab79
|
||||
RCTTypeSafety: 24a3c6d55684046ed550b1d0ef083a9bf71c8bd4
|
||||
React: 71c5a51135f291c3b32c0b558e167b858ae50e84
|
||||
@@ -565,12 +552,12 @@ SPEC CHECKSUMS:
|
||||
React-jsi: 4f35c1a2273d193a80c1c3831c808413840c260c
|
||||
React-jsiexecutor: de1c37cf59ae9adcbf2be82eea0e090dc3f3205e
|
||||
React-jsinspector: b76c4e84a7833bb4c90549d59ed53ec299ff912b
|
||||
react-native-background-timer: 0d34748e53a972507c66963490c775321a88f6f2
|
||||
react-native-background-timer: e0384ea2fa5a98f67f84f9c4dc274260ddd674ed
|
||||
react-native-calendar-events: 1442fad71a00388f933cfa25512588fec300fcf8
|
||||
react-native-keep-awake: eba3137546b10003361b37c761f6c429b59814ae
|
||||
react-native-netinfo: 8d8db463bcc5db66a8ac5c48a7d86beb3b92f61a
|
||||
react-native-webrtc: 86d841823e66d68cc1f86712db1c2956056bf0c2
|
||||
react-native-webview: 4dbc1d2a4a6b9c5e9e723c62651917aa2b5e579e
|
||||
react-native-webrtc: 9268ae9a2bc9730796b0968d012327e92c392adf
|
||||
react-native-webview: 6ee7868ca8eba635dbf7963986d1ab7959da0391
|
||||
React-RCTActionSheet: b72ddbfbe15b44ce691d128e4b582f4bb9abb540
|
||||
React-RCTAnimation: cfaefba5024499d336b76ab850e6bd33b232b5e3
|
||||
React-RCTBlob: c427e643bef82999deeab97489ba43298ecfbe24
|
||||
@@ -589,6 +576,6 @@ SPEC CHECKSUMS:
|
||||
RNWatch: a5320c959c75e72845c07985f3e935e58998f1d3
|
||||
Yoga: 7b4209fda2441f99d54dd6cf4c82b094409bb68f
|
||||
|
||||
PODFILE CHECKSUM: 082858daebbe170e7a490de433e7f2a99e0c3701
|
||||
PODFILE CHECKSUM: 224e84629bf45ae487c4ebc66faf33ec8304fb67
|
||||
|
||||
COCOAPODS: 1.9.1
|
||||
COCOAPODS: 1.9.3
|
||||
|
||||
@@ -291,9 +291,9 @@
|
||||
13B07F8E1A680F5B00A75B9A /* Resources */,
|
||||
0B26BE701EC5BC3C00EEFB41 /* Embed Frameworks */,
|
||||
B35383AD1DDA0083008F406A /* Adjust embedded framework architectures */,
|
||||
DE3A859324C701EA009B7D76 /* Copy WebRTC dSYM */,
|
||||
0BB7DA181EC9E695007AAE98 /* Adjust ATS */,
|
||||
DEF4813D224925A2002AD03A /* Copy Google Plist file */,
|
||||
DEC2069321CBBD6900072F03 /* Setup Crashlytics */,
|
||||
DE11877A21EE09640078D059 /* Setup Google reverse URL handler */,
|
||||
DE4F6D6E22005C0400DE699E /* Setup Dropbox */,
|
||||
0BEA5C491F7B8F73000D0AB4 /* Embed Watch Content */,
|
||||
@@ -474,6 +474,24 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "INFO_PLIST=\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"\nGOOGLE_PLIST=\"$PROJECT_DIR/GoogleService-Info.plist\"\n\nif [[ -f $GOOGLE_PLIST ]]; then\n REVERSED_CLIENT_ID=$(/usr/libexec/PlistBuddy -c \"Print :REVERSED_CLIENT_ID:\" $GOOGLE_PLIST)\n /usr/libexec/PlistBuddy -c \"Set :CFBundleURLTypes:1:CFBundleURLSchemes:0 $REVERSED_CLIENT_ID\" $INFO_PLIST\nfi\n";
|
||||
};
|
||||
DE3A859324C701EA009B7D76 /* Copy WebRTC dSYM */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Copy WebRTC dSYM";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "set -x\n\nif [[ \"${CONFIGURATION}\" != \"Debug\" ]]; then\n cp -r ../../node_modules/react-native-webrtc/ios/WebRTC.dSYM ${DWARF_DSYM_FOLDER_PATH}/\nfi\n";
|
||||
};
|
||||
DE4F6D6E22005C0400DE699E /* Setup Dropbox */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@@ -492,24 +510,6 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "INFO_PLIST=\"$BUILT_PRODUCTS_DIR/$INFOPLIST_PATH\"\nDROPBOX_KEY_FILE=\"$PROJECT_DIR/dropbox.key\"\n\nif [[ -f $DROPBOX_KEY_FILE ]]; then\n /usr/libexec/PlistBuddy -c \"Delete :LSApplicationQueriesSchemes\" $INFO_PLIST\n /usr/libexec/PlistBuddy -c \"Add :LSApplicationQueriesSchemes array\" $INFO_PLIST\n /usr/libexec/PlistBuddy -c \"Add :LSApplicationQueriesSchemes:0 string 'dbapi-2'\" $INFO_PLIST\n /usr/libexec/PlistBuddy -c \"Add :LSApplicationQueriesSchemes:1 string 'dbapi-8-emm'\" $INFO_PLIST\n\n DROPBOX_KEY=$(head -n 1 $DROPBOX_KEY_FILE)\n /usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:2:CFBundleURLName string dropbox\" $INFO_PLIST\n /usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:2:CFBundleURLSchemes array\" $INFO_PLIST\n /usr/libexec/PlistBuddy -c \"Add :CFBundleURLTypes:2:CFBundleURLSchemes:0 string $DROPBOX_KEY\" $INFO_PLIST\nfi\n";
|
||||
};
|
||||
DEC2069321CBBD6900072F03 /* Setup Crashlytics */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Setup Crashlytics";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "GOOGLE_PLIST=\"$PROJECT_DIR/GoogleService-Info.plist\"\n\nif [[ -f $GOOGLE_PLIST ]]; then\n if [ \"${CONFIGURATION}\" != \"Debug\" ]; then\n find \"${DWARF_DSYM_FOLDER_PATH}\" -name \"*.dSYM\" | xargs -I \\{\\} ${PODS_ROOT}/Fabric/upload-symbols -gsp $GOOGLE_PLIST -p ios \\{\\}\n fi\nfi\n";
|
||||
};
|
||||
DEF4813D224925A2002AD03A /* Copy Google Plist file */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#import "Types.h"
|
||||
#import "ViewController.h"
|
||||
|
||||
@import Crashlytics;
|
||||
@import Fabric;
|
||||
@import Firebase;
|
||||
@import JitsiMeet;
|
||||
|
||||
@@ -36,6 +34,7 @@
|
||||
jitsiMeet.universalLinkDomains = @[@"meet.jit.si", @"alpha.jitsi.net", @"beta.meet.jit.si"];
|
||||
|
||||
jitsiMeet.defaultConferenceOptions = [JitsiMeetConferenceOptions fromBuilder:^(JitsiMeetConferenceOptionsBuilder *builder) {
|
||||
[builder setFeatureFlag:@"resolution" withValue:@(360)];
|
||||
builder.serverURL = [NSURL URLWithString:@"https://meet.jit.si"];
|
||||
builder.welcomePageEnabled = YES;
|
||||
|
||||
@@ -47,10 +46,11 @@
|
||||
}];
|
||||
|
||||
// Initialize Crashlytics and Firebase if a valid GoogleService-Info.plist file was provided.
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist] && ![jitsiMeet isCrashReportingDisabled]) {
|
||||
NSLog(@"Enabling Crashlytics and Firebase");
|
||||
if ([FIRUtilities appContainsRealServiceInfoPlist]) {
|
||||
NSLog(@"Enabling Firebase");
|
||||
[FIRApp configure];
|
||||
[Fabric with:@[[Crashlytics class]]];
|
||||
// Crashlytics defaults to disabled wirth the FirebaseCrashlyticsCollectionEnabled Info.plist key.
|
||||
[[FIRCrashlytics crashlytics] setCrashlyticsCollectionEnabled:![jitsiMeet isCrashReportingDisabled]];
|
||||
}
|
||||
|
||||
[jitsiMeet application:application didFinishLaunchingWithOptions:launchOptions];
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>20.3.0</string>
|
||||
<string>20.5.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
@@ -66,10 +66,10 @@
|
||||
<string>See your scheduled meetings in the app.</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Participate in meetings with video.</string>
|
||||
<key>NSLocationWhenInUseUsageDescription</key>
|
||||
<string></string>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string>Participate in meetings with voice.</string>
|
||||
<key>NSLocalNetworkUsageDescription</key>
|
||||
<string>Local network is used for establishing Peer-to-Peer connections.</string>
|
||||
<key>NSUserActivityTypes</key>
|
||||
<array>
|
||||
<string>org.jitsi.JitsiMeet.ios.conference</string>
|
||||
@@ -99,7 +99,7 @@
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<key>firebase_crashlytics_collection_enabled</key>
|
||||
<key>FirebaseCrashlyticsCollectionEnabled</key>
|
||||
<string>false</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>20.3.0</string>
|
||||
<string>20.5.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>20.3.0</string>
|
||||
<string>20.5.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>CLKComplicationPrincipalClass</key>
|
||||
|
||||
@@ -80,6 +80,10 @@ platform :ios do
|
||||
uses_non_exempt_encryption: false
|
||||
)
|
||||
|
||||
# Upload dSYMs to Crashlytics
|
||||
download_dsyms
|
||||
upload_symbols_to_crashlytics
|
||||
|
||||
# Cleanup
|
||||
clean_build_artifacts
|
||||
reset_git_repo(skip_clean: true)
|
||||
|
||||
5
ios/scripts/run-packager-helper.command
Executable file
5
ios/scripts/run-packager-helper.command
Executable file
@@ -0,0 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
|
||||
exec ${THIS_DIR}/../../node_modules/react-native/scripts/launchPackager.command --reset-cache
|
||||
@@ -3,6 +3,8 @@
|
||||
# This script is executed from Xcode to start the React packager for Debug
|
||||
# targets.
|
||||
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
|
||||
export RCT_METRO_PORT="${RCT_METRO_PORT:=8081}"
|
||||
echo "export RCT_METRO_PORT=${RCT_METRO_PORT}" > "${SRCROOT}/../../node_modules/react-native/scripts/.packager.env"
|
||||
|
||||
@@ -13,7 +15,6 @@ if [[ "$CONFIGURATION" = "Debug" ]]; then
|
||||
exit 2
|
||||
fi
|
||||
else
|
||||
open -g "$SRCROOT/../../node_modules/react-native/scripts/launchPackager.command" || echo "Can't start packager automatically"
|
||||
open -g "$THIS_DIR/run-packager-helper.command" || echo "Can't start packager automatically"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2.9.0</string>
|
||||
<string>2.11.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"en": "Anglès",
|
||||
"af": "Afrikaans",
|
||||
"ar": "Àrab",
|
||||
"bg": "Búlgar",
|
||||
"ca": "Català",
|
||||
"cs": "Txec",
|
||||
@@ -10,25 +11,36 @@
|
||||
"enGB": "Anglès (Regne Unit)",
|
||||
"eo": "Esperanto",
|
||||
"es": "Espanyol",
|
||||
"esUS": "Espanyol (Amèrica llatina)",
|
||||
"esUS": "Espanyol (Amèrica Llatina)",
|
||||
"et": "Estonià",
|
||||
"eu": "Èuscar",
|
||||
"fi": "Finès",
|
||||
"fr": "Francès",
|
||||
"frCA": "Francès (Canadà)",
|
||||
"he": "Hebreu",
|
||||
"mr": "Marathi",
|
||||
"hr": "Croat",
|
||||
"hu": "Hongarès",
|
||||
"hy": "Armeni",
|
||||
"id": "Indonesi",
|
||||
"it": "Italià",
|
||||
"ja": "Japonès",
|
||||
"ko": "Coreà",
|
||||
"lt": "Lituà",
|
||||
"nl": "Neerlandès",
|
||||
"oc": "Occità",
|
||||
"pl": "Polonès",
|
||||
"ptBR": "Portuguès (Brasil)",
|
||||
"ru": "Rus",
|
||||
"ro": "Romanès",
|
||||
"sc": "Sard",
|
||||
"sk": "Eslovac",
|
||||
"sl": "Eslovè",
|
||||
"sv": "Suec",
|
||||
"th": "Tai",
|
||||
"tr": "Turc",
|
||||
"uk": "Ucraïnès",
|
||||
"vi": "Vietnamita",
|
||||
"zhCN": "Xinès (Xina)",
|
||||
"zhTW": "Xinès (Taiwan)",
|
||||
"et": "Estonià"
|
||||
"zhTW": "Xinès (Taiwan)"
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"ru": "Russisch",
|
||||
"sk": "Slowakisch",
|
||||
"sl": "Slowenisch",
|
||||
"sr": "Serbish",
|
||||
"sv": "Schwedisch",
|
||||
"tr": "Türkisch",
|
||||
"vi": "Vietnamesisch",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"ru": "Russian",
|
||||
"sk": "",
|
||||
"sl": "Slovenian",
|
||||
"sr": "Serbian",
|
||||
"sv": "Swedish",
|
||||
"tr": "Turkish",
|
||||
"vi": "Vietnamese",
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
"ru": "Ruski",
|
||||
"sk": "Slovački",
|
||||
"sl": "Slovenski",
|
||||
"sr": "Srpski",
|
||||
"sv": "Švedski",
|
||||
"tr": "Turski",
|
||||
"vi": "Vijetnamski",
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"it": "Taṭalyant",
|
||||
"ja": "Tajapunit",
|
||||
"ko": "Takurit",
|
||||
"kab": "Taqbaylit",
|
||||
"nb": "Tanurvijit Bukmal",
|
||||
"oc": "Tuksitant",
|
||||
"pl": "Tapulunit",
|
||||
@@ -23,5 +24,25 @@
|
||||
"sv": "Taswidit",
|
||||
"tr": "Taṭurkit",
|
||||
"vi": "Tavyitnamit",
|
||||
"zhCN": "Tavyitnamit"
|
||||
"zhCN": "Tavyitnamit",
|
||||
"ro": "Tarumanit",
|
||||
"ar": "Taɛrabt",
|
||||
"zhTW": "Tacinwat (Taiwan)",
|
||||
"uk": "Tukranit",
|
||||
"th": "Tayland",
|
||||
"sc": "Tasardit",
|
||||
"nl": "Tahulandit",
|
||||
"lt": "Taliṭwanit",
|
||||
"id": "Tandunizit",
|
||||
"hu": "Tahungrit",
|
||||
"hr": "Takrwasit",
|
||||
"he": "Taɛbrit",
|
||||
"frCA": "Tafṛansist (Kanada)",
|
||||
"fi": "Tafinit",
|
||||
"eu": "Tabaskit",
|
||||
"et": "Tastunit",
|
||||
"esUS": "Taspanit (Temrikt Talatinit)",
|
||||
"enGB": "Tagnizit (Tagldit i ddukklen)",
|
||||
"da": "Tadanit",
|
||||
"ca": "Takaṭalant"
|
||||
}
|
||||
|
||||
@@ -38,5 +38,11 @@
|
||||
"lt": "Lituanian",
|
||||
"id": "Indonesian",
|
||||
"he": "Ebrèu",
|
||||
"eu": "Basc"
|
||||
"eu": "Basc",
|
||||
"mr": "Marathi",
|
||||
"sl": "Eslovèn",
|
||||
"ro": "Romanian",
|
||||
"ar": "Arabi"
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"pl": "Польский",
|
||||
"ptBR": "Португальский (Бразилия)",
|
||||
"ru": "Русский",
|
||||
"sr": "Сербский",
|
||||
"sv": "Шведский",
|
||||
"tr": "Турецкий",
|
||||
"vi": "Вьетнамский",
|
||||
|
||||
@@ -1,34 +1,39 @@
|
||||
{
|
||||
"en": "",
|
||||
"af": "",
|
||||
"bg": "",
|
||||
"ca": "",
|
||||
"cs": "",
|
||||
"da": "",
|
||||
"de": "",
|
||||
"el": "",
|
||||
"enGB": "",
|
||||
"eo": "",
|
||||
"es": "",
|
||||
"esUS": "",
|
||||
"et": "",
|
||||
"fi": "",
|
||||
"fr": "",
|
||||
"frCA": "",
|
||||
"hr": "",
|
||||
"hu": "",
|
||||
"hy": "",
|
||||
"it": "",
|
||||
"ja": "",
|
||||
"ko": "",
|
||||
"nl": "",
|
||||
"oc": "",
|
||||
"pl": "",
|
||||
"ptBR": "",
|
||||
"ru": "",
|
||||
"sv": "",
|
||||
"tr": "",
|
||||
"vi": "",
|
||||
"zhCN": "",
|
||||
"zhTW": ""
|
||||
"en": "Енглески",
|
||||
"af": "Африкански",
|
||||
"az": "Азербејџански",
|
||||
"bg": "Бугарски",
|
||||
"cs": "Чешки",
|
||||
"de": "Њемачки",
|
||||
"el": "Грчки",
|
||||
"eo": "Есперанто",
|
||||
"es": "Шпански",
|
||||
"fr": "Француски",
|
||||
"hy": "Јерменски",
|
||||
"it": "Италијански",
|
||||
"ja": "Јапански",
|
||||
"ko": "Корејски",
|
||||
"nb": "Норвешки Бокал",
|
||||
"oc": "Окцитански",
|
||||
"pl": "Пољски",
|
||||
"ptBR": "Португалски (Бразил)",
|
||||
"ru": "Руски",
|
||||
"sk": "Словачки",
|
||||
"sl": "Словенски",
|
||||
"sr": "Српски",
|
||||
"sv": "Шведски",
|
||||
"tr": "Турски",
|
||||
"vi": "Вијетнамски",
|
||||
"zhCN": "Кинески (Кина)",
|
||||
"zhTW": "Кинески (Тајван)",
|
||||
"nl": "Холандски",
|
||||
"hu": "Мађарски",
|
||||
"hr": "Хрватски",
|
||||
"frCA": "Француски (Канада)",
|
||||
"fi": "Фински",
|
||||
"et": "Естонски",
|
||||
"esUS": "Шпански (Латинска Америка)",
|
||||
"enGB": "Енглески (Велика Британија)",
|
||||
"da": "Дански",
|
||||
"ca": "Каталонски"
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
"id": "Indonesian",
|
||||
"it": "Italian",
|
||||
"ja": "Japanese",
|
||||
"kab": "Kabyle",
|
||||
"ko": "Korean",
|
||||
"lt": "Lithuanian",
|
||||
"nl": "Dutch",
|
||||
@@ -36,6 +37,7 @@
|
||||
"sc": "Sardinian",
|
||||
"sk": "Slovak",
|
||||
"sl": "Slovenian",
|
||||
"sr": "Serbian",
|
||||
"sv": "Swedish",
|
||||
"th": "Thailand",
|
||||
"tr": "Turkish",
|
||||
|
||||
@@ -534,7 +534,7 @@
|
||||
"selectCamera": "Kamera",
|
||||
"selectMic": "Mikrofon",
|
||||
"startAudioMuted": "Při připojení všem zlumit zvuk",
|
||||
"startVideoMuted": "Všechny připojovat jako skrýté",
|
||||
"startVideoMuted": "Všechny připojovat jako skryté",
|
||||
"title": "Nastavení",
|
||||
"speakers": "Reproduktory",
|
||||
"microphones": "Mikrofony"
|
||||
@@ -567,7 +567,7 @@
|
||||
"name": "Řečník",
|
||||
"seconds": "",
|
||||
"speakerStats": "Statistika řečníků",
|
||||
"speakerTime": "Mluvil již"
|
||||
"speakerTime": "Mluvil(a) již"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": " ",
|
||||
@@ -638,7 +638,7 @@
|
||||
"openChat": "",
|
||||
"pip": "",
|
||||
"profile": "Upravit váš profil",
|
||||
"raiseHand": "Příhlásit / Odhlásit se o slovo",
|
||||
"raiseHand": "Přihlásit / Odhlásit se o slovo",
|
||||
"raiseYourHand": "",
|
||||
"Settings": "Nastavení",
|
||||
"sharedvideo": "Sdílet obraz YouTube videa",
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
"add": "Einladen",
|
||||
"addContacts": "Laden Sie Ihre Kontakte ein",
|
||||
"copyInvite": "Sitzungseinladung kopieren",
|
||||
"copyLink": "Meeting-Link kopieren",
|
||||
"copyStream": "Live-Streaming-Link kopieren",
|
||||
"copyLink": "Konferenzlink kopieren",
|
||||
"copyStream": "Livestreaminglink kopieren",
|
||||
"countryNotSupported": "Wir unterstützen dieses Land noch nicht.",
|
||||
"countryReminder": "Telefonnummer nicht in den USA? Bitte sicherstellen, dass die Telefonnummer mit dem Ländercode beginnt.",
|
||||
"defaultEmail": "Ihre Standard-E-Mail",
|
||||
"disabled": "Sie können keine Teilnehmer einladen.",
|
||||
"failedToAdd": "Fehler beim Hinzufügen von Teilnehmern",
|
||||
"footerText": "Abgehender Ruf ist deaktiviert.",
|
||||
"googleEmail": "Google-E-Mail",
|
||||
"inviteMoreHeader": "Sie sind alleine in der Sitzung",
|
||||
"inviteMoreMailSubject": "An {{appName}} Meeting teilnehmen",
|
||||
"inviteMorePrompt": "Mehr Leute einladen",
|
||||
@@ -20,14 +21,16 @@
|
||||
"loadingPeople": "Suche nach einzuladenden Teilnehmern",
|
||||
"noResults": "Keine passenden Ergebnisse",
|
||||
"noValidNumbers": "Telefonnummer eingeben",
|
||||
"outlookEmail": "Outlook-E-Mail",
|
||||
"searchNumbers": "Telefonnummern hinzufügen",
|
||||
"searchPeople": "Nach Teilnehmern suchen",
|
||||
"searchPeopleAndNumbers": "Nach Teilnehmen suchen oder deren Telefonnummern hinzufügen",
|
||||
"shareInvite": "Einladung zur Versammlung teilen",
|
||||
"shareLink": "Teilen Sie den Meeting-Link, um andere einzuladen",
|
||||
"shareStream": "Den Live-Streaming-Link freigeben",
|
||||
"shareLink": "Teilen Sie den Konferenzlink, um andere einzuladen",
|
||||
"shareStream": "Den Livestreaminglink freigeben",
|
||||
"telephone": "Telefon: {{number}}",
|
||||
"title": "Teilnehmer zu dieser Konferenz einladen"
|
||||
"title": "Teilnehmer zu dieser Konferenz einladen",
|
||||
"yahooEmail": "Yahoo-E-Mail"
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
@@ -40,7 +43,7 @@
|
||||
"audioOnly": "Geringe Bandbreite"
|
||||
},
|
||||
"calendarSync": {
|
||||
"addMeetingURL": "Meeting-Link hinzufügen",
|
||||
"addMeetingURL": "Konferenzlink hinzufügen",
|
||||
"confirmAddLink": "Möchten Sie einen Jitsi-Link zu diesem Termin hinzufügen?",
|
||||
"error": {
|
||||
"appConfiguration": "Kalenderintegration ist nicht richtig konfiguriert.",
|
||||
@@ -89,9 +92,9 @@
|
||||
"DISCONNECTED": "Getrennt",
|
||||
"DISCONNECTING": "Verbindung wird getrennt",
|
||||
"ERROR": "Fehler",
|
||||
"FETCH_SESSION_ID": "Sitzungs-ID erhalten...",
|
||||
"FETCH_SESSION_ID": "Sitzungs-ID abrufen …",
|
||||
"GET_SESSION_ID_ERROR": "Sitzungs-ID-Fehler erhalten: {{code}}",
|
||||
"GOT_SESSION_ID": "Sitzungs-ID erhalten... Beendet",
|
||||
"GOT_SESSION_ID": "Sitzungs-ID abrufen … beendet",
|
||||
"LOW_BANDWIDTH": "Video für {{displayName}} wurde ausgeschaltet, um Bandbreite einzusparen"
|
||||
},
|
||||
"connectionindicator": {
|
||||
@@ -107,6 +110,7 @@
|
||||
"localaddress_plural": "Lokale Adressen:",
|
||||
"localport": "Lokaler Port:",
|
||||
"localport_plural": "Lokale Ports:",
|
||||
"maxEnabledResolution": "max. senden",
|
||||
"more": "Mehr anzeigen",
|
||||
"packetloss": "Paketverlust:",
|
||||
"quality": {
|
||||
@@ -139,7 +143,7 @@
|
||||
"ifHaveApp": "Wenn Sie die App bereits haben:",
|
||||
"joinInApp": "An dem Meeting teilnehmen mit der App",
|
||||
"launchWebButton": "Im Web öffnen",
|
||||
"title": "Die Konferenz wird in {{app}} geöffnet...",
|
||||
"title": "Die Konferenz wird in {{app}} geöffnet …",
|
||||
"tryAgainButton": "Erneut mit der nativen Applikation versuchen"
|
||||
},
|
||||
"defaultLink": "Bsp.: {{url}}",
|
||||
@@ -160,6 +164,7 @@
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Livestream"
|
||||
},
|
||||
"add": "Hinzufügen",
|
||||
"allow": "Erlauben",
|
||||
"alreadySharedVideoMsg": "Ein anderer Teilnehmer gibt bereits ein Video weiter. Bei dieser Konferenz ist jeweils nur ein geteiltes Video möglich.",
|
||||
"alreadySharedVideoTitle": "Nur ein geteiltes Video gleichzeitig",
|
||||
@@ -174,9 +179,9 @@
|
||||
"cameraUnsupportedResolutionError": "Die Kamera unterstützt die erforderliche Auflösung nicht.",
|
||||
"Cancel": "Abbrechen",
|
||||
"close": "Schließen",
|
||||
"conferenceDisconnectMsg": "Prüfen Sie allenfalls Ihre Netzwerkverbindung. Verbinde in {{seconds}} Sekunden...",
|
||||
"conferenceDisconnectMsg": "Prüfen Sie allenfalls Ihre Netzwerkverbindung. Verbinde in {{seconds}} Sekunden …",
|
||||
"conferenceDisconnectTitle": "Ihre Verbindung ist getrennt worden.",
|
||||
"conferenceReloadMsg": "Wir versuchen das zu beheben. Verbinde in {{seconds}} Sekunden...",
|
||||
"conferenceReloadMsg": "Wir versuchen das zu beheben. Verbinde in {{seconds}} Sekunden …",
|
||||
"conferenceReloadTitle": "Leider ist etwas schiefgegangen.",
|
||||
"confirm": "Bestätigen",
|
||||
"confirmNo": "Nein",
|
||||
@@ -185,21 +190,25 @@
|
||||
"connectErrorWithMsg": "Oh! Es hat etwas nicht geklappt und der Konferenz konnte nicht beigetreten werden: {{msg}}",
|
||||
"connecting": "Verbindung wird hergestellt",
|
||||
"contactSupport": "Support kontaktieren",
|
||||
"copied": "Kopiert",
|
||||
"copy": "Kopieren",
|
||||
"dismiss": "OK",
|
||||
"displayNameRequired": "Hallo! Wie ist Ihr Name?",
|
||||
"done": "Fertig",
|
||||
"e2eeDescription": "Ende-zu-Ende-Verschlüsselung ist derzeit noch EXPERIMENTELL. Bitte beachten Sie, dass das Aktivieren der Ende-zu-Ende-Verschlüsselung diverse serverseitige Funktionen deaktiviert: Aufnahmen, Livestreaming und Telefoneinwahl. Bitte beachten Sie außerdem, dass der Konferenz dann nur noch mit Browsern beigetreten werden kann, die Insertable Streams unterstützen.",
|
||||
"e2eeLabel": "E2EE-Schlüssel",
|
||||
"e2eeNoKey": "Keiner",
|
||||
"e2eeToggleSet": "Schlüssel festlegen",
|
||||
"e2eeSet": "Setzen",
|
||||
"e2eeWarning": "WARNUNG: Nicht alle Teilnehmer dieser Konferenz scheinen Ende-zu-Ende-Verschlüsselung zu unterstützen. Wenn Sie diese aktivieren, können die entsprechenden Teilnehmer nichts mehr sehen oder hören.",
|
||||
"enterDisplayName": "Bitte geben Sie hier Ihren Namen ein",
|
||||
"error": "Fehler",
|
||||
"externalInstallationMsg": "Die Bildschirmfreigabe-Erweiterung muss installiert werden.",
|
||||
"externalInstallationTitle": "Erweiterung erforderlich",
|
||||
"goToStore": "Zum Store",
|
||||
"gracefulShutdown": "Der Dienst steht momentan wegen Wartungsarbeiten nicht zur Verfügung. Bitte versuchen Sie es später noch einmal.",
|
||||
"grantModeratorDialog": "Möchten Sie diesen Teilnehmer wirklich zum Moderator machen?",
|
||||
"grantModeratorTitle": "Zum Moderator machen",
|
||||
"IamHost": "Ich bin der Organisator",
|
||||
"incorrectRoomLockPassword": "Falsches Passwort",
|
||||
"incorrectPassword": "Benutzername oder Passwort ungültig",
|
||||
"inlineInstallationMsg": "Die Bildschirmfreigabe-Erweiterung muss installiert werden.",
|
||||
"inlineInstallExtension": "Jetzt installieren",
|
||||
"internalError": "Oh! Es hat etwas nicht funktioniert. Der folgende Fehler ist aufgetreten: {{error}}",
|
||||
"internalErrorTitle": "Interner Fehler",
|
||||
"kickMessage": "Sie können sich für mehr Details an {{participantDisplayName}} wenden.",
|
||||
@@ -208,10 +217,11 @@
|
||||
"kickParticipantTitle": "Teilnehmer entfernen?",
|
||||
"kickTitle": "Autsch! {{participantDisplayName}} hat Sie aus dem Meeting geworfen",
|
||||
"liveStreaming": "Livestreaming",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Während einer Aufnahme nicht möglich",
|
||||
"liveStreamingDisabledForGuestTooltip": "Gäste können kein Livestreaming starten.",
|
||||
"liveStreamingDisabledTooltip": "Starten des Livestreams deaktiviert.",
|
||||
"lockMessage": "Die Konferenz konnte nicht gesperrt werden.",
|
||||
"lockRoom": "Meeting-$t(lockRoomPasswordUppercase) hinzufügen",
|
||||
"lockRoom": "Konferenz$t(lockRoomPassword) hinzufügen",
|
||||
"lockTitle": "Sperren fehlgeschlagen",
|
||||
"logoutQuestion": "Sind Sie sicher, dass Sie sich abmelden und die Konferenz verlassen möchten?",
|
||||
"logoutTitle": "Abmelden",
|
||||
@@ -224,7 +234,7 @@
|
||||
"micPermissionDeniedError": "Die Berechtigung zur Verwendung des Mikrofons wurde nicht erteilt. Sie können trotzdem an der Konferenz teilnehmen, aber die anderen Teilnehmer können Sie nicht hören. Verwenden Sie die Kamera-Schaltfläche in der Adressleiste, um die Berechtigungen zu erteilen.",
|
||||
"micUnknownError": "Das Mikrofon kann aus einem unbekannten Grund nicht verwendet werden.",
|
||||
"muteEveryoneElseDialog": "Einmal stummgeschaltet, können Sie deren Stummschaltung nicht mehr beenden, aber sie können ihre Stummschaltung jederzeit selbst beenden.",
|
||||
"muteEveryoneElseTitle": "Alle außer {{whom}} stummschaten?",
|
||||
"muteEveryoneElseTitle": "Alle außer {{whom}} stummschalten?",
|
||||
"muteEveryoneDialog": "Wollen Sie wirklich alle stummschalten? Sie können deren Stummschaltung nicht mehr beenden, aber sie können ihre Stummschaltung jederzeit selbst beenden.",
|
||||
"muteEveryoneTitle": "Alle stummschalten?",
|
||||
"muteEveryoneSelf": "sich selbst",
|
||||
@@ -234,13 +244,15 @@
|
||||
"muteParticipantDialog": "Wollen Sie diesen Teilnehmer wirklich stummschalten? Sie können die Stummschaltung nicht wieder aufheben, der Teilnehmer kann dies aber jederzeit selbst tun.",
|
||||
"muteParticipantTitle": "Teilnehmer stummschalten?",
|
||||
"Ok": "OK",
|
||||
"passwordLabel": "Dieses Meeting wurde von einem Teilnehmer gesichert. Bitte geben Sie das $t(lockRoomPassword) ein, um dem Meeting beizutreten.",
|
||||
"passwordNotSupported": "Das Festlegen von einem $t(lockRoomPassword) für das Meeting wird nicht unterstützt.",
|
||||
"passwordLabel": "Dieses Meeting wurde von einem Teilnehmer gesichert. Bitte geben Sie das $t(lockRoomPasswordUppercase) ein, um dem Meeting beizutreten.",
|
||||
"passwordNotSupported": "Das Festlegen eines Konferenzpassworts wird nicht unterstützt.",
|
||||
"passwordNotSupportedTitle": "$t(lockRoomPasswordUppercase) nicht unterstützt",
|
||||
"passwordRequired": "$t(lockRoomPasswordUppercase) erforderlich",
|
||||
"popupError": "Ihr Browser blockiert Pop-ups von dieser Website. Bitte aktivieren Sie Pop-ups in den Sicherheitseinstellungen des Browsers und versuchen Sie es erneut.",
|
||||
"popupErrorTitle": "Pop-up blockiert",
|
||||
"readMore": "mehr",
|
||||
"recording": "Aufnahme",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Während eines Livestreams nicht möglich",
|
||||
"recordingDisabledForGuestTooltip": "Gäste können keine Aufzeichnungen starten.",
|
||||
"recordingDisabledTooltip": "Start der Aufzeichnung deaktiviert.",
|
||||
"rejoinNow": "Jetzt erneut beitreten",
|
||||
@@ -252,17 +264,16 @@
|
||||
"remoteControlStopMessage": "Die Fernsteuerung wurde beendet!",
|
||||
"remoteControlTitle": "Fernsteuerung",
|
||||
"Remove": "Entfernen",
|
||||
"removePassword": "$t(lockRoomPassword) entfernen",
|
||||
"removePassword": "$t(lockRoomPasswordUppercase) entfernen",
|
||||
"removeSharedVideoMsg": "Sind Sie sicher, dass Sie das geteilte Video entfernen möchten?",
|
||||
"removeSharedVideoTitle": "Freigegebenes Video entfernen",
|
||||
"reservationError": "Fehler im Reservierungssystem",
|
||||
"reservationErrorMsg": "Fehler, Nummer: {{code}}, Nachricht: {{msg}}",
|
||||
"retry": "Wiederholen",
|
||||
"screenSharingFailedToInstall": "Oh! Die Erweiterung für die Bildschirmfreigabe konnte nicht installiert werden.",
|
||||
"screenSharingFailedToInstallTitle": "Bildschirmfreigabe-Erweiterung konnte nicht installiert werden",
|
||||
"screenSharingFirefoxPermissionDeniedError": "Die Bildschirmfreigabe ist leider fehlgeschlagen. Bitte stellen Sie sicher, dass die Berechtigung für die Bildschirmfreigabe im Browser erteilt wurde. ",
|
||||
"screenSharingFirefoxPermissionDeniedTitle": "Die Bildschirmfreigabe konnte nicht gestartet werden!",
|
||||
"screenSharingPermissionDeniedError": "Oh! Beim Anfordern der Bildschirmfreigabe-Berechtigungen hat etwas nicht funktioniert. Bitte aktualisieren und erneut versuchen.",
|
||||
"screenSharingAudio": "Audio teilen",
|
||||
"screenSharingFailed": "Ups! Beim Teilen des Bildschirms ist etwas schiefgegangen!",
|
||||
"screenSharingFailedTitle": "Bildschirmfreigabe fehlgeschlagen!",
|
||||
"screenSharingPermissionDeniedError": "Ups! Etwas stimmt nicht mit Ihren Berechtigungen zur Bildschirmfreigabe. Bitte neu laden und erneut versuchen.",
|
||||
"sendPrivateMessage": "Sie haben kürzlich eine private Nachricht erhalten. Hatten Sie die Absicht, darauf privat zu antworten, oder wollen Sie Ihre Nachricht an die Gruppe senden?",
|
||||
"sendPrivateMessageCancel": "An die Gruppe senden",
|
||||
"sendPrivateMessageOk": "Privat antworten",
|
||||
@@ -275,13 +286,13 @@
|
||||
"shareYourScreen": "Bildschirm freigeben",
|
||||
"shareYourScreenDisabled": "Bildschirmfreigabe deaktiviert.",
|
||||
"shareYourScreenDisabledForGuest": "Gäste können den Bildschirm nicht freigeben.",
|
||||
"startLiveStreaming": "Einen Livestream starten",
|
||||
"startLiveStreaming": "Livestream starten",
|
||||
"startRecording": "Aufnahme starten",
|
||||
"startRemoteControlErrorMessage": "Beim Versuch, die Fernsteuerung zu starten, ist ein Fehler aufgetreten!",
|
||||
"stopLiveStreaming": "Livestreaming stoppen",
|
||||
"stopLiveStreaming": "Livestream stoppen",
|
||||
"stopRecording": "Aufnahme stoppen",
|
||||
"stopRecordingWarning": "Sind Sie sicher, dass Sie die Aufnahme stoppen möchten?",
|
||||
"stopStreamingWarning": "Sind Sie sicher, dass Sie das Livestreaming stoppen möchten?",
|
||||
"stopStreamingWarning": "Sind Sie sicher, dass Sie den Livestream stoppen möchten?",
|
||||
"streamKey": "Streamschlüssel",
|
||||
"Submit": "OK",
|
||||
"thankYou": "Danke für die Verwendung von {{appName}}!",
|
||||
@@ -289,14 +300,13 @@
|
||||
"tokenAuthFailed": "Sie sind nicht berechtigt, dieser Konferenz beizutreten.",
|
||||
"tokenAuthFailedTitle": "Authentifizierung fehlgeschlagen",
|
||||
"transcribing": "Wird transkribiert",
|
||||
"unlockRoom": "Meeting-$t(lockRoomPassword) entfernen",
|
||||
"unlockRoom": "Konferenz$t(lockRoomPassword) entfernen",
|
||||
"userPassword": "Benutzerpasswort",
|
||||
"WaitForHostMsg": "Die Konferenz <b>{{room}}</b> wurde noch nicht gestartet. Wenn Sie der Organisator sind, authentifizieren Sie sich. Warten Sie andernfalls, bis der Organisator erscheint.",
|
||||
"WaitForHostMsgWOk": "Die Konferenz <b>{{room}}</b> wurde noch nicht gestartet. Wenn Sie der Organisator sind, drücken Sie zum Authentifizieren auf OK. Warten Sie andernfalls, bis der Organisator erscheint.",
|
||||
"WaitingForHost": "Warten auf den Organisator...",
|
||||
"WaitingForHost": "Warten auf den Organisator …",
|
||||
"Yes": "Ja",
|
||||
"yourEntireScreen": "Ganzer Bildschirm",
|
||||
"screenSharingAudio": "Audio austauschen"
|
||||
"yourEntireScreen": "Ganzer Bildschirm"
|
||||
},
|
||||
"dialOut": {
|
||||
"statusMessage": "ist jetzt {{status}}"
|
||||
@@ -304,6 +314,12 @@
|
||||
"documentSharing": {
|
||||
"title": "Freigegebenes Dokument"
|
||||
},
|
||||
"e2ee": {
|
||||
"labelToolTip": "Audio- und Videodaten dieser Unterhaltung sind jetzt zwischen den Teilnehmern verschlüsselt"
|
||||
},
|
||||
"embedMeeting": {
|
||||
"title": "Diese Konferenz einbetten"
|
||||
},
|
||||
"feedback": {
|
||||
"average": "Durchschnittlich",
|
||||
"bad": "Schlecht",
|
||||
@@ -322,8 +338,8 @@
|
||||
},
|
||||
"info": {
|
||||
"accessibilityLabel": "Informationen anzeigen",
|
||||
"addPassword": "$t(lockRoomPassword) hinzufügen",
|
||||
"cancelPassword": "$t(lockRoomPassword) löschen",
|
||||
"addPassword": "$t(lockRoomPasswordUppercase) hinzufügen",
|
||||
"cancelPassword": "$t(lockRoomPasswordUppercase) löschen",
|
||||
"conferenceURL": "Link:",
|
||||
"country": "Land",
|
||||
"dialANumber": "Um am Meeting teilzunehmen, müssen Sie eine dieser Nummern wählen und dann die PIN eingeben.",
|
||||
@@ -335,7 +351,7 @@
|
||||
"genericError": "Es ist leider etwas schiefgegangen.",
|
||||
"inviteLiveStream": "Klicken Sie auf {{url}}, um den Livestream dieser Konferenz zu öffnen",
|
||||
"invitePhone": "Wenn Sie stattdessen per Telefon beitreten möchten, wählen sie: {{number}},,{{conferenceID}}#\n",
|
||||
"invitePhoneAlternatives": "Suchen Sie nach einer anderen Einwahlnummer ?\nMeeting-Einwahlnummern anzeigen: {{url}}\n\n\nWenn Sie sich auch über ein Raumtelefon einwählen, nehmen Sie teil, ohne sich mit dem Ton zu verbinden: {{silentUrl}}",
|
||||
"invitePhoneAlternatives": "Suchen Sie nach einer anderen Einwahlnummer ?\nEinwahlnummern der Konferenz anzeigen: {{url}}\n\n\nWenn Sie sich auch über ein Raumtelefon einwählen, nehmen Sie teil, ohne sich mit dem Ton zu verbinden: {{silentUrl}}",
|
||||
"inviteURLFirstPartGeneral": "Sie wurden zur Teilnahme an einem Meeting eingeladen.",
|
||||
"inviteURLFirstPartPersonal": "{{name}} lädt Sie zu einem Meeting ein.\n",
|
||||
"inviteURLSecondPart": "\nAm Meeting teilnehmen:\n{{url}}\n",
|
||||
@@ -348,7 +364,7 @@
|
||||
"password": "$t(lockRoomPasswordUppercase):",
|
||||
"title": "Teilen",
|
||||
"tooltip": "Freigabe-Link und Einwahlinformationen für dieses Meeting",
|
||||
"label": "Meeting-Informationen"
|
||||
"label": "Konferenzinformationen"
|
||||
},
|
||||
"inviteDialog": {
|
||||
"alertText": "Die Einladung einiger Teilnehmer ist fehlgeschlagen.",
|
||||
@@ -382,6 +398,8 @@
|
||||
"videoQuality": "Anrufqualität verwalten"
|
||||
},
|
||||
"liveStreaming": {
|
||||
"limitNotificationDescriptionWeb": "Wegen hoher Nachfrage ist Ihr Stream auf {{limit}} min. begrenzt. Für unlimitiertes Streaming nutzen Sie bitte <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"limitNotificationDescriptionNative": "Ihr Stream ist begrenzt auf {{limit}} min. Für unlimitiertes Streaming, nutzen Sie bitte {{app}}.",
|
||||
"busy": "Es werden Ressourcen zum Streamen bereitgestellt. Bitte in ein paar Minuten erneut versuchen.",
|
||||
"busyTitle": "Alle Streaming-Instanzen sind in Gebrauch",
|
||||
"changeSignIn": "Konten wechseln.",
|
||||
@@ -391,17 +409,17 @@
|
||||
"error": "Das Livestreaming ist fehlgeschlagen. Bitte versuchen Sie es erneut.",
|
||||
"errorAPI": "Beim Abrufen der YouTube-Livestreams ist ein Fehler aufgetreten. Bitte versuchen Sie, sich erneut anzumelden.",
|
||||
"errorLiveStreamNotEnabled": "Livestreaming ist für {{email}} nicht aktiviert. Aktivieren Sie das Livestreaming oder melden Sie sich bei einem Konto mit aktiviertem Livestreaming an.",
|
||||
"expandedOff": "Livestreaming wurde angehalten",
|
||||
"expandedOff": "Livestream wurde angehalten",
|
||||
"expandedOn": "Das Meeting wird momentan an YouTube gestreamt.",
|
||||
"expandedPending": "Livestreaming wird gestartet...",
|
||||
"failedToStart": "Livestreaming konnte nicht gestartet werden",
|
||||
"expandedPending": "Livestream wird gestartet …",
|
||||
"failedToStart": "Livestream konnte nicht gestartet werden",
|
||||
"getStreamKeyManually": "Wir waren nicht in der Lage, Livestreams abzurufen. Versuchen Sie, Ihren Livestream-Schlüssel von YouTube zu erhalten.",
|
||||
"invalidStreamKey": "Der Livestream-Schlüssel ist u. U. falsch.",
|
||||
"off": "Livestreaming gestoppt",
|
||||
"offBy": "{{name}} stoppte das Livestreaming",
|
||||
"on": "Livestreaming",
|
||||
"onBy": "{{name}} startete das Livestreaming",
|
||||
"pending": "Livestream wird gestartet...",
|
||||
"off": "Livestream gestoppt",
|
||||
"offBy": "{{name}} stoppte den Livestream",
|
||||
"on": "Livestream",
|
||||
"onBy": "{{name}} startete den Livestream",
|
||||
"pending": "Livestream wird gestartet …",
|
||||
"serviceName": "Livestreaming-Dienst",
|
||||
"signedInAs": "Sie sind derzeit angemeldet als:",
|
||||
"signIn": "Mit Google anmelden",
|
||||
@@ -442,7 +460,7 @@
|
||||
"stop": "Aufnahme stoppen",
|
||||
"yes": "Ja"
|
||||
},
|
||||
"lockRoomPassword": "Passwort",
|
||||
"lockRoomPassword": "passwort",
|
||||
"lockRoomPasswordUppercase": "Passwort",
|
||||
"me": "ich",
|
||||
"notify": {
|
||||
@@ -474,11 +492,51 @@
|
||||
"unmute": "Stummschaltung aufheben",
|
||||
"newDeviceCameraTitle": "Neue Kamera erkannt",
|
||||
"newDeviceAudioTitle": "Neues Audiogerät erkannt",
|
||||
"newDeviceAction": "Verwenden"
|
||||
"newDeviceAction": "Verwenden",
|
||||
"OldElectronAPPTitle": "Sicherheitslücke!",
|
||||
"oldElectronClientDescription1": "Sie scheinen eine alte Version des Jitsi-Meet-Clients zu nutzen. Diese hat bekannte Schwachstellen. Bitte aktualisieren Sie auf unsere ",
|
||||
"oldElectronClientDescription2": "aktuelle Version",
|
||||
"oldElectronClientDescription3": "!"
|
||||
},
|
||||
"passwordSetRemotely": "von einem anderen Teilnehmer gesetzt",
|
||||
"passwordDigitsOnly": "Bis zu {{number}} Ziffern",
|
||||
"poweredby": "Betrieben von",
|
||||
"prejoin": {
|
||||
"audioAndVideoError": "Audio- und Videofehler:",
|
||||
"audioOnlyError": "Audiofehler:",
|
||||
"audioTrackError": "Audiotrack konnte nicht erstellt werden.",
|
||||
"calling": "Rufaufbau",
|
||||
"callMe": "Mich anrufen",
|
||||
"callMeAtNumber": "Mich unter dieser Nummer anrufen:",
|
||||
"configuringDevices": "Geräte werden eingerichtet …",
|
||||
"connectedWithAudioQ": "Sie sind mit Audio verbunden?",
|
||||
"copyAndShare": "Konferenzlink kopieren & teilen",
|
||||
"dialInMeeting": "Telefoneinwahl",
|
||||
"dialInPin": "In die Konferenz einwählen und PIN eingeben:",
|
||||
"dialing": "Wählen",
|
||||
"doNotShow": "Nicht mehr anzeigen",
|
||||
"errorDialOut": "Anruf fehlgeschlagen",
|
||||
"errorDialOutDisconnected": "Anruf fehlgeschlagen. Verbindungsabbruch",
|
||||
"errorDialOutFailed": "Anruf fehlgeschlagen. Anruf fehlgeschlagen",
|
||||
"errorDialOutStatus": "Fehler beim Abrufen des Anrufstatus",
|
||||
"errorStatusCode": "Anruf fehlgeschlagen. Statuscode: {{status}}",
|
||||
"errorValidation": "Nummerverifikation fehlgeschlagen",
|
||||
"iWantToDialIn": "Ich möchte mich einwählen",
|
||||
"joinAudioByPhone": "Per Telefon teilnehmen",
|
||||
"joinMeeting": "Konferenz beitreten",
|
||||
"joinWithoutAudio": "Ohne Ton beitreten",
|
||||
"initiated": "Anruf gestartet",
|
||||
"linkCopied": "Link in die Zwischenablage kopiert",
|
||||
"lookGood": "Ihr Mikrofon scheint zu funktionieren.",
|
||||
"or": "oder",
|
||||
"premeeting": "Vorraum",
|
||||
"showScreen": "Konferenzvorraum aktivieren",
|
||||
"startWithPhone": "Mit Telefonaudio starten",
|
||||
"screenSharingError": "Fehler bei Bildschirmfreigabe:",
|
||||
"videoOnlyError": "Videofehler:",
|
||||
"videoTrackError": "Videotrack konnte nicht erstellt werden.",
|
||||
"viewAllNumbers": "alle Nummern anzeigen"
|
||||
},
|
||||
"presenceStatus": {
|
||||
"busy": "Beschäftigt",
|
||||
"calling": "Wird angerufen …",
|
||||
@@ -501,6 +559,8 @@
|
||||
},
|
||||
"raisedHand": "Ich möchte sprechen",
|
||||
"recording": {
|
||||
"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>.",
|
||||
"limitNotificationDescriptionNative": "Wegen hoher Nachfrage ist Ihre Aufnahme auf {{limit}} min begrenzt. Für unlimitierte Aufnahmen nutzen Sie bitte <3>{{app}}</3>.",
|
||||
"authDropboxText": "In Dropbox hochladen",
|
||||
"availableSpace": "Verfügbarer Speicherplatz: {{spaceLeft}} MB (ca. {{duration}} Minuten Aufzeichnung)",
|
||||
"beta": "BETA",
|
||||
@@ -511,7 +571,7 @@
|
||||
"expandedOn": "Das Meeting wird momentan aufgezeichnet.",
|
||||
"expandedPending": "Aufzeichnung wird gestartet…",
|
||||
"failedToStart": "Die Aufnahme konnte nicht gestartet werden",
|
||||
"fileSharingdescription": "Aufzeichnung mit Meeting-Teilnehmer teilen",
|
||||
"fileSharingdescription": "Aufzeichnung mit Konferenzteilnehmer teilen",
|
||||
"live": "LIVE",
|
||||
"loggedIn": "Als {{userName}} angemeldet",
|
||||
"off": "Aufnahme gestoppt",
|
||||
@@ -531,7 +591,8 @@
|
||||
"pullToRefresh": "Ziehen, um zu aktualisieren"
|
||||
},
|
||||
"security": {
|
||||
"about": "Sie können einen Passwort zu Ihrer Sitzung hinzufügen. Die Teilnehmer müssen dieses ebenfalls eingeben, bevor sie an der Sitzung teilnehmen dürfen",
|
||||
"about": "Sie können Ihre Konferenz mit einem Passwort sichern. Teilnehmer müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
|
||||
"aboutReadOnly": "Moderatoren können die Konferenz mit einem Passwort sichern. Teilnehmer müssen dieses eingeben, bevor sie an der Sitzung teilnehmen dürfen.",
|
||||
"insecureRoomNameWarning": "Der Raumname ist unsicher. Unerwünschte Teilnehmer könnten Ihrer Konferenz beitreten",
|
||||
"securityOptions": "Sicherheitsoptionen"
|
||||
},
|
||||
@@ -563,12 +624,15 @@
|
||||
"settingsView": {
|
||||
"advanced": "Erweitert",
|
||||
"alertOk": "OK",
|
||||
"alertCancel": "Abbrechen",
|
||||
"alertTitle": "Warnung",
|
||||
"alertURLText": "Die angegebene Server-URL ist ungültig",
|
||||
"buildInfoSection": "Build-Informationen",
|
||||
"conferenceSection": "Konferenz",
|
||||
"disableCallIntegration": "Native Anrufintegration deaktivieren",
|
||||
"disableP2P": "Ende-zu-Ende-Modus deaktivieren",
|
||||
"disableCrashReporting": "Absturzberichte deaktivieren",
|
||||
"disableCrashReportingWarning": "Möchten Sie die Absturzberichte wirklich deaktivieren? Diese Einstellung wird nach einem Neustart der App wirksam.",
|
||||
"displayName": "Anzeigename",
|
||||
"email": "E-Mail",
|
||||
"header": "Einstellungen",
|
||||
@@ -610,14 +674,18 @@
|
||||
"chat": "Chatfenster ein-/ausblenden",
|
||||
"document": "Geteiltes Dokument schließen",
|
||||
"download": "Unsere Apps herunterladen",
|
||||
"embedMeeting": "Konferenz einbetten",
|
||||
"e2ee": "Ende-zu-Ende-Verschlüsselung",
|
||||
"feedback": "Feedback hinterlassen",
|
||||
"fullScreen": "Vollbildmodus aktivieren/deaktivieren",
|
||||
"fullScreen": "Vollbildmodus ein-/ausschalten",
|
||||
"grantModerator": "Zum Moderator machen",
|
||||
"hangup": "Anruf beenden",
|
||||
"help": "Hilfe",
|
||||
"invite": "Teilnehmer einladen",
|
||||
"kick": "Teilnehmer entfernen",
|
||||
"lobbyButton": "Lobbymodus ein-/ausschalten",
|
||||
"localRecording": "Lokale Aufzeichnungssteuerelemente ein-/ausschalten",
|
||||
"lockRoom": "Meeting-Passwort ein-/auschalten",
|
||||
"lockRoom": "Konferenzpasswort ein-/auschalten",
|
||||
"moreActions": "Menü „Weitere Aktionen“ ein-/ausschalten",
|
||||
"moreActionsMenu": "Menü „Weitere Aktionen“",
|
||||
"moreOptions": "Menü „Weitere Optionen“",
|
||||
@@ -639,6 +707,7 @@
|
||||
"speakerStats": "Sprecherstatistik ein-/ausblenden",
|
||||
"tileView": "Kachelansicht ein-/ausschalten",
|
||||
"toggleCamera": "Kamera wechseln",
|
||||
"toggleFilmstrip": "Miniaturansichten ein-/ausschalten",
|
||||
"videomute": "„Video stummschalten“ ein-/ausschalten",
|
||||
"videoblur": "Video-Unschärfe ein-/ausschalten"
|
||||
},
|
||||
@@ -653,6 +722,8 @@
|
||||
"documentClose": "Geteiltes Dokument schließen",
|
||||
"documentOpen": "Geteiltes Dokument öffnen",
|
||||
"download": "Unsere Apps herunterladen",
|
||||
"e2ee": "Ende-zu-Ende-Verschlüsselung",
|
||||
"embedMeeting": "Konferenz einbetten",
|
||||
"enterFullScreen": "Vollbildmodus",
|
||||
"enterTileView": "Kachelansicht einschalten",
|
||||
"exitFullScreen": "Vollbildmodus verlassen",
|
||||
@@ -661,6 +732,8 @@
|
||||
"hangup": "Verlassen",
|
||||
"help": "Hilfe",
|
||||
"invite": "Teilnehmer einladen",
|
||||
"lobbyButtonDisable": "Lobbymodus deaktivieren",
|
||||
"lobbyButtonEnable": "Lobbymodus aktivieren",
|
||||
"login": "Anmelden",
|
||||
"logout": "Abmelden",
|
||||
"lowerYourHand": "Hand senken",
|
||||
@@ -755,6 +828,7 @@
|
||||
"domute": "Stummschalten",
|
||||
"domuteOthers": "Alle anderen stummschalten",
|
||||
"flip": "Spiegeln",
|
||||
"grantModerator": "Zum Moderator machen",
|
||||
"kick": "Hinauswerfen",
|
||||
"moderator": "Moderator",
|
||||
"mute": "Teilnehmer ist stumm geschaltet",
|
||||
@@ -768,7 +842,7 @@
|
||||
"join": "Zum Teilnehmen tippen",
|
||||
"roomname": "Konferenzname eingeben"
|
||||
},
|
||||
"appDescription": "Auf geht's! Starten Sie eine Videokonferenz mit dem ganzen Team. Oder besser noch: Laden Sie alle ein, die Sie kennen. {{app}} ist eine vollständig verschlüsselte, aus 100 % Open-Source-Software bestehende Videokonferenzlösung, die Sie den ganzen Tag kostenlos verwenden können — ohne Registrierung.",
|
||||
"appDescription": "Auf geht's! Starten Sie eine Videokonferenz mit ihrem Team oder besser noch: Laden Sie alle ein, die Sie kennen. {{app}} ist eine vollständig verschlüsselte und 100 % quelloffene Videokonferenzlösung, die Sie immer und überall kostenlos verwenden können – ohne Registrierung.",
|
||||
"audioVideoSwitch": {
|
||||
"audio": "Audio",
|
||||
"video": "Video"
|
||||
@@ -777,24 +851,62 @@
|
||||
"connectCalendarButton": "Kalender verbinden",
|
||||
"connectCalendarText": "Verbinden Sie Ihren Kalender, um all Ihre Meetings in {{app}} anzuzeigen. Fügen Sie zudem {{provider}}-Meetings in Ihren Kalender ein und starten Sie sie mit nur einem Klick.",
|
||||
"enterRoomTitle": "Neues Meeting starten",
|
||||
"roomNameAllowedChars": "Der Meeting-Name sollte keines der folgenden Zeichen enthalten: ?, &, :, ', \", %, #.",
|
||||
"getHelp": "Hilfe",
|
||||
"go": "Los",
|
||||
"goSmall": "Los",
|
||||
"join": "Beitreten",
|
||||
"info": "Informationen",
|
||||
"join": "ERSTELLEN / BEITRETEN",
|
||||
"moderatedMessage": "Oder <a href=\"{{url}}\" rel=\"noopener noreferrer\" target=\"_blank\">reservieren Sie sich eine Konferenz-URL</a>, unter der Sie der einzige Moderator sind.",
|
||||
"privacy": "Datenschutz",
|
||||
"recentList": "Letzte",
|
||||
"recentList": "Verlauf",
|
||||
"recentListDelete": "Löschen",
|
||||
"recentListEmpty": "Die Liste „Letzte“ ist momentan leer. Chatten Sie mit Ihrem Team. Sie finden all Ihre letzten Meetings hier.",
|
||||
"recentListEmpty": "Ihr Konferenzverlauf ist derzeit leer. Reden Sie mit Ihrem Team und Ihre vergangenen Konferenzen landen hier.",
|
||||
"reducedUIText": "Willkommen bei {{app}}!",
|
||||
"roomNameAllowedChars": "Der Konferenzname sollte keines der folgenden Zeichen enthalten: ?, &, :, ', \", %, #.",
|
||||
"roomname": "Konferenzname eingeben",
|
||||
"roomnameHint": "Name oder URL der Konferenz, der Sie beitreten möchten. Sie können einen Namen erfinden, er muss nur den anderen Teilnehmern übermittelt werden, damit diese der gleichen Konferenz beitreten.",
|
||||
"sendFeedback": "Feedback senden",
|
||||
"terms": "AGB",
|
||||
"title": "Sichere, mit umfassenden Funktionen ausgestattete und vollkommen kostenlose Videokonferenzen"
|
||||
"title": "Sichere, voll funktionale und komplett kostenlose Videokonferenzen"
|
||||
},
|
||||
"lonelyMeetingExperience": {
|
||||
"button": "Andere einladen",
|
||||
"youAreAlone": "Nur Sie sind in diesem Meeting"
|
||||
"youAreAlone": "Sie sind alleine in dieser Konferenz"
|
||||
},
|
||||
"helpView": {
|
||||
"header": "Hilfecenter"
|
||||
},
|
||||
"lobby": {
|
||||
"knockingParticipantList": "Liste anklopfender Teilnehmer",
|
||||
"allow": "Annehmen",
|
||||
"backToKnockModeButton": "Kein Passwort, stattdessen Beitritt anfragen",
|
||||
"dialogTitle": "Lobbymodus",
|
||||
"disableDialogContent": "Lobbymodus derzeit deaktiviert. Diese Funktion stellt sicher, dass unerwünschte Personen Ihrer Konferenz nicht beitreten können. Funktion aktivieren?",
|
||||
"disableDialogSubmit": "Deaktivieren",
|
||||
"emailField": "E-Mail-Adresse eingeben",
|
||||
"enableDialogPasswordField": "Passwort setzen (optional)",
|
||||
"enableDialogSubmit": "Aktivieren",
|
||||
"enableDialogText": "Mit dem Lobbymodus schützen Sie Ihre Konferenz, da nur von einem Moderator angenommene Teilnehmer beitreten können.",
|
||||
"enterPasswordButton": "Konferenzpasswort eingeben",
|
||||
"enterPasswordTitle": "Passwort zum Beitreten benutzen",
|
||||
"invalidPassword": "Ungültiges Passwort",
|
||||
"joiningMessage": "Sie treten der Konferenz bei, sobald jemand Ihre Anfrage annimmt.",
|
||||
"joinWithPasswordMessage": "Beitrittsversuch mit Passwort, bitte warten …",
|
||||
"joinRejectedMessage": "Ihr Beitrittsanfrage wurde von einem Moderator abgelehnt.",
|
||||
"joinTitle": "Konferenz beitreten",
|
||||
"joiningTitle": "Beitritt anfragen …",
|
||||
"joiningWithPasswordTitle": "Mit Passwort beitreten …",
|
||||
"knockButton": "Beitritt anfragen",
|
||||
"knockTitle": "Jemand möchte der Konferenz beitreten",
|
||||
"nameField": "Geben Sie Ihren Namen ein",
|
||||
"notificationLobbyAccessDenied": "{{targetParticipantName}} wurde von {{originParticipantName}} der Zutritt verwehrt",
|
||||
"notificationLobbyAccessGranted": "{{targetParticipantName}} wurde von {{originParticipantName}} der Zutritt gestattet",
|
||||
"notificationLobbyDisabled": "{{originParticipantName}} hat die Lobby deaktiviert",
|
||||
"notificationLobbyEnabled": "{{originParticipantName}} hat die Lobby aktiviert",
|
||||
"notificationTitle": "Lobby",
|
||||
"passwordField": "Konferenzpasswort eingeben",
|
||||
"passwordJoinButton": "Beitreten",
|
||||
"reject": "Ablehnen",
|
||||
"toggleLabel": "Lobby aktivieren"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,36 @@
|
||||
{
|
||||
"addPeople": {
|
||||
"add": "Προσκάλεσε",
|
||||
"addContacts": "Προσκάλεσε τις επαφές σου",
|
||||
"copyInvite": "Αντίγραψε την πρόσκληση της συνάντησης",
|
||||
"copyLink": "Αντίγραψε το σύνδεσμο της συνάντησης",
|
||||
"copyStream": "Αντίγραψε το σύνδεσμο της ζωντανής μετάδοσης",
|
||||
"countryNotSupported": "Δεν υποστηρίζουμε αυτόν τον προορισμό ακόμα.",
|
||||
"countryReminder": "Κλήση εκτός ΗΠΑ; Παρακαλώ βεβαιωθείτε ότι ξεκινάτε με τον κωδικό της χώρας!",
|
||||
"defaultEmail": "Το προεπιλεγμένο Email σου",
|
||||
"disabled": "Δεν μπορείτε να προσκαλέσετε άτομα.",
|
||||
"failedToAdd": "Αποτυχία προσθήκης συμμετεχόντων",
|
||||
"footerText": "Η κλήση είναι απενεργοποιημένη.",
|
||||
"googleEmail": "Google Email",
|
||||
"inviteMoreHeader": "Είσαι ο μόναδικός συμμετέχων στη συνάντηση",
|
||||
"inviteMoreMailSubject": "Συμμετοχή στη συνάντηση {{appName}}",
|
||||
"inviteMorePrompt": "Πρόσκληση συμμετεχόντων",
|
||||
"linkCopied": "Ο σύνδεσμος αντιγράφηκε στο πρόχειρο",
|
||||
"loading": "Αναζήτηση για ανθρώπους και αριθμούς τηλεφώνου",
|
||||
"loadingNumber": "Ο αριθμός τηλεφώνου επικυρώνεται",
|
||||
"loadingPeople": "Γίνεται αναζήτηση για ανθρώπους που θα καλεστούν",
|
||||
"noResults": "Δε βρέθηκαν αποτελέσματα αναζήτησης",
|
||||
"outlookEmail": "Outlook Email",
|
||||
"noValidNumbers": "Παρακαλώ εισάγετε έναν αριθμό τηλεφώνου",
|
||||
"searchNumbers": "Προσθέστε αριθμούς τηλεφώνου",
|
||||
"searchPeople": "Αναζήτηση για ανθρώπους",
|
||||
"searchPeopleAndNumbers": "Αναζήτηση για ανθρώπους ή προσθήκη των αριθμών τηλεφώνου τους",
|
||||
"shareInvite": "Κοινή χρήση πρόσκλησης συνάντησης",
|
||||
"shareLink": "Κοινή χρήση συνδέσμου συνάντησης για πρόσκληση άλλων",
|
||||
"shareStream": "Κοινή χρήση του συνδέσμου ζωντανής μετάδοσης",
|
||||
"telephone": "Τηλέφωνο: {{number}}",
|
||||
"title": "Καλέστε ανθρώπους σε αυτή τη συνάντηση"
|
||||
"title": "Καλέστε ανθρώπους σε αυτή τη συνάντηση",
|
||||
"yahooEmail": "Yahoo Email"
|
||||
},
|
||||
"audioDevices": {
|
||||
"bluetooth": "Bluetooth",
|
||||
@@ -79,7 +94,7 @@
|
||||
"ERROR": "Σφάλμα",
|
||||
"FETCH_SESSION_ID": "Απόκτηση session-id...",
|
||||
"GET_SESSION_ID_ERROR": "Λήψη session-id σφάλματος: {{code}}",
|
||||
"GOT_SESSION_ID": "Απόκτηση session-id... Κάνει",
|
||||
"GOT_SESSION_ID": "Απόκτηση session-id... Έγινε",
|
||||
"LOW_BANDWIDTH": "Το βίντεο για το {{displayName}} έχει απενεργοποιηθεί για να εξοικονομήσετε εύρος ζώνης"
|
||||
},
|
||||
"connectionindicator": {
|
||||
@@ -98,9 +113,9 @@
|
||||
"more": "Εμφάνιση περισσότερων",
|
||||
"packetloss": "Απώλεια πακέτων:",
|
||||
"quality": {
|
||||
"good": "Καλά",
|
||||
"inactive": "Ανενεργά",
|
||||
"lost": "Χαμένα",
|
||||
"good": "Καλή",
|
||||
"inactive": "Ανενεργό",
|
||||
"lost": "Χαμένη",
|
||||
"nonoptimal": "Μέτρια",
|
||||
"poor": "Κακή"
|
||||
},
|
||||
@@ -123,8 +138,10 @@
|
||||
"description": "Δεν έγινε τίποτα; Προσπαθήσαμε να κάνουμε έναρξη σύσκεψης στο {{app}} desktop app. Προσπαθήστε ξανά ή ξεκινήστε το {{app}} web app.",
|
||||
"descriptionWithoutWeb": "Δεν έγινε τίποτα; Προσπαθήσαμε να κάνουμε έναρξη σύσκεψης στο {{app}} desktop app.",
|
||||
"downloadApp": "Κατεβάστε την εφαρμογή",
|
||||
"ifDoNotHaveApp": "If you don't have the app yet:",
|
||||
"ifHaveApp": "If you already have the app:",
|
||||
"joinInApp": "Join this meeting using the app",
|
||||
"launchWebButton": "Έναρξη στο web",
|
||||
"openApp": "Συνεχίστε στην εφαρμογή",
|
||||
"title": "Γίνεται έναρξη της συνάντησής σας στο {{app}}...",
|
||||
"tryAgainButton": "Προσπαθήστε ξανά στην επιφάνεια εργασίας"
|
||||
},
|
||||
@@ -146,6 +163,7 @@
|
||||
"accessibilityLabel": {
|
||||
"liveStreaming": "Ζωντανή ροή"
|
||||
},
|
||||
"add": "Add",
|
||||
"allow": "Επίτρεψε",
|
||||
"alreadySharedVideoMsg": "Ένας άλλος συμμετέχων κάνει ήδη κοινή προβολή βίντεο. Η διάσκεψη αυτή επιτρέπει μόνο ένα κοινόχρηστο βίντεο τη φορά.",
|
||||
"alreadySharedVideoTitle": "Μόνο ένα κοινόχρηστο βίντεο επιτρέπεται τη φορά",
|
||||
@@ -174,22 +192,18 @@
|
||||
"copy": "Αντιγραφή",
|
||||
"dismiss": "Απόρριψη",
|
||||
"displayNameRequired": "Γεια σου! Ποιο είναι το όνομα σου;",
|
||||
"done": "Κάνει",
|
||||
"e2eeDescription": "<p>Η από άκρη σε άκρη κρυπτογράφηση είναι σήμερα <strong>σε ΠΕΙΡΑΜΑΤΙΚΟ στάδιο</strong>. Παρακαλώ δείτε <a href='https://jitsi.org/blog/e2ee/' target='_blank'>αυτήν την ανάρτηση</a> για λεπτομέρειες.</p><br/><p>Παρακαλώ να έχετε κατά νου ότι η ενεργοποίηση της από άκρη σε άκρη κρυπτογράφησης θα απενεργοποιήσει από την πλευρά του διακομιστή υπηρεσίες όπως: καταγραφή, live streaming και συμμετοχή μέσω τηλεφώνου. Επίσης, να έχετε κατά νου ότι η συνάντηση θα λειτουργήσει μόνο για τους ανθρώπους που συνδέονται από φυλλομετρητές με υποστήριξη για insertable streams.</p>",
|
||||
"e2eeLabel": "Κλειδί",
|
||||
"e2eeTitle": "Από άκρη σε άκρη κρυπτογράφηση",
|
||||
"e2eeWarning": "<br /><p><strong>ΠΡΟΕΙΔΟΠΟΊΗΣΗ:</strong> Δε φαίνεται να έχουν όλοι οι συμμετέχοντες στη συνάντηση αυτή υποστήριξη για από άκρη σε άκρη κρυπτογράφηση. Αν την ενεργοποιήσετε, δεν θα μπορέσουν να σας δουν ούτε να σας ακούσουν.</p>",
|
||||
"done": "Έγινε",
|
||||
"e2eeDescription": "Η από άκρη σε άκρη κρυπτογράφηση είναι σήμερα σε ΠΕΙΡΑΜΑΤΙΚΟ στάδιο. Παρακαλώ να έχετε κατά νου ότι η ενεργοποίηση της από άκρη σε άκρη κρυπτογράφησης θα απενεργοποιήσει από την πλευρά του διακομιστή υπηρεσίες όπως: καταγραφή, live streaming και συμμετοχή μέσω τηλεφώνου. Επίσης, να έχετε κατά νου ότι η συνάντηση θα λειτουργήσει μόνο για τους ανθρώπους που συνδέονται από φυλλομετρητές με υποστήριξη για insertable streams.",
|
||||
"e2eeNoKey": "None",
|
||||
"e2eeSet": "Set",
|
||||
"e2eeToggleSet": "Set key",
|
||||
"e2eeWarning": "ΠΡΟΕΙΔΟΠΟΊΗΣΗ: Δε φαίνεται να έχουν όλοι οι συμμετέχοντες στη συνάντηση αυτή υποστήριξη για από άκρη σε άκρη κρυπτογράφηση. Αν την ενεργοποιήσετε, δεν θα μπορέσουν να σας δουν ούτε να σας ακούσουν.",
|
||||
"enterDisplayName": "Παρακαλώ εισάγετε το όνομά σας εδώ",
|
||||
"error": "Σφάλμα",
|
||||
"externalInstallationMsg": "Θα πρέπει να εγκαταστήσετε την επέκτασή μας για διαμοιρασμό επιφάνειας εργασίας.",
|
||||
"externalInstallationTitle": "Απαιτείται επέκταση",
|
||||
"goToStore": "Μετάβαση στο webstore",
|
||||
"gracefulShutdown": "Μας υπηρεσία είναι προς το παρόν εκτός λειτουργίας για συντήρηση. Παρακαλώ προσπαθήστε ξανά αργότερα.",
|
||||
"IamHost": "Είμαι ο οικοδεσπότης",
|
||||
"incorrectRoomLockPassword": "Εσφαλμένος κωδικός πρόσβασης",
|
||||
"incorrectPassword": "Λανθασμένο όνομα χρήστη ή κωδικός πρόσβασης",
|
||||
"inlineInstallationMsg": "Θα πρέπει να εγκαταστήσετε την επέκτασή μας για διαμοιρασμό επιφάνειας εργασίας.",
|
||||
"inlineInstallExtension": "Εγκαταστήστε τώρα",
|
||||
"internalError": "Ουπς! Κάτι πήγε στραβά. Παρουσιάστηκε το παρακάτω σφάλμα: {{error}}",
|
||||
"internalErrorTitle": "Εσωτερικό σφάλμα",
|
||||
"kickMessage": "Μπορείτε να επικοινωνήσετε με το {{participantDisplayName}} για περισσότερες λεπτομέρειες.",
|
||||
@@ -198,6 +212,7 @@
|
||||
"kickParticipantTitle": "Θέλετε να αποβάλετε αυτόν τον συμμετέχοντα;",
|
||||
"kickTitle": "Ωχ! Ο/Η {{participantDisplayName}} σας απέβαλε από τη διάσκεψη",
|
||||
"liveStreaming": "Ζωντανή ροή",
|
||||
"liveStreamingDisabledBecauseOfActiveRecordingTooltip": "Not possible while recording is active",
|
||||
"liveStreamingDisabledForGuestTooltip": "Οι επισκέπτες δεν μπορούν να ξεκινήσουν τη ζωντανή ροή",
|
||||
"liveStreamingDisabledTooltip": "Έναρξη ζωντανής ροής απενεργοποιημένη",
|
||||
"lockMessage": "Αποτυχία κλειδώματος της διάσκεψης.",
|
||||
@@ -231,6 +246,7 @@
|
||||
"popupError": "Ο φυλλομετρητής σας μπλοκάρει τα pop-up windows από αυτό το site. Παρακαλούμε ενεργοποιήστε τα pop-ups στις ρυθμίσεις ασφαλείας του προγράμματος περιήγησής σας και προσπαθήστε ξανά.",
|
||||
"popupErrorTitle": "Pop-up μπλοκαρίστηκε",
|
||||
"recording": "Γίνεται εγγραφή",
|
||||
"recordingDisabledBecauseOfActiveLiveStreamingTooltip": "Not possible while a live stream is active",
|
||||
"recordingDisabledForGuestTooltip": "Οι επισκέπτες δεν μπορούν να ξεκινήσουν τις ηχογραφήσεις.",
|
||||
"recordingDisabledTooltip": "Έναρξη εγγραφής απενεργοποιημένη.",
|
||||
"rejoinNow": "Επανασύνδεση τώρα",
|
||||
@@ -251,8 +267,6 @@
|
||||
"screenSharingAudio": "Διαμοιρασμός ήχου",
|
||||
"screenSharingFailedToInstall": "Ουπς! Η εγκατάσταση της επέκταση κοινής χρήσης οθόνης απέτυχε.",
|
||||
"screenSharingFailedToInstallTitle": "Η εγκατάσταση της επέκταση κοινής χρήσης οθόνης απέτυχε",
|
||||
"screenSharingFirefoxPermissionDeniedError": "Κάτι πήγε στραβά ενώ προσπαθούσατε να μοιραστείτε την οθόνη σας. Παρακαλούμε βεβαιωθείτε ότι μας έχετε δώσει την άδεια να το πράξουμε.",
|
||||
"screenSharingFirefoxPermissionDeniedTitle": "Ουπς! Δεν ήμασταν σε θέση να ξεκινήσουμε την κοινή χρήση οθόνης!",
|
||||
"screenSharingPermissionDeniedError": "Ουπς! Κάτι πήγε στραβά με τα δικαιώματα της επέκτασης κοινής χρήσης οθόνης. Παρακαλώ ξαναφορτώστε και προσπαθήστε ξανά.",
|
||||
"sendPrivateMessage": "Πρόσφατα λάβατε ένα προσωπικό μήνυμα. Σκοπεύετε να απαντήσετε σε αυτό ιδιωτικά ή θέλετε να στείλετε το μήνυμά σας στην ομάδα;",
|
||||
"sendPrivateMessageCancel": "Στείλτε στην ομάδα",
|
||||
@@ -390,6 +404,8 @@
|
||||
"failedToStart": "Η ζωντανή ροή απέτυχε να ξεκινήσει",
|
||||
"getStreamKeyManually": "Δεν ήμασταν σε θέση να φέρουμε κάποια ζωντανή ροή. Προσπαθήστε να πάρετε το κλειδί της ζωντανής ροής από το YouTube.",
|
||||
"invalidStreamKey": "Το κλειδί της ζωντανής ροής μπορεί να είναι εσφαλμένο.",
|
||||
"limitNotificationDescriptionNative": "Your streaming will be limited to {{limit}} min. For unlimited streaming try {{app}}.",
|
||||
"limitNotificationDescriptionWeb": "Due to high demand your streaming will be limited to {{limit}} min. For unlimited streaming try <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"off": "Η ζωντανή ροή σταμάτησε",
|
||||
"offBy": "Ο/Η {{name}} σταμάτησε τη ζωντανή ροή",
|
||||
"on": "Ζωντανή ροή",
|
||||
@@ -476,6 +492,40 @@
|
||||
"passwordSetRemotely": "ορίστηκε από άλλον συμμετέχοντα",
|
||||
"passwordDigitsOnly": "Έως {{number}} ψηφία",
|
||||
"poweredby": "με τη δύναμη του",
|
||||
"prejoin": {
|
||||
"audioAndVideoError": "Σφάλμα ήχου και βίντεο:",
|
||||
"audioOnlyError": "Σφάλμα ήχου:",
|
||||
"audioTrackError": "Δεν ήταν δυνατή η δημιουργία κομματιού ήχου.",
|
||||
"callMe": "Κάλεσέ με",
|
||||
"callMeAtNumber": "Κάλεσέ με σε αυτό το νούμερο:",
|
||||
"configuringDevices": "Γίνεται παραμετροποίηση συσκευών...",
|
||||
"connectedWithAudioQ": "Είστε συνδεδεμένοι με ήχο;",
|
||||
"copyAndShare": "Αντιγραφή και κοινή χρήση συνδέσμου συνάντησης",
|
||||
"dialInMeeting": "Κλήση στη συνάντηση",
|
||||
"dialInPin": "Κλήση στη συνάντηση και εισαγωγή κωδικού PIN:",
|
||||
"dialing": "Γίνεται κλήση",
|
||||
"doNotShow": "Να μην εμφανιστεί αυτό ξανά",
|
||||
"errorDialOut": "Η κλήση δεν ήταν δυνατή",
|
||||
"errorDialOutDisconnected": "Η κλήση δεν ήταν δυνατή. Έγινε αποσύνδεση",
|
||||
"errorDialOutFailed": "Η κλήση δεν ήταν δυνατή. Η κλήση απέτυχε",
|
||||
"errorDialOutStatus": "Σφάλμα λήψης κατάστασης κλήσης",
|
||||
"errorStatusCode": "Σφάλμα κλήσης, κωδικός κατάστασης: {{status}}",
|
||||
"errorValidation": "Η επικύρωση του αριθμού απέτυχε",
|
||||
"iWantToDialIn": "Θέλω να κάνω κλήση",
|
||||
"joinAudioByPhone": "Συμμετοχή με ήχο τηλεφώνου",
|
||||
"joinMeeting": "Συμμετοχή στη συνάντηση",
|
||||
"joinWithoutAudio": "Συμμετοχή χωρίς ήχο",
|
||||
"initiated": "Η κλήση ξεκίνησε",
|
||||
"linkCopied": "Ο σύνδεσμος αντιγράφηκε στο πρόχειρο",
|
||||
"lookGood": "Ακούγεται ότι το μικρόφωνο σας λειτουργεί άψογα",
|
||||
"or": "ή",
|
||||
"calling": "Γίνεται κλήση",
|
||||
"startWithPhone": "Έναρξη με ήχο τηλεφώνου",
|
||||
"screenSharingError": "Σφάλμα διαμοιρασμού οθόνης:",
|
||||
"videoOnlyError": "Σφάλμα βίντεο:",
|
||||
"videoTrackError": "Δεν ήταν δυνατή η δημιουργία κομματιού βίντεο.",
|
||||
"viewAllNumbers": "προβολή όλων των αριθμών"
|
||||
},
|
||||
"presenceStatus": {
|
||||
"busy": "Απασχολημένος",
|
||||
"calling": "Γίνεται κλήση...",
|
||||
@@ -498,6 +548,8 @@
|
||||
},
|
||||
"raisedHand": "Θα ήθελα να μιλήσω",
|
||||
"recording": {
|
||||
"limitNotificationDescriptionWeb": "Λόγω υψηλής ζήτησης η εγγραφή σας θα περιριστεί σε {{limit}} λεπτά. Για απεριόριστες εγγραφές, δοκιμάστε το <a href={{url}} rel='noopener noreferrer' target='_blank'>{{app}}</a>.",
|
||||
"limitNotificationDescriptionNative": "Λόγω υψηλής ζήτησης η εγγραφή σας θα περιριστεί σε {{limit}} λεπτά. Για απεριόριστες εγγραφές, δοκιμάστε <3>{{app}}</3>.",
|
||||
"authDropboxText": "Ανεβάστε στο Dropbox",
|
||||
"availableSpace": "Διαθέσιμος χώρος: {{spaceLeft}} MB (περίπου {{duration}} λεπτά εγγραφής)",
|
||||
"beta": "BETA",
|
||||
@@ -527,6 +579,11 @@
|
||||
"sectionList": {
|
||||
"pullToRefresh": "Τραβήξτε για να ανανεώσετε"
|
||||
},
|
||||
"security": {
|
||||
"about": "Έχετε τη δυνατότητα να προσθέσετε κωδικό στη συνάντησή σας. Οι συμμετέχοντες θα πρέπει να τον εισάγουν για να τους δοθεί πρόσβαση στη συνάντηση.",
|
||||
"insecureRoomNameWarning": "Το όνομα του διαδρόμου δεν είναι ασφαλές. Ανεπιθύμητοι συμμετέχοντες μπορεί να συμμετάσχουν στη συνάντησή σας. Σκεφτείτε το να ασφαλίσετε τη συνάντηση σας χρησιμοποιώντας το κουμπί Ασφάλεια.",
|
||||
"securityOptions": "Επιλογές ασφαλείας"
|
||||
},
|
||||
"settings": {
|
||||
"calendar": {
|
||||
"about": "H σύνδεση ημερολογίου του {{appName}} χρησιμοποιείται για την ασφαλή πρόσβαση του ημερολογίου σας, ώστε να μπορεί να διαβάσει τις επερχόμενες εκδηλώσεις.",
|
||||
@@ -585,7 +642,7 @@
|
||||
"name": "Όνομα",
|
||||
"seconds": "{{count}}δ",
|
||||
"speakerStats": "Στατιστικά ομιλητή",
|
||||
"speakerTime": "Ώρα ομιλητή"
|
||||
"speakerTime": "Χρόνος ομιλητή"
|
||||
},
|
||||
"startupoverlay": {
|
||||
"policyText": " ",
|
||||
@@ -612,6 +669,7 @@
|
||||
"help": "Βοήθεια",
|
||||
"invite": "Πρόσκληση συμμετεχόντων",
|
||||
"kick": "Αποβολή συμμετέχοντα",
|
||||
"lobbyButton": "Ενεργοποίηση/απενεργοποίηση λειτουργίας διαδρόμου",
|
||||
"localRecording": "Εναλλαγή ελέγχων τοπικής καταγραφής",
|
||||
"lockRoom": "Εναλλαγή κωδικού πρόσβασης συνάντησης",
|
||||
"moreActions": "Εναλλαγή μενού περισσότερων ενεργειών",
|
||||
@@ -625,6 +683,7 @@
|
||||
"raiseHand": "Εναλλαγή σηκώματος χεριού",
|
||||
"recording": "Εναλλαγή καταγραφής",
|
||||
"remoteMute": "Σίγαση συμμετέχοντα",
|
||||
"security": "Επιλογές ασφαλείας",
|
||||
"Settings": "Εναλλαγή ρυθμίσεων",
|
||||
"sharedvideo": "Εναλλαγή κοινής χρήσης βίντεο στο Youtube",
|
||||
"shareRoom": "Προσκαλέστε κάποιον",
|
||||
@@ -658,6 +717,8 @@
|
||||
"hangup": "Αποσύνδεση",
|
||||
"help": "Βοήθεια",
|
||||
"invite": "Πρόσκληση συμμετεχόντων",
|
||||
"lobbyButtonDisable": "Απενεργοποίηση λειτουργίας διαδρόμου",
|
||||
"lobbyButtonEnable": "Ενεργοποίηση λειτουργίας διαδρόμου",
|
||||
"login": "Είσοδος",
|
||||
"logout": "Αποσύνδεση",
|
||||
"lowerYourHand": "Κατεβάστε το χέρι σας",
|
||||
@@ -678,6 +739,7 @@
|
||||
"profile": "Επεξεργαστείτε το προφίλ σας",
|
||||
"raiseHand": "Σηκώστε / κατεβάστε το χέρι σας",
|
||||
"raiseYourHand": "Σηκώστε το χέρι σας",
|
||||
"security": "Επιλογές ασφαλείας",
|
||||
"Settings": "Ρυθμίσεις",
|
||||
"sharedvideo": "Μοιραστείτε βίντεο στο YouTube",
|
||||
"shareRoom": "Προσκαλέστε κάποιον",
|
||||
@@ -743,9 +805,6 @@
|
||||
"lowDefinition": "Χαμηλής ευκρίνειας",
|
||||
"onlyAudioAvailable": "Μόνο ο ήχος είναι διαθέσιμος",
|
||||
"onlyAudioSupported": "Υποστηρίζουμε μόνο ήχο σε αυτό το πρόγραμμα περιήγησης.",
|
||||
"p2pEnabled": "Λειτουργία Peer to Peer Ενεργοποιημένη",
|
||||
"p2pVideoQualityDescription": "Σε λειτουργία peer-to-peer, η ποιότητα του εισερχόμενου βίντεο μπορεί μόνο να εναλλάσσεται μεταξύ της υψηλής και μόνο ήχου. Οι υπόλοιπες ρυθμίσεις δεν θα ενεργοποιηθούν μέχρι να τερματιστεί η λειτουργία peer to peer.",
|
||||
"recHighDefinitionOnly": "Να προτιμηθεί υψηλή ευκρίνεια.",
|
||||
"sd": "SD",
|
||||
"sdTooltip": "Προβολή βίντεο τυπικής ανάλυσης",
|
||||
"standardDefinition": "Τυπική ανάλυση"
|
||||
@@ -800,32 +859,31 @@
|
||||
"helpView": {
|
||||
"header": "Κέντρο βοήθειας"
|
||||
},
|
||||
"prejoin": {
|
||||
"audioAndVideoError": "Σφάλμα ήχου και βίντεο:",
|
||||
"audioOnlyError": "Σφάλμα ήχου:",
|
||||
"audioTrackError": "Δεν ήταν δυνατό να δημιουργηθεί το κομμάτι ήχου.",
|
||||
"callMe": "Κάλεσέ με",
|
||||
"callMeAtNumber": "Κάλεσε με σε αυτό το νούμερο:",
|
||||
"configuringDevices": "Διαμόρφωση συσκευών",
|
||||
"connectedWithAudioQ": "Είστε συνδεδεμένοι με ήχο;",
|
||||
"copyAndShare": "Αντιγραφή & διαμοιρασμός συνδέσμου συνάντησης",
|
||||
"dialInMeeting": "Καλέστε στη συνάντηση",
|
||||
"dialInPin": "Καλέστε στη συνάντηση και εισάγετε κωδικό PIN:",
|
||||
"dialing": "Γίνεται κλήση",
|
||||
"doNotShow": "Να μην εμφανιστεί αυτό ξανά",
|
||||
"iWantToDialIn": "Θέλω να καλέσω",
|
||||
"joinAudioByPhone": "Σύνδεση με ήχο τηλεφώνου",
|
||||
"joinMeeting": "Σύνδεση στη συνάντηση",
|
||||
"joinWithoutAudio": "Σύνδεση χωρίς ήχο",
|
||||
"initiated": "Η κλήση ξεκίνησε",
|
||||
"linkCopied": "Ο σύνδεσμος αντιγράφηκε στο πρόχειρο",
|
||||
"lookGood": "Ακούγεται ότι το μικρόφωνό σας δουλεύει σωστά",
|
||||
"or": "ή",
|
||||
"calling": "Γίνεται κλήση...",
|
||||
"startWithPhone": "Έναρξη με ήχο τηλεφώνου",
|
||||
"screenSharingError": "Σφάλμα διαμοιρασμού οθόνης:",
|
||||
"videoOnlyError": "Σφάλμα βίντεο:",
|
||||
"videoTrackError": "Δεν μπορεί να δημιουργηθεί το βίντεο",
|
||||
"viewAllNumbers": "προβολή όλων των αριθμών"
|
||||
"lobby": {
|
||||
"allow": "Επίτρεψε",
|
||||
"backToKnockModeButton": "Χωρίς κωδικό, ζητήστε πρόσβαση αντί αυτού",
|
||||
"dialogTitle": "Λειτουργία διαδρόμου",
|
||||
"disableDialogContent": "Η λειτουργία διαδρόμου είναι ενεργοποιημένη. Αυτή η λειτουργία εξασφαλιζει ότι οι ανεπιθύμητοι συμμετέχοντες δεν μπορούν να προστεθούν στη συνάντηση. Θέλετε να την απαεργοποιήσετε;",
|
||||
"disableDialogSubmit": "Απενεργοποίηση",
|
||||
"emailField": "Εισάγετε τη διεύθυνση email σας",
|
||||
"enableDialogPasswordField": "Ορισμός κωδικού (προαιρετικός)",
|
||||
"enableDialogSubmit": "Ενεργοποίηση",
|
||||
"enableDialogText": "Η ενεργοποίηση λειτουργίας διαδρόμου σας επιτρέπει να προστατεύσετε τη συνάντηση σας, επιτρέποντας την είσοδο μόνο μετά από επίσημη έγκριση από έναν διαχειριστή.",
|
||||
"enterPasswordButton": "Εισαγωγή κωδικού συνάντησής",
|
||||
"enterPasswordTitle": "Εισάγετε κωδικό για να προστεθείτε στη συνομιλία",
|
||||
"invalidPassword": "Εσφαλμένος κωδικός",
|
||||
"joiningMessage": "Θα προστεθείτε στη συνάντηση μόλις κάποιος αποδεχτεί το αίτημά σας",
|
||||
"joinWithPasswordMessage": "Γίνεται προσπάθεια εισόδου με κωδικό, παρακαλώ περιμένετε...",
|
||||
"joinRejectedMessage": "Το αίτημα εισόδου σας απορρίφθηκε από έναν διαχειριστή.",
|
||||
"joinTitle": "Προσθήκη σε συνάντηση",
|
||||
"joiningTitle": "Γίνεται αίτηση εισόδου σε συνάντηση...",
|
||||
"joiningWithPasswordTitle": "Γίνεται είσοδος με κωδικό...",
|
||||
"knockButton": "Αίτημα εισόδου",
|
||||
"knockTitle": "Κάποιος θέλει να προστεθεί στη συνάντηση",
|
||||
"nameField": "Εισάγετε το όνομά σας",
|
||||
"passwordField": "Εισάγετε τον κωδικό συνάντησης",
|
||||
"passwordJoinButton": "Είσοδος",
|
||||
"reject": "Απόρριψη",
|
||||
"toggleLabel": "Ενεργοποίηση διαδρόμου"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -195,10 +195,8 @@
|
||||
"dismiss": "Descartar",
|
||||
"displayNameRequired": "¡Hola! ¿Cuál es tu nombre?",
|
||||
"done": "Listo",
|
||||
"e2eeDescription": "<p>El cifrado Extremo-a-Extremo es actualmente <strong>EXPERIMENTAL</strong>. Por favor lea<a href='https://jitsi.org/blog/e2ee/' target='_blank'>este artículo</a> para más detalles.</p><br/><p>Tenga en cuenta que activar el cifrado extremo-a-extremo puede deshabilitar servicios en el servidor como: grabación, transmisión en vivo y participación telefónica. Sin embargo tenga en cuenta que esta reunion solo funcionará con personas que se unan usando un navegador.</p>",
|
||||
"e2eeLabel": "Clave",
|
||||
"e2eeTitle": "Cifrado Extremo-a-Extremo",
|
||||
"e2eeWarning": "<br /><p><strong>ATENCION:</strong> No todos los participantes de esta reunión soportan cifrado Extremo-a-Extremo. Si usted habilita el cifrado ellos no podrán verlo ni oirlo.</p>",
|
||||
"e2eeDescription": "El cifrado Extremo-a-Extremo es actualmente EXPERIMENTAL. Tenga en cuenta que activar el cifrado extremo-a-extremo puede deshabilitar servicios en el servidor como: grabación, transmisión en vivo y participación telefónica. Sin embargo tenga en cuenta que esta reunion solo funcionará con personas que se unan usando un navegador.",
|
||||
"e2eeWarning": "ATENCION: No todos los participantes de esta reunión soportan cifrado Extremo-a-Extremo. Si usted habilita el cifrado ellos no podrán verlo ni oirlo.",
|
||||
"enterDisplayName": "Por favor ingresa tu nombre aquí",
|
||||
"error": "Error",
|
||||
"externalInstallationMsg": "Necesita instalar nuestra extensión para compartir escritorio.",
|
||||
@@ -582,7 +580,7 @@
|
||||
},
|
||||
"security": {
|
||||
"about": "Usted puede agregar una contraseña a la reunión. Los participantes necesitaran la contraseña para unirse a la reunión.",
|
||||
"insecureRoomNameWarning": "El nombre de la sala es inseguro. Participantes no desseados pueden llegar a unirse a la reunión.",
|
||||
"insecureRoomNameWarning": "El nombre de la sala es inseguro. Participantes no deseados pueden llegar a unirse a la reunión.",
|
||||
"securityOptions": "Opciones de seguridad"
|
||||
},
|
||||
"settings": {
|
||||
|
||||
@@ -194,10 +194,8 @@
|
||||
"dismiss": "Descartar",
|
||||
"displayNameRequired": "¡Hola! ¿Cuál es tu nombre?",
|
||||
"done": "Listo",
|
||||
"e2eeDescription": "<p>El cifrado Extremo-a-Extremo es actualmente <strong>EXPERIMENTAL</strong>. Por favor lea<a href='https://jitsi.org/blog/e2ee/' target='_blank'>este artículo</a> para más detalles.</p><br/><p>Tenga en cuenta que activar el cifrado extremo-a-extremo puede deshabilitar servicios en el servidor como: grabación, transmisión en vivo y participación telefónica. Sin embargo tenga en cuenta que esta reunion solo funcionará con personas que se unan usando un navegador.</p>",
|
||||
"e2eeLabel": "Clave",
|
||||
"e2eeTitle": "Cifrado Extremo-a-Exremo",
|
||||
"e2eeWarning": "<br /><p><strong>ATENCION:</strong> No todos los participantes de esta reunión soportan cifrado Extremo-a-Extremo. Si usted habilita el cifrado ellos no podrán verlo ni oirlo.</p>",
|
||||
"e2eeDescription": "El cifrado Extremo-a-Extremo es actualmente EXPERIMENTAL. Tenga en cuenta que activar el cifrado extremo-a-extremo puede deshabilitar servicios en el servidor como: grabación, transmisión en vivo y participación telefónica. Sin embargo tenga en cuenta que esta reunion solo funcionará con personas que se unan usando un navegador.",
|
||||
"e2eeWarning": "ATENCION: No todos los participantes de esta reunión soportan cifrado Extremo-a-Extremo. Si usted habilita el cifrado ellos no podrán verlo ni oirlo.",
|
||||
"enterDisplayName": "Por favor ingresa tu nombre aquí",
|
||||
"error": "Error",
|
||||
"externalInstallationMsg": "Necesita instalar nuestra extensión para compartir escritorio.",
|
||||
@@ -580,7 +578,7 @@
|
||||
},
|
||||
"security": {
|
||||
"about": "Usted puede agregar una contraseña a la reunión. Los participantes necesitaran la contraseña para unirse a la reunión.",
|
||||
"insecureRoomNameWarning": "El nombre de la sala es inseguro. Participantes no desseados pueden llegar a unirse a la reunión.",
|
||||
"insecureRoomNameWarning": "El nombre de la sala es inseguro. Participantes no deseados pueden llegar a unirse a la reunión.",
|
||||
"securityOptions": "Opciones de seguridad"
|
||||
},
|
||||
"settings": {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user